This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Waterkotte Ecotouch Heatpump
#1
Hi @all,

I want to connect my Waterkotte Ecotouch heatpump to LM/W4k. I have a working .php script what is running on my Raspberry. This script I want to transfer to LM.

To start with: My goal is to read "TEMPERATURE_OUTSIDE" and write it to a group address and write "ENABLE_HEATING" from a group address. 

Is this possible? Has anybody an idea how to start?

Many thanks for your help!

Best Regards
Steffen

Attached Files
.zip   Waterkotte.zip (Size: 7.61 KB / Downloads: 6)
Reply
#2
Try running this code and post what you get in Logs. Change ip, user and pwd variables as needed.
Code:
http = require('socket.http')

ip = '192.168.178.100' -- ip address of Waterkotte heat pump
user = 'XXX' -- username of web interface
pwd = 'XXX' -- password of web interface

url = 'http://' .. ip .. '/cgi/login?username=' .. user .. '&password=' .. pwd

res, code = http.request(url)

log('login request', res, code)

if res and code == 200 then
  token = res:match('%x+')

  log('token', token)

  if type(token) == 'string' and #token == 32 then
    storage.set('ecotouch-token', token)
  end
end

if token then
  url = 'http://' .. ip .. '/cgi/readTags?n=1&t1=A1'

  res, code = http.request({
    url = url,
    headers = {
      ['Cookie'] = 'IDALToken=' .. token
    }
  })

  log('read request', res, code)
end
Reply
#3
@admin: Many thanks for your help.

I getting a login failure, here is the log:

Code:
Waterkotte 07.03.2022 16:22:21
* arg: 1
  * string: login request
* arg: 2
  * string: 1
#S_OK
IDALToken=d98d4aa1b188273a90c0440da3f3f9d0
* arg: 3
  * number: 200
Waterkotte 07.03.2022 16:22:21
* arg: 1
  * string: token
* arg: 2
  * string: 1
Waterkotte 07.03.2022 16:22:21
* arg: 1
  * string: read request
* arg: 2
  * string: #E_NEED_LOGIN

* arg: 3
  * number: 500

If I do the steps manual via Firefox browser:
1.) 
Code:
http://192.168.XXX.XX/cgi/login?username=XXX&password=XXX
[url=http://192.168.178.35/cgi/readTags?n=1&t1=A1][/url]

2.) 
Code:
http://192.168.XXX.XX/cgi/readTags?n=1&t1=A1

the return is: 
Code:
#A1    S_OK
192    80


The failure "E_NEED_LOGIN" I getting also in the browser when I don't do step 1 before step 2.
Reply
#4
Change line 14 to this and try again:
Code:
token = res:match('IDALToken=(%x+)')
Reply
#5
@admin: Many thanks, now the login works successful!

Code:
Waterkotte 08.03.2022 10:01:43
* arg: 1
  * string: login request
* arg: 2
  * string: 1
#S_OK
IDALToken=d09570725af35fbaf13ba699ed6c2a0e
* arg: 3
  * number: 200
Waterkotte 08.03.2022 10:01:43
* arg: 1
  * string: token
* arg: 2
  * string: d09570725af35fbaf13ba699ed6c2a0e
Waterkotte 08.03.2022 10:01:43
* arg: 1
  * string: read request
* arg: 2
  * string: #A19    S_OK
192    363

* arg: 3
  * number: 200

„363“ is the value I want to parse and write it to a group address. 

@admin: Do you have an idea how to do that?
Reply
#6
Add after log('read request', res, code), if it works then you can replace log(value) with grp.checkwrite or grp.checkupdate.
Code:
value = res:match('S_OK%s+%d+%s+(%d+)')
if value then
  value = tonumber(value)
  log(value)
end
Reply
#7
@admin: Many thanks again for your big help! Highly appreciated! 

I made two script sets out of it. 

The first one is to read the actual values I'm interested in:

Code:
http = require('socket.http')

ip = 'xxx' -- ip address of Waterkotte heat pump
user = 'xxx' -- username of web interface
pwd = 'xxx' -- password of web interface

url = 'http://' .. ip .. '/cgi/login?username=' .. user .. '&password=' .. pwd

res, code = http.request(url)

log('login request', res, code)

if res and code == 200 then
  token = res:match('IDALToken=(%x+)')

  log('token', token)

  if type(token) == 'string' and #token == 32 then
    storage.set('ecotouch-token', token)
  end
end

-- Read actual hot water temperature ****************************
if token then
  url = 'http://' .. ip .. '/cgi/readTags?n=1&t1=A19'

  res, code = http.request({
    url = url,
    headers = {
      ['Cookie'] = 'IDALToken=' .. token
    }
  })

  log('read request', res, code)
   
value = res:match('S_OK%s+%d+%s+(%d+)')
   if value then
      value = tonumber(value)
   -- log(value)
      grp.checkupdate('46/1/1', value/10)

   end
end

os.sleep(1)     


-- Read actual source in temperature ****************************

if token then
  url = 'http://' .. ip .. '/cgi/readTags?n=1&t1=A4'
  res, code = http.request({
    url = url,
    headers = {
      ['Cookie'] = 'IDALToken=' .. token
    }
  })

  log('read request', res, code)

value = res:match('S_OK%s+%d+%s+(%d+)')
   if value then
      value = tonumber(value)
   -- log(value)
      grp.checkupdate('46/1/2', value/10)

   end
end
os.sleep(1)     


-- Read actual source out temperature ****************************

if token then
  url = 'http://' .. ip .. '/cgi/readTags?n=1&t1=A5'
  res, code = http.request({
    url = url,
    headers = {
      ['Cookie'] = 'IDALToken=' .. token
    }
  })

  log('read request', res, code)

value = res:match('S_OK%s+%d+%s+(%d+)')
   if value then
      value = tonumber(value)
   -- log(value)
      grp.checkupdate('46/1/3', value/10)

   end
end
os.sleep(1)     


-- ************************************************************

-- Read actual return temperature ****************************

if token then
  url = 'http://' .. ip .. '/cgi/readTags?n=1&t1=A11'
  res, code = http.request({
    url = url,
    headers = {
      ['Cookie'] = 'IDALToken=' .. token
    }
  })

  log('read request', res, code)

value = res:match('S_OK%s+%d+%s+(%d+)')
   if value then
      value = tonumber(value)
   -- log(value)
      grp.checkupdate('46/1/4', value/10)

   end
end
os.sleep(1)     

-- Read actual flow temperature ****************************

if token then
  url = 'http://' .. ip .. '/cgi/readTags?n=1&t1=A12'
  res, code = http.request({
    url = url,
    headers = {
      ['Cookie'] = 'IDALToken=' .. token
    }
  })

  log('read request', res, code)

value = res:match('S_OK%s+%d+%s+(%d+)')
   if value then
      value = tonumber(value)
   -- log(value)
      grp.checkupdate('46/1/5', value/10)

   end
end
os.sleep(1)     


-- ************************************************************

-- Read actual power compressor ****************************

if token then
  url = 'http://' .. ip .. '/cgi/readTags?n=1&t1=A25'
  res, code = http.request({
    url = url,
    headers = {
      ['Cookie'] = 'IDALToken=' .. token
    }
  })

  log('read request', res, code)

value = res:match('S_OK%s+%d+%s+(%d+)')
   if value then
      value = tonumber(value)
   -- log(value)
      grp.checkupdate('46/1/6', value/10)

   end
end
os.sleep(1)     

-- Read actual power heating****************************

if token then
  url = 'http://' .. ip .. '/cgi/readTags?n=1&t1=A26'
  res, code = http.request({
    url = url,
    headers = {
      ['Cookie'] = 'IDALToken=' .. token
    }
  })

  log('read request', res, code)

value = res:match('S_OK%s+%d+%s+(%d+)')
   if value then
      value = tonumber(value)
   -- log(value)
      grp.checkupdate('46/1/7', value/10)

   end
end
os.sleep(1)     

-- Read actual COP***************************

if token then
  url = 'http://' .. ip .. '/cgi/readTags?n=1&t1=A28'
  res, code = http.request({
    url = url,
    headers = {
      ['Cookie'] = 'IDALToken=' .. token
    }
  })

  log('read request', res, code)

value = res:match('S_OK%s+%d+%s+(%d+)')
   if value then
      value = tonumber(value)
   -- log(value)
      grp.checkupdate('46/1/8', value/10)

   end
end


-- Read desrired hot water temperature ****************************
if token then
  url = 'http://' .. ip .. '/cgi/readTags?n=1&t1=A37'

  res, code = http.request({
    url = url,
    headers = {
      ['Cookie'] = 'IDALToken=' .. token
    }
  })

  log('read request', res, code)
   
value = res:match('S_OK%s+%d+%s+(%d+)')
   if value then
      value = tonumber(value)
   -- log(value)
      grp.checkupdate('46/3/1', value/10)

   end
end

os.sleep(1)   


-- Read status heeting mode****************************
if token then
  url = 'http://' .. ip .. '/cgi/readTags?n=1&t1=I30'

  res, code = http.request({
    url = url,
    headers = {
      ['Cookie'] = 'IDALToken=' .. token
    }
  })

  log('read request', res, code)
   
value = res:match('S_OK%s+%d+%s+(%d+)')
   if value then
      value = tonumber(value)
   -- log(value)
        if value == 1
            then
            value = true
            elseif
            value == 0
            then
            value = false
        end
      grp.checkupdate('46/3/2', value)

   end
end

os.sleep(1)   


-- Read status cooling mode****************************
if token then
  url = 'http://' .. ip .. '/cgi/readTags?n=1&t1=I31'

  res, code = http.request({
    url = url,
    headers = {
      ['Cookie'] = 'IDALToken=' .. token
    }
  })

  log('read request', res, code)
   
value = res:match('S_OK%s+%d+%s+(%d+)')
   if value then
      value = tonumber(value)
   -- log(value)
        if value == 1
            then
            value = true
            elseif
            value == 0
            then
            value = false
        end
      grp.checkupdate('46/3/3', value)

   end
end

os.sleep(1)   

And the second one to write the desired values:

Code:
http = require('socket.http')

ip = 'xxx' -- ip address of Waterkotte heat pump
user = 'xxx' -- username of web interface
pwd = 'xxx' -- password of web interface

url = 'http://' .. ip .. '/cgi/login?username=' .. user .. '&password=' .. pwd

res, code = http.request(url)

log('login request', res, code)

if res and code == 200 then
  token = res:match('IDALToken=(%x+)')

  log('token', token)

  if type(token) == 'string' and #token == 32 then
    storage.set('ecotouch-token', token)
  end
end
os.sleep(1)

-- Write enable heating mode ****************************
setvalue = grp.getvalue('46/2/2')
if setvalue == true
then setvalue = 1
    else setvalue = 0
end

if token then
  url = 'http://' .. ip .. '/cgi/writeTags?returnValue=true&n=1&t1=I30&v1='..setvalue

  res, code = http.request({
    url = url,
    headers = {
      ['Cookie'] = 'IDALToken=' .. token
    }
  })

  log('read request', res, code)
   
end
os.sleep(1)

-- Write enable cooling mode ****************************

setvalue = grp.getvalue('46/2/3')
if setvalue == true
then setvalue = 1
    else setvalue = 0
end
if token then
  url = 'http://' .. ip .. '/cgi/writeTags?returnValue=true&n=1&t1=I31&v1='..setvalue
  res, code = http.request({
    url = url,
    headers = {
      ['Cookie'] = 'IDALToken=' .. token
    }
  })
  log('read request', res, code)
end
os.sleep(1)

-- Write water temperature****************************

setvalue = grp.getvalue('46/2/1')
setvalue = setvalue *10

if token then
  url = 'http://' .. ip .. '/cgi/writeTags?returnValue=true&n=1&t1=A38&v1='..setvalue
  res, code = http.request({
    url = url,
    headers = {
      ['Cookie'] = 'IDALToken=' .. token
    }
  })
  log('read request', res, code)
end

Generally it works fine EXCEPT when the time between two request is to short I getting the following return in the log and the values are not written to the heatpump:

Code:
Waterkotte_Sollwerte 10.03.2022 20:23:55
* arg: 1
  * string: login request
* arg: 2
  * string: -37
#E_TOO_MANY_USERS
* arg: 3
  * number: 200

@admin: Do you have an idea how to control the situation? Do I need to detect: "#E_TOO_MANY_USERS" and then wait some second and resend? How would this look like? Many thanks for your help!
Reply
#8
The login procedure should not be performed for each request. The token is already saved into storage so it should be used in read/write requests. If the request fails with an error then the token should be refreshed.
Reply


Forum Jump: