async def async_call_method( self, entity: str, component: str, method: str, target: Any, context: Context = None, ): try: if not context: context = Context.admin() entity = self.get_entity(entity) new_state: Any = await entity.call_method(component, method, target, context) await self.state_queue.put(entity) self.dispatch_state_change_event(entity, component, new_state, context, context=context) except EntityNotFound: LOGGER.error( f"couldn't call method {component}.{method}, as the entity '{entity}' doesnt exist" ) except ComponentNotFound: LOGGER.error( f"couldn't call method {method}, as there is not '{component}' component attached to '{entity}'" )
def set_mutation(self, _, info, entity, component, target): self.core.registry.call_method(entity, component, "set", target, context=Context.admin(external=True)) return True
async def cio(self): while True: with suppress(Exception): _input = await ainput() args = _input.split(" ") if args[0] in ["run", "r"]: if len(args) == 4: config = ast.literal_eval(args[3]) else: config = {} self.io.run_service(args[1], ast.literal_eval(args[2]), config, Context.admin()) elif args[0] in ["set", "s"]: self.registry.call_method_d(f"{args[1]}.set", ast.literal_eval(args[2]), Context.admin()) elif args[0] in ["dispatch", "d"]: self.bus.dispatch(Event(args[1], ast.literal_eval(args[2])))
def dimmable_lamp_builder(registry, name: str, config: Dict, settings: Dict) -> Entity: entity = Entity(name, EntityType.LAMP_BRIGHTNESS) _switch_handler: Callable = registry.core.io.build_handler( config[CONTROL_SERVICE], *sanitize_component_config(config[SWITCH])) _brightness_handler: Callable = registry.core.io.build_handler( config[CONTROL_SERVICE], *sanitize_component_config(config[BRIGHTNESS])) async def switch_handler(target, context): if target and entity.components[BRIGHTNESS].state == 0: await entity.call_method(BRIGHTNESS, "set", 100, context) elif not target: await entity.call_method(BRIGHTNESS, "set", 0, context) await _switch_handler(target, context) async def brightness_handler(target, context): if target == 0 and entity.components[SWITCH].state: await entity.call_method(SWITCH, "turn_off", None, context) elif target != 0 and not entity.components[SWITCH].state: await entity.call_method(SWITCH, "turn_on", None, context) await _brightness_handler(target, context) entity.add_component( SWITCH, registry.components[SWITCH]({}, switch_handler, entity)) entity.add_component( BRIGHTNESS, registry.components[BRIGHTNESS]({}, brightness_handler, entity)) registry.core.add_job(entity.call_method, BRIGHTNESS, "increase", 10, Context.admin()) registry.core.add_job(entity.call_method, BRIGHTNESS, "increase", 10, Context.admin()) registry.core.add_job(entity.call_method, SWITCH, "turn_off", None, Context.admin()) entity.settings = settings return entity
async def dispatch_event_service(self, content: Any, context: Context, event_type: str = ""): """ dispatch an event on the event bus :param content: :param context: :param event_type: :return: """ if context.authorize(BUS, DISPATCH_EVENT): event = Event(event_type, content, context) self.dispatch(event) else: raise NotAuthorizedError( f"user {context.user} is not allowed to access the bus", context, BUS)
async def async_publish( self, payload: Any, context: Context, topic: str, qos: int = 0, retain: bool = True, ): """ Publish a message over MQTT :param payload: msg payload :param context: context :param topic: topic :param qos: qos :param retain: retain :return: """ if context.authorize(PUBLISH, "*"): await self.event.wait() self.core.add_job(self.client.publish, topic, payload, qos, retain)
async def update(self): try: await self.bridge.sensors.update() for sensor in self.bridge.sensors.values(): if ( type(sensor) is aiohue.sensors.ZLLSwitchSensor and sensor.state != self._sensor_states[sensor.name] ): listener = self._sensor_listeners.get(sensor.name, {}).get( "all", [] ) listener += self._sensor_listeners.get(sensor.name, {}).get( sensor.state["buttonevent"], [] ) for cb in listener: self.core.add_job( cb, sensor.state["buttonevent"], Context.admin() ) self._sensor_states[sensor.name] = sensor.state except Exception as e: print(e)
async def on_state(self, event): entity: Entity = event.event_content["entity"] component_type: str = event.event_content["component_type"] new_state: bool = event.event_content["new_state"] if entity == self.supplier: if new_state: self._grid_state = GridState.on else: self._grid_state = GridState.off return if entity not in self._consumer or component_type != "switch": return if new_state: if entity not in self._active_consumer: self._active_consumer.append(entity) else: if entity in self._active_consumer: self._active_consumer.remove(entity) if len(self._active_consumer) == 0 and self._grid_state in [ GridState.on, GridState.powering_up, GridState.unknown, ]: self.power_down() elif len(self._active_consumer) > 0 and self._grid_state in [ GridState.off, GridState.powering_down, GridState.unknown, ]: self.power_up() if entity.name in self._retry: await asyncio.sleep(0.75) await entity.call_method("switch", "set", new_state, Context.admin())
async def execute(self, context=None) -> T: if context is None: context = Context.default() await self.handler(self.state, context) return self.state
def __init__(self, event_type: str, event_content=None, context: Context = None): self.event_type: str = event_type self.event_content: T = event_content self.context: Context = context or Context.admin()
def default_run_context(): return Context.admin()
def created_event(entity: Entity, user: User): return Event( event_type=ENTITY_CREATED, event_content=entity, context=Context(user=user, remote=False), )
def get_context(self, device: str): # TODO: implement user return Context.admin(external=True)
def new_context(self, topic: str): return Context(User.new_admin(), remote=True)