Node-RED nodes for hubitat

I want to share with you my recent development with Hubitat and Node-RED.

node-red-contrib-hubitat

It is some generic nodes to facilitate the integration with Hubitat. The challenge was to found the middle between generic and easy of use. I will be very happy to have your feedbacks and discuss about how to improve it :slight_smile:

Note that I keep this post updated with every release, no need to read all posts to know new features or changes.
You can look at the CHANGELOG for news

How to use it

Prerequisite

Warning

If you have never used Node-RED before, follow tutorials. There are quick, funny and will avoid you pulling out your hair in the next steps. The debug node is your best friend to see message between nodes.

Installation of the module

Install node-red-contrib-hubitat from the menu -> Manage palette -> Install -> search for hubitat and install it.
Screenshot from 2020-04-04 16-59-15 Screenshot from 2020-06-27 07-50-22

You will have 5 real nodes and 1 configuration node:

  • command: Used to send command to Hubitat. It main advantage is the auto discover devices/commands and arguments.

  • device: Used to keep the device state. Fetch the device state when deployed and listen for events after. When an event is received, it can be sent to the output. The input message must have attribute property to output the state of the attribute asked.

  • mode: To keep the Hubitat mode (Day, Night, ...) state. It fetch the mode when deployed, then listen for webhook events

  • mode-setter: To set the Hubitat mode (Day, Night, ...)

  • location: To receive global location events (ex: systemStart, sunrise, sunset)

  • event: A generic node to receive all events.

  • request: A generic node to request any Hubitat's endpoints.

  • config: Used to add Hubitat configuration server (host, Application ID, token). It also listen webhook (on /hubitat/webhook) to dispatch events to device nodes. Warning this node is not a physical node like others. When you add another node, the server section correspond to this node.

Create amazing flows

My flows are not yet amazing but here a basic example:
Toggle light with only one action button:
Screenshot from 2020-06-27 07-57-44

You can import it directly into Node-RED

[{"id":"560ac76b.479898","type":"tab","label":"Example","disabled":false,"info":""},{"id":"7547eaf1.825834","type":"hubitat device","z":"560ac76b.479898","name":"Button","server":"3b6080dc.a2527","deviceId":"65","attribute":"pushed","sendEvent":true,"x":90,"y":80,"wires":[["460f9c07.53eb34"]]},{"id":"460f9c07.53eb34","type":"hubitat device","z":"560ac76b.479898","name":"Outlet","server":"3b6080dc.a2527","deviceId":"35","attribute":"switch","sendEvent":false,"x":220,"y":80,"wires":[["97b3dfb.e3b132"]]},{"id":"97b3dfb.e3b132","type":"switch","z":"560ac76b.479898","name":"","property":"payload.value","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"eq","v":"off","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":340,"y":80,"wires":[["53788eae.3d28"],["e63faae1.84e368"]]},{"id":"53788eae.3d28","type":"hubitat command","z":"560ac76b.479898","name":"Outlet OFF","server":"3b6080dc.a2527","deviceId":"35","command":"off","commandArgs":"","x":500,"y":60,"wires":[[]]},{"id":"e63faae1.84e368","type":"hubitat command","z":"560ac76b.479898","name":"Outlet ON","server":"3b6080dc.a2527","deviceId":"35","command":"on","commandArgs":"","x":490,"y":100,"wires":[[]]},{"id":"3b6080dc.a2527","type":"hubitat config","z":"","name":"","usetls":false,"host":"192.168.2.50","port":"80","appId":"100","nodeRedServer":"http://localhost:8080","webhookPath":"/hubitat/webhook","autoRefresh":true,"useWebsocket":false}]

Configuration node

Screenshot%20from%202020-02-13%2019-16-35

The first node is a device node that receive all button events

Screenshot%20from%202020-02-27%2016-55-35

The second reads the state of my Outlet

Screenshot%20from%202020-02-27%2016-58-23

The third does a switching logic

Screenshot%20from%202020-02-27%2016-59-52

Last, execute an action according the state of the Outlet. If the current state is ON, then turn light OFF and if current state is OFF then turn light ON

Screenshot%20from%202020-02-13%2019-18-04

Motivation

I lost patience after some misclicks with the Rule Machine and my friend @sylvainboilydroid just started to work on another Node-RED module. So, in theory, all I had to do was copy it ... so naive :rofl:

Based on ...

I firstly copy a lot of code from node-red-contrib-wazo-platform, then read Node-RED documentation (I know, I should have done it first).
After creating the config and command node, I started to read the node-red-contrib-smartthings module and I found some good ideas. So I did a device node and refactor the config node which listen on the Maker API webhook.

Now the code has been so much refactored and improved that nothing is left of them.

Limitations

  • I only have 4 different devices, so I'm quite limited on my tests :sweat_smile:
  • There is no ping command to trigger a webhook event, which prevent automatic configuration solution. It's why you need to make basic test flow after configuration to be sure to receive webhook

What's next?

There is some work to do and any help is welcome :smile: Here some ideas:

  • Improve documentation wording (non native speaker here :sweat_smile: and that's why I need your help on this point. Do not hesitate to make me suggestion/comment/feedback/fix typo or PR if you can)
  • Add flow examples
  • Internationalization (task state)

How I personally use it

Here is my currently flow for all my devices


The first one trigger night light when I go to the bathroom before going to bed
The second control a light with a button
and the last one automatically turn on/off an outlet

Feedback about Maker API

Here what cause me some trouble from Maker API

  • See Limitations section
  • Getting attributes from the GET /api/1/devices/<device_id> return a currentValue already cast to an object (integer, string, ..) but the value from the webhook event is always cast to string
    ex:
    GET /apps/api/1/devices/1
    ...
    {
    "name":"temperature",
    "currentValue":20.47,
    "dataType":"NUMBER"
    }
    ...
    
    and the event temperature return
    name: "temperature"
    value: "30.23"
    ....
    
    In the node I need to cast the value according the dataType to keep consistency

FAQ

How to configure webhook after configuring Node-RED authentication

Use Basic authentication format URL for Node-RED server http://username:password@192.168.0.10 (from this post)

Special configuration when you install Node-RED with Home Assistant

HA expose NR endpoints under /endpoint prefix, be sure to update webhook path (from this post):
Screenshot from 2020-06-18 19-07-41

Why not using websocket by default

Explanation here
Note: this answer was posted before the use websocket feature

26 Likes

Sorry to have leaked your work with my post a few days ago before you were able to release your in-depth explanation in this post. This is great work!

:grinning::grinning::grinning:

1 Like

Yep very nice work, thank you @fblackburn !

Nice work!

A few quick comments from my 1st 5 minutes...

  1. Easy to setup. All commands I've tried work correctly, and the device node sees the events I would expect it to see. Good job! :+1:

  2. It would be nice if device list in device/command node drop down box was alphabetic. It is very hard to find device when there are 100+ items in the list.

  3. I see multiple device value updates on single ON/OFF command for my lights. Not sure why... I only see one event on the device in HE and only one message in the HE log.
    .
    Example: This is from a single OFF command. The 1st debug message is the output of the COMMAND node, the other 4 are all from the single DEVICE node.

  4. Also, for those setting it up, don't be dumb (like me) and forget to put your Node-Red port in the POST URL in Maker API config... :slight_smile: For example, here is mine: http://192.168.2.6:1880/hubitat/webhook

For reference, this is the example flow I am using for testing a single GE motion dimmer device:

2 Likes

Thanks for the feedback, really appreciated :smile:

  1. :+1: it should be easy to do
  2. Each device keep its state and will send event independently. If you have 4 devices node, then each one will output an event. If you don't want to send events for a node, uncheck the box "send event"
  3. Thanks, first post updated !

Edited the answer of #2

But I only have 1 device node...

To be more exact, I have:

  1. One Device node
  2. Four Command nodes

So I'm not sure why the single device node outputs 4 times. It may be correct, and I just am misunderstanding (?).

Also note that I get the same 4 outputs from that device node whether "send event" is enabled or disabled, which seems odd... This screen shot is from turning the light OFF, and send event is disabled on the device node.

Still got 4 event output from the block.

Ah sorry I misunderstood your scenario
Can you check if you device has 4 attributes switch with the API
http://<hubitat-api>/apps/api/<api-di>/devices/<device-id>?access_token=<token>
For mine I have 2 switch attributes and I receive event twice :frowning:

attributes:
  1:
    name: switch
    ...
  2:
    name: switch
    ...

Not four, but there are two, which is odd enough...

I have published a new version 0.0.11

  • devices are now ordered
  • duplicate attributes from hubitat API are now removed from the node properties

For the send events not working, I cannot reproduce it. Can you try another device and be sure to deploy the flow

Since I can only reproduce the two events issue instead of your four events issue, I cannot guarantee if it will be fixed. But you can test it and give me feedback

EDIT: Gotcha !! There is an issue with the unregisterCallback. If you redeploy the entire flow, it should be OK. I will fix it and release another version :slight_smile:

EDIT2: All your issues should be fixed in version 0.0.12 :tada:

2 Likes

I must be doing something wrong. How does the device node get notice of changes from Hubitat? I created a simple node just to get the status of a light using an inject node that runs every 5 seconds. It works and gets the status correct the first time. However, after I turn the light off, my simple node still says the light is on.

By maker API sending a post event to node-red.
As long as the device is added to maker API, and maker API is configured to send post events to the proper address in node-red, the device node should get the event

So if that is all setup, maybe there is a new bug since this mornings version?

I am out, but will try the latest version when I get home in a few hours.

Yeah, I knew that it was something stupid that I didn't do. Lemme see if I can get it to work now.

1 Like

0.0.12 fixed the "send event" and repeated device node events. Thanks!

FYI that the device lists are still not in order, though. See below. This is after upgrading to 0.0.12 and rebooting node-red:

CALL ME DUMB!!!!!! haha. Working great now.

This was a great addition to Node Red when it was just a Command node. Now its even better. Thank you.

1 Like

Ah well see, can you try to update the config node: click to edit the server and click on Update button, then redeploy. But I'm not sure to understand why, I'll check it tomorrow

@stephen_nutt Nice to see it works :slight_smile:

I would love to have a dummy command to send and get back an event to verify that webhook is correctly configured. I'll try to think how to make this part easier

Nope, still not sorted. Minor issue in the big scheme of things.

I even deleted the connection and re-made it, still not sorted.

Again, minor issue for now - it will wait! Only thing I can think of for you to check is to make sure you are sorting based on the Device Label, not the Device Name.

EDIT: I would guess you are sorting on Device Name based on how mine are sorted.

My fault, wrong usage of sort method :sweat_smile:
It worked on my dev environment because I was lucky...
Fixed in 0.0.13 :wink:

2 Likes

0.0.13 fixed the sorting. Thanks!!! While minor in terms of overall functionality, that is a huge help when you have dozens/100+ devices in the list like I do!

1 Like

EDIT: Never mind, what I asked was already in the OP.