Hey there,
this is how to connect an ALLNET® ALL4176 6-way IP socket outlet to your OpenHAB (>= 2.3) server.
I’m using ALL4176 Software 3.35 (Patch 1088), Hardware 0.03
Architecture
Device has a password protected HTTP JSON interface, we will use that for interacting with the device.
Security precaution: HTTP is an unencrypted protocol, network sniffing in your network will allow an attacker to gain your credentials take over control over that device. Device supports HTTPS too, but that will require little more effort (e.g. to make SSL certificate known to Java) which will not be covered by this tutorial.
OpenHAB Prerequisites
OpenHAB: Version 2.3.0 or newer (could be adapted to older versions by not using Units Of Measurement in items definition)
Bindings: http1
Transformations: JavaScript, JsonPath
Setup IP Socket
For basic setup consult the manual. (I couldn’t find that online, conrad.de has a german one of quite similar ALL4076)
We need a fixed hostname / ipaddress, I will use <ipaddress>
in my examples.
In device HTTP Webinterface -> Configuration -> Servers and users -> User settings you need to add a new <user>
with <password>
that has type Remote Control
and rights View & Switch
Testing HTTP interface
Point your browser to http://<ipaddress>/xml/
and put in <user>
and <password>
you set up above, this will show a small help on how to use that interface:
XML Help
http://<ipaddress>/xml?mode=*&type=**&id=***&action=****
Parameter
=========
without: This help screen
*mode: possible values actor, sensor, info
**type: list/switch
***id: actor/sensor ID (optional)
****action: 0/1 (optional)
This is an XML based interface, I will use http://<ipaddress>/xml/json.php
and jsonswitch.php
which offers quite the same functionality, but is based on JSON.
OpenHAB Configuration
This is how to do it:
- Add a HTTP cache that gets queried for our device (reduces HTTP load on the device)
services/http.cfg
ALL4176_StatusCache.url=http://<ipaddress>/xml/json.php?mode=all{Authorization=Basic <base64-user:password>}
ALL4176_StatusCache.updateInterval=1000
The part <base64-user:password>
is a Base64 encoded string of »<user>:<password>
«, see http1 binding documentation for details
Side note: I use mode=all
here, which isn’t documented in above help but works anyways - otherwise I would have to set up two HTTP caches for mode=sensor
and mode=actor
which will double the HTTP load
- Add a JavaScript transformation for each socket - as passing parameters to JavaScript isn’t possible, you need to add one file for each socket:
transform/ALL4176switch_1.js
(function(dataString) {
var data = JSON.parse(dataString);
var value = 'UNDEF';
for (var i = 0; i < data.length; i++) {
if (data[i].id == '1') {
value = data[i].value;
break;
}
}
if (value != 'UNDEF') {
if (value == '0.00') {
value = 'OFF';
} else {
value = 'ON';
}
}
return value;
})(input)
Do this for socket 2 to 6 by replacing 1
in filename and '1'
in line 5 of the script by corresponding socket number.
- Add items
Now we can add our items:
items/ALL4176.items
Switch ALL4176_Relais1 "Relais 1" <poweroutlet> { http=">[ON:POST:http://<ipaddress>/xml/jsonswitch.php?id=1&set=1{Authorization=Basic <base64User:Password>}] >[OFF:POST:http://<ipaddress>/xml/jsonswitch.php?id=1&set=0{Authorization=Basic <base64User:Password>}]" }
Switch ALL4176_Relais1Status "Relais 1 [%s]" { http="<[ALL4176_StatusCache:1000:JS(ALL4176switch_1.js)]" }
Switch ALL4176_Relais2 "Relais 2" <poweroutlet> { http=">[ON:POST:http://<ipaddress>/xml/jsonswitch.php?id=2&set=1{Authorization=Basic <base64User:Password>}] >[OFF:POST:http://<ipaddress>/xml/jsonswitch.php?id=2&set=0{Authorization=Basic <base64User:Password>}]" }
Switch ALL4176_Relais2Status "Relais 2 [%s]" { http="<[ALL4176_StatusCache:1000:JS(ALL4176switch_2.js)]" }
Switch ALL4176_Relais3 "Relais 3" <poweroutlet> { http=">[ON:POST:http://<ipaddress>/xml/jsonswitch.php?id=3&set=1{Authorization=Basic <base64User:Password>}] >[OFF:POST:http://<ipaddress>/xml/jsonswitch.php?id=3&set=0{Authorization=Basic <base64User:Password>}]" }
Switch ALL4176_Relais3Status "Relais 3 [%s]" { http="<[ALL4176_StatusCache:1000:JS(ALL4176switch_3.js)]" }
Switch ALL4176_Relais4 "Relais 4" <poweroutlet> { http=">[ON:POST:http://<ipaddress>/xml/jsonswitch.php?id=4&set=1{Authorization=Basic <base64User:Password>}] >[OFF:POST:http://<ipaddress>/xml/jsonswitch.php?id=4&set=0{Authorization=Basic <base64User:Password>}]" }
Switch ALL4176_Relais4Status "Relais 4 [%s]" { http="<[ALL4176_StatusCache:1000:JS(ALL4176switch_4.js)]" }
Switch ALL4176_Relais5 "Relais 5" <poweroutlet> { http=">[ON:POST:http://<ipaddress>/xml/jsonswitch.php?id=5&set=1{Authorization=Basic <base64User:Password>}] >[OFF:POST:http://<ipaddress>/xml/jsonswitch.php?id=5&set=0{Authorization=Basic <base64User:Password>}]" }
Switch ALL4176_Relais5Status "Relais 5 [%s]" { http="<[ALL4176_StatusCache:1000:JS(ALL4176switch_5.js)]" }
Switch ALL4176_Relais6 "Relais 6" <poweroutlet> { http=">[ON:POST:http://<ipaddress>/xml/jsonswitch.php?id=6&set=1{Authorization=Basic <base64User:Password>}] >[OFF:POST:http://<ipaddress>/xml/jsonswitch.php?id=6&set=0{Authorization=Basic <base64User:Password>}]" }
Switch ALL4176_Relais6Status "Relais 6 [%s]" { http="<[ALL4176_StatusCache:1000:JS(ALL4176switch_6.js)]" }
Number:ElectricPotential ALL4176_Voltage "Voltage [%.2f V]" <line> { http="<[ALL4176_StatusCache:10000:JSONPATH($[?(@.id == '14')].value)]" }
Number:ElectricCurrent ALL4176_Current "Current [%.2f A]" <line> { http="<[ALL4176_StatusCache:10000:JSONPATH($[?(@.id == '15')].value)]" }
Number:Power ALL4176_Power "Power [%.2f W]" <line> { http="<[ALL4176_StatusCache:10000:JSONPATH($[?(@.id == '16')].value)]" }
Number:Frequency ALL4176_Frequency "Frequency [%.2f Hz]" <line> { http="<[ALL4176_StatusCache:10000:JSONPATH($[?(@.id == '18')].value)]" }
- Make a rule to keep hardware status in sync
Device has buttons on each socket to switch on/off a socket, so we need to keep track of that change in OpenHAB too. We do this with a rule, updating our items when status changes
rules/ALL4176_Sensors.rules
rule "Update ALL4176 Relais status from hardware"
when
Item ALL4176_Relais1Status changed or
Item ALL4176_Relais2Status changed or
Item ALL4176_Relais3Status changed or
Item ALL4176_Relais4Status changed or
Item ALL4176_Relais5Status changed or
Item ALL4176_Relais6Status changed
then
if(ALL4176_Relais1Status.state != ALL4176_Relais1.state) { ALL4176_Relais3.postUpdate(ALL4176_Relais1Status.state) }
if(ALL4176_Relais2Status.state != ALL4176_Relais2.state) { ALL4176_Relais4.postUpdate(ALL4176_Relais2Status.state) }
if(ALL4176_Relais3Status.state != ALL4176_Relais3.state) { ALL4176_Relais3.postUpdate(ALL4176_Relais3Status.state) }
if(ALL4176_Relais4Status.state != ALL4176_Relais4.state) { ALL4176_Relais4.postUpdate(ALL4176_Relais4Status.state) }
if(ALL4176_Relais5Status.state != ALL4176_Relais5.state) { ALL4176_Relais5.postUpdate(ALL4176_Relais5Status.state) }
if(ALL4176_Relais6Status.state != ALL4176_Relais6.state) { ALL4176_Relais6.postUpdate(ALL4176_Relais6Status.state) }
end
- Add items to your existing sitemap
Frame label="ALL4176 Relais" {
Switch item=ALL4176_Relais1
Switch item=ALL4176_Relais2
Switch item=ALL4176_Relais3
Switch item=ALL4176_Relais4
Switch item=ALL4176_Relais5
Switch item=ALL4176_Relais6
}
Frame label="ALL4176 Sensors" {
Text item=ALL4176_Voltage
Text item=ALL4176_Current
Text item=ALL4176_Power
Text item=ALL4176_Frequency
}
Frame label="ALL4176 Relais status (for debugging)" {
Text item=ALL4176_Relais1Status
Text item=ALL4176_Relais2Status
Text item=ALL4176_Relais3Status
Text item=ALL4176_Relais4Status
Text item=ALL4176_Relais5Status
Text item=ALL4176_Relais6Status
}
Volà, we are done.
Notes
This configuration will update status/sensors once a second, I found that to be enough.
Switch actions from OpenHAB will generate a HTTP request immediately.
Further work
Provided JSON string provides more sensors like cos ϕ, USB monitoring, connected sensors (sold seperately), … even the name of the sockets and their color configured in HTTP interface are available.
Add items as you need, just remember to refer to them by their ID as I did in above examples.
With mode=info
in URL you can get network configuration, MAC, uptime (as string), memory, … of the device, I didn’t have use for that.
Known Bugs
Measured power can sometimes be negative, I observed »-0.1 W«, so keep that in mind when you write rules based on that value.
Questions and suggestions for improvement are welcome!