예제 #1
0
    def __init__(
        self,
        entity_id: str,
        state: str,
        attributes: Optional[Mapping] = None,
        last_changed: Optional[datetime.datetime] = None,
        last_updated: Optional[datetime.datetime] = None,
        context: Optional[Context] = None,
        # Temp, because database can still store invalid entity IDs
        # Remove with 1.0 or in 2020.
        temp_invalid_id_bypass: Optional[bool] = False,
    ) -> None:
        """Initialize a new state."""
        state = str(state)

        if not valid_entity_id(entity_id) and not temp_invalid_id_bypass:
            raise InvalidEntityFormatError(
                ("Invalid entity id encountered: {}. "
                 "Format should be <domain>.<object_id>").format(entity_id))

        if not valid_state(state):
            raise InvalidStateError(
                ("Invalid state encountered for entity id: {}. "
                 "State max length is 255 characters.").format(entity_id))

        self.entity_id = entity_id.lower()
        self.state = state
        self.attributes = MappingProxyType(attributes or {})
        self.last_updated = last_updated or dt_util.utcnow()
        self.last_changed = last_changed or self.last_updated
        self.context = context or Context()
예제 #2
0
    def __init__(self,
                 entity_id: str,
                 state: Any,
                 attributes: Optional[Dict] = None,
                 last_changed: Optional[datetime.datetime] = None,
                 last_updated: Optional[datetime.datetime] = None,
                 context: Optional[Context] = None) -> None:
        """Initialize a new state."""
        state = str(state)

        if not valid_entity_id(entity_id):
            raise InvalidEntityFormatError(
                ("Invalid entity id encountered: {}. "
                 "Format should be <domain>.<object_id>").format(entity_id))

        if not valid_state(state):
            raise InvalidStateError(
                ("Invalid state encountered for entity id: {}. "
                 "State max length is 255 characters.").format(entity_id))

        self.entity_id = entity_id.lower()
        self.state = state
        self.attributes = MappingProxyType(attributes or {})
        self.last_updated = last_updated or dt_util.utcnow()
        self.last_changed = last_changed or self.last_updated
        self.context = context or Context()
예제 #3
0
async def async_setup_entry(hass: HomeAssistantType,
                            entry: ConfigEntry) -> bool:
    """
    set up digitalSTROM component from config entry
    """
    _LOGGER.debug("digitalstrom setup started")

    # initialize component data
    hass.data.setdefault(DOMAIN, dict())

    # old installations don't have an app token in their config entry
    if not entry.data.get(CONF_TOKEN, None):
        raise InvalidStateError(
            "No app token in config entry, please re-setup the integration")

    # setup client and listener
    client = DSClient(
        host=entry.data[CONF_HOST],
        port=entry.data[CONF_PORT],
        apptoken=entry.data[CONF_TOKEN],
        apartment_name=entry.data[CONF_ALIAS],
        stack_delay=entry.data.get(CONF_DELAY, DEFAULT_DELAY),
        loop=hass.loop,
    )
    listener = DSWebsocketEventListener(client=client, event_name="callScene")

    # store client in hass data for future usage
    entry_slug = slugify_entry(host=entry.data[CONF_HOST],
                               port=entry.data[CONF_PORT])
    hass.data[DOMAIN].setdefault(entry_slug, dict())
    hass.data[DOMAIN][entry_slug]["client"] = client
    hass.data[DOMAIN][entry_slug]["listener"] = listener

    # load all scenes from digitalSTROM server
    # this fails often on the first connection, but works on the second
    try:
        await client.initialize()
    except (DSException, RuntimeError, ConnectionResetError):
        try:
            await client.initialize()
        except (DSException, RuntimeError, ConnectionResetError):
            raise ConfigEntryNotReady(
                f"Failed to initialize digitalSTROM server at {client.host}")

    # we're connected
    _LOGGER.debug(
        f"Successfully retrieved session token from digitalSTROM server at {client.host}"
    )

    # register devices
    for component in COMPONENT_TYPES:
        hass.async_create_task(
            hass.config_entries.async_forward_entry_setup(entry, component))

    # start websocket listener and action delayer loops on hass startup
    async def digitalstrom_start_loops(event):
        _LOGGER.debug(
            f"loops started for digitalSTROM server at {client.host}")
        hass.async_add_job(listener.start)
        hass.async_add_job(client.stack.start)

    hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START,
                               digitalstrom_start_loops)

    # start websocket listener and action delayer loops on hass shutdown
    async def digitalstrom_stop_loops(event):
        _LOGGER.debug(
            f"loops stopped for digitalSTROM server at {client.host}")
        hass.async_add_job(client.stack.stop)
        hass.async_add_job(listener.stop)

    hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP,
                               digitalstrom_stop_loops)

    return True