Skip to content

Latest commit

 

History

History
419 lines (396 loc) · 19.1 KB

README.md

File metadata and controls

419 lines (396 loc) · 19.1 KB

TesyLocal

The opposite of Tesy cloud

Intro

This little package only reads data from your tesy boiler at the moment.

Requirements:

  • Python3.6 and up
  • Boiler firmware of 20.20 and up

Index

  1. Get Started
  2. Arguments
  3. Boiler Modes
  4. Home assistant YAML
  5. Notes

Simple how-to get started / command examples

# This is a small app, using the TesyLocal module
from tesylocal import tesy
# Please specify your boiler IP like so, and if you want a initial sync of all values
## NOTE: This is only important if you are not planning to integrate this.
boiler = tesy("192.168.1.1", "sync")
# No sync:
boiler = tesy("192.168.1.1", "nosync")
# Then print a property, This requires "sync" or updateallvalues / updateschedules after connecting.
print(boiler.tesyprettyprinter)

## Other options:
# Update values:
boiler.updateallvalues('192.168.2.254')
boiler.updateschedules('192.168.2.254')
# Got DHCP?, Or perhaps you want to validate the IP once in a while or check if the device is alive:
boiler.check_ip_status('192.168.2.254')
# Turn on the boiler
boiler.boileronoff("192.168.2.254","on")
# Turn the boiler off
boiler.boileronoff("192.168.2.254","off")
# More are available:
# boostonoff, boilermanualmode, boileronoff, manualtemp,
# automanualmode, boilermode, resetpower, settime, setboilervolume, setvacationmode

Available commands and expected arguments

Command Ip Needed Argument 1 Argument 2 Argument 3 Notes
boiler.updateallvalues True N/A N/A N/A Updates all current values for pretty print
boiler.updateschedules True N/A N/A N/A Updates all schedules for pretty print
boiler.check_ip_status True N/A N/A N/A Validates if the IP accepts /devstat and if the JSON we get is valid.
boiler.boileronoff True "on" / "off" N/A N/A Turns the boiler on or off, must be string
boiler.boostonoff True 0 - 1 N/A N/A Turns boost mode on or off, must be int 0 to 1 (0 off, 1 on)
boiler.manualtemp True 14 - 75 N/A N/A Sets the temperature of the boiler if the boiler is in manual mode, Must be int 14 to 75
boiler.automanualmode True 14 - 75 N/A N/A Sets the temperature of manual mode, but also forces the boiler in manual mode regardless, Must be int 14 to 75
boiler.boilermode True 0 - 9 N/A N/A Sets a mode of the boiler see "Boiler modes" chapter, Must be int 0 to 9
boiler.resetpower True N/A N/A N/A Resets the kWh meter of the boiler, Note this not the since powered on kWh counter, but a second meter
boiler.settime True Europe/Amsterdam N/A N/A Sets the time of the boiler to now, must need time zone in "Europe/Amsterdam" format
boiler.setboilervolume True 100 N/A N/A Sets the volume of the boiler, This might be wrong from factory and is a bug in FW21.21 that it cannot update, must be int one off (50, 80, 100, 120, 150)
boiler.setvacationmode True 23/12/32 (Y/M/D) 00 - 23 14 -75 Turns on vacation mode, needs date as string, hour as string, temp as int (boiler.setvacationmode("ip", "23/12/31","13",75)
boiler.pretyprinter False N/A N/A N/A Shows a pretty format of all the values (needs, sync or updateallvalues/updateschedules)
boiler.tesyprinter False N/A N/A N/A Raw data output (needs, sync or updateallvalues/updateschedules)
boiler.tesyprinter1 False N/A N/A N/A Raw data output of schedule 1 (needs, sync or updateschedules)
boiler.tesyprinter2 False N/A N/A N/A Raw data output of schedule 2 (needs, sync or updateschedules)
boiler.tesyprinter3 False N/A N/A N/A Raw data output of schedule 3 (needs, sync or updateschedules)

This is a example of the output you can expect with the print(boiler.tesyprettyprinter)

==========================================
# General:                               #
==========================================
| Temp:  53.0 | Target:  50  |
| Next Temp: 50 at 14:00
| Boost:  0   | Power:  on   | State:  READY
| Errors:  0   | Liters: 100 |
| TimeZone: CEST
| Local Time: 2022-04-08 13:27
==========================================
# Power Usage:                           #
==========================================
| Alltime KWH: 0.80
| Current KWH: 0.06
| Max Power: 2400
| Counter Reset: 2022-04-08 10:55:45
==========================================
# MyTesy:                                #
==========================================
| MyTDesc:           boiler1
| MyTEmail: noreply@yourdomain.com
| MyTDetail:
==========================================
# Vacation:                              #
==========================================
| Vacation Set:  0
| Vacation Target Temp:  70
| Vacation date (Y:M:D:H): 21:12:1:20
| Vacation WeekDay: 3
==========================================
# Wifi: (outgoing)                       #
==========================================
| Errors:  0
| Conected:  1
| Signal: -41
| SSID:       SSSIDDDD
| Internet:              1
==========================================
# Wifi: (Indoor)                         #
==========================================
| Protection:             psk2
| Password:               Password
==========================================
# Misc:                                  #
==========================================
| DevID:  2004-3402 FW21.21
| MacAddr:      70:f1:

Boiler modes:

1: Manual mode
2: Weekly program 1
3: Weekly program 2
4: Weekly program 3
5: Eco 1
6: Eco 2
7: Eco 3
8: ?
9: Vacation

Note that there are a total of 9 modes, Not sure what they all do.

Home Assistant

Currently a integration is in the works, but until then you can add the following to your configuration.yaml

Note that the ?_=1634912123253 (epoch) is a identifier to track your request, it is not needed to control the boiler.

rest_command:
  tsmt:
    url: "http://192.168.2.254/setTemp?val={{ temperature }}"
    method: GET

automation:
  - alias: "Tesy Temperature input automatically changed"
    trigger:
      platform: state
      entity_id: sensor.tesyboilertargettemp
    action:
      service: input_number.set_value
      target:
        entity_id: input_number.tesyboilermanualtempinput
      data:
        value: "{{ trigger.to_state.state }}"
  - alias: "Tesy Temperature input manually changed"
    trigger:
      platform: state
      entity_id: input_number.tesyboilermanualtempinput
    action:
      service: rest_command.tsmt
      data:
        temperature: "{{ trigger.to_state.state }}"

input_number:
  tesyboilermanualtempinput:
    name: Set Tesy Manual Temp
    min: 14
    max: 75
    step: 1
    unit_of_measurement: "°C"
    icon: mdi:temperature-celsius

switch:
  - platform: command_line
    switches:
      tesyboostonoff:
        command_on: "/usr/bin/curl -X GET http://192.168.2.254/boostSW?mode=1"
        command_off: "/usr/bin/curl -X GET http://192.168.2.254/boostSW?mode=0"
        command_state: "/usr/bin/curl -sX GET http://192.168.2.254/status"
        value_template: "{{ value_json['boost'] == '1' }}"
        friendly_name: Boost Tesy!
        icon_template: >
          {% if value_json['boost'] == '0' %} mdi:rocket
          {% elif value_json['boost'] == '1' %} mdi:rocket-launch
          {% else %} mdi:help-circle
          {% endif %}
      tesyonoff:
        command_on: "/usr/bin/curl -X GET http://192.168.2.254/power?val=on"
        command_off: "/usr/bin/curl -X GET http://192.168.2.254/power?val=off"
        command_state: "/usr/bin/curl -sX GET http://192.168.2.254/status"
        value_template: "{{ value_json['power_sw'] == 'on' }}"
        friendly_name: Tesy power switch!
        icon_template: >
          {% if value_json['power_sw'] == "on" %} mdi:toggle-switch
          {% else %} mdi:toggle-switch-off
          {% endif %}
      tesyresetpower:
        command_on: "/usr/bin/curl -X GET http://192.168.2.254/resetPow"
        friendly_name: Tesy power Reset!
      tesysetsetmanualmode:
        command_on: "/usr/bin/curl -X GET http://192.168.2.254/modeSW?mode=1"
        # Set a default schedule here if you dont want manual mode any longer
        command_off: "/usr/bin/curl -X GET http://192.168.2.254/modeSW?mode=2"
        command_state: "/usr/bin/curl -sX GET http://192.168.2.254/status"
        value_template: "{{ value_json['mode'] == '1' }}"
        friendly_name: Set Tesy manual mode
        icon_template: >
          {% if value_json['mode'] == '1' %} mdi:water-boiler
          {% elif value_json['mode'] == '2' %} mdi:calendar
          {% elif value_json['mode'] == '3' %} mdi:calendar
          {% elif value_json['mode'] == '4' %} mdi:calendar
          {% elif value_json['mode'] == '5' %} mdi:sprout
          {% elif value_json['mode'] == '6' %} mdi:sprout
          {% elif value_json['mode'] == '7' %} mdi:sprout
          # No idea what mode 8 is.
          {% elif value_json['mode'] == '8' %} mdi:help
          {% elif value_json['mode'] == '9' %} mdi:beach
          {% else %} mdi:help-circle
          {% endif %}
sensor:
  - platform: rest
    resource: http://192.168.2.254/status
    name: tesyboiler
    method: GET
    value_template: "OK"
    json_attributes:
      - gradus
      - ref_gradus
      - heater_state
      - err_flag
      - boost
      - power_sw
      - volume
      - watts
      - mode
  - platform: rest
    resource: http://192.168.2.254/calcRes
    name: tesyboilerpower
    method: GET
    value_template: "OK"
    json_attributes:
      - kwh
      - ltc
      - resetDate

template:
  - sensor:
      - name: "Boiler kWh all time"
        unit_of_measurement: "kWh"
        device_class: energy
        state_class: total_increasing
        state: "{{ states('sensor.TesyBoilerKwhAllTime') }}"
  - sensor:
      - name: "tesyboilerkwhresetdate"
        icon: mdi:calendar-blank-outline
        unique_id: "TesyBoilerKwhResetDate"
        state: "{{ state_attr('sensor.tesyboilerpower', 'resetDate') }}"
  - sensor:
      - name: "tesyboilerkwhafterreset"
        icon: mdi:lightning-bolt
        unique_id: "TesyBoilerKwhAfterReset"
        state: "{{ state_attr('sensor.tesyboilerpower', 'kwh') }}"
        unit_of_measurement: "kWh"
        device_class: energy
  - sensor:
      - name: "tesyboilerwatervolume"
        icon: mdi:cup-water
        unique_id: "TesyBoilerWaterVolume"
        state: "{{ state_attr('sensor.tesyboiler', 'volume') }}"
        unit_of_measurement: "L"
  - sensor:
      - name: "tesyboilerwatts"
        icon: mdi:power-plug
        unique_id: "TesyBoilerWatts"
        state: "{{ state_attr('sensor.tesyboiler', 'watts') }}"
        unit_of_measurement: "W"
  - sensor:
      - name: "tesyboilermode"
        icon: mdi:calendar
        unique_id: "TesyBoilerMode"
        state: "{{ state_attr('sensor.tesyboiler', 'mode') }}"
  - sensor:
      - name: "tesyboilererror"
        icon: mdi:water-boiler-alert
        unique_id: "TesyBoilerError"
        state: "{{ state_attr('sensor.tesyboiler', 'err_flag') }}"
  - sensor:
      - name: "tesyboilerboost"
        icon: mdi:arrow-up-circle
        unique_id: "TesyBoilerBoost"
        state: "{{ state_attr('sensor.tesyboiler', 'boost') }}"
  - sensor:
      - name: "tesyboileronoff"
        icon: mdi:help-circle
        unique_id: "TesyBoilerOnOff"
        state: "{{ state_attr('sensor.tesyboiler', 'power_sw') }}"
  - sensor:
      - name: "tesyboilerstate"
        icon: mdi:help-circle
        unique_id: "TesyBoilerState"
        state: "{{ state_attr('sensor.tesyboiler', 'heater_state') }}"
  - sensor:
      - name: "tesyboilertargettemp"
        icon: mdi:help-circle
        unique_id: "TesyBoilerTargetTemp"
        state: "{{ state_attr('sensor.tesyboiler', 'ref_gradus') }}"
  - sensor:
      - name: "tesyboilerwatertemp"
        icon: mdi:temperature-celsius
        unique_id: "TesyBoilerWaterTemp"
        state: "{{ state_attr('sensor.tesyboiler', 'gradus') }}"
        unit_of_measurement: "°C"
  - sensor:
      - name: "tesyboilerwatertargettemp"
        icon: mdi:temperature-celsius
        unique_id: "TesyBoilerWaterTargetTemp"
        state: "{{ state_attr('sensor.tesyboiler', 'ref_gradus') }}"
        unit_of_measurement: "°C"
  - sensor:
      - name: "tesyboilerkwhalltime"
        icon: mdi:lightning-bolt
        unique_id: "TesyBoilerKwhAllTime"
        state: "{{ state_attr('sensor.tesyboilerpower', 'ltc') }}"
        unit_of_measurement: "kWh"
        device_class: energy

Notes:

Here are some of the URLs you can manually make to control the boiler and a description:

1634911445424 == epoch

# boost on
http://192.168.2.254/boostSW?mode=0&_=1634911445424
# boost off
http://192.168.2.254/boostSW?mode=1&_=1634911446795
# set adaptive:
http://192.168.2.254/adaptive?val=
# Set antifreeze:
http://192.168.2.254/aantifrize?val=    # changeStatusParam, antifrost_enable   1 and 0
# Set lock:
http://192.168.2.254/lockKey?val=   # changeStatusParam lockB 1 and 0

# set to temp
http://192.168.2.254/setTemp?val=45&_=1634911879615
# manual mode
http://192.168.2.254/modeSW?mode=1&_=1634912123253
# set program 1
http://192.168.2.254/modeSW?mode=2&_=1634912027732
# set 2
http://192.168.2.254/modeSW?mode=3&_=1634912041121
# set 3
http://192.168.2.254/modeSW?mode=4&_=1634912071235
# eco 1
http://192.168.2.254/modeSW?mode=5&_=1634912151669
# eco 2
http://192.168.2.254/modeSW?mode=6&_=1634912164061
# eco 3
http://192.168.2.254/modeSW?mode=7&_=1634912180802
# device status
http://192.168.2.254/devstat?_=1634923248104
# get status
http://192.168.2.254/status?_=1634911418801
language+ set up status
http://192.168.2.254/getAccessories?_=1634923248606
# Set volume
http://192.168.2.254/setVolume?_=1634912180802&liters=100
http://192.168.2.254/setVolume&liters=100
# my tesy profile
http://192.168.2.254/mtProfile?_=1634911562552
# internet test
http://192.168.2.254/inettest?_=1634911553629
# kwh info
http://192.168.2.254/calcRes?&watt=&_=1634911625571
http://192.168.2.254/calcRes&_=1634911625571
# get volume
http://192.168.2.254/getVolume?_=1634911621820
# get schedule program 3
http://192.168.2.254/getP3?_=1634911711930
# get schedule program 2
http://192.168.2.254/getP2?_=1634911711930
# get schedule program 1
http://192.168.2.254/getP1?_=1634911711930
# get vacation
http://192.168.2.254/getVacation?_=1634911711432
# reset power
http://192.168.2.254/resetPow?_=1634912213060
# get power capacity
http://192.168.2.254/watt?_=1634912213060
# set power
http://192.168.2.254/power?val=1000&_=1634912213060

# Set vacation
# 30 december 2021 till 02:00 set to 70 This is day number 4 of the week sunday = 0 monday = 1,,
http://192.168.2.254/setVacation?_=1634990836894&vYear=21&vMonth=12&vMDay=30&vWDay=4&vHour=02&vTemp=70
# 1 december 2021 till 20:00 set to 70 This is day number 3 of the week sunday = 0 monday = 1,,
http://192.168.2.254/setVacation?_=1634990969916&vYear=21&vMonth=12&vMDay=1&vWDay=3&vHour=20&vTemp=70

# set a new item in the schedule:
http://192.168.2.254/setP1
+ body:
POST /setP1 HTTP/1.1
Host: 192.168.2.254
Connection: keep-alive
Content-Length: 1512
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Origin: http://192.168.2.254
Referer: http://192.168.2.254/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,nl;q=0.8
dnt: 1
sec-gpc: 1
&Mon00=30&Mon01=30&Mon02=30&Mon03=30&Mon04=30&Mon05=30&Mon06=30&Mon07=50&Mon08=50&Mon09=50&Mon10=40&Mon11=40&Mon12=50&Mon13=50&Mon14=40&Mon15=40&Mon16=40&Mon17=50&Mon18=50&Mon19=30&Mon20=30&Mon21=30&Mon22=30&Mon23=30&Tue00=30&Tue01=30&Tue02=30&Tue03=30&Tue04=30&Tue05=30&Tue06=30&Tue07=50&Tue08=50&Tue09=50&Tue10=40&Tue11=40&Tue12=50&Tue13=50&Tue14=40&Tue15=40&Tue16=40&Tue17=50&Tue18=50&Tue19=30&Tue20=30&Tue21=30&Tue22=30&Tue23=30&Wen00=30&Wen01=30&Wen02=30&Wen03=30&Wen04=30&Wen05=30&Wen06=30&Wen07=50&Wen08=50&Wen09=50&Wen10=40&Wen11=40&Wen12=50&Wen13=50&Wen14=40&Wen15=40&Wen16=40&Wen17=50&Wen18=50&Wen19=30&Wen20=30&Wen21=30&Wen22=30&Wen23=30&Thu00=30&Thu01=30&Thu02=30&Thu03=30&Thu04=30&Thu05=30&Thu06=30&Thu07=45&Thu08=45&Thu09=45&Thu10=45&Thu11=45&Thu12=45&Thu13=45&Thu14=45&Thu15=55&Thu16=65&Thu17=75&Thu18=75&Thu19=30&Thu20=30&Thu21=30&Thu22=30&Thu23=30&Fri00=30&Fri01=30&Fri02=30&Fri03=30&Fri04=30&Fri05=30&Fri06=30&Fri07=45&Fri08=45&Fri09=45&Fri10=35&Fri11=35&Fri12=45&Fri13=45&Fri14=35&Fri15=35&Fri16=35&Fri17=35&Fri18=45&Fri19=45&Fri20=55&Fri21=65&Fri22=75&Fri23=75&Sat00=30&Sat01=30&Sat02=30&Sat03=30&Sat04=30&Sat05=30&Sat06=30&Sat07=30&Sat08=30&Sat09=30&Sat10=50&Sat11=60&Sat12=60&Sat13=50&Sat14=50&Sat15=50&Sat16=50&Sat17=50&Sat18=50&Sat19=50&Sat20=50&Sat21=50&Sat22=50&Sat23=50&Sun00=30&Sun01=30&Sun02=30&Sun03=30&Sun04=30&Sun05=30&Sun06=30&Sun07=30&Sun08=30&Sun09=30&Sun10=50&Sun11=60&Sun12=60&Sun13=50&Sun14=50&Sun15=50&Sun16=50&Sun17=50&Sun18=50&Sun19=30&Sun20=30&Sun21=30&Sun22=30&Sun23=30

# update boiler time and date
http://192.168.2.254/setdate?tOffset=CET-1CEST,M3.5.0,M10.5.0/3&tDay=5&tMonth=10&tYear=2022&tHour=16&tMin=0&tSec=00?_=1664978401338