Node-Red Palette: Common Choices

you can use it to specify a specific sequence order. there is a drop down box to select that setting, then you specify how the paths are listed.

if you wanted to have different actions based on different sequences, you’d have to have separate nodes for each sequence.

1 Like

Good to know - thanks!

Coding question. How would I put two of these camera displays on the same dashboard? I want them different sizes, one is just to check the garage is shut, and dont need it to be 625px. I had them both working on the same page as different elementId's, but if I try and have two of these on the same dash, only 1 camera shows up. All paths are correct (if I disable one, the other camera works, and visa versa). This is in a node red UI Template Node.

  <!DOCTYPE html>
  <html>
  <style>
  img {
border: 1px solid #ddd;
border-radius: 8px;
padding: 2px;
width: 630px;
  }
  </style>

 <script type="text/javascript">
 scope.$watch('msg', function(msg) {
    inMessage(msg.payload);
 });

 function updatePic() {
    document.getElementById('z52').src = 'removed';
         //alert('updated pics');
 }

 function inMessage(event) {
     if (event.match('checkWeb')) {
        updatePic();
}
 }

 </script>
 <center>
 <table>
     <tr><!-- Row 1 -->
		 		    <td style="text-align: center"><img src="" id="z52" /></td>

</tr>

 </table>
 </center>
 </html>

Edit: updated crazy formating.

I finally got Sonos TTS going in Node Red via the recently added palette
node-red-contrib-tts-ultimate

Good news is on the Sonos Beam when currently playing via the television and a tts comes through it returns to the television audio after the tts automatically. Unlike using RM where I had to add a delay and an action to go to the url that the beam was playing prior to the tts playing to every rule that played a tts message.

Bad news is still unable to get it to return to playing spotify after a tts has occurred automatically and have to go back into the app and initiate playing it again after every tts message.

Hopefully someday they will find a fix for this and update.

Thanks for bringing this palette up - looks very interesting. I have not played around with TTS all that much but do have Sonos...

I noticed on the site that the maintainer said it's a Sonos API documentation issue.. which I guess isn't terrible news if it's just an undocumented feature.

  • Automatic resume of music queue (including radio stations, but here, some users reports problem resuming radio stations and, because of lack of Sonos API documentation, the issue cannot currently be fixed), at exact track, at exact time.

Yes that is the only downfall I've found so far, it seems no one is able to get this working properly still.

However on devices like the Sonos Beam while listening to TV and a TTS comes through it does appear to automatically go back to the TV input for audio after the message. When I used rule machine I had to make sure to add playing the track of the uri after each TTS rule for the beam as it's usually playing audio from the TV.

Can anyone recommend a palette/node that will calculate average? I want to calculate the average of 6 different sensors that I want to then send the result any time one of the sensors reports. All of the average nodes that I can find seem to just calculate the average of the last n number of values received. I want it to average the last value received from each sensor by topic.

I've used this - node-red-contrib-calculate (node) - Node-RED

EDIT:

This may work for your use case since it collects messages by topic and count.

Probably best to use a function node for this.

Another approach is to use the average node, but let it collect data for 1-2 hours before zeroing it out (immediately followed by pushing values from all your sensors to be averaged).

2 Likes

I actually use 2 functions nodes to do this with (except mine is for addition to give me real time wattage usage for energy monitoring)

This screenshot lists each function flow you've set up to add (in your case plus divide)

Instead your case you would list your set flows like the second screenshot then on the last line that is adding them together put divide at the end by how many flows you have listed and should give you an real time average.

Here is the flow.

[
{
    "id": "18245251.793d1e",
    "type": "function",
    "z": "7cc9bb85.63df34",
    "name": "",
    "func": "msg.payload = {};\npooltablelight = flow.get(\"Pool_Table_Light\")||0;\nsecuritytvpower = flow.get(\"Security_TV_Power\")||0;\ndeepfryer = flow.get(\"Deep_Fryer\")||0;\ngewasheroutlet = flow.get(\"GE_Washer_Outlet\")||0;\ncoffeemaker = flow.get(\"Coffee_Maker\")||0;\nmbpowerstrip = flow.get(\"MB_Power_Strip\")||0;\noxygenpower = flow.get(\"Oxygen_Power\")||0;\nmodempower = flow.get(\"Modem_Power\")||0;\nkitchenfridgepower = flow.get(\"Kitchen_Fridge_Power\")||0;\nacpower = flow.get(\"AC_Power\")||0;\nfridgefreezer3power = flow.get(\"Fridge_Freezer_3_Power\")||0;\nlrtvpower = flow.get(\"LR_TV_Power\")||0;\nbedroomtvpower = flow.get(\"Bedroom_TV_Power\")||0;\nbeerfridgepower = flow.get(\"Beer_Fridge_Power\")||0;\nfreezer1power = flow.get(\"Freezer_1_Power\")||0;\nlivingroomoutlet = flow.get(\"Living_Room_Outlet\")||0;\nicemakerpower = flow.get(\"IceMaker_Power\")||0;\nlivingroomoutlet = flow.get(\"Living_Room_Outlet\")||0;\nsmokeroutlet = flow.get(\"Smoker_Outlet\")||0;\nmicrowavepower = flow.get(\"Microwave_Power\")||0;\nmsg.payload.value = pooltablelight + securitytvpower + deepfryer + gewasheroutlet + coffeemaker + mbpowerstrip + oxygenpower + modempower + kitchenfridgepower + acpower + fridgefreezer3power + lrtvpower + bedroomtvpower + beerfridgepower + freezer1power + livingroomoutlet + icemakerpower + livingroomoutlet + smokeroutlet + microwavepower;\nreturn msg;",
    "outputs": 1,
    "noerr": 0,
    "initialize": "",
    "finalize": "",
    "x": 840,
    "y": 1240,
    "wires": [
        [
            "e9c74fd0.efee7"
        ]
    ]
},
{
    "id": "179688c8.8333f7",
    "type": "hubitat command",
    "z": "7cc9bb85.63df34",
    "deviceLabel": "Current Total Watts",
    "name": "",
    "server": "1a0c620f.77b4de",
    "deviceId": "6581",
    "command": "setPower",
    "commandArgs": "",
    "x": 1230,
    "y": 1240,
    "wires": [
        []
    ]
},
{
    "id": "e9c74fd0.efee7",
    "type": "change",
    "z": "7cc9bb85.63df34",
    "name": "",
    "rules": [
        {
            "t": "set",
            "p": "arguments",
            "pt": "msg",
            "to": "payload.value",
            "tot": "msg"
        }
    ],
    "action": "",
    "property": "",
    "from": "",
    "to": "",
    "reg": false,
    "x": 1030,
    "y": 1240,
    "wires": [
        [
            "179688c8.8333f7"
        ]
    ]
},
{
    "id": "afd330a2.46e2d",
    "type": "hubitat device",
    "z": "7cc9bb85.63df34",
    "deviceLabel": "Smoker Outlet",
    "name": "Smoker Outlet",
    "server": "88ea39b5.0f3b18",
    "deviceId": "6836",
    "attribute": "power",
    "sendEvent": true,
    "x": 380,
    "y": 1240,
    "wires": [
        [
            "c332d151.59e0f",
            "cdd70d85.b19c7"
        ]
    ]
},
{
    "id": "c332d151.59e0f",
    "type": "function",
    "z": "7cc9bb85.63df34",
    "name": "",
    "func": "flow.set(\"Smoker_Outlet\",msg.payload.value);\nreturn msg;",
    "outputs": 1,
    "noerr": 0,
    "initialize": "",
    "finalize": "",
    "x": 600,
    "y": 1240,
    "wires": [
        [
            "18245251.793d1e"
        ]
    ]
},
{
    "id": "1a0c620f.77b4de",
    "type": "hubitat config",
    "name": "Hubitat Wifi",
    "usetls": false,
    "host": "192.168.50.50",
    "port": "80",
    "appId": "2285",
    "nodeRedServer": "http://192.168.50.113:1880",
    "webhookPath": "/hubitat/webhook__",
    "autoRefresh": true,
    "useWebsocket": false,
    "colorEnabled": false,
    "color": "#000000"
},
{
    "id": "88ea39b5.0f3b18",
    "type": "hubitat config",
    "name": "C7",
    "usetls": false,
    "host": "192.168.50.49",
    "port": "80",
    "appId": "5437",
    "nodeRedServer": "http://192.168.50.113:1880",
    "webhookPath": "/hubitat/webhook____",
    "autoRefresh": true,
    "useWebsocket": false,
    "colorEnabled": false,
    "color": "#ace043"
}

]

Don't know why ] is outside of the post, but if it doesn't import I would assume that needs included.

1 Like

Unless I am misunderstanding, I saw that one but don't think it will accomplish what I want. I am trying to avoid a sensor that might report temperature every 30 seconds from skewing the average if there is another sensor that reports every 300 seconds.

@JasonJoel has already mentioned "node-red-node-smooth" which might be something to look at..

  • Minimum
  • Maximum
  • Mean
  • Standard Deviation
  • High Pass Smoothing
  • Low Pass Smoothing

Hmm - are you looking to get average for each sensor or for all? If average for each sensor, then I believe it keeps the average by msg.topic (so could be separated for each sensor).

1 Like

I am trying to get average of all 6 of the sensors; not the average of any one sensor. I don't know if I am explaining myself very well. Let's say I have one sensor that reports its temperature every 30 seconds at 75F and another one that reports every 5 minutes at 85F. The average nodes that I can find calculate based on last n values received so if n = 10, then the average that node would calculate would be approx. 76 but I want the average to be 80F.

1 Like

I think this will work. Every time a sensor spits out a new temperature, it sets the flow variable for the sensor to the new temperature. Then, in a Function Node, I am just taking an average of the 6 flow variables every time a new temperature is generated. I think that is what @waynespringer79 was trying to show me. I am Function Node illiterate so this should be fun to figure this out.

2 Likes

I am as well, someone showed me this method when trying to get a real time running total of watts being used.

I tried the method I posted above I couldn't get it to actually divide, I'm currently playing with it to see if I can get it to work (i'm sure it's some format error as I am function illiterate), it should do exactly like you want if it it can get working

Don't really need a function node, could do it in a Change node too with an expression.

You are. I used to use a function node (something like @waynespringer79's) and just push temperature values from 10 sensors (8 at the time) to calculate an average of all 8.

By trial and error I found it was somewhat more "accurate" just to use the average node in this manner:

  1. begin by pushing all sensor values to the average node (with an inject node)
  2. let sensor nodes send updated data to the average node for 1 hour
  3. every hour, reset the average node, and immediately after push all sensor values to the average node.

Edit: When you have more sensors, it reduces the possibility of any single sensor biasing the output. The reason all the sensors may not update at the same frequency is because some are more exposed to air currents in the house (eg. drafts from human/pet activity or air from supply registers).

1 Like

Figured it out need to add this palette.
node-red-contrib-calc

Then this flow should work, just substitute your devices. You'll need to make sure each of the devices reports at least once so that the variables get populated then the division will be accurate for the average.

Each of the function nodes after the device would look like this.
flow4

And the final function node they all go into would be like this
flow3

Then change the calculator to both input and output to payload.value. Set the Constant to how many device you have in the flow. The set the temp of your virtual device that would be the average of all.

[
{
"id": "688750db.62351",
"type": "tab",
"label": "Flow 1",
"disabled": false,
"info": ""
},
{
"id": "b6e478eb.4fbd58",
"type": "hubitat device",
"z": "688750db.62351",
"deviceLabel": "Back Door",
"name": "Back Door Temp",
"server": "a5b37dd4.13f5a",
"deviceId": "3113",
"attribute": "temperature",
"sendEvent": true,
"x": 80,
"y": 140,
"wires": [
[
"947f3eff.c277f"
]
]
},
{
"id": "e8f80bf1.edc398",
"type": "hubitat device",
"z": "688750db.62351",
"deviceLabel": "Bathroom Door",
"name": "Bathroom Door Temp",
"server": "a5b37dd4.13f5a",
"deviceId": "2",
"attribute": "temperature",
"sendEvent": true,
"x": 100,
"y": 240,
"wires": [
[
"ae60eba0.a33e28"
]
]
},
{
"id": "92b6a795.ae8088",
"type": "hubitat device",
"z": "688750db.62351",
"deviceLabel": "Bedroom Window",
"name": "Bedroom Window Temp",
"server": "a5b37dd4.13f5a",
"deviceId": "3012",
"attribute": "temperature",
"sendEvent": true,
"x": 110,
"y": 340,
"wires": [
[
"121988cc.6b3507"
]
]
},
{
"id": "947f3eff.c277f",
"type": "function",
"z": "688750db.62351",
"name": "",
"func": "flow.set("Back_Door_Temp",msg.payload.value);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 280,
"y": 140,
"wires": [
[
"bde6f2ea.de94a"
]
]
},
{
"id": "ae60eba0.a33e28",
"type": "function",
"z": "688750db.62351",
"name": "",
"func": "flow.set("Bathroom_Door_Temp",msg.payload.value);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 300,
"y": 240,
"wires": [
[
"bde6f2ea.de94a"
]
]
},
{
"id": "121988cc.6b3507",
"type": "function",
"z": "688750db.62351",
"name": "",
"func": "flow.set("Bedroom_Window_Temp",msg.payload.value);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 320,
"y": 340,
"wires": [
[
"bde6f2ea.de94a"
]
]
},
{
"id": "bde6f2ea.de94a",
"type": "function",
"z": "688750db.62351",
"name": "",
"func": "msg.payload = {};\nbackdoortemp = flow.get("Back_Door_Temp")||0;\nbathroomdoortemp = flow.get("Bathroom_Door_Temp")||0;\nbedroomwindowtemp = flow.get("Bedroom_Window_Temp")||0;\nmsg.payload.value = backdoortemp + bathroomdoortemp + bedroomwindowtemp;\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 480,
"y": 240,
"wires": [
[
"d655ad43.1b161"
]
]
},
{
"id": "9d866994.6c0058",
"type": "debug",
"z": "688750db.62351",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1130,
"y": 240,
"wires": []
},
{
"id": "8cdc9be7.be53a8",
"type": "hubitat command",
"z": "688750db.62351",
"deviceLabel": "Temp Average",
"name": "Temp Average",
"server": "1a0c620f.77b4de",
"deviceId": "6948",
"command": "setTemperature",
"commandArgs": "",
"x": 960,
"y": 240,
"wires": [
[
"9d866994.6c0058"
]
]
},
{
"id": "293a9f7c.78cf1",
"type": "hubitat device",
"z": "688750db.62351",
"deviceLabel": "Temp Average",
"name": "Temp Aveage",
"server": "1a0c620f.77b4de",
"deviceId": "6948",
"attribute": "temperature",
"sendEvent": false,
"x": 600,
"y": 320,
"wires": [
[]
]
},
{
"id": "3a743abd.d7e1b6",
"type": "change",
"z": "688750db.62351",
"name": "",
"rules": [
{
"t": "set",
"p": "arguments",
"pt": "msg",
"to": "payload.value",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 770,
"y": 240,
"wires": [
[
"8cdc9be7.be53a8"
]
]
},
{
"id": "d655ad43.1b161",
"type": "calculator",
"z": "688750db.62351",
"name": "",
"inputMsgField": "payload.value",
"outputMsgField": "payload.value",
"operation": "div",
"constant": "3",
"round": true,
"decimals": "2",
"x": 610,
"y": 240,
"wires": [
[
"3a743abd.d7e1b6"
]
]
},
{
"id": "a5b37dd4.13f5a",
"type": "hubitat config",
"name": "Zigbee Hub",
"usetls": false,
"host": "192.168.50.51",
"port": "80",
"appId": "2531",
"nodeRedServer": "http://192.168.50.113:1880",
"webhookPath": "/hubitat/webhook_____",
"autoRefresh": true,
"useWebsocket": false,
"colorEnabled": false,
"color": "#ace043"
},
{
"id": "1a0c620f.77b4de",
"type": "hubitat config",
"name": "Hubitat Wifi",
"usetls": false,
"host": "192.168.50.50",
"port": "80",
"appId": "2285",
"nodeRedServer": "http://192.168.50.113:1880",
"webhookPath": "/hubitat/webhook__",
"autoRefresh": true,
"useWebsocket": false,
"colorEnabled": false,
"color": "#000000"
}
]

Lots of ways to do it. I would have done it all in change nodes.

Change nodes to populate each of the flow variables:

Finally a change node that does the expression calc:


Not any better/worse than how you did it, but no 3rd party nodes to install/update.

1 Like