State Controller ESP32
by Ben Jones
SKU: OXRS-SHA-STATECONTROLLER-ESP32-FW
Introduction
A binary state controller for DIY home automation projects.
Listens for MQTT messages and send on/off binary output signals using MCP23017 I2C I/O buffers.
Typically the output signals would be used to drive relay coils in order to switch larger voltages - e.g. light circuits.
How does it work?
Outputs can be switched by publishing an MQTT message to the configured MQTT broker.
Each output can be configured as a relay
, for simple on
/off
control. A motor
, again with on
/off
control but longer interlock delays if interlocking is configured. Or a timer
, for on
and then timed off
control.
The firmware is designed to run on hardware using MCP23017 I/O buffer chips via I2C, e.g. the 16 Channel Relay Driver.
A single I2C bus can only support up to a maximum of 8x MCP23017 chips (addresses 0x20-0x27
). Therefore the maximum number of supported outputs is 128 (i.e. 8x MCP23017s * 16x I/O pins).
Interlocking
Interlocking two outputs allows them to control equipment such as roller blinds, garage doors, louvre roofing etc.
However if you are planning to control a motor of any sort then it is important that the two outputs are configured as type motor
and that both are interlocked with each other. This is to ensure that both outputs will not be commanded to operate at the same time and adds a 2 second delay between any changes of output.
Example payload to configure outputs 4 & 5 to control a set of roller blinds;
{
"outputs": [
{ "index": 4, "type": "motor", "interlockIndex": 5 },
{ "index": 5, "type": "motor", "interlockIndex": 4 }
]
}
The operation of the interlocked outputs should be verified before connecting to any external equipment. External interlocking equipment may be required for some equipment. Most importantly, the manufacturers wiring and installation guides must be adhered to.
Timers
Timers allow an output to automatically turn off
a set number of seconds after being turned on
(configurable via timerSeconds
, which defaults to 60 seconds).
If another on
command is sent while the timer is running, it will reset to zero and begin counting down again. If an off
command is sent the timer will be cancelled and the output turned off
immediately.
Configuration
The firmware can be configured by publishing an MQTT message to this topic;
[PREFIX/]conf/CLIENTID[/SUFFIX]
where:
PREFIX
: Optional topic prefix if requiredCLIENTID
: Client id of device, defaults to<MACADDRESS>
SUFFIX
: Optional topic suffix if required
The message payload should be JSON and it's format is defined in a JSON schema document included in the adoption payload published here;
[PREFIX/]stat/CLIENTID[/SUFFIX]/adopt
See the config
value in the /adopt
payload.
MCP Config
This firmware is compatible with I/O boards with MCPs driving 8 or 16 output relays (see Supported Hardware links below). If you are using a board which is only driving 8 output relays you need to tell the firmware to ignore pins 9-16 on each MCP.
Key | Mandatory | Value |
---|---|---|
outputsPerMcp | Optional | Number of outputs connected to each MCP (either 8 or 16, defaults to 16) |
Your device MUST be restarted after any changes to this configuration, before it will take effect.
Examples
To configure for use with 8 Channel Relay Driver Shield;
{
"outputsPerMcp": 8
}
WARNING
This config should be set using the REST API and NOT a retained MQTT message. This config is used when initialising the device and is needed by the firmware before a connection to the MQTT broker is made. Setting this via the REST API will ensure it is persisted to SPIFFS and loaded early enough in the boot sequence.
TIP
You can set this config via the REST API using curl
(substitute your device IP address);
curl -X POST http://<DEVICE_IP>/config -H 'Content-Type: application/json' -d '{"outputsPerMcp":8}'
Default Output Type
By default all outputs are initialised as type relay
. Individual outputs can then be configured as required (see below). However it is also possible to change this default. For example, if you are intending to control roller blinds throughout your home, instead of setting individual config for each output, you can simply set the defaultOutputType
to motor
and be done with it.
Key | Mandatory | Value |
---|---|---|
defaultOutputType | Optional | Either motor , relay , or timer |
Examples
To configure the default output type to be motor
;
{
"defaultOutputType": "motor"
}
TIP
You can still override the default output type with specific configuration for individual outputs, see below.
Output Config
Each OUTPUT can be configured via the following properties;
Key | Mandatory | Value |
---|---|---|
index | Mandatory | Index of the output to configure |
type | Optional | Either motor , relay , or timer |
interlockIndex | Optional | Index to interlock with (lock the opposite for interlocking both ways or self-lock to disable interlocking) |
timerSeconds | Optional | Number of seconds an output stays on when type set to timer (defaults to 60 seconds) |
The only difference between motor
and relay
outputs is the interlock delay (if an interlock is configured).
Output Type | Interlock delay |
---|---|
motor | 2000ms |
relay | 500ms |
Examples
To configure output 4 to be a 30 second timer and outputs 6 & 7 to drive a motor and be interlocked;
{
"outputs": [
{ "index": 4, "type": "timer", "timerSeconds": 30 },
{ "index": 6, "type": "motor", "interlockIndex": 7 },
{ "index": 7, "type": "motor", "interlockIndex": 6 }
]
}
TIP
A retained message will ensure the device auto-configures on startup.
Commands
Each OUTPUT can be controlled by publishing an MQTT message to the topic;
[PREFIX/]cmnd/CLIENTID[/SUFFIX]
where;
PREFIX
: Optional topic prefix if requiredCLIENTID
: Client id of device, defaults to<MACADDRESS>
SUFFIX
: Optional topic suffix if required
The message payload should be JSON and it's format is defined in a JSON schema document included in the adoption payload published here;
[PREFIX/]stat/CLIENTID[/SUFFIX]/adopt
See the command
value in the /adopt
payload.
Key | Mandatory | Value |
---|---|---|
index | Mandatory | Index of the output to switched |
command | Mandatory | Either on , off , or query |
TIP
The query
command will cause an event to be published, with the current state of that output.
Examples
To turn on output 4 and query the state of output 7;
{
"outputs": [
{ "index": 4, "command": "on" },
{ "index": 7, "command": "query" }
]
}
Events
An output STATE CHANGE is reported to a topic of the form;
[PREFIX/]stat/CLIENTID[/SUFFIX]
where;
PREFIX
: Optional topic prefix if requiredCLIENTID
: Client id of device, defaults to<MACADDRESS>
SUFFIX
: Optional topic suffix if required
The message payload is JSON and contains:
Key | Value |
---|---|
index | Index of this event (1-128) |
type | Event type (see below) |
event | Event (see below) |
Event Type | Event |
---|---|
motor | on or off |
relay | on or off |
timer | on or off |
Examples
A relay turning on for output 6;
{
"index": 6,
"type": "relay",
"event": "on"
}
A timer turning off for output 12;
{
"index": 12,
"type": "timer",
"event": "off"
}
Downloads
Download the latest version of the firmware on Github.
Supported Hardware
This firmware is compatible with the boards;
- 8 Channel Relay Driver Shield by SuperHouse
- 128 Channel Relay Driver by Bedrock Media Designs
- 16 Channel Relay Driver by Bedrock Media Designs
And is designed to run on the RACK32 as part of the OXRS eco-system.
Credits
- Jonathan Oxer jon@oxer.com.au
- Ben Jones https://github.com/sumnerboy12
- Moin https://github.com/moinmoin-sh
License
Copyright 2020-present SuperHouse Automation Pty Ltd www.superhouse.tv
The software portion of this project is licensed under the Simplified BSD License. The "licence" folder within this project contains a copy of this license in plain text format.