Flashing LED's on dashboard for kWh for High or Low rate is active

Hi

My kWh meter displays a low and a high rate (counters).

I have an MQTT connection to Node Red.

When the high rate is active, I would like an LED light on my dashboard to flash. And the same applies when the low rate is active.

I have tried to create a program that reads the high rate; when this high rate (counter) is active, the counter reading increases (when there is a load, of course).
But the program didn't work, what did I wrong?

[
    {
        "id": "5402ec8d1874bad7",
        "type": "function",
        "z": "0e30872a391bd11c",
        "name": "Low Rate Pulse",
        "func": "const message = msg.payload\nlet lrpulse = flow.get(\"pulselr\") || 0\nlet lowr = flow.get(\"lowrate\")\n\nif (message == 1)\n{\n    flow.set(\"lrtmphold\", lowr)\n    flow.set(\"pulselr\",0)\n    return\n}\n \nif (lowr == flow.get(\"lrtmphold\"))\n{\n    flow.set(\"pulselr\",0)\n    return\n}\n\nif (lowr > flow.get(\"lrtmphold\"))\n{\n    flow.set(\"pulslr\",1)\n    setTimeout(flow.set(\"lrtmphold\",lowr),1000)\n}\nreturn msg",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 300,
        "y": 460,
        "wires": [
            []
        ]
    },
    {
        "id": "d919a1f451322c97",
        "type": "change",
        "z": "0e30872a391bd11c",
        "name": "read pulse",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "#:(file)::pulselr",
                "tot": "flow"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 290,
        "y": 400,
        "wires": [
            [
                "46e24baf577e33b1"
            ]
        ]
    },
    {
        "id": "46e24baf577e33b1",
        "type": "debug",
        "z": "0e30872a391bd11c",
        "name": "debug 12",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 480,
        "y": 400,
        "wires": []
    },
    {
        "id": "343eadba06597da1",
        "type": "inject",
        "z": "0e30872a391bd11c",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "1",
        "payloadType": "num",
        "x": 90,
        "y": 460,
        "wires": [
            [
                "5402ec8d1874bad7",
                "d919a1f451322c97"
            ]
        ]
    }
]
  1. Precisely how does Node-red know when the active rate switches from low to high and vice versa?
  2. Are you using HomeAssistant?
  3. What dashboard add-on are you using, and how is the LED implemented?
  1. Node Red doesn't know when the active rate switches. I see the active rate because of the increasing counter.
  2. Domoticz has a connection with the kWh-meter (P1) and there a MQTT connection from Domoticz to Node Red.
  3. I am using Dashboard 2.0, the LED's are not yet implemented for this application.

I am not familiar with Domotiz so forgive me if my questions seem to make little sense.
I can't understand your use of context variables, nor what setTimeout brings to the party.

Domoticz publishes an MQTT message at intervals, which Node-red is subscribed to?
How frequently?
Can you give us an example of this mqtt message?
Please explain the mechanism by which you get from having a counter (count of what?) to knowing that High/Low rate is active.

I don't know exactly the message interval (about 1sec.)
Below the outcome from the MQTT regarding the high and low rate (filtered "by idx:1")


Below including comments

[
    {
        "id": "5402ec8d1874bad7",
        "type": "function",
        "z": "0e30872a391bd11c",
        "name": "Low Rate Pulse",
        "func": "const message = msg.payload\nlet lrpulse = flow.get(\"pulselr\") || 0 \n//Low Rate pulse \nlet lowr = flow.get(\"lowrate\")\n// Low rate come's from MQTT (svalue1)\n\nif (message == 1)\n{\n    flow.set(\"lrtmphold\", lowr)\n    // lrtmphold = Low rate temporary Hold\n    flow.set(\"pulselr\",0)\n    // pulselr, i use it for the flashing led\n    return\n}\n \nif (lowr == flow.get(\"lrtmphold\"))\n{\n    flow.set(\"pulselr\",0)\n    return\n}\n\nif (lowr > flow.get(\"lrtmphold\"))\n{\n    flow.set(\"pulselr\",1)\n    setTimeout(flow.set(\"lrtmphold\",lowr),1000)\n    // I try to use a delay to make the temporary hold the same ase the current low rate counter setting\n}\nreturn msg",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 300,
        "y": 460,
        "wires": [
            []
        ]
    },
    {
        "id": "343eadba06597da1",
        "type": "inject",
        "z": "0e30872a391bd11c",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "1",
        "payloadType": "num",
        "x": 90,
        "y": 460,
        "wires": [
            [
                "5402ec8d1874bad7",
                "d919a1f451322c97"
            ]
        ]
    },
    {
        "id": "d919a1f451322c97",
        "type": "change",
        "z": "0e30872a391bd11c",
        "name": "read pulse",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "#:(file)::pulselr",
                "tot": "flow"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 290,
        "y": 400,
        "wires": [
            []
        ]
    }
]

Active rate

I see this in your code, which may be a clue:

// Low rate come's from MQTT (svalue1)

I expect you have some understanding of how an msg.payload.svalue1 equal to "1358069" indicates that the low rate is currently active, but you don't seem to have explained it.

However, here is a function node which will compare a value extracted from message.payload with the previously seen value stored in context.

const thisvalue = msg.payload   // Extract the latest value from payload
const lastvalue = context.get("lastvalue") || 0  // and previous value from context

if (thisvalue > lastvalue) {   // Do some sort of comparison
    msg.payload = "LARGER"
}
else {
    msg.payload = "NO LARGER"
}

context.set("lastvalue", thisvalue)
return msg;

You might be able to adapt this to your input data. Note that your msg.payload.svalue1 is a string not a number, and you may wish to convert it to a number before doing any comparison.

Making an LED flash

My preferred way would be to use a custom class and CSS animation for this. While there is an LED widget for both dashboard 1 and 2, neither of them has the ability to accept a custom class. Therefore you need some jiggery-pokery to apply the CSS animation to the LED. This is an example using Dashboard 2

[{"id":"f6ed848e6f96a4f5","type":"ui-template","z":"dc69179c349b2cd7","group":"","page":"b3ca132d0792292e","ui":"","name":"CSS","order":0,"width":0,"height":0,"head":"","format":"@keyframes blink-animation {\n50% {\nvisibility: hidden;\n}\n}\n\n.myClass:has(.blink) .nrdb-ui-led  {\n animation: blink-animation 1s steps(1, start) 0s infinite;\n}\n\n.myclass:has(.noblink) .nrdb-ui-led {\nanimation: none;\n}","storeOutMessages":true,"passthru":true,"resendOnRefresh":true,"templateScope":"page:style","className":"","x":800,"y":50,"wires":[[]]},{"id":"a53524c1ceccc021","type":"ui-button","z":"dc69179c349b2cd7","group":"2bf45d898cab6025","name":"Blink","label":"Blink","order":4,"width":"1","height":"1","emulateClick":false,"tooltip":"","color":"","bgcolor":"","className":"","icon":"","iconPosition":"left","payload":"blink","payloadType":"str","topic":"topic","topicType":"msg","buttonColor":"","textColor":"","iconColor":"","enableClick":true,"enablePointerdown":false,"pointerdownPayload":"","pointerdownPayloadType":"str","enablePointerup":false,"pointerupPayload":"","pointerupPayloadType":"str","x":366,"y":111,"wires":[["3fc49ca1d0a1a7e1"]]},{"id":"17f68243bed3b672","type":"ui-button","z":"dc69179c349b2cd7","group":"2bf45d898cab6025","name":"No Blink","label":"Noblink","order":5,"width":"1","height":"1","emulateClick":false,"tooltip":"","color":"","bgcolor":"","className":"","icon":"","iconPosition":"left","payload":"noblink","payloadType":"str","topic":"topic","topicType":"msg","buttonColor":"","textColor":"","iconColor":"","enableClick":true,"enablePointerdown":false,"pointerdownPayload":"","pointerdownPayloadType":"str","enablePointerup":false,"pointerupPayload":"","pointerupPayloadType":"str","x":376,"y":151,"wires":[["3fc49ca1d0a1a7e1"]]},{"id":"3fc49ca1d0a1a7e1","type":"change","z":"dc69179c349b2cd7","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"ui_update.class","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":590,"y":125,"wires":[["ab11f1e8284fa144"]]},{"id":"15bccb2e95d0f039","type":"ui-led","z":"dc69179c349b2cd7","name":"","group":"2bf45d898cab6025","order":1,"width":"2","height":"2","label":"","labelPlacement":"left","labelAlignment":"left","states":[{"value":"false","valueType":"bool","color":"#ff0000"},{"value":"true","valueType":"bool","color":"#00ff00"}],"allowColorForValueInMessage":false,"shape":"circle","showBorder":false,"showGlow":true,"x":550,"y":250,"wires":[]},{"id":"ab11f1e8284fa144","type":"ui-text","z":"dc69179c349b2cd7","group":"2bf45d898cab6025","order":6,"width":"2","height":"1","name":"Dummy text widget","label":" ","format":"{{msg.payload}}","layout":"row-left","style":false,"font":"","fontSize":16,"color":"#717171","wrapText":false,"className":"","value":" ","valueType":"str","x":835,"y":125,"wires":[]},{"id":"d8877d4e349e1aba","type":"ui-button","z":"dc69179c349b2cd7","group":"2bf45d898cab6025","name":"Red","label":"Red","order":2,"width":"1","height":"1","emulateClick":false,"tooltip":"","color":"","bgcolor":"","className":"","icon":"","iconPosition":"left","payload":"false","payloadType":"bool","topic":"topic","topicType":"msg","buttonColor":"","textColor":"","iconColor":"","enableClick":true,"enablePointerdown":false,"pointerdownPayload":"","pointerdownPayloadType":"str","enablePointerup":false,"pointerupPayload":"","pointerupPayloadType":"str","x":375,"y":200,"wires":[["15bccb2e95d0f039","7e6ba07426701994"]]},{"id":"373be2e7dc7d25bc","type":"ui-button","z":"dc69179c349b2cd7","group":"2bf45d898cab6025","name":"Green","label":"Green","order":3,"width":"1","height":"1","emulateClick":false,"tooltip":"","color":"","bgcolor":"","className":"","icon":"","iconPosition":"left","payload":"true","payloadType":"bool","topic":"topic","topicType":"msg","buttonColor":"","textColor":"","iconColor":"","enableClick":true,"enablePointerdown":false,"pointerdownPayload":"","pointerdownPayloadType":"str","enablePointerup":false,"pointerupPayload":"","pointerupPayloadType":"str","x":375,"y":250,"wires":[["15bccb2e95d0f039","7e6ba07426701994"]]},{"id":"7e6ba07426701994","type":"change","z":"dc69179c349b2cd7","name":"","rules":[{"t":"set","p":"ui_update.class","pt":"msg","to":"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":610,"y":200,"wires":[["ab11f1e8284fa144"]]},{"id":"b3ca132d0792292e","type":"ui-page","name":"Test","ui":"d45641ed6d39fea1","path":"/test","icon":"home","layout":"grid","theme":"c835807cdc98644e","breakpoints":[{"name":"Default","px":"0","cols":"3"},{"name":"Tablet","px":"576","cols":"6"},{"name":"Small Desktop","px":"768","cols":"9"},{"name":"Desktop","px":"1024","cols":"12"}],"order":1,"className":"","visible":"true","disabled":"false"},{"id":"2bf45d898cab6025","type":"ui-group","name":"GroupTest","page":"b3ca132d0792292e","width":"6","height":"1","order":1,"showTitle":true,"className":"myClass","visible":"true","disabled":"false","groupType":"default"},{"id":"d45641ed6d39fea1","type":"ui-base","name":"This is my ui-base","path":"/dashboard","appIcon":"","includeClientData":true,"acceptsClientConfig":["ui-notification","ui-control"],"showPathInSidebar":false,"headerContent":"page","navigationStyle":"default","titleBarStyle":"default","showReconnectNotification":false,"notificationDisplayTime":5,"showDisconnectNotification":false,"allowInstall":true},{"id":"c835807cdc98644e","type":"ui-theme","name":"Default Theme","colors":{"surface":"#ffffff","primary":"#0094CE","bgPage":"#eeeeee","groupBg":"#ffffff","groupOutline":"#cccccc"},"sizes":{"density":"default","pagePadding":"12px","groupGap":"12px","groupBorderRadius":"4px","widgetGap":"12px"}},{"id":"9cb7e77d8f8d7575","type":"global-config","env":[],"modules":{"@flowfuse/node-red-dashboard":"1.30.2","@flowfuse/node-red-dashboard-2-ui-led":"1.1.0"}}]

An alternative would be some nodes to alternately send the codes for red and grey when the rate is active, but you have to be able to control the flash rate and stop flashing in the right state when the rate is no longer active.

I had already put msg.payload.svalue1 in the context, but I hadn't actually mentioned that yet.

I will implement the above and let you know the outcome.

Thanks for this option, this is working fine!. this is a good learning point for me.
What I have done, I have add a trigger node after the new function implemented, now I have short pulses created to my dashboard LED, I think this is an indication of the power consumption (flashing frequenty of the LED).

Hello @Johannesje

You have to deal with 2 things.

  1. Collect reliable information about when tariff 1 or when tariff 2 is active.
  2. Presentation

Domoticz presents the data of the P1 Smart Meter in 6 values (svalue1 - svalue6).
As @jbudd already said these are strings. (That's, why it is svalue. Opposite is nvalue).

They represent the following:

  • USAGE1= integer, total cumulative energy usage meter tariff 1 in Wh.
  • USAGE2= integer, total cumulative energy usage meter tariff 2 in Wh.
  • RETURN1= integer, total cumulative energy return meter tariff 1 in Wh.
  • RETURN2= integer, total cumulative energy return meter tariff 2 in Wh.
  • CONS= actual usage power (Watt)
  • PROD= actual return power (Watt)

I assume, you do not have solar panels or a battery, as svalue3, svalue4 and svalue6 are "0"

The MQTT does not contain information about which tariff is active.
I agree that, when svalue1 is counting, tariff1 is active and when svalue2 is counting, tariff 2 is active.

But

Is the opposite also true?
If svalue1 is not counting, does that mean, that tariff 1 is not active?
Or does it mean, that you have no consumption at that moment.

The P1 Companion Standard. (See https://www.netbeheernederland.nl/sites/default/files/2024-02/dsmr_5.0.2_p1_companion_standard.pdf) has an OBIS value (0-0:96.14.0.255) for it available. However, Domoticz is using that value, but does not send it as data to the outside world.

The most reliable way to get that information is to read the OBIS codes directly.
Node RED has a "contrib" node for it. ( See: node-red-contrib-p1reader (node) - Node-RED)

You might need a P1 splitter in order to get a dedicated /ttySx serial port.

But the most reliable way, in my opinion, is to contact your energy supplier or read its documentation and ask him, when tarriff 1, rest tariff 2 are active and use these times to control your leds. Keep in mind that in The Netherlands tariff code 1 is used for low tariff and tariff code 2 is used for normal tariff. In Belgium, it is the other way around.

For controlling the LED's, I would follow @jbudd's recommendation.

Regards

Hi,

Thanks for that information, it is new for me.
Before I using Node Red, I use Domoticz to store continue kWh-meter information. So it was for me the easiest way for me to have a MQTT connection.to Node Red.
But I will check your option, to get more info from MQTT.
I live in the Netherlands so the link is for me interesting.

I noticed that the way I read Domoticz data via MQTT is different from reading the COSEM data.

How can I read this within Node Red?

I am currently using a switch that allows me to filter on msg.payload.idx, but I do not see this reflected in the COSEM data.

I have the connection to the kWh meter (RPI USB <--> kWh RJ12), and it would be nice to be able to read it directly in Node Red.

Although the method explained by @JBUTT also works perfectly, and I also always have standby power from my home automation.

Hi @Johannesje,

If you are satisfied with the solution, as described by @jbudd, I would leave it that way.

Anyway, I will give you a description of a possible solution, as an alternative.
If you like to experiment somewhat.

Your Smart Electricity meter has a serial output, which has been made available on a RJ-12 output to the outside world. As most modern computers do not have a serial DB9 connector nowadays, you have to convert the serial signals to USB. All, so called, P1 Smart meter cables, contain a serial to USB converter.

But remember; Serial communication is a point to point communication and that means that a serial input/output cannot be shared, except the example described below.

I also said that Domoticz outputs data of all its connected devices to MQTT, if you have configured that. To receive data of a single device, you have to filter it by e.g. its IDX.

The RAW data from the P1 serial port is not send to MQTT from Domoticz.
So Node-RED has no option to read it from MQTT.

If you want to receive the RAW data, as shown below, in Node-RED you have to connect Node-RED to a serial port.

Example of RAW data:

/XMXGBBLA4412069552

1-3:0.2.8(50)
0-0:1.0.0(230213141307W)
0-0:96.1.1(4530303436303033383533373138313137)
1-0:1.8.1(016570.841*kWh)
1-0:1.8.2(017003.466*kWh)
1-0:2.8.1(000911.638*kWh)
1-0:2.8.2(001910.190*kWh)
0-0:96.14.0(0002)
1-0:1.7.0(00.746*kW)
1-0:2.7.0(00.000*kW)
0-0:96.7.21(00012)
0-0:96.7.9(00003)
1-0:99.97.0(3)(0-0:96.7.19)(180712012927S)(0000000197*s)(190523142742S)(0000000254*s)(220902152610S)(0000000990*s)
1-0:32.32.0(00021)
1-0:52.32.0(00018)
1-0:72.32.0(00019)
1-0:32.36.0(00000)
1-0:52.36.0(00000)
1-0:72.36.0(00000)
0-0:96.13.0()
1-0:32.7.0(234.0*V)
1-0:52.7.0(238.0*V)
1-0:72.7.0(239.0*V)
1-0:31.7.0(002*A)
1-0:51.7.0(000*A)
1-0:71.7.0(000*A)
1-0:21.7.0(00.551*kW)
1-0:41.7.0(00.012*kW)
1-0:61.7.0(00.182*kW)
1-0:22.7.0(00.000*kW)
1-0:42.7.0(00.000*kW)
1-0:62.7.0(00.000*kW)
0-1:24.1.0(003)
0-1:96.1.0(4730303339303031373230343732343137)
0-1:24.2.1(230213141006

This is one cycle and dependent on the protocol version you will receive 1 cycle/second or
1 cycle/10 seconds.

You don't tell, whether Node-RED and Domoticz run on the same PI or that Node-RED runs on another machine.
If it is another machine, you have to split the serial cable and probably need anther serial to USB converter. If it is the same, it may be needed on another USB port.

If it is the same you can try to use a LInux utility, called ttybus. Also socat does the same.
See: GitHub - danielinux/ttybus: A simple TTY multiplexer. · GitHub.

See also: https://raspberrypi.stackexchange.com/questions/106221/is-there-a-way-to-split-data-stream-from-one-serial-port-ttyama0-to-multiple-v.

This utility creates multiple virtual serial ports. However, I have never tested it, so I cannot tell, if either Domoticz and/or Node-RED recognizes this virtual serial port.

But suppose, Node-RED contrib node (node-red-contrib-p1reader (node) - Node-RED) or another Serial node (node-red-contrib-smartmeter (node) - Node-RED) recognizes the virtual port, you can parse the data 0-0:96.14 yourself and use it the way you want.

Regards

Thanks for explanation.
I leave what it is because:

  • all the signals what i need is cofigured now (including a nice flashing LED :slight_smile: )
  • I have one RPI where Domoticz and Node Red is installed, so I need also a TTY multiplexer (I had earlier allready P1reader tested, but i could see on the green LED that is was not a slable connection, now I know why)
  • I will using coninue use Domoticz for recording data

Maybe Ill do later a try....

Also a nice thing to tell is that my RPI is not nearest the kWh-meter installed, so I have lengthen the cable on the RJ12 connecter with 10m via existing UTP cable en everything works fine.