Page 16 of 37
Re: ELV Max! Heating control system
Posted: Wednesday 02 November 2016 8:46
by blackdog65
@Westcott
Thanks for jumping in here (and big thanks for your earlier work) as I'm out of my depth wth coding.
Do you have any clues about the
Code: Select all
attempt to concatenate field '?' (a nil value)
problem?
Sean
Re: ELV Max! Heating control system
Posted: Wednesday 02 November 2016 10:44
by Westcott
Hi Sean,
If I can see the offending Lua, I'll suggest a mod.
Re: ELV Max! Heating control system
Posted: Wednesday 02 November 2016 10:48
by Skippiemanz
Westcott wrote:Hi Skippiemanz,
Con you post the Lua file that You use, please?
I'll mod it for you.
Thanks for the help!
Here is the script(Copy past from WiKi, with adapted IP and Wll thermostat to False)
Code: Select all
--./script_time_max.lua
----------------------------------------------------------------------------------------------------------
-- Script parameters
----------------------------------------------------------------------------------------------------------
package.loadlib("core.so", "*")
local Socket = require "socket"
local Basexx = require "basexx"
local Rooms = {}
local Devices = {}
local Room_nums = {}
local MaxIP = "192.168.2.123"
local MaxPort = 62910
local useWMT = false --# Set to true if there is a wall mounted thermostat in every room, then this one will be used for setpoint getting/setting
Debug = "YES" --# Turn debugging on ("YES") or off ("NO")
----------------------------------------------------------------------------------------------------------
-- Script functions
----------------------------------------------------------------------------------------------------------
function age(timestring)
t = {}
t.year = string.sub(timestring,1,4)
t.month = string.sub(timestring,6,7)
t.day = string.sub(timestring,9,10)
t.hour = string.sub(timestring,12,13)
t.min = string.sub(timestring,15,16)
t.sec = string.sub(timestring,18,19)
return os.difftime(os.time(),os.time(t))
end
function maxCmd_H(data)
--if Debug=="YES" then print('H='..data) end
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-1)
pos = pos+name_len
adr = Basexx.to_hex(dec:sub(pos, pos+2))
Rooms[room_num] = name
pos = pos+3
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-1)
pos = pos+name_len
room_num = string.byte(dec, pos)
Room_nums[adr] = room_num
Devices[adr] = name
end
end
function maxCmd_C(data)
--if Debug=="YES" then print('C='..data) end
end
function maxCmd_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
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)
room_num = string.format("%02X", Room_nums[adr])
room = Rooms[Room_nums[adr]]
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(23,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
if (mode ~= 2) then
s = hex:sub(19,22)
temp = tonumber(s,16) / 10
else
temp = 0
end
dtype = "Valve"
end
--Temperaturdevices den Status aktualisieren
if temp ~= 0 and dtype == "Valve" then
table.insert(commandArray, { ['UpdateDevice'] = otherdevices_idx[name.." (Valve)"]..'|0|'..temp..';'..valve_pos..';0'})
elseif temp ~= 0 and dtype == "Thermostat" then
table.insert(commandArray, { ['UpdateDevice'] = otherdevices_idx[room]..'|0|'..temp})
end
if smode=="Manual" then
--Update virtual devices in Domoticz and update MAX! setpoints if necessary
if Debug=="YES" then print(dtype.." "..name.." Setpoint="..setpoint.." Temp="..temp.." Valve pos="..valve_pos) end
if dtype == "Valve" then
--table.insert(commandArray, { ['UpdateDevice'] = otherdevices_idx[name.." (Valve)"]..'|0|'..temp..';'..valve_pos..';0'})
if not useWMT and tonumber(otherdevices_svalues[name])~=nil then --Use valve to check setpoint mismatch
setpoint_Domoticz = tonumber(otherdevices_svalues[name])
---if name ~= "EcoTaster" and name ~= "Switch-SZ" and name ~= "Switch-WZ" then
if setpoint_Domoticz ~= setpoint then
print(otherdevices_lastupdate[name])
print(age(otherdevices_lastupdate[name]))
if otherdevices_lastupdate[name]~=nil and age(otherdevices_lastupdate[name]) > 120 then --Domoticz thermostat value must be updated
table.insert(commandArray, { ['UpdateDevice'] = otherdevices_idx[name]..'|0|'..setpoint})
if Debug=="YES" then print("Domoticz setpoint updated") end
else --Max! setpoint must be updated
MaxCmdSend(adr, room_num, "manual", setpoint_Domoticz)
if Debug=="YES" then print("MAX!Valve setpoint updated") end
end
end
---end
end
table.insert(commandArray, { ['UpdateDevice'] = otherdevices_idx[name]..'|0|'..valve_pos})
elseif dtype == "Thermostat" then
--table.insert(commandArray, { ['UpdateDevice'] = otherdevices_idx[room]..'|0|'..temp})
setpoint_Domoticz = tonumber(otherdevices_svalues[name])
if setpoint_Domoticz ~= setpoint then
print(otherdevices_lastupdate[name])
print(age(otherdevices_lastupdate[name]))
if otherdevices_lastupdate[name]~=nil and age(otherdevices_lastupdate[name]) > 120 then --Domoticz thermostat value must be updated
table.insert(commandArray, { ['UpdateDevice'] = otherdevices_idx[name]..'|0|'..setpoint})
if Debug=="YES" then print("Domoticz setpoint updated") end
else --Max! setpoint must be updated
MaxCmdSend(adr, room_num, "manual", setpoint_Domoticz)
if Debug=="YES" then print("MAX!WMT setpoint updated") end
end
end
end
end
dtype=""
name=""
setpoint=""
temp=""
valve_pos=""
pos = pos + (data_len*2)
end
end
function MaxCmdSend(id, room, mode, setpoint)
bits = setpoint * 2
smode = string.upper(mode)
if smode == 'MANUAL' then
bits = 64 + bits
elseif smode == 'BOOST' then
bits = 192 + bits
elseif smode == 'VACATION' then
bits = 128 + bits
end
hex = "000440000000"..id..room..string.format("%x",bits)
sendStr = Basexx.to_base64(Basexx.from_hex(hex))
i, status = tcp:send("s:"..sendStr.."\r\n")
if not i then
print("MAX! TCP send failed - "..status)
return
end
end
----------------------------------------------------------------------------------------------------------
-- CommandArray
----------------------------------------------------------------------------------------------------------
commandArray = {}
local m = os.date('%M')
if (m % 2 == 0) then
--print("The 3 minute script interval reached")
tcp = Socket.connect(MaxIP, MaxPort)
if not tcp then
print("MAX! Socket connect failed for "..MaxIP..':'..MaxPort)
return
end
tcp:settimeout(2)
local time = os.date("*t")
while (time.min ~= 0) do
s, status, partial = tcp:receive()
if (status) then
print("MAX! 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()
end
return commandArray
Re: ELV Max! Heating control system
Posted: Wednesday 02 November 2016 10:53
by blackdog65
Hi Westcott
here it is
Code: Select all
--./script_time_max.lua
----------------------------------------------------------------------------------------------------------
-- Script parameters
----------------------------------------------------------------------------------------------------------
package.loadlib("core.so", "*")
local Socket = require "socket"
local Basexx = require "basexx"
local Rooms = {}
local Devices = {}
local Room_nums = {}
local MaxIP = "192.168.1.131"
local MaxPort = 62910
local useWMT = true --# Set to true if there is a wall mounted thermostat in every room, then this one will be used for setpoint getting/setting
Debug = "YES" --# Turn debugging on ("YES") or off ("NO")
----------------------------------------------------------------------------------------------------------
-- Script functions
----------------------------------------------------------------------------------------------------------
function age(timestring)
t = {}
t.year = string.sub(timestring,1,4)
t.month = string.sub(timestring,6,7)
t.day = string.sub(timestring,9,10)
t.hour = string.sub(timestring,12,13)
t.min = string.sub(timestring,15,16)
t.sec = string.sub(timestring,18,19)
return os.difftime(os.time(),os.time(t))
end
function maxCmd_H(data)
--if Debug=="YES" then print('H='..data) end
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-1)
pos = pos+name_len
adr = Basexx.to_hex(dec:sub(pos, pos+2))
Rooms[room_num] = name
pos = pos+3
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-1)
pos = pos+name_len
room_num = string.byte(dec, pos)
Room_nums[adr] = room_num
Devices[adr] = name
end
end
function maxCmd_C(data)
--if Debug=="YES" then print('C='..data) end
end
function maxCmd_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
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)
room_num = string.format("%02X", Room_nums[adr])
room = Rooms[Room_nums[adr]]
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(23,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
if (mode ~= 2) then
s = hex:sub(19,22)
temp = tonumber(s,16) / 10
else
temp = 0
end
dtype = "Valve"
end
--Temperaturdevices den Status aktualisieren
if temp ~= 0 and dtype == "Valve" then
table.insert(commandArray, { ['UpdateDevice'] = otherdevices_idx[name.." (Valve)"]..'|0|'..temp..';'..valve_pos..';0'})
elseif temp ~= 0 and dtype == "Thermostat" then
table.insert(commandArray, { ['UpdateDevice'] = otherdevices_idx[room]..'|0|'..temp})
end
if smode=="Manual" then
--Update virtual devices in Domoticz and update MAX! setpoints if necessary
if Debug=="YES" then print(dtype.." "..name.." Setpoint="..setpoint.." Temp="..temp.." Valve pos="..valve_pos) end
if dtype == "Valve" then
--table.insert(commandArray, { ['UpdateDevice'] = otherdevices_idx[name.." (Valve)"]..'|0|'..temp..';'..valve_pos..';0'})
if not useWMT and tonumber(otherdevices_svalues[name])~=nil then --Use valve to check setpoint mismatch
setpoint_Domoticz = tonumber(otherdevices_svalues[name])
---if name ~= "EcoTaster" and name ~= "Switch-SZ" and name ~= "Switch-WZ" then
if setpoint_Domoticz ~= setpoint then
print(otherdevices_lastupdate[name])
print(age(otherdevices_lastupdate[name]))
if otherdevices_lastupdate[name]~=nil and age(otherdevices_lastupdate[name]) > 120 then --Domoticz thermostat value must be updated
table.insert(commandArray, { ['UpdateDevice'] = otherdevices_idx[name]..'|0|'..setpoint})
if Debug=="YES" then print("Domoticz setpoint updated") end
else --Max! setpoint must be updated
MaxCmdSend(adr, room_num, "manual", setpoint_Domoticz)
if Debug=="YES" then print("MAX!Valve setpoint updated") end
end
end
---end
end
table.insert(commandArray, { ['UpdateDevice'] = otherdevices_idx[name]..'|0|'..valve_pos})
elseif dtype == "Thermostat" then
--table.insert(commandArray, { ['UpdateDevice'] = otherdevices_idx[room]..'|0|'..temp})
setpoint_Domoticz = tonumber(otherdevices_svalues[name])
if setpoint_Domoticz ~= setpoint then
print(otherdevices_lastupdate[name])
print(age(otherdevices_lastupdate[name]))
if otherdevices_lastupdate[name]~=nil and age(otherdevices_lastupdate[name]) > 120 then --Domoticz thermostat value must be updated
table.insert(commandArray, { ['UpdateDevice'] = otherdevices_idx[name]..'|0|'..setpoint})
if Debug=="YES" then print("Domoticz setpoint updated") end
else --Max! setpoint must be updated
MaxCmdSend(adr, room_num, "manual", setpoint_Domoticz)
if Debug=="YES" then print("MAX!WMT setpoint updated") end
end
end
end
end
dtype=""
name=""
setpoint=""
temp=""
valve_pos=""
pos = pos + (data_len*2)
end
end
function MaxCmdSend(id, room, mode, setpoint)
bits = setpoint * 2
smode = string.upper(mode)
if smode == 'MANUAL' then
bits = 64 + bits
elseif smode == 'BOOST' then
bits = 192 + bits
elseif smode == 'VACATION' then
bits = 128 + bits
end
hex = "000440000000"..id..room..string.format("%x",bits)
sendStr = Basexx.to_base64(Basexx.from_hex(hex))
i, status = tcp:send("s:"..sendStr.."\r\n")
if not i then
print("MAX! TCP send failed - "..status)
return
end
end
----------------------------------------------------------------------------------------------------------
-- CommandArray
----------------------------------------------------------------------------------------------------------
commandArray = {}
local m = os.date('%M')
if (m % 2 == 0) then
--print("The 3 minute script interval reached")
tcp = Socket.connect(MaxIP, MaxPort)
if not tcp then
print("MAX! Socket connect failed for "..MaxIP..':'..MaxPort)
return
end
tcp:settimeout(2)
local time = os.date("*t")
while (time.min ~= 0) do
s, status, partial = tcp:receive()
if (status) then
print("MAX! 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()
end
return commandArray
line 131 is where the error occurs
Code: Select all
table.insert(commandArray, { ['UpdateDevice'] = otherdevices_idx[name.." (Valve)"]..'|0|'..temp..';'..valve_pos..';0'})
Many thanks
Sean
Re: ELV Max! Heating control system
Posted: Wednesday 02 November 2016 11:23
by Westcott
Thanks, both - I'm looking at them.
You are both failing on this command -
table.insert(commandArray, { ['UpdateDevice'] = otherdevices_idx[name.." (Valve)"]..'|0|'..temp..';'..valve_pos..';0'})
so there is no device called name.." (Valve)"
We need to change this bit of code somewhere near line 130 -
--Temperaturdevices den Status aktualisieren
if temp ~= 0 and dtype == "Valve" then
to -
--Temperaturdevices den Status aktualisieren
idx = otherdevices_idx[name.." (Valve)"]
if not idx then
print("No device "..name.." (Valve)")
print(data)
elseif temp ~= 0 and dtype == "Valve" then
I haven't tested it, but what could possibly go wrong?
Re: ELV Max! Heating control system
Posted: Wednesday 02 November 2016 11:35
by mvzut
blackdog65 wrote:line 131 is where the error occurs
Code: Select all
table.insert(commandArray, { ['UpdateDevice'] = otherdevices_idx[name.." (Valve)"]..'|0|'..temp..';'..valve_pos..';0'})
Many thanks
Sean
I think this error occurs because the script tries to find the IDX of a device named "<valve device name> (Valve)", i.e. it expects the device name to end with " (Valve)". Nowhere else in the Wiki it is stated that this is the required naming scheme, it actually suggests valves to end with "-Rad".
Since this device probably doesn't exist, it also cannot find the IDX, and returns nil. And LUA cannot concatenate strings where one of the composing elements has a nil value.
I need to dive into it deeper to see how to solve this error is, but I actually think this line is obsolete: it is apparently intended to update a combined percentage/temeprature sensor to represent the status of a valve, where further down the script other devices are already updated for the temperature and the valve percentage separately.
Re: ELV Max! Heating control system
Posted: Wednesday 02 November 2016 11:59
by blackdog65
Ah!
So the solution may be as simple as changing "valve" to "rad" or deleting function altogether. Great news!
Thanks for the continued help ans support guys.
As soon as we iron this out I'll update the wiki too
Sean
Re: ELV Max! Heating control system
Posted: Wednesday 02 November 2016 21:37
by jmbjmbjmb
After reading the wiki (great work, by the way), I am assuming that each and every room must have a wall thermostat. Is that correct ?
I believe that MaxBuddy was able somehow (and maybe in a quite unreliable way) to pull the current temperature right from the thermostat (i.e., without any wall thermostat). Is the code implementing this method too ?
Thanks
Re: ELV Max! Heating control system
Posted: Wednesday 02 November 2016 21:51
by blackdog65
latest scrip_time_max.lua has a variable for with/without stat

Re: ELV Max! Heating control system
Posted: Wednesday 02 November 2016 22:18
by jmbjmbjmb
Thanks. I will try that now.
Just a question about the nameing scheme.
In a particular room, I do have 2 radiators.
So, if that room is called "Salon", I can't have two radiators named "Salon-Rad" (the max app wont allow that anyways..).
Any clue ?
Re: ELV Max! Heating control system
Posted: Wednesday 02 November 2016 22:28
by blackdog65
I'd suggest "Salon1-Rad" and "Salon2-Rad"
Although that sounds like you have 2 salons

Re: ELV Max! Heating control system
Posted: Wednesday 02 November 2016 22:37
by jmbjmbjmb
I've done pretty much that.
When running the test script I am getting:
Code: Select all
Rooms
-----
Alienor 08F556
Cuisine
0B0442
Salon 08F541
Garcons 08F6D7
Couloir 08F616
Devices
-------
Salon-Stat 09B650
Alienor-Rad 08F556
Cuisine-Rad 0B0442
Salon-rue-Rad 08F6D4
Salon-jardin-Rad 08F541
Couloir-Rad 08F616
Garcon-Rad 08F6D7
Device status
-------------
lua: maxtest.lua:91: attempt to index global 'bit32' (a nil value)
stack traceback:
maxtest.lua:91: in function 'maxCmd_L'
maxtest.lua:148: in main chunk
[C]: ?
Re: ELV Max! Heating control system
Posted: Wednesday 02 November 2016 22:43
by Skippiemanz
Try SalonRue-Rad and SalonJardin-Rad
Re: ELV Max! Heating control system
Posted: Wednesday 02 November 2016 22:48
by jmbjmbjmb
Just did, now I am getting this (I can uncomment the debug lines to print the Max Messages if that helps debugging):
Code: Select all
Rooms
-----
Alienor 08F556
Cuisine
0B0442
Salon 08F541
Garcons 08F6D7
Couloir 08F616
Devices
-------
Salon-Stat 09B650
Alienor-Rad 08F556
Cuisine-Rad 0B0442
SalonRue-Rad 08F6D4
SalonJardin-Rad 08F541
Couloir-Rad 08F616
Garcon-Rad 08F6D7
Device status
-------------
lua: maxtest.lua:91: attempt to index global 'bit32' (a nil value)
stack traceback:
maxtest.lua:91: in function 'maxCmd_L'
maxtest.lua:148: in main chunk
[C]: ?
Re: ELV Max! Heating control system
Posted: Wednesday 02 November 2016 22:58
by Skippiemanz
Can you try alienor-room, cuisine-room and so on?
Re: ELV Max! Heating control system
Posted: Wednesday 02 November 2016 23:08
by jmbjmbjmb
Nothing in the code is expecting the "room" string in rooms names so I am not expecting this change to make a difference.
The rooms names in the wiki example are "Sitting Room", "Kitchen" (note that this one does not have "room" in it) and "Another Room".
None of the code checks for "-Rad" or "Stat" either.
So while this may matter once running this from domoticz, it should have no impact when simply running the lua code.
In case that helps finding out what one of the expected value is 'nil', I ma pasting the output including the debug prints that show the messages:
Code: Select all
lua maxtest.lua
H=JEQ0543318,03f77a,0113,00000000,5e12eb04,2a,32,100b02,1707,03,0000
Rooms
-----
Alienor 08F556
Cuisine
0B0442
Salon 08F541
Garcons 08F6D7
Couloir 08F616
Devices
-------
Salon-Stat 09B650
Alienor-Rad 08F556
Cuisine-Rad 0B0442
SalonRue-Rad 08F6D4
SalonJardin-Rad 08F541
Couloir-Rad 08F616
Garcon-Rad 08F6D7
C=03f77a,7QP3egATAf9KRVEwNTQzMzE4AQsABEAAAAAAAAAAAP///////////////////////////wsABEAAAAAAAAAAQf///////////////////////////2h0dHA6Ly93d3cubWF4LXBvcnRhbC5lbHYuZGU6ODAvY3ViZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAENFVAAACgADAAAOEENFU1QAAwACAAAcIA==
C=0b0442,0gsEQgICEABLRVEwNTcxNzk4JiE9CQcYAzAM/wBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIERITRRFIEUgRSBFIEUgRSBFIEUgRSBFIEUgREhNFEUgRSBFIEUgRSBFIEUgRSBFIEUgRSBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIERITRRFIEUgRSBFIEUgRSBFIEUgRSBFIEUgREhNFEUgRSBFIEUgRSBFIEUgRSBFIEUgRSBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIA==
C=08f6d7,0gj21wIDEP9LRVEwNTcwOTAzJiE9CQcYAzAM/wBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIERITRRFIEUgRSBFIEUgRSBFIEUgRSBFIEUgREhNFEUgRSBFIEUgRSBFIEUgRSBFIEUgRSBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIERITRRFIEUgRSBFIEUgRSBFIEUgRSBFIEUgREhNFEUgRSBFIEUgRSBFIEUgRSBFIEUgRSBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIA==
C=08f616,0gj2FgIFEP9LRVEwNTY5OTA3JiE9CQcYAzAM/wBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIERITRRFIEUgRSBFIEUgRSBFIEUgRSBFIEUgREhNFEUgRSBFIEUgRSBFIEUgRSBFIEUgRSBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIERITRRFIEUgRSBFIEUgRSBFIEUgRSBFIEUgREhNFEUgRSBFIEUgRSBFIEUgRSBFIEUgRSBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIA==
C=08f6d4,0gj21AIBEABLRVEwNTcwOTA2JiE9CQcYAzAM/wBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIERITRRFIEUgRSBFIEUgRSBFIEUgRSBFIEUgREhNFEUgRSBFIEUgRSBFIEUgRSBFIEUgRSBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIERITRRFIEUgRSBFIEUgRSBFIEUgRSBFIEUgREhNFEUgRSBFIEUgRSBFIEUgRSBFIEUgRSBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIA==
C=09b650,zgm2UAMBEP9LRVEwODYzNzAwJiE9CURITRRFIEUgRSBFIEUgRSBFIEUgRSBFIEUgREhNFEUgRSBFIEUgRSBFIEUgRSBFIEUgRSBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIERITRRFIEUgRSBFIEUgRSBFIEUgRSBFIEUgREhNFEUgRSBFIEUgRSBFIEUgRSBFIEUgRSBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIERITRRFIEUgRSBFIEUgRSBFIEUgRSBFIEUgBxgw
C=08f541,0gj1QQIBEP9LRVEwNTY5NjkzJiE9CQcYAzAM/wBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIERITRRFIEUgRSBFIEUgRSBFIEUgRSBFIEUgREhNFEUgRSBFIEUgRSBFIEUgRSBFIEUgRSBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIERITRRFIEUgRSBFIEUgRSBFIEUgRSBFIEUgREhNFEUgRSBFIEUgRSBFIEUgRSBFIEUgRSBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIA==
C=08f556,0gj1VgIEEABLRVEwNTY5NzE0KyE9CQcYAzAM/wBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIERITRRFIEUgRSBFIEUgRSBFIEUgRSBFIEUgREhNFEUgRSBFIEUgRSBFIEUgRSBFIEUgRSBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIERITRRFIEUgRSBFIEUgRSBFIEUgRSBFIEUgREhNFEUgRSBFIEUgRSBFIEUgRSBFIEUgRSBESE0URSBFIEUgRSBFIEUgRSBFIEUgRSBFIA==
Device status
-------------
lua: maxtest.lua:91: attempt to index global 'bit32' (a nil value)
stack traceback:
maxtest.lua:91: in function 'maxCmd_L'
maxtest.lua:148: in main chunk
[C]: ?
Re: ELV Max! Heating control system
Posted: Wednesday 02 November 2016 23:19
by jmbjmbjmb
Basically the code that throws the error is:
Code: Select all
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)
I've added the following to understand why this getting 'nil'
Code: Select all
print("valve_info for "..pos.." out of "..L_len)
print(valve_info)
Output is:
Code: Select all
Device status
-------------
valve_info for 1 out of 170
25
lua: maxtest.lua:93: attempt to index global 'bit32' (a nil value)
stack traceback:
maxtest.lua:93: in function 'maxCmd_L'
maxtest.lua:150: in main chunk
[C]: ?
As the decimal value is 25, the binary is:
00011001
and if I get the code right then it should feed batt, bst and mode respectively with 1, 1 and 00
so I'm not sure why I am getting this error message.
Re: ELV Max! Heating control system
Posted: Thursday 03 November 2016 0:07
by jmbjmbjmb
Found the issue. I had lua 5.1 which does not have bit32.
Re: ELV Max! Heating control system
Posted: Thursday 03 November 2016 8:47
by blackdog65

@jmbjmbjmb
jmbjmbjmb wrote:Found the issue. I had lua 5.1 which does not have bit32.
"DOH! Don't you just hate it when that happens? Good catch. Is everything else working now?
@mvzut & Westcott the "attempt to concatenate field '?' (a nil value)" issue occurs when a wall stat has a "Valve pos=0" reading.
So... is
Code: Select all
--Temperaturdevices den Status aktualisieren
idx = otherdevices_idx[name.." (Valve)"]
if not idx then
print("No device "..name.." (Valve)")
print(data)
elseif temp ~= 0 and dtype == "Valve" then
the cure? Not questioning your skills, just wanted confirmation before trying... as it's f***ing FREEZING here today!

Re: ELV Max! Heating control system
Posted: Thursday 03 November 2016 9:04
by blackdog65
Erm... no
Code: Select all
2016-11-03 08:02:00.861 LUA: No device SittingRoom-Stat (Valve)
2016-11-03 08:02:00.861 LUA: DBNwNQkSGQEoAAAAzQwU7Z0JElkBJgAAAL0LE4YvCRIZACgAzQALE4ZeCRIZACIAAAALFVXz8RoZACIAtwALDrjoCRIZZCgAAAAMFPDNCRIZASgAAAC1DBNwhAkSGQEiAAAArQ==
2016-11-03 08:02:00.861 LUA: Thermostat SittingRoom-Stat Setpoint=20 Temp=20.5 Valve pos=-1
2016-11-03 08:02:00.861 LUA: No device V-Bed-Stat (Valve)
2016-11-03 08:02:00.862 LUA: DBNwNQkSGQEoAAAAzQwU7Z0JElkBJgAAAL0LE4YvCRIZACgAzQALE4ZeCRIZACIAAAALFVXz8RoZACIAtwALDrjoCRIZZCgAAAAMFPDNCRIZASgAAAC1DBNwhAkSGQEiAAAArQ==
2016-11-03 08:02:00.862 LUA: Thermostat V-Bed-Stat Setpoint=19 Temp=18.9 Valve pos=-1
2016-11-03 08:02:00.862 LUA: No device SittingRoom-Rad (Valve)
2016-11-03 08:02:00.862 LUA: DBNwNQkSGQEoAAAAzQwU7Z0JElkBJgAAAL0LE4YvCRIZACgAzQALE4ZeCRIZACIAAAALFVXz8RoZACIAtwALDrjoCRIZZCgAAAAMFPDNCRIZASgAAAC1DBNwhAkSGQEiAAAArQ==
2016-11-03 08:02:00.862 LUA: Valve SittingRoom-Rad Setpoint=20 Temp=20.5 Valve pos=0
2016-11-03 08:02:00.862 LUA: No device Z-Bed-Rad (Valve)
2016-11-03 08:02:00.862 LUA: DBNwNQkSGQEoAAAAzQwU7Z0JElkBJgAAAL0LE4YvCRIZACgAzQALE4ZeCRIZACIAAAALFVXz8RoZACIAtwALDrjoCRIZZCgAAAAMFPDNCRIZASgAAAC1DBNwhAkSGQEiAAAArQ==
2016-11-03 08:02:00.862 LUA: Valve Z-Bed-Rad Setpoint=17 Temp=0 Valve pos=0
2016-11-03 08:02:00.863 LUA: No device V-Bed-Rad (Valve)
2016-11-03 08:02:00.863 LUA: DBNwNQkSGQEoAAAAzQwU7Z0JElkBJgAAAL0LE4YvCRIZACgAzQALE4ZeCRIZACIAAAALFVXz8RoZACIAtwALDrjoCRIZZCgAAAAMFPDNCRIZASgAAAC1DBNwhAkSGQEiAAAArQ==
2016-11-03 08:02:00.863 LUA: Valve V-Bed-Rad Setpoint=17 Temp=18.3 Valve pos=0
2016-11-03 08:02:00.863 LUA: No device Kitchen-Rad (Valve)
2016-11-03 08:02:00.863 LUA: DBNwNQkSGQEoAAAAzQwU7Z0JElkBJgAAAL0LE4YvCRIZACgAzQALE4ZeCRIZACIAAAALFVXz8RoZACIAtwALDrjoCRIZZCgAAAAMFPDNCRIZASgAAAC1DBNwhAkSGQEiAAAArQ==
2016-11-03 08:02:00.864 LUA: Valve Kitchen-Rad Setpoint=20 Temp=0 Valve pos=100
2016-11-03 08:02:00.864 LUA: No device Kitchen-Stat (Valve)
2016-11-03 08:02:00.864 LUA: DBNwNQkSGQEoAAAAzQwU7Z0JElkBJgAAAL0LE4YvCRIZACgAzQALE4ZeCRIZACIAAAALFVXz8RoZACIAtwALDrjoCRIZZCgAAAAMFPDNCRIZASgAAAC1DBNwhAkSGQEiAAAArQ==
2016-11-03 08:02:00.864 LUA: Thermostat Kitchen-Stat Setpoint=20 Temp=18.1 Valve pos=-1
2016-11-03 08:02:00.864 LUA: No device Z-Bed-Stat (Valve)
2016-11-03 08:02:00.864 LUA: DBNwNQkSGQEoAAAAzQwU7Z0JElkBJgAAAL0LE4YvCRIZACgAzQALE4ZeCRIZACIAAAALFVXz8RoZACIAtwALDrjoCRIZZCgAAAAMFPDNCRIZASgAAAC1DBNwhAkSGQEiAAAArQ==