SweetHomeHub: Home Control with Raspberry Pi and MQTT – Part 1

Since quite a long time I am working on my universal Raspberry Pi based Intertechno-Remote (see former posts 1 2 3 4):

intertechno remote

I tried different approaches to trigger/control my remote control service via a custom HTTPServer/-Handler and a simple Vert.x verticle.
Since MQTT v3.1.1 turns out as on of the de-facto standard protocols for the IoT I also implemented an MQTT client.

This MQTT client basically follows two design patterns:

1. One topic for each device
For each device a topic is defined. Its state can be controlled by publishing a message with payload “ON” or “OFF”.
Pro:

  • the user must not know about the address code of the Intertechno device
  • changes of the address must not be published
  • the message is simply “ON” or “OFF to control the device

Contra:

  • the user must know the topic for each device
  • the user can only control configured devices

2. One topic for a JSON message
Pro:

  • very flexible to control the devices

Contra:

  • the user must know about the syntax of the JSON and the coding of devices

Solution:
Provide both options 😉

One topic for each device

topics_table

My configuration is very simple
On start-up the Client is searching for sweethomehub-config.xml in the users home directory which is then unmarshalled from JAXB.
This configuration contains the codes and the topic for each device and the MQTT settings for the broker connection:

<configuration>
    <devices>
        <device>
            <houseCode>a</houseCode>
            <groupId>1</groupId>
            <deviceId>1</deviceId>
            <name>Light Front-Door</name>
            <mqttTopic>front/lights/door</mqttTopic>
        </device>
        <device>
            <houseCode>a</houseCode>
            <groupId>1</groupId>
            <deviceId>2</deviceId>
            <name>Light Terrace</name>
            <mqttTopic>garden/lights/terrace</mqttTopic>
        </device>
        <device>
            <houseCode>a</houseCode>
            <groupId>1</groupId>
            <deviceId>3</deviceId>
            <name>Fountain</name>
            <mqttTopic>garden/devices/fountain</mqttTopic>
        </device>
        <device>
            <houseCode>a</houseCode>
            <groupId>1</groupId>
            <deviceId>4</deviceId>
            <name>Light Garden</name>
            <mqttTopic>garden/lights/ambiente</mqttTopic>
        </device>
        <device>
            <houseCode>a</houseCode>
            <groupId>1</groupId>
            <deviceId>3</deviceId>
            <name>Light Living Room</name>
            <mqttTopic>livingroom/lights/ambiente</mqttTopic>
        </device>
    </devices>
    <mqttClientConfiguration>
        <mqttClientId>SweethoemMQTTClientId</mqttClientId>
        <mqttBrokerAddress>sweethome</mqttBrokerAddress>
        <mqttBrokerPort>1883</mqttBrokerPort>
        <mqttMessagesBaseTopic>sweethome</mqttMessagesBaseTopic>
    </mqttClientConfiguration>
</configuration>

And there is one additional topic awaiting the JSON commands:
sweethome/devices/jsoncommand

{
  "devices":[
    {
      "device":{
        "name": "Light Front-Door",
        "houseCode": "a",
        "groupId": "1",
        "deviceId": "1"
      },
      "command":"ON"
    },
    {
      "device":{
        "name": "Light Terrace",
        "houseCode": "a",
        "groupId": "1",
        "deviceId": "2"
      },
      "command":"ON"
    },
    {
      "device":{
        "name": "Light Living Room",
        "houseCode": "a",
        "groupId": "1",
        "deviceId": "3"
      },
      "command":"ON"
    }
  ]
}

The central method to handle arrived messages:

MqttMessageReceiver.messageArrived

The JsonDeviceCommandProcessor:

JsonCommandProcessor

And the doSwitch methods:

DeviceControl

MQTT Client running on the Raspberry Pi waiting for messages:
mqtt-receiver

… and receiving command messages:

mqtt-receiver-commands

Testing the receiver with MQTT.fx

mqtt-fx

Complete code can be found at BitBucket.

Recommended Reading

Discuss

Your email address will not be published. Required fields are marked *