Heltun thermostats. Expirence and problems

Good afternoon!
Three month ago, 6 Heltun Thermostats obtained.
It placed in each heat zone. Mode of using - control air temperature, and check limitations of floor (water heating system).

Each thermostat connected to controller, controller connected to valves and heating device.
And… all thermostats controlled by VeraPlus.

On board:
Air temperature sensor, floor temperature sensor, humidity sensor and lighting sensor (all of them - in one device)

How it works with Vera:
Not very vell

  1. Thermostat can support modes: Comfort, Eco, Dry, Manual and Timer. Vera - not
  2. Secondary sensor not recognised well. (but it can be used in DataMine - it works)
  3. a lot of Poll requests are lost. I don’t know, why - may be Vera not good, may be Heltun
  4. Device can support S2 security, Vera not
  5. OTA supported by device, but Vera…

My task:
Heat my house at night time (when possible). Use night tarif (when possible, do not avoid comfort)
Tariffs:
Day: 6,08₽
Night: 2,25₽

This script - make comforable setting in Home/Night mode
Decrease temperature at Vacation mode and heat house only at night - in Away mode

With checking dew

-- read house mode
local mode = luup.attr_get "Mode"
local CurrHumid=0
local CurrTemp=0
local CurrTempS
local CurrHumidS
local Humid=0
local Temp=0
local MinTemp=0
local MaxallowedTemp=21
local MinallowedTemp=9
local NightTemp=0

local HThermDayTemp
local HThermNightTemp


function ConfigureThermos(nodnostr,devno)
   local nodno=tonumber(nodnostr)
-- set temperature calendar for each thermostat
-- morning, day, evening, night
  for i = 56, 80, 4 do
      TempSet(nodno, i, HThermDayTemp)
      TempSet(nodno, i+1, HThermDayTemp)
      TempSet(nodno, i+2, HThermDayTemp)
      TempSet(nodno, i+3, HThermNightTemp)
   end
   luup.call_action("urn:upnp-org:serviceId:SwitchPower1", "SetTarget", {newTargetValue = "1"}, devno)
end

function TempSet(dev, prm, temp)
   local Nod = string.format("%d",dev) 
-- 112 4 - configuration set, after it - parameter number, 2 - paramter length in byttes , 0 - first byte, next - second byte
--   luup.log(string.format("---------------------------------------------112 4 %g 2 0 %g",prm,temp*10))
   local Dat = string.format("112 4 %d 2 0 %d",prm,math.floor(temp*10))
   luup.call_action('urn:micasaverde-com:serviceId:ZWaveNetwork1','SendData',{Node=Nod, Data=Dat},1)
end

-- check all zones t and humidity 
for deviceNo,d in pairs(luup.devices) do
   if d.id ~= "" then
      if d.device_type=='urn:schemas-upnp-org:device:HVAC_ZoneThermostat:1' then
         CurrTempS=luup.variable_get('urn:upnp-org:serviceId:TemperatureSensor1','CurrentTemperature',deviceNo)
         if CurrTempS==nil then
             CurrTemp=0
         else
             CurrTemp=tonumber(CurrTempS)
             if Temp<CurrTemp then
                Temp=CurrTemp
             end
         end
      end

--      luup.log(string.format('----------------------------DID: %s', d.id))

      if d.device_type=='urn:schemas-micasaverde-com:device:HumiditySensor:1' then
         CurrHumidS=luup.variable_get('urn:micasaverde-com:serviceId:HumiditySensor1','CurrentLevel',deviceNo)
         if CurrHumidS == nil then
            CurrHumid=0
            CurrHumidS = 'nil'
         else
             CurrHumid=tonumber(CurrHumidS)
             if Humid<CurrHumid then
                Humid=CurrHumid
             end
         end
      end
   end
end
-- Max allowed humidity - 60%, not 100. Better less, then greater
-- Shift humidity value
Humid = Humid+40
-- Calculate dew point 
MinTemp=Temp-((1-(Humid/100))/0.05) 
luup.log(string.format('----------------------------------- Max humid: %d  Max Temp:%g Min Temp:%g', Humid, Temp, MinTemp))
if MinTemp<MinallowedTemp then
   MinTemp=MinallowedTemp
end
if MinTemp>MaxallowedTemp then
   MinTemp=MaxallowedTemp
end
---------------------
-- Modes: 1 Home, 2 - Away, 3 - Night, 4 - Vacation
-- Calculate comfort temp for modes, except vacation
-- Calculate safe temp for Vacation

-- Home - comfort
if(mode=="1") then
    HThermDayTemp=MaxallowedTemp
    HThermNightTemp=MaxallowedTemp+2
end
-- Away - nightmost heating
if(mode=="2") then 
    HThermDayTemp=MinTemp
    HThermNightTemp=MaxallowedTemp+2
end
-- Night - as day
if(mode=="3") then
    HThermDayTemp=MaxallowedTemp
    HThermNightTemp=MaxallowedTemp+2
end
-- Vacation. Do not allow dew. 
if(mode=="4") then
    HThermDayTemp=MinTemp
    HThermNightTemp=MinTemp+3
end

-- fill Thermostat id's and reprogram it.
for deviceNo,d in pairs(luup.devices) do
   if d.id ~= "" then
      if d.device_type=='urn:schemas-upnp-org:device:HVAC_ZoneThermostat:1' then
         ConfigureThermos(d.id, deviceNo)
      end
   end
end

How it works:

  1. Switch thermostats to “Timer” - Vera does not support this, but… Thermostat can be programmed to react on “Basic_set”. Vera can’t send Basic_set directly, but workaround is:
    luup.call_action(“urn:upnp-org:serviceId:SwitchPower1”, “SetTarget”, {newTargetValue = “1”}, devno)

  2. Thermostat can be programmed by configuration parameters.
    Morning t, Day t, Evening t and night t.
    There are no way to set parameter by high-level LUUP.
    Direct Command 112 4 used to reprogram thermostats.

  3. In normal modes, schedule script for two times per day. In vacation - every 2 or 4 hour, check dew every time.

  4. Pot call of procedure to event “Humidity > 61%” - you don’t need a black mold on the walls.

Hello! Did you fix problems with Heltun thermostat? I have very unstable connection between Vera and Heltun thermostat and dont know how to fix that :frowning:

No.
And only Vera have problem with it. Z-Wave.me dongle works well.

But… workarounded. Not only Vera have bugs.

  1. Heltun devices with FW 1.0 have a bug. When light level ==0, Z-Wave network can be flooded by information about light level. Every 1 second. When reported to tech support, they immediately sent an updated OTA FW
  2. In timer mode, thermostat do not report SetPoint, if setpoint changed, when day periods switched.
    Fixed in FW 1.2

Workaround:
Disable poll. Set poll interval to 0. Watch ComnmFailure variable in script by variable_watch or timer, send something to device.
For example - luup.call_action(“urn:upnp-org:serviceId:SwitchPower1”, “SetTarget”, {newTargetValue = “1”}, devno) (see script at top)

This is same problem, like Philio PAN16

P.S. Heltun Tech support is in Yerevan, they can talk English, Armenian, Russian, at least :slight_smile:

If you can turn their attention to this problem, it will be better. Not as good as Vera would fix the problem, but better anyway.

The distance between Kharkov and Yerevan is so great that the chance of a joint solution to the problem with Ezlo and Heltun tends to zero. :slight_smile:

Problem is:
Thermostat is 217, additional sensors (ligting, humidity, soil temperature - 218, 219, 220)

08      09/24/19 11:14:24.107   JobHandler_LuaUPnP::HandleActionRequest device: 217 service: urn:micasaverde-com:serviceId:HaDevice1 action: Poll <0x727d6520>
08      09/24/19 11:14:24.107   JobHandler_LuaUPnP::HandleActionRequest argument id=lu_action <0x727d6520>
08      09/24/19 11:14:24.108   JobHandler_LuaUPnP::HandleActionRequest argument serviceId=urn:micasaverde-com:serviceId:HaDevice1 <0x727d6520>
08      09/24/19 11:14:24.108   JobHandler_LuaUPnP::HandleActionRequest argument action=Poll <0x727d6520>
08      09/24/19 11:14:24.108   JobHandler_LuaUPnP::HandleActionRequest argument DeviceNum=217 <0x727d6520>
08      09/24/19 11:14:24.108   JobHandler_LuaUPnP::HandleActionRequest argument rand=0.7426035906500705 <0x727d6520>
...
06      09/24/19 11:14:33.931   Device_Variable::m_szValue_set device: 217 service: urn:micasaverde-com:serviceId:GenericSensor1 variable: CurrentLevel was: 24.0 now: 24.0 #hooks: 1 upnp: 0 skip: 0 v:0x10667b0/NONE duplicate:1 <0x765d6520>
02      09/24/19 11:14:36.286   ZWJob_PollNode::ReceivedFrame HandlePollUpdate failed job job#1124 :pollnode_sms2 #48 dev:217 (0x151b260) N:48 P:20 S:5 Id: 1124 got after 1 seconds FUNC_ID_APPLICATION_COMMAND_HANDLER node info for 48 status 0 data 0xa 0x0 (\n#) <0x765d6520>
02      09/24/19 11:14:58.151   ZWaveSerial::GetFrame 0x75dd5c98 timed out now 0 m_listGetFramePending 0 <0x75dd6520>
02      09/24/19 11:14:58.151   ZWaveJobHandler::SendDataAbort got m_iFrameID 0 <0x75dd6520>
02      09/24/19 11:14:58.152   ZWJob_PollNode::ReturnMessageNotReceived -end- job job#1124 :pollnode_sms2 #48 dev:217 (0x151b260) N:48 P:20 S:5 Id: 1124 node 48 didn't reply iOK 0 iBadTx 0 iNoReply 1 Abort returned m_iFrameID 0 <0x75dd6520>
02      09/24/19 11:14:58.152   ZWJob_PollNode::PollFailed job job#1124 :pollnode_sms2 #48 dev:217 (0x151b260) N:48 P:20 S:5 Id: 1124 node 48 battery 0 notlist:0 <0x75dd6520>
06      09/24/19 11:14:58.153   Device_Variable::m_szValue_set device: 217 service: urn:micasaverde-com:serviceId:ZWaveNetwork1 variable: ConsecutivePollFails was: 20 now: 21 #hooks: 0 upnp: 0 skip: 0 v:(nil)/NONE duplicate:0 <0x75dd6520>
02      09/24/19 11:14:58.164   Device_Basic::AddPoll 217 poll list full, deleting old one <0x75dd6520>
06      09/24/19 11:14:58.165   Device_Variable::m_szValue_set device: 217 service: urn:micasaverde-com:serviceId:HaDevice1 variable: PollRatings was: 0.40 now: 0.40 #hooks: 0 upnp: 0 skip: 0 v:(nil)/NONE duplicate:1 <0x75dd6520>

What happened:

  1. Poll request.
  2. All data reported by thermostat
  3. Vera market this poll as FAILED
    :face_with_symbols_over_mouth:

Is that problem with polling fixed in newest firmware (7.30)?
Probably, I need to update my device.

Vera support team, please let us know, are you planning to add Heltun thermostats in the newest firmware?

Unknown yet.
My Vera firmware - 1.7.4453. It’s a latest firmware.

In 7.31 - NOT.
No changes.

Update FW to 1.2 (not by Vera, OTA can’t be performed by Vera), set poll to 0.

  1. New formware from Heltun - 1.3. Changelist - uknown
    No changes in polling

  2. Vera cannot implement correctly secondary sensor (external sensor of floor temperarure), AKA soil temperature
    Because secondary sensor not a TempertureSensor, it a level sensor.
    Created slave-device with name of not initialized variable - is it, but CurrentLevel variable not transferred to slave.

Workaround is:

  1. Update name of device
  2. Change device type from GenericSensor to TemperatureSensor
    Advanced → device_file → D_TemperatureSensor1.xml
    Advanced → device_json → D_TemperatureSensor1.json

add this code to Lua startup

deviceslaves={}
local Manuf
local CurrentTemperature
local masterdev

for deviceNo,d in pairs(luup.devices) do
   if d.id ~= "" then
      -- Check for T sensors
      if d.device_type=='urn:schemas-micasaverde-com:device:TemperatureSensor:1' then
         masterdev=d.device_num_parent or 0
         -- Only slaves of thermostats
         if luup.devices[masterdev].device_type =='urn:schemas-upnp-org:device:HVAC_ZoneThermostat:1' then
             Manuf=luup.variable_get('urn:micasaverde-com:serviceId:ZWaveDevice1','ManufacturerInfo',masterdev) or ''
            -- only slaves of Heltun thermostats
	     if Manuf=='836,3,1' then
                deviceslaves[masterdev]=deviceNo
                CurrentTemperature=luup.variable_get('urn:micasaverde-com:serviceId:GenericSensor1','CurrentLevel',masterdev) or 0
                -- init
                luup.variable_set( 'urn:upnp-org:serviceId:TemperatureSensor1', 'CurrentTemperature', CurrentTemperature, deviceNo)
                luup.variable_watch("updateHeltunTemperatureData",  'urn:micasaverde-com:serviceId:GenericSensor1', 'CurrentLevel', masterdev)
             end
         end
      end
   end
end

function updateHeltunTemperatureData(dev_id, service, variable, oldValue, newValue)
    local slavedev=deviceslaves[dev_id]
    if tonumber(oldValue) ~= tonumber(newValue) then
        luup.variable_set( 'urn:upnp-org:serviceId:TemperatureSensor1', 'CurrentTemperature', newValue, slavedev)
    end
end

Done.