Compare commits

..

7 Commits

Author SHA1 Message Date
andvikt
03462edf83 Merge pull request #156 from andvikt/dev
Dev
2023-10-09 14:59:50 +03:00
andvikt
8847290457 Merge pull request #124 from andvikt/dev
Dev
2022-09-08 13:28:01 +03:00
andvikt
36dfad1697 Merge pull request #113 from andvikt/dev
Dev
2022-07-22 10:17:28 +03:00
andvikt
dee0d6d1a7 Merge pull request #109 from wrt54g/hacs-url
Update HACS URL
2022-07-22 10:14:57 +03:00
Sven Serlier
da7305c07b Update HACS URL 2022-06-02 06:49:56 +02:00
andvikt
d3f3eeedc5 Update index.md 2022-02-11 21:43:58 +03:00
andvikt
16ad1ea4d2 Merge pull request #97 from andvikt/dev
Dev
2021-12-15 16:58:42 +03:00
5 changed files with 54 additions and 72 deletions

View File

@@ -1,5 +1,5 @@
[bumpversion] [bumpversion]
current_version = 1.1.8b3 current_version = 1.1.7
parse = (?P<major>\d+)(\.(?P<minor>\d+))(\.(?P<patch>\d+))(?P<release>[bf]*)(?P<build>\d*) parse = (?P<major>\d+)(\.(?P<minor>\d+))(\.(?P<patch>\d+))(?P<release>[bf]*)(?P<build>\d*)
commit = True commit = True
tag = True tag = True

View File

@@ -16,9 +16,7 @@ from homeassistant.components.light import (
SUPPORT_BRIGHTNESS, SUPPORT_BRIGHTNESS,
LightEntity, LightEntity,
SUPPORT_TRANSITION, SUPPORT_TRANSITION,
SUPPORT_COLOR, SUPPORT_COLOR, ColorMode, LightEntityFeature,
ColorMode,
LightEntityFeature,
# SUPPORT_WHITE_VALUE # SUPPORT_WHITE_VALUE
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
@@ -38,15 +36,7 @@ from .const import (
CONF_SWITCH, CONF_SWITCH,
DOMAIN, DOMAIN,
CONF_CUSTOM, CONF_CUSTOM,
CONF_SKIP, CONF_SKIP, CONF_LED, CONF_WS28XX, CONF_PORTS, CONF_WHITE_SEP, CONF_SMOOTH, CONF_ORDER, CONF_CHIP, RGB,
CONF_LED,
CONF_WS28XX,
CONF_PORTS,
CONF_WHITE_SEP,
CONF_SMOOTH,
CONF_ORDER,
CONF_CHIP,
RGB,
) )
from .tools import int_ignore, map_reorder_rgb from .tools import int_ignore, map_reorder_rgb
@@ -74,17 +64,13 @@ PLATFORM_SCHEMA = LIGHT_SCHEMA.extend(
async def async_setup_platform(hass, config, add_entities, discovery_info=None): async def async_setup_platform(hass, config, add_entities, discovery_info=None):
lg.warning( lg.warning('mega integration does not support yaml for lights, please use UI configuration')
"mega integration does not support yaml for lights, please use UI configuration"
)
return True return True
async def async_setup_entry( async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry, async_add_devices):
hass: HomeAssistant, config_entry: ConfigEntry, async_add_devices
):
mid = config_entry.data[CONF_ID] mid = config_entry.data[CONF_ID]
hub: MegaD = hass.data["mega"][mid] hub: MegaD = hass.data['mega'][mid]
devices = [] devices = []
customize = hass.data.get(DOMAIN, {}).get(CONF_CUSTOM, {}).get(mid, {}) customize = hass.data.get(DOMAIN, {}).get(CONF_CUSTOM, {}).get(mid, {})
skip = [] skip = []
@@ -92,29 +78,23 @@ async def async_setup_entry(
for entity_id, conf in customize[CONF_LED].items(): for entity_id, conf in customize[CONF_LED].items():
ports = conf.get(CONF_PORTS) or [conf.get(CONF_PORT)] ports = conf.get(CONF_PORTS) or [conf.get(CONF_PORT)]
skip.extend(ports) skip.extend(ports)
devices.append( devices.append(MegaRGBW(
MegaRGBW( mega=hub,
mega=hub, port=ports,
port=ports, name=entity_id,
name=entity_id, customize=conf,
customize=conf, id_suffix=entity_id,
id_suffix=entity_id, config_entry=config_entry
config_entry=config_entry, ))
) for port, cfg in config_entry.data.get('light', {}).items():
)
for port, cfg in config_entry.data.get("light", {}).items():
port = int_ignore(port) port = int_ignore(port)
c = customize.get(port, {}) c = customize.get(port, {})
if ( if c.get(CONF_SKIP, False) or port in skip or c.get(CONF_DOMAIN, 'light') != 'light':
c.get(CONF_SKIP, False)
or port in skip
or c.get(CONF_DOMAIN, "light") != "light"
):
continue continue
for data in cfg: for data in cfg:
hub.lg.debug(f"add light on port %s with data %s", port, data) hub.lg.debug(f'add light on port %s with data %s', port, data)
light = MegaLight(mega=hub, port=port, config_entry=config_entry, **data) light = MegaLight(mega=hub, port=port, config_entry=config_entry, **data)
if "<" in light.name: if '<' in light.name:
continue continue
devices.append(light) devices.append(light)
@@ -122,14 +102,17 @@ async def async_setup_entry(
class MegaLight(MegaOutPort, LightEntity): class MegaLight(MegaOutPort, LightEntity):
@property @property
def supported_features(self): def supported_features(self):
return (SUPPORT_BRIGHTNESS if self.dimmer else 0) | ( return (
SUPPORT_TRANSITION if self.dimmer else 0 (SUPPORT_BRIGHTNESS if self.dimmer else 0) |
(SUPPORT_TRANSITION if self.dimmer else 0)
) )
class MegaRGBW(LightEntity, BaseMegaEntity): class MegaRGBW(LightEntity, BaseMegaEntity):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self._is_on = None self._is_on = None
@@ -140,7 +123,7 @@ class MegaRGBW(LightEntity, BaseMegaEntity):
self._task: asyncio.Task = None self._task: asyncio.Task = None
self._restore = None self._restore = None
self.smooth: timedelta = self.customize[CONF_SMOOTH] self.smooth: timedelta = self.customize[CONF_SMOOTH]
self._color_order = self.customize.get(CONF_ORDER, "rgb") self._color_order = self.customize.get(CONF_ORDER, 'rgb')
self._last_called: float = 0 self._last_called: float = 0
self._max_values = None self._max_values = None
@@ -163,11 +146,12 @@ class MegaRGBW(LightEntity, BaseMegaEntity):
def is_ws(self): def is_ws(self):
return self.customize.get(CONF_WS28XX) return self.customize.get(CONF_WS28XX)
@property @property
def supported_color_modes(self) -> set[ColorMode] | set[str] | None: def supported_color_modes(self) -> set[ColorMode] | set[str] | None:
return { return {
ColorMode.BRIGHTNESS, ColorMode.BRIGHTNESS,
ColorMode.RGB if len(self.port) != 4 else ColorMode.RGBW, ColorMode.RGB if len(self.port) != 4 else ColorMode.RGBW
} }
@property @property
@@ -180,7 +164,7 @@ class MegaRGBW(LightEntity, BaseMegaEntity):
@property @property
def white_value(self): def white_value(self):
# if self.supported_features & SUPPORT_WHITE_VALUE: # if self.supported_features & SUPPORT_WHITE_VALUE:
return float(self.get_attribute("white_value", 0)) return float(self.get_attribute('white_value', 0))
@property @property
def rgb_color(self) -> tuple[int, int, int] | None: def rgb_color(self) -> tuple[int, int, int] | None:
@@ -193,15 +177,15 @@ class MegaRGBW(LightEntity, BaseMegaEntity):
@property @property
def brightness(self): def brightness(self):
return float(self.get_attribute("brightness", 0)) return float(self.get_attribute('brightness', 0))
@property @property
def hs_color(self): def hs_color(self):
return self.get_attribute("hs_color", [0, 0]) return self.get_attribute('hs_color', [0, 0])
@property @property
def is_on(self): def is_on(self):
return self.get_attribute("is_on", False) return self.get_attribute('is_on', False)
@property @property
def supported_features(self): def supported_features(self):
@@ -211,7 +195,7 @@ class MegaRGBW(LightEntity, BaseMegaEntity):
if not self.is_on: if not self.is_on:
return [0 for x in range(len(self.port))] if not self.is_ws else [0] * 3 return [0 for x in range(len(self.port))] if not self.is_ws else [0] * 3
rgb = colorsys.hsv_to_rgb( rgb = colorsys.hsv_to_rgb(
self.hs_color[0] / 360, self.hs_color[1] / 100, self.brightness / 255 self.hs_color[0]/360, self.hs_color[1]/100, self.brightness / 255
) )
rgb = [x for x in rgb] rgb = [x for x in rgb]
if self.white_value is not None: if self.white_value is not None:
@@ -219,7 +203,9 @@ class MegaRGBW(LightEntity, BaseMegaEntity):
if not self.customize.get(CONF_WHITE_SEP): if not self.customize.get(CONF_WHITE_SEP):
white = white * (self.brightness / 255) white = white * (self.brightness / 255)
rgb.append(white / 255) rgb.append(white / 255)
rgb = [round(x * self.max_values[i]) for i, x in enumerate(rgb)] rgb = [
round(x * self.max_values[i]) for i, x in enumerate(rgb)
]
if self.is_ws: if self.is_ws:
# восстанавливаем мэпинг # восстанавливаем мэпинг
rgb = map_reorder_rgb(rgb, RGB, self._color_order) rgb = map_reorder_rgb(rgb, RGB, self._color_order)
@@ -229,7 +215,7 @@ class MegaRGBW(LightEntity, BaseMegaEntity):
if (time.time() - self._last_called) < 0.1: if (time.time() - self._last_called) < 0.1:
return return
self._last_called = time.time() self._last_called = time.time()
self.lg.debug(f"turn on %s with kwargs %s", self.entity_id, kwargs) self.lg.debug(f'turn on %s with kwargs %s', self.entity_id, kwargs)
if self._restore is not None: if self._restore is not None:
self._restore.update(kwargs) self._restore.update(kwargs)
kwargs = self._restore kwargs = self._restore
@@ -245,9 +231,9 @@ class MegaRGBW(LightEntity, BaseMegaEntity):
return return
self._last_called = time.time() self._last_called = time.time()
self._restore = { self._restore = {
"hs_color": self.hs_color, 'hs_color': self.hs_color,
"brightness": self.brightness, 'brightness': self.brightness,
"white_value": self.white_value, 'white_value': self.white_value,
} }
_before = self.get_rgbw() _before = self.get_rgbw()
self._is_on = False self._is_on = False
@@ -256,22 +242,18 @@ class MegaRGBW(LightEntity, BaseMegaEntity):
self._task = asyncio.create_task(self.set_color(_before, **kwargs)) self._task = asyncio.create_task(self.set_color(_before, **kwargs))
async def set_color(self, _before, **kwargs): async def set_color(self, _before, **kwargs):
transition = kwargs.get("transition") transition = kwargs.get('transition')
update_state = transition is not None and transition > 3 update_state = transition is not None and transition > 3
_after = None
for item, value in kwargs.items(): for item, value in kwargs.items():
setattr(self, f"_{item}", value) setattr(self, f'_{item}', value)
if item == "rgb_color": _after = self.get_rgbw()
_after = map_reorder_rgb(value, RGB, self._color_order) self._rgb_color = tuple(_after[:3])
self._hs_color = colorsys.rgb_to_hsv(*value)
_after = _after or self.get_rgbw()
self._rgb_color = map_reorder_rgb(tuple(_after[:3]), self._color_order, RGB)
if transition is None: if transition is None:
transition = self.smooth.total_seconds() transition = self.smooth.total_seconds()
ratio = self.calc_speed_ratio(_before, _after) ratio = self.calc_speed_ratio(_before, _after)
transition = transition * ratio transition = transition * ratio
self.async_write_ha_state() self.async_write_ha_state()
ports = self.port if not self.is_ws else self.port * 3 ports = self.port if not self.is_ws else self.port*3
config = [(port, _before[i], _after[i]) for i, port in enumerate(ports)] config = [(port, _before[i], _after[i]) for i, port in enumerate(ports)]
try: try:
await self.mega.smooth_dim( await self.mega.smooth_dim(
@@ -287,7 +269,7 @@ class MegaRGBW(LightEntity, BaseMegaEntity):
except asyncio.CancelledError: except asyncio.CancelledError:
return return
except: except:
self.lg.exception("while dimming") self.lg.exception('while dimming')
async def async_will_remove_from_hass(self) -> None: async def async_will_remove_from_hass(self) -> None:
await super().async_will_remove_from_hass() await super().async_will_remove_from_hass()
@@ -302,10 +284,10 @@ class MegaRGBW(LightEntity, BaseMegaEntity):
w = None w = None
rgb = rgbw rgb = rgbw
if self.is_ws: if self.is_ws:
rgb = map_reorder_rgb(rgb, self._color_order, RGB) rgb = map_reorder_rgb(
h, s, v = colorsys.rgb_to_hsv( rgb, self._color_order, RGB
*[x / self.max_values[i] for i, x in enumerate(rgb)] )
) h, s, v = colorsys.rgb_to_hsv(*[x/self.max_values[i] for i, x in enumerate(rgb)])
h *= 360 h *= 360
s *= 100 s *= 100
v *= 255 v *= 255
@@ -314,7 +296,7 @@ class MegaRGBW(LightEntity, BaseMegaEntity):
self._brightness = v self._brightness = v
if w is not None: if w is not None:
if not self.customize.get(CONF_WHITE_SEP): if not self.customize.get(CONF_WHITE_SEP):
w = w / (self._brightness / 255) w = w/(self._brightness / 255)
else: else:
w = w w = w
w = w / (self.max_values[-1] / 255) w = w / (self.max_values[-1] / 255)
@@ -339,7 +321,7 @@ class MegaRGBW(LightEntity, BaseMegaEntity):
return return
data = data.get(x, None) data = data.get(x, None)
if isinstance(data, dict): if isinstance(data, dict):
data = data.get("value") data = data.get('value')
data = safe_int(data) data = safe_int(data)
if data is None: if data is None:
return return
@@ -356,4 +338,4 @@ class MegaRGBW(LightEntity, BaseMegaEntity):
ret = r ret = r
else: else:
ret = max([r, ret]) ret = max([r, ret])
return ret return ret

View File

@@ -15,5 +15,5 @@
"@andvikt" "@andvikt"
], ],
"issue_tracker": "https://github.com/andvikt/mega_hacs/issues", "issue_tracker": "https://github.com/andvikt/mega_hacs/issues",
"version": "v1.1.8b3" "version": "v1.1.7"
} }

View File

@@ -12,7 +12,7 @@
Если вам понравилась интеграция, не забудьте поставить звезду на гитхабе - вам не сложно, а мне приятно ) А если Если вам понравилась интеграция, не забудьте поставить звезду на гитхабе - вам не сложно, а мне приятно ) А если
интеграция очень понравилась - еще приятнее, если вы воспользуетесь кнопкой доната ) интеграция очень понравилась - еще приятнее, если вы воспользуетесь кнопкой доната )
Обновление прошивки MegaD можно делать прямо из HA с помощью [аддона](https://github.com/andvikt/mega_addon.git) Обновление прошивки MegaD можно делать из HA с помощью [аддона](https://github.com/andvikt/mega_addon.git)
## Основные особенности {: #mains } ## Основные особенности {: #mains }
- Настройка в [веб-интерфейсе](settings.md) + [yaml](yaml.md) - Настройка в [веб-интерфейсе](settings.md) + [yaml](yaml.md)

View File

@@ -1,7 +1,7 @@
# MegaD HomeAssistant integration # MegaD HomeAssistant integration
[![hacs_badge](https://img.shields.io/badge/HACS-Custom-orange.svg)](https://github.com/custom-components/hacs) [![hacs_badge](https://img.shields.io/badge/HACS-Custom-orange.svg)](https://github.com/hacs/integration)
[![Donate](https://img.shields.io/badge/donate-Yandex-red.svg)](https://yoomoney.ru/to/410013955329136) [![Donate](https://img.shields.io/badge/donate-Yandex-red.svg)](https://yoomoney.ru/to/410013955329136)
Интеграция с [MegaD-2561, MegaD-328](https://www.ab-log.ru/smart-house/ethernet/megad-2561) Интеграция с [MegaD-2561, MegaD-328](https://www.ab-log.ru/smart-house/ethernet/megad-2561)