Code: Select all
-- Peggy upgrade from original "mvzut CubeScript" source
-- Please launch the original script at least once in order to create the right devices in domoticz (see under why)
-- Improvements :
------- Domoticz is updated only if needed
------- Domoticz Modes : Automatic / Confort (Manual) / Eco (Manual) / Boost
------- Domoticz json device list is requested only once by script run, not once by device
------- Creation and update of a daily HTML log file with device update
------- LUA Log is more verbose
------- Domoticz Log is updated on some events
-- Script which creates & synchronizes devices in Domoticz with values from MAX! cube
-- Change variables below to your own values
-- Start by adding new cronjob "*/5 * * * * /usr/bin/lua /home/pi/domoticz/scripts/lua/maxscript.lua" (using crontab -e)
MaxIP='192.168.1.10' -- IP adress of your Cube, best to check via your router
MaxPort = 62910 -- Port used by your Cube, usually 62910
DomoticzPort = 8080 -- Port used by Domoticz, 8080 is the default
useWMT = false -- Set to true if there is a wall mounted thermostat in every room
interval = 5 -- Polling interval in minutes, fill in same value as in crontab
setpoint_DoorOpen = 5 -- Setpoint when door/window open
holidayTemp = 12 -- Holiday temperature is defined here
comfortTemp = 19.5 -- Confort temp (in Manual mode)
autoTemp = 19 -- Automatic mode in Domoticz
file = io.open("C:\\flat\\cube\\"..os.date("%Y%m%d")..'.html', "a")
io.output(file)
io.write(os.date("%X - "))
events = ""
valves = "<p style='font-family:\"Courier New\"'>\n"..string.gsub("Name ID Mod Setp Temp % Bst Raw</br>\n"," "," ")
-- The following settings are related to the new features and require the manual creation of selector switches in Domoticz having Auto / Manual / Holiday / Boost modes
-- Id of the valve / Id of the domoticz selector switch created
idModeDomoticz = {}
idModeDomoticz["00145C63"] = "1150" -- ROOM1
idModeDomoticz["00145C7B"] = "1143" -- ROOM2
idModeDomoticz["00145C7E"] = "1146" -- ROOM3
idModeDomoticz["00145C83"] = "1147" -- ROOM4
idModeDomoticz["0013E81F"] = "1144" -- ROOM5
idModeDomoticz["00145C74"] = "1145" -- ROOM6
idModeDomoticz["00145CB0"] = "1151" -- ROOM7
-- Here is a mapping of the domoticz temp device created by the original cube Script : this mapping is needed here to make a comparison between the valve temp and domoticz temp, so that Domoticz is not updated if not needed
idTempDomoticz = {}
idTempDomoticz["145C63"] = "681" -- ROOM1
idTempDomoticz["145C7B"] = "691" -- ROOM2
idTempDomoticz["145C7E"] = "690" -- ROOM3
idTempDomoticz["145C83"] = "677" -- ROOM4
idTempDomoticz["13E81F"] = "556" -- ROOM5
idTempDomoticz["145C74"] = "685" -- ROOM6
idTempDomoticz["145CB0"] = "688" -- ROOM7
--json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")() -- uncomment if you're using Linux (comment next line)
json = (loadfile "C:\\Program Files (x86)\\Domoticz\\scripts\\lua\\JSON.lua")() -- uncomment if you're using Windows (comment previous line)
----------------------------------------
-- No changes required below this line -
----------------------------------------
package.loadlib("core.so", "*")
Basexx = require "basexx"
Socket = require "socket"
http = require "socket.http"
Rooms = {}
Devices = {}
Types = {}
Room_nums = {}
resultT, statuscodeT, contentT = http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=devices&filter=utility')
rT,eT = json:decode(resultT)
resultM, statuscodeM, contentM = http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=devices&filter=light')
rM,eM = json:decode(resultM)
resultW, statuscodeW, contentW = http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=devices&filter=temp')
rW,eW = json:decode(resultW)
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 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 ReadDomoticzThermostat(DID)
-- result, statuscode, content = http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=devices&filter=utility&used=true')
if rT.status == "OK" then
for k,v in pairs(rT.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 ReadDomoticzValve(DID)
-- result, statuscode, content = http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=devices&filter=utility&used=true')
if rT.status == "OK" then
for k,v in pairs(rT.result) do
if v.ID == '00'..DID then return v.Data,v.LastUpdate end
end
end
return 0, '2016-01-01 00:00:00' -- value to return if device was not found
end
function ReadDomoticzTemp(DID)
-- Retrieving the Domoticz ID from the local hash table
domoticzID = nil
for key, valeur in pairs(idTempDomoticz) do
if key == DID then domoticzID = valeur end
end
if rW.status == "OK" then
for k,v in pairs(rW.result) do
if v.idx == domoticzID then return string.format("%.1f", v.Temp),v.LastUpdate end
end
end
return 0, '2016-01-01 00:00:00' -- value to return if device was not found
end
function ReadDomoticzMode(DID)
if rM.status == "OK" then
for k,v in pairs(rM.result) do
if v.ID == '0'..DID then
if (v.LevelInt ==0) then smode="Off"
elseif (v.LevelInt ==10) then smode="Auto"
elseif (v.LevelInt ==20) then smode="Manual"
elseif (v.LevelInt ==30) then
smode="Holiday"
elseif (v.LevelInt ==40) then
--print('Domoticz Boost Mode found for '..DID..'| Level '..v.LevelInt..' | Triggered on '..v.LastUpdate )
events = events..('<p style="color:green;">Domoticz Boost Mode found for '..DID..'| Level '..v.LevelInt..' | Triggered on '..v.LastUpdate.."</p>\n" )
smode="Boost"
end
return smode,v.LevelInt,v.LastUpdate end
end
else
print(rM.status)
events = events..(rM.status.."</br>\n")
end
return 0, '2016-01-01 00:00:00' -- value to return if device was not found
end
function UpdateDomoticzValve(DID, valve_Max)
domoticzValve = ReadDomoticzValve(DID)
if domoticzValve ~= valve_Max..'%' then
print ("Domoticz Valve "..DID.." update from "..domoticzValve.." to "..valve_Max..'%')
--events = events..("Domoticz Valve "..DID.." update from "..domoticzValve.." to "..valve_Max..'%')
--http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=addlogmessage&message='..string.gsub('Domoticz valve for '..DID..' set to '..valve_Max,' ','%%20'))
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=udevice&hid='..MAX_ID..'&did='..DID..'&dunit=1&dtype=243&dsubtype=6&nvalue=0&svalue='..valve_Max)
end
end
function UpdateDomoticzTemperature(DID, value) -- Update Temp in Domoticz
domoticzTemp, LastUpdate = ReadDomoticzTemp(DID)
if(domoticzTemp ~= string.format("%.1f", value)) then
print ("Domoticz Temp "..DID.." update from "..domoticzTemp.." to "..value)
--events = events..("Domoticz Temp "..DID.." update from "..domoticzTemp.." to "..value.."</br>\n")
--http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=addlogmessage&message='..string.gsub('Domoticz temp for '..DID..' set to '..value,' ','%%20'))
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=udevice&hid='..MAX_ID..'&did='..DID..'&dunit=1&dtype=80&dsubtype=5&nvalue=0&svalue='..value)
end
end
function UpdateDomoticzAutoMode(DID, sMode)
-- Retrieving the Domoticz ID from the local hash table
id = nil
for key, valeur in pairs(idModeDomoticz) do
if key == '0'..DID then id = valeur end
end
if sMode == "Auto" then
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=switchlight&idx='..id..'&switchcmd=Set%20Level&level=10') --&hid='..MAX_ID..'&did='..DID..'&dunit=1&dtype=244&dsubtype=62&svalue=10')
elseif sMode == "Manual" then
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=switchlight&idx='..id..'&switchcmd=Set%20Level&level=20')
elseif sMode == "Holiday" then
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=switchlight&idx='..id..'&switchcmd=Set%20Level&level=30')
elseif sMode == "Boost" then
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=switchlight&idx='..id..'&switchcmd=Set%20Level&level=40')
--http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=switchlight&hid='..MAX_ID..'&did='..DID..'&dunit=1&dtype=244&dsubtype=62&svalue=20')
end
end
function SetpointSync(DID, devicename, setpoint_MAX, mode_MAX)
updateMax = 'false'
-- Checking Mode update in domoticz
mode_Domoticz, modeDomoticzInt, LastUpdate = ReadDomoticzMode(DID)
forceHolidayTemp = 'false'
forceAutoTemp = 'false'
forceComfortTemp = 'false'
isHoliday = (mode_MAX == "Manual" and setpoint_MAX < comfortTemp -2 and mode_Domoticz == "Holiday")
if(mode_MAX == "Manual" and setpoint_MAX < comfortTemp -2) then
mode_MAX = "Holiday"
end
if not isHoliday and mode_Domoticz == "Holiday" and (age(LastUpdate) < interval * 60) then
forceHolidayTemp = 'true'
setpoint_MAX = holidayTemp
updateMax = 'true'
end
if mode_Domoticz ~= mode_MAX then
if (age(LastUpdate) > interval * 60) or mode_MAX == 'Boost' then -- Domoticz mode value must be updated
UpdateDomoticzAutoMode(DID, mode_MAX)
print('Domoticz mode '..devicename..' set from '..mode_Domoticz..' to '..mode_MAX)
events = events..('Domoticz mode '..devicename..' set from '..mode_Domoticz..' to '..mode_MAX.."</br>\n")
mode_Domoticz = mode_MAX
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=addlogmessage&message='..string.gsub('Domoticz mode for '..devicename..' set to '..mode_MAX,' ','%%20'))
else -- MAX! mode must be updated
print(devicename..' mode update from domoticz : '..mode_Domoticz..' (before '..mode_MAX..')')
events = events..(devicename..' mode update from domoticz : '..mode_Domoticz..' (before '..mode_MAX..")</br>\n")
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=addlogmessage&message='..string.gsub('Max '..devicename..' mode update from domoticz '..mode_Domoticz..' instead of '..mode_MAX,' ','%%20'))
updateMax = 'true'
mode_MAX = mode_Domoticz
if(mode_MAX == "Auto") then forceAutoTemp = "true" end
if(mode_MAX == "Manual" and forceHolidayTemp == 'false') then
forceComfortTemp = "true"
setpoint_MAX = comfortTemp
end
end
end
-- Checking setpoint update in domoticz
setpoint_Domoticz, LastUpdate = ReadDomoticzThermostat(DID)
if(forceHolidayTemp == 'true' and setpoint_Domoticz ~= holidayTemp) then
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=udevice&hid='..MAX_ID..'&did='..DID..'&dunit=1&dtype=242&dsubtype=1&nvalue=0&svalue='..holidayTemp)
print('Domoticz setpoint '..devicename..' set to holiday '..holidayTemp..' degrees instead of '..setpoint_Domoticz)
events = events..('Domoticz setpoint '..devicename..' set to holiday '..holidayTemp..' degrees instead of '..setpoint_Domoticz.."</br>\n")
end
if(forceComfortTemp == 'true' and setpoint_Domoticz ~= comfortTemp) then
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=udevice&hid='..MAX_ID..'&did='..DID..'&dunit=1&dtype=242&dsubtype=1&nvalue=0&svalue='..comfortTemp)
print('Domoticz setpoint '..devicename..' set to comfort '..comfortTemp..' degrees instead of '..setpoint_Domoticz)
events = events..('Domoticz setpoint '..devicename..' set to comfort '..comfortTemp..' degrees instead of '..setpoint_Domoticz.."</br>\n")
end
if(forceAutoTemp == 'true' and setpoint_Domoticz ~= autoTemp) then
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=udevice&hid='..MAX_ID..'&did='..DID..'&dunit=1&dtype=242&dsubtype=1&nvalue=0&svalue='..autoTemp)
print('Domoticz setpoint '..devicename..' set to auto '..autoTemp..' degrees instead of '..setpoint_Domoticz)
events = events..('Domoticz setpoint '..devicename..' set to auto '..autoTemp..' degrees instead of '..setpoint_Domoticz.."</br>\n")
if setpoint_Max ~= autoTemp then
updateMax = 'true'
setpoint_Max = autoTemp
end
end
if tonumber(setpoint_Domoticz) ~= setpoint_MAX and forceHolidayTemp == 'false' and forceComfortTemp == 'false' and forceAutoTemp == 'false' then
if (age(LastUpdate) > interval * 60) and mode_MAX ~= 'Boost' then -- Domoticz thermostat value must be updated
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=udevice&hid='..MAX_ID..'&did='..DID..'&dunit=1&dtype=242&dsubtype=1&nvalue=0&svalue='..setpoint_MAX)
print('Domoticz setpoint '..devicename..' set to '..setpoint_MAX..' degrees instead of '..setpoint_Domoticz)
events = events..('Domoticz setpoint '..devicename..' set to '..setpoint_MAX..' degrees instead of '..setpoint_Domoticz.."</br>\n")
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=addlogmessage&message='..string.gsub('Max '..devicename..' setpoint update in domoticz '..setpoint_MAX..' instead of '..setpoint_Domoticz,' ','%%20'))
elseif mode_MAX ~= "Boost" then -- MAX! setpoint must be updated
print(devicename..' setpoint update from domoticz : '..setpoint_Domoticz..' instead of '..setpoint_MAX)
events = events..(devicename..' setpoint update from domoticz : '..setpoint_Domoticz..' instead of '..setpoint_MAX.."</br>\n")
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=addlogmessage&message='..string.gsub('Max '..devicename..' setpoint update from domoticz '..setpoint_Domoticz..' instead of '..setpoint_MAX,' ','%%20'))
updateMax = 'true'
setpoint_MAX = setpoint_Domoticz
elseif mode_MAX == 'Boost' then
updateMax = 'false'
print(devicename..' setpoint not updated from domoticz because Boost : '..setpoint_Domoticz..' wont replace '..setpoint_MAX)
events = events..(devicename..' setpoint not updated from domoticz because Boost : '..setpoint_Domoticz..' wont replace '..setpoint_MAX.."</br>\n")
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=addlogmessage&message='..string.gsub('Max '..devicename..' setpoint not updated from domoticz because Boost '..setpoint_Domoticz..' instead of '..setpoint_MAX,' ','%%20'))
end
end
-- Sending new values to Max! if needed
if updateMax == 'true' then
if (forceAutoTemp == 'true') then setpoint_MAX = 0 end --autoTemp
if (forceComfortTemp == 'true') then setpoint_MAX = comfortTemp end
MaxCmdSend(adr, room_num, string.gsub(mode_MAX,'Holiday','Manual'), setpoint_MAX,devicename)
end
--print( 'Debug : forceHolidayTemp '..forceHolidayTemp..' forceAutoTemp '..forceAutoTemp..' forceComfortTemp '..forceComfortTemp..' updateMax '..updateMax..' mode_MAX '..mode_MAX)
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
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=addlogmessage&message=MAX!%20configuration%20error!')
end
print("Found "..num_rooms.." rooms")
print("------------")
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
Types[adr] = dtype
end
end
function maxCmd_C(data)
-- print('C='..data)
end
function toBits(num)
-- returns a table of bits, least significant first.
local t={} -- will contain the bits
while num>0 do
rest=math.fmod(num,2)
t[#t+1]=rest
num=(num-rest)/2
end
return t
end
local hex2bin = {
["0"] = "0000",
["1"] = "0001",
["2"] = "0010",
["3"] = "0011",
["4"] = "0100",
["5"] = "0101",
["6"] = "0110",
["7"] = "0111",
["8"] = "1000",
["9"] = "1001",
["a"] = "1010",
["b"] = "1011",
["c"] = "1100",
["d"] = "1101",
["e"] = "1110",
["f"] = "1111"
}
function Hex2Bin(s)
local ret = ""
local i = 0
for i in string.gfind(s, ".") do
i = string.lower(i)
ret = ret..hex2bin[i]
end
return ret
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]
dtype = Types[adr]
if not name then name=adr end
valve_info = tonumber(hex:sub(13,14),16)
valve_bits = toBits(valve_info)
valve_bits_V2 = Hex2Bin(hex:sub(13,14))
batt = 0 --bit32.extract(valve_info,7,1)
mode = valve_bits[1] --bit32.extract(valve_info,0,2)
bst = valve_bits[2] --bit32.extract(valve_info,3,1)
--mode 1 = Manuel 0 = Auto
-- Boost + Manu : bst 1 et mode 1
--mode 1 + bst 1 = boost
--mode 1 + bst 0 = manual
--mode 0 + bst 0 = auto
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" else print(table.concat(toBits(valve_info)))
end
if (bst == nil) then
print("!!!!!!!! BST is nil !!!!!!!!!!!!!!!")
--events = events..('<p style="color:red"> BST is nil for : '..name..'</p>\n')
bst = 9
end
if (bst==1) then smode="Boost" end
if dtype == 3 then -- WallMountedThermostat
print("Wall Therm. "..name.." "..adr)
s = hex:sub(17,18)
setpoint = tonumber(s,16) / 2
if setpoint > 50 then setpoint = setpoint - 64 end
s = hex:sub(23,26)
temp = tonumber(s,16) / 10
if temp ~= 0 and temp < 5 then temp = temp + 25.5 end -- temporary solution for 2 digit hex temperature limitation
SetpointSync('0'..adr, name, setpoint,smode)
--ModeSync('0'..adr, name, setpoint,smode)
elseif dtype == 1 or dtype == 2 then -- Valve
print("Valve "..name.." "..adr)
s = hex:sub(15,16)
valve_pos = tonumber(s,16)
s = hex:sub(17,18)
setpoint = tonumber(s,16) / 2
if setpoint > 50 then setpoint = setpoint - 64 end
s = hex:sub(19,22)
temp = tonumber(s,16) / 10
print("Raw "..table.concat(valve_bits).." | "..valve_bits_V2 )
if (mode ~= nil) then print("Mode "..smode) end
print("Setpoint "..setpoint)
print("Temperature "..temp)
print("Valve "..valve_pos.."%")
if (bst ~= nil) then print("Boost "..bst) end
if (mode ~= nil) then valves = valves..string.gsub(string.format("%-11s ",name)," "," ")..adr.." "..string.gsub(string.format("%-7s ",smode)," "," ")..string.format("%04.1f", setpoint).." "..string.format("%04.1f", temp).." "..string.format("%02d", valve_pos).." "..bst.." "..table.concat(valve_bits).." | "..valve_bits_V2.."</br>\n"
end
if temp ~= 0 and temp < 5 then
print("Valve Hack : "..name.." has a temp of "..temp.." : applying a 25.5 offset")
temp = temp + 25.5 end -- temporary solution for 2 digit hex temperature limitation
-- Bug? when in holiday mode, the temp is not right
if temp ~= 0 and (temp <8 or temp > 30) then
print("Valve "..name.." has a temp of "..temp.." : bug or Holiday mode")
events = events..('<p style="color:red"> Valve '..name.." has a temp of "..temp.." : bug or Holiday mode</p>\n")
--mode = 2
--smode = "Holiday"
end
if temp ~= 0 then UpdateDomoticzValve(adr, valve_pos) end -- Update Valve in Domoticz
if not useWMT then -- Use valve for temp & setpoint
if temp ~= 0 then
UpdateDomoticzTemperature(adr, temp) -- Update Temp in Domoticz
end
if (mode ~= nil) then SetpointSync('0'..adr, name, setpoint,smode) end
end
elseif dtype == 4 then -- Door/window sensor
print("Door Sensor "..name.." "..adr)
--if mode == 2 then UpdateDomoticzAutoMode(adr, "On") else UpdateDomoticzAutoMode(adr, "Off") end
end
print("------------")
pos = pos + (data_len*2)
end
end
function MaxCmdSend(id, room, mode, setpoint,name)
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
if smode == 'AUTO' then
hex = "000440000000"..id..room.."00"
else
hex = "000440000000"..id..room..string.format("%x",bits)
end
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
print("Sending to valve "..name.." mode "..smode.." setpoint "..setpoint.." bits "..bits.." "..Hex2Bin(i))
events = events..("Sending to valve "..name.." mode "..smode.." setpoint "..setpoint.." bits "..bits.."</br>\n")
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=addlogmessage&message='..string.gsub("Max update valve "..name.." "..id.." "..smode.." setpoint "..setpoint,' ','%%20') )
end
--function MaxCmdSend(id, room, smode, setpoint, name)
-- -- Holiday and manual temperature are static
-- if smode == 'Manual' and setpoint ~= holidayTemp then
-- setpoint = comfortTemp
-- print(name.." update temp override for Manual mode : "..comfortTemp)
-- io.write(name.." update toverride for Manual mode : "..comfortTemp.."</br>\n")
-- elseif smode == 'Holiday' or (smode == 'Manual' and setpoint == holidayTemp) then
-- smode = 'Auto'
-- setpoint = holidayTemp
-- print(name.." update temp override for holiday mode : "..holidayTemp)
-- io.write(name.." update toverride for holiday mode : "..holidayTemp.."</br>\n")
-- end
--
-- if smode == 'Manual' or smode == 'Holiday' or smode == 'Auto' then
-- bits = setpoint * 2
-- -- No setpoint change when using the boost feature. Auto could also be untouched, depending of what we expect.
-- else
-- bits = 0
-- end
--
-- print("Sending to valve "..name.." mode "..smode.." setpoint "..setpoint)
-- io.write("Sending to valve "..name.." mode "..smode.." setpoint "..setpoint.."</br>\n")
-- http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=addlogmessage&message='..string.gsub("Max update valve "..name.." "..id.." "..smode.." setpoint "..setpoint,' ','%%20') )
-- if smode == 'Manual' then
-- bits = 64 + bits
-- elseif smode == 'Boost' then
-- bits = 192 + bits
-- elseif smode == 'Holiday' 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.."</br>\n")
-- if not i then
-- print("MAX TCP send failed - "..status)
-- io.write("MAX TCP send failed - "..status.."</br>\n")
-- http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=addlogmessage&message=MAX!%20send%20error!%20'..id)
-- return
-- end
--end
-----------------------
-- Main script start --
-----------------------
--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
print("MAX! dummy hardware not yet created, create it")
io.write("MAX! dummy hardware not yet created, create it</br>\n")
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=addhardware&htype=15&port=1&name=MAX!&enabled=true')
end
tcp = Socket.connect(MaxIP, MaxPort)
if not tcp then
print("Socket connect failed for "..MaxIP..':'..MaxPort)
io.write("Socket connect failed for "..MaxIP..':'..MaxPort.."</br>\n")
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
success,error = pcall(maxCmd_L,data)
if not success then
print("Exception : "..error)
io.write('<p style="color:red"> Exception : '..error..'</p>\n')
http.request('http://127.0.0.1:'..DomoticzPort..'/json.htm?type=command¶m=addlogmessage&message='..string.gsub('<span style="color:red">Max script exception '..error..'</span>',' ','%%20'))
end
break
end
end
minute = tonumber(os.date("%M"))
if(events ~= "" ) then --or ( minute >= 0 and minute < 5)
io.write(events)
io.write(valves)
io.write(os.date("</p>--> END RUN %X --</br>\n</br>\n"))
end
io.close(file)
tcp:close()