Creating a sensor from Node Red

I have a birthday-car which shows nicely all the upcoming birthdays in days. But there is no integration of sensors which gives me the first birthday coming up so I can make some automation or raise a flag to notify me.
So I went ahead and got it done in Node Red (I may move it to a template once I learn more about the syntax in HA vs. what I am used to in Node Red).
I am now able to identify which of the whole list is the birthday coming up first. This is the code for the Node Red function:

//Get length of the array
var arrayLength = msg.payload.length;
//Save the array
var birthdayList = msg.payload;
//Get the first birthday
var firstBirthdate;
//Loop variable
var i;

//Loop through and get the minimum days
if (Array.isArray(birthdayList)) {
    //Save the first date for comparison
    firstBirthdate = birthdayList[0];
    //Loop through the rest
    for (i = 1; i < arrayLength; i++) {
        //node.warn(birthdayList[i].state + " < " + firstBirthdate.state);
        if (Number(birthdayList[i].state) < Number(firstBirthdate.state)) {
            firstBirthdate = birthdayList[i];
            //node.warn("current is " + birthdayList[i].state);
        }
        else{
            //node.warn("nothing for " + birthdayList[i].state);
        }
    }
}
msg.payload = firstBirthdate;
return msg;

This is my flow:

[{"id":"3717198c.c5c156","type":"inject","z":"e5872747.054fa8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"8","topic":"","payload":"","payloadType":"date","x":140,"y":2240,"wires":[["291c72a9.75590e"]]},{"id":"976b7b7a.5cf778","type":"comment","z":"e5872747.054fa8","name":"Birthday Check","info":"","x":140,"y":2200,"wires":[]},{"id":"291c72a9.75590e","type":"ha-get-entities","z":"e5872747.054fa8","name":"Get entities","server":"de97c73a.70e098","version":0,"rules":[{"property":"entity_id","logic":"starts_with","value":"sensor.birthday","valueType":"str"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":310,"y":2240,"wires":[["c213f0e5.6f59b"]]},{"id":"c213f0e5.6f59b","type":"function","z":"e5872747.054fa8","name":"First Birthday","func":"//Get length of the array\nvar arrayLength = msg.payload.length;\n//Save the array\nvar birthdayList = msg.payload;\n//Get the first birthday\nvar firstBirthdate;\n//Loop variable\nvar i;\n\n//Loop through and get the minimum days\nif (Array.isArray(birthdayList)) {\n    //Save the first date for comparison\n    firstBirthdate = birthdayList[0];\n    //Loop through the rest\n    for (i = 1; i < arrayLength; i++) {\n        //node.warn(birthdayList[i].state + \" < \" + firstBirthdate.state);\n        if (Number(birthdayList[i].state) < Number(firstBirthdate.state)) {\n            firstBirthdate = birthdayList[i];\n            //node.warn(\"current is \" + birthdayList[i].state);\n        }\n        else{\n            //node.warn(\"nothing for \" + birthdayList[i].state);\n        }\n    }\n}\nmsg.payload = firstBirthdate;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":510,"y":2240,"wires":[["e2bd79076e139beb"]]},{"id":"08a6eece79b9278e","type":"debug","z":"e5872747.054fa8","name":"debug 36","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":920,"y":2240,"wires":[]},{"id":"e2bd79076e139beb","type":"ha-sensor","z":"e5872747.054fa8","name":"first_birthday","entityConfig":"9feb0c5a587d6d03","version":0,"state":"payload","stateType":"msg","attributes":[],"inputOverride":"merge","outputProperties":[],"x":730,"y":2240,"wires":[["08a6eece79b9278e"]]},{"id":"de97c73a.70e098","type":"server","name":"Home Assistant","addon":true},{"id":"9feb0c5a587d6d03","type":"ha-entity-config","server":"de97c73a.70e098","deviceConfig":"","name":"first_birthday","version":"6","entityType":"sensor","haConfig":[{"property":"name","value":""},{"property":"icon","value":""},{"property":"entity_category","value":""},{"property":"device_class","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""}],"resend":false,"debugEnabled":false}]

I am not able to figure out how to create a sensor in HA called sensor.first_birthday
I am able to get a sensor created called sensor.nodered…followed by a random number.
It only has the following attributes:


It has the state at 9 which is correct, and the icon, which is also correct, the date, weeks remaining. But not the rest. I need at least the friendly_name to know whose birthday is coming up and display it on my dashboard.
So some of the attributes are being picked up. No matter what I try on the Node Red side, adding attributes for entity.id, friendly_name, etc. Nothing changes on the HA side.

In reading about it, there is a config node which adds the confusion. Not a lot of clear documentation about what do do in there or how to set it up. btw, do I need one of these config nodes for each entity I am creating in Node Red?
Here is mine:

Does anyone have a clear example on how to create a sensor in HA using a payload in Node Red?
This is my payload:
image

Any guides out there I can read to get this done right? Or anyone done anything like this and can give me some pointers?

I have a post in this thread on how to det up a dynamically created sensor.

1 Like

Yes, you need an ha-entity-configuration node for each of the new entity (sensor etc) nodes.
The configuration node deals with the connection to HA and bridges between the entity node (in the flow) and the home assistant websocket (sever).

It is essential to add the friendly name to the ha-entity-configuration node when you first set it up, otherwise you get the ‘random’ number as a name - it requires a full restart I believe to get the HA sensor updated if you add the name later. For simplicity, you should always ensure that you have all the fields you want set up correctly in the configuration node when you first set it up.

The main documentation is at
https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/

Kermit is the brains behind all of this amazing stuff and there are a few places where he has explained or documented the finer details of how to make the home assistant nodes work.

As a real example, here is an situation where I have complicated data that I want to pass to HA using a sensor node.

This is the sensor node setting
sensor node settings

The name is the name of the sensor node used in the flow (nothing more)
The entity configuration is the config node (a new one created just for this sensor node)
The state (the entity state value in HA) is taken usually from msg.payload, but here I am using msg.totalGas. Note that the state can only be a simple variable (number/string/Boolean).
I have added several attributes, which can be objects so useful for passing more complex data.

This is the associated ha-entity-configuration node settings
ha entity config node settings

The name is the name of the configuration node only - as the configuration nodes are mostly hidden this is not that important, but I like to reference back to the entity node it is connected to.
The server is the usual home assistant websocket server (configuration node) required for all ha nodes.
The device is optional
The type will be sensor for a basic HA entity

The friendly name is the name that the HA entity will appear under - so this is the important bit to set up!
The icon can optionally be set here
Device class and unit of measurement are helpful to set if you want HA to treat the entity as being a particular type - here I used ‘gas’ so the unit of measurement is m3, and this automatically appears in the HA display.
State class will almost always be measurement (unless you really do have a utility measurement that always increases and never goes down). Here I am just using the basic measurement to avoid any issues.

Resend state and attributes I think just ensures that the entity is updated when you deploy.

I have assumed that you only want to create one sensor called sensor.first_birthday, so you just need to set up a sensor node with the correct settings and the correct ha-entity-config node behind it. If you really do want to dynamically create and update an HA entity from Node-RED then there is also an update config node, which allows changes to be made to the node configuration node such as the friendly name. I have tested but not used this - apparently you could dynamically change the entity (friendly) name in HA from the Node-RED flow if required. Naturally this is becoming a little more complicated.

I hope this answers your question on why you get an entity in HA called nodered 9feb0c5a587d6d03 and what to do about it!

2 Likes

The issue is that you deployed the sensor node before you updated the name of it.
I have done that several times.
You need to fill in all the parameters (especially the name) first then deploy it. If you want to make a “quick test” to see if it’s working then you end up where you are now.

So delete the sensor node and deploy, then redo the sensor node with name, them deploy it.

1 Like

This is very helpful. So this method is to create a “static” type sensor in Node Red, and update the state of it using the flow. The most straight forward use of the sensor, and one I will be using for a few others I am making. So thank you for the reference and screenshots. I get how it all ties together.
I think for this specific use case I have, I will need the dynamic because I am changing some of the attributes, mainly the friendly_name. So @WallyR method is the applicable one this time. I will reply above with details of where I am in case someone uses this thread as a reference.

This worked. I no longer have the nodered sensor by following your steps. Indeed, got stuck with it trying to do a “quick test”…

1 Like

@WallyR , this got me way closer to what I needed to do. I had no idea about the Edit API node, a quick google search didn’t yield much either.
I used the node from your flow as is. No changes except the node name for clarity.

So here is my code in my function now:

//Get length of the array
var arrayLength = msg.payload.length;
//Save the array
var birthdayList = msg.payload;
//Get the first birthday
var firstBirthdate;
//Loop variable
var i;

//Loop through and get the minimum days
if (Array.isArray(birthdayList)) {
    //Save the first date for comparison
    firstBirthdate = birthdayList[0];
    //Loop through the rest
    for (i = 1; i < arrayLength; i++) {
        //node.warn(birthdayList[i].state + " < " + firstBirthdate.state);
        if (Number(birthdayList[i].state) < Number(firstBirthdate.state)) {
            firstBirthdate = birthdayList[i];
            //node.warn("current is " + birthdayList[i].state);
        }
        else{
            //node.warn("nothing for " + birthdayList[i].state);
        }
    }
}

msg.entity_id = `sensor.first_birthday`;

msg.payload = {
    data: {
        state: firstBirthdate.state,
        attributes: {
            'name': 'first_birthday',
            'entries': [
                { 'title': 'WEATHER ADVISORY, Barrie' },
                { 'title': 'SPECIAL WEATHER STATEMENT, Barrie' }
            ],
            unit_of_measurement: firstBirthdate.attributes.unit_of_measurement,
            friendly_name: firstBirthdate.attributes.friendly_name,
            icon: firstBirthdate.attributes.icon
        }
    }
};

//msg.payload = firstBirthdate;
return msg;

I kept the entries in {} from your post to see how they appear on HA, so I learn a bit of how to use them.
This is how it looks like:

The sensor node now is called sensor.first_birthday, so that’s great!
From the dev tab, I see all the entries:
image

My only question is what is the use case for the entries attribute? I have not seen one like it before, and I don’t want to discount it. Even if I may not need it now, I wanted to see what the usual use case for it is so I have it in my repertoire of stuff.

EDIT: Also wondering the difference in attributes, some have ’ ’ and some do not. Any difference? Or just illustrating that both work the same?

You can use the update config node to dynamically update the friendly name of an entity config node.

https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/update-config.html

You can rename the entity id in Home Assistant after creating it in NR and the id will stay changed. No need to delete and redeploy.

So I’ve had this running for a while. I have the injection node refreshing at 7AM. All good.
However, I have had this entity show missing in HA over the course of the day.

do I need to inject every minute to make sure the entity coming in from Node-Red is always active when HA does a refresh?

The dynamic node does not stay over a HA restart, so you need to run the script again if you restart HA.

I have this problem. I need to measure gas usage in Home Assistant. My gas meter produces magnetic impuls each 0.01 m^3 so I can react to it. I created NodeRed sensor and initiated the value to what I could read from the actual gas meter. Then on each pulse my NodeRed automation increased the Sensor value by 0.01. It worked for a week or so. Then I noticed it stopped measuring and the sensor value was Unknown. I fixed the state and it worked again but then broke very soon. I discovered that the state of the sensor gets broken when I restart Home Assistant. Is my reasoning right? If so, how to create sensor which will preserve the state during the restart. If it is not possible in NodeRed, how to do it in home assistant itself?

I think the correct way for you would be to make an energy sensor in HA and then just use Node Red to update it with a service call.

Ok thank you, and how do you create the energy sensor in HA?