-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
SimpleBinary Binding
This binding for openHAB has ability to connect DIY devices (based on Arduino or whatever else). Binding uses serial communication or network communication over implemented TCP server.
Used protocol is easy to implement. Implementation examples for Arduino(serial), STM8, ESP8266(TCP) is part of repository. Arduino IDE library is also available.
Compiled binding is in release branch of my repository: https://github.com/docbender/openHAB-SimpleBinary/releases
Binding is working with openHAB 1.8 as well as with openHAB2 in 1.x compatibility mode.
It is possible to configure several ports not only one. At one line it is possible to connect several devices (ready for RS422/RS485).
Binding sets the serial port speed according to user configuration. Other parameters are set as follows: 8 data bits, 1 stop bit, without parity and without flow control.
Flow control (especially for RS-485 converters) can be provided through RTS pin. This can be turned on by adding forceRTS parameter in binding port configuration. If it is required inverted function of RTS pin, forceRTSInv parameter should be added in configuration instead forceRTS.
Communication can operate in 2 data read modes - OnScan and OnChange.
At binding startup TCP server start listening on user defined port. In basic 256 clients are supported. Every connected client gets actual items states after device ID verification.
Known limitations: keep-alive missing, client ID must be explicitly specified -> max.256 clients(protocol limitation).
Communication can operate it 2 modes reading data from connected devices - OnScan and OnChange. In OnScan mode all data are reading cyclically. In OnChange mode only new data are sent to openHAB. Each device is polled whether has new data and then sends new data to openHAB. One of his modes must be choose in serial port connection. TCP server connection not use any of these modes as default. Because TCP connection is full-duplex, spontaneous states send is preferred and expected.
Binding support openHAB data types listed in the table. Individual item types are converted to simple data types such as byte, word, double word, float, array, rgb. For same types may be converted type defined, others has it strictly defined. Supported data types
Item type | Supported data type | Notes |
Number | byte, word, dword, float | Numbers are represented in signed form. Their maximum value depends on the used type. Floating point number is represented by float type. Float is stored in 4 bytes formatted according to IEEE 754. |
Color | hsb, rgb, rgbw | All color parts are transferred in one double word. Each color component corresponds to one byte. Assignment of bytes depending on the chosen data type is following: HSB - byte 0 - Hue, 1 - Saturation , 2 - Brightness, 3 - Not used RGB - byte 0 - Red, 1 - Green, 2 - Blue, 3 - Not used RGBW - byte 0 - Red, 1 - Green, 2 - Blue, 3 - White |
String | array | Array of bytes. Length of array is specified in square brackets behind type definition (e.g. array[32] defines byte array with length 32 bytes) |
Contact | byte | 0 - off, 1 - on |
Switch | byte | 0 - off, 1 - on |
Dimmer | byte | |
Rollershutter | word | Lower byte for position, upper byte for StopMove/UpDown command - 1-Move,2-Stop,4-Up,8-Down |
In openhab.cfg is binding configured this way:
################################### SimpleBinary Binding ######################################
#
# Select port (ex.: COM1:115200;onscan;forceRTSInv or /dev/ttyUSB1:9600). It is possible defined
# more ports ex. port1, port2,port145,... Behind semicolon you can specify data pool control (optional).
# Options for reach slave data are onchange(ask configured devices for new data - default)
# or onscan(read all data every scan). Option forceRTS or forceRTSInv are for trigger RTS signal
# during data send (useful for RS485 converter).
# TCP server is defined by tcpserver key. As value server port must be defined.
#
# serial port configuration
simplebinary:port=COM4:9600;onchange
# TCP server configuration
simplebinary:tcpserver=43243
#refresh - check for new data interval - default 10000ms
simplebinary:refresh=2000
Configuration parameter | Description |
port | Serial port definition. Configuration value consist from port name and bitrate (COM1:9600, /dev/ttyS2:57600). Behind semicolon optional parameters can be specified. Pool control (onchange, onscan) Enable RTS signal handling (forceRTS or forceRTSInv for signal inversion) Multiple port can be specified. Must be deviate by number behind key (ex.: port, port1, port123,...) |
tcpserver | TCP server definition. As value listening port must be specified. |
refresh | Execution period [ms] between reading cycles. Default 10000ms. |
Binding specify item configuration is located as usual in the brackets at the end of the configuration line. It consists of three compulsory and two optional parameters.
Configuration format:
simplebinary="port name:device address:item address:[used data type]:[direction]"
Configuration parameter | Description |
port name | Port name that is specified in binding configuration in openhab.cfg. For simplebinary:port= port name is port. For simplebinary:port1= port name is port1. For simplebinary:tcpserver= port name is tcpserver. |
device address | The device address is number that device is indicated on the bus (for RS485 and ethernet) |
item address | It is the address under which the data is stored in the target device. |
used data type | Optional. Allow define data type. See table Supported data types |
direction | Optional. Can be I - input, O - output or IO - both (default). It is used only for request data from connected devices. So if all device items are outputs only, there would be no requesting for data from device. It is also good to define data direction for inter-device communication items. |
Example of binding configuration:
Dimmer Item01 "Value[%d]" { simplebinary="port:1:1" }
Number Item02 "Value[%d]" { simplebinary="port:1:3:dword:IO" }
Number Item03 "Value[%f]" { simplebinary="port:1:4:float:O" }
Number Item04 "Value[%f]" { simplebinary="port:1:14:float:I" }
String Item05 "Value[%s]" { simplebinary="port:2:1:array[32]:O" }
Color TestColor01 { simplebinary="tcpserver:2:2:rgb:O" }
Binding support inter-device communication. To configure this another device/binding can be specified separated by comma in item configuration. In examples values from first device are written into openHAB (input-I direction) and same value is immediately written into second device (output-O direction):
Number Temperature "Value[%f]" { simplebinary="port:1:1:float:I", simplebinary="tcpserver:1:1:float:O" }
Number TemperatureCPU "Value[%f]" { exec="<[/bin/cat /sys/class/thermal/thermal_zone0/temp:30000:JS(divideTemp.js)]", simplebinary="tcpserver:1:2:float:O" }
Binding itself offers some diagnostic states. There are available statuses for communication port itself and also statuses for connected devices. These statuses can be provided into openHAB if they are properly configured (by use configuration parameter info behind port name or device address).
Port diagnostic info configuration format:
simplebinary="port name:info:port status"
Port statuses:
Status | Description | Returned values |
state | Return current port status. | 0 - Unknown 1 - Listening (opened and ready) 2 - Closed 3 - Not exist 4 - Not available (probably used) |
previous_state | Return previous port status | Same as state |
state_change_time | Return time when status was changed | DateTime value |
Device diagnostic info configuration format:
simplebinary="port name:device address:info:device status"
Device statuses:
Status | Description | Returned values |
state | Return current device status. | 0 - Unknown 1 - Connected and answering 2 - Not responding / disconnected 3 - Response error (device still wants repeat query - received message had bad CRC) 4 - Data error (device report unknown item address, unknown data, unsupported message or error while saving delivered data) |
previous_state | Return previous device status | Same as state |
state_change_time | Return time when status was changed | DateTime value |
packet_lost | Return percentage of packet lost (not delivered, bad CRC, ...) within last 5 minutes | 0-100% |
Example of diagnostic item configuration:
Number PortState "Port state [%s]" { simplebinary="port:info:state" }
Number PortPreviouState "Port previous state [%s]" { simplebinary="port:info:previous_state" }
DateTime PortStateChangeTime "Port changed [%1$tA, %1$td.%1$tm.%1$tY %1$tT]" { simplebinary="port:info:state_change_time" }
Number Dev01State "Device 1 state [%s]" { simplebinary="port:1:info:state" }
Number Dev01PreviouState "Device 1 previous state [%s]" { simplebinary="port:1:info:previous_state" }
DateTime Dev01StateChangeTime "Device 1 changed [%1$tA, %1$td.%1$tm.%1$tY %1$tT]" { simplebinary="port:1:info:state_change_time" }
Number Dev01PacketLost "Device 1 packet lost rate [%s]" { simplebinary="port:1:info:packet_lost" }
Number Dev02State "Device 2 state [%s]" { simplebinary="port:2:info:state" }
Number Dev02PreviouState "Device 2 previous state [%s]" { simplebinary="port:2:info:previous_state" }
DateTime Dev02StateChangeTime "Device 2 changed [%1$tA, %1$td.%1$tm.%1$tY %1$tT]" { simplebinary="port:2:info:state_change_time" }
Number Dev02PacketLost "Device 2 packet lost rate [%s]" { simplebinary="port:2:info:packet_lost" }
Binding implements master/slave communication model for serial communication. OpenHAB binding is master and connected devices are slaves. Master sends command and waits for response from slave. Answer should arrived in order tens of milliseconds. However bindings has 2000ms timeout to receive answer. Communication protocol itself depends on requested operating mode of the device (OnScan / OnChange). Of course device can support both operating modes.
Network TCP connection use same protocol as serial communication but in producer/consumer communication model. When client is connected, "Hi" message must be send. Then server can verify and register device ID.
Every packet start with device address and is followed by message type. Minimum packet length is 4 bytes. Packets are secured with CRC8 which should be enough for short packets.
###Master query for new data - OnChange mode On this packet master expecting as answer "data" packet or "no data" packet (message type 0xE2).
Byte | Value | Description |
0 | 0xXX | Device slave address |
1 | 0xD0 | Message type |
2 | 0xXX | Control byte. Supported values: 0 - standard (data check only) 1 - force all data request |
3 | CRC8 |
###Master query for data with specified address - OnScan mode On this packet master expecting as answer "data" packet or "invalid address" packet (message type 0xE4).
Byte | Value | Description |
0 | 0xXX | Device slave address |
1 | 0xD1 | Message type |
2 | 0xXX | Data address - low byte |
3 | 0xXX | Data address - high byte |
4 | CRC8 |
###Data packet for data type byte This "data" packet could be send by master to write data into slave or by slave as answer for data request. Answer from slave should "done" when everything was right.
Byte | Value | Description |
0 | 0xXX | Device slave address |
1 | 0xDA | Message type |
2 | 0xXX | Data address - low byte |
3 | 0xXX | Data address - high byte |
4 | 0xXX | Data |
5 | CRC8 |
###Data packet for data type word This "data" packet could be send by master to write data into slave or by slave as answer for data request. Answer from slave should "done" when everything was right.
Byte | Value | Description |
0 | 0xXX | Device slave address |
1 | 0xDB | Message type |
2 | 0xXX | Data address - low byte |
3 | 0xXX | Data address - high byte |
4 | 0xXX | Data - low byte |
5 | 0xXX | Data - high byte |
6 | CRC8 |
###Data packet for data type dword This "data" packet could be send by master to write data into slave or by slave as answer for data request. Answer from slave should "done" when everything was right.
Byte | Value | Description |
0 | 0xXX | Device slave address |
1 | 0xDC | Message type |
2 | 0xXX | Data address - low byte |
3 | 0xXX | Data address - high byte |
4 | 0xXX | Data - 1. byte (lowest) |
5 | 0xXX | Data - 2. byte |
6 | 0xXX | Data - 3. byte |
7 | 0xXX | Data - 4. byte (highest) |
8 | CRC8 |
###Data packet for type HSB, RGB, RGBW This "data" packet could be send by master to write data into slave or by slave as answer for data request. Answer from slave should "done" when everything was right.
Byte | Value | Description |
0 | 0xXX | Device slave address |
1 | 0xDD | Message type |
2 | 0xXX | Data address - low byte |
3 | 0xXX | Data address - high byte |
4 | 0xXX | Data - 1. byte (lowest) |
5 | 0xXX | Data - 2. byte |
6 | 0xXX | Data - 3. byte |
7 | 0xXX | Data - 4. byte (highest) |
8 | CRC8 |
###Data packet for type array This "data" packet could be send by master to write data into slave or by slave as answer for data request. Answer from slave should "done" when everything was right.
Byte | Value | Description |
0 | 0xXX | Device slave address |
1 | 0xDE | Message type |
2 | 0xXX | Data address - low byte |
3 | 0xXX | Data address - high byte |
4 | 0xXX | Data length - low byte |
5 | 0xXX | Data length - high byte |
6 | 0xXX | Data |
... | 0xXX | Data |
n-1 | CRC8 |
###Acknowledge packet - Done Answer from slave that data write from master was accepted.
Byte | Value | Description |
0 | 0xXX | Device slave address |
1 | 0xE0 | Message type |
2 | 0x00 | |
3 | CRC8 |
###Error packet - Repeat Answer that received packet had wrong CRC. On this packet master react by sending last packet again (max. 3 time).
Byte | Value | Description |
0 | 0xXX | Device slave address |
1 | 0xE1 | Message type |
2 | 0xXX | Here is expected CRC8 calculated by slave (master logged it for comparison). |
3 | CRC8 |
###Acknowledge packet - No new data Slave react with this packet on query for new data in OnChange mode in case that there's no data to send.
Byte | Value | Description |
0 | 0xXX | Device slave address |
1 | 0xE2 | Message type |
2 | 0x00 | |
3 | CRC8 |
###Error packet - Unknown data Slave react with this packet if received message had unknown/unsupported type.
Byte | Value | Description |
0 | 0xXX | Device slave address |
1 | 0xE3 | Message type |
2 | 0x00 | |
3 | CRC8 |
###Error packet - Unknown address Slave react with this packet if received message had unknown data item address.
Byte | Value | Description |
0 | 0xXX | Device slave address |
1 | 0xE4 | Message type |
2 | 0x00 | |
3 | CRC8 |
###Error packet - Error while saving data Slave send this packet when he could not save received data from master.
Byte | Value | Description |
0 | 0xXX | Device slave address |
1 | 0xE5 | Message type |
2 | 0x00 | |
3 | CRC8 |
###Hi packet This packet is for connection model producer/consumer (TCP client/server connection). Client sends this packet after he is connected to server.
Byte | Value | Description |
0 | 0xXX | Device address |
1 | 0xE6 | Message type |
2 | 0x00 | |
3 | CRC8 |
##Implementation The extent of implementation depends on the required features and data types (see chapter Protocol).
At first device should check if message is correctly received (CRC check). Secondly device should check if message is for him by compare message address and his own assigned address. If the address is different device must not respond! Otherwise device must response in corresponding way (see chapter Protocol).
##Implementation example Implementation example for Arduino can be found in Arduino library repo folder.
It consists of two main classes. Class simpleBinary which contains protocol implementation itself and class itemData which provides item data storage and handling with item.
Class simpleBinary - public methods
simpleBinary(int uartAddress, int size) Constructor. Parameters: uartAddress - device address at communication line, size - number of exchanged items |
|
void |
initItem(int indexAndAddress, itemType type, void (*pFce)(itemData*)) Initilize item. Parameters: indexAndAddress - item index in configuration array and also item address used during communication, type - item data type, last parameter is pointer to function that is executed on data receive(NULL for no action). |
void |
processSerial() Process data received by UART. |
bool |
checkAddress(int address) Check if address exist in items array. Parameters: address - item address used during communication |
void |
readData(int address) Read data on given address and send it to master. Parameters: address - item address used during communication |
bool |
saveByte(int address, char* data) Save byte from given data pointer to addresed item. Return false if target is not expected data type. Parameters: address - item address used during communication, data - pointer to data to save. |
bool |
saveWord(int address, char* data) Save word from given data pointer to addresed item. Return false if target is not expected data type. Parameters: address - item address used during communication, data - pointer to data to save. |
bool |
saveDword(int address, char* data) Save double word from given data pointer to addresed item. Return false if target is not expected data type. Parameters: address - item address used during communication, data - pointer to data to save. |
bool |
saveArray(int address, char *pData, int len) Save byte array from given data pointer to addresed item. Return false if target is not expected data type. Parameters: address - item address used during communication, pData - pointer to data to save, len - array length (byte count) |
int |
size() Return items count. |
void |
enableRTS(int pinNumber) Enable RTS handling. RTS pin is passed as parameter. |
void |
setSendDelay(unsigned int delayms) Sets delay between receive and transmit message (in ms). Good for communication line stabilization. |
Class itemData - public methods
itemData() Constructor. |
|
itemData(int address, itemType type, void (*pFce)(itemData*) ) Constructor with item initialization . Parameters: address - item address used during communication, type - item data type, last parameter is pointer to function that is executed on data receive(NULL for no action). |
|
itemData(int address, itemType type, int size, void (*pFce)(itemData*) ) Constructor with item initialization for arrays. Parameters: address - item address used during communication, type - item data type, size - data size in bytes, last parameter is pointer to function that is executed on data receive(NULL for no action). |
|
void |
init(int address, itemType type, void (*pFce)(itemData*)) Item initialization . Parameters: address - item address used during communication, type - item data type, last parameter is pointer to function that is executed on data receive(NULL for no action). |
bool |
saveByte(char* data) Save byte from given data pointer. Return false if target is not expected data type. Parameters: data - pointer to data to save. |
bool |
saveWord(char* data) Save word from given data pointer. Return false if target is not expected data type. Parameters: data - pointer to data to save. |
bool |
saveDword(char* data) Save double word from given data pointer. Return false if target is not expected data type. Parameters: data - pointer to data to save/td> |
bool |
saveArray(char *pData, int len) Save array from given data pointer. Return false if target is not expected data type. Parameters: data - pointer to data to save, len - array length (byte count) |
void |
save(int value) Save int value. Parameters: value - value to save |
void |
save(float value) Save float value. Parameters: value - value to save |
int |
getAddress() Return item address. |
void |
setNewData() Set item "new data" flag. |
bool |
hasNewData() Check if item has "new data" flag set. |
char* |
getData() Return item data. |
char* |
readNewData() Return item data and reset "new data" flag. |
itemType |
getType() Return item data type. |
int |
getDataLength() Return length of data. |
void |
executeAction() Execute action connected at item initialization. |
###CRC8 calculation implementation
char CRC8::evalCRC(char *data, int length)
{
int crc = 0;
int i, j;
for(j=0; j < length; j++)
{
crc ^= (data[j] << 8);
for(i=0;i<8;i++)
{
if((crc & 0x8000) != 0)
crc ^= (0x1070 << 3);
crc <<= 1;
}
}
return (char)(crc >> 8);
}
ℹ Please find all documentation for openHAB 2 under http://docs.openhab.org.
The wiki pages here contain (outdated) documentation for the older openHAB 1.x version. Please be aware that a lot of core details changed with openHAB 2.0 and this wiki as well as all tutorials found for openHAB 1.x might be misleading. Check http://docs.openhab.org for more details and consult the community forum for all remaining questions.
- Classic UI
- iOS Client
- Android Client
- Windows Phone Client
- GreenT UI
- CometVisu
- Kodi
- Chrome Extension
- Alfred Workflow
- Cosm Persistence
- db4o Persistence
- Amazon DynamoDB Persistence
- Exec Persistence
- Google Calendar Presence Simulator
- InfluxDB Persistence
- JDBC Persistence
- JPA Persistence
- Logging Persistence
- mapdb Persistence
- MongoDB Persistence
- MQTT Persistence
- my.openHAB Persistence
- MySQL Persistence
- rrd4j Persistence
- Sen.Se Persistence
- SiteWhere Persistence
- AKM868 Binding
- AlarmDecoder Binding
- Anel Binding
- Arduino SmartHome Souliss Binding
- Asterisk Binding
- Astro Binding
- Autelis Pool Control Binding
- BenQ Projector Binding
- Bluetooth Binding
- Bticino Binding
- CalDAV Binding
- Chamberlain MyQ Binding
- Comfo Air Binding
- Config Admin Binding
- CUL Transport
- CUL Intertechno Binding
- CUPS Binding
- DAIKIN Binding
- Davis Binding
- DD-WRT Binding
- Denon Binding
- digitalSTROM Binding
- DIY on XBee Binding
- DMX512 Binding
- DSC Alarm Binding
- DSMR Binding
- eBUS Binding
- Ecobee Binding
- EDS OWSever Binding
- eKey Binding
- Energenie Binding
- EnOcean Binding
- Enphase Energy Binding
- Epson Projector Binding
- Exec Binding
- Expire Binding
- Fatek PLC Binding
- Freebox Binding
- Freeswitch Binding
- Frontier Silicon Radio Binding
- Fritz AHA Binding
- Fritz!Box Binding
- FritzBox-TR064-Binding
- FS20 Binding
- Garadget Binding
- Global Caché IR Binding
- GPIO Binding
- HAI/Leviton OmniLink Binding
- HDAnywhere Binding
- Heatmiser Binding
- Homematic / Homegear Binding
- Horizon Mediabox Binding
- HTTP Binding
- IEC 62056-21 Binding
- IHC / ELKO Binding
- ImperiHome Binding
- Insteon Hub Binding
- Insteon PLM Binding
- IPX800 Binding
- IRtrans Binding
- jointSPACE-Binding
- KM200 Binding
- KNX Binding
- Koubachi Binding
- LCN Binding
- LightwaveRF Binding
- Leviton/HAI Omnilink Binding
- Lg TV Binding
- Logitech Harmony Hub
- MailControl Binding
- MAX!Cube-Binding
- MAX! CUL Binding
- MCP23017 I/O Expander Binding
- MCP3424 ADC Binding
- MiLight Binding
- MiOS Binding
- Mochad X10 Binding
- Modbus Binding
- MPD Binding
- MQTT Binding
- MQTTitude binding
- MystromEcoPower Binding
- Neohub Binding
- Nest Binding
- Netatmo Binding
- Network Health Binding
- Network UPS Tools Binding
- Nibe Heatpump Binding
- Nikobus Binding
- Novelan/Luxtronic Heatpump Binding
- NTP Binding
- One-Wire Binding
- Onkyo AV Receiver Binding
- Open Energy Monitor Binding
- OpenPaths presence detection binding
- OpenSprinkler Binding
- OSGi Configuration Admin Binding
- Panasonic TV Binding
- panStamp Binding
- Philips Hue Binding
- Picnet Binding
- Piface Binding
- PiXtend Binding
- pilight Binding
- Pioneer-AVR-Binding
- Plex Binding
- Plugwise Binding
- PLCBus Binding
- PowerDog Local API Binding
- Powermax alarm Binding
- Primare Binding
- Pulseaudio Binding
- Raspberry Pi RC Switch Binding
- RFXCOM Binding
- RWE Smarthome Binding
- Sager WeatherCaster Binding
- Samsung AC Binding
- Samsung TV Binding
- Serial Binding
- Sallegra Binding
- Satel Alarm Binding
- Siemens Logo! Binding
- SimpleBinary Binding
- Sinthesi Sapp Binding
- Smarthomatic Binding
- Snmp Binding
- Somfy URTSI II Binding
- Sonance Binding
- Sonos Binding
- Souliss Binding
- Squeezebox Binding
- Stiebel Eltron Heatpump
- Swegon ventilation Binding
- System Info Binding
- TA CMI Binding
- TCP/UDP Binding
- Tellstick Binding
- TinkerForge Binding
- Tivo Binding
- UCProjects.eu Relay Board Binding
- UPB Binding
- VDR Binding
- Velleman-K8055-Binding
- Wago Binding
- Wake-on-LAN Binding
- Waterkotte EcoTouch Heatpump Binding
- Weather Binding
- Wemo Binding
- Withings Binding
- XBMC Binding
- xPL Binding
- Yamahareceiver Binding
- Zibase Binding
- Z-Wave Binding
- Asterisk
- DoorBird
- FIND
- Foscam IP Cameras
- LG Hombot
- Worx Landroid
- Heatmiser PRT Thermostat
- Google Calendar
- Linux Media Players
- Osram Lightify
- Rainforest EAGLE Energy Access Gateway
- Roku Integration
- ROS Robot Operating System
- Slack
- Telldus Tellstick
- Zoneminder
- Wink Hub (rooted)
- Wink Monitoring
- openHAB Cloud Connector
- Google Calendar Scheduler
- Transformations
- XSLT
- JSON
- REST-API
- Security
- Service Discovery
- Voice Control
- BritishGasHive-Using-Ruby
- Dropbox Bundle
A good source of inspiration and tips from users gathered over the years. Be aware that things may have changed since they were written and some examples might not work correctly.
Please update the wiki if you do come across any out of date information.
- Rollershutter Bindings
- Squeezebox
- WAC Binding
- WebSolarLog
- Alarm Clock
- Convert Fahrenheit to Celsius
- The mother of all lighting rules
- Reusable Rules via Functions
- Combining different Items
- Items, Rules and more Examples of a SmartHome
- Google Map
- Controlling openHAB with Android
- Usecase examples
- B-Control Manager
- Spell checking for foreign languages
- Flic via Tasker
- Chromecast via castnow
- Speedtest.net integration