661 lines
33 KiB
C#
661 lines
33 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using Dapper;
|
|||
|
using System.Data;
|
|||
|
using System.Linq;
|
|||
|
using System.Threading.Tasks;
|
|||
|
using System.Text;
|
|||
|
using System.Net;
|
|||
|
using Repository.Models;
|
|||
|
using Microsoft.Extensions.Options;
|
|||
|
using System.IO;
|
|||
|
using System.Xml;
|
|||
|
using Newtonsoft.Json;
|
|||
|
using Newtonsoft.Json.Linq;
|
|||
|
|
|||
|
namespace Repository.Services.Implement
|
|||
|
{
|
|||
|
public class ObixApiConfig
|
|||
|
{
|
|||
|
public string ApiBase { get; set; }
|
|||
|
public string UserName { get; set; }
|
|||
|
public string Password { get; set; }
|
|||
|
}
|
|||
|
|
|||
|
public class Variable
|
|||
|
{
|
|||
|
public string System_type { get; set; }
|
|||
|
public string System_key { get; set; }
|
|||
|
public string system_value { get; set; }
|
|||
|
}
|
|||
|
|
|||
|
public class DeviceSubscrip
|
|||
|
{
|
|||
|
public string building_guid { get; set; }
|
|||
|
public string main_system_guid { get; set; }
|
|||
|
public string sub_system_guid { get; set; }
|
|||
|
public string device_number { get; set; }
|
|||
|
}
|
|||
|
|
|||
|
public class OntimeDeviceSubscripService
|
|||
|
{
|
|||
|
private readonly IDbConnection conn;
|
|||
|
private readonly IDbTransaction trans;
|
|||
|
private readonly IOptions<ObixApiConfig> _obixApiConfig;
|
|||
|
|
|||
|
public OntimeDeviceSubscripService(IDbConnection conn, IDbTransaction trans, IOptions<ObixApiConfig> _obixApiConfig)
|
|||
|
{
|
|||
|
this.conn = conn;
|
|||
|
this.trans = trans;
|
|||
|
this._obixApiConfig = _obixApiConfig;
|
|||
|
}
|
|||
|
|
|||
|
private string InsertGenerateString(List<string> properties, string table_name)
|
|||
|
{
|
|||
|
var insertQuery = new StringBuilder($"INSERT INTO {table_name} ");
|
|||
|
|
|||
|
insertQuery.Append("(");
|
|||
|
|
|||
|
properties.ForEach(prop => { insertQuery.Append($"{table_name}.{prop.Replace("@", "")},"); });
|
|||
|
|
|||
|
insertQuery
|
|||
|
.Remove(insertQuery.Length - 1, 1)
|
|||
|
.Append(") VALUES (");
|
|||
|
|
|||
|
properties.ForEach(prop => { insertQuery.Append($"{prop},"); });
|
|||
|
|
|||
|
insertQuery
|
|||
|
.Remove(insertQuery.Length - 1, 1)
|
|||
|
.Append(");");
|
|||
|
|
|||
|
return insertQuery.ToString();
|
|||
|
}
|
|||
|
|
|||
|
public void MaintainOntimeDeviceSubscription(string targetTable, string mode, Dictionary<string, object> targetData, string origData = null)
|
|||
|
{
|
|||
|
List<Dictionary<string, object>> final_device_subscrip = new List<Dictionary<string, object>>();
|
|||
|
List<DeviceSubscrip> tempDeviceSubscrips = new List<DeviceSubscrip>();
|
|||
|
//判斷來源是什麼資料表
|
|||
|
if ("device" == targetTable)
|
|||
|
{ //設備表格
|
|||
|
switch (mode)
|
|||
|
{
|
|||
|
case "delete": //軟刪除
|
|||
|
//直接刪除該設備
|
|||
|
object device_guid = null;
|
|||
|
var has_device_guid = targetData.TryGetValue("device_guid", out device_guid);
|
|||
|
|
|||
|
var sql_device = $@"SELECT device_number FROM device WHERE device_guid = @device_guid";
|
|||
|
var device_number = conn.QueryFirstOrDefault<string>(sql_device, new { device_guid = device_guid.ToString() }, trans);
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(device_number))
|
|||
|
{
|
|||
|
var purge_for_delete_sql = $@"DELETE FROM ontime_device_subscription WHERE device_number = @device_number";
|
|||
|
conn.Execute(purge_for_delete_sql, new { device_number = device_number }, trans);
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
else if ("device_item" == targetTable)
|
|||
|
{ //點位表格
|
|||
|
List<DeviceSubscrip> deviceSubscrips = new List<DeviceSubscrip>();
|
|||
|
// step 1 找出所有該系統小類的設備
|
|||
|
if (mode != "delete")
|
|||
|
{
|
|||
|
var sql_device = $@"SELECT building_guid, main_system_guid, sub_system_guid, device_number FROM device WHERE deleted = 0 AND sub_system_guid = @sub_system_guid";
|
|||
|
object sub_system_guid = null;
|
|||
|
var has_value = targetData.TryGetValue("@sub_system_guid", out sub_system_guid);
|
|||
|
|
|||
|
deviceSubscrips = conn.Query<DeviceSubscrip>(sql_device, new { sub_system_guid = sub_system_guid.ToString() }).ToList();
|
|||
|
tempDeviceSubscrips = deviceSubscrips;
|
|||
|
}
|
|||
|
else
|
|||
|
{ //需先找出該點位的sub_system_guid
|
|||
|
object device_item_guid = null;
|
|||
|
var has_value = targetData.TryGetValue("device_item_guid", out device_item_guid);
|
|||
|
|
|||
|
if (has_value)
|
|||
|
{
|
|||
|
var sql_device_item = $@"SELECT sub_system_guid FROM device_item WHERE device_item_guid = @device_item_guid";
|
|||
|
var sub_system_guid = conn.QueryFirstOrDefault<string>(sql_device_item, new { device_item_guid = device_item_guid.ToString() });
|
|||
|
|
|||
|
var sql_device = $@"SELECT building_guid, main_system_guid, sub_system_guid, device_number FROM device WHERE deleted = 0 AND sub_system_guid = @sub_system_guid";
|
|||
|
deviceSubscrips = conn.Query<DeviceSubscrip>(sql_device, new { sub_system_guid = sub_system_guid.ToString() }).ToList();
|
|||
|
tempDeviceSubscrips = deviceSubscrips;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//判斷是什麼模式,ex:insert、insert_list、update...等
|
|||
|
switch (mode)
|
|||
|
{
|
|||
|
case "insert": //新增
|
|||
|
List<Dictionary<string, object>> insertDics = new List<Dictionary<string, object>>();
|
|||
|
|
|||
|
object point_name = null;
|
|||
|
var has_point_value = targetData.TryGetValue("@points", out point_name);
|
|||
|
if (has_point_value)
|
|||
|
{
|
|||
|
foreach (var deviceSubscrip in deviceSubscrips)
|
|||
|
{
|
|||
|
Dictionary<string, object> insertDic = new Dictionary<string, object>()
|
|||
|
{
|
|||
|
{ "@building_guid", deviceSubscrip.building_guid },
|
|||
|
{ "@main_system_guid", deviceSubscrip.main_system_guid },
|
|||
|
{ "@sub_system_guid", deviceSubscrip.sub_system_guid },
|
|||
|
{ "@device_number", deviceSubscrip.device_number },
|
|||
|
{ "@name", point_name}
|
|||
|
};
|
|||
|
|
|||
|
insertDics.Add(insertDic);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
List<string> properties = insertDics.First().Keys.ToList();
|
|||
|
string sql = InsertGenerateString(properties, "ontime_device_subscription");
|
|||
|
conn.Execute(sql, insertDics, trans);
|
|||
|
final_device_subscrip = insertDics;
|
|||
|
|
|||
|
break;
|
|||
|
case "update": //更新
|
|||
|
|
|||
|
if (origData != null)
|
|||
|
{
|
|||
|
var device_point_name = origData;
|
|||
|
//刪除訂閱表的資料
|
|||
|
var purge_sql = $@"DELETE FROM ontime_device_subscription WHERE name=@name AND device_number IN @device_number";
|
|||
|
conn.Execute(purge_sql, new { name = device_point_name, device_number = deviceSubscrips.Select(x => x.device_number).ToList() }, trans);
|
|||
|
}
|
|||
|
|
|||
|
//新增訂閱表的資料
|
|||
|
List<Dictionary<string, object>> insertDics2 = new List<Dictionary<string, object>>();
|
|||
|
|
|||
|
object point_name2 = null;
|
|||
|
var has_point_value2 = targetData.TryGetValue("@points", out point_name);
|
|||
|
if (has_point_value2)
|
|||
|
{
|
|||
|
foreach (var deviceSubscrip in deviceSubscrips)
|
|||
|
{
|
|||
|
Dictionary<string, object> insertDic = new Dictionary<string, object>()
|
|||
|
{
|
|||
|
{ "@building_guid", deviceSubscrip.building_guid },
|
|||
|
{ "@main_system_guid", deviceSubscrip.main_system_guid },
|
|||
|
{ "@sub_system_guid", deviceSubscrip.sub_system_guid },
|
|||
|
{ "@device_number", deviceSubscrip.device_number },
|
|||
|
{ "@name", point_name}
|
|||
|
};
|
|||
|
|
|||
|
insertDics2.Add(insertDic);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
List<string> properties2 = insertDics2.First().Keys.ToList();
|
|||
|
string sql2 = InsertGenerateString(properties2, "ontime_device_subscription");
|
|||
|
conn.Execute(sql2, insertDics2, trans);
|
|||
|
final_device_subscrip = insertDics2;
|
|||
|
break;
|
|||
|
|
|||
|
case "delete": //軟刪除
|
|||
|
//找出原本的
|
|||
|
object delete_device_item_guid = null;
|
|||
|
var has_delete_device_item_guid = targetData.TryGetValue("device_item_guid", out delete_device_item_guid);
|
|||
|
|
|||
|
if (has_delete_device_item_guid)
|
|||
|
{
|
|||
|
var sql_device_item = $@"SELECT points FROM device_item WHERE device_item_guid = @device_item_guid";
|
|||
|
var delete_device_point_name = conn.QueryFirst<string>(sql_device_item, new { device_item_guid = delete_device_item_guid.ToString() });
|
|||
|
|
|||
|
//刪除訂閱表的資料
|
|||
|
var purge_for_delete_sql = $@"DELETE FROM ontime_device_subscription WHERE name=@name AND device_number IN @device_number";
|
|||
|
conn.Execute(purge_for_delete_sql, new { name = delete_device_point_name, device_number = deviceSubscrips.Select(x => x.device_number).ToList() }, trans);
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#region step 2 設定要訂閱的設備點位
|
|||
|
var subscripUriFormat = @" <uri val='/obix/config/Arena/{0}/{1}/{2}/out/' />";
|
|||
|
|
|||
|
List<string> subscripStrings = new List<string>();
|
|||
|
|
|||
|
foreach (var deviceSubscrip in final_device_subscrip)
|
|||
|
{
|
|||
|
List<string> devicePaths = new List<string>();
|
|||
|
|
|||
|
object device_number = null;
|
|||
|
var has_device_number = deviceSubscrip.TryGetValue("@device_number", out device_number);
|
|||
|
|
|||
|
//拆解設備編號來組出路徑
|
|||
|
var deviceSubscripSplit = device_number.ToString().Split("_");
|
|||
|
foreach (var temp in deviceSubscripSplit)
|
|||
|
{
|
|||
|
if (temp[0].ToString().All(char.IsDigit))
|
|||
|
{
|
|||
|
devicePaths.Add($"$3{temp}");
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
devicePaths.Add(temp);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//剔除最後一個,因為是設備名稱
|
|||
|
devicePaths.RemoveAt(devicePaths.Count() - 1);
|
|||
|
|
|||
|
object point_name = null;
|
|||
|
var has_point_name = deviceSubscrip.TryGetValue("@name", out point_name);
|
|||
|
|
|||
|
subscripStrings.Add(string.Format(subscripUriFormat, string.Join('/', devicePaths), device_number.ToString(), point_name.ToString()));
|
|||
|
}
|
|||
|
|
|||
|
#endregion step 2 設定要訂閱的設備點位
|
|||
|
|
|||
|
#region step 3 訂閱設備點位,並將回傳的值新增至資料庫
|
|||
|
EDFunction ed = new EDFunction();
|
|||
|
|
|||
|
string userName = ed.AESDecrypt(_obixApiConfig.Value.UserName);
|
|||
|
string password = ed.AESDecrypt(_obixApiConfig.Value.Password);
|
|||
|
|
|||
|
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(userName + ":" + password));
|
|||
|
|
|||
|
var sql_watch = $@"SELECT * FROM variable WHERE deleted = 0 AND system_type = @system_type AND system_key = @system_key";
|
|||
|
|
|||
|
var watch = conn.QueryFirstOrDefault<Variable>(sql_watch, new { system_type = "obixConfig", system_key = "watch_id" });
|
|||
|
|
|||
|
HttpWebRequest addWatchServiceRequest = (HttpWebRequest)WebRequest.Create($"{_obixApiConfig.Value.ApiBase}obix/watchService/watch{watch.system_value}/add/");
|
|||
|
addWatchServiceRequest.Method = "POST";
|
|||
|
addWatchServiceRequest.Headers.Add("Authorization", "Basic " + encoded);
|
|||
|
addWatchServiceRequest.PreAuthenticate = true;
|
|||
|
|
|||
|
var subscripFullString = $@"<obj is='obix: WatchIn'>
|
|||
|
<list names = 'hrefs'>
|
|||
|
{string.Join(null, subscripStrings)}
|
|||
|
</list>
|
|||
|
</obj>";
|
|||
|
byte[] byteArray = Encoding.UTF8.GetBytes(subscripFullString);
|
|||
|
using (Stream reqStream = addWatchServiceRequest.GetRequestStream())
|
|||
|
{
|
|||
|
reqStream.Write(byteArray, 0, byteArray.Length);
|
|||
|
}
|
|||
|
|
|||
|
HttpWebResponse addWatchServiceResponse = (HttpWebResponse)addWatchServiceRequest.GetResponse();
|
|||
|
var addWatchServiceResponseContent = new StreamReader(addWatchServiceResponse.GetResponseStream()).ReadToEnd();
|
|||
|
|
|||
|
XmlDocument xmlDocument = new XmlDocument();
|
|||
|
xmlDocument.LoadXml(addWatchServiceResponseContent);
|
|||
|
string addWatchServiceJson = JsonConvert.SerializeXmlNode(xmlDocument);
|
|||
|
JObject addWatchServiceJsonResult = (JObject)JsonConvert.DeserializeObject(addWatchServiceJson);
|
|||
|
|
|||
|
if (addWatchServiceJsonResult.ContainsKey("err")) //抓取錯誤
|
|||
|
{
|
|||
|
throw new NotImplementedException("設備點位訂閱失敗");
|
|||
|
|
|||
|
//logger.LogError("【OnTimeDeviceRawDataJob】【設備點位訂閱失敗】");
|
|||
|
//logger.LogError("【OnTimeDeviceRawDataJob】【設備點位訂閱失敗】[錯誤內容]:{0}", addWatchServiceJsonResult);
|
|||
|
}
|
|||
|
|
|||
|
if (addWatchServiceJsonResult.ContainsKey("obj")) //表示可以讀取到內容
|
|||
|
{
|
|||
|
List<Dictionary<string, object>> ontimeRawDatas = new List<Dictionary<string, object>>();
|
|||
|
|
|||
|
var ontimeList = addWatchServiceJsonResult["obj"]["list"];
|
|||
|
if (ontimeList["real"] != null && ontimeList["real"].HasValues)
|
|||
|
{
|
|||
|
//讀取數值型
|
|||
|
foreach (var real in ontimeList["real"])
|
|||
|
{
|
|||
|
var valueSplit = real["@display"].ToString().Split();
|
|||
|
var value = valueSplit[0];
|
|||
|
var href = real["@href"].ToString();
|
|||
|
var hrefSplit = href.Split("/");
|
|||
|
var findOutIndex = 0;
|
|||
|
var outIndex = 0;
|
|||
|
foreach (var tempHref in hrefSplit) //找出out的Index
|
|||
|
{
|
|||
|
if (tempHref == "out")
|
|||
|
{
|
|||
|
outIndex = findOutIndex;
|
|||
|
}
|
|||
|
findOutIndex++;
|
|||
|
}
|
|||
|
|
|||
|
var device_number = hrefSplit[outIndex - 2]; //透過outIndex找出設備編號
|
|||
|
var name = hrefSplit[outIndex - 1];//透過outIndex找出點位
|
|||
|
|
|||
|
var selectDevice = tempDeviceSubscrips.Where(x => x.device_number == device_number).FirstOrDefault();
|
|||
|
|
|||
|
Dictionary<string, object> ontimeRawData = new Dictionary<string, object>()
|
|||
|
{
|
|||
|
{ "@building_guid", selectDevice.building_guid },
|
|||
|
{ "@main_system_guid", selectDevice.main_system_guid },
|
|||
|
{ "@sub_system_guid", selectDevice.sub_system_guid },
|
|||
|
{ "@device_number", device_number},
|
|||
|
{ "@name", name},
|
|||
|
{ "@value", value},
|
|||
|
{ "@is_bool", 0},
|
|||
|
};
|
|||
|
|
|||
|
ontimeRawDatas.Add(ontimeRawData);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (ontimeList["bool"] != null && ontimeList["bool"].HasValues)
|
|||
|
{
|
|||
|
//讀取布林型
|
|||
|
foreach (var real in ontimeList["bool"])
|
|||
|
{
|
|||
|
var valueSplit = real["@display"].ToString().Split();
|
|||
|
var value = valueSplit[0];
|
|||
|
var href = real["@href"].ToString();
|
|||
|
var hrefSplit = href.Split("/");
|
|||
|
var findOutIndex = 0;
|
|||
|
var outIndex = 0;
|
|||
|
foreach (var tempHref in hrefSplit) //找出out的Index
|
|||
|
{
|
|||
|
if (tempHref == "out")
|
|||
|
{
|
|||
|
outIndex = findOutIndex;
|
|||
|
}
|
|||
|
findOutIndex++;
|
|||
|
}
|
|||
|
|
|||
|
var device_number = hrefSplit[outIndex - 2]; //透過outIndex找出設備編號
|
|||
|
var name = hrefSplit[outIndex - 1];//透過outIndex找出點位
|
|||
|
|
|||
|
var selectDevice = tempDeviceSubscrips.Where(x => x.device_number == device_number).FirstOrDefault();
|
|||
|
|
|||
|
Dictionary<string, object> ontimeRawData = new Dictionary<string, object>()
|
|||
|
{
|
|||
|
{ "@building_guid", selectDevice.building_guid },
|
|||
|
{ "@main_system_guid", selectDevice.main_system_guid },
|
|||
|
{ "@sub_system_guid", selectDevice.sub_system_guid },
|
|||
|
{ "@device_number", device_number},
|
|||
|
{ "@name", name},
|
|||
|
{ "@value", value},
|
|||
|
{ "@is_bool", 1},
|
|||
|
};
|
|||
|
|
|||
|
ontimeRawDatas.Add(ontimeRawData);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (ontimeRawDatas.Count() > 0)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
var insert_update_sql = $@"INSERT INTO ontime_device_rawdata (building_guid, main_system_guid, sub_system_guid, device_number, name, value, is_bool) VALUES(@building_guid, @main_system_guid, @sub_system_guid, @device_number, @name, @value, @is_bool)
|
|||
|
ON DUPLICATE KEY UPDATE value=@value, is_bool = @is_bool";
|
|||
|
conn.Execute(insert_update_sql, ontimeRawDatas);
|
|||
|
}
|
|||
|
catch (Exception exception)
|
|||
|
{
|
|||
|
throw new NotImplementedException("新增設備點位原始資料失敗", exception);
|
|||
|
|
|||
|
//logger.LogError("【OnTimeDeviceSubscriptionJob】【新增設備點位原始資料失敗】");
|
|||
|
//logger.LogError("【OnTimeDeviceSubscriptionJob】【新增設備點位原始資料失敗】[Exception]:{0}", exception.ToString());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//logger.LogInformation("【OnTimeDeviceSubscriptionJob】【任務完成】");
|
|||
|
}
|
|||
|
|
|||
|
#endregion step 3 訂閱設備點位,並將回傳的值新增至資料庫
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 維護多筆的設備點位訂閱表
|
|||
|
/// </summary>
|
|||
|
/// <param name="targetTable"></param>
|
|||
|
/// <param name="mode"></param>
|
|||
|
/// <param name="targetDataList"></param>
|
|||
|
public void MaintainMutiOntimeDeviceSubscription(string targetTable, List<Dictionary<string, object>> targetDataList)
|
|||
|
{
|
|||
|
//只有新增設備時,會有多筆
|
|||
|
if (targetTable == "device")
|
|||
|
{
|
|||
|
List<string> points = new List<string>();
|
|||
|
// step 1 找出所有該系統小類的點位
|
|||
|
var sql_points = $@"SELECT points FROM device_item WHERE deleted = 0 AND sub_system_guid = @sub_system_guid";
|
|||
|
object sub_system_guid = null;
|
|||
|
var has_value = targetDataList.First().TryGetValue("@sub_system_guid", out sub_system_guid);
|
|||
|
|
|||
|
points = conn.Query<string>(sql_points, new { sub_system_guid = sub_system_guid.ToString() }).ToList();
|
|||
|
|
|||
|
List<Dictionary<string, object>> insertDics = new List<Dictionary<string, object>>();
|
|||
|
List<DeviceSubscrip> tempDeviceSubscrips = new List<DeviceSubscrip>();
|
|||
|
foreach (var targetData in targetDataList)
|
|||
|
{
|
|||
|
object device_number = null;
|
|||
|
var has_device_number_value = targetData.TryGetValue("@device_number", out device_number);
|
|||
|
if (has_device_number_value)
|
|||
|
{
|
|||
|
object building_guid = null;
|
|||
|
targetData.TryGetValue("@building_guid", out building_guid);
|
|||
|
object main_system_guid = null;
|
|||
|
targetData.TryGetValue("@main_system_guid", out main_system_guid);
|
|||
|
object local_sub_system_guid = null;
|
|||
|
targetData.TryGetValue("@sub_system_guid", out local_sub_system_guid);
|
|||
|
|
|||
|
|
|||
|
foreach (var point in points)
|
|||
|
{
|
|||
|
Dictionary<string, object> insertDic = new Dictionary<string, object>()
|
|||
|
{
|
|||
|
{ "@building_guid", building_guid },
|
|||
|
{ "@main_system_guid", main_system_guid },
|
|||
|
{ "@sub_system_guid", local_sub_system_guid },
|
|||
|
{ "@device_number", device_number },
|
|||
|
{ "@name", point}
|
|||
|
};
|
|||
|
|
|||
|
insertDics.Add(insertDic);
|
|||
|
|
|||
|
DeviceSubscrip deviceSubscrip = new DeviceSubscrip()
|
|||
|
{
|
|||
|
building_guid = building_guid.ToString(),
|
|||
|
main_system_guid = main_system_guid.ToString(),
|
|||
|
sub_system_guid = local_sub_system_guid.ToString(),
|
|||
|
device_number = device_number.ToString(),
|
|||
|
};
|
|||
|
|
|||
|
tempDeviceSubscrips.Add(deviceSubscrip);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
List<string> properties = insertDics.First().Keys.ToList();
|
|||
|
string sql = InsertGenerateString(properties, "ontime_device_subscription");
|
|||
|
conn.Execute(sql, insertDics, trans);
|
|||
|
|
|||
|
#region step 2 設定要訂閱的設備點位
|
|||
|
var subscripUriFormat = @" <uri val='/obix/config/Arena/{0}/{1}/{2}/out/' />";
|
|||
|
|
|||
|
List<string> subscripStrings = new List<string>();
|
|||
|
|
|||
|
foreach (var deviceSubscrip in insertDics)
|
|||
|
{
|
|||
|
List<string> devicePaths = new List<string>();
|
|||
|
|
|||
|
object device_number = null;
|
|||
|
var has_device_number = deviceSubscrip.TryGetValue("@device_number", out device_number);
|
|||
|
|
|||
|
//拆解設備編號來組出路徑
|
|||
|
var deviceSubscripSplit = device_number.ToString().Split("_");
|
|||
|
foreach (var temp in deviceSubscripSplit)
|
|||
|
{
|
|||
|
if (temp[0].ToString().All(char.IsDigit))
|
|||
|
{
|
|||
|
devicePaths.Add($"$3{temp}");
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
devicePaths.Add(temp);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//剔除最後一個,因為是設備名稱
|
|||
|
devicePaths.RemoveAt(devicePaths.Count() - 1);
|
|||
|
|
|||
|
object point_name = null;
|
|||
|
var has_point_name = deviceSubscrip.TryGetValue("@name", out point_name);
|
|||
|
|
|||
|
subscripStrings.Add(string.Format(subscripUriFormat, string.Join('/', devicePaths), device_number.ToString(), point_name.ToString()));
|
|||
|
}
|
|||
|
|
|||
|
#endregion step 2 設定要訂閱的設備點位
|
|||
|
|
|||
|
#region step 3 訂閱設備點位,並將回傳的值新增至資料庫
|
|||
|
EDFunction ed = new EDFunction();
|
|||
|
|
|||
|
string userName = ed.AESDecrypt(_obixApiConfig.Value.UserName);
|
|||
|
string password = ed.AESDecrypt(_obixApiConfig.Value.Password);
|
|||
|
|
|||
|
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(userName + ":" + password));
|
|||
|
|
|||
|
var sql_watch = $@"SELECT * FROM variable WHERE deleted = 0 AND system_type = @system_type AND system_key = @system_key";
|
|||
|
|
|||
|
var watch = conn.QueryFirstOrDefault<Variable>(sql_watch, new { system_type = "obixConfig", system_key = "watch_id" });
|
|||
|
|
|||
|
HttpWebRequest addWatchServiceRequest = (HttpWebRequest)WebRequest.Create($"{_obixApiConfig.Value.ApiBase}obix/watchService/watch{watch.system_value}/add/");
|
|||
|
addWatchServiceRequest.Method = "POST";
|
|||
|
addWatchServiceRequest.Headers.Add("Authorization", "Basic " + encoded);
|
|||
|
addWatchServiceRequest.PreAuthenticate = true;
|
|||
|
|
|||
|
var subscripFullString = $@"<obj is='obix: WatchIn'>
|
|||
|
<list names = 'hrefs'>
|
|||
|
{string.Join(null, subscripStrings)}
|
|||
|
</list>
|
|||
|
</obj>";
|
|||
|
byte[] byteArray = Encoding.UTF8.GetBytes(subscripFullString);
|
|||
|
using (Stream reqStream = addWatchServiceRequest.GetRequestStream())
|
|||
|
{
|
|||
|
reqStream.Write(byteArray, 0, byteArray.Length);
|
|||
|
}
|
|||
|
|
|||
|
HttpWebResponse addWatchServiceResponse = (HttpWebResponse)addWatchServiceRequest.GetResponse();
|
|||
|
var addWatchServiceResponseContent = new StreamReader(addWatchServiceResponse.GetResponseStream()).ReadToEnd();
|
|||
|
|
|||
|
XmlDocument xmlDocument = new XmlDocument();
|
|||
|
xmlDocument.LoadXml(addWatchServiceResponseContent);
|
|||
|
string addWatchServiceJson = JsonConvert.SerializeXmlNode(xmlDocument);
|
|||
|
JObject addWatchServiceJsonResult = (JObject)JsonConvert.DeserializeObject(addWatchServiceJson);
|
|||
|
|
|||
|
if (addWatchServiceJsonResult.ContainsKey("err")) //抓取錯誤
|
|||
|
{
|
|||
|
throw new NotImplementedException("設備點位訂閱失敗");
|
|||
|
|
|||
|
//logger.LogError("【OnTimeDeviceRawDataJob】【設備點位訂閱失敗】");
|
|||
|
//logger.LogError("【OnTimeDeviceRawDataJob】【設備點位訂閱失敗】[錯誤內容]:{0}", addWatchServiceJsonResult);
|
|||
|
}
|
|||
|
|
|||
|
if (addWatchServiceJsonResult.ContainsKey("obj")) //表示可以讀取到內容
|
|||
|
{
|
|||
|
List<Dictionary<string, object>> ontimeRawDatas = new List<Dictionary<string, object>>();
|
|||
|
|
|||
|
var ontimeList = addWatchServiceJsonResult["obj"]["list"];
|
|||
|
if (ontimeList["real"] != null && ontimeList["real"].HasValues)
|
|||
|
{
|
|||
|
//讀取數值型
|
|||
|
foreach (var real in ontimeList["real"])
|
|||
|
{
|
|||
|
var valueSplit = real["@display"].ToString().Split();
|
|||
|
var value = valueSplit[0];
|
|||
|
var href = real["@href"].ToString();
|
|||
|
var hrefSplit = href.Split("/");
|
|||
|
var findOutIndex = 0;
|
|||
|
var outIndex = 0;
|
|||
|
foreach (var tempHref in hrefSplit) //找出out的Index
|
|||
|
{
|
|||
|
if (tempHref == "out")
|
|||
|
{
|
|||
|
outIndex = findOutIndex;
|
|||
|
}
|
|||
|
findOutIndex++;
|
|||
|
}
|
|||
|
|
|||
|
var device_number = hrefSplit[outIndex - 2]; //透過outIndex找出設備編號
|
|||
|
var name = hrefSplit[outIndex - 1];//透過outIndex找出點位
|
|||
|
|
|||
|
var selectDevice = tempDeviceSubscrips.Where(x => x.device_number == device_number).FirstOrDefault();
|
|||
|
|
|||
|
Dictionary<string, object> ontimeRawData = new Dictionary<string, object>()
|
|||
|
{
|
|||
|
{ "@building_guid", selectDevice.building_guid },
|
|||
|
{ "@main_system_guid", selectDevice.main_system_guid },
|
|||
|
{ "@sub_system_guid", selectDevice.sub_system_guid },
|
|||
|
{ "@device_number", device_number},
|
|||
|
{ "@name", name},
|
|||
|
{ "@value", value},
|
|||
|
{ "@is_bool", 0},
|
|||
|
};
|
|||
|
|
|||
|
ontimeRawDatas.Add(ontimeRawData);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (ontimeList["bool"] != null && ontimeList["bool"].HasValues)
|
|||
|
{
|
|||
|
//讀取布林型
|
|||
|
foreach (var real in ontimeList["bool"])
|
|||
|
{
|
|||
|
var valueSplit = real["@display"].ToString().Split();
|
|||
|
var value = valueSplit[0];
|
|||
|
var href = real["@href"].ToString();
|
|||
|
var hrefSplit = href.Split("/");
|
|||
|
var findOutIndex = 0;
|
|||
|
var outIndex = 0;
|
|||
|
foreach (var tempHref in hrefSplit) //找出out的Index
|
|||
|
{
|
|||
|
if (tempHref == "out")
|
|||
|
{
|
|||
|
outIndex = findOutIndex;
|
|||
|
}
|
|||
|
findOutIndex++;
|
|||
|
}
|
|||
|
|
|||
|
var device_number = hrefSplit[outIndex - 2]; //透過outIndex找出設備編號
|
|||
|
var name = hrefSplit[outIndex - 1];//透過outIndex找出點位
|
|||
|
|
|||
|
var selectDevice = tempDeviceSubscrips.Where(x => x.device_number == device_number).FirstOrDefault();
|
|||
|
|
|||
|
Dictionary<string, object> ontimeRawData = new Dictionary<string, object>()
|
|||
|
{
|
|||
|
{ "@building_guid", selectDevice.building_guid },
|
|||
|
{ "@main_system_guid", selectDevice.main_system_guid },
|
|||
|
{ "@sub_system_guid", selectDevice.sub_system_guid },
|
|||
|
{ "@device_number", device_number},
|
|||
|
{ "@name", name},
|
|||
|
{ "@value", value},
|
|||
|
{ "@is_bool", 1},
|
|||
|
};
|
|||
|
|
|||
|
ontimeRawDatas.Add(ontimeRawData);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (ontimeRawDatas.Count() > 0)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
var insert_update_sql = $@"INSERT INTO ontime_device_rawdata (building_guid, main_system_guid, sub_system_guid, device_number, name, value, is_bool) VALUES(@building_guid, @main_system_guid, @sub_system_guid, @device_number, @name, @value, @is_bool)
|
|||
|
ON DUPLICATE KEY UPDATE value=@value, is_bool = @is_bool";
|
|||
|
conn.Execute(insert_update_sql, ontimeRawDatas);
|
|||
|
}
|
|||
|
catch (Exception exception)
|
|||
|
{
|
|||
|
throw new NotImplementedException("新增設備點位原始資料失敗", exception);
|
|||
|
|
|||
|
//logger.LogError("【OnTimeDeviceSubscriptionJob】【新增設備點位原始資料失敗】");
|
|||
|
//logger.LogError("【OnTimeDeviceSubscriptionJob】【新增設備點位原始資料失敗】[Exception]:{0}", exception.ToString());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//logger.LogInformation("【OnTimeDeviceSubscriptionJob】【任務完成】");
|
|||
|
}
|
|||
|
|
|||
|
#endregion step 3 訂閱設備點位,並將回傳的值新增至資料庫
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|