This commit is contained in:
dev01 2022-11-11 17:39:49 +08:00
commit 84eecefd2d
5 changed files with 223 additions and 31 deletions

96
Backend/N4v1021.xml Normal file
View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type='text/xsl' href='/obix/xsl'?>
<obj display="Component" 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">
<str name="res" val="/TPE/B1/EE/E4/R2F/NA/WHT/N1/V1/" href="res/" />
<str name="res1" val="/TPE/B1/EE/E4/R2F/NA/WHT/N1/V2/" href="res1/" />
<str name="res2" val="/TPE/B1/EE/E4/R2F/NA/WHT/N1/V3/" href="res2/" />
<str name="res3" val="/TPE/B1/EE/E4/R2F/NA/WHT/N1/A1/" href="res3/" />
<str name="res4" val="/TPE/B1/EE/E4/R2F/NA/WHT/N1/A2/" href="res4/" />
<str name="res5" val="/TPE/B1/EE/E4/R2F/NA/WHT/N1/A3/" href="res5/" />
<str name="res6" val="/TPE/B1/EE/E4/R2F/NA/WHT/N1/P/" href="res6/" />
<str name="res7" val="/TPE/B1/EE/E4/R2F/NA/WHT/N1/Q/" href="res7/" />
<str name="res8" val="/TPE/B1/EE/E4/R2F/NA/WHT/N1/KWH/" href="res8/" />
<str name="res9" val="/TPE/B1/EE/E4/R2F/NA/WHT/N1/KVARH/" href="res9/" />
<str name="res10" val="/TPE/B1/EE/E4/R2F/NA/WHT/N1/F/" href="res10/" />
<str name="res11" val="/TPE/B1/EE/E4/R2F/NA/WHT/N1/PF/" href="res11/" />
<str name="res12" val="/TPE/B1/LT/L1/U1F/NA/EHL/N1/SSC/" href="res12/" />
<str name="res13" val="/TPE/B1/LT/L1/U1F/NA/EHL/N1/ST/" href="res13/" />
<str name="res14" val="/TPE/B1/LT/L1/U1F/NA/EHL/N2/SSC/" href="res14/" />
<str name="res15" val="/TPE/B1/LT/L1/U1F/NA/EHL/N2/ST/" href="res15/" />
<str name="res16" val="/TPE/B1/LT/L1/U1F/NA/EHL/N3/SSC/" href="res16/" />
<str name="res17" val="/TPE/B1/LT/L1/U1F/NA/EHL/N3/ST/" href="res17/" />
<str name="res18" val="/TPE/B1/ME/M10/U1F/NA/FCU/N1/SP_SSC/" href="res18/" />
<str name="res19" val="/TPE/B1/ME/M10/U1F/NA/FCU/N1/SP_MD/" href="res19/" />
<str name="res20" val="/TPE/B1/ME/M10/U1F/NA/FCU/N1/SP_Temp/" href="res20/" />
<str name="res21" val="/TPE/B1/ME/M10/U1F/NA/FCU/N1/SP_AF/" href="res21/" />
<str name="res22" val="/TPE/B1/ME/M10/U1F/NA/FCU/N1/SP_AD/" href="res22/" />
<str name="res23" val="/TPE/B1/ME/M10/U1F/NA/FCU/N1/Temp/" href="res23/" />
<str name="res24" val="/TPE/B1/ME/M10/U1F/NA/FCU/N1/AL/" href="res24/" />
<str name="res25" val="/TPE/B1/ME/M10/U1F/NA/FCU/N1/SSC/" href="res25/" />
<str name="res26" val="/TPE/B1/ME/M10/U1F/NA/FCU/N1/STA_MD/" href="res26/" />
<str name="res27" val="/TPE/B1/ME/M10/U1F/NA/FCU/N1/ST/" href="res27/" />
<str name="res28" val="/TPE/B1/ME/M10/U1F/NA/FCU/N2/SP_SSC/" href="res28/" />
<str name="res29" val="/TPE/B1/ME/M10/U1F/NA/FCU/N2/SP_MD/" href="res29/" />
<str name="res30" val="/TPE/B1/ME/M10/U1F/NA/FCU/N2/SP_Temp/" href="res30/" />
<str name="res31" val="/TPE/B1/ME/M10/U1F/NA/FCU/N2/SP_AF/" href="res31/" />
<str name="res32" val="/TPE/B1/ME/M10/U1F/NA/FCU/N2/SP_AD/" href="res32/" />
<str name="res33" val="/TPE/B1/ME/M10/U1F/NA/FCU/N2/Temp/" href="res33/" />
<str name="res34" val="/TPE/B1/ME/M10/U1F/NA/FCU/N2/AL/" href="res34/" />
<str name="res35" val="/TPE/B1/ME/M10/U1F/NA/FCU/N2/SSC/" href="res35/" />
<str name="res36" val="/TPE/B1/ME/M10/U1F/NA/FCU/N2/STA_MD/" href="res36/" />
<str name="res37" val="/TPE/B1/ME/M10/U1F/NA/FCU/N2/ST/" href="res37/" />
<str name="res38" val="/TPE/B1/ME/M10/U1F/NA/FCU/N3/SP_SSC/" href="res38/" />
<str name="res39" val="/TPE/B1/ME/M10/U1F/NA/FCU/N3/SP_MD/" href="res39/" />
<str name="res40" val="/TPE/B1/ME/M10/U1F/NA/FCU/N3/SP_Temp/" href="res40/" />
<str name="res41" val="/TPE/B1/ME/M10/U1F/NA/FCU/N3/SP_AF/" href="res41/" />
<str name="res42" val="/TPE/B1/ME/M10/U1F/NA/FCU/N3/SP_AD/" href="res42/" />
<str name="res43" val="/TPE/B1/ME/M10/U1F/NA/FCU/N3/Temp/" href="res43/" />
<str name="res44" val="/TPE/B1/ME/M10/U1F/NA/FCU/N3/AL/" href="res44/" />
<str name="res45" val="/TPE/B1/ME/M10/U1F/NA/FCU/N3/SSC/" href="res45/" />
<str name="res46" val="/TPE/B1/ME/M10/U1F/NA/FCU/N3/STA_MD/" href="res46/" />
<str name="res47" val="/TPE/B1/ME/M10/U1F/NA/FCU/N3/ST/" href="res47/" />
<str name="res48" val="/TPE/B1/ME/M10/U1F/NA/FCU/N4/SP_SSC/" href="res48/" />
<str name="res49" val="/TPE/B1/ME/M10/U1F/NA/FCU/N4/SP_MD/" href="res49/" />
<str name="res50" val="/TPE/B1/ME/M10/U1F/NA/FCU/N4/SP_Temp/" href="res50/" />
<str name="res51" val="/TPE/B1/ME/M10/U1F/NA/FCU/N4/SP_AF/" href="res51/" />
<str name="res52" val="/TPE/B1/ME/M10/U1F/NA/FCU/N4/SP_AD/" href="res52/" />
<str name="res53" val="/TPE/B1/ME/M10/U1F/NA/FCU/N4/Temp/" href="res53/" />
<str name="res54" val="/TPE/B1/ME/M10/U1F/NA/FCU/N4/AL/" href="res54/" />
<str name="res55" val="/TPE/B1/ME/M10/U1F/NA/FCU/N4/SSC/" href="res55/" />
<str name="res56" val="/TPE/B1/ME/M10/U1F/NA/FCU/N4/STA_MD/" href="res56/" />
<str name="res57" val="/TPE/B1/ME/M10/U1F/NA/FCU/N4/ST/" href="res57/" />
<str name="res58" val="/TPE/B1/ME/M12/R2F/NA/TH/N1/TEMP/" href="res58/" />
<str name="res59" val="/TPE/B1/ME/M12/R2F/NA/TH/N1/RH/" href="res59/" />
<str name="res60" val="/TPE/B1/ME/M12/R2F/NA/TH/N1/Or/" href="res60/" />
<str name="res61" val="/TPE/B1/ME/M12/R2F/NA/TH/N1/TRIP/" href="res61/" />
<str name="res62" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/ST/" href="res62/" />
<str name="res63" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/TRIP/" href="res63/" />
<str name="res64" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/FRC/" href="res64/" />
<str name="res65" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/SP_RCS/" href="res65/" />
<str name="res66" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/SP_RO/" href="res66/" />
<str name="res67" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/SP_FLS_1F/" href="res67/" />
<str name="res68" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/SP_FLS_2F/" href="res68/" />
<str name="res69" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/SP_FLS_3F/" href="res69/" />
<str name="res70" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/SP_FLS_4F/" href="res70/" />
<str name="res71" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/SP_FLS_5F/" href="res71/" />
<str name="res72" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/SP_FLS_6F/" href="res72/" />
<str name="res73" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/SP_FLS_7F/" href="res73/" />
<str name="res74" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/SP_FLS_8F/" href="res74/" />
<str name="res75" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/SP_FLS_9F/" href="res75/" />
<str name="res76" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/SP_FLS_10F/" href="res76/" />
<str name="res77" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/SP_FLS_11F/" href="res77/" />
<str name="res78" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/SP_FLS_12F/" href="res78/" />
<str name="res79" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/SP_FLS_13F/" href="res79/" />
<str name="res80" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/DuringFireemergencyreturnoperation/" href="res80/" />
<str name="res81" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/CompletionofreturnbyFireemergencyreturnoperation/" href="res81/" />
<str name="res82" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/DuringEarthquakeoperation/" href="res82/" />
<str name="res83" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/CompletionofEarthquakeoperation/" href="res83/" />
<str name="res84" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/NormalPowerSupply/" href="res84/" />
<str name="res85" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/Emergencypowersourcedetection/" href="res85/" />
<str name="res86" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/DuringEmergencypowercontroloperation/" href="res86/" />
<str name="res87" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/CompletionofreturnbyEmergencypowercontroloperation/" href="res87/" />
<str name="res88" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/UP/" href="res88/" />
<str name="res89" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/DOWN/" href="res89/" />
<str name="res90" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/DoorState/" href="res90/" />
<str name="res91" val="/TPE/B1/ELEV/EL/R2F/NA/ELEV1/N1/MultiVibrator/" href="res91/" />
</obj>

View File

@ -26,7 +26,7 @@ namespace Backend.Services.Implement
XmlDocument xmlDoc = new XmlDocument(); XmlDocument xmlDoc = new XmlDocument();
//xmlDoc.LoadXml(responseString); //xmlDoc.LoadXml(responseString);
xmlDoc.Load("N4.xml");//N4v1021 xmlDoc.Load("N4v1021.xml");//N4v1021
//xmlDoc.Save("N4.xml"); //xmlDoc.Save("N4.xml");
@ -40,7 +40,24 @@ namespace Backend.Services.Implement
string[] s1 = item.Val.Split(','); string[] s1 = item.Val.Split(',');
string[] s2 = s1[0].Split('/'); string[] s2 = s1[0].Split('/');
foreach (var ss in s2) row.tag_name = "";
for (int i = 0; i < s2.Length; i++)
{
if (i == s2.Length - 2)
{
row.point_name = s2[i];
}
else if (i == 1)
{
row.tag_name += s2[i];
}
else if (i > 1 && i < s2.Length - 2)
{
row.tag_name += "_" + s2[i];
}
}
/*foreach (var ss in s2)
{ {
if (ss.Contains('_')) if (ss.Contains('_'))
{ {
@ -52,7 +69,7 @@ namespace Backend.Services.Implement
break; break;
} }
} }
} }*/
result.Add(row); result.Add(row);
} }

View File

@ -11,6 +11,7 @@ using System.Web;
using Repository.BackendRepository.Interface; using Repository.BackendRepository.Interface;
using Repository.FrontendRepository.Interface; using Repository.FrontendRepository.Interface;
using System.IO; using System.IO;
using static Microsoft.Extensions.Logging.EventSource.LoggingEventSource;
namespace FrontendWebApi.ApiControllers namespace FrontendWebApi.ApiControllers
{ {
@ -99,28 +100,27 @@ namespace FrontendWebApi.ApiControllers
List<GraphList> graManList = new List<GraphList>(); List<GraphList> graManList = new List<GraphList>();
try try
{ {
var sqlString = @$"SELECT gm.* var param = new { @graph_manage_layer1 = graph_manage_layer1, @graph_manage_layer2 = graph_manage_layer2, @sub_system_tag = gi.sub_system_tag, @main_system_tag = gi.main_system_tag };
if (gi.keyWord != null && !string.IsNullOrEmpty(gi.keyWord))
{
graManList = await backendRepository.GetAllAsync<GraphList>(@$"SELECT gm.*
FROM graph_manage gm
JOIN variable v1 ON v1.system_value = @main_system_tag and v1.system_type = @graph_manage_layer1 and v1.deleted = 0 AND convert(v1.system_value, nchar) = gm.main_system_tag
JOIN variable v2 ON v1.id = v2.system_parent_id AND v2.system_type = @graph_manage_layer2 AND v2.deleted = 0 and convert(v2.system_value, nchar) = gm.sub_system_tag
WHERE v2.system_value in @sub_system_tag AND gm.deleted = 0
AND (gm.code like '%{gi.keyWord}%' OR gm.name like '%{gi.keyWord}%' OR gm.oriOrgName like '%{gi.keyWord}%' OR gm.donOrgName like '%{gi.keyWord}%')
ORDER BY gm.priority, gm.created_at desc", param);
}
else
{
var sqlString = @$"SELECT gm.*
FROM graph_manage gm FROM graph_manage gm
JOIN variable v1 ON v1.system_value = @main_system_tag and v1.system_type = @graph_manage_layer1 and v1.deleted = 0 AND convert(v1.system_value, nchar) = gm.main_system_tag JOIN variable v1 ON v1.system_value = @main_system_tag and v1.system_type = @graph_manage_layer1 and v1.deleted = 0 AND convert(v1.system_value, nchar) = gm.main_system_tag
JOIN variable v2 ON v1.id = v2.system_parent_id AND v2.system_type = @graph_manage_layer2 AND v2.deleted = 0 AND convert(v2.system_value, nchar) = gm.sub_system_tag JOIN variable v2 ON v1.id = v2.system_parent_id AND v2.system_type = @graph_manage_layer2 AND v2.deleted = 0 AND convert(v2.system_value, nchar) = gm.sub_system_tag
WHERE v2.system_value in @sub_system_tag AND gm.deleted = 0 WHERE v2.system_value in @sub_system_tag AND gm.deleted = 0
ORDER BY gm.priority, gm.created_at desc"; ORDER BY gm.priority, gm.created_at desc";
graManList = await backendRepository.GetAllAsync<GraphList>(sqlString, param);
var param = new { @graph_manage_layer1 = graph_manage_layer1, graph_manage_layer2 = graph_manage_layer2, @sub_system_tag = gi.sub_system_tag, @main_system_tag = gi.main_system_tag };
graManList = await backendRepository.GetAllAsync<GraphList>(sqlString, param);
if (gi.keyWord != null)
{
var wParam = new { @graph_manage_layer1 = graph_manage_layer1, graph_manage_layer2 = graph_manage_layer2, @sub_system_tag = gi.sub_system_tag, @main_system_tag = gi.main_system_tag, @keyWord = gi.keyWord };
graManList = await backendRepository.GetAllAsync<GraphList>(@$"SELECT gm.*
FROM graph_manage gm
JOIN variable v1 ON v1.system_value = @main_system_tag and v1.system_type = @graph_manage_layer1 and v1.deleted = 0 AND convert(v1.system_value, nchar) = gm.main_system_tag
JOIN variable v2 ON v1.id = v2.system_parent_id AND v2.system_type = @graph_manage_layer2 AND v2.deleted = 0 and convert(v2.system_value, nchar) = gm.sub_system_tag
WHERE v2.system_value in @sub_system_tag AND gm.deleted = 0
AND (code like '%@keyWord%' OR name like '%@keyWord%' OR oriOrgName like '%@keyWord%' OR donOrgName like '%@keyWord%')
ORDER BY gm.priority, gm.created_at desc", wParam);
} }
apiResult.Code = "0000"; apiResult.Code = "0000";

View File

@ -96,22 +96,18 @@ namespace FrontendWebApi.ApiControllers
} }
/// <summary> /// <summary>
/// 大樓列表 /// 地區列表
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<ApiResult<List<BuildingList>>> BuiList() public async Task<ApiResult<List<BuildingList>>> AreaList()
{ {
ApiResult<List<BuildingList>> apiResult = new ApiResult<List<BuildingList>>(); ApiResult<List<BuildingList>> apiResult = new ApiResult<List<BuildingList>>();
List<BuildingList> bl = new List<BuildingList>(); List<BuildingList> bl = new List<BuildingList>();
try try
{ {
var sqlString = @$"select d.device_area_tag, d.device_building_tag, d.device_floor_tag, CONCAT(case when d.device_area_tag='TPE' then '台北市' else '新北市' end, b.full_name, d.device_floor_tag) as full_name var sqlString = @$"select system_key as area_name, system_value as device_area_tag from variable where deleted = 0 and system_type = 'area'";
from device d
join building b on d.device_building_tag = b.building_tag
where d.deleted = 0
group by d.device_area_tag, d.device_building_tag, d.device_floor_tag, b.full_name";
bl = await backendRepository.GetAllAsync<BuildingList>(sqlString); bl = await backendRepository.GetAllAsync<BuildingList>(sqlString);
@ -128,6 +124,71 @@ namespace FrontendWebApi.ApiControllers
return apiResult; return apiResult;
} }
/// <summary>
/// 東別列表
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<List<BuildingList>>> BuiList([FromBody] BuildingList b)
{
ApiResult<List<BuildingList>> apiResult = new ApiResult<List<BuildingList>>();
List<BuildingList> bl = new List<BuildingList>();
try
{
var sqlString = @$"select d.device_building_tag, b.full_name as building_name
from device d
join building b on d.device_building_tag = b.building_tag
where d.deleted = 0 and d.device_area_tag = @device_area_tag
group by b.building_name, d.device_building_tag";
bl = await backendRepository.GetAllAsync<BuildingList>(sqlString, new { @device_area_tag = b.device_area_tag });
apiResult.Code = "0000";
apiResult.Data = bl;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 樓層列表
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<List<BuildingList>>> FloList([FromBody] BuildingList b)
{
ApiResult<List<BuildingList>> apiResult = new ApiResult<List<BuildingList>>();
List<BuildingList> bl = new List<BuildingList>();
try
{
var sqlString = @$"select d.device_floor_tag
from device d
where d.deleted = 0 and d.device_area_tag = @device_area_tag and d.device_building_tag = @device_building_tag
group by d.device_floor_tag";
bl = await backendRepository.GetAllAsync<BuildingList>(sqlString, new { @device_area_tag = b.device_area_tag, @device_building_tag = b.device_building_tag });
apiResult.Code = "0000";
apiResult.Data = bl;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary> /// <summary>
/// 設備列表 /// 設備列表
/// </summary> /// </summary>
@ -141,9 +202,9 @@ namespace FrontendWebApi.ApiControllers
try try
{ {
var sqlString = @$"select device_number, concat(device_floor_tag, ' ', device_last_name, ' ', device_serial_tag) as device_name var sqlString = @$"select device_number, concat(device_floor_tag, ' ', device_last_name, ' ', device_serial_tag) as device_name
from device where deleted = 0 and device_building_tag = @device_building_tag and device_floor_tag = @device_floor_tag"; from device where deleted = 0 and device_area_tag = @device_area_tag and device_building_tag = @device_building_tag and device_floor_tag = @device_floor_tag";
var param = new { @device_building_tag = bl.device_building_tag, @device_floor_tag = bl.device_floor_tag }; var param = new { @device_building_tag = bl.device_building_tag, @device_floor_tag = bl.device_floor_tag, @device_area_tag = bl.device_area_tag };
d = await backendRepository.GetAllAsync<Device>(sqlString, param); d = await backendRepository.GetAllAsync<Device>(sqlString, param);

View File

@ -166,7 +166,7 @@ namespace tpDomeWinAPP.Service
XmlDocument xmlDoc = new XmlDocument(); XmlDocument xmlDoc = new XmlDocument();
//xmlDoc.LoadXml(responseString); //xmlDoc.LoadXml(responseString);
xmlDoc.Load("N4.xml"); xmlDoc.Load("N4v1021.xml");//N4v1021
//xmlDoc.Save("N4.xml"); //xmlDoc.Save("N4.xml");
@ -182,9 +182,26 @@ namespace tpDomeWinAPP.Service
device_value2 row = new device_value2(); device_value2 row = new device_value2();
row.value = item.Val; row.value = item.Val;
string[] s1 = item.Val.Split(','); string[] s1 = item.Val.Split(',');
string[] s2 = s1[0].Split('/'); string[] s2 = s1[0].Split('/');
foreach (var ss in s2) row.tag_name = "";
for (int i = 0; i < s2.Length; i++)
{
if (i == s2.Length - 2)
{
row.point_name = s2[i];
}
else if (i == 1)
{
row.tag_name += s2[i];
}
else if (i > 1 && i < s2.Length - 2)
{
row.tag_name += "_" + s2[i];
}
}
/*foreach (var ss in s2)
{ {
if (ss.Contains('_')) if (ss.Contains('_'))
{ {
@ -208,6 +225,7 @@ namespace tpDomeWinAPP.Service
// //} // //}
//} //}
} }
*/
result.Add(row); result.Add(row);
//row.tag_name = s2.Where( x => x.Contains("_") && //row.tag_name = s2.Where( x => x.Contains("_") &&
// (x.Contains("H") || x.Contains("O") || x.Contains("C") || x.Contains("D") || x.Contains("M"))) // (x.Contains("H") || x.Contains("O") || x.Contains("C") || x.Contains("D") || x.Contains("M")))