Skip to content

Commit

Permalink
🎄 fix services
Browse files Browse the repository at this point in the history
  • Loading branch information
al-one committed Dec 25, 2020
1 parent bd4d322 commit e5665b1
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 58 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

## Tested By Community
- yeelink.bhf_light.v1
- yeelink.bhf_light.v5
- yeelink.light.lamp3
- yeelink.light.lamp5
- yeelink.light.fancl2
Expand Down
70 changes: 60 additions & 10 deletions custom_components/miio_yeelink/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Support for Yeelink."""
import logging
import asyncio
from math import ceil
from datetime import timedelta
from functools import partial
Expand Down Expand Up @@ -49,6 +50,27 @@
},
)

SERVICE_TO_METHOD_BASE = {
'send_command': {
'method': 'async_command',
'schema': XIAOMI_MIIO_SERVICE_SCHEMA.extend(
{
vol.Required('method'): cv.string,
vol.Optional('params', default = []): cv.ensure_list,
},
),
},
'set_property': {
'method': 'async_set_property',
'schema': XIAOMI_MIIO_SERVICE_SCHEMA.extend(
{
vol.Required('field'): cv.string,
vol.Required('value'): cv.match_all,
},
),
},
}

LIGHT_SCENES = [
None,
['cf',2,1,'50,2,4000,1,900000,2,4000,100'],
Expand All @@ -64,19 +86,11 @@

async def async_setup(hass, config: dict):
hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN].setdefault('entities', {})
component = EntityComponent(_LOGGER, DOMAIN, hass, SCAN_INTERVAL)
hass.data[DOMAIN]['component'] = component
await component.async_setup(config)
component.async_register_entity_service(
'send_command',
XIAOMI_MIIO_SERVICE_SCHEMA.extend(
{
vol.Required('method'): cv.string,
vol.Optional('params', default = []): cv.ensure_list,
},
),
'async_command'
)
bind_services_to_entries(hass, SERVICE_TO_METHOD_BASE)
return True

async def async_setup_entry(hass: core.HomeAssistant, config_entry: config_entries.ConfigEntry):
Expand Down Expand Up @@ -118,6 +132,42 @@ async def async_setup_entry(hass: core.HomeAssistant, config_entry: config_entri
return True


def bind_services_to_entries(hass, services):
async def async_service_handler(service):
method = services.get(service.service)
fun = method['method']
params = {
key: value
for key, value in service.data.items()
if key != ATTR_ENTITY_ID
}
target_devices = []
entity_ids = service.data.get(ATTR_ENTITY_ID)
if entity_ids:
target_devices = [
dvc
for dvc in hass.data[DOMAIN]['entities'].values()
if dvc.entity_id in entity_ids
]
_LOGGER.debug('Yeelink async_service_handler %s', {
'targets' : [ dvc.entity_id for dvc in target_devices ],
'method' : fun,
'params' : params,
})
update_tasks = []
for dvc in target_devices:
if not hasattr(dvc, fun):
_LOGGER.info('%s have no method: %s', dvc.entity_id, fun)
continue
await getattr(dvc, fun)(**params)
update_tasks.append(dvc.async_update_ha_state(True))
if update_tasks:
await asyncio.wait(update_tasks)
for srv, obj in services.items():
schema = obj.get('schema', XIAOMI_MIIO_SERVICE_SCHEMA)
hass.services.async_register(DOMAIN, srv, async_service_handler, schema = schema)


class MiotDevice(Device):
def __init__(
self,
Expand Down
23 changes: 13 additions & 10 deletions custom_components/miio_yeelink/fan.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Support for Yeelink Fan and Bath heater."""
import logging
import asyncio
import voluptuous as vol

from homeassistant.const import *

Expand All @@ -12,12 +12,20 @@
DOMAIN,
CONF_MODEL,
PLATFORM_SCHEMA,
bind_services_to_entries,
)

_LOGGER = logging.getLogger(__name__)
DATA_KEY = f'fan.{DOMAIN}'

async def async_add_entities_from_config(hass, config, async_add_entities):
SERVICE_TO_METHOD = {}


async def async_setup_entry(hass, config_entry, async_add_entities):
config = hass.data[DOMAIN]['configs'].get(config_entry.entry_id, config_entry.data)
await async_setup_platform(hass, config, async_add_entities)

async def async_setup_platform(hass, config, async_add_entities, discovery_info = None):
if DATA_KEY not in hass.data:
hass.data[DATA_KEY] = {}
host = config[CONF_HOST]
Expand Down Expand Up @@ -46,12 +54,7 @@ async def async_add_entities_from_config(hass, config, async_add_entities):
else:
entity = VenFanEntity(config)
entities.append(entity)
hass.data[DATA_KEY][host] = entity
for entity in entities:
hass.data[DOMAIN]['entities'][entity.unique_id] = entity
async_add_entities(entities, update_before_add = True)

async def async_setup_entry(hass, config_entry, async_add_entities):
config = hass.data[DOMAIN]['configs'].get(config_entry.entry_id,config_entry.data)
await async_add_entities_from_config(hass, config, async_add_entities)

async def async_setup_platform(hass, config, async_add_entities, discovery_info = None):
await async_add_entities_from_config(hass, config, async_add_entities)
bind_services_to_entries(hass, SERVICE_TO_METHOD)
49 changes: 11 additions & 38 deletions custom_components/miio_yeelink/light.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Support for Yeelink Light."""
import logging
import asyncio
import voluptuous as vol

import homeassistant.helpers.config_validation as cv
Expand All @@ -13,6 +12,7 @@
CONF_MODEL,
PLATFORM_SCHEMA,
XIAOMI_MIIO_SERVICE_SCHEMA,
bind_services_to_entries,
)

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -43,10 +43,15 @@
},
}

async def async_add_entities_from_config(hass, config, async_add_entities):

async def async_setup_entry(hass, config_entry, async_add_entities):
config = hass.data[DOMAIN]['configs'].get(config_entry.entry_id, config_entry.data)
await async_setup_platform(hass, config, async_add_entities)

async def async_setup_platform(hass, config, async_add_entities, discovery_info = None):
if DATA_KEY not in hass.data:
hass.data[DATA_KEY] = {}
host = config[CONF_HOST]
host = config[CONF_HOST]
model = config.get(CONF_MODEL)
entities = []
if model.find('light.fancl') > 0:
Expand All @@ -55,39 +60,7 @@ async def async_add_entities_from_config(hass, config, async_add_entities):
else:
entity = YeelightEntity(config)
entities.append(entity)
hass.data[DATA_KEY][host] = entity
for entity in entities:
hass.data[DOMAIN]['entities'][entity.unique_id] = entity
async_add_entities(entities, update_before_add = True)

async def async_service_handler(service):
method = SERVICE_TO_METHOD.get(service.service)
params = {
key: value for key, value in service.data.items() if key != ATTR_ENTITY_ID
}
entity_ids = service.data.get(ATTR_ENTITY_ID)
if entity_ids:
target_devices = [
dev
for dev in hass.data[DATA_KEY].values()
if dev.entity_id in entity_ids
]
else:
target_devices = hass.data[DATA_KEY].values()
update_tasks = []
for target_device in target_devices:
if not hasattr(target_device, method['method']):
continue
await getattr(target_device, method['method'])(**params)
update_tasks.append(target_device.async_update_ha_state(True))
if update_tasks:
await asyncio.wait(update_tasks)
for srv in SERVICE_TO_METHOD:
schema = SERVICE_TO_METHOD[srv].get('schema', XIAOMI_MIIO_SERVICE_SCHEMA)
hass.services.async_register(DOMAIN, srv, async_service_handler, schema = schema)


async def async_setup_entry(hass, config_entry, async_add_entities):
config = hass.data[DOMAIN]['configs'].get(config_entry.entry_id,config_entry.data)
await async_add_entities_from_config(hass, config, async_add_entities)

async def async_setup_platform(hass, config, async_add_entities, discovery_info = None):
await async_add_entities_from_config(hass, config, async_add_entities)
bind_services_to_entries(hass, SERVICE_TO_METHOD)
13 changes: 13 additions & 0 deletions custom_components/miio_yeelink/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ send_command:
description: Params for the method.
example: ['on']

set_property:
description: Set miot property.
fields:
entity_id:
description: Name of the entity.
example: "light.yeelink_fancl1_45f3"
field:
description: Field of property.
example: power
value:
description: Value of property.
example: True

light_set_scene:
description: Set a scene.
fields:
Expand Down

0 comments on commit e5665b1

Please sign in to comment.