Thankfully you can use NodeJS to do basically anything you want using the node-homeassistant API which is extremely easy to use. If anyone knows how to use this API or another method to get “push” updates from HA, please share and try to include as complete an example as possible, really appreciated.
NodeJS is great for performing calculations, managing/transforming data, routing information as well as adding extended functionality to HA.
Personally neither Automations nor NodeRed worked for me, way too inconcise and fiddly. In my limited experience, Automations seemed to be very unreliable and flaky and managing data, performing calculations and creating functions in NodeRed is probably the most agonizing experience I think I’ve ever had in my life.
If you know javascript, i wouldn’t even bother using automations and helpers, etc because its just so difficult to do anything complicated. If you dont know JS/NodeJS and automations arn’t working for you, i don’t suggest NodeRed, it’s so cumbersome and data management and logic is far more difficult than just doing in JS. So i really don’t see the point and system impact of NodeRed is hardly justified. In the same amount of time you could just as well get comfortable with JS/NodeJS and be far better off. It’s the most well documented and explained language on earth, you’ll be just fine.
Lets have a look:
Install NodeJS, and do a local install of “homeassistant” via NPM
Simple example usage of the API is here: https://www.npmjs.com/package/homeassistant
Just generate your token from your profile settings in HA, make sure to copy paste the WHOLE long line.
API is extremely straight forward. I found it easy enough in just minutes to:
- Verify API is connected to the HA instance
hass.status()
.then(data => { console.log('HA Status: ', data.message); })
.catch(err => console.error(err));
- List out all names of entities you can interact with using:
hass.states.list()
.then(data => console.log(data))
- Read the state of a sensor, ESP Sensor or switch
hass.states.get('sensor', 'sensor.esp_filter_psi_filter')
.then(data => press.filter = Number(data.state))
//consider using a catcher for when HA starts dropping the ball it wont crash your script
.catch(err => console.error(err));
- Set the state of a switch or input boolean “switch helper”
hass.services.call('turn_off', 'switch', { entity_id: 'switch.esp_tazok_relay_luckypro' })
hass.services.call('turn_on, 'input_boolean', { entity_id: 'input_boolean.auto_pump' })
- Automatically create a sensor inside HA and continually update that sensor
hass.states.update('sensor', 'flow_hour', {
state: Number(flow.hour).toFixed(2), attributes: { unit_of_measurement: 'm3' }
});
- Update the value of a “number helper” inside HA
hass.services.call('set_value', 'input_number', { entity_id: 'input_number.tank_mountain', value: tank.mountain.level })
So with that alone, you could do just about anything you wanted. If any knows how to get push data from HA into NodeJS using the “homeassistant” NPM or via another means like websocket etc, please share that.
That being said, in order to have a functioning automation without push capability (which i dont know how to do), then obviously you need to “get” the state of the things you want from HA in some interval so you can do something with it. Once a second seems to work fine for me but you could go less if you had the need.
setTimeout(() => {
try {
hass.states.get('sensor', 'sensor.esp_filter_flow_filter')
.then(data => flow.lm = Number(data.state))
hass.states.get('sensor', 'sensor.esp_filter_flow_total_filter')
.then(data => isNaN(Number(data.state)) == false ? flow.temp = Number(data.state) : flow.temp = 0);
hass.states.get('sensor', 'sensor.esp_tazok_psi_tank_tazok')
.then(data => press.tazok = Number(data.state))
hass.states.get('input_boolean', 'input_boolean.auto_pump')
.then(data => data.state == "on" ? auto.tazok.state = true : auto.tazok.state = false)
hass.states.get('switch', 'switch.esp_tazok_relay_compressor')
.then(data => data.state == "on" ? pump.air = true : pump.air = false)
}
catch (error) { console.log(error) }
}, 1000);
For users new to NodeJS and want a more complete example, just ask.