ELV Max! Heating control system

For heating/cooling related questions in Domoticz

Moderator: leecollings

User avatar
blackdog65
Posts: 311
Joined: Tuesday 17 June 2014 18:25
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Norfolk, UK
Contact:

Re: ELV Max! Heating control system

Post 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
CubieTruck Master
RasPi slaves
Aeon Labs Z-Stick, multi sensor
Fibaro Dimmers, relays, Universal sensors
EQ3 MAX!
TKB Sockets
RFXCOM
LightwaveRF sockets, switches, relays, doorbell
MySensors
ESPEasy ESP8266-12E
User avatar
Westcott
Posts: 423
Joined: Tuesday 09 December 2014 17:04
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: UK - Glos
Contact:

Re: ELV Max! Heating control system

Post by Westcott »

Hi Sean,

If I can see the offending Lua, I'll suggest a mod.
Zwave - Sigma Z+ stick, Fibaro, Horstmann, Neo Coolcam, EUROtronic
RFlink - IR detectors and temperatures
Wifi - YeeLights, ESP32s, Anoop sockets
Zigbee - lots with zigbee2mqtt and ZbBridge
Skippiemanz
Posts: 230
Joined: Sunday 14 July 2013 20:21
Target OS: Linux
Domoticz version: 4.10233
Location: Alkmaar, The Netherlands
Contact:

Re: ELV Max! Heating control system

Post 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
User avatar
blackdog65
Posts: 311
Joined: Tuesday 17 June 2014 18:25
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Norfolk, UK
Contact:

Re: ELV Max! Heating control system

Post 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
CubieTruck Master
RasPi slaves
Aeon Labs Z-Stick, multi sensor
Fibaro Dimmers, relays, Universal sensors
EQ3 MAX!
TKB Sockets
RFXCOM
LightwaveRF sockets, switches, relays, doorbell
MySensors
ESPEasy ESP8266-12E
User avatar
Westcott
Posts: 423
Joined: Tuesday 09 December 2014 17:04
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: UK - Glos
Contact:

Re: ELV Max! Heating control system

Post 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?
Last edited by Westcott on Wednesday 02 November 2016 11:59, edited 1 time in total.
Zwave - Sigma Z+ stick, Fibaro, Horstmann, Neo Coolcam, EUROtronic
RFlink - IR detectors and temperatures
Wifi - YeeLights, ESP32s, Anoop sockets
Zigbee - lots with zigbee2mqtt and ZbBridge
mvzut
Posts: 443
Joined: Thursday 12 November 2015 10:55
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: The Netherlands
Contact:

Re: ELV Max! Heating control system

Post 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.
Raspberry Pi 4 - RFXtrx433 - CC2531 Zigbee - Opentherm Gateway - P1 smart meter - Netatmo - Philips Hue - ELV Max! - ESP8266 DIY water meter - 6 x Sonos - 4 x IP cameras - Wall mounted tablet + Dashticz - Google Home integration - MANY switches/sensors
User avatar
blackdog65
Posts: 311
Joined: Tuesday 17 June 2014 18:25
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Norfolk, UK
Contact:

Re: ELV Max! Heating control system

Post 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
CubieTruck Master
RasPi slaves
Aeon Labs Z-Stick, multi sensor
Fibaro Dimmers, relays, Universal sensors
EQ3 MAX!
TKB Sockets
RFXCOM
LightwaveRF sockets, switches, relays, doorbell
MySensors
ESPEasy ESP8266-12E
jmbjmbjmb
Posts: 48
Joined: Monday 25 January 2016 10:41
Target OS: -
Domoticz version:
Contact:

Re: ELV Max! Heating control system

Post 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
User avatar
blackdog65
Posts: 311
Joined: Tuesday 17 June 2014 18:25
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Norfolk, UK
Contact:

Re: ELV Max! Heating control system

Post by blackdog65 »

latest scrip_time_max.lua has a variable for with/without stat
:D
CubieTruck Master
RasPi slaves
Aeon Labs Z-Stick, multi sensor
Fibaro Dimmers, relays, Universal sensors
EQ3 MAX!
TKB Sockets
RFXCOM
LightwaveRF sockets, switches, relays, doorbell
MySensors
ESPEasy ESP8266-12E
jmbjmbjmb
Posts: 48
Joined: Monday 25 January 2016 10:41
Target OS: -
Domoticz version:
Contact:

Re: ELV Max! Heating control system

Post 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 ?
User avatar
blackdog65
Posts: 311
Joined: Tuesday 17 June 2014 18:25
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Norfolk, UK
Contact:

Re: ELV Max! Heating control system

Post by blackdog65 »

I'd suggest "Salon1-Rad" and "Salon2-Rad"
Although that sounds like you have 2 salons :)
CubieTruck Master
RasPi slaves
Aeon Labs Z-Stick, multi sensor
Fibaro Dimmers, relays, Universal sensors
EQ3 MAX!
TKB Sockets
RFXCOM
LightwaveRF sockets, switches, relays, doorbell
MySensors
ESPEasy ESP8266-12E
jmbjmbjmb
Posts: 48
Joined: Monday 25 January 2016 10:41
Target OS: -
Domoticz version:
Contact:

Re: ELV Max! Heating control system

Post 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]: ?
Skippiemanz
Posts: 230
Joined: Sunday 14 July 2013 20:21
Target OS: Linux
Domoticz version: 4.10233
Location: Alkmaar, The Netherlands
Contact:

Re: ELV Max! Heating control system

Post by Skippiemanz »

Try SalonRue-Rad and SalonJardin-Rad
jmbjmbjmb
Posts: 48
Joined: Monday 25 January 2016 10:41
Target OS: -
Domoticz version:
Contact:

Re: ELV Max! Heating control system

Post 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]: ?
Skippiemanz
Posts: 230
Joined: Sunday 14 July 2013 20:21
Target OS: Linux
Domoticz version: 4.10233
Location: Alkmaar, The Netherlands
Contact:

Re: ELV Max! Heating control system

Post by Skippiemanz »

Can you try alienor-room, cuisine-room and so on?
jmbjmbjmb
Posts: 48
Joined: Monday 25 January 2016 10:41
Target OS: -
Domoticz version:
Contact:

Re: ELV Max! Heating control system

Post 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]: ?
jmbjmbjmb
Posts: 48
Joined: Monday 25 January 2016 10:41
Target OS: -
Domoticz version:
Contact:

Re: ELV Max! Heating control system

Post 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.
jmbjmbjmb
Posts: 48
Joined: Monday 25 January 2016 10:41
Target OS: -
Domoticz version:
Contact:

Re: ELV Max! Heating control system

Post by jmbjmbjmb »

Found the issue. I had lua 5.1 which does not have bit32.
User avatar
blackdog65
Posts: 311
Joined: Tuesday 17 June 2014 18:25
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Norfolk, UK
Contact:

Re: ELV Max! Heating control system

Post by blackdog65 »

:lol: @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! :shock:
CubieTruck Master
RasPi slaves
Aeon Labs Z-Stick, multi sensor
Fibaro Dimmers, relays, Universal sensors
EQ3 MAX!
TKB Sockets
RFXCOM
LightwaveRF sockets, switches, relays, doorbell
MySensors
ESPEasy ESP8266-12E
User avatar
blackdog65
Posts: 311
Joined: Tuesday 17 June 2014 18:25
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Norfolk, UK
Contact:

Re: ELV Max! Heating control system

Post 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== 
CubieTruck Master
RasPi slaves
Aeon Labs Z-Stick, multi sensor
Fibaro Dimmers, relays, Universal sensors
EQ3 MAX!
TKB Sockets
RFXCOM
LightwaveRF sockets, switches, relays, doorbell
MySensors
ESPEasy ESP8266-12E
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest