Re: ELV Max! Heating control system
Posted: Tuesday 24 May 2016 0:18
I can't remember how I did it, but this might help -
http://www.domoticz.com/forum/viewtopic ... 638#p22638
http://www.domoticz.com/forum/viewtopic ... 638#p22638
Open source Home Automation System
https://forum.domoticz.com/
Code: Select all
pi@raspberrypi ~ $ lua max.lua
lua: max.lua:2: module 'basexx' not found:
no field package.preload['basexx']
no file '/usr/local/share/lua/5.2/basexx.lua'
no file '/usr/local/share/lua/5.2/basexx/init.lua'
no file '/usr/local/lib/lua/5.2/basexx.lua'
no file '/usr/local/lib/lua/5.2/basexx/init.lua'
no file './basexx.lua'
no file '/usr/share/lua/5.2/basexx.lua'
no file '/usr/share/lua/5.2/basexx/init.lua'
no file './basexx.lua'
no file '/usr/local/lib/lua/5.2/basexx.so'
no file '/usr/lib/arm-linux-gnueabihf/lua/5.2/basexx.so'
no file '/usr/lib/lua/5.2/basexx.so'
no file '/usr/local/lib/lua/5.2/loadall.so'
no file './basexx.so'
stack traceback:
[C]: in function 'require'
max.lua:2: in main chunk
[C]: in ?
pi@raspberrypi ~ $ Code: Select all
pi@raspberrypi ~ $ sudo cp /usr/local/share/lua/5.1/*.lua /usr/local/share/lua/5.2Code: Select all
pi@raspberrypi ~ $ lua test.lua
L=CxMOQwkSGAAYAAAADBIYAAkSGAQYAAAAnQwSF58JEhgEGAAAAJkLExCVCRIYABgAAAA=
Len=12 Adr=130E43 batt=0 bst=0 mode=1
Valve pos=0 Setpoint=12 Temp=0
pi@raspberrypi ~ $ Code: Select all
L=CxOGXgkSGAAnAAAADBNwhAkSGAEnAAAAyQsThi8JEhgAJwAAAAwJbJ4JEhgAJwAAAMwME3A1CRIYAScAAADMCw646AkSGAAnAAAA
Len=12 Adr=13865E batt=0 bst=0 mode=1
Valve pos=0 Setpoint=19.5 Temp=0
Code: Select all
package.loadlib("core.so", "*")
local socket = require "socket"
local basexx = require "basexx"
--MaxIP='172.16.176.26'
MaxIP='KEQ0817132' -- Your Cube's IP name
MaxPort=62910
function maxCmd_H(data)
-- print('H='..data)
end
function maxCmd_M(data)
print('M='..data)
end
function maxCmd_C(data)
-- print('C='..data)
end
function maxCmd_L(data)
print('L='..data)
pos = 1
dec = basexx.from_base64(data)
L_hex = basexx.to_hex(dec)
L_len = string.len(L_hex)
while (pos < L_len) do -- Extract the data for one device at a time
s = L_hex:sub(pos,(pos+1))
data_len = tonumber(s,16) + 1
hex = L_hex:sub(pos,pos+(data_len*2))
valve_adr = hex:sub(3,8)
valve_info = tonumber(hex:sub(13,14),16)
batt = bit32.extract(valve_info,7,1)
bst = bit32.extract(valve_info,3,1)
mode = bit32.extract(valve_info,0,2)
if (batt==0) then sbat="OK" else sbat="Low" end
if (mode==0) then smode="Auto" elseif (mode==1) then smode="Manual"
elseif (mode==2) then smode="Holiday" elseif (mode==3) then smode="Boost" end
print("Len="..data_len, "Adr="..valve_adr, "batt="..sbat, "mode="..smode, "bst="..bst)
if (data_len == 13) then -- WallMountedThermostat (dev_type 3)
s = hex:sub(17,18)
setpoint = tonumber(s,16) / 2
s = hex:sub(25,26)
temp = tonumber(s,16) / 10
print("Thermostat setpoint="..setpoint, "Temp="..temp)
elseif (data_len == 12) then -- HeatingThermostat (dev_type 1 or 2)
s = hex:sub(15,16)
valve_pos = tonumber(s,16)
s = hex:sub(17,18)
setpoint = tonumber(s,16) / 2
s = hex:sub(21,22)
temp = tonumber(s,16) / 10
print("Valve pos="..valve_pos, "Setpoint="..setpoint, "Temp="..temp)
end
pos = pos + (data_len*2)
end
end
local tcp = socket.connect(MaxIP, MaxPort)
if not tcp then
print("Socket connect failed for "..MaxIP..':'..MaxPort)
return
end
tcp:settimeout(2)
while true do
s, status, partial = tcp:receive()
if (status) then
print("TCP receive - "..status)
break
end
local line = (s or partial)
local cmd = line:sub(1,1)
local data = line:sub(3)
if (cmd == 'H') then
maxCmd_H(data)
elseif (cmd == 'M') then
maxCmd_M(data)
elseif (cmd == 'C') then
maxCmd_C(data)
elseif (cmd == 'L') then
maxCmd_L(data)
break
end
end
tcp:close()
Code: Select all
M=00,01,VgIDAQlCZWRyb29tLTEThl4CCVNpdHRpbmdSbQ646AMHS2l0Y2hlbhOGLwYDE3CETUVRMDg1NjQzNQpXYWxsU3RhdC0xAQEThl5NRVExNDY3NjQzCVJhZGlhdG9yMQEDCWyeS0VRMDQ5OTEwNwpXYWxsU3RhdC0xAgEOuOhMRVEwMDUyNjc5ClJhZGlhdG9yLTECAxNwNU1FUTA4NTY1MTYKV2FsbFN0YXQtMQMBE4YvTUVRMTQ2NzY5NQpSYWRpYXRvci0xAwE=
L=CxOGXgkSGAAnAAAADBNwhAkSGAEnAAAA0AsThi8JEhgAJwAAAAwJbJ4JEhgAJwAAAMoME3A1CRIYAScAAADKCw646AkSGAAnAAAA
Len=12 Adr=13865E batt=OK mode=Auto bst=1
Valve pos=0 Setpoint=19.5 Temp=0
Len=13 Adr=137084 batt=OK mode=Auto bst=1
Thermostat setpoint=19.5 Temp=20.8
Len=12 Adr=13862F batt=OK mode=Auto bst=1
Valve pos=0 Setpoint=19.5 Temp=0
Len=13 Adr=096C9E batt=OK mode=Auto bst=1
Thermostat setpoint=19.5 Temp=20.2
Len=13 Adr=137035 batt=OK mode=Auto bst=1
Thermostat setpoint=19.5 Temp=20.2
Len=12 Adr=0EB8E8 batt=OK mode=Auto bst=1
Valve pos=0 Setpoint=19.5 Temp=0Most welcome, but I'll be away for a fortnight, so no help for a while.Westcott wrote:Thanks for the data, BD.
Decoding the new M= data will take a little while, so remember to breathe occasionally, please!
Code: Select all
pi@raspberrypi ~ $ lua test.lua
M=00,01,VgICAQtLYW1lciBOaWVscxMOQwIMU3R1ZGVlcmthbWVyExCVBAMSF59NRVEwODUzNDQ2F1RoZXJtb3N0YWF0IGthbWVyIE5pZWxzAQETDkNNRVExNDQ0NzAzGVJhZGlhdG9ya3J
hYW4ga2FtZXIgTmllbHMBAxIYAE1FUTA4NTMzMzYYVGhlcm1vc3RhYXQgc3R1ZGVlcmthbWVyAgETEJVNRVExNDQzODY4GlJhZGlhdG9ya3JhYW4gc3R1ZGVlcmthbWVyAgE=
L=CxMOQwkSGAAYAAAADBIYAAkSGAQYAAAAmAwSF58JEhgEGAAAAJkLExCVCRIYABgAAAA=
Len=12 Adr=130E43 batt=OK mode=Auto bst=1
Valve pos=0 Setpoint=12 Temp=0
Len=13 Adr=121800 batt=OK mode=Auto bst=1
Thermostat setpoint=12 Temp=15.2
Len=13 Adr=12179F batt=OK mode=Auto bst=1
Thermostat setpoint=12 Temp=15.3
Len=12 Adr=131095 batt=OK mode=Auto Code: Select all
package.loadlib("core.so", "*")
local Socket = require "socket"
local Basexx = require "basexx"
--MaxIP='172.16.176.26'
local MaxIP = 'your IP name'
local MaxPort = 62910
local Rooms = {}
local Devices = {}
function maxCmd_H(data)
-- print('H='..data)
end
function maxCmd_M(data)
i = 0
j = 0
while true do -- find 'next' comma
i = string.find(data, ",", i+1)
if not i then break end
j = i
end
s = data:sub(j+1)
dec = Basexx.from_base64(s)
num_rooms = string.byte(dec,3)
pos=4
for i=1, num_rooms do
room_num = string.byte(dec, pos)
name_len = string.byte(dec, pos+1)
pos = pos+2
name = dec:sub(pos, pos+name_len)
pos = pos+name_len
adr = Basexx.to_hex(dec:sub(pos, pos+2))
Rooms[adr] = name
pos = pos+3
end
print("Rooms\n-----")
for adr, name in pairs(Rooms) do
print(name, adr)
end
num_devs = string.byte(dec, pos)
for i=1, num_devs do
dtype = string.byte(dec, pos+1)
adr = Basexx.to_hex(dec:sub(pos+2, pos+4))
snum = dec:sub(pos+5, pos+14)
name_len = string.byte(dec, pos+15)
pos = pos+16
name = dec:sub(pos, pos+name_len)
pos = pos+name_len
room_num = string.byte(dec, pos)
Devices[adr] = name
end
print("\nDevices\n-------")
for adr, name in pairs(Devices) do
print(name, adr)
end
end
function maxCmd_C(data)
-- print('C='..data)
end
function maxCmd_L(data)
print("\nDevice status\n-------------")
pos = 1
dec = Basexx.from_base64(data)
L_hex = Basexx.to_hex(dec)
L_len = string.len(L_hex)
while (pos < L_len) do
s = L_hex:sub(pos,(pos+1))
data_len = tonumber(s,16) + 1
hex = L_hex:sub(pos,pos+(data_len*2))
adr = hex:sub(3,8)
name = Devices[adr]
if not name then name=adr end
valve_info = tonumber(hex:sub(13,14),16)
batt = bit32.extract(valve_info,7,1)
bst = bit32.extract(valve_info,3,1)
mode = bit32.extract(valve_info,0,2)
if (batt==0) then sbat="OK" else sbat="Low" end
if (mode==0) then smode="Auto" elseif (mode==1) then smode="Manual"
elseif (mode==2) then smode="Holiday" elseif (mode==3) then smode="Boost" end
if (data_len == 13) then -- WallMountedThermostat (dev_type 3)
valve_pos = -1
s = hex:sub(17,18)
setpoint = tonumber(s,16) / 2
s = hex:sub(25,26)
temp = tonumber(s,16) / 10
dtype = "Thermostat"
elseif (data_len == 12) then -- HeatingThermostat (dev_type 1 or 2)
s = hex:sub(15,16)
valve_pos = tonumber(s,16)
s = hex:sub(17,18)
setpoint = tonumber(s,16) / 2
s = hex:sub(21,22)
temp = tonumber(s,16) / 10
dtype = "Valve "
end
print(dtype, name, "Setpoint="..setpoint, "Temp="..temp, "Valve pos="..valve_pos, "Battery="..sbat, "Mode="..smode)
pos = pos + (data_len*2)
end
end
local tcp = Socket.connect(MaxIP, MaxPort)
if not tcp then
print("Socket connect failed for "..MaxIP..':'..MaxPort)
return
end
tcp:settimeout(2)
while true do
s, status, partial = tcp:receive()
if (status) then
print("TCP receive - "..status)
break
end
local line = (s or partial)
local cmd = line:sub(1,1)
local data = line:sub(3)
if (cmd == 'H') then
maxCmd_H(data)
elseif (cmd == 'M') then
maxCmd_M(data)
elseif (cmd == 'C') then
maxCmd_C(data)
elseif (cmd == 'L') then
maxCmd_L(data)
break
end
end
tcp:close()
Code: Select all
pi@raspberrypi ~ $ lua test.lua
Rooms
-----
Studeerkamer 131095
Kamer Niels 130E43
Devices
-------
Thermostaat studeerkamer 121800
Thermostaat kamer Niels 12179F
Radiatorkraan studeerkamer 131095
Radiatorkraan kamer Niels 130E43
Device status
-------------
Valve Radiatorkraan kamer Niels Setpoint=12 Temp=0 Valve pos=0 Battery=OK Mode=Auto
Thermostat Thermostaat studeerkamer Setpoint=12 Temp=15.3 Valve pos=-1 Battery=OK Mode=Auto
Thermostat Thermostaat kamer Niels Setpoint=12 Temp=15.7 Valve pos=-1 Battery=OK Mode=Auto
Valve Radiatorkraan studeerkamer Setpoint=12 Temp=0 Valve pos=0 Battery=OK Mode=Auto
pi@raspberrypi ~ $I think I read somewhere that the valves DO send their actual temperatures, but only after they have received a new setpoint, and for a limited amount of time. Probably they go into a low power mode to save battery. I'll check if this is true when I have some time.Westcott wrote:Hi Mvzut,
Thanks for the kind words!
Valve position -1 means it does not have a valve, it is just for debug printing porpoises.
When I get my replacement Cube I can work on sending data TO valves.
Also need to discover why nobody else's valves send their actual temperatures. Mine does.
Possibly valve firmware versions?
Just checked, and I can confirm that the valves indeed only briefly report the actual temperature when they just received a new setpoint.Skippiemanz wrote:i thought that the valves only send there temp when the valves are in motion.
But maybe i'm wrong. I sure hope so