Detect if number contains decimal

Hi,

i have a electric meter which sends me (rpi, serial measurement thingy, mqtt) the total amount of energy. But, thanks to german law or whatever (privacy reasons....), after a power breakdown the resolution drops to 1 kWh. The energy meter has to be configured again for "high" resolution output.
Now i want to detect these low resolution so that a dont miss another month with higher resolution. The main reason is, that in low resolution mode also the 1W resolution is disabled.

E.g. i would like to trigger a message after 100 messages "9000" (value probably changes, but no "dot" appears). If one message is "xxxx.1" the counter should be resettet. If low resolution is detected, a message once a day should be send (telegram - the only thing that works right now)
A typical dataset looks like (1 message every second)

vzlogger/data/chn1/raw : msg.payload : number
9889878.9

vzlogger/data/chn1/raw : msg.payload : number
9889879

vzlogger/data/chn1/raw : msg.payload : number
9889879.1

I tried switch, but there is no "does not contain". The idea was to, if no dot is present, a counter decreases (function node)

Edit - the standard switch node has an "otherwise" option which works -
Contains dot -> output 1
Otherwise -> output 2

I doubt whether that will work in this case as the value is a number, not a string.

That was my thoughts and it works fine, here is a test flow demonstrating the use of the switch with a 'contains .

[{"id":"53df66a3fb21264f","type":"inject","z":"999bb768077d599d","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"95.4","payloadType":"num","x":270,"y":340,"wires":[["f6accf52c028ec3d"]]},{"id":"5e73fb937fec39e0","type":"inject","z":"999bb768077d599d","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"345","payloadType":"num","x":270,"y":420,"wires":[["f6accf52c028ec3d"]]},{"id":"f6accf52c028ec3d","type":"switch","z":"999bb768077d599d","name":"","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":".","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":450,"y":380,"wires":[["b2d9f9d5be7d25b4"],["fbb37a3148f0145d"]]},{"id":"b2d9f9d5be7d25b4","type":"debug","z":"999bb768077d599d","name":"debug 3","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":640,"y":340,"wires":[]},{"id":"fbb37a3148f0145d","type":"debug","z":"999bb768077d599d","name":"debug 4","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":640,"y":440,"wires":[]}]

If it is a number you could just use modulus using JSONata expression $$.payload % 1 and rules equals 0, otherwise.

[{"id":"53df66a3fb21264f","type":"inject","z":"fe76f7928e585317","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"95.4","payloadType":"num","x":204,"y":1130.9999389648438,"wires":[["f6accf52c028ec3d"]]},{"id":"f6accf52c028ec3d","type":"switch","z":"fe76f7928e585317","name":"","property":"$$.payload%1","propertyType":"jsonata","rules":[{"t":"eq","v":"0","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":384,"y":1170.9999389648438,"wires":[["b2d9f9d5be7d25b4"],["fbb37a3148f0145d"]]},{"id":"5e73fb937fec39e0","type":"inject","z":"fe76f7928e585317","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"345","payloadType":"num","x":204,"y":1210.9999389648438,"wires":[["f6accf52c028ec3d"]]},{"id":"b2d9f9d5be7d25b4","type":"debug","z":"fe76f7928e585317","name":"debug 3","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":574,"y":1130.9999389648438,"wires":[]},{"id":"fbb37a3148f0145d","type":"debug","z":"fe76f7928e585317","name":"debug 4","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":574,"y":1230.9999389648438,"wires":[]}]
1 Like

Yes, you are right. Perhaps the Switch node converts it to a string first. That looks like a solution then.

Oh ye of little faith @Colin, @zenofmud !

I didn't think it would work either till I tried it :upside_down_face:

1 Like

Wow, really fast replies.

As I dont know whats all inside a "export" here is just a screenshot. The messages for "kWh" are sent one every hour. There is a counter which is preloaded with 24 and ist decreased on every message that doesnt contain a dot. If a dot ist detected, the counter is set back to 24. If the counter reaches zero, the message to telegram is sent.

I think you could do it more easily with a Trigger node. Set it to Send Nothing then after an appropriate time send the telegram message. Select Extend delay if new message arrives, and feed into it the Switch node output that means that it is a fractional number. Then all the time fractional numbers appear it will send nothing, but if no fractional numbers appear for the configured time then it will send the telegram message.

Just note that while the proposed solution may work for you, it is not a generic solution since a dot is not a universal symbol for decimals. Most European countries use a comma to indicate decimals in a string.

If the incoming data is a numeric, the solution from @E1cid is more robust.

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.