2023-09-20 17:32:03 +08:00
using FrontendWebApi.Models ;
using Microsoft.AspNetCore.Mvc ;
using Microsoft.Extensions.Logging ;
using Newtonsoft.Json ;
using NPOI.SS.UserModel ;
using NPOI.XSSF.UserModel ;
using Repository.FrontendRepository.Interface ;
using System ;
using System.Collections.Generic ;
using System.IO ;
using System.Linq ;
using System.Net.Http ;
using System.Text ;
using System.Threading.Tasks ;
using System.Xml ;
using System.Xml.Linq ;
namespace FrontendWebApi.ApiControllers
{
/// <summary>
/// 告警紀錄
/// </summary>
public class AlarmController : MyBaseApiController < AlarmRecordController >
{
private readonly IFrontendRepository frontendRepository ;
public AlarmController
(
IFrontendRepository frontendRepository
)
{
this . frontendRepository = frontendRepository ;
}
[HttpPost]
[Route("api/Alarm/GetAlarmFromObix")]
public async Task < ActionResult < ApiResult < AlarmObj > > > GetAlarmFromObix ( )
{
ApiResult < AlarmObj > apiResult = new ApiResult < AlarmObj > ( jwt_str ) ;
if ( ! jwtlife )
{
apiResult . Code = "5000" ;
return BadRequest ( apiResult ) ;
}
try
{
var sqlString = $@"SELECT system_value FROM variable WHERE system_type = 'obixConfig' AND system_key = 'ApiBase' AND deleted = 0" ;
string baseApiUrl = await frontendRepository . GetOneAsync < string > ( sqlString ) ;
if ( string . IsNullOrEmpty ( baseApiUrl ) )
{
apiResult . Code = "9998" ;
apiResult . Msg = "未找到 obixConfig baseAPI, 請聯絡管理者。" ;
return BadRequest ( apiResult ) ;
}
2023-10-27 18:14:07 +08:00
sqlString = $@"SELECT system_value FROM variable WHERE system_type = 'emergencyConfig' AND system_key = 'getNiagaraAlarmMoveDayNumStart' AND deleted = 0" ;
int moveDayNum = int . Parse ( ( await frontendRepository . GetOneAsync < string > ( sqlString ) ) ? ? "-1" ) ;
2023-09-20 17:32:03 +08:00
string apiUrl = Path . Combine ( baseApiUrl , "obix/config/Services/AlarmService/~alarmQuery/" ) ;
using ( HttpClient client = new HttpClient ( ) )
{
2024-10-25 17:47:38 +08:00
var sqlObix = $@"SELECT system_value as Value, system_key as Name FROM variable WHERE deleted = 0 AND system_type = 'obixConfig'" ;
var variableObix = frontendRepository . GetAllAsync < KeyValue > ( sqlObix ) . Result ;
string username = variableObix . Where ( x = > x . Name = = "UserName" ) . Select ( x = > x . Value ) . FirstOrDefault ( ) ;
string password = variableObix . Where ( x = > x . Name = = "Password" ) . Select ( x = > x . Value ) . FirstOrDefault ( ) ;
2023-09-20 17:32:03 +08:00
string encoded = Convert . ToBase64String ( System . Text . Encoding . GetEncoding ( "ISO-8859-1" ) . GetBytes ( username + ":" + password ) ) ;
client . DefaultRequestHeaders . Add ( "Authorization" , "Basic " + encoded ) ;
// 建構 XML 數據
string xmlData = @ $ "<obj href='obix:AlarmFilter'>
2023-10-27 18:14:07 +08:00
< abstime name = ' start ' val = ' { DateTime . Now . AddDays ( moveDayNum ) . ToString ( "yyyy-MM-ddTHH:mm:ss.fff" ) } + 08 : 00 ' / >
2023-09-20 17:32:03 +08:00
< abstime name = ' end ' val = ' { DateTime . Now . ToString ( "yyyy-MM-ddTHH:mm:ss.fff" ) } + 08 : 00 ' / >
< / obj > ";
HttpContent content = new StringContent ( xmlData , Encoding . UTF8 , "application/xml" ) ;
var response = await client . PostAsync ( apiUrl , content ) ;
var resString = ( await response . Content . ReadAsStringAsync ( ) ) . ToString ( ) ;
XDocument xmlDoc = XDocument . Parse ( resString ) ;
/ * 回 傳 結 果 範 例
< ? xml version = "1.0" encoding = "UTF-8" ? >
< ? xml - stylesheet type = ' text / xsl ' href = ' / obix / xsl ' ? >
< obj is = "obix:AlarmQueryOut" xmlns = "http://obix.org/ns/schema/1.0" xsi : schemaLocation = "http://obix.org/ns/schema/1.0 /obix/xsd" xmlns : xsi = "http://www.w3.org/2001/XMLSchema-instance" >
< list name = "data" of = "obix:Alarm" >
< obj href = "/obix/alarm/3378ed4a-94ff-4aca-b857-ff66083b9131" is = "obix:Alarm obix:AckAlarm obix:PointAlarm obix:StatefulAlarm" display = "" >
. . . .
< str name = "sourceName" val = "H_E1_B1F_MVCB_MVCBH_ER" / >
< abstime name = "timestamp" val = "2023-08-08T10:30:04.473+08:00" tz = "Asia/Taipei" / >
. . . .
< / obj >
< obj href = "/obix/alarm/f6116713-9830-4e7d-aa10-a28db29d0edc" is = "obix:Alarm obix:AckAlarm obix:PointAlarm obix:StatefulAlarm" display = "" >
. . . .
< str name = "sourceName" val = "H_E1_B1F_MVCB_MVCBH_ER" / >
< abstime name = "timestamp" val = "2023-08-08T10:50:00.953+08:00" tz = "Asia/Taipei" / >
. . . .
< / obj >
< / list >
< / obj >
* /
var list = xmlDoc . Descendants ( ) . Where ( d = > d . Name ? . LocalName = = "list" ) . FirstOrDefault ( ) ;
var objs = list . Descendants ( ) . Where ( d = > d . Name ? . LocalName = = "obj" & & ( d . Attribute ( "is" ) ? . Value ? . Contains ( "obix:Alarm" ) ? ? false ) ) . ToList ( ) ;
// 宣告要丟出去的資料容器
AlarmObj alarmObj = new AlarmObj ( )
{
alarmorion = new List < AlarmorionString > ( ) ,
buildingAlarmDeviceAmount = new List < BuildingAlarmDeviceAmount > ( )
} ;
// 篩選 toState != normal
objs = objs . Where ( d = > d . Descendants ( ) . Any ( dd = > dd ? . Name ? . LocalName = = "str" & & dd ? . Attribute ( "name" ) ? . Value = = "toState" & & dd ? . Attribute ( "val" ) ? . Value ! = "normal" ) ) . ToList ( ) ;
// <str name="sourceName" val="H_E1_B1F_MVCB_MVCBH_ER"/>
// <abstime name="timestamp" val="2023-08-08T10:30:04.473+08:00" tz="Asia/Taipei"/>
alarmObj . alarmorion = objs . Select ( obj = > new AlarmorionString ( )
{
alarm_timestamp = obj . Descendants ( ) . Where ( d = > d . Name . LocalName = = "abstime" & & d . Attribute ( "name" ) . Value = = "timestamp" )
. Select ( d = >
{
DateTime valid ;
if ( DateTime . TryParse ( d . Attribute ( "val" ) . Value , out valid ) )
{
2024-06-12 16:29:20 +08:00
return DateTime . Parse ( d . Attribute ( "val" ) . Value ) . ToString ( "yyyy-MM-dd HH:mm:ss" ) ;
2023-09-20 17:32:03 +08:00
}
else
{
return null ;
}
} ) . FirstOrDefault ( ) ,
device_number = obj . Descendants ( ) . Where ( d = > d . Name . LocalName = = "str" & & d . Attribute ( "name" ) . Value = = "sourceName" )
. Select ( d = > d . Attribute ( "val" ) . Value ) . Select ( d = > string . Join ( "_" , d . Split ( "_" ) . Take ( 5 ) ) ) . FirstOrDefault ( ) ,
} ) . ToList ( ) ;
// obix alarm 回傳 device_number + point 取出棟別分組
2023-09-21 10:01:12 +08:00
// 20230920 - 佳豪表示棟別按鈕不顯示數量
//alarmObj.buildingAlarmDeviceAmount = alarmObj.alarmorion.Where(a => a.device_number?.Contains("_") ?? false)
// .GroupBy(g => g.device_number.Split("_")[0]).Select(g => new BuildingAlarmDeviceAmount()
//{
// building_tag = g.Key,
// device_amount = g.Count()
//}).ToList();
2023-09-20 17:32:03 +08:00
apiResult . Data = alarmObj ;
}
apiResult . Msg = "讀取成功" ;
apiResult . Code = "0000" ;
}
catch ( Exception exception )
{
apiResult . Code = "9999" ;
apiResult . Msg = "系統內部錯誤,請聯絡管理者。" ;
Logger . LogError ( "【" + controllerName + "/" + actionName + "】" + exception . Message ) ;
return Ok ( apiResult ) ;
}
return Ok ( apiResult ) ;
}
}
}