Adding support for Netatmo Thermostat

I’m trying to add support for the netamo thermostat.
Heavily based on work of Philippe Larduinat and fastcolors and ezekri I wrote this.
My netatmo.py:

"""
Support for Netatmo thermostat.

For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/thermostat.netatmo/
"""
import logging
import socket

from datetime import timedelta

#from homeassistant.components.thermostat import ThermostatDevice, DOMAIN
from homeassistant.components.thermostat import (
    STATE_COOL, STATE_HEAT, STATE_IDLE, ThermostatDevice, DOMAIN)

from homeassistant.const import (
    CONF_API_KEY, CONF_PASSWORD, CONF_USERNAME, TEMP_CELCIUS)
from homeassistant.helpers import validate_config
from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle


REQUIREMENTS = [
    'https://github.com/gieljnssns/tnetatmo/archive/master.zip'
    '#tnetatmo==0.1.0']

_LOGGER = logging.getLogger(__name__)

CONF_SECRET_KEY = 'secret_key'
ATTR_MODULE = 'modules'

# Return cached results if last scan was less then this time ago
# NetAtmo Data is uploaded to server every 10mn
# so this time should not be under
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=600)


def setup_platform(hass, config, add_devices, discovery_info=None):
    """Setup the NetAtmo Thermostat."""
    if not validate_config({DOMAIN: config},
                           {DOMAIN: [CONF_API_KEY,
                                     CONF_USERNAME,
                                     CONF_PASSWORD,
                                     CONF_SECRET_KEY]},
                           _LOGGER):
        return None

    import tnetatmo

    authorization = tnetatmo.ClientAuth(config.get(CONF_API_KEY, None),
                                        config.get(CONF_SECRET_KEY, None),
                                        config.get(CONF_USERNAME, None),
                                        config.get(CONF_PASSWORD, None))

    if not authorization:
        _LOGGER.error(
            "Connection error "
            "Please check your settings for NatAtmo API.")
        return False

    data = NetAtmoData(authorization)
    dev = tnetatmo.DeviceList(authorization)
    #dev = (netatmothermostat)
    # try:
    #     # Iterate each module
    #     for module_name in config[ATTR_MODULE].items():
    #         # Test if module exist """
    #         if module_name not in data.get_module_names():
    #             _LOGGER.error('Module name: "%s" not found', module_name)
    #             continue
    #         # Only create sensor for monitored """
    #         # for variable in monitored_conditions:
    #         #     if variable not in SENSOR_TYPES:
    #         #         _LOGGER.error('Sensor type: "%s" does not exist', variable)
    #         #     else:
    #         #         dev.append(
    #         #             NetAtmoSensor(data, module_name, variable))
    # except KeyError:
    #     pass

    add_devices([
        NetatmoThermostat(dev)
    ])


class NetatmoThermostat(ThermostatDevice):
    """Representation a Netatmo thermostat."""

    def __init__(self, netatmo_data):
        """Initialize the sensor."""
        self._name = "NetAtmo {} {}"
        self.netatmo_data = netatmo_data
        self._dev = dev
#        self.module_name = module_name
        # self.type = sensor_type
        self._state = None
        # self._unit_of_measurement = SENSOR_TYPES[sensor_type][1]
        self.update()

    @property
    def name(self):
        """Return the name of the sensor."""
        return self._name

    @property
    def state(self):
        """Return the state of the device."""
        return self._state

    # pylint: disable=too-many-branches
    # def update(self):
    #     """Get the latest data from NetAtmo API and updates the states."""
    #     self.netatmo_data.update()
    #     data = self.netatmo_data.data[self.module_name]
    #
    #     if self.type == 'temperature':
    #         self._state = round(data['Temperature'], 1)
    #     elif self.type == 'humidity':
    #         self._state = data['Humidity']
    #     elif self.type == 'rain':
    #         self._state = data['Rain']
    #     elif self.type == 'sum_rain_1':
    #         self._state = data['sum_rain_1']
    #     elif self.type == 'sum_rain_24':
    #         self._state = data['sum_rain_24']
    #     elif self.type == 'noise':
    #         self._state = data['Noise']
    #     elif self.type == 'co2':
    #         self._state = data['CO2']
    #     elif self.type == 'pressure':
    #         self._state = round(data['Pressure'], 1)

    @property
    def unit_of_measurement(self):
        """Return the unit of measurement."""
        return TEMP_CELCIUS

    @property
    def current_temperature(self):
        """Return the current temperature."""
        return self._dev.getthermoinfo

#     def __init__(self, pdp):
#         """Initialize the thermostat."""
#         self._pdp = pdp
#         # self._name = self._pdp.moduleByName
# #        self.netatmo_data = netatmo_data
# #        self.module_name = module_name
# #        self.type = sensor_type
#         self._state = None
# #        self._unit_of_measurement = SENSOR_TYPES[sensor_type][1]
#         self.update()

#
#     @property
#     def should_poll(self):
#         """Polling needed for thermostat."""
#         return True
#
#     def update(self):
#         """Update the data from the thermostat."""
#         self.netatmo_data.update()
#
#     @property
#     def name(self):
#         """Return the name of the thermostat."""
#         return self._name
#
#     @property
#     def device_state_attributes(self):
#         """Return the device specific state attributes."""
#         return {
#             "fan": self._data.fan_state
#         }
#
#     @property
#     def unit_of_measurement(self):
#         """Return the unit of measurement."""
#         return TEMP_CELCIUS
#
#     @property
#     def current_temperature(self):
#         """Return the current temperature."""
#         return self._data.cur_temp
#
    @property
    def target_temperature(self):
        """Return the temperature we try to reach."""
        return self._dev.setPointTemp
#
#     @property
#     def operation(self):
#         """Return the current state of the thermostat."""
#         state = self._data.hvac_state
#         if state in (1, 2):
#             return STATE_IDLE
#         elif state == 3:
#             return STATE_HEAT
#         elif state == 6:
#             return STATE_COOL
#
#     def set_temperature(self, temperature):
#         """Set new target temperature."""
#         self._data.setback_heat = temperature
#
#
class NetAtmoData(object):
    """Get the latest data from NetAtmo."""

    def __init__(self, auth):
        """Initialize the data object."""
        self.auth = auth
        self.data = None

    def get_module_names(self):
        """Return all module available on the API as a list."""
        self.update()
        return self.data.keys()

    @Throttle(MIN_TIME_BETWEEN_UPDATES)
    def update(self):
        """Call the NetAtmo API to update the data."""
        import tnetatmo
        dev_list = tnetatmo.DeviceList(self.auth)
        self.data = dev_list.getthermoinfo(exclude=3600)
#

I can get tnetatmo installed in /deps

but I get this error while booting

16-05-04 08:19:24 ERROR (MainThread) [homeassistant.components.thermostat] Error while setting up platform netatmo
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/entity_component.py", line 94, in _setup_platform
    discovery_info)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/components/thermostat/netatmo.py", line 62, in setup_platform
    dev = tnetatmo.DeviceList(authorization)
  File "/home/pi/.homeassistant/deps/tnetatmo.py", line 122, in __init__
    for m in self.devices['modules']: self.modules[m['_id']] = m
KeyError: 'modules'

This is the response in Postman:

{
  "body": {
    "devices": [
      {
        "_id": "***",
        "firmware": 49,
        "last_bilan": {
          "y": 2016,
          "m": 4
        },
        "last_setup": 1442917735,
        "last_status_store": 1462308429,
        "modules": [
          {
            "_id": "****",
            "module_name": "Thermostaat",
            "type": "NATherm1",
            "firmware": 38,
            "last_message": 1462308423,
            "rf_status": 74,
            "battery_vp": 4376,
            "therm_orientation": 2,
            "therm_relay_cmd": 0,
            "battery_percent": 92,
            "event_history": {
              "boiler_not_responding_events": [
                {
                  "K": 1452448030
                }
              ],
              "boiler_responding_events": [
                {
                  "K": 1452448040
                }
              ]
            },
            "last_therm_seen": 1462308423,
            "setpoint": {
              "setpoint_mode": "program"
            },
            "therm_program_list": [
              {
                "zones": [
                  {
                    "type": 0,
                    "id": 0,
                    "temp": 19
                  },
                  {
                    "type": 1,
                    "id": 1,
                    "temp": 17
                  },
                  {
                    "type": 2,
                    "id": 2,
                    "temp": 12
                  },
                  {
                    "type": 3,
                    "id": 3,
                    "temp": 7
                  },
                  {
                    "type": 5,
                    "id": 4,
                    "temp": 16
                  }
                ],
                "timetable": [
                  {
                    "m_offset": 0,
                    "id": 1
                  },
                  {
                    "m_offset": 420,
                    "id": 0
                  },
                  {
                    "m_offset": 480,
                    "id": 4
                  },
                  {
                    "m_offset": 1140,
                    "id": 0
                  },
                  {
                    "m_offset": 1320,
                    "id": 1
                  },
                  {
                    "m_offset": 1860,
                    "id": 0
                  },
                  {
                    "m_offset": 1920,
                    "id": 4
                  },
                  {
                    "m_offset": 2580,
                    "id": 0
                  },
                  {
                    "m_offset": 2760,
                    "id": 1
                  },
                  {
                    "m_offset": 3300,
                    "id": 0
                  },
                  {
                    "m_offset": 3360,
                    "id": 4
                  },
                  {
                    "m_offset": 4020,
                    "id": 0
                  },
                  {
                    "m_offset": 4200,
                    "id": 1
                  },
                  {
                    "m_offset": 4740,
                    "id": 0
                  },
                  {
                    "m_offset": 4800,
                    "id": 4
                  },
                  {
                    "m_offset": 5460,
                    "id": 0
                  },
                  {
                    "m_offset": 5640,
                    "id": 1
                  },
                  {
                    "m_offset": 6180,
                    "id": 0
                  },
                  {
                    "m_offset": 6240,
                    "id": 4
                  },
                  {
                    "m_offset": 6900,
                    "id": 0
                  },
                  {
                    "m_offset": 7080,
                    "id": 1
                  },
                  {
                    "m_offset": 7620,
                    "id": 0
                  },
                  {
                    "m_offset": 8520,
                    "id": 1
                  },
                  {
                    "m_offset": 9060,
                    "id": 0
                  },
                  {
                    "m_offset": 9960,
                    "id": 1
                  }
                ],
                "default": true,
                "program_id": "56012d8acce37c2c5d6d07a3",
                "name": "Default"
              },
              {
                "zones": [
                  {
                    "type": 0,
                    "name": "Comfort",
                    "temp": 21,
                    "id": 0
                  },
                  {
                    "type": 1,
                    "name": "Nacht",
                    "temp": 18,
                    "id": 1
                  },
                  {
                    "type": 2,
                    "name": "Afwezig",
                    "temp": 14,
                    "id": 2
                  },
                  {
                    "type": 3,
                    "name": "Vorstvrij",
                    "temp": 7,
                    "id": 3
                  },
                  {
                    "type": 5,
                    "name": "Eco",
                    "temp": 16,
                    "id": 4
                  },
                  {
                    "type": 4,
                    "name": "Tussenin",
                    "temp": 19.5,
                    "id": 5
                  },
                  {
                    "type": 4,
                    "name": "Ochtend",
                    "temp": 20,
                    "id": 6
                  }
                ],
                "timetable": [
                  {
                    "id": 1,
                    "m_offset": 0
                  },
                  {
                    "id": 6,
                    "m_offset": 420
                  },
                  {
                    "id": 4,
                    "m_offset": 510
                  },
                  {
                    "id": 5,
                    "m_offset": 720
                  },
                  {
                    "id": 4,
                    "m_offset": 810
                  },
                  {
                    "id": 0,
                    "m_offset": 960
                  },
                  {
                    "id": 1,
                    "m_offset": 1350
                  },
                  {
                    "id": 6,
                    "m_offset": 1860
                  },
                  {
                    "id": 4,
                    "m_offset": 1950
                  },
                  {
                    "id": 5,
                    "m_offset": 2160
                  },
                  {
                    "id": 4,
                    "m_offset": 2250
                  },
                  {
                    "id": 0,
                    "m_offset": 2400
                  },
                  {
                    "id": 1,
                    "m_offset": 2790
                  },
                  {
                    "id": 6,
                    "m_offset": 3300
                  },
                  {
                    "id": 4,
                    "m_offset": 3390
                  },
                  {
                    "id": 5,
                    "m_offset": 3600
                  },
                  {
                    "id": 4,
                    "m_offset": 3690
                  },
                  {
                    "id": 0,
                    "m_offset": 3840
                  },
                  {
                    "id": 1,
                    "m_offset": 4230
                  },
                  {
                    "id": 6,
                    "m_offset": 4740
                  },
                  {
                    "id": 4,
                    "m_offset": 4830
                  },
                  {
                    "id": 5,
                    "m_offset": 5040
                  },
                  {
                    "id": 4,
                    "m_offset": 5130
                  },
                  {
                    "id": 0,
                    "m_offset": 5280
                  },
                  {
                    "id": 1,
                    "m_offset": 5670
                  },
                  {
                    "id": 6,
                    "m_offset": 6180
                  },
                  {
                    "id": 4,
                    "m_offset": 6270
                  },
                  {
                    "id": 5,
                    "m_offset": 6480
                  },
                  {
                    "id": 4,
                    "m_offset": 6570
                  },
                  {
                    "id": 0,
                    "m_offset": 6720
                  },
                  {
                    "id": 1,
                    "m_offset": 7110
                  },
                  {
                    "id": 0,
                    "m_offset": 7620
                  },
                  {
                    "id": 5,
                    "m_offset": 7800
                  },
                  {
                    "id": 0,
                    "m_offset": 8100
                  },
                  {
                    "id": 1,
                    "m_offset": 8580
                  },
                  {
                    "id": 0,
                    "m_offset": 9060
                  },
                  {
                    "id": 5,
                    "m_offset": 9240
                  },
                  {
                    "id": 0,
                    "m_offset": 9540
                  },
                  {
                    "id": 1,
                    "m_offset": 10020
                  }
                ],
                "program_id": "56012fd94bda1d9b14b0088a",
                "name": "Week",
                "selected": true
              },
              {
                "timetable": [
                  {
                    "id": 1,
                    "m_offset": 0
                  },
                  {
                    "id": 0,
                    "m_offset": 420
                  },
                  {
                    "id": 4,
                    "m_offset": 480
                  },
                  {
                    "id": 0,
                    "m_offset": 720
                  },
                  {
                    "id": 4,
                    "m_offset": 780
                  },
                  {
                    "id": 0,
                    "m_offset": 1140
                  },
                  {
                    "id": 1,
                    "m_offset": 1320
                  },
                  {
                    "id": 0,
                    "m_offset": 1860
                  },
                  {
                    "id": 4,
                    "m_offset": 1920
                  },
                  {
                    "id": 0,
                    "m_offset": 2160
                  },
                  {
                    "id": 4,
                    "m_offset": 2220
                  },
                  {
                    "id": 0,
                    "m_offset": 2580
                  },
                  {
                    "id": 1,
                    "m_offset": 2760
                  },
                  {
                    "id": 0,
                    "m_offset": 3300
                  },
                  {
                    "id": 4,
                    "m_offset": 3360
                  },
                  {
                    "id": 0,
                    "m_offset": 3600
                  },
                  {
                    "id": 4,
                    "m_offset": 3660
                  },
                  {
                    "id": 0,
                    "m_offset": 4020
                  },
                  {
                    "id": 1,
                    "m_offset": 4200
                  },
                  {
                    "id": 0,
                    "m_offset": 4740
                  },
                  {
                    "id": 4,
                    "m_offset": 4800
                  },
                  {
                    "id": 0,
                    "m_offset": 5040
                  },
                  {
                    "id": 4,
                    "m_offset": 5100
                  },
                  {
                    "id": 0,
                    "m_offset": 5460
                  },
                  {
                    "id": 1,
                    "m_offset": 5640
                  },
                  {
                    "id": 0,
                    "m_offset": 6180
                  },
                  {
                    "id": 4,
                    "m_offset": 6240
                  },
                  {
                    "id": 0,
                    "m_offset": 6480
                  },
                  {
                    "id": 4,
                    "m_offset": 6540
                  },
                  {
                    "id": 0,
                    "m_offset": 6900
                  },
                  {
                    "id": 1,
                    "m_offset": 7080
                  },
                  {
                    "id": 0,
                    "m_offset": 7620
                  },
                  {
                    "id": 1,
                    "m_offset": 8520
                  },
                  {
                    "id": 0,
                    "m_offset": 9060
                  },
                  {
                    "id": 1,
                    "m_offset": 9960
                  }
                ],
                "zones": [
                  {
                    "type": 0,
                    "temp": 20,
                    "id": 0
                  },
                  {
                    "type": 1,
                    "temp": 18,
                    "id": 1
                  },
                  {
                    "type": 2,
                    "temp": 13,
                    "id": 2
                  },
                  {
                    "type": 3,
                    "temp": 7,
                    "id": 3
                  },
                  {
                    "type": 5,
                    "temp": 16,
                    "id": 4
                  }
                ],
                "name": "Week2",
                "program_id": "560f760c45a1e3ed33b0a8a4"
              }
            ],
            "measured": {
              "time": 1462308046,
              "temperature": 21.3,
              "setpoint_temp": 18
            }
          }
        ],
        "place": {
          "altitude": 9,
          "city": "****",
          "country": "BE",
          "improveLocProposed": true,
          "location": [
            ***,
            ****
          ],
          "timezone": "Europe/Brussels",
          "trust_location": true
        },
        "plug_connected_boiler": true,
        "station_name": "Thuis",
        "type": "NAPlug",
        "udp_conn": true,
        "wifi_status": 65,
        "last_plug_seen": 1462308429
      }
    ],
    "user": {
      "mail": "***",
      "administrative": {
        "reg_locale": "nl-BE",
        "lang": "nl-NL",
        "unit": 0,
        "windunit": 0,
        "pressureunit": 0,
        "feel_like_algo": 0
      }
    }
  },
  "status": "ok",
  "time_exec": 0.011533975601196,
  "time_server": 1462309050

How do i reach ‘modules’?

My suggestion would be to use the requests python library in tnetatmo.py

rr = requests.post(url, params)
json = rr.json()
print(json['body']['devices'][0]['modules'])

Sorry for the late response.

Now I’m using requests now, but i have problems reaching my temperature

tnetatmo;

class Thermos:

    def __init__(self, authData):

        self.accessToken = authData.accessToken
        postParams = {
                "access_token" : self.accessToken
                }
        resp = requests.post(_GETTHERMOSTATDATA_REQ, data=postParams).json()

        self.rawData = resp['body']
        self.status = resp['status']
        self.devList = self.rawData['devices']
        self.devId = self.devList[0]['_id']
        self.modList = self.devList[0]['modules']
        self.modId = self.modList[0]['_id']

        self.measTemp = self.modList[0]['measured']["temperature"]

        self.setPointTemp = self.modList[0]['measured']['setpoint_temp']

this is my error

16-05-21 13:10:23 ERROR (MainThread) [homeassistant.components.thermostat] Error while setting up platform netatmo
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/entity_component.py", line 98, in _setup_platform
    discovery_info)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/components/thermostat/netatmo.py", line 62, in setup_platform
    data = tnetatmo.Thermos(authorization)
  File "/home/pi/.homeassistant/deps/tnetatmo.py", line 244, in __init__
    self.measTemp = self.modList[0]['measured']["temperature"]
AttributeError: can't set attribute

‘measured’ is almost at the bottom of the JSON response

Also can’t reach ‘status’

16-05-21 13:19:12 ERROR (MainThread) [homeassistant.components.thermostat] Error while setting up platform netatmo
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/entity_component.py", line 98, in _setup_platform
    discovery_info)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/components/thermostat/netatmo.py", line 62, in setup_platform
    data = tnetatmo.Thermos(authorization)
  File "/home/pi/.homeassistant/deps/tnetatmo.py", line 238, in __init__
    self.status = resp['status']
AttributeError: can't set attribute

It is because you define status as a property so you can’t change its value directly, you need to use a private variable like self._status that will be returned by the property def status(self)

for self.measTemp you don’t need to set its value to self.modList[0][‘measured’][“temperature”] as it is already done in its property

@gieljnssns: did you make any progress with this?

Since 2 day’s I have 2 custom components running in my Home Assistant.
You can view My_Home-Assistant at Github.

I also made some changes to lnetatmo file from @jabesq. First let lnetatmo install, then replace it by mine.

It’s not perfect but it works.

@koen01

@gieljnssns
haven’t tested it completely , but it seems it works.
“De aanhouder wint” in dit geval. Goed gedaan !

thank you!

@jabesq and @gieljnssns

I made a pull request to add thermostat support to the lnetatmo.py

@gieljnssns; Hope you don’t mind? You deserve full credit!

No problem!

@gieljnssns;
could you take a look at the comments made on my pull request?
it’s way beyond my capabilities to answer the questions :slight_smile:
edit: pull request has been removed;

original comments were:

in lnetatmo.py:

> @@ -67,7 +69,7 @@ def __init__(self, clientId=_CLIENT_ID,
>                         clientSecret=_CLIENT_SECRET,
>                         username=_USERNAME,
>                         password=_PASSWORD,
> -                       scope="read_station"):
> +                       scope="read_station read_thermostat write_thermostat"):
I would prefer that you let the default scope as it is, so the developper knows what is doing when he asks for a specific scope and the thermostat is quite a sensitive device (you don't want your temperature to be changed by a bug in a weather station app)

and

Please also update the documentation in usage.md file, this is needed if I want to do a pull request on the master project (used by pypi) which is https://github.com/philippelt/netatmo-api-python (or you can do directly your PR on this project, then i'll redo my sync on it)

I think you must use my scope, found on netatmo dev site:
https://dev.netatmo.com/dev/resources/technical/guides/authentication/authorizationcode

Step 4 - Retrieve the access token with the code

Retrieve an access token for your user with the code parameter received at step 3 with method https://api.netatmo.com/oauth2/token and grant_type authorization_code.

Access_tokens are associated to a scope, when requesting one, you should precise which scope you require. There are five available scopes:
read_station: to retrieve weather station data (Getstationsdata, Getmeasure)
read_thermostat: to retrieve thermostat data ( Getmeasure, Getthermostatsdata)
write_thermostat: to set up the thermostat (Syncschedule, Setthermpoint)
read_camera: to retrieve Welcome data (Gethomedata, Getcamerapicture)
access_camera: to access the camera, the videos and the live stream.
If no scope is provided during the token request, the default is "read_station".
Endpoint: https://api.netatmo.com/oauth2/token

I don’t have time now, lots of other things to do…

added in my HA … works well ! Thanks for the job !

Just an error when trying to change the temp with HA :

**16-09-15 15:06:45 homeassistant.core: BusHandler:Exception doing job
Traceback (most recent call last):
File “/usr/local/lib/python3.4/dist-packages/homeassistant/core.py”, line 865, in job_handler
func(*args)
File “/usr/local/lib/python3.4/dist-packages/homeassistant/core.py”, line 730, in _execute_service
service(call)
File “/usr/local/lib/python3.4/dist-packages/homeassistant/core.py”, line 586, in call
self.func(call)
File “/usr/local/lib/python3.4/dist-packages/homeassistant/components/climate/init.py”, line 240, in temperature_set_service
climate.set_temperature(kwargs)
TypeError: set_temperature() got an unexpected keyword argument 'entity_id’

I know it isn’t perfect, but my python skills aren’t good enough for getting it wright.
I use this for monitoring the temperature in my living room and turning on and off away mode.

I think if you add it ass thermostat instead off climate it still works?

@gieljnssns and @jabesq :
Have you seen this?

It is another Python API for netatmo, but it seems that it just provides a python interface for the http API from Netatmo, no sorting of the data and other stuff.

@doune @gieljnssns
I think i fixed it
set_temp works with climate component

https://github.com/koen01/hass/blob/master/custom_components/climate/netatmo.py

Hi,

Great Job !

Can you also share your lnetatmo.py ?

I’ve still the following error :

16-09-26 06:18:25 homeassistant.core: BusHandler:Exception doing job
Traceback (most recent call last):
File “/usr/local/lib/python3.4/dist-packages/homeassistant/core.py”, line 865, in job_handler
func(*args)
File “/usr/local/lib/python3.4/dist-packages/homeassistant/core.py”, line 730, in _execute_service
service(call)
File “/usr/local/lib/python3.4/dist-packages/homeassistant/core.py”, line 586, in call
self.func(call)
File “/usr/local/lib/python3.4/dist-packages/homeassistant/components/climate/init.py”, line 202, in away_mode_set_service
climate.update_ha_state(True)
File “/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/entity.py”, line 154, in update_ha_state
self.update()
File “/usr/local/lib/python3.4/dist-packages/homeassistant/util/init.py”, line 296, in wrapper
result = method(*args, **kwargs)
File “/home/pi/.homeassistant/custom_components/climate/netatmo.py”, line 141, in update
self._data.update()
File “/usr/local/lib/python3.4/dist-packages/homeassistant/util/init.py”, line 296, in wrapper
result = method(*args, **kwargs)
File “/home/pi/.homeassistant/custom_components/climate/netatmo.py”, line 173, in update
self.thermostatdata = lnetatmo.ThermostatData(self.auth)
File “/home/pi/.homeassistant/deps/lnetatmo.py”, line 510, in init
self.setpoint_mode = self.modList[0][‘setpoint’][‘setpoint_mode’]
KeyError: ‘setpoint’

@doune