Integration to third party – A Beginner’s Guide to DIY Smart Home

You have successfully set up and secured your initial IoT network. However, as your private home IoT network grows, maintaining each device individually becomes a real burden. This is where overarching smart home management systems come to save the day. Two of the most popular open-source tools today are Node-RED and Home Assistant. These platforms offer robust tools to quickly integrate any smart device, including custom or self-made ones, as long as they utilize open communication APIs like HTTP and MQTT.

To integrate with these systems, unicontrol features an extensive, fully documented HTTP API and MQTT API, ensuring seamless, unrestricted communication and straightforward integration with any third-party management system or architecture. The exchange between the device and the system then occurs using MQTT messages or HTTP REST requests with a strictly predefined structure.

While Home Assistant can support a Node-RED instance within itself, these two systems are fundamentally different, requiring distinct approaches for setup and configuration.

Node-RED flow configuration window
Node-RED flow configuration window
Home Assistant configuration editor
Home Assistant configuration editor

How to

While it is entirely possible to manually build any required URL or MQTT topic by following the instructions provided in the HTTP API and MQTT API documentation, the most important and relevant ones are automatically generated and embedded directly into the interface tooltips. Users can easily copy the desired string to the clipboard by clicking on the clipboard icon. Typically, you will encounter the following formats:

  • Topic: Represents the topic of an MQTT message. Outbound messages usually contain the /pub/ level in the topic string, while inbound messages are typically distinguished by the /sub/ level. Parameter topics (containing /sub/) are special and can be used for both inbound and outbound messages. States and Values are provided as raw integers, decimals, or strings, depending on the requested variable, and are included in the message’s Payload.
  • URL read: Provides the precise URL address from which a specific value or reading can be obtained in response to an HTTP GET request. This response contains the raw value based on the requested variable.
  • URL set: Provides the precise URL address to which a specific parameter or command can be sent using an HTTP POST request. The request must contain the raw value corresponding to the requested variable or command.

If the URL/topic string contains any placeholder text highlighted by [*] brackets, it must be replaced by a valid integer to make the URL/topic functional. This integer may represent the day of the week ([i]), a time interval ([i]), a State ([stat]), or a general Value.

Although sending data and commands should be done using the HTTP POST method, unicontrol will respond identically to the HTTP GET method. Utilizing the HTTP GET method to send commands is, for example, a common practice in Home Assistant.

Interface tooltip displaying selected relevant topics and URLs
Interface tooltip displaying selected relevant topics and URLs

Video guide

You may follow our video tutorial demonstrating the integration of a simple unicontrol device with Node-RED and Home Assistant in a real-world scenario. Using both MQTT and HTTP, the demonstration focuses on the following two aspects of such integration:

  • Obtaining Readings (demonstrated with a standard DHT22 sensor)
  • Remote Switch (demonstrated with an ESP8266 on-board LED)

The use cases above are only selected examples and do not exhaust the integration capabilities.

All JSON and YAML codes used in the video are available below.

Resources used in a video

To fully replicate what is shown in the video, you may utilize the following resources:

  1. Unicontrol Device and Processes setup (JSON)
  2. Node-RED Flow and Dashboard setup (JSON)
  3. Home Assistant Configuration and Dashboard setup (YAML)

1. Unicontrol

Use the JSON files below to get quickly up to speed. They contain unicontrol settings compatible with the rest of the tutorial. Note that device settings and process settings are separated into different files and must be imported separately.

Wi-Fi settings are not included in the device file above. These are expected to be provided prior to importing the settings.

Device
JSON
{"version":1.16,"data":"device","mqttallow":1,"mqttip":"test.mosquitto.org","mqttuser":"","topicL1":"ayatec","topicL2":"integration","topicL3":"showcase","d4d":1,"d5d":24,"timestamp":"26.06.2024"}
Device Download

Processes
JSON
{"version":1.16,"data":"processes","pname_1":"LED","mstr_1":1,"outper_1":4,"outinv_1":1,"outpub_1":1,"pname_2":"temperature","mstr_2":1,"inper_2":5,"inpub_2":1,"inpubfr_2":3,"procfrom":1,"procto":5,"timestamp":"26.06.2024"}
Processes Download

2. Node-RED

Although you can follow the video to build your own Node-RED flow and dashboards, copy-pasting the following JSON will certainly speed up the process.

Remember to replace all [*placeholder*] strings with valid values copied from the interface. This can be done either before or after importing the JSON into Node-RED.

Flow, Dashboard & Broker
JSON
[
    {
        "id": "5731580a18aac99d",
        "type": "inject",
        "repeat": "10",
        "once": false,
        "x": 110,
        "y": 100,
        "wires": [["18ba2c67b5962669"]]
    },
    {
        "id": "18ba2c67b5962669",
        "type": "http request",
        "method": "GET",
        "url": "[*Temperature reading URL*]",
        "x": 330,
        "y": 100,
        "wires": [["4b4f92d7e552f9bb"]]
    },
    {
        "id": "107eb3eb8c0b8fe0",
        "type": "mqtt in",
        "topic": "[*Temperature reading topic*]",
        "broker": "275fb70c0e5ba1e8",
        "x": 210,
        "y": 140,
        "wires": [["32b776ae01606b22"]]
    },
    {
        "id": "4b4f92d7e552f9bb",
        "type": "ui_gauge",
        "group": "36c7f6690f714d07",
        "gtype": "gage",
        "title": "Temperature HTTP",
        "label": "°C",
        "format": "{{value}}",
        "min": 0,
        "max": "35",
        "x": 550,
        "y": 100,
        "wires": []
    },
    {
        "id": "32b776ae01606b22",
        "type": "ui_gauge",
        "group": "36c7f6690f714d07",
        "gtype": "gage",
        "title": "Temperature MQTT",
        "label": "°C",
        "format": "{{value}}",
        "min": 0,
        "max": "35",
        "x": 550,
        "y": 140,
        "wires": []
    },
    {
        "id": "343501510db5fdbd",
        "type": "ui_switch",
        "label": "LED HTTP",
        "group": "36c7f6690f714d07",
        "onvalue": "{\"val\":1}",
        "onvalueType": "json",
        "offvalue": "{\"val\":0}",
        "offvalueType": "json",
        "x": 90,
        "y": 260,
        "wires": [["f68b0144cabfca64"]]
    },
    {
        "id": "f68b0144cabfca64",
        "type": "http request",
        "method": "GET",
        "ret": "txt",
        "paytoqs": "query",
        "url": "[*Output set URL without &val=0/1 !!!*]",
        "x": 290,
        "y": 260,
        "wires": [[]]
    },
    {
        "id": "bffaac11ab21f255",
        "type": "ui_switch",
        "label": "LED MQTT",
        "group": "36c7f6690f714d07",
        "onvalue": "1",
        "onvalueType": "str",
        "offvalue": "0",
        "offvalueType": "str",
        "x": 90,
        "y": 320,
        "wires": [["3f123412576b2f19"]]
    },
    {
        "id": "3f123412576b2f19",
        "type": "mqtt out",
        "topic": "[*Output set topic*]",
        "broker": "275fb70c0e5ba1e8",
        "x": 430,
        "y": 320,
        "wires": []
    },
    {
        "id": "275fb70c0e5ba1e8",
        "type": "mqtt-broker",
        "name": "mosquitto.org",
        "broker": "test.mosquitto.org",
        "port": "1883"
    },
    {
        "id": "36c7f6690f714d07",
        "type": "ui_group",
        "name": "Home",
        "tab": "cfd6935e1ed77512",
        "order": 1,
        "disp": true,
        "width": "6",
        "collapse": false,
        "className": ""
    },
    {
        "id": "cfd6935e1ed77512",
        "type": "ui_tab",
        "name": "Tab 1",
        "icon": "dashboard"
    }
]

3. Home Assistant

In Home Assistant, you may need to copy-paste the following Configuration code into the configuration.yaml file, as building it from scratch is significantly less convenient. However, the Dashboard part is easy to reproduce manually. You can still copy-paste the code into the newly created dashboard’s Raw configuration editor to ensure full alignment with the tutorial.

Home Assistant only supports a single MQTT broker and needs to be set up independently. Please use the address test.mosquitto.org and port 1883 with no credentials.

Again, remember to replace all [*placeholder*] strings with valid values copied from the interface. This can be done either before or after pasting the YAML into Home Assistant.

Configuration
YAML
#---------------------------------------------------
#                   MQTT CASE
#---------------------------------------------------

mqtt:
  sensor:
  - name: "Thermometer MQTT"
    object_id: "thermometer_mqtt"                                               # optional
    state_topic: "[*Temperature reading topic*]"                                # topic provided in the unicontrol interface
    unit_of_measurement: "°C"
    value_template: "{{ value | float }}"
  switch:
    name: "LED Control MQTT"                                                    # MQTT Switch is more straightforward and does not need helper scripts
    object_id: "led_control_mqtt"                                               # optional
    state_topic: "[*Output state topic*]"                                       # topic provided in the unicontrol interface
    command_topic: "[*Output set topic*]"                                       # topic provided in the unicontrol interface
    payload_on: "1"                                                             # may be used to reverse the On/Off logic if necessary
    payload_off: "0"
    optimistic: false                                                           # requires the new state confirmation from the device instead of an immediate state change
    retain: false                                                               # optional


#---------------------------------------------------
#                   HTTP CASE
#---------------------------------------------------

sensor:
  - platform: rest
    name: "Thermometer HTTP"
    resource: "[*Temperature reading URL*]"                                     # url provided in the unicontrol interface
    method: GET
    scan_interval: 30                                                           # time in seconds between updates initiated by HA
    value_template: "{{ value | float }}"
    unit_of_measurement: "°C"
  - platform: rest
    name: "LED State HTTP"                                                      # current state of the LED process - feedback for the Rest Switch
    resource: "[*Output state URL*]"                                            # url provided in the unicontrol interface
    method: GET
    scan_interval: 30                                                           # basic time in seconds between updates initiated by HA
    value_template: "{{ value }}" 
      
rest_command:
  http_led_on:
    url: "[*Output set on URL*]"                                                # url provided in the unicontrol interface
  http_led_off:
    url: "[*Output set off URL*]"                                               # url provided in the unicontrol interface
    
script:
  button_http_led_on:
    sequence:
      - service: rest_command.http_led_on                                       # a callable command used by HTTP Rest buttons or switches
  button_http_led_off:
    sequence:
      - service: rest_command.http_led_off                                      # a callable command used by HTTP Rest buttons or switches
  update_led_state_http:
    sequence:
      - service: homeassistant.update_entity
        target:
          entity_id: sensor.led_state_http

switch:
  - platform: template
    switches:
      led_control_http:
        friendly_name: "LED Control HTTP"                                       # HTTP Switch in HA requires significant overhead in form of rest commands and sctips definitions
        value_template: "{{ is_state('sensor.led_state_http', '1') }}"          # state feedback
        turn_on:
          service: rest_command.http_led_on
        turn_off:
          service: rest_command.http_led_off

automation:                                                     
  - alias: "HTTP LED State check"                                               # check current LED state outside of the preset interval - switch feedback
    trigger:
      - platform: event    
        event_type: call_service
        event_data:
          domain: switch
          service: turn_on                                                      # verify state when switching on
          service_data:
            entity_id: switch.led_control_http
      - platform: event    
        event_type: call_service
        event_data:
          domain: switch
          service: turn_off                                                     # verify state when switching off
          service_data:
            entity_id: switch.led_control_http
      - platform: event                                                         # MQTT switch also added as a trigger so that the HTTP switch will react to changes on the MQTT switch (normally it would not)
        event_type: call_service
        event_data:
          domain: switch
          service: turn_on                                                      # verify state when switching on
          service_data:
            entity_id: switch.led_control_mqtt
      - platform: event
        event_type: call_service
        event_data:
          domain: switch
          service: turn_off                                                     # verify state when switching off
          service_data:
            entity_id: switch.led_control_mqtt
    action:
      - service: homeassistant.update_entity
        target:
          entity_id: sensor.led_state_http                                      # request current LED state

Dashboard
YAML
title: ayatec demo
views:
  - title: Home
    cards:
      - type: gauge
        entity: sensor.thermometer_http
      - show_name: true
        show_icon: true
        type: button
        entity: switch.led_control_http
        tap_action:
          action: toggle
      - type: gauge
        entity: sensor.thermometer_mqtt
      - show_name: true
        show_icon: true
        type: button
        entity: switch.led_control_mqtt
        tap_action:
          action: toggle