/** * @author Martin Karkowski * @email m.karkowski@zema.de * @create date 2020-07-16 10:52:32 * @modify date 2020-11-25 07:37:04 * @desc [description] */ export const LOGIC_TEMPLATES: { [index: string]: string; } = { // Template to define the Places. // // Requires the following Input: // { // places: [ {id: string} ] // options.nameOfStatesType: string // } statesStructTemplate: ` `, transitionStructTemplate: ` `, transitionVariableTemplate: ` `, ifHeaderTemplate: "IF ({{> testConsumedPlaces}}{{> testRequiredPlaces}}{{> testAvoidedPlaces}}{{> testPostPlaces}}{{> testGuard}} {{>testTime}} {{#if isAction}}aTransitions.{{id}}.bRelease AND{{/if}} iRecursionCounter < {{options.maxRecursion}}) THEN", testConsumedPlaces: "{{#each consumed}} ((aTokens.{{placeId}}{{#if minTokens}} - {{minTokens}}{{/if}}) >= {{tokensToRemove}}) AND{{/each}}", testRequiredPlaces: "{{#each required}} (aTokens.{{placeId}} > 0) AND{{/each}}", testAvoidedPlaces: "{{#each avoided}} (aTokens.{{placeId}} = 0) AND{{/each}}", testPostPlaces: "{{#if hasTestOutputs}}{{#each testOutputs}} ((aTokens.{{placeId}} + {{tokensToAdd}}) <= {{maxTokens}}) AND{{/each}}{{/if}}", testGuard: " {{{ externalGuard }}}", testTime: "AND (aTransitions.{{id}}.bTimeParamsValid AND iDeltaTime >= aTransitions.{{id}}.iCurrentMinTime AND (NOT(aTransitions.{{id}}.bUseMaxTime) OR iDeltaTime <= aTransitions.{{id}}.iCurrentMinTime)) AND", removeTokens: "{{#each consumed}}aTokens.{{placeId}} := aTokens.{{placeId}} - {{tokensToRemove}};{{/each}}", addTokens: "{{#each produced}}aTokens.{{placeId}} := aTokens.{{placeId}} + {{tokensToAdd}};{{/each}}", ifLogicalHeaderTemplate: "IF ({{> testConsumedPlaces}}{{> testRequiredPlaces}}{{> testAvoidedPlaces}}{{> testPostPlaces}} TRUE) THEN", // Template to define a Method on a Function-Block. // // Requires the following Input: // { // functionName: string, // // Contains the Returnvalue. // functionReturnValue: string, // // Containing the Inputs // functionInputs: string, // // Containing the Implementation // functionImplementation: string // } fbTransitionFunctionTemplate: "" + ` ifHeaderTemplate}} {{#if hasInputs}} // Removing Tokens from Pre-Places. {{> removeTokens}} {{#each consumed}} {{#timeAdaption this.placeId}}{{/timeAdaption}} {{/each}} {{/if}} {{#if hasOutputs}} // Adding Tokens to the Post-Places. {{> addTokens}} {{#each produced}} {{#timeAdaption this.placeId}}{{/timeAdaption}} {{/each}} {{/if}} {{#if functionName}} // Execute the desired Function {{#getFunctionTriggerCode this}}{{/getFunctionTriggerCode}} {{/if}} IF bEnableMQTT THEN // If MQTT is enabled just forward the fired Transition. sId:= '{{id}}'; fbMqttClient.Publish('{{options.nameOfPlc}}/fired',ADR(sID),LEN(sID),1,FALSE,FALSE); END_IF {{#if isAction}} // Remove the Release aTransitions.{{id}}.bRelease := FALSE; {{/if}} // Mark the Transition as Triggered bTempTriggered := TRUE; {{#if hasTriggers}} // Prepare Triggering Elements. iTempRecursionCounter := iRecursionCounter + 1; {{#each triggered}} // Trigger Transition {{{label}}} {{methodName}}(iTempRecursionCounter, TRUE, iCurrentTime); {{/each}} {{/if}} {{#if hasReleases}} {{#each releases}} // Set a Release to Transition {{{label}}} aTransitions.{{this}}.bRelease := TRUE; {{/each}} {{/if}} {{#if hasLocks}} {{#each locks}} // Lock the Transition {{{label}}} aTransitions.{{this}}.bRelease := FALSE; {{/each}} {{/if}} END_IF // Transmit the Result. {{methodName}} := bTempTriggered;]]> `, fbTransitionAdaptTimesFunctionTemplate: "" + ` ifLogicalHeaderTemplate}} // The Transtion is logically able to Fire. bTempEnabled := TRUE; // Determine the Valid-Timestamp. aTransitions.{{id}}.iCurrentMinTime := aTransitions.{{id}}.iMinTime + iCurrentTime; aTransitions.{{id}}.iCurrentMaxTime := aTransitions.{{id}}.iMaxTime + iCurrentTime; // Mark the Element as Enabled. aTransitions.{{id}}.bTimeParamsValid := TRUE; ELSE // Mark the Element as Enabled. aTransitions.{{id}}.bTimeParamsValid := FALSE; END_IF // Transmit the Result. {{methodName}}_ADAPT_TIMES := bTempEnabled;]]> `, // Template to define a logic based on a Petri-net. // // Requires the following Input: // { // uuid: '{uuid}', // fbName: string, // // Contains the Returnvalue. // functionReturnValue: string, // // Containing the Inputs // functionInputs: string, // // Containing the Implementation // functionImplementation: string // } mainTemplate: ` Returns the Length iStateLength := fbJson.CopyDocument(sState, SIZEOF(sState)); // Publish the State IF iStateLength > 0 THEN fbMqttClient.Publish('plc-0003/logic',ADR(sState),iStateLength,1,FALSE,FALSE); END_IF ELSE // Call the Timer fbTONUpdateStates(IN:=TRUE,PT:=T#1000MS); END_IF END_IF END_IF // Determine if the Logic is allowed to execute IF bEnableMQTT AND bEnableLogic THEN // Only allow the Logic to go one, if the MQTT-Client is connected bLogicEnabled := fbMqttClient.bConnected; ELSE // MQTT is disabled => Use the Enable Flag. bLogicEnabled := bEnableLogic; END_IF // The Main Loop. This Loop contains the compiled Petri-Net IF bLogicEnabled THEN // Update the Inputs read_inputs(); // Get the Current Time fbTime(timeLoDW=>iTimeLoPart, timeHiDW=>iTimeHiPart); // Convert The Time to an LWORD Value. iTimeLo64 := UDINT_TO_LWORD(iTimeLoPart); iTimeHi64 := UDINT_TO_LWORD(iTimeHiPart); // Assemble the current Time. (Shift the Higher one by 2**32) iCurrentTime := (iTimeHi64 * 4294967296 + iTimeLo64); // The Resolution is 1 ms (Originally 100ns => Resolution) iCurrentTime := iCurrentTime / (1000 * 1000 / 100); // If the Programm runs the First time or the Logic should be // resetted => Reset the Tokens of the Petri-Net. IF bFirstRun OR bResetLogic THEN // Resetting the State of the Petri-Net reset_tokens(); // Turn Off logic Reset. bResetLogic := FALSE; bFirstRun := FALSE; // During the First Run Assing the Start-Time iStartTime := iCurrentTime; // Upadte the Time-Parameters. reset_transtions(); END_IF // Determine the Delta of the time. iDeltaTime := iCurrentTime - iStartTime; // Flag, indicating whether the System should test for other Transitions or not. bRunTestLoop := TRUE; // Reset the Iteration iIterationCounter iIterationCounter := 0; WHILE bRunTestLoop AND iIterationCounter < {{options.maxIterations}} DO // Mark the Loop as tested. bRunTestLoop := FALSE; // Update and Call the Instances updateInstances(); callInstances(); // Rise the Iteration Counter. iIterationCounter := iIterationCounter + 1; {{#each transitionsSortedByPriority}} {{#if isFirst}}IF{{/if}}{{#unless isFirst}}ELSIF{{/unless}} {{methodName}}(0, FALSE, iDeltaTime) THEN // Transition "{{{label}}}" fired! bRunTestLoop := TRUE; {{#if isLast}} END_IF {{/if}} {{/each}} END_WHILE END_IF ]]> {{#each transitions}} {{> fbTransitionFunctionTemplate}} {{> fbTransitionAdaptTimesFunctionTemplate}} {{/each}} 0 THEN IF fbMessageQueue.Dequeue(fbMessage:=fbMessage) THEN // Assign the Message handling based on the Topic: fbMessage.GetTopic(pTopic:=ADR(sTopicRcv), nTopicSize:=SIZEOF(sTopicRcv) ); sPayloadRcv := ''; fbMessage.GetPayload(pPayload:=ADR(sPayloadRcv), nPayloadSize:=SIZEOF(sPayloadRcv), bSetNullTermination:=TRUE); IF sTopicRcv=sMQTTTopicRelease THEN {{#each actions}} {{#if isFirst}}IF{{/if}}{{#unless isFirst}}ELSIF{{/unless}} bEnableLogic AND sPayloadRcv = '"{{id}}"' THEN // Release the Transition {{label}} aTransitions.{{id}}.bRelease := TRUE; {{#if isLast}} END_IF {{/if}}{{/each}} ELSIF sTopicRcv=sMQTTTopicLocK THEN {{#each actions}} {{#if isFirst}}IF{{/if}}{{#unless isFirst}}ELSIF{{/unless}} bEnableLogic AND sPayloadRcv = '"{{id}}"' THEN // Lock the Transition {{label}} aTransitions.{{id}}.bRelease := FALSE; {{#if isLast}} END_IF {{/if}}{{/each}} ELSIF sTopicRcv=sMQTTTopicTrigger THEN {{#each actions}} {{#if isFirst}}IF{{/if}}{{#unless isFirst}}ELSIF{{/unless}} bEnableLogic AND sPayloadRcv = '"{{id}}"' THEN // Trigger Transition {{label}} {{methodName}}(0, FALSE, iCurrentTime); {{#if isLast}} END_IF {{/if}}{{/each}} END_IF END_IF END_IF ]]> `, plcProject: ` 1.0.0.0 2.0 {d052bc74-6748-44e9-ab97-c76a5465eacb} True true true false Testcode 3.1.4023.0 {bbff2287-a113-4d28-8f6d-efcabdf5d264} {b24aea9d-6e67-48f8-a831-3bc6f2342ea4} {da805644-4748-448f-b5b2-6ca842e9030d} {56ede67f-e61e-4c59-92de-6e963a28d9bb} {cd90ab99-2020-4094-a370-afc280347629} {114fa4ae-03f9-4200-addb-a4bf60a385a9} {{#each codeFiles}} Code {{/each}} Tc2_Standard, * (Beckhoff Automation GmbH) Tc2_Standard Tc2_System, * (Beckhoff Automation GmbH) Tc2_System Tc2_Utilities, * (Beckhoff Automation GmbH) Tc2_Utilities Tc3_IotBase, * (Beckhoff Automation GmbH) Tc3_IotBase Tc3_Module, * (Beckhoff Automation GmbH) Tc3_Module "<ProjectRoot>" {192FAD59-8248-4824-A8DE-9177C94C195A} "{192FAD59-8248-4824-A8DE-9177C94C195A}" {8F99A816-E488-41E4-9FA3-846536012284} "{8F99A816-E488-41E4-9FA3-846536012284}" {40450F57-0AA3-4216-96F3-5444ECB29763} "{40450F57-0AA3-4216-96F3-5444ECB29763}" ActiveVisuProfile IR0whWr8bwfwBwAAhiaVXgAAAABVAgAAWdTSaQAAAAABAAAAAAAAAAEaUwB5AHMAdABlAG0ALgBTAHQAcgBpAG4AZwACTHsAZgA5ADUAYgBiADQAMgA2AC0ANQA1ADIANAAtADQAYgA0ADUALQA5ADQAMAAwAC0AZgBiADAAZgAyAGUANwA3AGUANQAxAGIAfQADCE4AYQBtAGUABDBUAHcAaQBuAEMAQQBUACAAMwAuADEAIABCAHUAaQBsAGQAIAA0ADAAMgA0AC4AMAAFFlAAcgBvAGYAaQBsAGUARABhAHQAYQAGTHsAMQA2AGUANQA1AGIANgAwAC0ANwAwADQAMwAtADQAYQA2ADMALQBiADYANQBiAC0ANgAxADQANwAxADMAOAA3ADgAZAA0ADIAfQAHEkwAaQBiAHIAYQByAGkAZQBzAAhMewAzAGIAZgBkADUANAA1ADkALQBiADAANwBmAC0ANABkADYAZQAtAGEAZQAxAGEALQBhADgAMwAzADUANgBhADUANQAxADQAMgB9AAlMewA5AGMAOQA1ADgAOQA2ADgALQAyAGMAOAA1AC0ANAAxAGIAYgAtADgAOAA3ADEALQA4ADkANQBmAGYAMQBmAGUAZABlADEAYQB9AAoOVgBlAHIAcwBpAG8AbgALBmkAbgB0AAwKVQBzAGEAZwBlAA0KVABpAHQAbABlAA4aVgBpAHMAdQBFAGwAZQBtAE0AZQB0AGUAcgAPDkMAbwBtAHAAYQBuAHkAEAxTAHkAcwB0AGUAbQARElYAaQBzAHUARQBsAGUAbQBzABIwVgBpAHMAdQBFAGwAZQBtAHMAUwBwAGUAYwBpAGEAbABDAG8AbgB0AHIAbwBsAHMAEyhWAGkAcwB1AEUAbABlAG0AcwBXAGkAbgBDAG8AbgB0AHIAbwBsAHMAFCRWAGkAcwB1AEUAbABlAG0AVABlAHgAdABFAGQAaQB0AG8AcgAVIlYAaQBzAHUATgBhAHQAaQB2AGUAQwBvAG4AdAByAG8AbAAWFHYAaQBzAHUAaQBuAHAAdQB0AHMAFwxzAHkAcwB0AGUAbQAYGFYAaQBzAHUARQBsAGUAbQBCAGEAcwBlABkmRABlAHYAUABsAGEAYwBlAGgAbwBsAGQAZQByAHMAVQBzAGUAZAAaCGIAbwBvAGwAGyJQAGwAdQBnAGkAbgBDAG8AbgBzAHQAcgBhAGkAbgB0AHMAHEx7ADQAMwBkADUAMgBiAGMAZQAtADkANAAyAGMALQA0ADQAZAA3AC0AOQBlADkANAAtADEAYgBmAGQAZgAzADEAMABlADYAMwBjAH0AHRxBAHQATABlAGEAcwB0AFYAZQByAHMAaQBvAG4AHhRQAGwAdQBnAGkAbgBHAHUAaQBkAB8WUwB5AHMAdABlAG0ALgBHAHUAaQBkACBIYQBmAGMAZAA1ADQANAA2AC0ANAA5ADEANAAtADQAZgBlADcALQBiAGIANwA4AC0AOQBiAGYAZgBlAGIANwAwAGYAZAAxADcAIRRVAHAAZABhAHQAZQBJAG4AZgBvACJMewBiADAAMwAzADYANgBhADgALQBiADUAYwAwAC0ANABiADkAYQAtAGEAMAAwAGUALQBlAGIAOAA2ADAAMQAxADEAMAA0AGMAMwB9ACMOVQBwAGQAYQB0AGUAcwAkTHsAMQA4ADYAOABmAGYAYwA5AC0AZQA0AGYAYwAtADQANQAzADIALQBhAGMAMAA2AC0AMQBlADMAOQBiAGIANQA1ADcAYgA2ADkAfQAlTHsAYQA1AGIAZAA0ADgAYwAzAC0AMABkADEANwAtADQAMQBiADUALQBiADEANgA0AC0ANQBmAGMANgBhAGQAMgBiADkANgBiADcAfQAmFk8AYgBqAGUAYwB0AHMAVAB5AHAAZQAnVFUAcABkAGEAdABlAEwAYQBuAGcAdQBhAGcAZQBNAG8AZABlAGwARgBvAHIAQwBvAG4AdgBlAHIAdABpAGIAbABlAEwAaQBiAHIAYQByAGkAZQBzACgQTABpAGIAVABpAHQAbABlACkUTABpAGIAQwBvAG0AcABhAG4AeQAqHlUAcABkAGEAdABlAFAAcgBvAHYAaQBkAGUAcgBzACs4UwB5AHMAdABlAG0ALgBDAG8AbABsAGUAYwB0AGkAbwBuAHMALgBIAGEAcwBoAHQAYQBiAGwAZQAsEnYAaQBzAHUAZQBsAGUAbQBzAC1INgBjAGIAMQBjAGQAZQAxAC0AZAA1AGQAYwAtADQAYQAzAGIALQA5ADAANQA0AC0AMgAxAGYAYQA3ADUANgBhADMAZgBhADQALihJAG4AdABlAHIAZgBhAGMAZQBWAGUAcgBzAGkAbwBuAEkAbgBmAG8AL0x7AGMANgAxADEAZQA0ADAAMAAtADcAZgBiADkALQA0AGMAMwA1AC0AYgA5AGEAYwAtADQAZQAzADEANABiADUAOQA5ADYANAAzAH0AMBhNAGEAagBvAHIAVgBlAHIAcwBpAG8AbgAxGE0AaQBuAG8AcgBWAGUAcgBzAGkAbwBuADIMTABlAGcAYQBjAHkAMzBMAGEAbgBnAHUAYQBnAGUATQBvAGQAZQBsAFYAZQByAHMAaQBvAG4ASQBuAGYAbwA0MEwAbwBhAGQATABpAGIAcgBhAHIAaQBlAHMASQBuAHQAbwBQAHIAbwBqAGUAYwB0ADUaQwBvAG0AcABhAHQAaQBiAGkAbABpAHQAeQDQAAIaA9ADAS0E0AUGGgfQBwgaAUUHCQjQAAkaBEUKCwQDAAAABQAAAA0AAAAAAAAA0AwLrQIAAADQDQEtDtAPAS0Q0AAJGgRFCgsEAwAAAAUAAAANAAAAFQAAANAMC60BAAAA0A0BLRHQDwEtENAACRoERQoLBAMAAAAFAAAADQAAAAAAAADQDAutAgAAANANAS0S0A8BLRDQAAkaBEUKCwQDAAAABQAAAA0AAAAUAAAA0AwLrQIAAADQDQEtE9APAS0Q0AAJGgRFCgsEAwAAAAUAAAANAAAAAAAAANAMC60CAAAA0A0BLRTQDwEtENAACRoERQoLBAMAAAAFAAAADQAAAAAAAADQDAutAgAAANANAS0V0A8BLRDQAAkaBEUKCwQDAAAABQAAAA0AAAAAAAAA0AwLrQIAAADQDQEtFtAPAS0X0AAJGgRFCgsEAwAAAAUAAAANAAAAFQAAANAMC60EAAAA0A0BLRjQDwEtENAZGq0BRRscAdAAHBoCRR0LBAMAAAAFAAAADQAAAAAAAADQHh8tINAhIhoCRSMkAtAAJRoFRQoLBAMAAAADAAAAAAAAAAoAAADQJgutAAAAANADAS0n0CgBLRHQKQEtENAAJRoFRQoLBAMAAAADAAAAAAAAAAoAAADQJgutAQAAANADAS0n0CgBLRHQKQEtEJoqKwFFAAEC0AABLSzQAAEtF9AAHy0t0C4vGgPQMAutAQAAANAxC60XAAAA0DIarQDQMy8aA9AwC60CAAAA0DELrQMAAADQMhqtANA0Gq0A0DUarQA= System.Collections.Hashtable {54dd0eac-a6d8-46f2-8c27-2f43c7e49861} System.String `, plcTask: ` 10000 20 {{nameOfMainFb}} {40b78878-0487-47d4-ba7d-2f596fd0f0fe} {bf297dd4-78e5-43f2-b98d-3899ae75bf54} {9e24ead9-19c2-4f25-b930-d7c9fbcaf678} {94c51f5d-cf3e-4304-857a-330e87fa21ab} {a9235a07-fbb3-4457-81e0-1ff81b29917f} `, gvlLogic: ` ` };