LogicMachine Forum
Control Nefit boiler - Printable Version

+- LogicMachine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8)
+--- Thread: Control Nefit boiler (/showthread.php?tid=6128)



Control Nefit boiler - gjniewenhuijse - 26.09.2025

I like to control a Nefit boiler that has an EMS protocol. Its not possible to control it directly so i inserted an EMS-ESP into my system.

Now i can get data from my system with this script
Code:
--[[
Nefit heat pump ems bus
https://bbqkees-electronics.nl/wiki/gateway/restful-api.html
https://docs.emsesp.org/Commands/
ems-esp/boiler                                        {"cmd":"heatingactivated", "data":"on"}        turn on heatingactivated in boiler
ems-esp/boiler/heatingactivated        {"data":"on"}                                                            turn on heatingactivated in boiler (equivalent to command above)
ems-esp/boiler                                        {"cmd":"dhw.disinfecting", "data":"on"}        turn on DHW disinfecting in boiler
--]]

https = require('ssl.https')
json = require('json')
ltn12 = require('ltn12')

iDebug = true
devIp = '192.168.x.xx' -- ems-esp.local
devUrl = 'http://'..devIp..'/api/'

function getData(iFunction)
  if iDebug then log(devUrl..iFunction) end
  res, code = https.request({
      url = devUrl..iFunction,
      method = 'GET'
  })
  if iDebug then
      log(code, res)
  end
  return code, res
end

function setData(iFunction, iData)
  if iDebug then log(devUrl..iFunction) end
  res, code = https.request({
      url = devUrl..iFunction,
      method = 'POST',
      headers = {["content-type"] = "application/json"},
      data = iData
      })
  if iDebug then
      log(code, res)
  end
  return code, res
end

-- get system info
--getData('system')

-- get boiler info - GET outputs current EMS device information in verbose
--getData('boiler/info')

-- get boiler values - GET outputs current EMS device information in short format
--getData('boiler/values')

-- get boiler - GET    same as values above
--getData('boiler')

-- get boiler commands - GET    lists the available command entities to call
--getData('boiler/commands')

-- get boiler entities -     GET    lists all enabled entities
--getData('boiler/entities')

-- get boiler dhw info
--getData('boiler/dhw/info')

-- get boiler entity heatingactive
--getData('boiler/heatingactive')

-- thermostaat streeftemperatuur
--getData('thermostat/seltemp')

-- dhw Laden
--getData('thermostat/dhw/charge')
setData('thermostat/dhw/charge', '{"value": true}') --curl -X POST http:///api/system/dhw/charge -H "Content-Type: application/json" -d '{"value": true}'

I also like to control the data with the setData function (last line). But i received an error 400. Whats wrong with my code?

Documentation can be found here: https://docs.emsesp.org/Commands/


RE: Control Nefit boiler - admin - 26.09.2025

You are missing Content-Length header for the POST request.
Code:
["Content-Length"] = #iData,

You should use json.encode instead of writing JSON manually to avoid potential errors.


RE: Control Nefit boiler - gjniewenhuijse - 26.09.2025

(26.09.2025, 12:58)admin Wrote: You are missing Content-Length header for the POST request.
Code:
["Content-Length"] = #iData,

You should use json.encode instead of writing JSON manually to avoid potential errors.

Like this (but with same error)?
Code:
setData('thermostat/dhw/charge', {value = true})


function setData(iFunction, iData)
  if iDebug then log(devUrl..iFunction) end
  res, code = https.request({
      url = devUrl..iFunction,
      method = 'POST',
      headers = {["Content-Type"] = "application/json",
                           ["Content-Length"] = #iData
                          },
      data = json.encode(iData)
      })
  if iDebug then
      log(code, res)
  end
  return code, res
end



RE: Control Nefit boiler - admin - 26.09.2025

Try this:
Code:
setData('thermostat/dhw/charge', {value = true})

function setData(iFunction, iData)
  local data = json.encode(iData)
  if iDebug then log(devUrl..iFunction) end
  res, code = https.request({
    url = devUrl..iFunction,
    method = 'POST',
    headers = {
      ["Content-Type"] = "application/json",
      ["Content-Length"] = #data
    },
    data = data
  })
  if iDebug then log(code, res) end
  return code, res
end



RE: Control Nefit boiler - gjniewenhuijse - 26.09.2025

(26.09.2025, 13:13)admin Wrote: Try this:
Code:
setData('thermostat/dhw/charge', {value = true})

function setData(iFunction, iData)
  local data = json.encode(iData)
  if iDebug then log(devUrl..iFunction) end
  res, code = https.request({
    url = devUrl..iFunction,
    method = 'POST',
    headers = {
      ["Content-Type"] = "application/json",
      ["Content-Length"] = #data
    },
    data = data
  })
  if iDebug then log(code, res) end
  return code, res
end

Other error:
* arg: 1
  * string: closed
* arg: 2
  * nil


RE: Control Nefit boiler - admin - 26.09.2025

Are you sure that URL endpoint and parameters are correct?


RE: Control Nefit boiler - gjniewenhuijse - 26.09.2025

(26.09.2025, 13:27)admin Wrote: Are you sure that URL endpoint and parameters are correct?

getData for that endpoint works and the result is:
* arg: 1
  * number: 200
* arg: 2
  * string: {"name":"charge","fullname":"dhw Laden","circuit":"dhw","bool":false,"index":0,"value":"uit","type":"boolean","readable":true,"writeable":true,"visible":true}


RE: Control Nefit boiler - admin - 26.09.2025

Send a request to http://<hostname>/api/<device>/commands to get a list of available commands. Do you have access token enabled in Security->Manage Users?


RE: Control Nefit boiler - gjniewenhuijse - 26.09.2025

(26.09.2025, 13:39)admin Wrote: Send a request to http://<hostname>/api/<device>/commands to get a list of available commands. Do you have access token enabled in Security->Manage Users?

Access token is disabled

In the output i need the command:  ,"dhw[n].charge":"Laden"

Output:
{"info":"lijst van alle waardes","values":"list all values","commands":"lijst van alle commando's","entities":"lijst van alle entiteiten","[hc<n>.]boost":"boost mode","[hc<n>.]boosttime":"boost time","[hc<n>.]comforttemp":"Comforttemperatuur","[hc<n>.]control":"Afstandsbedieding","[hc<n>.]controlmode":"Comtrolemodus","[hc<n>.]cooloffdelay":"cooling off delay","[hc<n>.]coolondelay":"cooling on delay","[hc<n>.]coolstart":"cooling starttemp","[hc<n>.]cooltemp":"Temperatuur koelbedrijf","[hc<n>.]designtemp":"Ontwerptemperatuur","[hc<n>.]dewoffset":"Offset dauwpunt","[hc<n>.]dhwprio":"Prioriteit warm water","[hc<n>.]ecotemp":"Temperatuur eco","[hc<n>.]fastheatup":"Snel opwarmen","[hc<n>.]heatingtype":"Verwarmingstype","[hc<n>.]heatoffdelay":"heat-off delay","[hc<n>.]heatondelay":"heat-on delay","[hc<n>.]hpcooling":"WP koelbedrijf","[hc<n>.]hpminflowtemp":"Minimale aanvoertemperatuur WP","[hc<n>.]hpmode":"Modus warmtepomp","[hc<n>.]hpoperatingmode":"Bedrijfsmodus warmtepomp","[hc<n>.]instantstart":"instant start","[hc<n>.]intoffset":"Offset interne temperatuur","[hc<n>.]manualtemp":"Temperatuur handmatig","[hc<n>.]maxflowtemp":"Maximale aanvoertemperatuur","[hc<n>.]minflowtemp":"Minimale aanvoertemperatuur","[hc<n>.]mode":"Modus","[hc<n>.]nofrostmode":"Vorstbeveiligingsmodus","[hc<n>.]nofrosttemp":"Temperatuur vorstbeveiliging","[hc<n>.]noreducetemp":"Reduceermodus onderbreken onder","[hc<n>.]offsettemp":"Temperatuur offset","[hc<n>.]program":"Programma","[hc<n>.]redthreshold":"reduction threshold","[hc<n>.]reducemode":"Gereduceerde modus","[hc<n>.]reducetemp":"Onderste afschakeltemperatuur","[hc<n>.]remotehum":"room humidity from remote","[hc<n>.]remotetemp":"Ruimtetemperatuur van afstandsbediening","[hc<n>.]roominflfactor":"Factor ruimteinvloed","[hc<n>.]roominfluence":"Ruimteinvloed","[hc<n>.]roomtempdiff":"Verschiltemperatuur kamertemp","[hc<n>.]seltemp":"Streeftemperatuur kamer","[hc<n>.]solarinfl":"solar influence","[hc<n>.]summersetmode":"Instelling zomerbedrijf","[hc<n>.]summertemp":"Zomertemperatuur","[hc<n>.]switchonoptimization":"Inschakeloptimalisering","[hc<n>.]switchprogmode":"switch program mode","[hc<n>.]tempautotemp":"Streeftemperatuur automodus tijdelijk","absent":"absent","building":"Type gebouw","damping":"Demping buitentemperatuur","datetime":"Datum/Tijd","delayboiler":"Vertragingsoptie","dhw[n].charge":"Laden","dhw[n].chargeduration":"Laadtijd","dhw[n].circmode":"Modus circulatiepomp","dhw[n].dailyheating":"Dagelijks opwarmen","dhw[n].dailyheattime":"Tijd dagelijkse opwarming","dhw[n].disinfectday":"Desinfectiedag","dhw[n].disinfecting":"Desinfectie","dhw[n].disinfecttime":"Desinfectietijd","dhw[n].mode":"Modus","dhw[n].settemp":"Streeftemperatuut","dhw[n].settemplow":"Onderste streeftemperatuur","electricfactor":"Energiefactor electrisch","energycostratio":"Energiekostenratio","fossilefactor":"Energiefactor fossiele brandstof","hybridstrategy":"Hybride strategie","intoffset":"Offset interne temperatuur","minexttemp":"Min. buitentemperatuur","pvenabledhw":"Verhoging WW activeren","pvlowercool":"Verlagen koeling met PV activeren","pvraiseheat":"Verwarmen met PV activeren","solar":"solar","switchovertemp":"Schakeltemperatuur buitentemperatuur","tempdiffboiler":"Verschiltemperatuuroptie"}


RE: Control Nefit boiler - admin - 26.09.2025

Try sending true instead of {value = true}. If this does not help then you should ask this question here: https://github.com/emsesp/EMS-ESP32/discussions


RE: Control Nefit boiler - maxmp - 26.09.2025

Fyi: Theben has an Opentherm to KNX gateway and there is an Opentherm to EMS converter. I have this setup and it works very well.


RE: Control Nefit boiler - gjniewenhuijse - 29.09.2025

(26.09.2025, 21:00)maxmp Wrote: Fyi: Theben has an Opentherm to KNX gateway and there is an Opentherm to EMS converter. I have this setup and it works very well.

Which Openterm to EMS converter do you use?

And can you control the DHW charge? (Extra warm water function)