Page 30 of 37
Re: ELV Max! Heating control system
Posted: Thursday 09 November 2017 18:43
by Rostikator
after two years of correct function MaxBuddy hangs after two days running max.
I try LUA script. on windows
installed LuaForWindows_v5.1.4-46
MAX! dummy created
script edited
IP, port, path
Basexx = require "base64"
but still don't run
C:\Program Files (x86)\Lua\5.1>cubeScript.lua
C:\Program Files (x86)\Lua\5.1\lua.exe: C:\Program Files (x86)\Lua\5.1\cubeScript.lua
106: attempt to call field 'from_base64' (a nil value)
stack traceback:
C:\Program Files (x86)\Lua\5.1\cubeScript.lua:106: in function 'maxCmd_M'
C:\Program Files (x86)\Lua\5.1\cubeScript.lua:264: in main chunk
[C]: ?
any idea , I need only reading from MAX
Re: ELV Max! Heating control system
Posted: Thursday 09 November 2017 18:47
by Peggy
Why did you change
Basexx = require "basexx"
into
Basexx = require "base64"
Re: ELV Max! Heating control system
Posted: Thursday 09 November 2017 19:21
by Rostikator
I don't have basexx lua. now I have basexx.lua on system.
Now I try maxtest/lua
error on the end
lua -e "io.stdout:setvbuf 'no'" "maxtest.lua"
Rooms
-----
Bed ROOM 0821EF
Living ROOM 173F01
Corridor 173CB5
SIMA ROOM 0821FB
MATA ROOM 0821F8
Devices
-------
BR-WT 09B522
LR-WT 09B827
LR-RT 0821F8
CH1R-WT 0970F8
WS-M 1597B7
WT-LR 16B49E
RT-LR-basic 173F01
WS-S 15983A
BR-RT 0821EF
RT-Corr 173CB5
CH1R-RT 0821FB
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: Thursday 09 November 2017 19:29
by Peggy
What is maxtest.lua? I don't remember this file. you should'nt need this script.
I gave you my cubeScript.lua file which was adapted to work on Lua 5.1, because mvzut's one was written for Lua 5.2.
Re: ELV Max! Heating control system
Posted: Thursday 09 November 2017 19:52
by Rostikator
maxtest.lua from
https://www.domoticz.com/wiki/EQ3_MAX!
now I must create all devices manually in domoticz ?
Re: ELV Max! Heating control system
Posted: Thursday 09 November 2017 20:05
by Rostikator
after renaming in MAX
Rooms
-----
Bed ROOM 0821EF
Living ROOM 173F01
Corridor 173CB5
SIMA ROOM 0821FB
MATA ROOM 0821F8
Devices
-------
WT-BedRoom 09B522
WT-Mata 09B827
RT-Mata 0821F8
WT-Sima 0970F8
WS-Mata 1597B7
WT-LivingRoom 16B49E
RT-LivingRoom 173F01
WS-Sima 15983A
RT-BedRoom 0821EF
RT-Corridor 173CB5
RT-Sima 0821FB
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: Tuesday 21 November 2017 23:47
by oasisnl
Hello, since a few days I receive an error on the script_time_max.lua script
Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_max.lua: /home/pi/domoticz/scripts/lua/JSON.lua:1009: /home/pi/domoticz/scripts/lua/JSON.lua:834: Lua script execution exceeds maximum number of lines
It was running good for several weeks. When the error came the first time I didn't make any changes to domoticz or the PI .
Any help would be great, I'm just a beginner with the scripts.
Re: ELV Max! Heating control system
Posted: Thursday 23 November 2017 8:00
by mvzut
oasisnl wrote:Hello, since a few days I receive an error on the script_time_max.lua script
Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_max.lua: /home/pi/domoticz/scripts/lua/JSON.lua:1009: /home/pi/domoticz/scripts/lua/JSON.lua:834: Lua script execution exceeds maximum number of lines
It was running good for several weeks. When the error came the first time I didn't make any changes to domoticz or the PI .
Any help would be great, I'm just a beginner with the scripts.
Hmmm, strange, especially since it suddenly started without any changes made to the system.
Do you get the same errors of you run the test script from the command line?
Re: ELV Max! Heating control system
Posted: Friday 24 November 2017 0:49
by Meza
Not been here for a little while, but experimenting with my MAX! eq3 cube brought me back.
I was thinking of how to make an embeded boiler controller, that wouldn't need to run on Domoticz, or raspberry pi or other server.
I noticed that ESP8266 can run LUA scripts - does that mean there's a posibility to run the max lua scripts (
https://www.domoticz.com/wiki/EQ3_MAX!) on an tiny ESP device with relays connected?
That would be very nifty.
Re: ELV Max! Heating control system
Posted: Friday 24 November 2017 0:49
by Meza
Not been here for a little while, but experimenting with my MAX! eq3 cube brought me back.
I was thinking of how to make an embeded boiler controller, that wouldn't need to run on Domoticz, or raspberry pi or other server.
I noticed that ESP8266 can run LUA scripts - does that mean there's a posibility to run the max lua scripts (
https://www.domoticz.com/wiki/EQ3_MAX!) on an tiny ESP device with relays connected?
That would be very nifty.
Re: ELV Max! Heating control system
Posted: Friday 24 November 2017 7:41
by bilbolodz
I'm using these
https://github.com/autopower/thermeq3 solution. It has "some issues" but it's working over one year without any big problems.
Re: ELV Max! Heating control system
Posted: Friday 24 November 2017 8:20
by Peggy
My Cube reseted like you mvzut. Is your reboot trick working? I want to prevent this shit.
Re: ELV Max! Heating control system
Posted: Friday 24 November 2017 9:46
by mvzut
Peggy wrote: ↑Friday 24 November 2017 8:20
My Cube reseted like you mvzut. Is your reboot trick working? I want to prevent this shit.
It has not reset since more than half a year since I forced it to reboot once every week! I'm using a remote controlled wall plug for this.
Re: ELV Max! Heating control system
Posted: Friday 24 November 2017 10:23
by Peggy
I wish I had set this trick before. The cube is out of control, I have to hard reset it and make again pairings, then room settings, then temp planning. I had fine tuned the temp offsets for all 6 valves, it will take hours to make all work again together with the domoticz devices already created using your script.
Re: ELV Max! Heating control system
Posted: Friday 24 November 2017 18:44
by oasisnl
Sorry for copying the whole text, Didn't find the option to reply with quote
when I run testscript it doesn't give any errors. Also Domoticz just updates the thermostats, valves, and radiators. It just gives an error on the script?
Hello, since a few days I receive an error on the script_time_max.lua script
Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_max.lua: /home/pi/domoticz/scripts/lua/JSON.lua:1009: /home/pi/domoticz/scripts/lua/JSON.lua:834: Lua script execution exceeds maximum number of lines
It was running good for several weeks. When the error came the first time I didn't make any changes to domoticz or the PI .
Any help would be great, I'm just a beginner with the scripts.
Hmmm, strange, especially since it suddenly started without any changes made to the system.
Do you get the same errors of you run the test script from the command line?
Re: ELV Max! Heating control system
Posted: Friday 24 November 2017 18:59
by oasisnl
oasisnl wrote: ↑Friday 24 November 2017 18:44
Sorry for copying the whole text, Didn't find the option to reply with quote
when I run testscript it doesn't give any errors. Also Domoticz just updates the thermostats, valves, and radiators. It just gives an error on the script?
Hello, since a few days I receive an error on the script_time_max.lua script
Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_max.lua: /home/pi/domoticz/scripts/lua/JSON.lua:1009: /home/pi/domoticz/scripts/lua/JSON.lua:834: Lua script execution exceeds maximum number of lines
It was running good for several weeks. When the error came the first time I didn't make any changes to domoticz or the PI .
Any help would be great, I'm just a beginner with the scripts.
Hmmm, strange, especially since it suddenly started without any changes made to the system.
Do you get the same errors of you run the test script from the command line?
here is the total log from domoticz.
Rebooted the Pi to be sure, also rebooted the cube.
2017-11-24 18:50:00.066 Incoming connection from: 127.0.0.1
2017-11-24 18:50:02.677 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_max.lua: /home/pi/domoticz/scripts/lua/JSON.lua:1009: /home/pi/domoticz/scripts/lua/JSON.lua:836: Lua script execution exceeds maximum number of lines
2017-11-24 18:50:02.677 EventSystem: Fetching url...
2017-11-24 18:50:02.933 (MAX!) General/Percentage (Slaapkamer D Re Klep)
2017-11-24 18:51:01.903 Notification sent (Email)
As fas as I can see in domoticz only one valve gets updated ( slaapkamer D Re Klep)
the other valves and thermostats don't get updated. I see them al when running test script
see output from tests :
pi@raspberrypi:~/domoticz/scripts/lua $ lua maxtest.lua
Rooms
-----
HalBeneden 17ABB4
SlaapkamerJR 17AC40
Woonkamer 17AC45
SlaapkamerD 17BA61
Devices
-------
SlaapkamerJR-Stat 18F17C
SlaapkamerD-Stat 18E0CA
Woonkamer-Stat 18EA70
HalBeneden-Rad 17ABB4
SlaapkamerD_R-Rad 17BA61
SlaapkamerJR-Rad 17AC40
Woonkamer A-Rad 17AC45
Device status
-------------
Valve SlaapkamerD_R-Rad Setpoint=20 Temp=0 Valve pos=0 Battery=OK Mode=Manual
Thermostat SlaapkamerJR-Stat Setpoint=20 Temp=20.3 Valve pos=-1 Battery=OK Mode=Manual
Thermostat SlaapkamerD-Stat Setpoint=20 Temp=20.4 Valve pos=-1 Battery=OK Mode=Manual
Valve HalBeneden-Rad Setpoint=19 Temp=0 Valve pos=100 Battery=OK Mode=Manual
Thermostat Woonkamer-Stat Setpoint=21.5 Temp=21.1 Valve pos=-1 Battery=OK Mode=Manual
Valve SlaapkamerJR-Rad Setpoint=20 Temp=0 Valve pos=0 Battery=OK Mode=Manual
Valve Woonkamer A-Rad Setpoint=21.5 Temp=0 Valve pos=100 Battery=OK Mode=Manual
Hope this all helpes, I now have renamed the script so it doesn't mail me every 5 minutes but offcourse now my heating isn't controlled from domoticz.
Any help would be great.
Re: ELV Max! Heating control system
Posted: Saturday 25 November 2017 11:44
by mvzut
oasisnl wrote: ↑Friday 24 November 2017 18:59 2017-11-24 18:50:02.677 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_max.lua: /home/pi/domoticz/scripts/lua/JSON.lua:1009: /home/pi/domoticz/scripts/lua/JSON.lua:836: Lua script execution exceeds maximum number of lines
Hi oasisnl,
Which version of the script do you use? Your script name (
script_time_max.lua) suggests that you use the version that is automatically started by Domoticz. But this version doesn't need JSON decoding at all, so you shouldn't get this error message. The version with JSON is intended to be run outside Domoticz, e.g. with a crontab entry if you are using a Raspberry Pi or similar (which you do).
The crontab version is described here:
http://www.domoticz.com/forum/viewtopic ... 05#p104705
The Domoticz script is here:
https://www.domoticz.com/wiki/EQ3_MAX!#Max_Script
I personally use the crontab version, since the Domoticz version gives timeout errors if you have a lot of devices. Plus the crontab version creates all devices automatically for you. It just doesn't name them, you have to do that yourself. This is the easiest by running the test script once and writing down the hex codes of each device. These are shown in the device list in Domoticz as the ID for each newly created device, so you will quickly recognize which is which.
Re: ELV Max! Heating control system
Posted: Saturday 25 November 2017 12:36
by oasisnl
mvzut wrote: ↑Saturday 25 November 2017 11:44
oasisnl wrote: ↑Friday 24 November 2017 18:59 2017-11-24 18:50:02.677 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_max.lua: /home/pi/domoticz/scripts/lua/JSON.lua:1009: /home/pi/domoticz/scripts/lua/JSON.lua:836: Lua script execution exceeds maximum number of lines
Hi oasisnl,
Which version of the script do you use? Your script name (
script_time_max.lua) suggests that you use the version that is automatically started by Domoticz. But this version doesn't need JSON decoding at all, so you shouldn't get this error message. The version with JSON is intended to be run outside Domoticz, e.g. with a crontab entry if you are using a Raspberry Pi or similar (which you do).
The crontab version is described here:
http://www.domoticz.com/forum/viewtopic ... 05#p104705
The Domoticz script is here:
https://www.domoticz.com/wiki/EQ3_MAX!#Max_Script
I personally use the crontab version, since the Domoticz version gives timeout errors if you have a lot of devices. Plus the crontab version creates all devices automatically for you. It just doesn't name them, you have to do that yourself. This is the easiest by running the test script once and writing down the hex codes of each device. These are shown in the device list in Domoticz as the ID for each newly created device, so you will quickly recognize which is which.
Hello, Thanks for the reply.
I guess i'm using the crontab version . It automatically created the devices for me and I had to name them in Domoticz.
I guess i'm not running it as a cronjob then??? i'm not sure about that ( i'm not much of a linux man and a real newby to scripts ). the script is placed in the domoticz\scripts\lua folder, here is also the maxtest.lua located.
here is the script i use, it refers to some json stuff as you mention
- Spoiler: show
- package.loadlib("core.so", "*")
Socket = require "socket"
Basexx = require "basexx"
json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")() -- for Linux
--json = (loadfile "D:\\Domoticz\\scripts\\lua\\json.lua")() -- for Windows
http = require "socket.http"
MaxIP='192.168.32.89'
MaxPort = 62910
DomoticzPort = 8080
useWMT = true --Set to true if there is a wall mounted thermostat in every room
interval = 5 --Polling interval in minutes, possible range 1-59. Cube doesn't seem to like too frequent communication, 5 minutes is a safe value
Rooms = {}
Devices = {}
Room_nums = {}
function get_MAX_ID()
result, statuscode, content = http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=hardware')
r,e = json:decode(result)
if r.status == "OK" then
for k,v in pairs(r.result) do
if v.Name == "MAX!" then return v.idx end
end
end
end
function Thermostat(DID)
result, statuscode, content = http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=devices')
r,e = json:decode(result)
if r.status == "OK" then
for k,v in pairs(r.result) do
if v.ID == DID then return v.SetPoint,v.LastUpdate end
end
end
return 0, '2016-01-01 00:00:00' -- value to return if device was not found
end
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)
-- 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)
if num_rooms == 0 or num_rooms == nil then table.insert(commandArray, {['SendNotification'] = 'MAX! problem#Configuration lost?#1'}) end
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)
-- print('C='..data)
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
--Following two lines correct temperatures over 25.5 degrees, since e.g. 26 degrees is reported as 0.5 degrees
--This is due to the fact that temperatures seem to be stored as two Hex characters only (= max 255 in decimal)
--Pending better solution
if temp < 5 then temp = temp + 25.5 end
if setpoint > 50 then setpoint = setpoint - 64 end
-- Update virtual devices in Domoticz and update MAX! setpoints if necessary
--print(dtype.." "..name.." Setpoint="..setpoint.." Temp="..temp.." Valve pos="..valve_pos)
if dtype == "Valve" then
table.insert(commandArray, {['OpenURL'] = 'http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=udevice&hid='..MAX_ID..'&did='..adr..'&dunit=1&dtype=243&dsubtype=6&nvalue=0&svalue='..valve_pos})
if not useWMT then --Use valve to check setpoint mismatch
if temp ~=25.5 then
table.insert(commandArray, {['OpenURL'] = 'http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=udevice&hid='..MAX_ID..'&did='..adr..'&dunit=1&dtype=80&dsubtype=5&nvalue=0&svalue='..temp})
end
setpoint_Domoticz, LastUpdate = Thermostat('0'..adr)
if tonumber(setpoint_Domoticz) ~= setpoint then
if age(LastUpdate) > interval * 60 then --Domoticz thermostat value must be updated
table.insert(commandArray, {['OpenURL'] = 'http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=udevice&hid='..MAX_ID..'&did=0'..adr..'&dunit=1&dtype=242&dsubtype=1&nvalue=0&svalue='..setpoint})
print('Domoticz setpoint ' .. name .. ' updated')
else --Max! setpoint must be updated
MaxCmdSend(adr, room_num, "manual", setpoint_Domoticz)
print('MAX! setpoint ' .. name .. ' updated')
end
end
end
elseif dtype == "Thermostat" and smode ~= 'Auto' then
table.insert(commandArray, {['OpenURL'] = 'http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=udevice&hid='..MAX_ID..'&did='..adr..'&dunit=1&dtype=80&dsubtype=5&nvalue=0&svalue='..temp})
setpoint_Domoticz, LastUpdate = Thermostat('0'..adr)
if tonumber(setpoint_Domoticz) ~= setpoint then
if age(LastUpdate) > interval * 60 then --Domoticz thermostat value must be updated
table.insert(commandArray, {['OpenURL'] = 'http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=udevice&hid='..MAX_ID..'&did=0'..adr..'&dunit=1&dtype=242&dsubtype=1&nvalue=0&svalue='..setpoint})
print('Domoticz setpoint ' .. name .. ' updated')
else --Max! setpoint must be updated
MaxCmdSend(adr, room_num, "manual", setpoint_Domoticz)
print('MAX! setpoint ' .. name .. ' updated')
end
end
end
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 = {}
m = tonumber(os.date('%M'))
if (m % interval == 0) and (m ~= 0) and (m ~= 30) then
--Get ID of MAX hardware in Domoticz, create if it doesn't exist
MAX_ID = get_MAX_ID()
if MAX_ID == nil then -- "MAX!" dummy hardware not yet created, create it
table.insert(commandArray, {['OpenURL'] = 'http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=addhardware&htype=15&port=1&name=MAX!&enabled=true'})
return commandArray
end
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
status = maxCmd_H(data)
if status == 'Error' then break end
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
If it shouldn't be in the scripts folder , can you then explain where to put it and how to create a cronjob for it ( and yes i'm using PI ) .
And is there any explanation why it ran good for a couple of weeks?
Thanks in advance for the reply and the support.
Re: ELV Max! Heating control system
Posted: Saturday 25 November 2017 13:17
by Peggy
I'm getting crazy with the Max! software. I just hard reset it and made pairing again. I don't know why, but whenever I change the temp on one valve, three other valves automatically change to the same temp. You can see hereunder the 4 valves that react together ( 16.5°C), though it is absolutely not what I want.

Re: ELV Max! Heating control system
Posted: Saturday 25 November 2017 13:44
by oasisnl
oasisnl wrote: ↑Saturday 25 November 2017 12:36
mvzut wrote: ↑Saturday 25 November 2017 11:44
oasisnl wrote: ↑Friday 24 November 2017 18:59 2017-11-24 18:50:02.677 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_max.lua: /home/pi/domoticz/scripts/lua/JSON.lua:1009: /home/pi/domoticz/scripts/lua/JSON.lua:836: Lua script execution exceeds maximum number of lines
Hi oasisnl,
Which version of the script do you use? Your script name (
script_time_max.lua) suggests that you use the version that is automatically started by Domoticz. But this version doesn't need JSON decoding at all, so you shouldn't get this error message. The version with JSON is intended to be run outside Domoticz, e.g. with a crontab entry if you are using a Raspberry Pi or similar (which you do).
The crontab version is described here:
http://www.domoticz.com/forum/viewtopic ... 05#p104705
The Domoticz script is here:
https://www.domoticz.com/wiki/EQ3_MAX!#Max_Script
I personally use the crontab version, since the Domoticz version gives timeout errors if you have a lot of devices. Plus the crontab version creates all devices automatically for you. It just doesn't name them, you have to do that yourself. This is the easiest by running the test script once and writing down the hex codes of each device. These are shown in the device list in Domoticz as the ID for each newly created device, so you will quickly recognize which is which.
Hello, Thanks for the reply.
I guess i'm using the crontab version . It automatically created the devices for me and I had to name them in Domoticz.
I guess i'm not running it as a cronjob then??? i'm not sure about that ( i'm not much of a linux man and a real newby to scripts ). the script is placed in the domoticz\scripts\lua folder, here is also the maxtest.lua located.
here is the script i use, it refers to some json stuff as you mention
- Spoiler: show
- package.loadlib("core.so", "*")
Socket = require "socket"
Basexx = require "basexx"
json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")() -- for Linux
--json = (loadfile "D:\\Domoticz\\scripts\\lua\\json.lua")() -- for Windows
http = require "socket.http"
MaxIP='192.168.32.89'
MaxPort = 62910
DomoticzPort = 8080
useWMT = true --Set to true if there is a wall mounted thermostat in every room
interval = 5 --Polling interval in minutes, possible range 1-59. Cube doesn't seem to like too frequent communication, 5 minutes is a safe value
Rooms = {}
Devices = {}
Room_nums = {}
function get_MAX_ID()
result, statuscode, content = http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=hardware')
r,e = json:decode(result)
if r.status == "OK" then
for k,v in pairs(r.result) do
if v.Name == "MAX!" then return v.idx end
end
end
end
function Thermostat(DID)
result, statuscode, content = http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=devices')
r,e = json:decode(result)
if r.status == "OK" then
for k,v in pairs(r.result) do
if v.ID == DID then return v.SetPoint,v.LastUpdate end
end
end
return 0, '2016-01-01 00:00:00' -- value to return if device was not found
end
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)
-- 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)
if num_rooms == 0 or num_rooms == nil then table.insert(commandArray, {['SendNotification'] = 'MAX! problem#Configuration lost?#1'}) end
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)
-- print('C='..data)
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
--Following two lines correct temperatures over 25.5 degrees, since e.g. 26 degrees is reported as 0.5 degrees
--This is due to the fact that temperatures seem to be stored as two Hex characters only (= max 255 in decimal)
--Pending better solution
if temp < 5 then temp = temp + 25.5 end
if setpoint > 50 then setpoint = setpoint - 64 end
-- Update virtual devices in Domoticz and update MAX! setpoints if necessary
--print(dtype.." "..name.." Setpoint="..setpoint.." Temp="..temp.." Valve pos="..valve_pos)
if dtype == "Valve" then
table.insert(commandArray, {['OpenURL'] = 'http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=udevice&hid='..MAX_ID..'&did='..adr..'&dunit=1&dtype=243&dsubtype=6&nvalue=0&svalue='..valve_pos})
if not useWMT then --Use valve to check setpoint mismatch
if temp ~=25.5 then
table.insert(commandArray, {['OpenURL'] = 'http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=udevice&hid='..MAX_ID..'&did='..adr..'&dunit=1&dtype=80&dsubtype=5&nvalue=0&svalue='..temp})
end
setpoint_Domoticz, LastUpdate = Thermostat('0'..adr)
if tonumber(setpoint_Domoticz) ~= setpoint then
if age(LastUpdate) > interval * 60 then --Domoticz thermostat value must be updated
table.insert(commandArray, {['OpenURL'] = 'http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=udevice&hid='..MAX_ID..'&did=0'..adr..'&dunit=1&dtype=242&dsubtype=1&nvalue=0&svalue='..setpoint})
print('Domoticz setpoint ' .. name .. ' updated')
else --Max! setpoint must be updated
MaxCmdSend(adr, room_num, "manual", setpoint_Domoticz)
print('MAX! setpoint ' .. name .. ' updated')
end
end
end
elseif dtype == "Thermostat" and smode ~= 'Auto' then
table.insert(commandArray, {['OpenURL'] = 'http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=udevice&hid='..MAX_ID..'&did='..adr..'&dunit=1&dtype=80&dsubtype=5&nvalue=0&svalue='..temp})
setpoint_Domoticz, LastUpdate = Thermostat('0'..adr)
if tonumber(setpoint_Domoticz) ~= setpoint then
if age(LastUpdate) > interval * 60 then --Domoticz thermostat value must be updated
table.insert(commandArray, {['OpenURL'] = 'http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=udevice&hid='..MAX_ID..'&did=0'..adr..'&dunit=1&dtype=242&dsubtype=1&nvalue=0&svalue='..setpoint})
print('Domoticz setpoint ' .. name .. ' updated')
else --Max! setpoint must be updated
MaxCmdSend(adr, room_num, "manual", setpoint_Domoticz)
print('MAX! setpoint ' .. name .. ' updated')
end
end
end
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 = {}
m = tonumber(os.date('%M'))
if (m % interval == 0) and (m ~= 0) and (m ~= 30) then
--Get ID of MAX hardware in Domoticz, create if it doesn't exist
MAX_ID = get_MAX_ID()
if MAX_ID == nil then -- "MAX!" dummy hardware not yet created, create it
table.insert(commandArray, {['OpenURL'] = 'http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=addhardware&htype=15&port=1&name=MAX!&enabled=true'})
return commandArray
end
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
status = maxCmd_H(data)
if status == 'Error' then break end
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
If it shouldn't be in the scripts folder , can you then explain where to put it and how to create a cronjob for it ( and yes i'm using PI ) .
And is there any explanation why it ran good for a couple of weeks?
Thanks in advance for the reply and the support.
renamed the script to maxscript.lua and added following line to cron
in the domoticz none of the valves and thermostats get updated?
- Spoiler: show
-
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
*/5 * * * * /usr/bin/lua /home/pi/domoticz/sripts/lua/maxscript.lua