Last active
December 6, 2023 19:44
-
-
Save rosaldanha/a0f8a5be9161745126c7e21563239118 to your computer and use it in GitHub Desktop.
home assistant pyscript to update device config on rslighsystem !
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import homeassistant | |
from homeassistant.helpers.template import Template | |
#from homeassistant.helpers.entity_registry import RegistryEntryHider | |
from homeassistant.helpers.entity_registry import RegistryEntryDisabler | |
from homeassistant.const import EVENT_SERVICE_REGISTERED | |
from homeassistant.core import Context | |
PANELS = 'panels' | |
def render_template(template, **kwargs): | |
tpl = Template(template, hass) | |
return tpl.async_render(kwargs) | |
# {{ device_entities( '0556da2031a3335ed396db777a69f0b1' ) }} | |
class Device: | |
def __init__(self,device_dict, panel): | |
self.name = device_dict['device'] | |
self.controled_entities = device_dict['controled_entities'] | |
self.relay = device_dict['relay'] | |
self.button_pos = str(device_dict['button_pos']).strip() | |
self.light_name = device_dict['light_name'] | |
self.panel = panel | |
def get_entity_id_rslights_version(self): | |
return f"sensor.{self.name}_rslights_version" | |
def get_entity_id_controled_entities(self): | |
return f"sensor.{self.name}_controled_entities" | |
def get_entity_id_relay(self): | |
return f"sensor.{self.name}_relay_enabled" | |
def get_entiy_id_panel_name(self): | |
return f"sensor.{self.name}_panel_name" | |
def get_entity_id_button_pos(self): | |
return f"sensor.{self.name}_button_pos" | |
def get_entity_id_status(self): | |
return f"binary_sensor.{self.name}_status" | |
def get_config_service_name(self): | |
return f"{self.name}_setup_smr2" | |
def is_config_synced(self): | |
return ( state.get(self.get_entity_id_controled_entities()) == self.controled_entities | |
and state.get(self.get_entity_id_relay()) == self.relay | |
and str(state.get(self.get_entity_id_button_pos())).strip() == self.button_pos | |
) | |
def device_exists_hass(self): | |
# entreg = homeassistant.helpers.entity_registry.async_get(hass) | |
# status_entity = entreg.async_get(self.get_entity_id_status()) | |
# return status_entity != None | |
template_str = "{{ states('"+ self.get_entity_id_rslights_version()+"') == '1.0' }}" | |
return render_template(template=template_str) | |
def is_online(self): | |
return state.get(self.get_entity_id_status()) != 'unavailable' | |
def get_hass_device_entities_ids(self): | |
entreg = homeassistant.helpers.entity_registry.async_get(hass) | |
status_entity = entreg.async_get(self.get_entity_id_status()) | |
# complete entries here | |
entries = homeassistant.helpers.entity_registry.async_entries_for_device(entreg, | |
device_id=status_entity.device_id, | |
include_disabled_entities=True) | |
return [entry.entity_id for entry in entries] | |
def sync_light_name(self): | |
entreg = homeassistant.helpers.entity_registry.async_get(hass) | |
status_entity = entreg.async_get(self.get_entity_id_status()) | |
if status_entity != None: | |
# resolving a template | |
device_current_entities = self.get_hass_device_entities_ids() | |
current_light_entity_id = None | |
for entity_name in device_current_entities: | |
if entity_name.startswith('light.'): | |
current_light_entity_id = entity_name | |
current_light_entity = entreg.async_get(current_light_entity_id) | |
if self.light_name == 'hide': | |
#check and hide current light entity found above. | |
if current_light_entity != None: | |
if current_light_entity.disabled_by == None: | |
# Hide the entity, RegistryEntryHider.INTEGRATION DO NOT allow the user to unhide, if needed use RegistryEntryHider.USER | |
entreg.async_update_entity(entity_id=current_light_entity_id, | |
disabled_by=RegistryEntryDisabler.INTEGRATION) | |
else: | |
new_light_id = f"light.{self.light_name.replace(' ','_').lower()}" | |
if new_light_id != current_light_entity_id: | |
log.error(new_light_id) | |
# Change Entity ID and name | |
try: | |
entreg.async_update_entity(entity_id=current_light_entity_id, | |
new_entity_id=new_light_id, | |
name=self.light_name, | |
disabled_by=None) | |
except: | |
entreg.async_update_entity(entity_id=current_light_entity_id, | |
new_entity_id=new_light_id, | |
name=self.light_name) | |
def sync_device_area(self): | |
# change/assign an area to a device (all device entities will follow) | |
devreg = homeassistant.helpers.device_registry.async_get(hass) | |
entreg = homeassistant.helpers.entity_registry.async_get(hass) | |
entity = entreg.async_get(self.get_entity_id_status()) | |
if entity != None: | |
devreg.async_update_device(device_id=entity.device_id, area_id=self.panel.area) | |
def sync_device(self): | |
#using rslights services update device config | |
task.sleep(5) | |
service.call(domain='esphome',name=self.get_config_service_name(), | |
controled_entities_value=self.controled_entities, | |
panel_name_value=self.panel.panel_name, | |
relay_enabled_value=self.relay, | |
button_pos_value=self.button_pos ) | |
def enable_service_run(self): | |
# Enable devices to call services from home assistant ! | |
devreg = homeassistant.helpers.device_registry.async_get(hass) | |
entreg = homeassistant.helpers.entity_registry.async_get(hass) | |
entity = entreg.async_get(self.get_entity_id_status()) | |
device = devreg.async_get(entity.device_id) | |
device_config_entry_id = list(device.config_entries)[0] | |
device_config_entry = hass.config_entries.async_get_entry(device_config_entry_id) | |
hass.config_entries.async_update_entry(device_config_entry,options={'allow_service_calls': True }) | |
class Panel: | |
def __init__(self, panel_name): | |
self.panel_name = panel_name | |
self.area = pyscript.app_config[PANELS][self.panel_name]['area'] | |
self.devices = [] | |
for device in pyscript.app_config[PANELS][self.panel_name]['devices']: | |
self.devices.append(Device(device_dict=device,panel=self)) | |
@service | |
def sync_rslights(): | |
is_panel_in_sync = True | |
for panel in pyscript.app_config[PANELS]: | |
# panel_list.append(Panel(panel)) | |
tmp_panel = Panel(panel) | |
for device in tmp_panel.devices: | |
if device.device_exists_hass(): | |
#if render_template(template='') | |
device.sync_light_name() | |
if not device.is_config_synced(): | |
log.info(f"Device: {device.name} is out of sync") | |
is_panel_in_sync = False | |
device.sync_device() | |
device.sync_device_area() | |
device.enable_service_run() | |
if not is_panel_in_sync: | |
log.info(f"Panel: {tmp_panel.panel_name} has been synced") | |
else: | |
log.info(f"Panel: {tmp_panel.panel_name} was synced") | |
''' | |
2023-12-04 05:34:31.878 INFO (MainThread) [custom_components.pyscript.apps.rslights.monitor_service_registred] got | |
EVENT_SERVICE_REGISTERED with kwargs={ | |
'trigger_type': 'event', | |
'event_type': 'service_registered', | |
'context': <homeassistant.core.Context object at 0x7f3798f25ad0>, | |
'domain': 'esphome', 'service': 'smr2055_setup_smr2'} | |
''' | |
@event_trigger(EVENT_SERVICE_REGISTERED,"domain == 'esphome' and service[-11:] == '_setup_smr2' ") | |
def monitor_service_registred(domain=None, context=None, service=None): | |
device_name = service[:7] | |
template_str = "{{ device_id( '" + device_name + "' ) }}" | |
device_id = render_template(template=template_str) | |
log.info(f"got EVENT_SERVICE_REGISTERED with context.id={context.id}, device={service[:7]} device_id={device_id}") | |
for panel in pyscript.app_config[PANELS]: | |
# panel_list.append(Panel(panel)) | |
tmp_panel = Panel(panel) | |
for device in tmp_panel.devices: | |
if device.name == device_name: | |
if device.device_exists_hass(): | |
log.info(f"NEW Device: {device.name} is out of sync") | |
task.sleep(5) | |
device.sync_light_name() | |
device.sync_device() | |
device.sync_device_area() | |
device.enable_service_run() | |
# device.sync_device() | |
# device.sync_light_name() | |
# device.sync_device_area() | |
log.info(f"NEW Device: {device.name} in sync !") | |
#TODO: Create a code to generate panels in lovelace each panel with his devices | |
#TODO: NOTIFY ? | |
#TODO: detect buttons pressed to identify devices | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment