Example #1
0
    def __init__(self, hass, device_id, friendly_name,
                 target_entity, attribute, sensor_class, invert):
        """Initialize the sensor."""
        self._hass = hass
        self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, device_id,
                                            hass=hass)
        self._name = friendly_name
        self._target_entity = target_entity
        self._attribute = attribute
        self._sensor_class = sensor_class
        self._invert = invert
        self._state = None
        self.from_state = None
        self.to_state = None

        self.update()

        def trend_sensor_state_listener(entity, old_state, new_state):
            """Called when the target device changes state."""
            self.from_state = old_state
            self.to_state = new_state
            self.update_ha_state(True)

        track_state_change(hass, target_entity,
                           trend_sensor_state_listener)
Example #2
0
def trigger(hass, config, action):
    """Listen for state changes based on configuration."""
    value_template = config.get(CONF_VALUE_TEMPLATE)

    # Local variable to keep track of if the action has already been triggered
    already_triggered = False

    def state_changed_listener(entity_id, from_s, to_s):
        """Listen for state changes and calls action."""
        nonlocal already_triggered
        template_result = condition.template(hass, value_template)

        # Check to see if template returns true
        if template_result and not already_triggered:
            already_triggered = True
            action({
                'trigger': {
                    'platform': 'template',
                    'entity_id': entity_id,
                    'from_state': from_s,
                    'to_state': to_s,
                },
            })
        elif not template_result:
            already_triggered = False

    track_state_change(hass, MATCH_ALL, state_changed_listener)
    return True
Example #3
0
def trigger(hass, config, action):
    """Listen for state changes based on configuration."""
    entity_id = config.get(CONF_ENTITY_ID)

    if entity_id is None:
        _LOGGER.error("Missing configuration key %s", CONF_ENTITY_ID)
        return False

    below = config.get(CONF_BELOW)
    above = config.get(CONF_ABOVE)
    value_template = config.get(CONF_VALUE_TEMPLATE)

    if below is None and above is None:
        _LOGGER.error("Missing configuration key."
                      " One of %s or %s is required",
                      CONF_BELOW, CONF_ABOVE)
        return False

    renderer = partial(_renderer, hass, value_template)

    # pylint: disable=unused-argument
    def state_automation_listener(entity, from_s, to_s):
        """Listen for state changes and calls action."""
        # Fire action if we go from outside range into range
        if _in_range(above, below, renderer(to_s)) and \
           (from_s is None or not _in_range(above, below, renderer(from_s))):
            action()

    track_state_change(
        hass, entity_id, state_automation_listener)

    return True
    def __init__(
        self,
        hass,
        name,
        heater_entity_id,
        sensor_entity_id,
        min_temp,
        max_temp,
        target_temp,
        ac_mode,
        min_cycle_duration,
    ):
        """Initialize the thermostat."""
        self.hass = hass
        self._name = name
        self.heater_entity_id = heater_entity_id
        self.ac_mode = ac_mode
        self.min_cycle_duration = min_cycle_duration

        self._active = False
        self._cur_temp = None
        self._min_temp = min_temp
        self._max_temp = max_temp
        self._target_temp = target_temp
        self._unit = hass.config.units.temperature_unit

        track_state_change(hass, sensor_entity_id, self._sensor_changed)

        sensor_state = hass.states.get(sensor_entity_id)
        if sensor_state:
            self._update_temp(sensor_state)
Example #5
0
    def turn_on(self, *args, **kwargs):
        """ Turn on the selected media_player from input_select """
        if (self._api == None):
            _LOGGER.error("Can't start the player, no header file")
            return
        _LOGGER.debug("TURNON")

        self._playing = False
        if not self._update_entity_ids():
            return
        _player = self.hass.states.get(self._entity_ids)
        data = {ATTR_ENTITY_ID: _player.entity_id}

        self._allow_next = False
        track_state_change(self.hass, _player.entity_id, self._sync_player)
        track_state_change(self.hass, self._playMode, self._update_playmode)
        self._turn_on_media_player(data)
        #_LOGGER.error("subscribe to changes of ")

        self._get_cipher('BB2mjBuAtiQ')

        # display imidiatly a loading state to provide feedback to the user
        self._track_name = "loading..."
        self._track_album_name = ""
        self._track_artist = ""
        self._track_artist_cover = None
        self._track_album_cover = None
        self._state = STATE_PLAYING  # a bit early otherwise no info will be shown
        self.schedule_update_ha_state()

        # grabbing data from API, might take a 1-3 sec
        self._load_playlist()
Example #6
0
    def __init__(self, hass, app_name, topic, sandbox, cert_file):
        """Initialize APNS application."""
        self.hass = hass
        self.app_name = app_name
        self.sandbox = sandbox
        self.certificate = cert_file
        self.yaml_path = hass.config.path(app_name + '_' + APNS_DEVICES)
        self.devices = {}
        self.device_states = {}
        self.topic = topic
        if os.path.isfile(self.yaml_path):
            self.devices = {
                str(key): ApnsDevice(
                    str(key),
                    value.get('name'),
                    value.get('tracking_device_id'),
                    value.get('disabled', False)
                )
                for (key, value) in
                load_yaml_config_file(self.yaml_path).items()
            }

        tracking_ids = [
            device.full_tracking_device_id
            for (key, device) in self.devices.items()
            if device.tracking_device_id is not None
        ]
        track_state_change(
            hass, tracking_ids, self.device_state_changed_listener)
Example #7
0
def trigger(hass, config, action):
    """ Listen for state changes based on `config`. """
    entity_id = config.get(CONF_ENTITY_ID)
    zone_entity_id = config.get(CONF_ZONE)

    if entity_id is None or zone_entity_id is None:
        logging.getLogger(__name__).error(
            "Missing trigger configuration key %s or %s", CONF_ENTITY_ID,
            CONF_ZONE)
        return False

    event = config.get(CONF_EVENT, DEFAULT_EVENT)

    def zone_automation_listener(entity, from_s, to_s):
        """ Listens for state changes and calls action. """
        if from_s and None in (from_s.attributes.get(ATTR_LATITUDE),
                               from_s.attributes.get(ATTR_LONGITUDE)) or \
            None in (to_s.attributes.get(ATTR_LATITUDE),
                     to_s.attributes.get(ATTR_LONGITUDE)):
            return

        from_match = _in_zone(hass, zone_entity_id, from_s) if from_s else None
        to_match = _in_zone(hass, zone_entity_id, to_s)

        # pylint: disable=too-many-boolean-expressions
        if event == EVENT_ENTER and not from_match and to_match or \
           event == EVENT_LEAVE and from_match and not to_match:
            action()

    track_state_change(hass, entity_id, zone_automation_listener, MATCH_ALL,
                       MATCH_ALL)

    return True
def setup_proximity_component(
    hass: HomeAssistant, name: str, config: ConfigType
) -> bool:
    """Set up the individual proximity component."""
    ignored_zones: list[str] = config[CONF_IGNORED_ZONES]
    proximity_devices: list[str] = config[CONF_DEVICES]
    tolerance: int = config[CONF_TOLERANCE]
    proximity_zone = name
    unit_of_measurement: str = config.get(
        CONF_UNIT_OF_MEASUREMENT, hass.config.units.length_unit
    )
    zone_id = f"zone.{config[CONF_ZONE]}"

    proximity = Proximity(  # type:ignore[no-untyped-call]
        hass,
        proximity_zone,
        DEFAULT_DIST_TO_ZONE,
        DEFAULT_DIR_OF_TRAVEL,
        DEFAULT_NEAREST,
        ignored_zones,
        proximity_devices,
        tolerance,
        zone_id,
        unit_of_measurement,
    )
    proximity.entity_id = f"{DOMAIN}.{proximity_zone}"

    proximity.schedule_update_ha_state()

    track_state_change(hass, proximity_devices, proximity.check_proximity_state_change)

    return True
Example #9
0
    def __init__(self, hass, entity_id, entity_state, start, end, duration,
                 sensor_type, name):
        """Initialize the HistoryStats sensor."""
        self._hass = hass

        self._entity_id = entity_id
        self._entity_state = entity_state
        self._duration = duration
        self._start = start
        self._end = end
        self._type = sensor_type
        self._name = name
        self._unit_of_measurement = UNITS[sensor_type]

        self._period = (datetime.datetime.now(), datetime.datetime.now())
        self.value = None
        self.count = None

        def force_refresh(*args):
            """Force the component to refresh."""
            self.schedule_update_ha_state(True)

        # Update value when home assistant starts
        hass.bus.listen_once(EVENT_HOMEASSISTANT_START, force_refresh)

        # Update value when tracked entity changes its state
        track_state_change(hass, entity_id, force_refresh)
Example #10
0
def register_presence_handlers(hass, config):
    """ Registers the event handlers that handle presence. """
    rfid_sensor = config[DOMAIN].get(CONF_RFID, None)
    if rfid_sensor is None:
        _LOGGER.warning('RFID sensor not configured.')
        return

    def rfid_seen(now=None):
        """ Calls see service periodically with state of RFID sensor. """
        rfid_state = hass.states.get(rfid_sensor)
        location = STATE_NOT_HOME
        if rfid_state is not None and str(rfid_state.state) == '1':
            location = STATE_HOME
        _LOGGER.debug('rfid %s state is %s', rfid_sensor, location)
        hass.services.call(DEVICE_TRACKER_DOMAIN, SERVICE_SEE, {
            ATTR_DEV_ID: split_entity_id(rfid_sensor)[1],
            ATTR_LOCATION_NAME: location,
        })

    helper.track_utc_time_change(hass, rfid_seen, second=0)

    def rfid_state_change(entity_id, old_state, new_state):
        """ Calls see service immediately with state of RFID sensor. """
        rfid_seen()

    helper.track_state_change(hass, rfid_sensor, rfid_state_change)
Example #11
0
    def __init__(self, hass, device_id, friendly_name, target_entity,
                 attribute, sensor_class, invert):
        """Initialize the sensor."""
        self._hass = hass
        self.entity_id = generate_entity_id(ENTITY_ID_FORMAT,
                                            device_id,
                                            hass=hass)
        self._name = friendly_name
        self._target_entity = target_entity
        self._attribute = attribute
        self._sensor_class = sensor_class
        self._invert = invert
        self._state = None
        self.from_state = None
        self.to_state = None

        self.update()

        def trend_sensor_state_listener(entity, old_state, new_state):
            """Called when the target device changes state."""
            self.from_state = old_state
            self.to_state = new_state
            self.update_ha_state(True)

        track_state_change(hass, target_entity, trend_sensor_state_listener)
Example #12
0
def setup(hass, config):
    """Set up a component."""
    _LOGGER.debug("Couples setting up...")

    component = EntityComponent(_LOGGER, DOMAIN, hass)

    entities = []
    object_ids = []

    for couple_name, cfg in config[DOMAIN].items():
        if not cfg:
            cfg = {}
        ids = cfg[CONF_ENTITIES]
        object_ids = object_ids + ids
        entities.append(CoupledAlarms(hass, couple_name, ids))

    if not entities:
        return False

    component.add_entities(entities)

    def notify_state_change(entity_id, old_state, new_state):
        for entity in entities:
            entity.state_changed(entity_id, old_state, new_state)

    track_state_change(hass, object_ids, notify_state_change)

    return True
Example #13
0
def trigger(hass, config, action):
    """ Listen for state changes based on `config`. """
    entity_id = config.get(CONF_ENTITY_ID)

    if entity_id is None:
        logging.getLogger(__name__).error(
            "Missing trigger configuration key %s", CONF_ENTITY_ID)
        return False

    from_state = config.get(CONF_FROM, MATCH_ALL)
    to_state = config.get(CONF_TO) or config.get(CONF_STATE) or MATCH_ALL

    if isinstance(from_state, bool) or isinstance(to_state, bool):
        logging.getLogger(__name__).error(
            'Config error. Surround to/from values with quotes.')
        return False

    def state_automation_listener(entity, from_s, to_s):
        """ Listens for state changes and calls action. """
        action()

    track_state_change(hass, entity_id, state_automation_listener, from_state,
                       to_state)

    return True
    def __init__(self, hass, name, temp_sensor, humidity_sensor):
        """Initialize the sensor."""
        self._state = None
        self._name = name
        self._temp_sensor = temp_sensor
        self._humidity_sensor = humidity_sensor
        self._is_metric = hass.config.units.is_metric

        self._temp = None
        self._hum = None

        track_state_change(hass, temp_sensor, self._sensor_changed)
        track_state_change(hass, humidity_sensor, self._sensor_changed)

        # Read initial state
        temp = hass.states.get(temp_sensor)
        hum = hass.states.get(humidity_sensor)

        if temp:
            self._temp = DewPoint._update_temp_sensor(temp)

        if hum:
            self._hum = DewPoint._update_hum_sensor(hum)

        self.update()
Example #15
0
def trigger(hass, config, action):
    """ Listen for state changes based on `config`. """
    entity_id = config.get(CONF_ENTITY_ID)

    if entity_id is None:
        _LOGGER.error("Missing configuration key %s", CONF_ENTITY_ID)
        return False

    below = config.get(CONF_BELOW)
    above = config.get(CONF_ABOVE)
    attribute = config.get(CONF_ATTRIBUTE)

    if below is None and above is None:
        _LOGGER.error("Missing configuration key."
                      " One of %s or %s is required",
                      CONF_BELOW, CONF_ABOVE)
        return False

    # pylint: disable=unused-argument
    def state_automation_listener(entity, from_s, to_s):
        """ Listens for state changes and calls action. """

        # Fire action if we go from outside range into range
        if _in_range(to_s, above, below, attribute) and \
           (from_s is None or not _in_range(from_s, above, below, attribute)):
            action()

    track_state_change(
        hass, entity_id, state_automation_listener)

    return True
    def __init__(
            self, hass, entity_id, entity_state, start, end, duration,
            sensor_type, name):
        """Initialize the HistoryStats sensor."""
        self._hass = hass

        self._entity_id = entity_id
        self._entity_state = entity_state
        self._duration = duration
        self._start = start
        self._end = end
        self._type = sensor_type
        self._name = name
        self._unit_of_measurement = UNITS[sensor_type]

        self._period = (datetime.datetime.now(), datetime.datetime.now())
        self.value = 0
        self.count = 0

        def force_refresh(*args):
            """Force the component to refresh."""
            self.schedule_update_ha_state(True)

        # Update value when home assistant starts
        hass.bus.listen_once(EVENT_HOMEASSISTANT_START, force_refresh)

        # Update value when tracked entity changes its state
        track_state_change(hass, entity_id, force_refresh)
Example #17
0
    def __init__(self, hass, app_name, topic, sandbox, cert_file):
        """Initialize APNS application."""
        self.hass = hass
        self.app_name = app_name
        self.sandbox = sandbox
        self.certificate = cert_file
        self.yaml_path = hass.config.path(app_name + '_' + APNS_DEVICES)
        self.devices = {}
        self.device_states = {}
        self.topic = topic
        if os.path.isfile(self.yaml_path):
            self.devices = {
                str(key): ApnsDevice(str(key), value.get('name'),
                                     value.get('tracking_device_id'),
                                     value.get('disabled', False))
                for (key,
                     value) in load_yaml_config_file(self.yaml_path).items()
            }

        tracking_ids = [
            device.full_tracking_device_id
            for (key, device) in self.devices.items()
            if device.tracking_device_id is not None
        ]
        track_state_change(hass, tracking_ids,
                           self.device_state_changed_listener)
Example #18
0
def trigger(hass, config, action):
    """ Listen for state changes based on `config`. """
    entity_id = config.get(CONF_ENTITY_ID)

    if entity_id is None:
        _LOGGER.error("Missing configuration key %s", CONF_ENTITY_ID)
        return False

    below = config.get(CONF_BELOW)
    above = config.get(CONF_ABOVE)

    if below is None and above is None:
        _LOGGER.error(
            "Missing configuration key."
            " One of %s or %s is required", CONF_BELOW, CONF_ABOVE)
        return False

    # pylint: disable=unused-argument
    def state_automation_listener(entity, from_s, to_s):
        """ Listens for state changes and calls action. """

        # Fire action if we go from outside range into range
        if _in_range(to_s.state, above, below) and \
                (from_s is None or not _in_range(from_s.state, above, below)):
            action()

    track_state_change(hass, entity_id, state_automation_listener)

    return True
Example #19
0
def setup_proximity_component(hass, name, config):
    """Set up the individual proximity component."""
    ignored_zones = config.get(CONF_IGNORED_ZONES)
    proximity_devices = config.get(CONF_DEVICES)
    tolerance = config.get(CONF_TOLERANCE)
    proximity_zone = name
    unit_of_measurement = config.get(CONF_UNIT_OF_MEASUREMENT,
                                     hass.config.units.length_unit)
    zone_id = f"zone.{config.get(CONF_ZONE)}"

    proximity = Proximity(
        hass,
        proximity_zone,
        DEFAULT_DIST_TO_ZONE,
        DEFAULT_DIR_OF_TRAVEL,
        DEFAULT_NEAREST,
        ignored_zones,
        proximity_devices,
        tolerance,
        zone_id,
        unit_of_measurement,
    )
    proximity.entity_id = f"{DOMAIN}.{proximity_zone}"

    proximity.schedule_update_ha_state()

    track_state_change(hass, proximity_devices,
                       proximity.check_proximity_state_change)

    return True
Example #20
0
    def __init__(self, hass, config, logger):

        self.logger = logger
        self.hass = hass
        self.heater_entity_id = config.get("heater")

        self.name_device = config.get("name")
        self.target_sensor_entity_id = config.get("target_sensor")

        self.time_temp = []
        if config.get("time_temp"):
            for time_temp in list(config.get("time_temp").split(",")):
                time, temp = time_temp.split(':')
                time_start, time_end = time.split('-')
                start_time = datetime.datetime.time(
                    datetime.datetime.strptime(time_start, '%H%M'))
                end_time = datetime.datetime.time(
                    datetime.datetime.strptime(time_end, '%H%M'))
                self.time_temp.append((start_time, end_time, float(temp)))

        self._min_temp = util.convert(config.get("min_temp"), float, 0)
        self._max_temp = util.convert(config.get("max_temp"), float, 100)

        self._manual_sat_temp = None
        self._away = False
        self._heater_manual_changed = True

        track_state_change(hass, self.heater_entity_id,
                           self._heater_turned_on,
                           STATE_OFF, STATE_ON)
        track_state_change(hass, self.heater_entity_id,
                           self._heater_turned_off,
                           STATE_ON, STATE_OFF)
Example #21
0
    def __init__(self, hass, app_name, topic, sandbox, cert_file):
        """Initialize APNS application."""
        self.hass = hass
        self.app_name = app_name
        self.sandbox = sandbox
        self.certificate = cert_file
        self.yaml_path = hass.config.path(f"{app_name}_{APNS_DEVICES}")
        self.devices = {}
        self.device_states = {}
        self.topic = topic

        try:
            self.devices = {
                str(key): ApnsDevice(
                    str(key),
                    value.get("name"),
                    value.get("tracking_device_id"),
                    value.get("disabled", False),
                )
                for (key,
                     value) in load_yaml_config_file(self.yaml_path).items()
            }
        except FileNotFoundError:
            pass

        tracking_ids = [
            device.full_tracking_device_id
            for (key, device) in self.devices.items()
            if device.tracking_device_id is not None
        ]
        track_state_change(hass, tracking_ids,
                           self.device_state_changed_listener)
Example #22
0
def trigger(hass, config, action):
    """ Listen for state changes based on `config`. """
    entity_id = config.get(CONF_ENTITY_ID)
    zone_entity_id = config.get(CONF_ZONE)

    if entity_id is None or zone_entity_id is None:
        logging.getLogger(__name__).error(
            "Missing trigger configuration key %s or %s", CONF_ENTITY_ID,
            CONF_ZONE)
        return False

    event = config.get(CONF_EVENT, DEFAULT_EVENT)

    def zone_automation_listener(entity, from_s, to_s):
        """ Listens for state changes and calls action. """
        if from_s and None in (from_s.attributes.get(ATTR_LATITUDE),
                               from_s.attributes.get(ATTR_LONGITUDE)) or \
            None in (to_s.attributes.get(ATTR_LATITUDE),
                     to_s.attributes.get(ATTR_LONGITUDE)):
            return

        from_match = _in_zone(hass, zone_entity_id, from_s) if from_s else None
        to_match = _in_zone(hass, zone_entity_id, to_s)

        # pylint: disable=too-many-boolean-expressions
        if event == EVENT_ENTER and not from_match and to_match or \
           event == EVENT_LEAVE and from_match and not to_match:
            action()

    track_state_change(
        hass, entity_id, zone_automation_listener, MATCH_ALL, MATCH_ALL)

    return True
    def __init__(self, hass, entity_id, name, sampling_size):
        """Initialize the Statistics sensor."""
        self._hass = hass
        self._entity_id = entity_id
        self.is_binary = True if self._entity_id.split('.')[0] == \
            'binary_sensor' else False
        if not self.is_binary:
            self._name = '{} {}'.format(name, ATTR_MEAN)
        else:
            self._name = '{} {}'.format(name, ATTR_COUNT)
        self._sampling_size = sampling_size
        self._unit_of_measurement = None
        if self._sampling_size == 0:
            self.states = deque()
        else:
            self.states = deque(maxlen=self._sampling_size)
        self.median = self.mean = self.variance = self.stdev = 0
        self.min = self.max = self.total = self.count = 0
        self.update()

        def stats_sensor_state_listener(entity, old_state, new_state):
            """Called when the sensor changes state."""
            self._unit_of_measurement = new_state.attributes.get(
                ATTR_UNIT_OF_MEASUREMENT)

            try:
                self.states.append(float(new_state.state))
                self.count = self.count + 1
            except ValueError:
                self.count = self.count + 1

            self.update_ha_state(True)

        track_state_change(hass, entity_id, stats_sensor_state_listener)
Example #24
0
def trigger(hass, config, action):
    """ Listen for state changes based on `config`. """
    entity_id = config.get(CONF_ENTITY_ID)

    if entity_id is None:
        logging.getLogger(__name__).error(
            "Missing trigger configuration key %s", CONF_ENTITY_ID)
        return False

    from_state = config.get(CONF_FROM, MATCH_ALL)
    to_state = config.get(CONF_TO) or config.get(CONF_STATE) or MATCH_ALL

    if isinstance(from_state, bool) or isinstance(to_state, bool):
        logging.getLogger(__name__).error(
            'Config error. Surround to/from values with quotes.')
        return False

    def state_automation_listener(entity, from_s, to_s):
        """ Listens for state changes and calls action. """
        action()

    track_state_change(
        hass, entity_id, state_automation_listener, from_state, to_state)

    return True
Example #25
0
    def __init__(self, hass, entity_id, name, sampling_size):
        """Initialize the Statistics sensor."""
        self._hass = hass
        self._entity_id = entity_id
        self.is_binary = True if self._entity_id.split(".")[0] == "binary_sensor" else False
        if not self.is_binary:
            self._name = "{} {}".format(name, ATTR_MEAN)
        else:
            self._name = "{} {}".format(name, ATTR_COUNT)
        self._sampling_size = sampling_size
        self._unit_of_measurement = None
        if self._sampling_size == 0:
            self.states = deque()
        else:
            self.states = deque(maxlen=self._sampling_size)
        self.median = self.mean = self.variance = self.stdev = 0
        self.min = self.max = self.total = self.count = 0
        self.update()

        def calculate_sensor_state_listener(entity, old_state, new_state):
            """Called when the sensor changes state."""
            self._unit_of_measurement = new_state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)

            try:
                self.states.append(float(new_state.state))
                self.count = self.count + 1
            except ValueError:
                self.count = self.count + 1

            self.update_ha_state(True)

        track_state_change(hass, entity_id, calculate_sensor_state_listener)
    def _resume_mp(config):
        media_player = "media_player." + config.get("media_player", "")
        resume_state = None
        resume = False

        def _state_change(entity_id=None, old_state=None, new_state=None):
            nonlocal resume_state, resume
            content_id = hass.states.get(media_player).attributes.get(
                "media_content_id", [])
            if resume_state and new_state.state != 'playing' and resume:
                print(resume_state)
                data = {
                    ATTR_MEDIA_CONTENT_ID:
                    resume_state.attributes.get("media_content_id", ""),
                    ATTR_MEDIA_CONTENT_TYPE:
                    "audio/mp3",
                    ATTR_ENTITY_ID:
                    media_player,
                }
                resume_state = None
                resume = True
                hass.services.call(DOMAIN_MP, SERVICE_PLAY_MEDIA, data)
            elif (new_state.state == 'playing'
                  and ("nrk.no" in content_id
                       or "nrk-mms-live.online.no" in content_id)):
                resume_state = new_state
            elif (resume_state and new_state.state == 'playing'
                  and "tts_proxy" in content_id):
                resume = True
            else:
                resume_state = None
                resume = False

        track_state_change(hass, media_player, _state_change)
Example #27
0
 def track_change(self, entity_ids, action, from_state=None, to_state=None):
     """DEPRECATED AS OF 8/4/2015."""
     _LOGGER.warning(
         'hass.states.track_change is deprecated. '
         'Use homeassistant.helpers.event.track_state_change instead.')
     import homeassistant.helpers.event as helper
     helper.track_state_change(_MockHA(self._bus), entity_ids, action,
                               from_state, to_state)
Example #28
0
def setup(hass, config):
    def coffee_state_changed(entity_id, old_state, new_state):
        _LOGGER.info('{} changed to {}'.format(entity_id, new_state.state))

        if new_state.state in [
                'unknown', 'INITIALISING', 'UNINITIALISED', 'ERROR'
        ]:
            # hide all but init
            hide_entity(hass, entity_id=INIT_COFFEE_SCRIPT, hidden=False)
            for e in [
                    SINGLE_COFFEE_SCRIPT, DOUBLE_COFFEE_SCRIPT,
                    FUND_COFFEE_SCRIPT, ADDRESSES_COFFEE_SENSOR,
                    CLOSE_COFFEE_SCRIPT, BALANCE_COFFEE_SENSOR,
                    PROVIDER_TRANSACTION, COFFEE_TRANSACTION,
                    COFFEE_FLASH_SERVER, PROVIDER_FLASH_SERVER
            ]:
                hide_entity(hass, entity_id=e, hidden=True)
        elif new_state.state == 'INITIALISED':
            hide_entity(hass, entity_id=INIT_COFFEE_SCRIPT, hidden=True)
            hide_entity(hass, entity_id=FUND_COFFEE_SCRIPT, hidden=False)
            hide_entity(hass, entity_id=BALANCE_COFFEE_SENSOR, hidden=True)
            hide_entity(hass, entity_id=ADDRESSES_COFFEE_SENSOR, hidden=False)
        elif new_state.state == 'FUNDED':
            hide_entity(hass, entity_id=FUND_COFFEE_SCRIPT, hidden=True)
            hide_entity(hass, entity_id=BALANCE_COFFEE_SENSOR, hidden=False)
            hide_entity(hass, entity_id=CLOSE_COFFEE_SCRIPT, hidden=False)
            hide_entity(hass, entity_id=SINGLE_COFFEE_SCRIPT, hidden=False)
            hide_entity(hass, entity_id=DOUBLE_COFFEE_SCRIPT, hidden=False)
            hide_entity(hass, entity_id=ADDRESSES_COFFEE_SENSOR, hidden=False)
        elif new_state.state == 'CLOSING':
            hide_entity(hass, entity_id=SINGLE_COFFEE_SCRIPT, hidden=True)
            hide_entity(hass, entity_id=DOUBLE_COFFEE_SCRIPT, hidden=True)
        elif new_state.state == 'CLOSED':
            hide_entity(hass, entity_id=INIT_COFFEE_SCRIPT, hidden=False)
            # hide all but init and transaction
            for e in [
                    SINGLE_COFFEE_SCRIPT, DOUBLE_COFFEE_SCRIPT,
                    FUND_COFFEE_SCRIPT, ADDRESSES_COFFEE_SENSOR,
                    CLOSE_COFFEE_SCRIPT, BALANCE_COFFEE_SENSOR,
                    COFFEE_TRANSACTION, PROVIDER_TRANSACTION
            ]:
                hide_entity(hass, entity_id=e, hidden=True)
        elif new_state.state in ['NO_FUNDS', 'NO_ADDRESSES_LEFT']:
            for e in [
                    SINGLE_COFFEE_SCRIPT, DOUBLE_COFFEE_SCRIPT,
                    FUND_COFFEE_SCRIPT, INIT_COFFEE_SCRIPT,
                    PROVIDER_TRANSACTION, COFFEE_TRANSACTION
            ]:
                hide_entity(hass, entity_id=e, hidden=True)
            hide_entity(hass, entity_id=CLOSE_COFFEE_SCRIPT, hidden=False)
            hide_entity(hass, entity_id=BALANCE_COFFEE_SENSOR, hidden=False)

    track_state_change(hass,
                       entity_ids=['sensor.coffee_machine_state'],
                       action=coffee_state_changed)

    return True
Example #29
0
def setup(hass, config):
    """ Sets up the simple alarms. """
    logger = logging.getLogger(__name__)
    logger.info("Starting laundry automation.")
    sensors = ["sensor.washer_status", "sensor.dryer_status"]
    wait_time = config[DOMAIN].get(CONF_WAIT_TIME, 300)

    def track_complete_status(entity_id, old_state, new_state):
        """ Called when appliance goes from running to complete. """
        actually_complete = True
        for i in range(1, wait_time):
            state = hass.states.get(entity_id).state
            if state == COMPLETE:
                time.sleep(1)
            else:
                actually_complete = False
                logger.info("LAUNDRY NOT ACTUALLY COMPLETE!!")
                break
        if actually_complete:
            global fluxing
            fluxing = False
            if 'dryer' in entity_id:
                hass.services.call('scene', 'turn_on', {"entity_id":"scene.red"})
                message = "The dryer is complete, please empty it!"
            elif 'washer' in entity_id:
                hass.services.call('scene', 'turn_on', {"entity_id":"scene.blue"})
                message = "The washing machine is complete, please empty it!"
            logger.info("LAUNDRY ACTUALLY COMPLETE!!")
            if hass.states.get(LAURENS_DEVICE).state == STATE_HOME:
                hass.services.call('notify', 'join_lauren', {"message":message})
            if hass.states.get(NOLANS_DEVICE).state == STATE_HOME:
                hass.services.call('notify', 'join', {"message":message})

    def appliance_emptied(entity_id, old_state, new_state):
        """ Called when appliance goes from complete to empty. """
        hass.services.call('scene', 'turn_on', {"entity_id":"scene.normal"})
        global fluxing
        fluxing = True

    def flux_update(service):
        """ Called every 30 seconds to flux the lights. """
        global fluxing
        ib_flux_state = hass.states.get('input_boolean.flux_automation')
        if fluxing and ib_flux_state:
            if ib_flux_state.state == 'on':
                hass.services.call('switch', 'flux_update')  

    track_state_change(
            hass, sensors,
            track_complete_status, RUNNING, COMPLETE)
    track_state_change(
            hass, sensors,
            appliance_emptied, COMPLETE, EMPTY)
    track_time_change(hass, flux_update, second=[0,30])
    return True
Example #30
0
def setup(hass, config):
    """ Sets up the simple alarms. """
    logger = logging.getLogger(__name__)
    logger.info("Starting laundry automation.")
    sensors = ["sensor.washer_status", "sensor.dryer_status"]
    wait_time = config[DOMAIN].get(CONF_WAIT_TIME, 300)

    def track_complete_status(entity_id, old_state, new_state):
        """ Called when appliance goes from running to complete. """
        actually_complete = True
        for i in range(1, wait_time):
            state = hass.states.get(entity_id).state
            if state == COMPLETE:
                time.sleep(1)
            else:
                actually_complete = False
                logger.info("LAUNDRY NOT ACTUALLY COMPLETE!!")
                break
        if actually_complete:
            global fluxing
            fluxing = False
            if 'dryer' in entity_id:
                hass.services.call('scene', 'turn_on',
                                   {"entity_id": "scene.red"})
                message = "The dryer is complete, please empty it!"
            elif 'washer' in entity_id:
                hass.services.call('scene', 'turn_on',
                                   {"entity_id": "scene.blue"})
                message = "The washing machine is complete, please empty it!"
            logger.info("LAUNDRY ACTUALLY COMPLETE!!")
            if hass.states.get(LAURENS_DEVICE).state == STATE_HOME:
                hass.services.call('notify', 'join_lauren',
                                   {"message": message})
            if hass.states.get(NOLANS_DEVICE).state == STATE_HOME:
                hass.services.call('notify', 'join', {"message": message})

    def appliance_emptied(entity_id, old_state, new_state):
        """ Called when appliance goes from complete to empty. """
        hass.services.call('scene', 'turn_on', {"entity_id": "scene.normal"})
        global fluxing
        fluxing = True

    def flux_update(service):
        """ Called every 30 seconds to flux the lights. """
        global fluxing
        ib_flux_state = hass.states.get('input_boolean.flux_automation')
        if fluxing and ib_flux_state:
            if ib_flux_state.state == 'on':
                hass.services.call('switch', 'flux_update')

    track_state_change(hass, sensors, track_complete_status, RUNNING, COMPLETE)
    track_state_change(hass, sensors, appliance_emptied, COMPLETE, EMPTY)
    track_time_change(hass, flux_update, second=[0, 30])
    return True
Example #31
0
def setup(hass, config):
    """ Sets up the simple alarms. """
    logger = logging.getLogger(__name__)

    max_sun_elevation = 100
    light_entity_id = "light.gang"
    leave_lights_on_for_min = 1
    #    keep_lights_off_for_min = 5
    trigger_sensors = ['binary_sensor.movement3', 'binary_sensor.door_soverom']

    #auto_triggered = False
    turn_off_light_listener = None

    def activate(entity_id, old_state, new_state):
        """ Called when a known person comes home. """
        state_sun = hass.states.get('sun.sun')
        if state_sun.attributes[STATE_ATTR_ELEVATION] > max_sun_elevation:
            return

        nonlocal turn_off_light_listener
        if turn_off_light_listener is not None:
            turn_off_light_listener()
            turn_off_light_listener = None
        turn_off_light_listener = track_point_in_time(
            hass, deactivate,
            dt_util.utcnow() +
            datetime.timedelta(minutes=leave_lights_on_for_min))

        light_state = hass.states.get(light_entity_id)
        if light_state.state == STATE_ON:
            return

        now = dt_util.now()
        if now.hour >= 22 or now.hour < 7:
            light.turn_on(hass,
                          light_entity_id,
                          xy_color=[0.6461, 0.3426],
                          brightness=64,
                          transition=3)
        elif entity_id == 'binary_sensor.movement3':
            light.turn_on(hass,
                          light_entity_id,
                          xy_color=[0.4607, 0.43],
                          brightness=81,
                          transition=1)
        else:
            return

    def deactivate(now):
        light.turn_off(hass, light_entity_id)

    track_state_change(hass, trigger_sensors, activate, STATE_OFF, STATE_ON)

    return True
Example #32
0
def setup_platform(
    hass: HomeAssistant,
    config: ConfigEntry,
    add_entities: Callable[[List[Entity], bool], None],
    discovery_info=None,
) -> None:
    """Set up the Spotify Metafy platform."""

    if "spotify" not in hass.data:
        raise PlatformNotReady

    entities: List[MetafyMediaPlayer] = []
    entity_component: EntityComponent = hass.data[MEDIA_PLAYER_DOMAIN]

    # Make sure all the players are ready
    for user in config["users"]:
        spotify_entity_id = user["spotify_entity_id"]
        spotify_media_player: SpotifyMediaPlayer = entity_component.get_entity(
            spotify_entity_id
        )
        if spotify_media_player is None:
            raise PlatformNotReady

    for user in config["users"]:
        user_prefix = user["user_prefix"] if "user_prefix" in user else ""
        destination = user["destination"]
        playlists = user["playlists"]
        spotify_entity_id = user["spotify_entity_id"]
        spotify_media_player: SpotifyMediaPlayer = entity_component.get_entity(
            spotify_entity_id
        )
        for playlist in playlists:
            uri = playlist["uri"]
            spotify_playlist_info = spotify_media_player._spotify.playlist(uri)
            playlist_name = user_prefix + spotify_playlist_info["name"]
            mmp = MetafyMediaPlayer(
                spotify_media_player,
                uri,
                destination,
                playlist_name,
                spotify_playlist_info,
            )
            entities.append(mmp)

    add_entities(entities)

    for entity in entities:
        track_state_change(
            hass,
            [entity._spotify_media_player.entity_id],
            entity.update_on_state_change,
        )

    return True
Example #33
0
    def __init__(self, hass, scene_config):
        self.hass = hass
        self.scene_config = scene_config

        self.is_active = False
        self.prev_states = None
        self.ignore_updates = False

        track_state_change(self.hass, self.entity_ids,
                           self.entity_state_changed)

        self.update()
Example #34
0
def trigger(hass, config, action):
    """ Listen for state changes based on `config`. """
    entity_id = config.get(CONF_ENTITY_ID)

    if entity_id is None:
        logging.getLogger(__name__).error(
            "Missing trigger configuration key %s", CONF_ENTITY_ID)
        return None

    from_state = config.get(CONF_FROM, MATCH_ALL)
    to_state = config.get(CONF_TO) or config.get(CONF_STATE) or MATCH_ALL
    time_delta = get_time_config(config)

    if isinstance(from_state, bool) or isinstance(to_state, bool):
        logging.getLogger(__name__).error(
            'Config error. Surround to/from values with quotes.')
        return None

    if CONF_FOR in config and time_delta is None:
        return None

    def state_automation_listener(entity, from_s, to_s):
        """ Listens for state changes and calls action. """

        def state_for_listener(now):
            """ Fires on state changes after a delay and calls action. """
            hass.bus.remove_listener(
                EVENT_STATE_CHANGED, for_state_listener)
            action()

        def state_for_cancel_listener(entity, inner_from_s, inner_to_s):
            """ Fires on state changes and cancels
                for listener if state changed. """
            if inner_to_s == to_s:
                return
            hass.bus.remove_listener(EVENT_TIME_CHANGED, for_time_listener)
            hass.bus.remove_listener(
                EVENT_STATE_CHANGED, for_state_listener)

        if time_delta is not None:
            target_tm = dt_util.utcnow() + time_delta
            for_time_listener = track_point_in_time(
                hass, state_for_listener, target_tm)
            for_state_listener = track_state_change(
                hass, entity_id, state_for_cancel_listener,
                MATCH_ALL, MATCH_ALL)
        else:
            action()

    track_state_change(
        hass, entity_id, state_automation_listener, from_state, to_state)

    return True
Example #35
0
    def __init__(self, hass, scene_config):
        self.hass = hass
        self.scene_config = scene_config

        self.is_active = False
        self.prev_states = None
        self.ignore_updates = False

        track_state_change(
            self.hass, self.entity_ids, self.entity_state_changed)

        self.update()
Example #36
0
    def test_track_state_change(self):
        """Test track_state_change."""
        # 2 lists to track how often our callbacks get called
        specific_runs = []
        wildcard_runs = []

        track_state_change(
            self.hass, 'light.Bowl', lambda a, b, c: specific_runs.append(1),
            'on', 'off')

        track_state_change(
            self.hass, 'light.Bowl',
            lambda _, old_s, new_s: wildcard_runs.append((old_s, new_s)),
            ha.MATCH_ALL, ha.MATCH_ALL)

        # Adding state to state machine
        self.hass.states.set("light.Bowl", "on")
        self.hass.pool.block_till_done()
        self.assertEqual(0, len(specific_runs))
        self.assertEqual(1, len(wildcard_runs))
        self.assertIsNone(wildcard_runs[-1][0])
        self.assertIsNotNone(wildcard_runs[-1][1])

        # Set same state should not trigger a state change/listener
        self.hass.states.set('light.Bowl', 'on')
        self.hass.pool.block_till_done()
        self.assertEqual(0, len(specific_runs))
        self.assertEqual(1, len(wildcard_runs))

        # State change off -> on
        self.hass.states.set('light.Bowl', 'off')
        self.hass.pool.block_till_done()
        self.assertEqual(1, len(specific_runs))
        self.assertEqual(2, len(wildcard_runs))

        # State change off -> off
        self.hass.states.set('light.Bowl', 'off', {"some_attr": 1})
        self.hass.pool.block_till_done()
        self.assertEqual(1, len(specific_runs))
        self.assertEqual(3, len(wildcard_runs))

        # State change off -> on
        self.hass.states.set('light.Bowl', 'on')
        self.hass.pool.block_till_done()
        self.assertEqual(1, len(specific_runs))
        self.assertEqual(4, len(wildcard_runs))

        self.hass.states.remove('light.bowl')
        self.hass.pool.block_till_done()
        self.assertEqual(1, len(specific_runs))
        self.assertEqual(5, len(wildcard_runs))
        self.assertIsNotNone(wildcard_runs[-1][0])
        self.assertIsNone(wildcard_runs[-1][1])
Example #37
0
    def test_case_insensitivty(self):
        self.pool.add_worker()
        runs = []

        track_state_change(ha._MockHA(self.bus), 'light.BoWl',
                           lambda a, b, c: runs.append(1), ha.MATCH_ALL,
                           ha.MATCH_ALL)

        self.states.set('light.BOWL', 'off')
        self.bus._pool.block_till_done()

        self.assertTrue(self.states.is_state('light.bowl', 'off'))
        self.assertEqual(1, len(runs))
Example #38
0
    def test_case_insensitivty(self):
        self.pool.add_worker()
        runs = []

        track_state_change(
            ha._MockHA(self.bus), 'light.BoWl', lambda a, b, c: runs.append(1),
            ha.MATCH_ALL, ha.MATCH_ALL)

        self.states.set('light.BOWL', 'off')
        self.bus._pool.block_till_done()

        self.assertTrue(self.states.is_state('light.bowl', 'off'))
        self.assertEqual(1, len(runs))
Example #39
0
def trigger(hass, config, action):
    """Listen for state changes based on configuration."""
    entity_id = config.get(CONF_ENTITY_ID)
    from_state = config.get(CONF_FROM, MATCH_ALL)
    to_state = config.get(CONF_TO) or config.get(CONF_STATE) or MATCH_ALL
    time_delta = config.get(CONF_FOR)

    def state_automation_listener(entity, from_s, to_s):
        """Listen for state changes and calls action."""
        def call_action():
            """Call action with right context."""
            action({
                'trigger': {
                    'platform': 'state',
                    'entity_id': entity,
                    'from_state': from_s,
                    'to_state': to_s,
                    'for': time_delta,
                }
            })

        if time_delta is None:
            call_action()
            return

        def state_for_listener(now):
            """Fire on state changes after a delay and calls action."""
            hass.bus.remove_listener(EVENT_STATE_CHANGED,
                                     attached_state_for_cancel)
            call_action()

        def state_for_cancel_listener(entity, inner_from_s, inner_to_s):
            """Fire on changes and cancel for listener if changed."""
            if inner_to_s.state == to_s.state:
                return
            hass.bus.remove_listener(EVENT_TIME_CHANGED,
                                     attached_state_for_listener)
            hass.bus.remove_listener(EVENT_STATE_CHANGED,
                                     attached_state_for_cancel)

        attached_state_for_listener = track_point_in_time(
            hass, state_for_listener,
            dt_util.utcnow() + time_delta)

        attached_state_for_cancel = track_state_change(
            hass, entity, state_for_cancel_listener)

    track_state_change(hass, entity_id, state_automation_listener, from_state,
                       to_state)

    return True
Example #40
0
def trigger(hass, config, action):
    """Listen for state changes based on configuration."""
    entity_id = config.get(CONF_ENTITY_ID)
    from_state = config.get(CONF_FROM, MATCH_ALL)
    to_state = config.get(CONF_TO) or config.get(CONF_STATE) or MATCH_ALL
    time_delta = config.get(CONF_FOR)

    def state_automation_listener(entity, from_s, to_s):
        """Listen for state changes and calls action."""
        def call_action():
            """Call action with right context."""
            action({
                'trigger': {
                    'platform': 'state',
                    'entity_id': entity,
                    'from_state': from_s,
                    'to_state': to_s,
                    'for': time_delta,
                }
            })

        if time_delta is None:
            call_action()
            return

        def state_for_listener(now):
            """Fire on state changes after a delay and calls action."""
            hass.bus.remove_listener(
                EVENT_STATE_CHANGED, attached_state_for_cancel)
            call_action()

        def state_for_cancel_listener(entity, inner_from_s, inner_to_s):
            """Fire on changes and cancel for listener if changed."""
            if inner_to_s.state == to_s.state:
                return
            hass.bus.remove_listener(EVENT_TIME_CHANGED,
                                     attached_state_for_listener)
            hass.bus.remove_listener(EVENT_STATE_CHANGED,
                                     attached_state_for_cancel)

        attached_state_for_listener = track_point_in_time(
            hass, state_for_listener, dt_util.utcnow() + time_delta)

        attached_state_for_cancel = track_state_change(
            hass, entity, state_for_cancel_listener)

    track_state_change(
        hass, entity_id, state_automation_listener, from_state, to_state)

    return True
Example #41
0
def trigger(hass, config, action):
    """ Listen for state changes based on `config`. """
    entity_id = config.get(CONF_ENTITY_ID)

    if entity_id is None:
        logging.getLogger(__name__).error(
            "Missing trigger configuration key %s", CONF_ENTITY_ID)
        return None

    from_state = config.get(CONF_FROM, MATCH_ALL)
    to_state = config.get(CONF_TO) or config.get(CONF_STATE) or MATCH_ALL
    time_delta = get_time_config(config)

    if isinstance(from_state, bool) or isinstance(to_state, bool):
        logging.getLogger(__name__).error(
            'Config error. Surround to/from values with quotes.')
        return None

    if CONF_FOR in config and time_delta is None:
        return None

    def state_automation_listener(entity, from_s, to_s):
        """ Listens for state changes and calls action. """
        def state_for_listener(now):
            """ Fires on state changes after a delay and calls action. """
            hass.bus.remove_listener(EVENT_STATE_CHANGED, for_state_listener)
            action()

        def state_for_cancel_listener(entity, inner_from_s, inner_to_s):
            """ Fires on state changes and cancels
                for listener if state changed. """
            if inner_to_s == to_s:
                return
            hass.bus.remove_listener(EVENT_TIME_CHANGED, for_time_listener)
            hass.bus.remove_listener(EVENT_STATE_CHANGED, for_state_listener)

        if time_delta is not None:
            target_tm = dt_util.utcnow() + time_delta
            for_time_listener = track_point_in_time(hass, state_for_listener,
                                                    target_tm)
            for_state_listener = track_state_change(hass, entity_id,
                                                    state_for_cancel_listener,
                                                    MATCH_ALL, MATCH_ALL)
        else:
            action()

    track_state_change(hass, entity_id, state_automation_listener, from_state,
                       to_state)

    return True
Example #42
0
    def _started(self, event):
        '''
    Callback invoked when all components have been initialized. Setting up
    other listeners here ensures we won't get extra calls. This is when time
    events start firing anyway.
    '''
        _LOGGER.info('Starting alarm for {}'.format(self.time))

        track_state_change(self.hass, self.time, self._time_changed)
        if self.master_control:
            track_state_change(self.hass, self.master_control,
                               self._master_control_changed)

        self._update_alarms()
Example #43
0
    def turn_on(self, *args, **kwargs):
        """ Turn on the selected media_player from input_select """
        if self._unsub_speaker_tracker:
            self._unsub_speaker_tracker()
        self._playing = False
        select_speaker = self.hass.states.get(self._media_player)
        self._speaker = "media_player.{}".format(select_speaker.state)
        speaker_state = self.hass.states.get(self._speaker)
        if speaker_state == None:
            self._speaker = None
            return
        self.schedule_update_ha_state()
        _LOGGER.info("turn on speaker %s", self._speaker)

        if speaker_state.state == STATE_OFF:
            self.hass.services.call(DOMAIN_MP, 'turn_on',
                                    {ATTR_ENTITY_ID: self._speaker})
            self._state = STATE_IDLE
            self._unsub_speaker_tracker = track_state_change(
                self.hass, self._speaker, self._sync_player)
            self.schedule_update_ha_state()
        elif speaker_state.state == STATE_IDLE:
            self._state = STATE_IDLE
            self._unsub_speaker_tracker = track_state_change(
                self.hass, self._speaker, self._sync_player)
            self.schedule_update_ha_state()
        elif speaker_state.state == STATE_PLAYING or speaker_state.state == STATE_PAUSED:
            self._state = STATE_IDLE
            self.hass.services.call(DOMAIN_MP, 'media_stop',
                                    {ATTR_ENTITY_ID: self._speaker})
            self._unsub_speaker_tracker = track_state_change(
                self.hass, self._speaker, self._sync_player)
            self.schedule_update_ha_state()
        else:
            self._state = STATE_OFF
            return

        if self._current_track == None:
            url = "{}/current_track".format(self._gmproxyurl)
            try:
                self._current_track = json.loads(requests.get(url).content)
                self.update_media_info()
            except:
                self._state = STATE_OFF
                return

        if self._current_track == None:
            self._state = STATE_OFF
        else:
            self.media_play()
Example #44
0
    def __init__(self, hass, name, heater_entity_id, sensor_entity_id):
        self.hass = hass
        self._name = name
        self.heater_entity_id = heater_entity_id

        self._active = False
        self._cur_temp = None
        self._target_temp = None
        self._unit = None

        track_state_change(hass, sensor_entity_id, self._sensor_changed)

        sensor_state = hass.states.get(sensor_entity_id)
        if sensor_state:
            self._update_temp(sensor_state)
Example #45
0
def setup(hass, config):

    # state listener: pass in entity that changed
    def state_changed(entity_id, old_state, new_state):
        _LOGGER.debug(f"{dbg()}:{entity_id} changed state: {new_state}")
        hass.data[ENERGY_ASSET_DOMAIN].add_dirty_list(entity_id)
        hass.data[ENERGY_ASSET_DOMAIN].update_asset(entity_id, new_state.attributes)

    _LOGGER.debug(f"{dbg()}:Entities: {group.get_entity_ids(hass, 'group.all_switches')}")

    # register the state change listener: pass in the entities to observer and the callback listener
    # will listen on the event bus and filter for the entities we care about
    track_state_change(hass, group.get_entity_ids(hass, 'group.all_switches'), state_changed)

    return True  # show that the component loaded successfully
    def __init__(self, hass, name, heater_entity_id, sensor_entity_id):
        self.hass = hass
        self._name = name
        self.heater_entity_id = heater_entity_id

        self._active = False
        self._cur_temp = None
        self._target_temp = None
        self._unit = None

        track_state_change(hass, sensor_entity_id, self._sensor_changed)

        sensor_state = hass.states.get(sensor_entity_id)
        if sensor_state:
            self._update_temp(sensor_state)
Example #47
0
def trigger(hass, config, action):
    """Listen for state changes based on configuration."""
    entity_id = config.get(CONF_ENTITY_ID)
    zone_entity_id = config.get(CONF_ZONE)
    event = config.get(CONF_EVENT)

    def zone_automation_listener(entity, from_s, to_s):
        """Listen for state changes and calls action."""
        if from_s and not location.has_location(from_s) or not location.has_location(to_s):
            return

        zone_state = hass.states.get(zone_entity_id)
        if from_s:
            from_match = condition.zone(hass, zone_state, from_s)
        else:
            from_match = False
        to_match = condition.zone(hass, zone_state, to_s)

        # pylint: disable=too-many-boolean-expressions
        if event == EVENT_ENTER and not from_match and to_match or event == EVENT_LEAVE and from_match and not to_match:
            action(
                {
                    "trigger": {
                        "platform": "zone",
                        "entity_id": entity,
                        "from_state": from_s,
                        "to_state": to_s,
                        "zone": zone_state,
                        "event": event,
                    }
                }
            )

    return track_state_change(hass, entity_id, zone_automation_listener, MATCH_ALL, MATCH_ALL)
Example #48
0
def trigger(hass, config, action):
    """Listen for state changes based on configuration."""
    value_template = config.get(CONF_VALUE_TEMPLATE)
    value_template.hass = hass

    # Local variable to keep track of if the action has already been triggered
    already_triggered = False

    @asyncio.coroutine
    def state_changed_listener(entity_id, from_s, to_s):
        """Listen for state changes and calls action."""
        nonlocal already_triggered
        template_result = condition.async_template(hass, value_template)

        # Check to see if template returns true
        if template_result and not already_triggered:
            already_triggered = True
            hass.async_add_job(action, {
                'trigger': {
                    'platform': 'template',
                    'entity_id': entity_id,
                    'from_state': from_s,
                    'to_state': to_s,
                },
            })
        elif not template_result:
            already_triggered = False

    return track_state_change(hass, value_template.extract_entities(),
                              state_changed_listener)
Example #49
0
def trigger(hass, config, action):
    """Listen for state changes based on configuration."""
    entity_id = config.get(CONF_ENTITY_ID)
    from_state = config.get(CONF_FROM, MATCH_ALL)
    to_state = config.get(CONF_TO) or config.get(CONF_STATE) or MATCH_ALL
    time_delta = config.get(CONF_FOR)
    remove_state_for_cancel = None
    remove_state_for_listener = None

    def state_automation_listener(entity, from_s, to_s):
        """Listen for state changes and calls action."""
        nonlocal remove_state_for_cancel, remove_state_for_listener

        def call_action():
            """Call action with right context."""
            action(
                {
                    "trigger": {
                        "platform": "state",
                        "entity_id": entity,
                        "from_state": from_s,
                        "to_state": to_s,
                        "for": time_delta,
                    }
                }
            )

        if time_delta is None:
            call_action()
            return

        def state_for_listener(now):
            """Fire on state changes after a delay and calls action."""
            remove_state_for_cancel()
            call_action()

        def state_for_cancel_listener(entity, inner_from_s, inner_to_s):
            """Fire on changes and cancel for listener if changed."""
            if inner_to_s.state == to_s.state:
                return
            remove_state_for_listener()
            remove_state_for_cancel()

        remove_state_for_listener = track_point_in_time(hass, state_for_listener, dt_util.utcnow() + time_delta)

        remove_state_for_cancel = track_state_change(hass, entity, state_for_cancel_listener)

    unsub = track_state_change(hass, entity_id, state_automation_listener, from_state, to_state)

    def remove():
        """Remove state listeners."""
        unsub()
        # pylint: disable=not-callable
        if remove_state_for_cancel is not None:
            remove_state_for_cancel()

        if remove_state_for_listener is not None:
            remove_state_for_listener()

    return remove
Example #50
0
    def state_automation_listener(entity, from_s, to_s):
        """Listen for state changes and calls action."""
        def state_for_listener(now):
            """Fire on state changes after a delay and calls action."""
            hass.bus.remove_listener(
                EVENT_STATE_CHANGED, for_state_listener)
            action()

        def state_for_cancel_listener(entity, inner_from_s, inner_to_s):
            """Fire on changes and cancel for listener if changed."""
            if inner_to_s == to_s:
                return
            hass.bus.remove_listener(EVENT_TIME_CHANGED, for_time_listener)
            hass.bus.remove_listener(
                EVENT_STATE_CHANGED, for_state_listener)

        if time_delta is not None:
            target_tm = dt_util.utcnow() + time_delta
            for_time_listener = track_point_in_time(
                hass, state_for_listener, target_tm)
            for_state_listener = track_state_change(
                hass, entity_id, state_for_cancel_listener,
                MATCH_ALL, MATCH_ALL)
        else:
            action()
    def __init__(self, hass, config, see):
        self._hass = hass
        self._see = see
        entities = config[CONF_ENTITY_ID]
        self._entities = {}
        for entity_id in entities:
            self._entities[entity_id] = {
                WARNED: False,
                SOURCE_TYPE: None,
                STATE: None
            }
        self._dev_id = config[CONF_NAME]
        self._entity_id = ENTITY_ID_FORMAT.format(self._dev_id)
        self._time_as = config[CONF_TIME_AS]
        if self._time_as in [TZ_DEVICE_UTC, TZ_DEVICE_LOCAL]:
            from timezonefinderL import TimezoneFinder
            self._tf = TimezoneFinder()
        self._lock = threading.Lock()
        self._prev_seen = None

        self._remove = track_state_change(hass, entities, self._update_info)

        for entity_id in entities:
            self._update_info(entity_id,
                              None,
                              hass.states.get(entity_id),
                              init=True)
Example #52
0
    def __init__(self, hass, device_id, friendly_name, unit_of_measurement, state_template, entity_ids):
        """Initialize the sensor."""
        self.hass = hass
        self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, device_id, hass=hass)
        self._name = friendly_name
        self._unit_of_measurement = unit_of_measurement
        self._template = state_template
        self._state = None

        self.update()

        def template_sensor_state_listener(entity, old_state, new_state):
            """Called when the target device changes state."""
            self.update_ha_state(True)

        track_state_change(hass, entity_ids, template_sensor_state_listener)
Example #53
0
def setup(hass, config):  # pylint: disable=too-many-locals,too-many-statements
    """ Get the zones and offsets from configuration.yaml. """
    ignored_zones = []
    if 'ignored_zones' in config[DOMAIN]:
        for variable in config[DOMAIN]['ignored_zones']:
            ignored_zones.append(variable)

    # Get the devices from configuration.yaml
    if 'devices' not in config[DOMAIN]:
        _LOGGER.error('devices not found in config')
        return False

    proximity_devices = []
    for variable in config[DOMAIN]['devices']:
        proximity_devices.append(variable)

    # Get the direction of travel tolerance from configuration.yaml
    tolerance = config[DOMAIN].get('tolerance', DEFAULT_TOLERANCE)

    # Get the zone to monitor proximity to from configuration.yaml
    proximity_zone = config[DOMAIN].get('zone', DEFAULT_PROXIMITY_ZONE)

    entity_id = DOMAIN + '.' + proximity_zone
    proximity_zone = 'zone.' + proximity_zone

    state = hass.states.get(proximity_zone)
    zone_friendly_name = (state.name).lower()

    # set the default values
    dist_to_zone = 'not set'
    dir_of_travel = 'not set'
    nearest = 'not set'

    proximity = Proximity(hass, zone_friendly_name, dist_to_zone,
                          dir_of_travel, nearest, ignored_zones,
                          proximity_devices, tolerance, proximity_zone)
    proximity.entity_id = entity_id

    proximity.update_ha_state()

    # Main command to monitor proximity of devices
    track_state_change(hass, proximity_devices,
                       proximity.check_proximity_state_change)

    return True
    def test_multiple_emails(self):
        """Test multiple emails."""
        states = []

        test_message1 = email.message.Message()
        test_message1['From'] = "*****@*****.**"
        test_message1['Subject'] = "Test"
        test_message1['Date'] = datetime.datetime(2016, 1, 1, 12, 44, 57)
        test_message1.set_payload("Test Message")

        test_message2 = email.message.Message()
        test_message2['From'] = "*****@*****.**"
        test_message2['Subject'] = "Test 2"
        test_message2['Date'] = datetime.datetime(2016, 1, 1, 12, 44, 57)
        test_message2.set_payload("Test Message 2")

        states_received = Event()

        def state_changed_listener(entity_id, from_s, to_s):
            states.append(to_s)
            if len(states) == 2:
                states_received.set()

        track_state_change(
            self.hass,
            ["sensor.emailtest"],
            state_changed_listener)

        sensor = imap_email_content.EmailContentSensor(
            self.hass,
            FakeEMailReader(deque([test_message1, test_message2])),
            "test_emails_sensor",
            ["*****@*****.**"],
            None)

        sensor.entity_id = "sensor.emailtest"
        sensor.update()

        self.hass.block_till_done()
        states_received.wait(5)

        self.assertEqual("Test Message", states[0].state)
        self.assertEqual("Test Message 2", states[1].state)

        self.assertEqual("Test Message 2", sensor.state)
Example #55
0
    def __init__(self, hass, name, children, commands, attributes):
        """Initialize the Universal media device."""
        self.hass = hass
        self._name = name
        self._children = children
        self._cmds = commands
        self._attrs = attributes
        self._child_state = None

        def on_dependency_update(*_):
            """Update ha state when dependencies update."""
            self.update_ha_state(True)

        depend = copy(children)
        for entity in attributes.values():
            depend.append(entity[0])

        track_state_change(hass, depend, on_dependency_update)
Example #56
0
    def __init__(self, hass, name, children, commands, attributes):
        # pylint: disable=too-many-arguments
        self.hass = hass
        self._name = name
        self._children = children
        self._cmds = commands
        self._attrs = attributes
        self._child_state = None

        def on_dependency_update(*_):
            """ update ha state when dependencies update """
            self.update_ha_state(True)

        depend = copy(children)
        for entity in attributes.values():
            depend.append(entity[0])

        track_state_change(hass, depend, on_dependency_update)