//Variables used for averages and other calculations. sumPPM = 0 sumRej = 0 sumCheck = 0 email_sent% = 0 Reject_Percentage_count% = 0 DIM PPM15(30) DIM REJ15(30) DIM CHECK15(30) DIM message_list$(7, 50) DIM PPMarr(30) ONDATE 1,"50 6 * * *","@Clear_Data" ONDATE 2,"2 15 * * *","@Clear_Data" ONDATE 3,"50 22 * * *","@Clear_Data" ONDATE 4,"50 6 * * 6","Weekend = 1" ONDATE 5,"50 6 * * 1","Weekend = 0" ONDATE 6, "0 * * * *", "@Hourly_Bottles" TSET 3, 30 ONTIMER 3, "@changes()" A$ = Time$ H% = Val(A$(12 To 13)) If H% >= 23 Then shift = 3 Else If H% < 7 Then shift = 3 Else If H% < 15 Then shift = 1 Else If H% < 23 Then shift = 2 Endif Endif Endif Endif If Val(tmax_perhour@) <> 0 Then If shift = 1 Then tmax_perhour_s1@ = Val(tmax_perhour@) Max_s1@ = Val(tmax_perhour@) * 1.50 Endif If shift = 2 Then tmax_perhour_s2@ = Val(tmax_perhour@) Max_s1@ = Val(tmax_perhour@) * 1.50 Endif If shift = 3 Then tmax_perhour_s3@ = Val(tmax_perhour@) Max_s1@ = Val(tmax_perhour@) * 1.50 Endif Graph_line@ = Val(tmax_perhour@) * .75 Else Max_s1@ = 3000 Max_s2@ = 3000 Max_s3@ = 3000 Graph_line@ = 1500 EndIF Function changes() ONCHANGE "AMP_1300CountFill02_Running","@Status_Change()" TSET 3,0 Endfn Function Status_Change() If AMP_1300CountFill02_Running@= 0 Then //Line stopped down_start_time% = GETSYS PRG, "TIMESEC" RETURN ELSE down_end_time% = GETSYS PRG, "TIMESEC" downtime% = down_end_time% - down_start_time% filler_downtime@ = filler_downtime@+downtime% ENDIF ENDFN Function Hourly_Bottles() $A$ = Time$ $H$ = $A$(12 To 13) $tagname$ = "Hour_" + $H$ If $H$ = '7' Or $H$ = '16' Or $H$ = '23' Then SETIO $tagname$, (Finished_bottles@ + saved_count@) previous_count@ = Finished_bottles@ Else SETIO $tagname$, (Finished_bottles@ - previous_count@) previous_count@ = Finished_bottles@ Endfn //-------Clears all data between shifts-------------------- Function Clear_Data() $A$ = Time$ $H% = Val($A$(12 To 13)) saved_count@ = Finished_bottles@ - previous_count@ //Commands counters to be set to 0 through modbus tag Clear_Counter_Outfeed_Filler@ = 1 Clear_Counter_Checkweigher_Reject@ = 1 Clear_Counter_Checkweigher_Infeed@ = 1 Pace_Throughput@ = 0 email_sent%=0 // down_start_time%=GETSYS PRG, "TIMESEC" //filler_dnts@=TIME$ filler_downtime@ = 0 previous_count@ = 0 // //resets all averages DIM PPM15(30) DIM REJ15(30) DIM CHECK15(30) If $H% = 6 Then shift =1 Endif If $H% = 15 Then shift = 2 Endif If $H% = 22 Then shift = 3 Endif Endfn Function duration() $A$ = Time$ $H% = Val($A$(12 To 13)) //Get Hour $M% = Val($A$(15 To 16)) If $H% >= 23 Then $duration = ($H%-22) * 60 + $M% Return Endif If $H% < 7 Then $duration = ($H%+1) * 60 + $M% Return Endif If $H% < 15 Then $duration = ($H%-7) * 60 + $M% Return Endif If $H% < 23 Then $duration = ($H%-15) * 60 + $M% Return Endif EndFn down_start_time% = GETSYS PRG, "TIMESEC" Infeed_Count = Checkweigher_Infeed@ Reject_Count = Checkweigher_Reject@ TSET 1,2 ONTIMER 1, "@Cycle_Calculation()" fin_diff%=0 last_fin%=0 cycle_count% = 25 fin_diff15%=0 rej_diff15%=0 infeed15% = 0 last_fin15% = 0 rejpct15% = 0 lastrej% = 0 Function Cycle_Calculation () $sum_ppm% = 0 finished_bottles@ = Checkweigher_Infeed@ - Checkweigher_Reject@ fin_diff% = finished_bottles@ - last_fin% last_fin% = finished_bottles@ If Checkweigher_Infeed@ = 0 Then Reject_Percentage_Shift@ = 0 Else Reject_Percentage_Shift@ = Checkweigher_Reject@/Checkweigher_Infeed@ Endif For $i% = 30 To 1 Step -1 If $i% > 1 Then PPMarr($i%) = PPMarr($i%-1) $sum_ppm% = $sum_ppm% + PPMarr($i%) Else PPMarr($i%) = fin_diff% $sum_ppm% = $sum_ppm% + PPMarr($i%) Endif Next $i% PPM@ = $sum_ppm% $duration1=@duration() line_throughput@ = finished_bottles@/ $duration1 run_efficiency@ = 100 * finished_bottles@ / ((Val(tmax_perhour@) * ($duration1/60))) downtime_percentage@ = 100* (filler_downtime@/60) / $duration1 If cycle_count% < 30 Then cycle_count% = cycle_count% + 1 Else infeed15% = Checkweigher_Infeed@ fin_diff15% = infeed15% - last_fin15% last_fin15% = infeed15% rej_diff% = Checkweigher_Reject@ - lastrej% lastrej% = Checkweigher_Reject@ If fin_diff15% = 0 Then rejpct15% = 0 Else rejpct15 = rej_diff% / fin_diff15% Endif @fifteen_min() cycle_count% = 0 Endif ENDFN Function fifteen_min () $sum_ppm% = 0 For $i% = 15 To 1 Step -1 If $i% > 1 Then PPM15($i%) = PPM15($i%-1) $sum_ppm% = $sum_ppm% + PPM15($i%) REJ15($i%) = REJ15($i%-1) $sum_REJ15 = $sum_REJ15 + REJ15($i%) Else PPM15($i%) = PPM@ $sum_ppm% = $sum_ppm% + PPM15($i%) Print rejpct15 REJ15($i%) = rejpct15 $sum_REJ15 = $sum_REJ15 + REJ15($i%) Endif Next $i% PPM15_AVG@ = $sum_ppm% / 15.0 REJ15_AVG@ = 100 * $sum_REJ15 / 15.0 ENDFN //-->NAME : AWS IOT Live Data //-->VERSION : 1.0 //-->DESCRIPTION //This program allows the Flexy to push its instantaneous Tag values to AWS IOT (including Text buffer in case of communication loss). //Device Authentication is done using certificate and key files. //-->END DESCRIPTION // //-->REQUIREMENTS //You will have first to create your device or your "thing" in Aws IOT. //An easy way is to do it is via the "Connect -> GetStarted" menu (Select Linux>NodeJs). //At the end, you should get a zip file containing the Flexy certificates and a start.sh file containing the broker URL and the Client ID. //Push the files .cert.pem and .private.key to the usr/ directory via FTP. // //Regarding the topic, verify this one is well allowed by your device policy in AWS IoT. // //Before starting the script, make sure to //- Create at least one Tag and set them into one of the selected Tag Group(s) - See Program Parameters below. //- Connect your Flexy to the Internet (Port 8883 must be open) //Need help ? Check our video tutorial //-->END REQUIREMENTS //-->CONFIGURATION CONF_AWSMQTTBROKERURL$="aaxnzbrs38f2e-ats.iot.us-east-2.amazonaws.com"//COMMENT:AWS MQTT Broker URL (See start.sh) ->Ex: xxxx-ats.iot.eu-west-3.amazonaws.com CONF_ClientID$ = "sdk-nodejs-dcf42eff-9106-41fc-b1a5-bdaf47ed45a4"//COMMENT:AWS IOT Client ID (See start.sh)->Ex: sdk-nodejs-93514xxxx... CONF_ThingName$ = "Ameriplex_1300-Count-Fill-02"//COMMENT:Thing Name choosen when creating the Thing/Device in Aws IoT (See start.sh) CONF_DeviceTopic$ = "topic_1"//COMMENT:AWS IOT Device Topic used for sending message (See permission on Device policy. See requirents) -> Ex : topic_1 ->topic_1 CONF_DeviceTopic2$ = "topic_2" CONF_GROUPA$ = "0"//COMMENT:Select Tags from group A -> 0 or 1->1 CONF_GROUPB$ = "1"//COMMENT:Select Tags from group B -> 0 or 1->1 CONF_GROUPC$ = "0"//COMMENT:Select Tags from group C -> 0 or 1->1 CONF_GROUPD$ = "0"//COMMENT:Select Tags from group D -> 0 or 1->1 CONF_FullPushTime$ = "3"//COMMENT:Time interval to push all values -> time in seconds ->60 CONF_ChangePushTime$ = "0"//COMMENT:Time interval to push all values that changed -> time in seconds ->5 line_ID$="13.00-Count-Fill-02" site_ID$= "Ameriplex" //-->END CONFIGURATION CONF_FullPushTime% = VAL CONF_FullPushTime$ CONF_ChangePushTime% = VAL CONF_ChangePushTime$ MsgDBPath$ = "/usr/mqttmsg_db.txt" MaxMsgBufferFileSize% = 5000000 //max size of file used to save msg in bytes CLS Last_ConnStatus% = -1 FullPushLastTimeSec% = 0 ChangePushLastTimeSec% = 0 @LOG("Generate CA Certificate in usr directory.") @Generate_Aws_CA_Certificate() @LOG("Initalize MQTT, connecting to Aws IoT broker") MQTT "OPEN",CONF_ClientID$, CONF_AWSMQTTBROKERURL$ MQTT "SETPARAM", "Port","8883" MQTT "SETPARAM", "log", "1" MQTT "SETPARAM", "keepalive", "20" MQTT "SETPARAM", "cafile","/usr/AWS_CA.crt" MQTT "SETPARAM", "certfile","/usr/"+CONF_ThingName$+".cert.pem" MQTT "SETPARAM", "keyfile","/usr/"+CONF_ThingName$+".private.key" SETSYS PRG,"RESUMENEXT",1 //Continue in case of error at MQTT "CONNECT" MQTT "CONNECT" ErrorReturned% = GETSYS PRG,"LSTERR" IF ErrorReturned% = 28 THEN @Log("WAN interface not yet ready. MQTT Launched anyway...") SETSYS PRG,"RESUMENEXT",0 //a = table with 2 columns : one with the negative indice of the tag and the second one with 1 if the values of the tag change or 0 otherwise //Record the Tag ONCHANGE events into an array. //Allows to post only values that have changed NB%= GETSYS PRG,"NBTAGS" DIM a(NB%,2) FOR i% = 0 TO NB%-1 k%=i%+1 SETSYS Tag, "load",-i% a(k%,1)=-i% a(k%,2) = 0 GroupA$= GETSYS TAG,"IVGROUPA" GroupB$= GETSYS TAG,"IVGROUPB" GroupC$= GETSYS TAG,"IVGROUPC" GroupD$= GETSYS TAG,"IVGROUPD" IF GroupA$ = "1" And CONF_GroupA$= "1" THEN Onchange -i%, "a("+ STR$ k%+",2)= 1" IF GroupB$ = "1" And CONF_GroupB$= "1" THEN Onchange -i%, "a("+ STR$ k%+",2)= 1" IF GroupC$ = "1" And CONF_GroupC$= "1" THEN Onchange -i%, "a("+ STR$ k%+",2)= 1" IF GroupD$ = "1" And CONF_GroupD$= "1" THEN Onchange -i%, "a("+ STR$ k%+",2)= 1" NEXT i% //Set and Start Timer MQTTProcess_CycleTime% = 1 ONTIMER 4, "GOTO MqttProcess" TSET 4, MQTTProcess_CycleTime% END //Publish a message. If not connected, save the message in a file FUNCTION MQTT_Publish($json$) $ConnStatus% = MQTT "STATUS" IF $ConnStatus% = 5 THEN MQTT "PUBLISH",CONF_DeviceTopic$,$json$, 1, 0 //PRINT "[MQTT SCRIPT] Message "+ $json$(1 To 20) +"... sent to topic " + CONF_DeviceTopic$ ELSE //If not connected --> Save message in file @MQTT_SaveMQTTEvent($json$) ENDIF ENDFN //Check if the Connection is recovered and //if yes, send the messages contained in the buffer file to broker FUNCTION MQTT_CheckConnection() $ConnStatus% = MQTT "STATUS" IF Last_ConnStatus% <> $ConnStatus% THEN IF $ConnStatus% = 5 THEN //Connection is back online @Log("Ewon Flexy connected to Broker") @MQTT_SendSavedEvents() //Parse Saved Messages and publish them ELSE @Log("Ewon Flexy disconnected from Broker") ENDIF Last_ConnStatus% = $ConnStatus% ENDIF ENDFN //Save message in Txt file. FUNCTION MQTT_SaveMQTTEvent($Msg$) $filesize% = FS "size", MsgDBPath$ IF $filesize% < MaxMsgBufferFileSize% THEN OPEN "file:" + MsgDBPath$ FOR BINARY APPEND AS 1 PUT 1, $Msg$ + CHR$(10) CLOSE 1 @LOG("Flexy not connected - message saved") ELSE @LOG("Flexy not connected - message not saved, buffer file is full") ENDIF ENDFN // Save messages contained in the txt file to the broker. FUNCTION MQTT_SendSavedEvents() $FileExist% = FS "isFile", MsgDBPath$ IF $FileExist% = -1 THEN RETURN ENDIF $NbrMsg% = 0 OPEN "file:" + MsgDBPath$ FOR BINARY INPUT AS 1 $Line$ = "" $ReadNext: IF EOF 1 THEN GOTO $ReadDone $CHAR$ = GET 1,1 IF $CHAR$ = CHR$(10) THEN MQTT "PUBLISH", CONF_DeviceTopic$ , $Line$, 1,0 $Line$ = "" $NbrMsg% = $NbrMsg% + 1 ELSE $Line$ = $Line$ + $CHAR$ ENDIF GOTO $ReadNext $ReadDone: CLOSE 1 @LOG(STR$ $NbrMsg% + " saved messages published.") ERASE MsgDBPath$ ENDFN //Compute the right time format for AZURE FUNCTION MQTT_GetJsonTime$() $a$ = Time$ $MQTT_GetJsonTime$ = $a$(7 To 10) + "-" + $a$(4 To 5) + "-" + $a$(1 To 2) + " " + $a$(12 To 13)+":"+$a$(15 To 16)+":"+$a$(18 To 19) ENDFN //Compute the Json string with the Tags that have changed. FUNCTION MQTT_ComputeJsonChangeTags$() $counter% = 0 //Compute JSON $json$ = '{' $NB% = GETSYS PRG,"NBTAGS" FOR $r% = 1 TO $NB% IF a($r%,2) = 1 THEN a($r%,2) = 0 $negIndex% = a($r%,1) SETSYS Tag, "LOAD", $negIndex% $Tagname$= GETSYS TAG, "NAME" $TagValue$ = GETSYS TAG, "TAGVALUE" $json$ = $json$ + '"' + $Tagname$ + '":"'+ $TagValue$ + '",' $counter% = $counter% +1 ENDIF NEXT $r% $json$ = $json$ + '"time": "' + @MQTT_GetJsonTime$() + '"' $json$ = $json$ + '}' IF $counter% <> 0 THEN $MQTT_ComputeJsonChangeTags$ = $json$ ELSE $MQTT_ComputeJsonChangeTags$ = "" ENDIF ENDFN //Build json with all Tags FUNCTION MQTT_ComputeJsonAllTags$() $json$ = '{' $NBTags% = GETSYS PRG,"NBTAGS" $count%=1 FOR $i% = 0 TO $NBTags% -1 SETSYS TAG, "load",-$i% $Tagname$= GETSYS TAG,"NAME" $GroupA$ = GETSYS TAG,"IVGROUPA" $GroupB$ = GETSYS TAG,"IVGROUPB" $GroupC$ = GETSYS TAG,"IVGROUPC" $GroupD$ = GETSYS TAG,"IVGROUPD" $TagValue$ = GETSYS TAG, "TAGVALUE" IF $GroupA$ = "1" And CONF_GroupA$= "1" THEN $json$ = $json$ + '"' + $Tagname$ + '":"' + $TagValue$ + '",' IF ($GroupB$ = "1" And CONF_GroupB$= "1") THEN $json$ = $json$ + '"' + 'Tag' + STR$($count%) + '":"' + $Tagname$ + '",' $json$ = $json$ + '"' + 'Status'+ STR$($count%) + '":"' + $TagValue$ + '",' $count%=$count%+1 ENDIF IF $GroupC$ = "1" And CONF_GroupC$= "1" THEN $json$ = $json$ + '"' + $Tagname$ + '":"' + $TagValue$ + '",' IF $GroupD$ = "1" And CONF_GroupD$= "1" THEN $json$ = $json$ + '"' + $Tagname$ + '":"' + $TagValue$ + '",' NEXT $i% $json$ = $json$ + '"time": "'+ @MQTT_GetJsonTime$() +'"' $json$ = $json$ + '}' $MQTT_ComputeJsonAllTags$ = $json$ ENDFN //Log in event logs and BASIC Console FUNCTION Log($Msg$) LOGEVENT "[MQTT Aws IoT SCRIPT] " + $Msg$ ,100 PRINT "[MQTT SCRIPT] " + $Msg$ ENDFN FUNCTION Generate_Aws_CA_Certificate() //WRITE OLD CA CERT In case of Old instances CACRT$ = "-----BEGIN CERTIFICATE-----" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"rqXRfboQnoZsG4q5WTP468SQvvG5" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"-----END CERTIFICATE-----" OPEN "file:/usr/AWS_CA_old.crt" FOR BINARY OUTPUT AS 1 PUT 1, CACRT$ CLOSE 1 //WRITE CA CERT CACRT$ = "-----BEGIN CERTIFICATE-----" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"sSi6" + CHR$(13) + CHR$(10) CACRT$ = CACRT$ +"-----END CERTIFICATE-----" OPEN "file:/usr/AWS_CA.crt" FOR BINARY OUTPUT AS 1 PUT 1, CACRT$ CLOSE 1 ENDFN Function ParseMessage ($message$) leftindex%=1 rightindex% = INSTR 1,message$,"|" For $a% = 1 TO 100 STEP 1 IF rightindex% =0 THEN message_list$($a%, 1 TO 50) = message$(leftindex% TO Len message$ - 1) item_code@ = message_list$(1) item_description@ = message_list$(2) units_expected@ = message_list$(3) standard_people@ = message_list$(4) standard_units_per_hour@ = message_list$(5) actual_people@ = message_list$(6) tmax_perhour@ = message_list$(7) If shift = 1 Then tmax_perhour_s1@ = Val(tmax_perhour@) Max_s1@ = Val(tmax_perhour@) * 1.50 Endif If shift = 2 Then tmax_perhour_s2@ = Val(tmax_perhour@) Max_s1@ = Val(tmax_perhour@) * 1.50 Endif If shift = 3 Then tmax_perhour_s3@ = Val(tmax_perhour@) Max_s1@ = Val(tmax_perhour@) * 1.50 Endif Graph_line@ = Val(tmax_perhour@) * .75 RETURN //print item_code@ ENDIF message_list$($a%, 1 TO 50) = $message$(leftindex% TO rightindex% - 1) leftindex%=rightindex%+1 rightindex% = INSTR leftindex%, message$, "|" NEXT $a% ENDFN Function ParseSimpleJson$($inputJson$, $key$, $CollectionIndex%) $StartIndex% = 1 FOR $i% = 0 TO 10000 $StartBracketPos% = INSTR $StartIndex%, $inputJson$, '{' IF $StartBracketPos% = 0 THEN $ParseSimpleJson$ = "ELEMENT DOES NOT EXIST" RETURN ENDIF IF $CollectionIndex% > 0 THEN $CollectionIndex% = $CollectionIndex% - 1 $StartIndex% = $StartBracketPos% + 1 //Find next element ELSE IF $StartBracketPos% = 0 THEN $ParseSimpleJson$ = "JSON FORMAT NOT VALID" RETURN ELSE $EndBracketPos% = INSTR $StartBracketPos%, $inputJson$, '}' $ELEMENTString$ = $inputJson$($StartBracketPos% TO $EndBracketPos%) $ParseSimpleJson$ = @ExtractKeyValue$($ELEMENTString$, $key$) RETURN ENDIF ENDIF NEXT $i% EndFn Function ExtractKeyValue$($ElementString$, $Key$) $StartPosKey% = INSTR 1,$ElementString$, $key$ $StartPosKeyColumn% = INSTR $StartPosKey% ,$ElementString$, ":" $EndPosKeyColumn% = INSTR $StartPosKeyColumn% ,$ElementString$, ',' $StartPosKeyColumn% = $StartPosKeyColumn% + 1 $EndPosKeyColumn% = $EndPosKeyColumn% - 1 IF $EndPosKeyColumn% = -1 THEN //Last key $EndPosKeyColumn% = LEN $ElementString$ - 1 ENDIF $KeyValue$ = $ElementString$($StartPosKeyColumn% TO $EndPosKeyColumn%) $KeyValue$ = LTRIM $KeyValue$ $KeyValue$ = RTRIM $KeyValue$ IF $KeyValue$(1) = '"' THEN //is a string value -> remove quote $EndKeyValue = LEN $KeyValue$ - 1 $ExtractKeyValue$ = $KeyValue$(2 TO $EndKeyValue) ELSE $ExtractKeyValue$ = $KeyValue$ ENDIF EndFn MQTTProcess: //Disable timer TSET 4,0 @MQTT_CheckConnection() TSET 4, MQTTProcess_CycleTime% TimeSecTemp% = GETSYS PRG , "TIMESEC" //-----------Publish Section----------------------------- IF TimeSecTemp% - FullPushLastTimeSec% >= CONF_FullPushTime% THEN FullPushLastTimeSec% = TimeSecTemp% @MQTT_Publish(@MQTT_ComputeJsonAllTags$) //PRINT "[MQTT SCRIPT] All Tags published" ENDIF //IF TimeSecTemp% - ChangePushLastTimeSec% >= CONF_ChangePushTime% THEN //ChangePushLastTimeSec% = TimeSecTemp% //Json$ = @MQTT_ComputeJsonChangeTags$() //IF Json$ <> "" THEN //@MQTT_Publish(json$) //PRINT "[MQTT SCRIPT] Some Tags have changed - Publish" //ELSE //PRINT "[MQTT SCRIPT] No Tag changes detected! -> Don't publish" //ENDIF //ENDIF //-----------Subscribe Section-------------------------------------- $ConnStatus% = MQTT "STATUS" IF $ConnStatus% = 5 THEN MQTT "subscribe", CONF_DeviceTopic2$, 0 msgID% = MQTT "read" IF msgID% <>0 THEN match_found% =0 inputStr$= MQTT "msgdata" indexElement%=0 indexelement%=0 Loop: site$=@ParseSimpleJson$(inputStr$,"site",indexElement%) IF site$ = "ELEMENT DOES NOT EXIST" THEN GOTO EndLoop //jobname%=@ParseSimpleJson$(inputStr$,"jobname",indexElement%) linename$=@ParseSimpleJson$(inputStr$,"linename",indexElement%) message$=@ParseSimpleJson$(inputStr$,"message",indexElement%) jobtime$=@ParseSimpleJson$(inputStr$,"jobtime",indexElement%) IF linename$ = line_ID$ And site$ = site_ID$ THEN @ParseMessage(message$) match_found%=1 GOTO EndLoop ENDIF indexelement%=indexelement%+1 IF indexElement% < 100 THEN GOTO Loop: EndLoop: IF match_found% = 0 Then item_description@ = 'No Job Found' ENDIF ELSE Print "Not connected (" + STR$ $ConnStatus% + ")" ENDIF END