#OpenHab Modbus <abstract> In this article will be described the use of the [Eastron SDM120 Energy Meter](http://eastrongroupco.hk02.057321.com/productsview/42.html) as an example about interfacing an RS485 device to OpenHAB with the Modbus protocol. </abstract> ##Configuration Once the [Modbus binding](https://docs.openhab.org/addons/bindings/modbus1/readme.html) is installed, the usual three files are available . ###Service The default configuration of the SDM120 has not been modified. The details about the configuration and the registers exposed by the device are linked below. The system device used in this example is /dev/ttyUSB0, related to the most left RS485 socket on the board. /etc/openhab2/services/modbus.cfg <pre class="terminal"> #the serial object has been attached to the RS485 port through the /dev/ttyUSB0 device #the SDM120 default speed is 2400bps #the handshake is in RTU mode serial.Voltage.connection=/dev/ttyUSB0:2400:8:none:1:rtu:35:1500:none:none #this is an input device serial.Voltage.type=input #device ID = 1 serial.Voltage.id=1 #the starting register for the Voltage variable is 0 (device dependant) serial.Voltage.start=0 #the variable is two 16bit world lenght (4 byte) serial.Voltage.length=2 #it's a float32 variable serial.Voltage.valuetype=float32 #for each other variable it needs a similar configuration set serial.Current.connection=/dev/ttyUSB0:2400:8:none:1:rtu:35:1500:none:none serial.Current.type=input serial.Current.id=1 serial.Current.start=6 serial.Current.length=2 serial.Current.valuetype=float32 serial.Power.connection=/dev/ttyUSB0:2400:8:none:1:rtu:35:1500:none:none serial.Power.type=input serial.Power.id=1 serial.Power.start=12 serial.Power.length=2 serial.Power.valuetype=float32 serial.CosFi.connection=/dev/ttyUSB0:2400:8:none:1:rtu:35:1500:none:none serial.CosFi.type=input serial.CosFi.id=1 serial.CosFi.start=30 serial.CosFi.length=2 serial.CosFi.valuetype=float32 serial.Freq.connection=/dev/ttyUSB0:2400:8:none:1:rtu:35:1500:none:none serial.Freq.type=input serial.Freq.id=1 serial.Freq.start=70 serial.Freq.length=2 serial.Freq.valuetype=float32 serial.Ener.connection=/dev/ttyUSB0:2400:8:none:1:rtu:35:1500:none:none serial.Ener.type=input serial.Ener.id=1 serial.Ener.start=72 serial.Ener.length=2 serial.Ener.valuetype=float32 </pre> On this example we read the parameters for voltage, current, active power, power factor (CosFi), frequency and energy for the phase 1 from registers 0, 6, 12, 30, 70 e 72 . ###Item Now we can associate the items to these parameters, the key is the name of the objects created in modbus.cfg. The items related to the desired variables must be formatted for the printout similarly to the printf sintax. /etc/openhab2/items/modbus.items <pre class="terminal"> Number L1V "Tensione [%.1f V]" {modbus="Voltage:0"} Number L1A "Corrente [%.1f A]" {modbus="Current:0"} Number L1P "Potenza A [%.1f W]" {modbus="Power:0"} Number L1C "Cos Fi [%.2f]" {modbus="CosFi:0"} Number L1F "Frequenza [%.1f Hz]" {modbus="Freq:0"} Number L1E "Energia A [%.1f kWh]" {modbus="Ener:0"} </pre> ###Sitemap To show the values on the GUI, the variables must be associated to the sitemap. The association is possible through the name of the items. /etc/openhab2/sitemaps/your-site-name.sitemap <pre class="terminal"> sitemap knx label="GUIOTT home" { ... Frame label="Energia" { Text label="Energia" icon=pressure { Text item=L1V valuecolor=[>240="red",>230="orange",>220="green",<=220="orange"] Text item=L1A Text item=L1P valuecolor=[>3300="red",>3000="orange",>2500="green",<=2500="blue"] Text item=L1C valuecolor=[>0.8="green",<=0.8="orange"] Text item=L1F valuecolor=[<49="orange",>49="green",>51="orange"] Text item=L1E } } } </pre> Now the service starts polling the energy meter to collect data with the polling time configured on services.cfg file, updating the values on the page: Classic UI <img src="./ClassicUI" class="img-responsive center-block" width="40%"/> Basic UI <img src="./BasicUI" class="img-responsive center-block" width="40%"/> Or in the Habpanel <img src="./EnergyGraph" class="img-responsive center-block" width="40%"/> using knob widget as instruments, disabling interaction: <img src="./KnobConfig" class="img-responsive center-block" width="40%"/> you can also enable the measure range of the instrument, so the bar change its color depending on some alarm thresholds: <img src="./KnobRange" class="img-responsive center-block" width="40%"/> <a name="alarm"></a> The values collected can be used to obtain, for example, some audible or visible alarms as in the example below: /etc/openhab2/rules/modbus.rules <pre class="terminal"> var Cmd="python /etc/openhab2/scripts/led.py " var Timer set_timer = null rule "Led" when Time cron " 0/3 * * ? * * *" then var Power = (L1P.state as DecimalType).intValue if (Power <= 2500) { //val results = executeCommandLine(Cmd+"G",5000) //logInfo("Exec",results) sendCommand(LedG, OFF) sendCommand(LedB, ON) sendCommand(LedR, ON) set_timer = createTimer(now.plusSeconds(0.1)) [ sendCommand(LedG, ON) set_timer = null ] } else if (Power > 2500 && Power <= 3000) { //val results = executeCommandLine(Cmd+"B",5000) //logInfo("Exec",results) sendCommand(LedB, OFF) sendCommand(LedG, ON) sendCommand(LedR, ON) set_timer = createTimer(now.plusSeconds(0.1)) [ sendCommand(LedB, ON) set_timer = null ] } else if (Power > 3000) { //val results = executeCommandLine(Cmd+"R",5000) //logInfo("Exec",results) sendCommand(LedR, OFF) sendCommand(LedB, ON) sendCommand(LedG, ON) sendCommand(Rele1, ON) set_timer = createTimer(now.plusSeconds(0.1)) [ sendCommand(LedR, ON) set_timer = null ] set_timer = createTimer(now.plusSeconds(1)) [ sendCommand(Rele1, OFF) set_timer = null ] } end </pre> In this case the [CM3-Home RGB LED](https://www.acmesystems.it/CM3-HOME_rgbled) blinks with different colors when some electrical power thresholds have been exceeded. Furthermore one of the [two relays](https://www.acmesystems.it/CM3-HOME_relay) is used to switch a buzzer, alerting with more evidence that the contractual power threshold has been exceeded. [More details here](http://tanzolab.it/openhab_gpio_example). This is one of the most useful function I use often, hearing the beep I immediately switch off the appliance I'm using, avoiding to go dowstairs to reset the main breaker. In the picture below the buzzer connected: <img src="./CM3-HomeGuiottGPIO.jpg" class="img-responsive center-block" width="40%"/> The 3.3V power supply come from the 1-wire connector on the left and is switched by the normally open contact of the relay. ## Links * [Modbus binding](http://docs.openhab.org/addons/bindings/modbus1/readme.html) * [Eastron SDM120](http://eastrongroupco.hk02.057321.com/productsview/42.html) * [Flavio Anesi, esempi di utilizzo](http://www.flanesi.it/blog/2015/02/13/contatore-eastron-sdm120c-modbus-per-monitoraggio-energetico/) * [Brochure SDM120](./SDM120C.pdf) * [HTTP interface to SDM120](https://github.com/gonium/gosdm630) * [Simply Modbus, librerie Modbus](http://www.simplymodbus.ca/) * [Configuration example](https://community.openhab.org/t/modbus-energy-meter-reading-float-registers/14051/20) * [SDM120 data, exposed registers and protocol](http://www.flanesi.it/blog/download/sdm120c/SDM120-Modbus_protocol_V2.1.pdf?dl=0) @include='bio_guido_ottaviani' @include='bio_massimiliano_casini' @include='bio_salvatore_imparato'
2018 Ⓒ TanzoLab