Skip to content

Commit

Permalink
Merge branch 'master' into switch-channel-names
Browse files Browse the repository at this point in the history
  • Loading branch information
twhittock committed Nov 3, 2019
2 parents f4079de + 05bf512 commit bc8a9d9
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 37 deletions.
7 changes: 4 additions & 3 deletions custom_components/meross_cloud/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import homeassistant.helpers.config_validation as cv
import voluptuous as vol
from homeassistant.const import CONF_USERNAME, CONF_PASSWORD
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.exceptions import PlatformNotReady
from homeassistant.helpers import discovery
from homeassistant.helpers.event import async_track_time_interval
Expand All @@ -16,8 +16,9 @@
from meross_iot.manager import MerossManager
from meross_iot.meross_event import MerossEventType

from .common import (DOMAIN, HA_SWITCH, HA_SENSOR, HA_LIGHT, HA_COVER, ENROLLED_DEVICES,
notify_error, dismiss_notification, MANAGER, SENSORS)
from .common import (DOMAIN, ENROLLED_DEVICES, HA_COVER, HA_LIGHT, HA_SENSOR,
HA_SWITCH, MANAGER, SENSORS, dismiss_notification,
notify_error)

_LOGGER = logging.getLogger(__name__)

Expand Down
12 changes: 6 additions & 6 deletions custom_components/meross_cloud/cover.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from homeassistant.components.cover import CoverDevice, SUPPORT_OPEN, SUPPORT_CLOSE
from homeassistant.const import STATE_CLOSED, STATE_OPEN, STATE_OPENING, STATE_CLOSING, STATE_UNKNOWN
from homeassistant.components.cover import (SUPPORT_CLOSE, SUPPORT_OPEN,
CoverDevice)
from homeassistant.const import (STATE_CLOSED, STATE_CLOSING, STATE_OPEN,
STATE_OPENING, STATE_UNKNOWN)
from meross_iot.cloud.devices.door_openers import GenericGarageDoorOpener

from .common import (calculate_gerage_door_opener_id, DOMAIN, ENROLLED_DEVICES, MANAGER)
from .common import (DOMAIN, ENROLLED_DEVICES, MANAGER,
calculate_gerage_door_opener_id)

ATTR_DOOR_STATE = 'door_state'

Expand Down Expand Up @@ -118,9 +121,6 @@ def supported_features(self):
"""Flag supported features."""
return SUPPORT_OPEN | SUPPORT_CLOSE

@property
def unique_id(self) -> str:
return self._id

async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
switch_devices = []
Expand Down
94 changes: 69 additions & 25 deletions custom_components/meross_cloud/light.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
import colorsys
import homeassistant.util.color as color_util
import logging
from homeassistant.components.light import (Light, SUPPORT_BRIGHTNESS, SUPPORT_COLOR, SUPPORT_COLOR_TEMP,
ATTR_HS_COLOR, ATTR_COLOR_TEMP, ATTR_BRIGHTNESS)
from meross_iot.cloud.devices.light_bulbs import GenericBulb
from .common import calculate_switch_id, DOMAIN, ENROLLED_DEVICES, MANAGER

from homeassistant.components.light import Light, SUPPORT_BRIGHTNESS, SUPPORT_COLOR
from meross_iot.cloud.devices.light_bulbs import GenericBulb, to_rgb
_LOGGER = logging.getLogger(__name__)

from .common import (calculate_switch_id, DOMAIN, ENROLLED_DEVICES, MANAGER)

def rgb_int_to_tuple(color):
blue = color & 255
green = (color >> 8) & 255
red = (color >> 16) & 255
return (red, green, blue)


def expand_status(status):
"Expand the status information for readability"
out = dict(status)
out['rgb'] = rgb_int_to_tuple(status['rgb'])
return out


class LightEntityWrapper(Light):
Expand All @@ -26,6 +42,7 @@ def __init__(self, device: GenericBulb, channel: int):
self._device.register_event_callback(self.handler)

def handler(self, evt):
_LOGGER.debug("event_handler(name=%r, evt=%r)" % (self._device_name, repr(vars((evt)))))
self.async_schedule_update_ha_state(False)

@property
Expand All @@ -50,43 +67,70 @@ def is_on(self) -> bool:
return self._device.get_channel_status(self._channel_id).get('onoff')

def turn_off(self, **kwargs) -> None:
_LOGGER.debug('turn_off(name=%r)' % self._device_name)
self._device.turn_off(channel=self._channel_id)

def turn_on(self, **kwargs) -> None:
self._device.turn_on(channel=self._channel_id)
rgb = self._device.get_light_color(self._channel_id).get('rgb')
brightness = self._device.get_light_color(self._channel_id).get('luminance')

if 'hs_color' in kwargs:
h, s = kwargs['hs_color']
r, g, b = colorsys.hsv_to_rgb(h/360, s/100, 255)
rgb = to_rgb((int(r), int(g), int(b)))
elif 'brightness' in kwargs:
brightness = kwargs['brightness'] / 255 * 100

self._device.set_light_color(self._channel_id, rgb=rgb, luminance=brightness)
if not self.is_on:
_LOGGER.debug('turn_on(name=%r)' % (self._device_name))
self._device.turn_on(channel=self._channel_id) # Avoid a potential response event race between setting on and below set_light_color

# Color is taken from either of these 2 values, but not both.
if ATTR_HS_COLOR in kwargs:
h, s = kwargs[ATTR_HS_COLOR]
rgb = color_util.color_hsv_to_RGB(h, s, 100)
_LOGGER.debug("color change: rgb=%r -- h=%r s=%r" % (rgb, h, s))
self._device.set_light_color(self._channel_id, rgb=rgb)
elif ATTR_COLOR_TEMP in kwargs:
mired = kwargs[ATTR_COLOR_TEMP]
norm_value = (mired - self.min_mireds) / (self.max_mireds - self.min_mireds)
temperature = 100 - (norm_value * 100)
_LOGGER.debug("temperature change: mired=%r meross=%r" % (mired, temperature))
self._device.set_light_color(self._channel_id, temperature=temperature)

# Brightness must always be set, so take previous luminance if not explicitly set now.
if ATTR_BRIGHTNESS in kwargs:
brightness = kwargs[ATTR_BRIGHTNESS] * 100 / 255
_LOGGER.debug(" brightness change: %r" % brightness)
self._device.set_light_color(self._channel_id, luminance=brightness)

@property
def brightness(self):
# Meross bulbs support luminance between 0 and 100;
# while the HA wants values from 0 to 255. Therefore, we need to scale the values.
status = self._device.get_status(self._channel_id)
_LOGGER.debug('get_brightness(name=%r status=%r)' % (self._device_name, expand_status(status)))
return status.get('luminance') / 100 * 255

@property
def hs_color(self):
color = self._device.get_channel_status(self._channel_id).get('rgb')
blue = color & 255
green = (color >> 8) & 255
red = (color >> 16) & 255
h, s, v = colorsys.rgb_to_hsv(red, green, blue)
return [h*360, s*100]
status = self._device.get_channel_status(self._channel_id)
_LOGGER.debug('get_hs_color(name=%r status=%r)' % (self._device_name, expand_status(status)))
if status.get('capacity') == 5: # rgb mode
rgb = rgb_int_to_tuple(status.get('rgb'))
return color_util.color_RGB_to_hs(*rgb)
return None

@property
def supported_features(self):
return SUPPORT_BRIGHTNESS | SUPPORT_COLOR
def color_temp(self):
status = self._device.get_channel_status(self._channel_id)
_LOGGER.debug('get_color_temp(name=%r status=%r)' % (self._device_name, expand_status(status)))
if status.get('capacity') == 6: # White light mode
value = status.get('temperature')
norm_value = (100 - value) / 100.0
return self.min_mireds + (norm_value * (self.max_mireds - self.min_mireds))
return None

# TODO: Handle temperature/luminance support.
@property
def supported_features(self):
flags = 0
if self._device.supports_luminance():
flags |= SUPPORT_BRIGHTNESS
if self._device.is_rgb():
flags |= SUPPORT_COLOR
if self._device.is_light_temperature():
flags |= SUPPORT_COLOR_TEMP
return flags


async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
Expand Down
2 changes: 1 addition & 1 deletion custom_components/meross_cloud/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
"documentation": "https://www.home-assistant.io/components/meross_cloud",
"dependencies": ["persistent_notification"],
"codeowners": ["@albertogeniola"],
"requirements": ["meross_iot==0.3.1.5"]
"requirements": ["meross_iot==0.3.1.7"]
}
3 changes: 2 additions & 1 deletion custom_components/meross_cloud/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
from homeassistant.helpers.entity import Entity
from meross_iot.cloud.device import AbstractMerossDevice

from .common import (calculate_sensor_id, DOMAIN, SENSORS, ENROLLED_DEVICES, MANAGER)
from .common import (DOMAIN, ENROLLED_DEVICES, MANAGER, SENSORS,
calculate_sensor_id)


class PowerSensorWrapper(Entity):
Expand Down
3 changes: 2 additions & 1 deletion custom_components/meross_cloud/switch.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from homeassistant.components.switch import SwitchDevice
from meross_iot.cloud.devices.power_plugs import GenericPlug
from .common import (calculate_switch_id, DOMAIN, ENROLLED_DEVICES, MANAGER)

from .common import DOMAIN, ENROLLED_DEVICES, MANAGER, calculate_switch_id


class SwitchEntityWrapper(SwitchDevice):
Expand Down

0 comments on commit bc8a9d9

Please sign in to comment.