Пример #1
0
    def __init__(self, hass, name, serial, accesskey, password, holiday_temp,
                 holiday_duration):
        from nefit import NefitClient
        """Initialize the thermostat."""
        self.hass = hass
        self._name = name
        self._serial = serial
        self._accesskey = accesskey
        self._password = password
        self._unit_of_measurement = TEMP_CELSIUS
        self._data = {}
        self._attributes = {}
        self._attributes["connection_error_count"] = 0
        self._operation_list = [
            OPERATION_MANUAL, OPERATION_AUTO, OPERATION_HOLIDAY
        ]
        self.override_target_temp = False
        self.new_target_temp = 0
        self._manual = False
        self._holiday_mode = False
        self._holiday_temp = holiday_temp
        self._holiday_duration = holiday_duration

        _LOGGER.debug("Constructor for %s called.", self._name)

        hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, self._shutdown)

        self._client = NefitClient(serial_number=self._serial,
                                   access_key=self._accesskey,
                                   password=self._password)
        self._client.connect()
Пример #2
0
 def test_exceptions(self):
     client = NefitClient(
         os.environ.get("NEFIT_SERIAL", 123456789),
         os.environ.get("NEFIT_ACCESS_KEY", "abc1abc2abc3abc4"),
         "asddasadsasdcx")
     client.connect()
     with self.assertRaises(NefitResponseException):
         client.get_display_code()
     client.disconnect()
     client.force_disconnect()
Пример #3
0
class AesTest(unittest.TestCase):
    client = None

    def setUp(self):
        self.client = NefitClient(123456789, "abc1abc2abc3abc4",
                                  "passworddddd")

    # encrypt and decrypt a string
    def test_crypt(self):
        text = "super_secret"
        text_encrypted = self.client.encrypt(text)
        text_decrypted = self.client.decrypt(text_encrypted)
        self.assertEqual(text, text_decrypted)

    # decrypt a known encrypted string
    def test_decrypt(self):
        text_encrypted = b'NSsVDVOegzLWF+Kpgcscgw=='
        text_decrypted = self.client.decrypt(text_encrypted)
        self.assertEqual("super_secret", text_decrypted)
Пример #4
0
    def __init__(self, hass, name, serial, accesskey, password):
        """Initialize the thermostat."""
        self.hass = hass
        self._name = name
        self._serial = serial
        self._accesskey = accesskey
        self._password = password
        self._unit_of_measurement = TEMP_CELSIUS
        self._data = {}
        self._attributes = {}
        self._attributes["connection_error_count"] = 0
        self.override_target_temp = False
        self.new_target_temp = 0

        _LOGGER.debug("Constructor for {} called.".format(self._name))

        hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, self._shutdown)

        self._client = NefitClient(serial_number=self._serial,
                                   access_key=self._accesskey,
                                   password=self._password)
        self._client.connect()
Пример #5
0
class NefitThermostat(ClimateDevice):
    """Representation of a NefitThermostat device."""
    def __init__(self, hass, name, serial, accesskey, password):
        """Initialize the thermostat."""
        self.hass = hass
        self._name = name
        self._serial = serial
        self._accesskey = accesskey
        self._password = password
        self._unit_of_measurement = TEMP_CELSIUS
        self._data = {}
        self._attributes = {}
        self._attributes["connection_error_count"] = 0
        self._override_target_temp = False
        self._new_target_temp = 0
        self._away = None

        _LOGGER.debug("Constructor for {} called.".format(self._name))

        hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, self._shutdown)

        self._client = NefitClient(serial_number=self._serial,
                                   access_key=self._accesskey,
                                   password=self._password)
        self._client.connect()

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

    @property
    def temperature_unit(self):
        """Return the unit of measurement."""
        return self._unit_of_measurement

    @property
    def operation_list(self):
        """List of available operation modes."""
        return [STATE_AUTO, STATE_MANUAL]

    def update(self):
        """Get latest data"""
        _LOGGER.debug("update called.")
        errors = []

        try:
            data = self._client.get_status()
            _LOGGER.debug("update finished. result={}".format(data))

            if type(data) is dict and "user mode" in data:
                self._attributes["connection_state"] = "ok"
            else:
                self._attributes["connection_state"] = "error"
                self._attributes["connection_error_count"] += self._attributes[
                    "connection_error_count"]

            if data:
                self._data = data

            self._attributes["boiler_indicator"] = self._data.get(
                "boiler indicator")
            self._attributes["control"] = self._data.get("control")

            r = self._client.get_year_total()
            self._attributes["year_total"] = r.get("value")
            self._attributes["year_total_unit_of_measure"] = r.get(
                "unitOfMeasure")

            r = self._client.get("/ecus/rrc/userprogram/activeprogram")
            self._attributes["active_program"] = r.get("value")

            r = self._client.get("/ecus/rrc/dayassunday/day10/active")
            self._attributes["today_as_sunday"] = (r.get("value") == "on")

            r = self._client.get("/ecus/rrc/dayassunday/day11/active")
            self._attributes["tomorrow_as_sunday"] = (r.get("value") == "on")

            r = self._client.get("/system/appliance/systemPressure")
            self._attributes["system_pressure"] = r.get("value")

            r = self._client.get(
                "/heatingCircuits/hc1/actualSupplyTemperature")
            self._attributes["supply_temp"] = r.get("value")

            r = self._client.get("/system/sensors/temperatures/outdoor_t1")
            self._attributes["outside_temp"] = r.get("value")
        except:
            _LOGGER.warning('Nefit api returned invalid data')

    @property
    def current_temperature(self):
        """Return the current temperature."""
        _LOGGER.debug("current_temperature called.")

        return self._data.get('in house temp', None)

    @property
    def current_operation(self):
        state = self._data.get("boiler indicator")
        if state == 'central heating':
            return STATE_HEAT
        elif state == 'hot water':
            return STATE_HOTWATER
        elif state == 'off':
            return STATE_ECO
        else:
            return None

    @property
    def target_temperature(self):

        #update happens too fast after setting new target, so value is not changed on server yet.
        #assume for this first update that the set target was succesful
        if self._override_target_temp:
            self._target_temperature = self._new_target_temp
            self._override_target_temp = False
        else:
            self._target_temperature = self._data.get('temp setpoint', None)

        return self._target_temperature

    def set_temperature(self, **kwargs):
        """Set new target temperature."""
        try:
            temperature = kwargs.get(ATTR_TEMPERATURE)
            _LOGGER.debug(
                "set_temperature called (temperature={}).".format(temperature))

            if temperature is None:
                return None

            self._client.set_temperature(temperature)

            self._override_target_temp = True
            self._new_target_temp = temperature

        except:
            _LOGGER.error("Error setting target temperature")

    def set_operation_mode(self, operation_mode):
        """Set new target operation mode."""
        _LOGGER.debug(
            "set_operation_mode called mode={}.".format(operation_mode))
        if operation_mode == "manual":
            self._client.put('/heatingCircuits/hc1/usermode',
                             {'value': 'manual'})
        else:
            self._client.put('/heatingCircuits/hc1/usermode',
                             {'value': 'clock'})

    @property
    def is_away_mode_on(self):
        """Return true if away mode is on."""
        endpoint = 'dhwOperationClockMode' if self._data.get(
            "user mode") == 'clock' else 'dhwOperationManualMode'
        try:
            r = self._client.get('/dhwCircuits/dhwA/' + endpoint)
            #_LOGGER.debug("Getting hot water state: " + r.get("value"))
            return r.get(
                "value") == "off"  # if hot water is off, away mode is on
        except:
            _LOGGER.error("Error getting away mode state")

        return self._away

    def turn_away_mode_on(self):
        """Turn away on."""
        endpoint = 'dhwOperationClockMode' if self._data.get(
            "user mode") == 'clock' else 'dhwOperationManualMode'

        try:
            self._client.put('/dhwCircuits/dhwA/' + endpoint, {"value": "off"})
            self._away = True
        except:
            _LOGGER.error("Error setting away mode on")

    def turn_away_mode_off(self):
        """Turn away off."""
        endpoint = 'dhwOperationClockMode' if self._data.get(
            "user mode") == 'clock' else 'dhwOperationManualMode'

        try:
            self._client.put('/dhwCircuits/dhwA/' + endpoint, {"value": "on"})
            self._away = False
        except:
            _LOGGER.error("Error setting away mode off")

    @property
    def device_state_attributes(self):
        """Return the device specific state attributes."""

        return self._attributes

    @property
    def supported_features(self):
        """Return the list of supported features."""
        return SUPPORT_FLAGS

    def _shutdown(self, event):
        _LOGGER.debug("shutdown")
        self._client.disconnect()
Пример #6
0
class NefitThermostat(ClimateDevice):
    """Representation of a NefitThermostat device."""
    def __init__(self, hass, name, serial, accesskey, password, holiday_temp,
                 holiday_duration):
        from nefit import NefitClient
        """Initialize the thermostat."""
        self.hass = hass
        self._name = name
        self._serial = serial
        self._accesskey = accesskey
        self._password = password
        self._unit_of_measurement = TEMP_CELSIUS
        self._data = {}
        self._attributes = {}
        self._attributes["connection_error_count"] = 0
        self._operation_list = [
            OPERATION_MANUAL, OPERATION_AUTO, OPERATION_HOLIDAY
        ]
        self.override_target_temp = False
        self.new_target_temp = 0
        self._manual = False
        self._holiday_mode = False
        self._holiday_temp = holiday_temp
        self._holiday_duration = holiday_duration

        _LOGGER.debug("Constructor for %s called.", self._name)

        hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, self._shutdown)

        self._client = NefitClient(serial_number=self._serial,
                                   access_key=self._accesskey,
                                   password=self._password)
        self._client.connect()

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

    @property
    def temperature_unit(self):
        """Return the unit of measurement."""
        return self._unit_of_measurement

    @property
    def operation_list(self):
        """List of available operation modes."""
        return self._operation_list

    def update(self):
        """Get latest data"""
        _LOGGER.debug("update called.")

        try:
            data = self._client.get_status()
            _LOGGER.debug("update finished. result=%s", data)

            if isinstance(data, dict) and "user mode" in data:
                self._attributes["connection_state"] = "ok"
                self._manual = (data.get("user mode") == "manual")
            else:
                self._attributes["connection_state"] = "error"
                self._attributes["connection_error_count"] += self._attributes[
                    "connection_error_count"]

            if data:
                self._data = data

            self._attributes["boiler_indicator"] = self._data.get(
                "boiler indicator")
            self._attributes["control"] = self._data.get("control")

            year_total, year_total_uom = self._client.get_year_total()
            _LOGGER.debug("Fetched get_year_total: %s %s", year_total,
                          year_total_uom)
            self._attributes["year_total"] = year_total
            self._attributes["year_total_unit_of_measure"] = year_total_uom

            r = self._client.get("/ecus/rrc/userprogram/activeprogram")
            self._attributes["active_program"] = r.get("value")

            r = self._client.get("/ecus/rrc/dayassunday/day10/active")
            self._attributes["today_as_sunday"] = (r.get("value") == "on")

            r = self._client.get("/ecus/rrc/dayassunday/day11/active")
            self._attributes["tomorrow_as_sunday"] = (r.get("value") == "on")

            r = self._client.get("/system/appliance/systemPressure")
            self._attributes["system_pressure"] = r.get("value")

            r = self._client.get(
                "/heatingCircuits/hc1/actualSupplyTemperature")
            self._attributes["supply_temp"] = r.get("value")

            r = self._client.get("/system/sensors/temperatures/outdoor_t1")
            self._attributes["outside_temp"] = r.get("value")

            r = self._client.get("/heatingCircuits/hc1/holidayMode/activated")
            self._holiday_mode = (r.get("value") == "on")

            dc = self._client.get_display_code()
            self._attributes["display_code"] = dc
        except Exception as exc:
            _LOGGER.warning("Nefit api returned invalid data: %s", exc)

    @property
    def current_temperature(self):
        """Return the current temperature."""
        _LOGGER.debug("current_temperature called.")

        return self._data.get("in house temp", None)

    @property
    def current_operation(self):
        if self._manual:
            return OPERATION_MANUAL
        elif self._holiday_mode:
            return OPERATION_HOLIDAY
        else:
            return OPERATION_AUTO

    @property
    def target_temperature(self):

        #update happens too fast after setting new target, so value is not changed on server yet.
        #assume for this first update that the set target was succesful
        if self.override_target_temp:
            self._target_temperature = self.new_target_temp
            self.override_target_temp = False
        else:
            self._target_temperature = self._data.get("temp setpoint", None)

        return self._target_temperature

    def set_temperature(self, **kwargs):
        """Set new target temperature."""
        try:
            temperature = kwargs.get(ATTR_TEMPERATURE)
            _LOGGER.debug("set_temperature called (temperature=%s).",
                          temperature)

            if temperature is None:
                return None

            self._client.set_temperature(temperature)

            self.override_target_temp = True
            self.new_target_temp = temperature

        except:
            _LOGGER.error("Error setting target temperature")

    def set_operation_mode(self, operation_mode):
        """Set new target operation mode."""
        _LOGGER.debug("set_operation_mode called mode=%s.", operation_mode)
        if operation_mode == OPERATION_HOLIDAY:
            self.turn_holidaymode_on()
        else:
            if self._holiday_mode:
                self.turn_holidaymode_off()
            if operation_mode == OPERATION_MANUAL:
                self._client.put("/heatingCircuits/hc1/usermode",
                                 {"value": "manual"})
            else:
                self._client.put("/heatingCircuits/hc1/usermode",
                                 {"value": "clock"})
        self.schedule_update_ha_state()

    @property
    def device_state_attributes(self):
        """Return the device specific state attributes."""
        return self._attributes

    @property
    def supported_features(self):
        """Return the list of supported features."""
        return SUPPORT_FLAGS

    @property
    def is_on(self):
        """Return true if the device is on."""
        return self._manual or not self._holiday_mode

    def _shutdown(self, event):
        _LOGGER.debug("shutdown")
        self._client.disconnect()

    def turn_on(self):
        """Turn on."""
        self.set_operation_mode(OPERATION_AUTO)
        self.schedule_update_ha_state()

    def turn_off(self):
        """Turn off."""
        self.set_operation_mode(OPERATION_HOLIDAY)
        self.schedule_update_ha_state()

    def turn_holidaymode_on(self):
        if self._manual:
            self._client.put("/heatingCircuits/hc1/usermode",
                             {"value": "clock"})

        start_data = self._client.get("/heatingCircuits/hc1/holidayMode/start")
        start = datetime.strptime(start_data["value"], DATE_FORMAT)
        end = start + timedelta(days=self._holiday_duration)
        self._client.put("/heatingCircuits/hc1/holidayMode/activated",
                         {"value": "on"})
        self._client.put("/heatingCircuits/hc1/holidayMode/temperature",
                         {"value": self._holiday_temp})
        self._client.put("/heatingCircuits/hc1/holidayMode/end",
                         {"value": end.strftime(DATE_FORMAT)})

        self.override_target_temp = True
        self.new_target_temp = self._holiday_temp
        self._holiday_mode = True

    def turn_holidaymode_off(self):
        self._client.put("/heatingCircuits/hc1/holidayMode/activated",
                         {"value": "off"})
        self._holiday_mode = False
Пример #7
0
 def setUp(self):
     self.client = NefitClient(123456789, "abc1abc2abc3abc4",
                               "passworddddd")