I have a Node Red Flow that is doing a couple dozen writes to scratch pad per second. (or is supposed to…) It seems to have trouble getting all of them done. I suspect writes are getting queued, but over running the write buffer or something. Here is a screenshot of the Node Red. I’m working to optimize the Flow by combining all scratchpad reads, then combining all writes (Write to multiple RIO scratchpad using 1 groov i/o write node), then perhaps using fewer time injects. Is there anything else I should be doing to this Flow to optimize it?
‘’’
[{“id”:“d1117df142d0a677”,“type”:“tab”,“label”:“Flow 1”,“disabled”:false,“info”:“”,“env”:},{“id”:“4da262bb925e6e4d”,“type”:“debug”,“z”:“d1117df142d0a677”,“name”:“”,“active”:false,“tosidebar”:true,“console”:false,“tostatus”:false,“complete”:“true”,“targetType”:“full”,“statusVal”:“”,“statusType”:“auto”,“x”:1250,“y”:380,“wires”:},{“id”:“4ca5625dc0732e0a”,“type”:“groov-io-write”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“channel-digital”,“moduleIndex”:“0”,“channelIndex”:“8”,“mmpAddress”:“0xF0D81000”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“cmd”,“valueType”:“msg”,“name”:“CMD”,“x”:710,“y”:380,“wires”:[[“08af0b6268a9e1fc”]]},{“id”:“5ce9c4b8158daf57”,“type”:“inject”,“z”:“d1117df142d0a677”,“name”:“Every Second”,“props”:[{“p”:“payload”},{“p”:“topic”,“vt”:“str”}],“repeat”:“1”,“crontab”:“”,“once”:false,“onceDelay”:0.1,“topic”:“”,“payload”:“”,“payloadType”:“date”,“x”:120,“y”:380,“wires”:[[“53ad6dc8c6c139c6”]]},{“id”:“53ad6dc8c6c139c6”,“type”:“groov-io-read”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“channel-analog”,“moduleIndex”:“0”,“channelIndex”:“3”,“mmpAddress”:“0xF0D81004”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“”,“valueType”:“msg.payload”,“itemName”:“”,“name”:“Read Well Level”,“x”:320,“y”:380,“wires”:[[“27b66f186e972aed”]]},{“id”:“4733a47c8ab6da57”,“type”:“inject”,“z”:“d1117df142d0a677”,“name”:“Every Second”,“props”:[{“p”:“payload”},{“p”:“topic”,“vt”:“str”}],“repeat”:“1”,“crontab”:“”,“once”:false,“onceDelay”:0.1,“topic”:“”,“payload”:“”,“payloadType”:“date”,“x”:140,“y”:80,“wires”:[[“2b1c2d4a26d1df58”]]},{“id”:“2b1c2d4a26d1df58”,“type”:“groov-io-read”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“mmp-address”,“moduleIndex”:“”,“channelIndex”:“”,“mmpAddress”:“0xF0D81000”,“mmpType”:“int32”,“mmpLength”:“30”,“mmpEncoding”:“ascii”,“value”:“”,“valueType”:“msg.payload”,“itemName”:“”,“name”:“Load All Scratchpad Values from HMI”,“x”:430,“y”:80,“wires”:[[“7dd524962a7a771d”]]},{“id”:“391821a9e36324f9”,“type”:“debug”,“z”:“d1117df142d0a677”,“name”:“”,“active”:false,“tosidebar”:true,“console”:false,“tostatus”:false,“complete”:“payload”,“targetType”:“msg”,“statusVal”:“”,“statusType”:“auto”,“x”:1290,“y”:80,“wires”:},{“id”:“7dd524962a7a771d”,“type”:“function”,“z”:“d1117df142d0a677”,“name”:“Save HMI Values to flow.*”,“func”:“// Functions for Bits from Stack Overflow\nfunction bit_test(num, bit){\n return ((num>>bit) % 2 != 0)\n}\n\nfunction bit_set(num, bit){\n return num | 1<<bit;\n}\n\nfunction bit_clear(num, bit){\n return num & ~(1<<bit);\n}\n\nfunction bit_toggle(num, bit){\n return bit_test(num, bit) ? bit_clear(num, bit) : bit_set(num, bit);\n}\n\n// HMI Counter:\nvar HMI_Count = flow.get(‘HMI_Count’)||0;\nHMI_Count = msg.payload[0];\nflow.set(‘HMI_Count’,HMI_Count);\n\n// HOA:\nvar HOA = flow.get(‘HOA’)||1;\nHOA = msg.payload[1];\nflow.set(‘HOA’,HOA);\n\n// ON_SP:\nvar ON_SP = flow.get(‘ON_SP’)||17.0;\nON_SP = msg.payload[2]/10.0;\nflow.set(‘ON_SP’,ON_SP);\n\n// OFF_SP:\nvar OFF_SP = flow.get(‘OFF_SP’)||5.0;\nOFF_SP = msg.payload[3]/10.0;\nflow.set(‘OFF_SP’,OFF_SP);\n\n// Speed_SP:\nvar Speed_SP = flow.get(‘Speed_SP’)||100.0;\nSpeed_SP = msg.payload[4]/10.0;\nflow.set(‘Speed_SP’,Speed_SP);\n\n// Pump_Resets:\nvar Pump_Resets = flow.get(‘Pump_Resets’)||0;\nPump_Resets = msg.payload[5];\nflow.set(‘Pump_Resets’,Pump_Resets);\n\n// Flow_Resets:\nvar Flow_Resets = flow.get(‘Flow_Resets’)||0;\nPump_Resets = msg.payload[6];\nflow.set(‘Flow_Resets’,Flow_Resets);\n\n\nmsg.payload = [HMI_Count,HOA,ON_SP,OFF_SP,Speed_SP,Pump_Resets,Flow_Resets]\n\nreturn msg;”,“outputs”:1,“noerr”:0,“initialize”:“”,“finalize”:“”,“libs”:,“x”:810,“y”:80,“wires”:[[“391821a9e36324f9”]]},{“id”:“27b66f186e972aed”,“type”:“function”,“z”:“d1117df142d0a677”,“name”:“Run Pump?”,“func”:“// Level:\nvar Level = flow.get(‘Level’)||1.0;\nvar HOA = flow.get(‘HOA’);\nvar VFD_Fault = flow.get(‘VFD_Fault’)||false;\nvar CMD = flow.get(‘CMD’)||false;\nvar Call = flow.get(‘Call’)||false;\nvar ON_SP = flow.get(‘ON_SP’)||17.0;\nvar OFF_SP = flow.get(‘OFF_SP’)||5.0;\nvar Speed_SP = flow.get(‘Speed_SP’)||100.0;\nLevel = msg.payload;\nflow.set(‘Level’,Level);\n\nswitch(HOA) {\n case 0: \n CMD = false;\n break;\n \n case 1:\n if(Level > ON_SP) {\n CMD = true;\n } else if(Level < OFF_SP) {\n CMD = false;\n } \n break;\n \n case 2:\n CMD = true;\n break;\n \n default:\n break;\n}\n\n\n// if(HOA == 0) {\n// CMD = false;\n// } else if(VFD_Fault) {\n// CMD = false;\n// } else if(HOA == 2) {\n// CMD = true;\n// } else if(HOA == 1) {\n// if(Level > ON_SP) {\n// CMD = true;\n// } else if(Level < OFF_SP) {\n// CMD = false;\n// }\n// } \nif (Level > ON_SP) {\n Call = true;\n} else if (Level < OFF_SP) {\n Call = false;\n}\nflow.set(‘CMD’,CMD);\nflow.set(‘Call’,Call);\n\nif (CMD) { \n msg.speed = Speed_SP\n} else {\n msg.speed = 0.0\n}\n\nmsg.hoa = HOA;\nmsg.cmd = CMD;\nmsg.level = Level * 10;\n\nreturn msg;”,“outputs”:1,“noerr”:0,“initialize”:“”,“finalize”:“”,“libs”:,“x”:530,“y”:380,“wires”:[[“4ca5625dc0732e0a”]]},{“id”:“9684982098190457”,“type”:“groov-io-read”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“channel-digital”,“moduleIndex”:“0”,“channelIndex”:“6”,“mmpAddress”:“0xF0D81000”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“”,“valueType”:“msg.payload”,“itemName”:“”,“name”:“Read VFD Fault”,“x”:320,“y”:280,“wires”:[[“cd948352edc1db67”]]},{“id”:“adfc641cf5f84c6e”,“type”:“inject”,“z”:“d1117df142d0a677”,“name”:“Every Second”,“props”:[{“p”:“payload”},{“p”:“topic”,“vt”:“str”}],“repeat”:“1”,“crontab”:“”,“once”:false,“onceDelay”:0.1,“topic”:“”,“payload”:“”,“payloadType”:“date”,“x”:120,“y”:280,“wires”:[[“9684982098190457”]]},{“id”:“3b407fce5e8fe8d2”,“type”:“debug”,“z”:“d1117df142d0a677”,“name”:“”,“active”:false,“tosidebar”:true,“console”:false,“tostatus”:false,“complete”:“true”,“targetType”:“full”,“statusVal”:“”,“statusType”:“auto”,“x”:1250,“y”:280,“wires”:},{“id”:“cd948352edc1db67”,“type”:“function”,“z”:“d1117df142d0a677”,“name”:“VFD Fault”,“func”:“// Functions for Bits from Stack Overflow\nfunction bit_test(num, bit){\n return ((num>>bit) % 2 != 0)\n}\n\nfunction bit_set(num, bit){\n return num | 1<<bit;\n}\n\nfunction bit_clear(num, bit){\n return num & ~(1<<bit);\n}\n\nfunction bit_toggle(num, bit){\n return bit_test(num, bit) ? bit_clear(num, bit) : bit_set(num, bit);\n}\n\n// Pump_Resets:\nvar Pump_Resets = flow.get(‘Pump_Resets’)||0;\n\n\n// VFD_Fault:\nvar VFD_Fault = flow.get(‘VFD_Fault’)||false;\nVFD_Fault = msg.payload;\nflow.set(‘VFD_Fault’,VFD_Fault);\n// Reset VFD Fault\nvar VFD_Reset = flow.get(‘VFD_Reset’)||false;\nVFD_Reset = bit_test(Pump_Resets, 0)\n\n// Pump_Info\nvar Pump_Info = flow.get(‘Pump_Info’)||0;\nif(VFD_Fault) {\n bit_set(Pump_Info,1);\n}\nif(VFD_Fault == 0) {\n bit_clear(Pump_Info,1);\n Pump_Resets = bit_clear(Pump_Resets,0);\n}\n\nflow.set(‘Pump_Resets’,Pump_Resets);\n\nmsg.fault = VFD_Fault;\nmsg.pump_resets = Pump_Resets;\nmsg.payload = VFD_Reset;\n\nreturn msg;\n”,“outputs”:1,“noerr”:0,“initialize”:“”,“finalize”:“”,“libs”:,“x”:500,“y”:280,“wires”:[[“e195f945d013c80a”]]},{“id”:“b235b59428397b2c”,“type”:“inject”,“z”:“d1117df142d0a677”,“name”:“Every Second”,“props”:[{“p”:“payload”},{“p”:“topic”,“vt”:“str”}],“repeat”:“1”,“crontab”:“”,“once”:false,“onceDelay”:0.1,“topic”:“”,“payload”:“”,“payloadType”:“date”,“x”:120,“y”:180,“wires”:[[“a17a3d7e32c7aca2”]]},{“id”:“d93c646640282293”,“type”:“debug”,“z”:“d1117df142d0a677”,“name”:“”,“active”:false,“tosidebar”:true,“console”:false,“tostatus”:false,“complete”:“false”,“statusVal”:“”,“statusType”:“auto”,“x”:1250,“y”:180,“wires”:},{“id”:“97eefd31a39273e2”,“type”:“function”,“z”:“d1117df142d0a677”,“name”:“PLC Counter”,“func”:“// PLC_Count:\nvar PLC_Count = flow.get(‘PLC_Count’)||0;\nPLC_Count = msg.payload;\n\nPLC_Count++;\n\nif (PLC_Count > 2000000000) {\n PLC_Count = 0;\n}\n\nflow.set(‘PLC_Count’,PLC_Count);\n\nmsg.payload = PLC_Count;\n\nreturn msg;\n”,“outputs”:1,“noerr”:0,“initialize”:“”,“finalize”:“”,“libs”:,“x”:510,“y”:180,“wires”:[[“4f2732ebfca6a3f8”]]},{“id”:“a17a3d7e32c7aca2”,“type”:“groov-io-read”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“mmp-address”,“moduleIndex”:“”,“channelIndex”:“”,“mmpAddress”:“0xF0D81028”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“”,“valueType”:“msg.payload”,“itemName”:“”,“name”:“PLC Counter”,“x”:310,“y”:180,“wires”:[[“97eefd31a39273e2”]]},{“id”:“4f2732ebfca6a3f8”,“type”:“groov-io-write”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“mmp-address”,“moduleIndex”:“”,“channelIndex”:“”,“mmpAddress”:“0xF0D81028”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“”,“valueType”:“msg.payload”,“name”:“Write PLC Count”,“x”:710,“y”:180,“wires”:[[“d93c646640282293”]]},{“id”:“08af0b6268a9e1fc”,“type”:“groov-io-write”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“mmp-address”,“moduleIndex”:“”,“channelIndex”:“”,“mmpAddress”:“0xF0D81030”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“level”,“valueType”:“msg”,“name”:“Level to HMI”,“x”:870,“y”:380,“wires”:[[“50608db94ce33d6e”]]},{“id”:“6a1a8b97793f6464”,“type”:“inject”,“z”:“d1117df142d0a677”,“name”:“Every Second”,“props”:[{“p”:“payload”},{“p”:“topic”,“vt”:“str”}],“repeat”:“1”,“crontab”:“”,“once”:false,“onceDelay”:0.1,“topic”:“”,“payload”:“”,“payloadType”:“date”,“x”:120,“y”:500,“wires”:[[“2e8ff1d8ac30f535”]]},{“id”:“2e8ff1d8ac30f535”,“type”:“groov-io-read”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“channel-digital”,“moduleIndex”:“0”,“channelIndex”:“5”,“mmpAddress”:“0xF0D81004”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“status”,“valueType”:“msg”,“itemName”:“”,“name”:“Read Pump Run Status”,“x”:330,“y”:500,“wires”:[[“be00435fe055d5e4”]]},{“id”:“be00435fe055d5e4”,“type”:“function”,“z”:“d1117df142d0a677”,“name”:“Pump Timers”,“func”:“function bit_test(num, bit){\n return ((num>>bit) % 2 != 0)\n}\n\nfunction bit_set(num, bit){\n return num | 1<<bit;\n}\n\nfunction bit_clear(num, bit){\n return num & ~(1<<bit);\n}\n\nfunction bit_toggle(num, bit){\n return bit_test(num, bit) ? bit_clear(num, bit) : bit_set(num, bit);\n}\n\n// Status:\nvar S_Status = flow.get(‘Status’)||false;\nvar P_Status = msg.status;\nvar Status = msg.status;\nvar StartTime = flow.get(‘StartTime’);\nvar AccTime = 0;\n\n// Pump_Resets:\nvar Pump_Resets = flow.get(‘Pump_Resets’)||0;\n\n// Reset Pump Runtime 1\nvar Pump_R1 = flow.get(‘Pump_R1’)||0;\nPump_R1 = bit_test(Pump_Resets, 1);\nflow.set(‘Pump_R1’,Pump_R1);\n\n// Reset Pump Runtime 2\nvar Pump_R2 = flow.get(‘Pump_R2’)||0;\nPump_R2 = bit_test(Pump_Resets, 2);\nflow.set(‘Pump_R2’,Pump_R2);\n\n// Other Vars\nvar P_Seconds = flow.get(‘P_Seconds’)||0.0;\nvar THours_R0 = flow.get(‘Hours_R0’)||0;\nvar THours_R1 = flow.get(‘Hours_R1’)||0;\nvar THours_R2 = flow.get(‘Hours_R2’)||0;\n\n\nif (StartTime > 1) {\n AccTime = msg.payload - StartTime\n}\n\nif (!S_Status && P_Status) {\n StartTime = msg.payload;\n flow.set(‘StartTime’,StartTime);\n S_Status = true;\n} else if (S_Status && P_Status) {\n P_Seconds = P_Seconds + AccTime / 1000;\n} else if (S_Status && !P_Status) {\n flow.set(‘P_Seconds’,P_Seconds);\n StartTime = 1;\n S_Status = false;\n}\nif (P_Seconds > 360.0) {\n THours_R0++;\n THours_R1++;\n THours_R2++;\n P_Seconds = P_Seconds - 360.0;\n StartTime = msg.payload;\n flow.set(‘THours_R0’,THours_R0);\n flow.set(‘THours_R1’,THours_R1);\n flow.set(‘THours_R2’,THours_R2);\n flow.set(‘P_Seconds’,P_Seconds);\n flow.set(‘StartTime’,StartTime);\n} else if (THours_R0 > 2000000000) {\n THours_R0 = 0;\n flow.set(‘THours_R0’,THours_R0);\n} else if (Pump_R1 || THours_R1 > 2000000000) {\n THours_R1 = 0;\n flow.set(‘THours_R1’,THours_R1);\n Pump_Resets = bit_clear(Pump_Resets, 1);\n} else if (Pump_R2 || THours_R2 > 2000000000) {\n THours_R2 = 0;\n flow.set(‘THours_R2’,THours_R2);\n Pump_Resets = bit_clear(Pump_Resets, 2);\n}\n\nflow.set(‘Pump_Resets’,Pump_Resets);\nflow.set(‘Status’,Status);\n\nmsg.stime = StartTime;\nmsg.pstatus = P_Status;\nmsg.sstatus = S_Status;\nmsg.secs = P_Seconds;\nmsg.hours = [THours_R0, THours_R1, THours_R2]\nmsg.resets = Pump_Resets;\n\nreturn msg;”,“outputs”:1,“noerr”:0,“initialize”:“”,“finalize”:“”,“libs”:,“x”:530,“y”:500,“wires”:[[“75461fc90b894bbd”]]},{“id”:“50608db94ce33d6e”,“type”:“groov-io-write”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“channel-analog”,“moduleIndex”:“0”,“channelIndex”:“4”,“mmpAddress”:“0xF0D81000”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“speed”,“valueType”:“msg”,“name”:“Set Pump Speed CMD”,“x”:1080,“y”:380,“wires”:[[“4da262bb925e6e4d”]]},{“id”:“d51e1d1ed0963045”,“type”:“debug”,“z”:“d1117df142d0a677”,“name”:“”,“active”:false,“tosidebar”:true,“console”:false,“tostatus”:false,“complete”:“true”,“targetType”:“full”,“statusVal”:“”,“statusType”:“auto”,“x”:1250,“y”:500,“wires”:},{“id”:“75461fc90b894bbd”,“type”:“groov-io-write”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“mmp-address”,“moduleIndex”:“”,“channelIndex”:“”,“mmpAddress”:“0xF0D8103C”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“hours[0]”,“valueType”:“msg”,“name”:“Hours”,“x”:670,“y”:500,“wires”:[[“227b4309867593de”]]},{“id”:“227b4309867593de”,“type”:“groov-io-write”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“mmp-address”,“moduleIndex”:“”,“channelIndex”:“”,“mmpAddress”:“0xF0D81040”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“hours[1]”,“valueType”:“msg”,“name”:“Hours”,“x”:790,“y”:500,“wires”:[[“cd1425aecf438fef”]]},{“id”:“cd1425aecf438fef”,“type”:“groov-io-write”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“mmp-address”,“moduleIndex”:“”,“channelIndex”:“”,“mmpAddress”:“0xF0D81044”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“hours[2]”,“valueType”:“msg”,“name”:“Hours”,“x”:910,“y”:500,“wires”:[[“c2cf59c1a615d06a”]]},{“id”:“c09efcbc81408815”,“type”:“inject”,“z”:“d1117df142d0a677”,“name”:“Every Second”,“props”:[{“p”:“payload”},{“p”:“topic”,“vt”:“str”}],“repeat”:“1”,“crontab”:“”,“once”:false,“onceDelay”:0.1,“topic”:“”,“payload”:“”,“payloadType”:“date”,“x”:120,“y”:560,“wires”:[[“fee8f16df449eb1a”]]},{“id”:“fee8f16df449eb1a”,“type”:“groov-io-read”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“channel-analog”,“moduleIndex”:“0”,“channelIndex”:“2”,“mmpAddress”:“0xF0D81004”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“payload”,“valueType”:“msg”,“itemName”:“”,“name”:“Read Pump Run Speed”,“x”:350,“y”:560,“wires”:[[“f3fa617ee9d5a10b”]]},{“id”:“f3fa617ee9d5a10b”,“type”:“function”,“z”:“d1117df142d0a677”,“name”:“Pump Speed”,“func”:“// Pump_Speed:\nvar Pump_Speed = flow.get(‘Pump_Speed’)||0;\nPump_Speed = msg.payload * 10.0;\nflow.set(‘Pump_Speed’,Pump_Speed);\n\n\nmsg.payload = Pump_Speed;\n\n\nreturn msg;”,“outputs”:1,“noerr”:0,“initialize”:“”,“finalize”:“”,“libs”:,“x”:590,“y”:560,“wires”:[[“213afdeaa99701ef”]]},{“id”:“3bf722cf69a93865”,“type”:“debug”,“z”:“d1117df142d0a677”,“name”:“”,“active”:false,“tosidebar”:true,“console”:false,“tostatus”:false,“complete”:“false”,“statusVal”:“”,“statusType”:“auto”,“x”:1270,“y”:560,“wires”:},{“id”:“213afdeaa99701ef”,“type”:“groov-io-write”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“mmp-address”,“moduleIndex”:“”,“channelIndex”:“”,“mmpAddress”:“0xF0D81034”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“”,“valueType”:“msg.payload”,“name”:“Pump Speed”,“x”:790,“y”:560,“wires”:[[“3bf722cf69a93865”]]},{“id”:“b07ec93190189c83”,“type”:“inject”,“z”:“d1117df142d0a677”,“name”:“Every Second”,“props”:[{“p”:“payload”},{“p”:“topic”,“vt”:“str”}],“repeat”:“1”,“crontab”:“”,“once”:false,“onceDelay”:0.1,“topic”:“”,“payload”:“”,“payloadType”:“date”,“x”:120,“y”:620,“wires”:[[“2fec3772d772f4b4”]]},{“id”:“2fec3772d772f4b4”,“type”:“function”,“z”:“d1117df142d0a677”,“name”:“Pump Info Builder”,“func”:“// Pump Bits:\nvar Status = flow.get(‘Status’)||false;\nvar VFD_Fault = flow.get(‘VFD_Fault’)||false;\nvar Call = flow.get(‘Call’)||false;\nvar CMD = flow.get(‘CMD’)||false;\nvar Pump_Info = 0;\n\n\nPump_Info = Status + (VFD_Fault << 1) + (Call << 2) + (CMD << 3)\n\n\nmsg.payload = Pump_Info\n\nreturn msg;\n”,“outputs”:1,“noerr”:0,“initialize”:“”,“finalize”:“”,“libs”:,“x”:550,“y”:620,“wires”:[[“9237eca872020457”]]},{“id”:“4ded074277f550b8”,“type”:“debug”,“z”:“d1117df142d0a677”,“name”:“”,“active”:false,“tosidebar”:true,“console”:false,“tostatus”:false,“complete”:“false”,“statusVal”:“”,“statusType”:“auto”,“x”:1270,“y”:620,“wires”:},{“id”:“9237eca872020457”,“type”:“groov-io-write”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“mmp-address”,“moduleIndex”:“”,“channelIndex”:“”,“mmpAddress”:“0xF0D8102C”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“”,“valueType”:“msg.payload”,“name”:“Pump Info”,“x”:770,“y”:620,“wires”:[[“4ded074277f550b8”]]},{“id”:“500cf5f3f54e8142”,“type”:“inject”,“z”:“d1117df142d0a677”,“name”:“Every Second”,“props”:[{“p”:“payload”},{“p”:“topic”,“vt”:“str”}],“repeat”:“1”,“crontab”:“”,“once”:false,“onceDelay”:0.1,“topic”:“”,“payload”:“”,“payloadType”:“date”,“x”:120,“y”:680,“wires”:[[“3cb04f07142cac5e”]]},{“id”:“3cb04f07142cac5e”,“type”:“groov-io-read”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“channel-analog”,“moduleIndex”:“0”,“channelIndex”:“1”,“mmpAddress”:“0xF0D81004”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“flow”,“valueType”:“msg”,“itemName”:“”,“name”:“Read Flow Meter”,“x”:310,“y”:680,“wires”:[[“2b12fad40dbd568b”]]},{“id”:“2b12fad40dbd568b”,“type”:“function”,“z”:“d1117df142d0a677”,“name”:“Flow Totals”,“func”:“// Functions for Bits from Stack Overflow\nfunction bit_test(num, bit){\n return ((num>>bit) % 2 != 0)\n}\n\nfunction bit_set(num, bit){\n return num | 1<<bit;\n}\n\nfunction bit_clear(num, bit){\n return num & ~(1<<bit);\n}\n\nfunction bit_toggle(num, bit){\n return bit_test(num, bit) ? bit_clear(num, bit) : bit_set(num, bit);\n}\n\n// Flow: (Assuming GPM)\nvar Flow = msg.flow;\nvar Flow_T0 = flow.get(‘Flow_T0’)||1.0;\nvar Flow_T1 = flow.get(‘Flow_T1’);\nvar Flow_T2 = flow.get(‘Flow_T2’);\n\n// HMI_DI:\nvar Flow_Resets = flow.get(‘Flow_Resets’)||0;\nvar Reset1 = bit_test(Flow_Resets, 0);\nvar Reset2 = bit_test(Flow_Resets, 1);\n\nvar Now = msg.payload;\nvar Last = flow.get(‘Last’)||msg.payload;\nvar msecs = Now - Last;\nvar F_Total = flow.get(‘F_Total’);\nvar Counts_Total = 1000.0; // == Galons per Count.\n\nif (Flow > 5.0) {\n if (msecs > 0) {\n weight = msecs / 1000.0;\n sec_Total = Flow * weight / 60.0; // Divide by 60 because we assume GPM. Change for others.\n F_Total += sec_Total; \n }\n if (F_Total > Counts_Total) {\n Flow_T0++;\n Flow_T1++;\n Flow_T2++;\n F_Total -= Counts_Total;\n }\n} \n\nif (Flow_T0 > 2000000000) {\n Flow_T0 = 0;\n}\nif (Reset1 || Flow_T1 > 2000000000) {\n Flow_T1 = 0;\n Flow_Resets = bit_clear(Flow_Resets, 0);\n}\nif (Reset2 || Flow_T2 > 2000000000) {\n Flow_T2 = 0;\n Flow_Resets = bit_clear(Flow_Resets, 1);\n}\nmsg.last = Last;\n\nflow.set(‘Last’,Now);\nflow.set(‘F_Total’,F_Total);\nflow.set(‘Flow_T0’,Flow_T0);\nflow.set(‘Flow_T1’,Flow_T1);\nflow.set(‘Flow_T2’,Flow_T2);\nflow.set(‘Flow_Resets’,Flow_Resets);\nmsg.now = Now;\n\nmsg.msecs = msecs;\nmsg.float = F_Total;\nmsg.resets = Flow_Resets;\nmsg.totals = [Flow_T0,Flow_T1,Flow_T2];\nmsg.payload = Flow * 10;\n\nreturn msg;”,“outputs”:1,“noerr”:0,“initialize”:“”,“finalize”:“”,“libs”:,“x”:490,“y”:680,“wires”:[[“1c6d3caa0ceae154”]]},{“id”:“85e3d8f3a0b3c812”,“type”:“debug”,“z”:“d1117df142d0a677”,“name”:“”,“active”:true,“tosidebar”:true,“console”:false,“tostatus”:false,“complete”:“true”,“targetType”:“full”,“statusVal”:“”,“statusType”:“auto”,“x”:1310,“y”:680,“wires”:},{“id”:“3210d3b5c2800cf3”,“type”:“inject”,“z”:“d1117df142d0a677”,“name”:“Every Second”,“props”:[{“p”:“payload”},{“p”:“topic”,“vt”:“str”}],“repeat”:“1”,“crontab”:“”,“once”:false,“onceDelay”:0.1,“topic”:“”,“payload”:“”,“payloadType”:“date”,“x”:120,“y”:440,“wires”:[[“717e17eb5f08ad65”]]},{“id”:“717e17eb5f08ad65”,“type”:“groov-io-read”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“mmp-address”,“moduleIndex”:“”,“channelIndex”:“”,“mmpAddress”:“0xF0D8103C”,“mmpType”:“int32”,“mmpLength”:“6”,“mmpEncoding”:“ascii”,“value”:“”,“valueType”:“msg.payload”,“itemName”:“”,“name”:“Load Scratchpad Totalizers”,“x”:360,“y”:440,“wires”:[[“ce95301ec25d216b”]]},{“id”:“7a5515285c7a1638”,“type”:“debug”,“z”:“d1117df142d0a677”,“name”:“”,“active”:false,“tosidebar”:true,“console”:false,“tostatus”:false,“complete”:“payload”,“targetType”:“msg”,“statusVal”:“”,“statusType”:“auto”,“x”:1250,“y”:440,“wires”:},{“id”:“ce95301ec25d216b”,“type”:“function”,“z”:“d1117df142d0a677”,“name”:“Save Totals to Flow”,“func”:“// Hours_R0:\nvar Hours_R0 = flow.get(‘Hours_R0’)||0;\nHours_R0 = msg.payload[0];\nflow.set(‘Hours_R0’,Hours_R0);\n\n// Hours_R1:\nvar Hours_R1 = flow.get(‘Hours_R1’)||0;\nHours_R1 = msg.payload[1];\nflow.set(‘Hours_R1’,Hours_R1);\n\n// Hours_R2:\nvar Hours_R2 = flow.get(‘Hours_R2’)||0;\nHours_R2 = msg.payload[2];\nflow.set(‘Hours_R2’,Hours_R2);\n\n// Flow_T0:\nvar Flow_T0 = flow.get(‘Flow_T0’)||0;\nFlow_T0 = msg.payload[3];\nflow.set(‘Flow_T0’,Flow_T0);\n\n// Flow_T1:\nvar Flow_T1 = flow.get(‘Flow_T1’)||0;\nFlow_T1 = msg.payload[4];\nflow.set(‘Flow_T1’,Flow_T1);\n\n// Flow_T2:\nvar Flow_T2 = flow.get(‘Flow_T2’)||0;\nFlow_T2 = msg.payload[5];\nflow.set(‘Flow_T2’,Flow_T2);\n\n\nreturn msg;”,“outputs”:1,“noerr”:0,“initialize”:“”,“finalize”:“”,“libs”:,“x”:650,“y”:440,“wires”:[[“7a5515285c7a1638”]]},{“id”:“7924106d31c13d86”,“type”:“groov-io-write”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“mmp-address”,“moduleIndex”:“”,“channelIndex”:“”,“mmpAddress”:“0xF0D81048”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“totals[0]”,“valueType”:“msg”,“name”:“Totals”,“x”:750,“y”:680,“wires”:[[“0739e337abf25863”]]},{“id”:“0739e337abf25863”,“type”:“groov-io-write”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“mmp-address”,“moduleIndex”:“”,“channelIndex”:“”,“mmpAddress”:“0xF0D8104C”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“totals[1]”,“valueType”:“msg”,“name”:“Totals”,“x”:870,“y”:680,“wires”:[[“c01866a67a2dbb25”]]},{“id”:“c01866a67a2dbb25”,“type”:“groov-io-write”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“mmp-address”,“moduleIndex”:“”,“channelIndex”:“”,“mmpAddress”:“0xF0D81050”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“totals[2]”,“valueType”:“msg”,“name”:“Totals”,“x”:990,“y”:680,“wires”:[[“2d812bd98e3a5a4b”]]},{“id”:“1c6d3caa0ceae154”,“type”:“groov-io-write”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“mmp-address”,“moduleIndex”:“”,“channelIndex”:“”,“mmpAddress”:“0xF0D81038”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“”,“valueType”:“msg.payload”,“name”:“Flow”,“x”:630,“y”:680,“wires”:[[“7924106d31c13d86”]]},{“id”:“65eb083f60f299dd”,“type”:“inject”,“z”:“d1117df142d0a677”,“name”:“”,“props”:[{“p”:“payload”},{“p”:“topic”,“vt”:“str”}],“repeat”:“1800”,“crontab”:“”,“once”:false,“onceDelay”:0.1,“topic”:“”,“payload”:“”,“payloadType”:“date”,“x”:110,“y”:800,“wires”:[[“e6987c7af8fe5bfc”]]},{“id”:“e6987c7af8fe5bfc”,“type”:“groov-io-write”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“mmp-address”,“moduleIndex”:“”,“channelIndex”:“”,“mmpAddress”:“0xF0380000”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“03”,“valueType”:“value”,“name”:“Write Scratchpad to Flash”,“x”:790,“y”:800,“wires”:[[“911426daa82ea136”]]},{“id”:“911426daa82ea136”,“type”:“debug”,“z”:“d1117df142d0a677”,“name”:“”,“active”:false,“tosidebar”:true,“console”:false,“tostatus”:false,“complete”:“payload”,“targetType”:“msg”,“statusVal”:“”,“statusType”:“auto”,“x”:1130,“y”:800,“wires”:},{“id”:“e195f945d013c80a”,“type”:“groov-io-write”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“channel-digital”,“moduleIndex”:“0”,“channelIndex”:“9”,“mmpAddress”:“0xF0D81000”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“”,“valueType”:“msg.payload”,“name”:“Reset”,“x”:650,“y”:280,“wires”:[[“2ef299ace042eb49”]]},{“id”:“2ef299ace042eb49”,“type”:“groov-io-write”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“mmp-address”,“moduleIndex”:“0”,“channelIndex”:“”,“mmpAddress”:“0xF0D81014”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“pump_resets”,“valueType”:“msg”,“name”:“Pump Resets”,“x”:840,“y”:280,“wires”:[[“3b407fce5e8fe8d2”]]},{“id”:“c2cf59c1a615d06a”,“type”:“groov-io-write”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“mmp-address”,“moduleIndex”:“0”,“channelIndex”:“”,“mmpAddress”:“0xF0D81014”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“resets”,“valueType”:“msg”,“name”:“Pump Resets”,“x”:1080,“y”:500,“wires”:[[“d51e1d1ed0963045”]]},{“id”:“2d812bd98e3a5a4b”,“type”:“groov-io-write”,“z”:“d1117df142d0a677”,“device”:“4e9fa67a17225a9e”,“dataType”:“mmp-address”,“moduleIndex”:“0”,“channelIndex”:“”,“mmpAddress”:“0xF0D81018”,“mmpType”:“int32”,“mmpLength”:“1”,“mmpEncoding”:“ascii”,“value”:“resets”,“valueType”:“msg”,“name”:“Flow Resets”,“x”:1130,“y”:680,“wires”:[[“85e3d8f3a0b3c812”]]},{“id”:“4e9fa67a17225a9e”,“type”:“groov-io-device”,“address”:“localhost”,“msgQueueFullBehavior”:“DROP_OLD”}]
‘’’