Pushing Status Updates to OpenHab Switch from Node-Red

Hi guys, i have a Node Red Flow that outputs an On or Off string, How can i use this to update the status of a Light Switch.
This is what i currently have
I can turn the light on via Openhab it then publishes a string to MQTT,
then MQTT picks this change up and then runs through a subflow to check the last know state. this outputs a “0” for off or “1” for on. i then run it through a switch to detect it and set each to either “ON” or “OFF”
this is done like this because i also have devices on MQTT updating the Lights

Cheers

why you just wont map OH item to mqtt so it will update self via mqtt instead of nodered?
wouldnt be that simplier?

@kriznik
How can i do that?

well it depends on which sw ur running on those switches, but in general, when u have working mqtt it should be enough to all the tricks.

nodered publishes to mqtt ON, and switches which are subbed to that topic will update self, or if there are several topics you’ll need to create rule which will pickup state of changed item and send commands to others.

hows your items defined?

This is my .items file


Group    Home           "Home"           <house>                            ["Building"]

Group    GF             "Ground Floor"   <groundfloor>   (Home)             ["GroundFloor"]

Group    Office         "Office"         <office>        (Home)             ["Room"]

Switch   Office_Light   "Light"          <light>         (gLight)   ["Lighting", "Switchable"]     
Switch   Lounge_Light   "Light"          <light>         (gLight)   ["Lighting", "Switchable"]   
Switch   Bedroom1_Light   "Light"          <light>         (gLight)   ["Lighting", "Switchable"] 
Group:Switch:OR(ON, OFF)   gLight   "Light"   <light>   (Home)   ["Lighting", "Switchable"]

everything ive done so far has been via Node red

and things?
do you have mqtt binding going?

Dont have one,
ive installed the binding, but couldnt figure out the .things file

well you either configure it via paperui or things files.
then you will end up with something like

switch light [channel=mqtt:broker:myswitch:switch]

which will listen on defined mqtt topic for any updates

I can give you an example later on as am now on ipad :slight_smile:

@kriznik if you could that would be fantastic

Cheers

so, here we go.
I’ll show you how to configure it via files which suits me better, but you can indeed do it in PaperUI GUI if you like as well.

  1. configure your MQTT Broker in OH
    /conf/things/mqtt-broker.things
Bridge mqtt:broker:home "Mosquitto MQTT Broker" [ 
  host="IP",
  secure=false,
  port=1883,
  qos=0,
  retain=false,
  clientid="somerandomstring",
  //certificate="",
  //certificatepin=false,
  //publickey="",
  //publickeypin=false,
  keep_alive_time=30000,
  reconnect_time=60000,
  //lastwill_message="",
  //lastwill_qos=1,
  //lastwill_topic="",
  username="",
  password=""
]
  1. configure your switch (let’s asume it’s Tasmota)
    /conf/things/switches.things
Thing mqtt:topic:WallSwitchDressroom1 "WallSwitch Light Dressroom" (mqtt:broker:home) @ "Dressroom" {
Channels:
    Type switch : switch        "Dressroom Lights"  [ stateTopic="home/dressroom/light/1/stat/POWER", commandTopic="home/dressroom/light/1/cmnd/POWER", on="ON", off="OFF" ]
    Type string : wifi-ssid     "Wifi SSID"         [ stateTopic="home/dressroom/light/1/tele/STATE", transformationPattern="JSONPATH:$.Wifi.SSId" ]
    Type string : wifi-rssi     "Wifi RSSI"         [ stateTopic="home/dressroom/light/1/tele/STATE", transformationPattern="JSONPATH:$.Wifi.RSSI" ]
    Type string : uptime        "Uptime"            [ stateTopic="home/dressroom/light/1/tele/STATE", transformationPattern="JSONPATH:$.Uptime" ]
    Type string : time          "Time"              [ stateTopic="home/dressroom/light/1/tele/STATE", transformationPattern="JSONPATH:$.Time" ]
    Type string : devicestate   "Device State"      [ stateTopic="home/dressroom/light/1/tele/LWT" ]
} 
Thing mqtt:topic:WallSwitchDressroom2 "WallSwitch Light Dressroom" (mqtt:broker:home) @ "Dressroom" {
Channels:
    Type switch : switch        "Dressroom Lights"  [ stateTopic="home/dressroom/light/2/stat/POWER", commandTopic="home/dressroom/light/2/cmnd/POWER", on="ON", off="OFF" ]
    Type string : wifi-ssid     "Wifi SSID"         [ stateTopic="home/dressroom/light/2/tele/STATE", transformationPattern="JSONPATH:$.Wifi.SSId" ]
    Type string : wifi-rssi     "Wifi RSSI"         [ stateTopic="home/dressroom/light/2/tele/STATE", transformationPattern="JSONPATH:$.Wifi.RSSI" ]
    Type string : uptime        "Uptime"            [ stateTopic="home/dressroom/light/2/tele/STATE", transformationPattern="JSONPATH:$.Uptime" ]
    Type string : time          "Time"              [ stateTopic="home/dressroom/light/2/tele/STATE", transformationPattern="JSONPATH:$.Time" ]
    Type string : devicestate   "Device State"      [ stateTopic="home/dressroom/light/2/tele/LWT" ]
} 
  1. configure your items (let’s work with dressroom for now)
    /conf/items/dressroom.items
Switch  WSwitch_Dressroom1   "Dressroom Lights"  <light>     (gWSwitch, gLightsHome, gLights, gStoreChange) ["Switchable"]  { channel="mqtt:topic:WallSwitchDressroom1:switch" }
Switch  WSwitch_Dressroom2   "Dressroom Lights"  <light>     (gWSwitch, gLightsHome, gLights, gStoreChange) ["Switchable"]  { channel="mqtt:topic:WallSwitchDressroom2:switch" }

So this is definition, now, when you publish via NodeRed ON into home/dressroom/light/+/cmnd/POWER ON
both switches will be ON
And indeed OH state will be updated automatically based on MQTT

However this will not do anything when you press button on the switch itself. Here will be handy OH rules or NodeRed rules or Tasmota Group topic, which will trigger button on slave switch whenever needed.

For this take a look in here, I’ve posted it yesterday:

basically you either can use rules in OH or directly in NodeRed which will publish msg into relevant MQTT topic. I do prefer not to use Tasmota group topics, but instead I’m using this:

NodeRed (this is just for a general idea how to put those rules together)

[{"id":"a7769c75.cda58","type":"mqtt in","z":"9d128c8a.994b5","name":"Switch 08","topic":"sonoff-touch-08/stat/POWER","qos":"0","datatype":"utf8","broker":"83323ac5.ab4df8","x":300,"y":4120,"wires":[["134b5b18.61d3e5","88b82873.07df98"]]},{"id":"3a4af89a.3d3d48","type":"mqtt in","z":"9d128c8a.994b5","name":"Switch 09","topic":"sonoff-touch-09/stat/POWER","qos":"0","datatype":"utf8","broker":"83323ac5.ab4df8","x":300,"y":4220,"wires":[["88b82873.07df98","134b5b18.61d3e5"]]},{"id":"a2bb607f.6bd8a","type":"change","z":"9d128c8a.994b5","name":"08","rules":[{"t":"set","p":"status08","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":690,"y":4120,"wires":[[]]},{"id":"134b5b18.61d3e5","type":"switch","z":"9d128c8a.994b5","name":"08s","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"status08","vt":"flow"},{"t":"neq","v":"status08","vt":"flow"}],"checkall":"true","repair":false,"outputs":2,"x":510,"y":4120,"wires":[["a2bb607f.6bd8a"],["a2bb607f.6bd8a","48747ed4.c73b2"]]},{"id":"88b82873.07df98","type":"switch","z":"9d128c8a.994b5","name":"09s","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"status09","vt":"flow"},{"t":"neq","v":"status09","vt":"flow"}],"checkall":"true","repair":false,"outputs":2,"x":510,"y":4220,"wires":[["aacb9062.c6922"],["aacb9062.c6922","27d97c2.8192d84"]]},{"id":"aacb9062.c6922","type":"change","z":"9d128c8a.994b5","name":"09","rules":[{"t":"set","p":"status09","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":690,"y":4220,"wires":[[]]},{"id":"48747ed4.c73b2","type":"mqtt out","z":"9d128c8a.994b5","name":"to the 08","topic":"sonoff-touch-08/cmnd/POWER","qos":"","retain":"","broker":"83323ac5.ab4df8","x":700,"y":4160,"wires":[]},{"id":"27d97c2.8192d84","type":"mqtt out","z":"9d128c8a.994b5","name":"to the 09","topic":"sonoff-touch-09/cmnd/POWER","qos":"","retain":"","broker":"83323ac5.ab4df8","x":700,"y":4260,"wires":[]},{"id":"83323ac5.ab4df8","type":"mqtt-broker","z":"","name":"MQTT","broker":"IP","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

I’m pretty sure you can do it as you originaly posted, but it’s unnecessary as you already have all needed informations from/in mqtt. And OH will update self based on those informations.

Hi @kriznik

I have set all that up. i believe ive done it all correctly, but i cant seam to get openhab to change the state of the switch

Here are my config files, ive modified them to suit my needs because my light switches are based based on a stateless design, it just sends the same string on each press i needed a way to store and check the state in Mqtt.
i made this Subflow

[{"id":"9c00f54f.6d8b28","type":"subflow","name":"Panel 20 button 41","info":"","category":"","in":[{"x":300,"y":320,"wires":[{"id":"177fd9f2.6de656"}]}],"out":[{"x":1060,"y":320,"wires":[{"id":"ea211b8a.407558","port":0},{"id":"59c06ba.0d6b894","port":0}]}],"env":[]},{"id":"b334b24f.d3394","type":"switch","z":"9c00f54f.6d8b28","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"str"},{"t":"eq","v":"0","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":650,"y":320,"wires":[["ea211b8a.407558"],["59c06ba.0d6b894"]]},{"id":"ea211b8a.407558","type":"change","z":"9c00f54f.6d8b28","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"1","tot":"str"},{"t":"set","p":"next","pt":"flow","to":"0","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":860,"y":280,"wires":[[]]},{"id":"59c06ba.0d6b894","type":"change","z":"9c00f54f.6d8b28","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"0","tot":"str"},{"t":"set","p":"next","pt":"flow","to":"1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":860,"y":340,"wires":[[]]},{"id":"177fd9f2.6de656","type":"function","z":"9c00f54f.6d8b28","name":"get next value","func":"if (msg.payload == \"20-41\") {\nmsg.payload = flow.get(\"next\")||0;\nreturn msg;\n} \nelse {\nmsg.payload=\"\"\n}\n","outputs":1,"noerr":0,"x":460,"y":320,"wires":[["b334b24f.d3394"]]}]

and this is my current flow.

[{"id":"9c00f54f.6d8b28","type":"subflow","name":"Panel 20 button 41","info":"","category":"","in":[{"x":300,"y":320,"wires":[{"id":"177fd9f2.6de656"}]}],"out":[{"x":1060,"y":320,"wires":[{"id":"ea211b8a.407558","port":0},{"id":"59c06ba.0d6b894","port":0}]}],"env":[]},{"id":"b334b24f.d3394","type":"switch","z":"9c00f54f.6d8b28","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"str"},{"t":"eq","v":"0","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":650,"y":320,"wires":[["ea211b8a.407558"],["59c06ba.0d6b894"]]},{"id":"ea211b8a.407558","type":"change","z":"9c00f54f.6d8b28","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"1","tot":"str"},{"t":"set","p":"next","pt":"flow","to":"0","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":860,"y":280,"wires":[[]]},{"id":"59c06ba.0d6b894","type":"change","z":"9c00f54f.6d8b28","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"0","tot":"str"},{"t":"set","p":"next","pt":"flow","to":"1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":860,"y":340,"wires":[[]]},{"id":"177fd9f2.6de656","type":"function","z":"9c00f54f.6d8b28","name":"get next value","func":"if (msg.payload == \"20-41\") {\nmsg.payload = flow.get(\"next\")||0;\nreturn msg;\n} \nelse {\nmsg.payload=\"\"\n}\n","outputs":1,"noerr":0,"x":460,"y":320,"wires":[["b334b24f.d3394"]]},{"id":"4600abdd.2cc1a4","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"4068230e.faf1ac","type":"mqtt in","z":"4600abdd.2cc1a4","name":"","topic":"buttons","qos":"0","datatype":"auto","broker":"ba6907f8.d77f18","x":170,"y":200,"wires":[["a48c0d0b.0ef5f"]]},{"id":"e47550bc.7f4dd","type":"openhab2-in","z":"4600abdd.2cc1a4","name":"","controller":"f7d06c8e.b7d0a","itemname":"Office_Light","x":150,"y":120,"wires":[["cb6877a9.dc9fb8"],[]]},{"id":"cb6877a9.dc9fb8","type":"change","z":"4600abdd.2cc1a4","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"20-41","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":440,"y":100,"wires":[["d36595ad.8bfb68"]]},{"id":"d36595ad.8bfb68","type":"mqtt out","z":"4600abdd.2cc1a4","name":"","topic":"buttons","qos":"0","retain":"","broker":"ba6907f8.d77f18","x":660,"y":60,"wires":[]},{"id":"a48c0d0b.0ef5f","type":"subflow:9c00f54f.6d8b28","z":"4600abdd.2cc1a4","name":"","env":[],"x":430,"y":160,"wires":[["4174d83d.b994a8"]]},{"id":"65a40361.135abc","type":"comment","z":"4600abdd.2cc1a4","name":"Panel 20 button 41","info":"","x":150,"y":60,"wires":[]},{"id":"4174d83d.b994a8","type":"switch","z":"4600abdd.2cc1a4","name":"Change Payload to On or Off","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"str"},{"t":"eq","v":"1","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":720,"y":120,"wires":[["21d47498.1f566c"],["56346c7d.136074"]]},{"id":"56346c7d.136074","type":"change","z":"4600abdd.2cc1a4","name":"Light ON","rules":[{"t":"change","p":"payload","pt":"msg","from":"1","fromt":"str","to":"ON","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":920,"y":140,"wires":[["7377e6d.32f9118"]]},{"id":"21d47498.1f566c","type":"change","z":"4600abdd.2cc1a4","name":"Light OFF","rules":[{"t":"change","p":"payload","pt":"msg","from":"0","fromt":"str","to":"OFF","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":920,"y":80,"wires":[["7377e6d.32f9118"]]},{"id":"7377e6d.32f9118","type":"delay","z":"4600abdd.2cc1a4","name":"","pauseType":"delay","timeout":"50","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":950,"y":200,"wires":[["dda2bda4.fa1e9"]]},{"id":"9bb9b8c5.7ca538","type":"debug","z":"4600abdd.2cc1a4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1010,"y":320,"wires":[]},{"id":"dda2bda4.fa1e9","type":"mqtt out","z":"4600abdd.2cc1a4","name":"","topic":"home/office/light/1/cmnd/POWER","qos":"","retain":"","broker":"ba6907f8.d77f18","x":1240,"y":100,"wires":[]},{"id":"50db30b0.ea713","type":"mqtt in","z":"4600abdd.2cc1a4","name":"","topic":"home/office/light/1/cmnd/POWER","qos":"0","datatype":"auto","broker":"ba6907f8.d77f18","x":680,"y":320,"wires":[["9bb9b8c5.7ca538"]]},{"id":"ba6907f8.d77f18","type":"mqtt-broker","z":"","name":"Mosquitto","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"f7d06c8e.b7d0a","type":"openhab2-controller","z":"","name":"Openhab","protocol":"http","host":"localhost","port":"8080","path":"","username":"openhabian","password":"bedrock"}]

doing it this way i can have openhab effectively act in a somewhat stateless manner and have my subflow manage the state. this is all working correclty i just cant seam to get openhab to update the state.

just the rest of my configs.

lights.items

Switch  Office_Light   "Office Light"  <light>     (gWSwitch, gLightsHome, gLights, gStoreChange) ["Switchable"]  { channel="mqtt:topic:officelight:switch" }
Switch  Lounge_Light   "Lounge Light"  <light>     (gWSwitch, gLightsHome, gLights, gStoreChange) ["Switchable"]  { channel="mqtt:topic:loungelight:switch" }

switches.things

Thing mqtt:topic:officelight "Office Light" (mqtt:broker:rpi) @ "Office" {
Channels:
    Type switch : switch        "Office Lights"  [ stateTopic="home/office/light/1/stat/POWER", commandTopic="home/office/light/1/cmnd/POWER", on="ON", off="OFF" ]
    Type string : devicestate   "Device State"      [ stateTopic="home/office/light/1/tele/LWT" ]
} 
Thing mqtt:topic:loungelight "Lounge Light" (mqtt:broker:rpi) @ "Lounge" {
Channels:
    Type switch : switch        "Dressroom Lights"  [ stateTopic="home/lounge/light/2/stat/POWER", commandTopic="home/lounge/light/2/cmnd/POWER", on="ON", off="OFF" ]
    Type string : devicestate   "Device State"      [ stateTopic="home/lounge/light/2/tele/LWT" ]
} 

mqtt-broker.things

Bridge mqtt:broker:rpi "Mosquitto MQTT Broker" [ 
  host="192.168.1.108",
  secure=false,
  port=1883,
  qos=0,
  retain=false,
  clientid="1921681108",
  //certificate="",
  //certificatepin=false,
  //publickey="",
  //publickeypin=false,
  keep_alive_time=30000,
  reconnect_time=60000,
  //lastwill_message="",
  //lastwill_qos=1,
  //lastwill_topic="",
  username="openhabian",
  password="bedrock"
]

default.sitemap

sitemap home label="Home" {
    Frame {
        Group item=Office
    }

    Frame {
        Text label="Light" icon="light" {
            Default item=Office_Light label="Office"
            Default item=Lounge_Light label="Office"
        }
        
    }
}

toggling the switch in either openhab or pressing one of my light switch buttons it sends the correct command ON or OFF so im hoping its just a mistake ive made somewhere,

Cheers

try something like this
(change it to your broker and your mqtt items)

OH will pickup information from mqtt as I can see it’s tasmota so it will be sending stat topic after receiving cmnd

[{"id":"638e945e.123bbc","type":"mqtt in","z":"c558c636.d27d08","name":"2","topic":"home/office/light/2/state/POWER","qos":"0","datatype":"utf8","broker":"83323ac5.ab4df8","x":290,"y":260,"wires":[["b5830905.b17648","9342fd20.a9f71"]]},{"id":"81ef06b4.b9f2a8","type":"mqtt in","z":"c558c636.d27d08","name":"1","topic":"home/office/light/1/state/POWER","qos":"0","datatype":"utf8","broker":"83323ac5.ab4df8","x":290,"y":360,"wires":[["9342fd20.a9f71","b5830905.b17648"]]},{"id":"b6df68a9.c63738","type":"change","z":"c558c636.d27d08","name":"2","rules":[{"t":"set","p":"status2","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":670,"y":220,"wires":[[]]},{"id":"b5830905.b17648","type":"switch","z":"c558c636.d27d08","name":"2 status","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"status2","vt":"flow"},{"t":"neq","v":"status2","vt":"flow"}],"checkall":"true","repair":false,"outputs":2,"x":500,"y":260,"wires":[["b6df68a9.c63738"],["b6df68a9.c63738","b736bf3d.44f89"]]},{"id":"9342fd20.a9f71","type":"switch","z":"c558c636.d27d08","name":"1 status","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"status1","vt":"flow"},{"t":"neq","v":"status1","vt":"flow"}],"checkall":"true","repair":false,"outputs":2,"x":500,"y":360,"wires":[["ba0a4139.dd427"],["ba0a4139.dd427","857b3311.0a1c1"]]},{"id":"ba0a4139.dd427","type":"change","z":"c558c636.d27d08","name":"1","rules":[{"t":"set","p":"status1","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":670,"y":340,"wires":[[]]},{"id":"b736bf3d.44f89","type":"mqtt out","z":"c558c636.d27d08","name":"to 2","topic":"home/office/light/2/cmnd/POWER","qos":"","retain":"","broker":"83323ac5.ab4df8","x":670,"y":280,"wires":[]},{"id":"857b3311.0a1c1","type":"mqtt out","z":"c558c636.d27d08","name":"to 1","topic":"home/office/light/1/cmnd/POWER","qos":"","retain":"","broker":"83323ac5.ab4df8","x":670,"y":400,"wires":[]},{"id":"83323ac5.ab4df8","type":"mqtt-broker","z":"","name":"MQTT","broker":"IP","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

hi @kriznik

i seam to be having a looping effect now.
if i publish into home/office/light/1/cmnd/POWER
it loops with on and off. and openhab still doesnt seam to be updating its state even
when i publish into
home/office/light/1/cmnd/POWER

any ideas?

nevermind, just restarted my RPI and its working,
@kriznik you sir are a legend. thank you for helping me :heart_eyes:

glad to help :slight_smile:

1 Like

@kriznik, you have any experience with arduino I2C,ive got a couple of the freetronics Relay8 boards that im struggling to control

not directly arduino, but as it is python, yes I do :slight_smile:

when i get home a bit later, ill post my current code, i can get 2 of the Relay8 board to work correctly but i cant get the second 2 to work correctly.

@kriznik

now that im home,

This is the code i currently have,

Relay Controller MQTT Code

#include <SPI.h>
#include “Ethernet.h”
#include “Wire.h”
#include <PubSubClient.h>
#include <stdlib.h>

#define SHIELD_1_I2C_ADDRESS 0x20 // 0x20 is the address with all jumpers removed
#define SHIELD_2_I2C_ADDRESS 0x21 // 0x21 is the address with a jumper on position A0

#define MAC_I2C_ADDRESS 0x50 // Microchip 24AA125E48 I2C ROM address

/* If channelInterlocks is set to true, the channels are grouped into

  • pairs starting at 1 (ie: channels 1 & 2, 3 & 4, etc) and only one
  • channel in each pair can be on at any time. For example, if channel
  • 1 is on and 2 is set to on, channel 1 will be turned off first and
  • vice versa. This is to allow control of dual-active devices such as
  • electric curtain motors which must only be driven in one direction
  • at a time. */
    const byte channelInterlocks = false;

/* CHANGE THIS TO YOUR OWN UNIQUE VALUE. The MAC number should be

  • different from any other devices on your network or you’ll have
  • problems receiving packets. Can be replaced automatically below
  • using a MAC address ROM. */
    static uint8_t mac[] = { 0xDE, 0xA7, 0x0E, 0xEF, 0xFE, 0xED };

/* CHANGE THIS TO MATCH YOUR HOST NETWORK. Most home networks are in

  • the 192.168.0.XXX or 192.168.1.XXX subrange. Pick an address
  • that’s not in use and isn’t going to be automatically allocated by
  • DHCP from your router. Can be replaced automatically using DHCP. */
    static uint8_t ip[] = { 192, 168, 1, 182 };

static uint8_t serverIP[] = { 192, 168, 1, 108 };

char* outputTopic="/output";
char topic[37];
char message[22];

byte shield1BankA = 0; // Current status of all outputs on first shield, one bit per output
byte shield2BankA = 0; // Current status of all outputs on second shield, one bit per output
EthernetClient ethClient;
PubSubClient client(serverIP, 1883, ethClient);

// New message receive
void callback(char* topic, byte* payload, unsigned int length) {
String strPayload= String((char*)payload).substring(0,length);

Serial.print(“Receive message”);
Serial.println(strPayload);

// topic will be something like /relay/power/1/01

char channel[]=" ";
channel[0]= *(topic+13);
channel[1]= *(topic+14);

unsigned short int relay = atoi(channel);

if (strPayload.equals(“on”))
{
setLatchChannelOn( relay );
publishState(atoi(channel),1,outputTopic);
Serial.print("Turning on ");
Serial.println(channel);
}

  if (strPayload.equals("off"))

  {
    setLatchChannelOff( relay );
    publishState(atoi(channel),0,outputTopic);
            Serial.print("Turning off ");
             Serial.println(channel);
  }

}

void setup()
{
Wire.begin(); // Wake up I2C bus
Serial.begin( 38400 );
Serial.println(“Strting MQTT Relay 8 board”);

Serial.print("Getting MAC address from ROM: ");
// mac[0] = readRegister(0xFA);
// mac[1] = readRegister(0xFB);
// mac[2] = readRegister(0xFC);
// mac[3] = readRegister(0xFD);
// mac[4] = readRegister(0xFE);
// mac[5] = readRegister(0xFF);
char tmpBuf[17];
sprintf(tmpBuf, “%02X:%02X:%02X:%02X:%02X:%02X”, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
Serial.println(tmpBuf);

// setup the Ethernet library to talk to the Wiznet board
Ethernet.begin(mac, ip); // Use static address defined above
//Ethernet.begin(mac); // Use DHCP

// Print IP address:
Serial.print(“My IP: “);
for (byte thisByte = 0; thisByte < 4; thisByte++) {
// print the value of each byte of the IP address:
Serial.print(Ethernet.localIP()[thisByte], DEC);
if( thisByte < 3 )
{
Serial.print(”.”);
}
}

/* Set up the Relay8 shields */
initialiseShield(SHIELD_1_I2C_ADDRESS);
sendRawValueToLatch1(0); // If we don’t do this, channel 6 turns on! I don’t know why

initialiseShield(SHIELD_2_I2C_ADDRESS);
sendRawValueToLatch2(0); // If we don’t do this, channel 6 turns on! I don’t know why

Serial.println(“Ready.”);
}

void connect() {
if (client.connect(“arduinoClient”, “openhabian”, “bedrock”)) {
Serial.println(“Connected”);
client.subscribe("/relay/power/1/#");
}
}

void loop()
{
if (!client.connected()) {
connect();
}

client.loop();
}

void publishState(int channel,int state,char* theTopic) {
sprintf(topic,theTopic,channel);
sprintf(message,"{channel:%1d,state:%1d}",channel,state);
client.publish(topic,message);
}

void initialiseShield(int shieldAddress)
{
// Set addressing style
Wire.beginTransmission(shieldAddress);
Wire.write(0x12);
Wire.write(0x20); // use table 1.4 addressing
Wire.endTransmission();

// Set I/O bank A to outputs
Wire.beginTransmission(shieldAddress);
Wire.write(0x00); // IODIRA register
Wire.write(0x00); // Set all of bank A to outputs
Wire.endTransmission();
}

/**
*/
void toggleLatchChannel(byte channelId)
{
if( channelId >= 1 && channelId <= 8 )
{
byte shieldOutput = channelId;
byte channelMask = 1 << (shieldOutput - 1);
shield1BankA = shield1BankA ^ channelMask;
sendRawValueToLatch1(shield1BankA);
}
else if( channelId >= 9 && channelId <= 16 )
{
byte shieldOutput = channelId - 8;
byte channelMask = 1 << (shieldOutput - 1);
shield2BankA = shield2BankA ^ channelMask;
sendRawValueToLatch2(shield2BankA);
}
}

/**
*/
void setLatchChannelOn (byte channelId)
{
if( channelInterlocks == true )
{
if ( (channelId % 2) == 0) // This is an even number channel, so turn off the channel before it
{
setLatchChannelOff( channelId - 1 );
} else { // This is an odd number channel, so turn off the channel after it
setLatchChannelOff( channelId + 1 );
}
}

if( channelId >= 1 && channelId <= 8 )
{
byte shieldOutput = channelId;
byte channelMask = 1 << (shieldOutput - 1);
shield1BankA = shield1BankA | channelMask;
sendRawValueToLatch1(shield1BankA);
}
else if( channelId >= 9 && channelId <= 16 )
{
byte shieldOutput = channelId - 8;
byte channelMask = 1 << (shieldOutput - 1);
shield2BankA = shield2BankA | channelMask;
sendRawValueToLatch2(shield2BankA);
}
}

/**
*/
void setLatchChannelOff (byte channelId)
{
if( channelId >= 1 && channelId <= 8 )
{
byte shieldOutput = channelId;
byte channelMask = 255 - ( 1 << (shieldOutput - 1));
shield1BankA = shield1BankA & channelMask;
sendRawValueToLatch1(shield1BankA);
}
else if( channelId >= 9 && channelId <= 16 )
{
byte shieldOutput = channelId - 8;
byte channelMask = 255 - ( 1 << (shieldOutput - 1));
shield2BankA = shield2BankA & channelMask;
sendRawValueToLatch2(shield2BankA);
}
}

/**
*/
void sendRawValueToLatch1(byte rawValue)
{
Wire.beginTransmission(SHIELD_1_I2C_ADDRESS);
Wire.write(0x12); // Select GPIOA
Wire.write(rawValue); // Send value to bank A
shield1BankA = rawValue;
Wire.endTransmission();
}

/**
*/
void sendRawValueToLatch2(byte rawValue)
{
Wire.beginTransmission(SHIELD_2_I2C_ADDRESS);
Wire.write(0x12); // Select GPIOA
Wire.write(rawValue); // Send value to bank A
shield2BankA = rawValue;
Wire.endTransmission();
}

/**

  • Required to read the MAC address ROM
    */
    byte readRegister(byte r)
    {
    unsigned char v;
    Wire.beginTransmission(MAC_I2C_ADDRESS);
    Wire.write®; // Register to read
    Wire.endTransmission();

Wire.requestFrom(MAC_I2C_ADDRESS, 1); // Read a byte
while(!Wire.available())
{
// Wait
}
v = Wire.read();
return v;
}

not all of it is mine so im trying to piece this together. i should be able to publish into /relay/power/1/01 ‘on’ or ‘off’ and that should trigger the relay. am i missing something here?

Thanks again for your help

well … and which part is working and which is not ? :slight_smile:
(also split topic as it is irelevant to your original question)