From 037c1f05831b090c30f53c17fce1e023aa34fb3a Mon Sep 17 00:00:00 2001 From: Diego Francisco Carvajal Flores <diegofcarvajalf@gmail.com> Date: Mon, 27 Jun 2022 18:19:49 +0200 Subject: [PATCH] Update --- Dockerfile | 4 +- L5.ts | 241 ++++++++++++++++++++++++++++++++++++ environment.env | 16 +-- upmclient.ts | 54 ++++---- upmclientNoDocker.ts | 286 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 564 insertions(+), 37 deletions(-) create mode 100644 L5.ts create mode 100644 upmclientNoDocker.ts diff --git a/Dockerfile b/Dockerfile index c270c47..3cb3840 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ COPY . . # COPY ./client.ts ./ -COPY ./upmclient.ts ./ +COPY ./L5.ts ./ COPY ./Logger.ts ./ @@ -20,4 +20,4 @@ RUN npm install typescript RUN npm install -g ts-node -CMD [ "ts-node", "./upmclient.ts" ] +CMD [ "ts-node", "./L5.ts" ] diff --git a/L5.ts b/L5.ts new file mode 100644 index 0000000..4e335b8 --- /dev/null +++ b/L5.ts @@ -0,0 +1,241 @@ + +import { AttributeIds,OPCUAClient,DataValue,TimestampsToReturn,SecurityPolicy, NotificationMessage} from "node-opcua"; +import { Logger } from './Logger' +import { trytypes } from './trytypes' + +var trayType="NA"; +var default_index = 0 +// const nodeId_TypeNoCur = "ns=4;s=\"DataHandling\".\"TypeNoCur\""; +const dateIssued ="https://smart-data-models.github.io/data-models/terms.jsonld#/definitions/dateIssued" +var axios= require("axios") +//Fiware Configuration +const fiware_url=process.env.FIWARE_SERVER_URL || undefined +const fiware_node_id=process.env.FIWARE_NODE_ID || undefined +//const fiware_node_id="urn:ngsi-ld:Alert:BOSH:feed-trigger-"; + +//Line 5 configuration +const LINE_5_URL=process.env.LINE_5_URL || undefined +const TypeNoCur_plc_nodeid_L5=process.env.TypeNoCur_NODEID_L5 || undefined +const BlisterEntry_plc_nodeid_L5=process.env.BlisterEntry_NODEID_L5|| undefined + +// interval of subscription checks +const publishing_interval = 1000 + + +var notification_body ={ + id: '', + type: "Alert", + category:{ + type: "Property", + value: "feeding-trigger" + }, + description: { + type: "Property", + value: '', + }, + dateIssued: { + type: "Property", + value: { + "@type": "DateTime", + "@value": new Date().toISOString() + } + }, + + alertSource: { + type: "Relationship", + object: '' + }, + "@context": [ + "https://smartdatamodels.org/context.jsonld", + "https://raw.githubusercontent.com/shop4cf/data-models/master/docs/shop4cfcontext.jsonld" + + ] + + } + +const connectionStrategy={ + maxRetry: 2, + initialDelay: 2000, + maxDelay: 10 * 1000 +} +const requestedParameter= { + samplingInterval: 500, + discardOldest: true, + queueSize: 10 +} +const serverConnectionConfiguration={ + endpointMustExist: false, + securityPolicy: SecurityPolicy.None, + applicationName: "WoT-IL", + connectionStrategy: connectionStrategy +} + + +async function init(){ + + if(fiware_node_id == undefined){ + Logger.failure(`Undefined fiware_node_id. Actual value =${fiware_node_id}. Check environment configuration`) + throw new Error(); + } + if(fiware_url == undefined){ + const message=`Undefined fiware_url. Actual value =${fiware_url}. Check environment configuration` + Logger.failure(message) + throw new Error(message); + } + + + if(LINE_5_URL == undefined){ + const message=`Undefined LINE_5_URL. Actual value =${LINE_5_URL}. Check environment configuration` + Logger.failure(message) + throw new Error(message); + } + + + + if(TypeNoCur_plc_nodeid_L5 == undefined){ + const message=`Undefined TypeNoCur_plc_nodeid_L5. Actual value =${TypeNoCur_plc_nodeid_L5}. Check environment configuration` + Logger.failure(message) + throw new Error(message); + } + if(BlisterEntry_plc_nodeid_L5 == undefined){ + const message=`Undefined BlisterEntry_plc_nodeid_L5. Actual value =${BlisterEntry_plc_nodeid_L5}. Check environment configuration` + Logger.failure(message) + throw new Error(message); + } + + const entity_id = await getLastRecordOfType("https://uri.fiware.org/ns/data-models%23Alert") + if(entity_id > 0){ + default_index = entity_id + } + + + //Line 5 setup + const l5_client = await connectoToPLC(LINE_5_URL) + const TypeNoCur_subscription_L5 = await createSubscription(l5_client,TypeNoCur_plc_nodeid_L5) + const BlisterEntry_subscription_L5 = await createSubscription(l5_client,BlisterEntry_plc_nodeid_L5) + + TypeNoCur_subscription_L5.on("changed", async (dataValue_TypeNoCur: DataValue) => { + Logger.debug(`Monitoring TypeNoCur on line 5. Current value = ${dataValue_TypeNoCur.value.value.toString()}`) + if(trytypes.TypeA.indexOf(dataValue_TypeNoCur.value.value.toString()) != -1){ + trayType = 'A' + }else if(trytypes.TypeB.indexOf(dataValue_TypeNoCur.value.value.toString()) == -1){ + trayType = 'B' + }else if(trytypes.TypeC.indexOf(dataValue_TypeNoCur.value.value.toString()) == -1){ + trayType = 'C' + }else{ + Logger.warn(`L5 - tray type not defined. Given ${dataValue_TypeNoCur.value.value.toString()}`) + } + }); + + BlisterEntry_subscription_L5.on("changed", async (dataValue_BlisterEntry: DataValue) => { + Logger.debug(`Monitoring BlisterEntry on line 5. Current value = ${dataValue_BlisterEntry.value.value.toString()}`) + if(dataValue_BlisterEntry.value.value.toString() == "false"){ + default_index=default_index+1; + notification_body.id=`${fiware_node_id}${default_index}` + notification_body.description.value=trayType + notification_body.alertSource.object='urn:ngsi-ld:Asset:BOSH:LS5' + postRecord(notification_body) + }else{ + Logger.debug("No tray needed at line L5") + } + }); + +} + +async function connectoToPLC(url:any){ + Logger.debug(`Connecting to PLC ${url}...`) + const client = OPCUAClient.create(serverConnectionConfiguration); + try { + await client.connect(url) + return client + } catch (error) { + Logger.failure(`Can not connect to PLC ${url} --- ${JSON.stringify(error)}`) + } +} + +async function getLastRecordOfType(record_type:any){ + Logger.debug(`Finding record of type ${record_type}`) + try { + var result = await axios.get(`${fiware_url}/ngsi-ld/v1/entities?type=${record_type}`).then((response:any)=>response.data) + if(result.length != 0 ){ + let idStartNumber = result.map((o:any)=>o.id.split('-') + .slice(-1)[0]) + .map((l:string)=>parseInt(l)).sort( (a: number,b: number) =>a - b ) + .slice(-1)[0] + + Logger.debug(`Last notification id was ${idStartNumber}`) + return parseInt(idStartNumber) + }else{ + Logger.debug(`There is no entity matching with ${record_type}`) + return 0 + } + } catch (error) { + Logger.failure(`EXCEPTION GIVEN - Can not get getLastRecordOfType ${record_type } - ${JSON.stringify(error)}`) + return 0 + } +} + +async function createSubscription(client:any,node_id:any) { + Logger.debug(`Creating subscription for ${node_id}...`); + const session = await client.createSession(); + const subscription = await session.createSubscription2({ + requestedPublishingInterval: 1000, + requestedLifetimeCount: 100, + requestedMaxKeepAliveCount: 20, + maxNotificationsPerPublish: 10, + publishingEnabled: true, + priority: 10 + }); + + subscription + .on("Started", () => console.log("Subscription started - subscriptionId=", subscription.subscriptionId)) + .on("Keepalive", () => Logger.debug(`keep alive ${node_id}`)) + .on("Terminated", () => console.log("Subscription terminated")); + const itemToMonitor={ + nodeId:node_id, + attributeId: AttributeIds.Value + } + const monitoredItem = await subscription.monitor( + itemToMonitor, + requestedParameter, + TimestampsToReturn.Both); +return monitoredItem +} + +async function readVariable(client:any,node:any){ + const session = await client.createSession(); + const maxAge = 0; + const nodeToRead = { + nodeId: node, + }; + const dataValue = await session.read(nodeToRead, maxAge); + console.log(" Value " , dataValue.toString()); +} + +async function browse(client:any){ + + const session = await client.createSession(); + const browseResult = await session.browse("RootFolder"); + // const browsePath = makeBrowsePath("RootFolder", "/Objects/Server.ServerStatus.BuildInfo"); + // const result = await session.translateBrowsePath(browsePath); + console.log(JSON.stringify(browseResult)); + + // const productNameNodeId = result.targets[0].targetId; + // console.log(" Product Name nodeId = ", productNameNodeId.toString()); +} + +function postRecord(body:any){ + const headers={ + 'Content-Type': 'application/ld+json', + } + Logger.debug(`body id = ${body.id}`) + axios.post(`${fiware_url}/ngsi-ld/v1/entities`,body,{headers:headers}).then((response:any)=>{ + Logger.debug(JSON.stringify({response:response.status,statusText:response.statusText})) + },(error:any)=>{ + Logger.failure(JSON.stringify(error)) + }).catch((r:any)=>{ + Logger.failure(JSON.stringify(r)) + }) + +} +init() diff --git a/environment.env b/environment.env index 2d4e1ef..00253cb 100644 --- a/environment.env +++ b/environment.env @@ -1,11 +1,11 @@ -LINE_2_URL=opc.tcp://10.151.233.6:4334 -TypeNoCur_NODEID_L2=ns=1;s=DataHandling.TypeNoCur -BlisterEntry_NODEID_L2=ns=1;s=Station090.BlisterEntry +LINE_2_URL=opc.tcp://10.100.151.40:4840 +TypeNoCur_NODEID_L2=ns=4;s=DataHandling.TypeNoCur +BlisterEntry_NODEID_L2=ns=4;s=Station090.BlisterEntry -LINE_5_URL=opc.tcp://10.151.233.6:4334 -TypeNoCur_NODEID_L5=ns=1;s=DataHandling.TypeNoCur2 -BlisterEntry_NODEID_L5=ns=1;s=Station090.BlisterEntry2 +LINE_5_URL=opc.tcp://10.100.168.13:4840 +TypeNoCur_NODEID_L5=ns=4;s=DataHandling.TypeNoCur +BlisterEntry_NODEID_L5=ns=4;s=Station090.BlisterEntry FIWARE_NODE_ID=urn:ngsi-ld:Alert:BOSH:feed-trigger- -FIWARE_SERVER_URL=http://10.151.233.6:1026 -#FIWARE_RECORD_TYPE=https://uri.fiware.org/ns/data-models%23Alert \ No newline at end of file +FIWARE_SERVER_URL=http://10.100.147.11:1026 +#FIWARE_RECORD_TYPE=https://uri.fiware.org/ns/data-models%23Alert diff --git a/upmclient.ts b/upmclient.ts index aed9ea0..74316df 100644 --- a/upmclient.ts +++ b/upmclient.ts @@ -48,7 +48,7 @@ var notification_body ={ alertSource: { type: "Relationship", - object: "urn:ngsi-ld:Asset:BOS:LS2" + object: '' }, "@context": [ "https://smartdatamodels.org/context.jsonld", @@ -69,7 +69,7 @@ const requestedParameter= { queueSize: 10 } const serverConnectionConfiguration={ - endpoint_must_exist: false, + endpointMustExist: false, securityPolicy: SecurityPolicy.None, applicationName: "WoT-IL", connectionStrategy: connectionStrategy @@ -79,49 +79,49 @@ const serverConnectionConfiguration={ async function init(){ if(fiware_node_id == undefined){ - Logger.failure(`undefined fiware_node_id. Actual value =${fiware_node_id}. Check environment configuration`) + Logger.failure(`Undefined fiware_node_id. Actual value =${fiware_node_id}. Check environment configuration`) throw new Error(); } if(fiware_url == undefined){ - const message=`undefined fiware_url. Actual value =${fiware_url}. Check environment configuration` + const message=`Undefined fiware_url. Actual value =${fiware_url}. Check environment configuration` Logger.failure(message) throw new Error(message); } if(LINE_2_URL == undefined){ - const message=`undefined LINE_2_URL. Actual value =${LINE_2_URL}. Check environment configuration` + const message=`Undefined LINE_2_URL. Actual value =${LINE_2_URL}. Check environment configuration` Logger.failure(message) throw new Error(message); } if(LINE_5_URL == undefined){ - const message=`undefined LINE_5_URL. Actual value =${LINE_5_URL}. Check environment configuration` + const message=`Undefined LINE_5_URL. Actual value =${LINE_5_URL}. Check environment configuration` Logger.failure(message) throw new Error(message); } if(TypeNoCur_plc_nodeid_L2 == undefined){ - const message=`undefined TypeNoCur_plc_nodeid_L2. Actual value =${TypeNoCur_plc_nodeid_L2}. Check environment configuration` + const message=`Undefined TypeNoCur_plc_nodeid_L2. Actual value =${TypeNoCur_plc_nodeid_L2}. Check environment configuration` Logger.failure(message) throw new Error(message); } if(BlisterEntry_plc_nodeid_L2 == undefined){ - const message=`undefined BlisterEntry_plc_nodeid_L2. Actual value =${BlisterEntry_plc_nodeid_L2}. Check environment configuration` + const message=`Undefined BlisterEntry_plc_nodeid_L2. Actual value =${BlisterEntry_plc_nodeid_L2}. Check environment configuration` Logger.failure(message) throw new Error(message); } if(TypeNoCur_plc_nodeid_L5 == undefined){ - const message=`undefined TypeNoCur_plc_nodeid_L5. Actual value =${TypeNoCur_plc_nodeid_L5}. Check environment configuration` + const message=`Undefined TypeNoCur_plc_nodeid_L5. Actual value =${TypeNoCur_plc_nodeid_L5}. Check environment configuration` Logger.failure(message) throw new Error(message); } if(BlisterEntry_plc_nodeid_L5 == undefined){ - const message=`undefined BlisterEntry_plc_nodeid_L5. Actual value =${BlisterEntry_plc_nodeid_L5}. Check environment configuration` + const message=`Undefined BlisterEntry_plc_nodeid_L5. Actual value =${BlisterEntry_plc_nodeid_L5}. Check environment configuration` Logger.failure(message) throw new Error(message); } const entity_id = await getLastRecordOfType("https://uri.fiware.org/ns/data-models%23Alert") if(entity_id > 0){ - default_index = 0 + default_index = entity_id } //Line 2 setup @@ -138,7 +138,7 @@ async function init(){ }else if(trytypes.TypeC.indexOf(dataValue_TypeNoCur.value.value.toString()) == -1){ trayType = 'C' }else{ - Logger.warn(`L2 - try type not defined. Given ${dataValue_TypeNoCur.value.value.toString()}`) + Logger.warn(`L2 - tray type not defined. Given ${dataValue_TypeNoCur.value.value.toString()}`) } }); @@ -148,10 +148,10 @@ async function init(){ default_index=default_index+1; notification_body.id=`${fiware_node_id}${default_index}` notification_body.description.value=trayType - notification_body.alertSource.object='urn:ngsi-ld:Asset:BOS:LS2' + notification_body.alertSource.object='urn:ngsi-ld:Asset:BOSH:LS2' postRecord(notification_body) }else{ - Logger.debug("BlisterEntry at line L2 is not needed") + Logger.debug("No tray needed at line L2") } }); //Line 5 setup @@ -168,7 +168,7 @@ async function init(){ }else if(trytypes.TypeC.indexOf(dataValue_TypeNoCur.value.value.toString()) == -1){ trayType = 'C' }else{ - Logger.warn(`L5 - try type not defined. Given ${dataValue_TypeNoCur.value.value.toString()}`) + Logger.warn(`L5 - tray type not defined. Given ${dataValue_TypeNoCur.value.value.toString()}`) } }); @@ -178,10 +178,10 @@ async function init(){ default_index=default_index+1; notification_body.id=`${fiware_node_id}${default_index}` notification_body.description.value=trayType - notification_body.alertSource.object='urn:ngsi-ld:Asset:BOS:LS5' + notification_body.alertSource.object='urn:ngsi-ld:Asset:BOSH:LS5' postRecord(notification_body) }else{ - Logger.debug("BlisterEntry at line L5 is not needed") + Logger.debug("No tray needed at line L5") } }); @@ -194,12 +194,12 @@ async function connectoToPLC(url:any){ await client.connect(url) return client } catch (error) { - Logger.failure(`Cant connect to PLC ${url} --- ${JSON.stringify(error)}`) + Logger.failure(`Can not connect to PLC ${url} --- ${JSON.stringify(error)}`) } } async function getLastRecordOfType(record_type:any){ - Logger.debug(`finding record of type ${record_type}`) + Logger.debug(`Finding record of type ${record_type}`) try { var result = await axios.get(`${fiware_url}/ngsi-ld/v1/entities?type=${record_type}`).then((response:any)=>response.data) if(result.length != 0 ){ @@ -208,20 +208,20 @@ async function getLastRecordOfType(record_type:any){ .map((l:string)=>parseInt(l)).sort( (a: number,b: number) =>a - b ) .slice(-1)[0] - Logger.debug(`last notification id was ${idStartNumber}`) + Logger.debug(`Last notification id was ${idStartNumber}`) return parseInt(idStartNumber) }else{ - Logger.debug(`there is no entity matching with ${record_type}`) + Logger.debug(`There is no entity matching with ${record_type}`) return 0 } } catch (error) { - Logger.failure(`EXCEPTION GIVEN - cant get getLastRecordOfType ${record_type } - ${JSON.stringify(error)}`) + Logger.failure(`EXCEPTION GIVEN - Can not get getLastRecordOfType ${record_type } - ${JSON.stringify(error)}`) return 0 } } async function createSubscription(client:any,node_id:any) { - Logger.debug(`creating subscription for ${node_id}...`); + Logger.debug(`Creating subscription for ${node_id}...`); const session = await client.createSession(); const subscription = await session.createSubscription2({ requestedPublishingInterval: 1000, @@ -233,9 +233,9 @@ async function createSubscription(client:any,node_id:any) { }); subscription - .on("started", () => console.log("subscription started - subscriptionId=", subscription.subscriptionId)) - .on("keepalive", () => Logger.debug(`keep alive ${node_id}`)) - .on("terminated", () => console.log("subscription terminated")); + .on("Started", () => console.log("Subscription started - subscriptionId=", subscription.subscriptionId)) + .on("Keepalive", () => Logger.debug(`keep alive ${node_id}`)) + .on("Terminated", () => console.log("Subscription terminated")); const itemToMonitor={ nodeId:node_id, attributeId: AttributeIds.Value @@ -254,7 +254,7 @@ async function readVariable(client:any,node:any){ nodeId: node, }; const dataValue = await session.read(nodeToRead, maxAge); - console.log(" value " , dataValue.toString()); + console.log(" Value " , dataValue.toString()); } async function browse(client:any){ diff --git a/upmclientNoDocker.ts b/upmclientNoDocker.ts new file mode 100644 index 0000000..f07cae2 --- /dev/null +++ b/upmclientNoDocker.ts @@ -0,0 +1,286 @@ + +import { AttributeIds,OPCUAClient,DataValue,TimestampsToReturn,SecurityPolicy, NotificationMessage} from "node-opcua"; +import { Logger } from './Logger' +import { trytypes } from './trytypes' + +var trayType="NA"; +var default_index = 0 + +// const nodeId_TypeNoCur = "ns=4;s=\"DataHandling\".\"TypeNoCur\""; +const dateIssued ="https://smart-data-models.github.io/data-models/terms.jsonld#/definitions/dateIssued" +var axios= require("axios") +//Fiware Configuration +const fiware_url="http://localhost:1026" +const fiware_node_id="urn:ngsi-ld:Alert:BOSH:feed-trigger-" + + +//Line 2 configuration +const LINE_2_URL="opc.tcp://localhost:4334" +const TypeNoCur_plc_nodeid_L2="ns=1;s=DataHandling.TypeNoCur" +const BlisterEntry_plc_nodeid_L2="ns=1;s=Station090.BlisterEntry" + +//Line 5 configuration +const LINE_5_URL="opc.tcp://localhost:4334" +const TypeNoCur_plc_nodeid_L5="ns=1;s=DataHandling.TypeNoCur2" +const BlisterEntry_plc_nodeid_L5="ns=1;s=Station090.BlisterEntry2" +// interval of subscription checks +const publishing_interval = 1000 + + +var notification_body ={ + id: '', + type: "Alert", + category:{ + type: "Property", + value: "feeding-trigger" + }, + description: { + type: "Property", + value: '', + }, + dateIssued: { + type: "Property", + value: { + "@type": "DateTime", + "@value": new Date().toISOString() + } + }, + + alertSource: { + type: "Relationship", + object: "urn:ngsi-ld:Asset:BOSH:LS2" + }, + "@context": [ + "https://smartdatamodels.org/context.jsonld", + "https://raw.githubusercontent.com/shop4cf/data-models/master/docs/shop4cfcontext.jsonld" + + ] + + } + +const connectionStrategy={ + maxRetry: 2, + initialDelay: 2000, + maxDelay: 10 * 1000 +} +const requestedParameter= { + samplingInterval: 500, + discardOldest: true, + queueSize: 10 +} +const serverConnectionConfiguration={ + endpointMustExist: false, + securityPolicy: SecurityPolicy.None, + applicationName: "WoT-IL", + connectionStrategy: connectionStrategy +} + + +async function init(){ + + if(fiware_node_id == undefined){ + Logger.failure(`undefined fiware_node_id. Actual value =${fiware_node_id}. Check environment configuration`) + throw new Error(); + } + if(fiware_url == undefined){ + const message=`undefined fiware_url. Actual value =${fiware_url}. Check environment configuration` + Logger.failure(message) + throw new Error(message); + } + if(LINE_2_URL == undefined){ + const message=`undefined LINE_2_URL. Actual value =${LINE_2_URL}. Check environment configuration` + Logger.failure(message) + throw new Error(message); + } + if(LINE_5_URL == undefined){ + const message=`undefined LINE_5_URL. Actual value =${LINE_5_URL}. Check environment configuration` + Logger.failure(message) + throw new Error(message); + } + if(TypeNoCur_plc_nodeid_L2 == undefined){ + const message=`undefined TypeNoCur_plc_nodeid_L2. Actual value =${TypeNoCur_plc_nodeid_L2}. Check environment configuration` + Logger.failure(message) + throw new Error(message); + } + if(BlisterEntry_plc_nodeid_L2 == undefined){ + const message=`undefined BlisterEntry_plc_nodeid_L2. Actual value =${BlisterEntry_plc_nodeid_L2}. Check environment configuration` + Logger.failure(message) + throw new Error(message); + } + + if(TypeNoCur_plc_nodeid_L5 == undefined){ + const message=`undefined TypeNoCur_plc_nodeid_L5. Actual value =${TypeNoCur_plc_nodeid_L5}. Check environment configuration` + Logger.failure(message) + throw new Error(message); + } + if(BlisterEntry_plc_nodeid_L5 == undefined){ + const message=`undefined BlisterEntry_plc_nodeid_L5. Actual value =${BlisterEntry_plc_nodeid_L5}. Check environment configuration` + Logger.failure(message) + throw new Error(message); + } + + const entity_id = await getLastRecordOfType("https://uri.fiware.org/ns/data-models%23Alert") + if(entity_id > 0){ + default_index = entity_id + } + + //Line 2 setup + const l2_client = await connectoToPLC(LINE_2_URL) + const TypeNoCur_subscription_L2 = await createSubscription(l2_client,TypeNoCur_plc_nodeid_L2) + const BlisterEntry_subscription_L2 = await createSubscription(l2_client,BlisterEntry_plc_nodeid_L2) + + TypeNoCur_subscription_L2.on("changed", async (dataValue_TypeNoCur: DataValue) => { + Logger.debug(`Monitoring TypeNoCur on line 2. Current value = ${dataValue_TypeNoCur.value.value.toString()}`) + if(trytypes.TypeA.indexOf(dataValue_TypeNoCur.value.value.toString()) != -1){ + trayType = 'A' + }else if(trytypes.TypeB.indexOf(dataValue_TypeNoCur.value.value.toString()) == -1){ + trayType = 'B' + }else if(trytypes.TypeC.indexOf(dataValue_TypeNoCur.value.value.toString()) == -1){ + trayType = 'C' + }else{ + Logger.warn(`L2 - try type not defined. Given ${dataValue_TypeNoCur.value.value.toString()}`) + } + }); + + BlisterEntry_subscription_L2.on("changed", async (dataValue_BlisterEntry: DataValue) => { + Logger.debug(`Monitoring BlisterEntry on line 2. Current value = ${dataValue_BlisterEntry.value.value.toString()}`) + if(dataValue_BlisterEntry.value.value.toString() == "false"){ + default_index=default_index+1; + notification_body.id=`${fiware_node_id}${default_index}` + notification_body.description.value=trayType + notification_body.alertSource.object='urn:ngsi-ld:Asset:BOS:LS2' + postRecord(notification_body) + }else{ + Logger.debug("BlisterEntry at line L2 is not needed") + } + }); + //Line 5 setup + const l5_client = await connectoToPLC(LINE_5_URL) + const TypeNoCur_subscription_L5 = await createSubscription(l5_client,TypeNoCur_plc_nodeid_L5) + const BlisterEntry_subscription_L5 = await createSubscription(l5_client,BlisterEntry_plc_nodeid_L5) + + TypeNoCur_subscription_L5.on("changed", async (dataValue_TypeNoCur: DataValue) => { + Logger.debug(`Monitoring TypeNoCur on line 5. Current value = ${dataValue_TypeNoCur.value.value.toString()}`) + if(trytypes.TypeA.indexOf(dataValue_TypeNoCur.value.value.toString()) != -1){ + trayType = 'A' + }else if(trytypes.TypeB.indexOf(dataValue_TypeNoCur.value.value.toString()) == -1){ + trayType = 'B' + }else if(trytypes.TypeC.indexOf(dataValue_TypeNoCur.value.value.toString()) == -1){ + trayType = 'C' + }else{ + Logger.warn(`L5 - try type not defined. Given ${dataValue_TypeNoCur.value.value.toString()}`) + } + }); + + BlisterEntry_subscription_L5.on("changed", async (dataValue_BlisterEntry: DataValue) => { + Logger.debug(`Monitoring BlisterEntry on line 5. Current value = ${dataValue_BlisterEntry.value.value.toString()}`) + if(dataValue_BlisterEntry.value.value.toString() == "false"){ + default_index=default_index+1; + notification_body.id=`${fiware_node_id}${default_index}` + notification_body.description.value=trayType + notification_body.alertSource.object='urn:ngsi-ld:Asset:BOS:LS5' + postRecord(notification_body) + }else{ + Logger.debug("BlisterEntry at line L5 is not needed") + } + }); + +} + +async function connectoToPLC(url:any){ + Logger.debug(`Connecting to PLC ${url}...`) + const client = OPCUAClient.create(serverConnectionConfiguration); + try { + await client.connect(url) + return client + } catch (error) { + Logger.failure(`Cant connect to PLC ${url} --- ${JSON.stringify(error)}`) + } +} + +async function getLastRecordOfType(record_type:any){ + Logger.debug(`finding record of type ${record_type}`) + try { + var result = await axios.get(`${fiware_url}/ngsi-ld/v1/entities?type=${record_type}`).then((response:any)=>response.data) + if(result.length != 0 ){ + let idStartNumber = result.map((o:any)=>o.id.split('-') + .slice(-1)[0]) + .map((l:string)=>parseInt(l)).sort( (a: number,b: number) =>a - b ) + .slice(-1)[0] + + Logger.debug(`last notification id was ${idStartNumber}`) + return parseInt(idStartNumber) + }else{ + Logger.debug(`there is no entity matching with ${record_type}`) + return 0 + } + } catch (error) { + Logger.failure(`EXCEPTION GIVEN - cant get getLastRecordOfType ${record_type } - ${JSON.stringify(error)}`) + return 0 + } +} + +async function createSubscription(client:any,node_id:any) { + Logger.debug(`creating subscription for ${node_id}...`); + const session = await client.createSession(); + const subscription = await session.createSubscription2({ + requestedPublishingInterval: 1000, + requestedLifetimeCount: 100, + requestedMaxKeepAliveCount: 20, + maxNotificationsPerPublish: 10, + publishingEnabled: true, + priority: 10 + }); + + subscription + .on("started", () => console.log("subscription started - subscriptionId=", subscription.subscriptionId)) + .on("keepalive", () => Logger.debug(`keep alive ${node_id}`)) + .on("terminated", () => console.log("subscription terminated")); + const itemToMonitor={ + nodeId:node_id, + attributeId: AttributeIds.Value + } + const monitoredItem = await subscription.monitor( + itemToMonitor, + requestedParameter, + TimestampsToReturn.Both); +return monitoredItem +} + +async function readVariable(client:any,node:any){ + const session = await client.createSession(); + const maxAge = 0; + const nodeToRead = { + nodeId: node, + }; + const dataValue = await session.read(nodeToRead, maxAge); + console.log(" value " , dataValue.toString()); +} + +async function browse(client:any){ + + const session = await client.createSession(); + const browseResult = await session.browse("RootFolder"); + // const browsePath = makeBrowsePath("RootFolder", "/Objects/Server.ServerStatus.BuildInfo"); + // const result = await session.translateBrowsePath(browsePath); + console.log(JSON.stringify(browseResult)); + + // const productNameNodeId = result.targets[0].targetId; + // console.log(" Product Name nodeId = ", productNameNodeId.toString()); +} + +function postRecord(body:any){ + const headers={ + 'Content-Type': 'application/ld+json', + } + Logger.debug(`body id = ${body.id}`) + axios.post(`${fiware_url}/ngsi-ld/v1/entities`,body,{headers:headers}).then((response:any)=>{ + Logger.debug(JSON.stringify({response:response.status,statusText:response.statusText})) + },(error:any)=>{ + Logger.failure(JSON.stringify(error)) + }).catch((r:any)=>{ + Logger.failure(JSON.stringify(r)) + }) + +} +init() -- GitLab