0.2.0 • Published 2 years ago

node-red-contrib-node-homie-red v0.2.0

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

node-red-contrib-node-homie-red

Provides nodes to interact with devices published on mqtt following the homie convention

works with MQTT Homie

This package is based on node-homie and hc-node-homie-smarthome.

Release notes

0.1.0 (2022-01-16)

  • Initial release

Usage scenarios

The Homie convention differentiates between Devices and Controllers:

  • Device

    "An instance of a physical piece of hardware is called a device. For example, a car, an Arduino/ESP8266 or a coffee machine. It publishes Nodes and Properties to the MQTT broker." (see https://homieiot.github.io/implementations)

  • Controller

    "A controller does not announce anything to the MQTT broker, but discovers and interacts with Devices. There can be more than one Controller interacting with the different devices on the same broker." (see https://homieiot.github.io/implementations)

This node package provides nodes to support both device (virtual devices) and controller (discover and interact with existing devices) scenarios.

Controller Nodes

Configuration Nodes:

  • homie-config

Pallette Nodes:

  • Device (homie-device)
  • Property (homie-property)

homie-config

Here you specify the connection to your mqtt broker. Please not that also for controller mode the user needs publish rights at least for the properties homie/<device>/<node>/<property>/set topic.

homie-config-editor

Please find the documentation for the fields below:

Name

  • name of the configuration node

MQTT Url

  • the connection address of the mqtt broker. This can be a mqtt:// protocol address or ws:// | wss:// address depending on you scenario. If no port is specified defaults will be assumed. (mqtt: 1883, ws: 80, wss: 443)

Homie topic root

  • MQTT topic under which all homie devices are published. By convention this defaults to homie, however for your testing or developing reasons this can be changed here as not to disturb productive usage.

Username

  • Username for the MQTT connection. If the MQTT broker is unsecured this can be left empty.

Password

  • Password for the MQTT connection. If the MQTT broker is unsecured this can be left empty.

Device (homie-device)

node-homie-device

Represents a homie device.

Input

If a message is sent to the node the current device state will be emitted.

Output

Will send outgoing messages with the device state (init, ready...).

Outgoing messages include device state in the payload and device id as seperate field:

{
    "payload": "ready",
    "device": "security"
}

TODO: Implement dynamic device selection via topic like for homie-property.

Property (homie-property)

node-homie-property

Represents a property of a homie device. The node will send property value updates as outgoing messages.

Input

Message payload will be send to the homie property via .../set topic requesting the value update. If a topic is included in the incoming message it will be used to dynamically select the property to act on. (format: <deviceId>/<nodeId>/<propertyId>).

TODO: Implement a switch in the node which controls if the topic should be used or not. There are scenarios where a topic is present but should not be used.

If no payload is included and the property is a retained property the node will emit only the current value.

Special case: If the property is non-retained and the property was selected dynamically via the topic attribute a value message will be sent out immediately with the input value (without it beeing received from the property as there is no subscription to it due to the dynamic selection)

TODO: Maybe this behaviour should ne optional.

Output

Will send outgoing messages with the poperties value as payload. Besides that the message will include a additional metadata about the property:

{
    "payload": "false",
    "topic": "group-3/switch/state",
    "homieDevice": "group-3",
    "homieNode": "switch",
    "homieProperty": "state",
    "propertyAttrs": {
        "settable": true,
        "retained": true,
        "id": "state",
        "tags": [],
        "meta": [],
        "datatype": "boolean",
        "name": "On/Off state"
    }
}

{
    "payload": "22.5",
    "topic": "meq0006971/weather/temperature",
    "homieDevice": "meq0006971",
    "homieNode": "weather",
    "homieProperty": "temperature",
    "propertyAttrs": {
        "settable": false,
        "retained": true,
        "id": "temperature",
        "tags": [],
        "meta": [],
        "datatype": "float",
        "name": "Current temperature",
        "unit": "°C"
    }
}

Virtual Device

Configuration Nodes:

  • homie-vdevice-config

Pallette Nodes:

  • Virtual Device (homie-vdevice)
  • vprop value (homie-vproperty-value-update)
  • vprop /set (homie-vproperty-set-command)

homie-vdevice-config

A configuration node that creates a virtual device owned by nodered. The specification of a device is to complex to build a nice user interface around it. Therefor the spec has to be provided as JSON input. The datamodel is more or less straight forward with some specials to it. In general you can more or less model the devices, nodes and properties as they would be published via the mqtt topic structure with the following differences:

  • attributes are written without the "$" prefix for ease of use (name instead of $name)
  • ids have to be specified as fields, nodes and properties are arrays (lists) instead of dictionaries/maps like you would expect in the topic hierarchy.

Explanation

This will show the tree structure level by level.

Device:

id: deviceId
name: device name
nodes:
    - node1
    - node2
    - node3

For each node:

id: nodeId
name: node name
type: node type
properties:
    - property1
    - property2
    - property3

For each property:

id: propertyId
name: property name
datatype: boolean
settable: true

All together this looks like this:

id: deviceId
name: device name
nodes:
    - id: nodeId
      name: node name
      type: node type
      properties:
        - id: propertyId
          name: property name
          datatype: boolean
          settable: true
        - id: propertyId
          name: property name
          datatype: boolean
          settable: true
    - id: nodeId
      name: node name
      type: node type
      properties:
        - id: propertyId
          name: property name
          datatype: boolean
          settable: true
        - id: propertyId
          name: property name
          datatype: boolean
          settable: true

Below you find an actual JSON example that can be used directly for testing.

{
    "id": "node-red-virtual-device-1",
    "name": "Virtual a test device",
    "nodes": [
        {
            "id": "switch",
            "name": "Virtual switch",
            "type": "virtual-switch",
            "properties": [
                {
                    "id": "state",
                    "datatype": "boolean",
                    "passThrough": false,
                    "name": "Virtual switch state",
                    "settable": true,
                    "propertyOpts": {
                        "readValueFromMqtt": true
                    }
                }
            ]
        }
    ]
}

The resulting device on mqtt will then look like the following:

virtual-device-mqtt-explorer

General note The following fields on the device cannot be specified:

  • state
  • homie
  • extensions

As you can see in the example above there are a few extra configuration options that can be used. Below you can find them listed by homie structure element.

Node level extra configuration

passThrough (boolean, default false):

  • when set to true, all properties below this node will 'autoconfirm' /set messages sent to them. Which means they will simply update their value state with the value sent to /set.

  • when set to false, you have to take care to update the property value in your flow yourself using the vprop value (homie-vproperty-value-update) node.

fromSmarthome (object):

  • node-homie-red uses the node-homie and hc-node-homie-smarthome libraries under the hood. The later one defines a set of standard node types for smarthome usage in the homie-homecontrol smarthome system. This option offers easy specification of these default nodes in your devices. For more details see the section Smarthome Spec.

propertyOpts (object, default { "readValueFromMqtt": true, "readTimeout": 3000 }):

  • node-homie offers to read the current value of a property from mqtt when creating the device. Basically using mqtt as persistent storage itself. This is useful to retain the last value of the property in case of a Node-RED restart for example.

    TODO: maybe provide a value field in the spec to always initialize with a static value.

  • readValueFromMqtt: Default is to read the last value in on device initialization - if you set this to false make sure to take of setting the inital value for the property after a Node-RED restart.

  • readTimeout: max time in milliseconds to wait for a message to be received from mqtt for the property topic. Please note for new empty properties this leads to a delay of readTimeout milliseconds before the device finishes intializing (transitions to state ready).
  • data format:
    {
        "readValueFromMqtt": true,
        "readTimeout": 3000
    }

Property level extra configuration

passThrough (boolean, default false):

  • when set to true, all the property will 'autoconfirm' /set messages sent to them. Which means it will simply update it's value state with the value sent to /set.

  • when set to false, you have to take care to update the property value in your flow yourself using the vprop value (homie-vproperty-value-update) node.

  • this will overwrite any setting on node level per property

propertyOpts (object, default { "readValueFromMqtt": true, "readTimeout": 3000 }):

  • node-homie offers to read the current value of a property from mqtt when creating the device. Basically using mqtt as persistent storage itself. This is useful to retain the last value of the property in case of a Node-RED restart for example.

    TODO: maybe provide a value field in the spec to always initialize with a static value.

  • readValueFromMqtt: Default is to read the last value in on device initialization - if you set this to false make sure to take of setting the inital value for the property after a Node-RED restart.

  • readTimeout: max time in milliseconds to wait for a message to be received from mqtt for the property topic. Please note for new empty properties this leads to a delay of readTimeout milliseconds before the device finishes intializing (transitions to state ready).
  • data format:
    {
        "readValueFromMqtt": true,
        "readTimeout": 3000
    }

Smarthome Spec

The smarthome spec offers quick definition of nodes and properties according to the homie-homecontrol smarthome node definition without having to specify every single property manually. (see hc-node-homie-smarthome)

For example, if you only need a simple switch the following device spec:

{
    "id": "node-red-virtual-device-2",
    "name": "Virtual switch device",
    "nodes": [
        {
            "id": "switch",
            "fromSmarthome": {
                "type": "homie-homecontrol/v1/type=switch"
            }
        }
    ]
}

Would result in a device with the following properties:

from-smarthome-example

Data format for fromSmarthome:

{
    "type": "homie-homecontrol/v1/type=<typename>",
    "config": {
        // typespecific node configuration
    }
}

type

  • The following types are supported:
    • homie-homecontrol/v1/type=battery
    • homie-homecontrol/v1/type=switch
    • homie-homecontrol/v1/type=contact
    • homie-homecontrol/v1/type=weather
    • homie-homecontrol/v1/type=button
    • homie-homecontrol/v1/type=tiltsensor
    • homie-homecontrol/v1/type=motionsensor
    • homie-homecontrol/v1/type=thermostat
    • homie-homecontrol/v1/type=mediaplayer
    • homie-homecontrol/v1/type=powermeter
    • homie-homecontrol/v1/type=maintenance
    • homie-homecontrol/v1/type=dimmer
    • homie-homecontrol/v1/type=shutter
    • homie-homecontrol/v1/type=colorlight
    • homie-homecontrol/v1/type=text

config

  • Each type has it's own configuration. for more details see the technical spec of the data model.

Overriding or extending on default nodes

You can still provide a properties field in combination with fromSmarthome. Any matching property ids will overwrite the default ones where supported. You can also extend the node with additional properties (however then it is not adhering to the standard any more)

Virtual Device (homie-vdevice)

node-homie-vdevice

Update virtual device state.

Input

If a message is sent to the node the device will be set to the payload value. If not payload is specified only the current state will be emitted via the output.

Output

Will send outgoing messages with the device state (init, ready...).

Outgoing messages include device state in the payload and device id as seperate field:

{
    "payload": "ready",
    "device": "security"
}

vprop value (homie-vproperty-value-update)

node-homie-vproperty-value-update

Update virtual device's property value.

Input

If a message is sent to the node the properties value will be set to the payload value. Please not that this is different from the homie-property node as it will update the interval value of the property which will be then published to mqtt. The homie-property will send a /set message which is different.

vprop /set (homie-vproperty-set-command)

node-homie-vproperty-set-command

Emits when a message is published under the virtual device's property '/set' topic.

Output

Message with /set value that was send to the device via mqtt.

Outgoing messages include the /set value as payload and a topic and property field with the property path:

{
    "payload": "true",
    "topic": "lamp-1/switch/state",
    "property": "lamp-1/switch/state"
}