Skip to content

Commit

Permalink
Merge pull request #22 from claudegel/new-devices
Browse files Browse the repository at this point in the history
Added support for new devices
  • Loading branch information
claudegel authored Jan 1, 2021
2 parents 6e4120c + 5553485 commit 8e64237
Show file tree
Hide file tree
Showing 7 changed files with 223 additions and 63 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Here is a list of currently supported devices. Basically, it's everything that c
- Sinopé TH1300ZB 3600W Floor heating thermostat
- Sinopé TH1400ZB Low voltage thermostat
- Sinopé TH1500ZB 3600W double pole thermostat
- Ouellet OTH4000-ZB 4000W Line voltage thermostat
- Ouellet OTH3600-GA-ZB Floor thermostat
- Wifi thermostats
- Sinopé TH1124WF wifi 4000W Line voltage thermostat
- Sinopé TH1123WF wifi 3000W Line voltage thermostat
Expand Down
49 changes: 27 additions & 22 deletions custom_components/neviweb130/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,25 @@

import homeassistant.helpers.config_validation as cv
from homeassistant.helpers import discovery
from homeassistant.const import (CONF_USERNAME, CONF_EMAIL, CONF_PASSWORD,
CONF_SCAN_INTERVAL)
from homeassistant.const import (
CONF_USERNAME,
CONF_EMAIL,
CONF_PASSWORD,
CONF_SCAN_INTERVAL,
)
from homeassistant.util import Throttle
from .const import (DOMAIN, CONF_NETWORK, ATTR_INTENSITY, ATTR_ONOFF, ATTR_POWER_MODE,
ATTR_SETPOINT_MODE, ATTR_ROOM_SETPOINT, ATTR_SIGNATURE)

VERSION = '0.1.8'
from .const import (
DOMAIN,
CONF_NETWORK,
ATTR_INTENSITY,
ATTR_ONOFF,
ATTR_POWER_MODE,
ATTR_SETPOINT_MODE,
ATTR_ROOM_SETPOINT,
ATTR_SIGNATURE,
)

VERSION = '0.1.9'

_LOGGER = logging.getLogger(__name__)

Expand All @@ -32,9 +44,11 @@
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_NETWORK): cv.string,
vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL):
cv.time_period
cv.time_period,
})
}, extra=vol.ALLOW_EXTRA)
},
extra=vol.ALLOW_EXTRA,
)

def setup(hass, hass_config):
"""Set up neviweb130."""
Expand Down Expand Up @@ -63,15 +77,6 @@ def __init__(self, config):
network = config.get(CONF_NETWORK)
self.neviweb130_client = Neviweb130Client(username, password, network)

# Need some refactoring here concerning the class used to transport data
# @Throttle(SCAN_INTERVAL)
# def update(self):
# """Get the latest data from pyneviweb."""
# self.neviweb130_client.update()
# _LOGGER.debug("Neviweb130 data updated successfully")



# According to HA:
# https://developers.home-assistant.io/docs/en/creating_component_code_review.html
# "All API specific code has to be part of a third party library hosted on PyPi.
Expand All @@ -83,9 +88,9 @@ class PyNeviweb130Error(Exception):

class Neviweb130Client(object):

def __init__(self, email, password, network, timeout=REQUESTS_TIMEOUT):
def __init__(self, username, password, network, timeout=REQUESTS_TIMEOUT):
"""Initialize the client object."""
self._email = email
self._email = username
self._password = password
self._network_name = network
self._gateway_id = None
Expand All @@ -108,8 +113,8 @@ def __post_login_page(self):
"interface": "neviweb", "stayConnected": 1}
try:
raw_res = requests.post(LOGIN_URL, data=data,
cookies=self._cookies, allow_redirects=False,
timeout=self._timeout)
cookies = self._cookies, allow_redirects=False,
timeout = self._timeout)
except OSError:
raise PyNeviweb130Error("Cannot submit login form")
if raw_res.status_code != 200:
Expand Down Expand Up @@ -176,7 +181,7 @@ def __get_gateway_data(self):
if ATTR_SIGNATURE in data:
device[ATTR_SIGNATURE] = data[ATTR_SIGNATURE]
_LOGGER.debug("Received signature data: %s", data) ###
# _LOGGER.debug("Updated gateway data: %s", self.gateway_data)
# _LOGGER.debug("Updated gateway data: %s", self.gateway_data)

def get_device_attributes(self, device_id, attributes):
"""Get device attributes."""
Expand Down
110 changes: 88 additions & 22 deletions custom_components/neviweb130/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
model 1123 = thermostat TH1123ZB 3000W
model 1124 = thermostat TH1124ZB 4000W
model 737 = thermostat TH1300ZB 3600W (floor)
model 1500 = thermostat TH1500ZB double pole thermostat
model 7373 = thermostat TH1500ZB double pole thermostat
model 7372 = thermostat TH1400ZB low voltage
model 1124 = thermostat OTH4000-ZB Ouellet
model 737 = thermostat OTH3600-GA-ZB Ouellet
Support for Neviweb wifi thermostats
model 1510 = thermostat TH1123WF 3000W (wifi)
Expand All @@ -24,47 +26,95 @@
import custom_components.neviweb130 as neviweb130
from . import (SCAN_INTERVAL)
from homeassistant.components.climate import ClimateEntity
from homeassistant.components.climate.const import (HVAC_MODE_HEAT,
HVAC_MODE_OFF, HVAC_MODE_AUTO, SUPPORT_TARGET_TEMPERATURE,
SUPPORT_PRESET_MODE, PRESET_AWAY, PRESET_NONE, CURRENT_HVAC_HEAT,
CURRENT_HVAC_IDLE, CURRENT_HVAC_OFF)
from homeassistant.const import (TEMP_CELSIUS, TEMP_FAHRENHEIT,
ATTR_TEMPERATURE)
from homeassistant.components.climate.const import (
HVAC_MODE_HEAT,
HVAC_MODE_OFF,
HVAC_MODE_AUTO,
SUPPORT_TARGET_TEMPERATURE,
SUPPORT_PRESET_MODE,
PRESET_AWAY,
PRESET_NONE,
CURRENT_HVAC_HEAT,
CURRENT_HVAC_IDLE,
CURRENT_HVAC_OFF,
)
from homeassistant.const import (
DEVICE_CLASS_TEMPERATURE,
TEMP_CELSIUS,
TEMP_FAHRENHEIT,
ATTR_TEMPERATURE,
)
from datetime import timedelta
from homeassistant.helpers.event import track_time_interval
from .const import (DOMAIN, ATTR_SETPOINT_MODE, ATTR_ROOM_SETPOINT,
ATTR_OUTPUT_PERCENT_DISPLAY, ATTR_ROOM_TEMPERATURE, ATTR_ROOM_SETPOINT_MIN,
ATTR_ROOM_SETPOINT_MAX, ATTR_WATTAGE, ATTR_GFCI_STATUS, ATTR_FLOOR_MODE, MODE_AUTO, MODE_AUTO_BYPASS,
MODE_MANUAL, MODE_OFF, MODE_AWAY, ATTR_FLOOR_AUX, ATTR_FLOOR_OUTPUT2, ATTR_KEYPAD, ATTR_WIFI_FLOOR_OUTPUT1,
ATTR_WIFI_WATTAGE, ATTR_WIFI, ATTR_WIFI_DISPLAY2, ATTR_WIFI_KEYPAD)
from .const import (
DOMAIN,
ATTR_SETPOINT_MODE,
ATTR_ROOM_SETPOINT,
ATTR_OUTPUT_PERCENT_DISPLAY,
ATTR_ROOM_TEMPERATURE,
ATTR_ROOM_SETPOINT_MIN,
ATTR_ROOM_SETPOINT_MAX,
ATTR_WATTAGE,
ATTR_GFCI_STATUS,
ATTR_FLOOR_MODE,
ATTR_OCCUPANCY,
ATTR_FLOOR_AUX,
ATTR_FLOOR_OUTPUT2,
ATTR_KEYPAD,
ATTR_OCCUPANCY,
ATTR_BACKLIGHT,
ATTR_WIFI_FLOOR_OUTPUT1,
ATTR_WIFI_WATTAGE,
ATTR_WIFI,
ATTR_WIFI_DISPLAY2,
ATTR_WIFI_KEYPAD,
MODE_AUTO,
MODE_AUTO_BYPASS,
MODE_MANUAL,
MODE_OFF,
MODE_AWAY,
)

_LOGGER = logging.getLogger(__name__)

SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_PRESET_MODE)

DEFAULT_NAME = "neviweb130 climate"

UPDATE_ATTRIBUTES = [ATTR_ROOM_SETPOINT,
ATTR_OUTPUT_PERCENT_DISPLAY, ATTR_ROOM_TEMPERATURE, ATTR_ROOM_SETPOINT_MIN,
ATTR_ROOM_SETPOINT_MAX]
UPDATE_ATTRIBUTES = [
ATTR_ROOM_SETPOINT,
ATTR_OUTPUT_PERCENT_DISPLAY,
ATTR_ROOM_TEMPERATURE,
ATTR_ROOM_SETPOINT_MIN,
ATTR_ROOM_SETPOINT_MAX,
]

SUPPORTED_HVAC_MODES = [HVAC_MODE_OFF, HVAC_MODE_AUTO, HVAC_MODE_HEAT]
SUPPORTED_HVAC_MODES = [
HVAC_MODE_OFF,
HVAC_MODE_AUTO,
HVAC_MODE_HEAT,
]

PRESET_BYPASS = 'temporary'
PRESET_MODES = [
PRESET_NONE,
PRESET_AWAY,
PRESET_BYPASS
PRESET_BYPASS,
]

DEVICE_MODEL_LOW = [7372]
DEVICE_MODEL_FLOOR = [737]
DEVICE_MODEL_WIFI_FLOOR = [738]
DEVICE_MODEL_WIFI = [1510]
DEVICE_MODEL_HEAT = [1123, 1124, 1500]
DEVICE_MODEL_HEAT = [1123, 1124, 7373]
IMPLEMENTED_DEVICE_MODEL = DEVICE_MODEL_HEAT + DEVICE_MODEL_FLOOR + DEVICE_MODEL_LOW + DEVICE_MODEL_WIFI_FLOOR + DEVICE_MODEL_WIFI

async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
async def async_setup_platform(
hass,
config,
async_add_entities,
discovery_info=None,
):
"""Set up the neviweb130 thermostats."""
data = hass.data[DOMAIN]

Expand Down Expand Up @@ -100,7 +150,9 @@ def __init__(self, data, device_info, name):
self._load2 = 0
self._load2_status = None
self._rssi = None
self._occupancy = None
self._wifi_display2 = None
self._backlight = None
self._is_floor = device_info["signature"]["model"] in \
DEVICE_MODEL_FLOOR
self._is_wifi_floor = device_info["signature"]["model"] in \
Expand All @@ -125,9 +177,9 @@ def update(self):
else:
WIFI_FLOOR_ATTRIBUTE = []
if self._is_wifi:
WIFI_ATTRIBUTE = [ATTR_WIFI_WATTAGE, ATTR_WIFI, ATTR_WIFI_KEYPAD, ATTR_WIFI_DISPLAY2, ATTR_SETPOINT_MODE]
WIFI_ATTRIBUTE = [ATTR_WIFI_WATTAGE, ATTR_WIFI, ATTR_WIFI_KEYPAD, ATTR_WIFI_DISPLAY2, ATTR_SETPOINT_MODE, ATTR_OCCUPANCY]
else:
WIFI_ATTRIBUTE = [ATTR_KEYPAD]
WIFI_ATTRIBUTE = [ATTR_KEYPAD, ATTR_BACKLIGHT]
"""Get the latest data from Neviweb and update the state."""
start = time.time()
device_data = self._client.get_device_attributes(self._id,
Expand All @@ -146,6 +198,7 @@ def update(self):
if not self._is_wifi:
self._heat_level = device_data[ATTR_OUTPUT_PERCENT_DISPLAY]
self._keypad = device_data[ATTR_KEYPAD]
self._backlight = device_data[ATTR_BACKLIGHT]
self._rssi = None
if not self._is_low_voltage:
self._wattage = device_data[ATTR_WATTAGE]
Expand All @@ -156,6 +209,7 @@ def update(self):
self._wifi_display2 = device_data[ATTR_WIFI_DISPLAY2]
self._wattage = device_data[ATTR_WIFI_WATTAGE]
self._operation_mode = device_data[ATTR_SETPOINT_MODE]
self._occupancy = device_data[ATTR_OCCUPANCY]
if self._is_floor or self._is_wifi_floor:
self._gfci_status = device_data[ATTR_GFCI_STATUS]
self._floor_mode = device_data[ATTR_FLOOR_MODE]
Expand All @@ -181,6 +235,16 @@ def name(self):
"""Return the name of the thermostat."""
return self._name

@property
def unit_of_measurement(self):
"""Return the unit of measurement of this entity, if any."""
return TEMP_CELSIUS

@property
def device_class(self):
"""Return the device class of this entity."""
return DEVICE_CLASS_TEMPERATURE

@property
def device_state_attributes(self):
"""Return the state attributes."""
Expand All @@ -194,9 +258,11 @@ def device_state_attributes(self):
'slave_status': self._load2_status,
'slave_load': self._load2})
if self._is_wifi:
data.update({'second display': self._wifi_display2})
data.update({'second display': self._wifi_display2,
'occupancy': self._occupancy})
data.update({'heat_level': self._heat_level,
'keypad': self._keypad,
'backlight': self._backlight,
'rssi': self._rssi,
'id': self._id})
return data
Expand Down
3 changes: 3 additions & 0 deletions custom_components/neviweb130/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@
ATTR_FLOOR_OUTPUT2 = "loadWattOutput2"
ATTR_FLOOR_AUX = "auxHeatConfig"
ATTR_KEYPAD = "lockKeypad"
ATTR_OCCUPANCY = "occupancyMode"
ATTR_WIFI_FLOOR_OUTPUT1 = "loadWattOutput1"
ATTR_WIFI_WATTAGE = "loadWatt"
ATTR_WIFI = "wifiRssi"
ATTR_WIFI_DISPLAY2 = "config2ndDisplay"
ATTR_WIFI_KEYPAD = "keyboardLock"
ATTR_SWITCH_TIMER = "powerTimer"
ATTR_DRSTATUS = "drStatus"
ATTR_BACKLIGHT = "backlightAdaptive"

MODE_AUTO = "auto"
MODE_AUTO_BYPASS = "autoBypass"
Expand Down
Loading

0 comments on commit 8e64237

Please sign in to comment.