Esempio n. 1
0
def setup(hass, config):
    """Setup input select."""
    if not isinstance(config.get(DOMAIN), dict):
        _LOGGER.error('Expected %s config to be a dictionary', DOMAIN)
        return False

    component = EntityComponent(_LOGGER, DOMAIN, hass)

    entities = []

    for object_id, cfg in config[DOMAIN].items():
        if object_id != slugify(object_id):
            _LOGGER.warning(
                "Found invalid key for boolean input: %s. "
                "Use %s instead", object_id, slugify(object_id))
            continue
        if not cfg:
            _LOGGER.warning("No configuration specified for %s", object_id)
            continue

        name = cfg.get(CONF_NAME)
        options = cfg.get(CONF_OPTIONS)

        if not isinstance(options, list) or len(options) == 0:
            _LOGGER.warning('Key %s should be a list of options', CONF_OPTIONS)
            continue

        options = [str(val) for val in options]

        state = cfg.get(CONF_INITIAL)

        if state not in options:
            state = options[0]

        icon = cfg.get(CONF_ICON)

        entities.append(InputSelect(object_id, name, state, options, icon))

    if not entities:
        return False

    def select_option_service(call):
        """Handle a calls to the input select services."""
        target_inputs = component.extract_from_service(call)

        for input_select in target_inputs:
            input_select.select_option(call.data[ATTR_OPTION])

    hass.services.register(DOMAIN,
                           SERVICE_SELECT_OPTION,
                           select_option_service,
                           schema=SERVICE_SELECT_OPTION_SCHEMA)

    component.add_entities(entities)

    return True
Esempio n. 2
0
def setup(hass, config):
    """Set up input slider."""
    if not isinstance(config.get(DOMAIN), dict):
        _LOGGER.error('Expected %s config to be a dictionary', DOMAIN)
        return False

    component = EntityComponent(_LOGGER, DOMAIN, hass)

    entities = []

    for object_id, cfg in config[DOMAIN].items():
        if object_id != slugify(object_id):
            _LOGGER.warning(
                "Found invalid key for boolean input: %s. "
                "Use %s instead", object_id, slugify(object_id))
            continue
        if not cfg:
            _LOGGER.warning("No configuration specified for %s", object_id)
            continue

        name = cfg.get(CONF_NAME)
        minimum = cfg.get(CONF_MIN)
        maximum = cfg.get(CONF_MAX)
        state = cfg.get(CONF_INITIAL, minimum)
        step = cfg.get(CONF_STEP, 1)
        icon = cfg.get(CONF_ICON)
        unit = cfg.get(ATTR_UNIT_OF_MEASUREMENT)

        if state < minimum:
            state = minimum
        if state > maximum:
            state = maximum

        entities.append(
            InputSlider(object_id, name, state, minimum, maximum, step, icon,
                        unit))

    if not entities:
        return False

    def select_value_service(call):
        """Handle a calls to the input slider services."""
        target_inputs = component.extract_from_service(call)

        for input_slider in target_inputs:
            input_slider.select_value(call.data[ATTR_VALUE])

    hass.services.register(DOMAIN,
                           SERVICE_SELECT_VALUE,
                           select_value_service,
                           schema=SERVICE_SELECT_VALUE_SCHEMA)

    component.add_entities(entities)

    return True
Esempio n. 3
0
def setup(hass, config):
    """Set up input boolean."""
    if not isinstance(config.get(DOMAIN), dict):
        _LOGGER.error('Expected %s config to be a dictionary', DOMAIN)
        return False

    component = EntityComponent(_LOGGER, DOMAIN, hass)

    entities = []

    for object_id, cfg in config[DOMAIN].items():
        if object_id != slugify(object_id):
            _LOGGER.warning(
                "Found invalid key for boolean input: %s. "
                "Use %s instead", object_id, slugify(object_id))
            continue
        if not cfg:
            cfg = {}

        name = cfg.get(CONF_NAME)
        state = cfg.get(CONF_INITIAL, False)
        icon = cfg.get(CONF_ICON)

        entities.append(InputBoolean(object_id, name, state, icon))

    if not entities:
        return False

    def toggle_service(service):
        """Handle a calls to the input boolean services."""
        target_inputs = component.extract_from_service(service)

        for input_b in target_inputs:
            if service.service == SERVICE_TURN_ON:
                input_b.turn_on()
            else:
                input_b.turn_off()

    hass.services.register(DOMAIN,
                           SERVICE_TURN_OFF,
                           toggle_service,
                           schema=TOGGLE_SERVICE_SCHEMA)
    hass.services.register(DOMAIN,
                           SERVICE_TURN_ON,
                           toggle_service,
                           schema=TOGGLE_SERVICE_SCHEMA)

    component.add_entities(entities)

    return True
Esempio n. 4
0
def setup_platform(hass, config, add_devices, discovery_info=None):
    """Setup template binary sensors."""
    sensors = []
    if config.get(CONF_SENSORS) is None:
        _LOGGER.error('Missing configuration data for binary_sensor platform')
        return False

    for device, device_config in config[CONF_SENSORS].items():

        if device != slugify(device):
            _LOGGER.error('Found invalid key for binary_sensor.template: %s. '
                          'Use %s instead', device, slugify(device))
            continue

        if not isinstance(device_config, dict):
            _LOGGER.error('Missing configuration data for binary_sensor %s',
                          device)
            continue

        friendly_name = device_config.get(ATTR_FRIENDLY_NAME, device)
        sensor_class = device_config.get('sensor_class')
        value_template = device_config.get(CONF_VALUE_TEMPLATE)

        if sensor_class not in SENSOR_CLASSES:
            _LOGGER.error('Sensor class is not valid')
            continue

        if value_template is None:
            _LOGGER.error(
                'Missing %s for sensor %s', CONF_VALUE_TEMPLATE, device)
            continue

        entity_ids = device_config.get(ATTR_ENTITY_ID, MATCH_ALL)

        sensors.append(
            BinarySensorTemplate(
                hass,
                device,
                friendly_name,
                sensor_class,
                value_template,
                entity_ids)
            )
    if not sensors:
        _LOGGER.error('No sensors added')
        return False
    add_devices(sensors)

    return True
Esempio n. 5
0
def setup_platform(hass, config, add_devices, discovery_info=None):
    """Setup the Template switch."""
    switches = []
    if config.get(CONF_SWITCHES) is None:
        _LOGGER.error("Missing configuration data for switch platform")
        return False

    for device, device_config in config[CONF_SWITCHES].items():

        if device != slugify(device):
            _LOGGER.error("Found invalid key for switch.template: %s. "
                          "Use %s instead", device, slugify(device))
            continue

        if not isinstance(device_config, dict):
            _LOGGER.error("Missing configuration data for switch %s", device)
            continue

        friendly_name = device_config.get(ATTR_FRIENDLY_NAME, device)
        state_template = device_config.get(CONF_VALUE_TEMPLATE)
        on_action = device_config.get(ON_ACTION)
        off_action = device_config.get(OFF_ACTION)
        if state_template is None:
            _LOGGER.error(
                "Missing %s for switch %s", CONF_VALUE_TEMPLATE, device)
            continue

        if on_action is None or off_action is None:
            _LOGGER.error(
                "Missing action for switch %s", device)
            continue

        entity_ids = device_config.get(ATTR_ENTITY_ID, MATCH_ALL)

        switches.append(
            SwitchTemplate(
                hass,
                device,
                friendly_name,
                state_template,
                on_action,
                off_action,
                entity_ids)
            )
    if not switches:
        _LOGGER.error("No switches added")
        return False
    add_devices(switches)
    return True
Esempio n. 6
0
def apply_received_command(event):
    """Apply command from rfxtrx."""
    device_id = slugify(event.device.id_string.lower())
    # Check if entity exists or previously added automatically
    if device_id not in RFX_DEVICES:
        return

    _LOGGER.debug("EntityID: %s device_update. Command: %s", device_id,
                  event.values['Command'])

    if event.values['Command'] == 'On'\
            or event.values['Command'] == 'Off':

        # Update the rfxtrx device state
        is_on = event.values['Command'] == 'On'
        RFX_DEVICES[device_id].update_state(is_on)

    elif hasattr(RFX_DEVICES[device_id], 'brightness')\
            and event.values['Command'] == 'Set level':
        _brightness = (event.values['Dim level'] * 255 // 100)

        # Update the rfxtrx device state
        is_on = _brightness > 0
        RFX_DEVICES[device_id].update_state(is_on, _brightness)

    # Fire event
    if RFX_DEVICES[device_id].should_fire_event:
        RFX_DEVICES[device_id].hass.bus.fire(
            EVENT_BUTTON_PRESSED, {
                ATTR_ENTITY_ID: RFX_DEVICES[device_id].entity_id,
                ATTR_STATE: event.values['Command'].lower()
            })
Esempio n. 7
0
    def sensor_update(event):
        """Callback for sensor updates from the RFXtrx gateway."""
        if not isinstance(event, SensorEvent):
            return

        device_id = "sensor_" + slugify(event.device.id_string.lower())

        if device_id in rfxtrx.RFX_DEVICES:
            sensors = rfxtrx.RFX_DEVICES[device_id]
            for key in sensors:
                sensors[key].event = event
            return

        # Add entity if not exist and the automatic_add is True
        if not config[ATTR_AUTOMATIC_ADD]:
            return

        pkt_id = "".join("{0:02x}".format(x) for x in event.data)
        _LOGGER.info("Automatic add rfxtrx.sensor: %s",
                     device_id)

        data_type = "Unknown"
        for _data_type in DATA_TYPES:
            if _data_type in event.values:
                data_type = _data_type
                break
        new_sensor = RfxtrxSensor(event, pkt_id, data_type)
        sub_sensors = {}
        sub_sensors[new_sensor.data_type] = new_sensor
        rfxtrx.RFX_DEVICES[device_id] = sub_sensors
        add_devices_callback([new_sensor])
Esempio n. 8
0
    def sensor_update(event):
        """Callback for sensor updates from the RFXtrx gateway."""
        if not isinstance(event, SensorEvent):
            return

        device_id = "sensor_" + slugify(event.device.id_string.lower())

        if device_id in rfxtrx.RFX_DEVICES:
            sensors = rfxtrx.RFX_DEVICES[device_id]
            for key in sensors:
                sensors[key].event = event
            return

        # Add entity if not exist and the automatic_add is True
        if not config[ATTR_AUTOMATIC_ADD]:
            return

        pkt_id = "".join("{0:02x}".format(x) for x in event.data)
        _LOGGER.info("Automatic add rfxtrx.sensor: %s", device_id)

        data_type = "Unknown"
        for _data_type in DATA_TYPES:
            if _data_type in event.values:
                data_type = _data_type
                break
        new_sensor = RfxtrxSensor(event, pkt_id, data_type)
        sub_sensors = {}
        sub_sensors[new_sensor.data_type] = new_sensor
        rfxtrx.RFX_DEVICES[device_id] = sub_sensors
        add_devices_callback([new_sensor])
Esempio n. 9
0
    def see(self,
            mac=None,
            dev_id=None,
            host_name=None,
            location_name=None,
            gps=None,
            gps_accuracy=None,
            battery=None):
        """Notify the device tracker that you see a device."""
        with self.lock:
            if mac is None and dev_id is None:
                raise BluMateError('Neither mac or device id passed in')
            elif mac is not None:
                mac = mac.upper()
                device = self.mac_to_dev.get(mac)
                if not device:
                    dev_id = util.slugify(host_name or '') or util.slugify(mac)
            else:
                dev_id = cv.slug(str(dev_id).lower())
                device = self.devices.get(dev_id)

            if device:
                device.seen(host_name, location_name, gps, gps_accuracy,
                            battery)
                if device.track:
                    device.update_ha_state()
                return

            # If no device can be found, create it
            dev_id = util.ensure_unique_string(dev_id, self.devices.keys())
            device = Device(self.hass, self.consider_home, self.home_range,
                            self.track_new, dev_id, mac,
                            (host_name or dev_id).replace('_', ' '))
            self.devices[dev_id] = device
            if mac is not None:
                self.mac_to_dev[mac] = device

            device.seen(host_name, location_name, gps, gps_accuracy, battery)
            if device.track:
                device.update_ha_state()

            # During init, we ignore the group
            if self.group is not None:
                self.group.update_tracked_entity_ids(
                    list(self.group.tracking) + [device.entity_id])
            update_config(self.hass.config.path(YAML_DEVICES), dev_id, device)
Esempio n. 10
0
 def __init__(self, hass, name, url, icon):
     """Initialize the link."""
     self.hass = hass
     self._name = name
     self._url = url
     self._icon = icon
     self.entity_id = DOMAIN + '.%s' % slugify(name)
     self.update_ha_state()
Esempio n. 11
0
 def __init__(self, hass, name, url, icon):
     """Initialize the link."""
     self.hass = hass
     self._name = name
     self._url = url
     self._icon = icon
     self.entity_id = DOMAIN + '.%s' % slugify(name)
     self.update_ha_state()
Esempio n. 12
0
def setup(hass, config):
    """Set up input boolean."""
    if not isinstance(config.get(DOMAIN), dict):
        _LOGGER.error('Expected %s config to be a dictionary', DOMAIN)
        return False

    component = EntityComponent(_LOGGER, DOMAIN, hass)

    entities = []

    for object_id, cfg in config[DOMAIN].items():
        if object_id != slugify(object_id):
            _LOGGER.warning("Found invalid key for boolean input: %s. "
                            "Use %s instead", object_id, slugify(object_id))
            continue
        if not cfg:
            cfg = {}

        name = cfg.get(CONF_NAME)
        state = cfg.get(CONF_INITIAL, False)
        icon = cfg.get(CONF_ICON)

        entities.append(InputBoolean(object_id, name, state, icon))

    if not entities:
        return False

    def toggle_service(service):
        """Handle a calls to the input boolean services."""
        target_inputs = component.extract_from_service(service)

        for input_b in target_inputs:
            if service.service == SERVICE_TURN_ON:
                input_b.turn_on()
            else:
                input_b.turn_off()

    hass.services.register(DOMAIN, SERVICE_TURN_OFF, toggle_service,
                           schema=TOGGLE_SERVICE_SCHEMA)
    hass.services.register(DOMAIN, SERVICE_TURN_ON, toggle_service,
                           schema=TOGGLE_SERVICE_SCHEMA)

    component.add_entities(entities)

    return True
Esempio n. 13
0
    def scene_activated(node, scene_id):
        """Called when a scene is activated on any node in the network."""
        name = _node_name(node)
        object_id = "{}_{}".format(slugify(name), node.node_id)

        hass.bus.fire(EVENT_SCENE_ACTIVATED, {
            ATTR_ENTITY_ID: object_id,
            ATTR_SCENE_ID: scene_id
        })
Esempio n. 14
0
def slug(value):
    """Validate value is a valid slug."""
    if value is None:
        raise vol.Invalid('Slug should not be None')
    value = str(value)
    slg = slugify(value)
    if value == slg:
        return value
    raise vol.Invalid('invalid slug {} (try {})'.format(value, slg))
Esempio n. 15
0
def slug(value):
    """Validate value is a valid slug."""
    if value is None:
        raise vol.Invalid('Slug should not be None')
    value = str(value)
    slg = slugify(value)
    if value == slg:
        return value
    raise vol.Invalid('invalid slug {} (try {})'.format(value, slg))
Esempio n. 16
0
def setup_platform(hass, config, add_devices, discovery_info=None):
    """Setup template binary sensors."""
    sensors = []
    if config.get(CONF_SENSORS) is None:
        _LOGGER.error('Missing configuration data for binary_sensor platform')
        return False

    for device, device_config in config[CONF_SENSORS].items():

        if device != slugify(device):
            _LOGGER.error(
                'Found invalid key for binary_sensor.template: %s. '
                'Use %s instead', device, slugify(device))
            continue

        if not isinstance(device_config, dict):
            _LOGGER.error('Missing configuration data for binary_sensor %s',
                          device)
            continue

        friendly_name = device_config.get(ATTR_FRIENDLY_NAME, device)
        sensor_class = device_config.get('sensor_class')
        value_template = device_config.get(CONF_VALUE_TEMPLATE)

        if sensor_class not in SENSOR_CLASSES:
            _LOGGER.error('Sensor class is not valid')
            continue

        if value_template is None:
            _LOGGER.error('Missing %s for sensor %s', CONF_VALUE_TEMPLATE,
                          device)
            continue

        entity_ids = device_config.get(ATTR_ENTITY_ID, MATCH_ALL)

        sensors.append(
            BinarySensorTemplate(hass, device, friendly_name, sensor_class,
                                 value_template, entity_ids))
    if not sensors:
        _LOGGER.error('No sensors added')
        return False
    add_devices(sensors)

    return True
Esempio n. 17
0
def generate_entity_id(entity_id_format, name, current_ids=None, hass=None):
    """Generate a unique entity ID based on given entity IDs or used IDs."""
    name = (name or DEVICE_DEFAULT_NAME).lower()
    if current_ids is None:
        if hass is None:
            raise RuntimeError("Missing required parameter currentids or hass")

        current_ids = hass.states.entity_ids()

    return ensure_unique_string(
        entity_id_format.format(slugify(name)), current_ids)
Esempio n. 18
0
def generate_entity_id(entity_id_format, name, current_ids=None, hass=None):
    """Generate a unique entity ID based on given entity IDs or used IDs."""
    name = (name or DEVICE_DEFAULT_NAME).lower()
    if current_ids is None:
        if hass is None:
            raise RuntimeError("Missing required parameter currentids or hass")

        current_ids = hass.states.entity_ids()

    return ensure_unique_string(entity_id_format.format(slugify(name)),
                                current_ids)
Esempio n. 19
0
def setup_platform(hass, config, add_devices, discovery_info=None):
    """Setup the template sensors."""
    sensors = []
    if config.get(CONF_SENSORS) is None:
        _LOGGER.error("Missing configuration data for sensor platform")
        return False

    for device, device_config in config[CONF_SENSORS].items():
        if device != slugify(device):
            _LOGGER.error("Found invalid key for sensor.template: %s. "
                          "Use %s instead", device, slugify(device))
            continue

        if not isinstance(device_config, dict):
            _LOGGER.error("Missing configuration data for sensor %s", device)
            continue

        friendly_name = device_config.get(ATTR_FRIENDLY_NAME, device)
        unit_of_measurement = device_config.get(ATTR_UNIT_OF_MEASUREMENT)
        state_template = device_config.get(CONF_VALUE_TEMPLATE)
        if state_template is None:
            _LOGGER.error(
                "Missing %s for sensor %s", CONF_VALUE_TEMPLATE, device)
            continue

        entity_ids = device_config.get(ATTR_ENTITY_ID, MATCH_ALL)

        sensors.append(
            SensorTemplate(
                hass,
                device,
                friendly_name,
                unit_of_measurement,
                state_template,
                entity_ids)
            )
    if not sensors:
        _LOGGER.error("No sensors added")
        return False
    add_devices(sensors)
    return True
Esempio n. 20
0
    def see(self, mac=None, dev_id=None, host_name=None, location_name=None,
            gps=None, gps_accuracy=None, battery=None):
        """Notify the device tracker that you see a device."""
        with self.lock:
            if mac is None and dev_id is None:
                raise BluMateError('Neither mac or device id passed in')
            elif mac is not None:
                mac = mac.upper()
                device = self.mac_to_dev.get(mac)
                if not device:
                    dev_id = util.slugify(host_name or '') or util.slugify(mac)
            else:
                dev_id = cv.slug(str(dev_id).lower())
                device = self.devices.get(dev_id)

            if device:
                device.seen(host_name, location_name, gps, gps_accuracy,
                            battery)
                if device.track:
                    device.update_ha_state()
                return

            # If no device can be found, create it
            dev_id = util.ensure_unique_string(dev_id, self.devices.keys())
            device = Device(
                self.hass, self.consider_home, self.home_range, self.track_new,
                dev_id, mac, (host_name or dev_id).replace('_', ' '))
            self.devices[dev_id] = device
            if mac is not None:
                self.mac_to_dev[mac] = device

            device.seen(host_name, location_name, gps, gps_accuracy, battery)
            if device.track:
                device.update_ha_state()

            # During init, we ignore the group
            if self.group is not None:
                self.group.update_tracked_entity_ids(
                    list(self.group.tracking) + [device.entity_id])
            update_config(self.hass.config.path(YAML_DEVICES), dev_id, device)
Esempio n. 21
0
def _object_id(value):
    """Return the object_id of the device value.

    The object_id contains node_id and value instance id
    to not collide with other entity_ids.
    """
    object_id = "{}_{}".format(slugify(_value_name(value)), value.node.node_id)

    # Add the instance id if there is more than one instance for the value
    if value.instance > 1:
        return "{}_{}".format(object_id, value.instance)

    return object_id
Esempio n. 22
0
def setup_platform(hass, config, add_devices, discovery_info=None):
    """Setup the template sensors."""
    sensors = []
    if config.get(CONF_SENSORS) is None:
        _LOGGER.error("Missing configuration data for sensor platform")
        return False

    for device, device_config in config[CONF_SENSORS].items():
        if device != slugify(device):
            _LOGGER.error(
                "Found invalid key for sensor.template: %s. "
                "Use %s instead", device, slugify(device))
            continue

        if not isinstance(device_config, dict):
            _LOGGER.error("Missing configuration data for sensor %s", device)
            continue

        friendly_name = device_config.get(ATTR_FRIENDLY_NAME, device)
        unit_of_measurement = device_config.get(ATTR_UNIT_OF_MEASUREMENT)
        state_template = device_config.get(CONF_VALUE_TEMPLATE)
        if state_template is None:
            _LOGGER.error("Missing %s for sensor %s", CONF_VALUE_TEMPLATE,
                          device)
            continue

        entity_ids = device_config.get(ATTR_ENTITY_ID, MATCH_ALL)

        sensors.append(
            SensorTemplate(hass, device, friendly_name, unit_of_measurement,
                           state_template, entity_ids))
    if not sensors:
        _LOGGER.error("No sensors added")
        return False
    add_devices(sensors)
    return True
Esempio n. 23
0
def _parse_see_args(topic, data):
    """Parse the OwnTracks location parameters, into the format see expects."""
    parts = topic.split('/')
    dev_id = slugify('{}_{}'.format(parts[1], parts[2]))
    host_name = parts[1]
    kwargs = {
        'dev_id': dev_id,
        'host_name': host_name,
        'gps': (data['lat'], data['lon'])
    }
    if 'acc' in data:
        kwargs['gps_accuracy'] = data['acc']
    if 'batt' in data:
        kwargs['battery'] = data['batt']
    return dev_id, kwargs
Esempio n. 24
0
def _parse_see_args(topic, data):
    """Parse the OwnTracks location parameters, into the format see expects."""
    parts = topic.split('/')
    dev_id = slugify('{}_{}'.format(parts[1], parts[2]))
    host_name = parts[1]
    kwargs = {
        'dev_id': dev_id,
        'host_name': host_name,
        'gps': (data['lat'], data['lon'])
    }
    if 'acc' in data:
        kwargs['gps_accuracy'] = data['acc']
    if 'batt' in data:
        kwargs['battery'] = data['batt']
    return dev_id, kwargs
Esempio n. 25
0
def get_new_device(event, config, device):
    """Add entity if not exist and the automatic_add is True."""
    device_id = slugify(event.device.id_string.lower())
    if device_id in RFX_DEVICES:
        return

    if not config[ATTR_AUTOMATIC_ADD]:
        return

    _LOGGER.info("Automatic add %s rfxtrx device (Class: %s Sub: %s)",
                 device_id, event.device.__class__.__name__,
                 event.device.subtype)
    pkt_id = "".join("{0:02x}".format(x) for x in event.data)
    datas = {ATTR_STATE: False, ATTR_FIREEVENT: False}
    signal_repetitions = config[CONF_SIGNAL_REPETITIONS]
    new_device = device(pkt_id, event, datas, signal_repetitions)
    RFX_DEVICES[device_id] = new_device
    return new_device
Esempio n. 26
0
def get_devices_from_config(config, device):
    """Read rfxtrx configuration."""
    signal_repetitions = config[CONF_SIGNAL_REPETITIONS]

    devices = []
    for packet_id, entity_info in config[CONF_DEVICES].items():
        event = get_rfx_object(packet_id)
        device_id = slugify(event.device.id_string.lower())
        if device_id in RFX_DEVICES:
            continue
        _LOGGER.info("Add %s rfxtrx", entity_info[ATTR_NAME])

        # Check if i must fire event
        fire_event = entity_info[ATTR_FIREEVENT]
        datas = {ATTR_STATE: False, ATTR_FIREEVENT: fire_event}

        new_device = device(entity_info[ATTR_NAME], event, datas,
                            signal_repetitions)
        RFX_DEVICES[device_id] = new_device
        devices.append(new_device)
    return devices
Esempio n. 27
0
    def owntracks_event_update(topic, payload, qos):
        """MQTT event (geofences) received."""
        # Docs on available data:
        # http://owntracks.org/booklet/tech/json/#_typetransition
        data = validate_payload(payload, 'transition')
        if not data:
            return

        if data.get('desc') is None:
            _LOGGER.error("Location missing from `Entering/Leaving` message - "
                          "please turn `Share` on in OwnTracks app")
            return
        # OwnTracks uses - at the start of a beacon zone
        # to switch on 'hold mode' - ignore this
        location = slugify(data['desc'].lstrip("-"))
        if location.lower() == 'home':
            location = STATE_HOME

        dev_id, kwargs = _parse_see_args(topic, data)

        def enter_event():
            """Execute enter event."""
            zone = hass.states.get("zone.{}".format(location))
            with LOCK:
                if zone is None and data.get('t') == 'b':
                    # Not a HA zone, and a beacon so assume mobile
                    beacons = MOBILE_BEACONS_ACTIVE[dev_id]
                    if location not in beacons:
                        beacons.append(location)
                    _LOGGER.info("Added beacon %s", location)
                else:
                    # Normal region
                    regions = REGIONS_ENTERED[dev_id]
                    if location not in regions:
                        regions.append(location)
                    _LOGGER.info("Enter region %s", location)
                    _set_gps_from_zone(kwargs, location, zone)

                see(**kwargs)
                see_beacons(dev_id, kwargs)

        def leave_event():
            """Execute leave event."""
            with LOCK:
                regions = REGIONS_ENTERED[dev_id]
                if location in regions:
                    regions.remove(location)
                new_region = regions[-1] if regions else None

                if new_region:
                    # Exit to previous region
                    zone = hass.states.get("zone.{}".format(new_region))
                    _set_gps_from_zone(kwargs, new_region, zone)
                    _LOGGER.info("Exit to %s", new_region)
                    see(**kwargs)
                    see_beacons(dev_id, kwargs)

                else:
                    _LOGGER.info("Exit to GPS")
                    # Check for GPS accuracy
                    if not ('acc' in data and max_gps_accuracy is not None
                            and data['acc'] > max_gps_accuracy):

                        see(**kwargs)
                        see_beacons(dev_id, kwargs)
                    else:
                        _LOGGER.info("Inaccurate GPS reported")

                beacons = MOBILE_BEACONS_ACTIVE[dev_id]
                if location in beacons:
                    beacons.remove(location)
                    _LOGGER.info("Remove beacon %s", location)

        if data['event'] == 'enter':
            enter_event()
        elif data['event'] == 'leave':
            leave_event()
        else:
            _LOGGER.error('Misformatted mqtt msgs, _type=transition, event=%s',
                          data['event'])
            return
Esempio n. 28
0
 def test_slugify(self):
     """Test slugify."""
     self.assertEqual("test", util.slugify("T-!@#$!#@$!$est"))
     self.assertEqual("test_more", util.slugify("Test More"))
     self.assertEqual("test_more", util.slugify("Test_(More)"))
Esempio n. 29
0
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
    """Setup the RFXtrx platform."""
    # pylint: disable=too-many-locals
    from RFXtrx import SensorEvent
    sensors = []
    for packet_id, entity_info in config['devices'].items():
        event = rfxtrx.get_rfx_object(packet_id)
        device_id = "sensor_" + slugify(event.device.id_string.lower())
        if device_id in rfxtrx.RFX_DEVICES:
            continue
        _LOGGER.info("Add %s rfxtrx.sensor", entity_info[ATTR_NAME])

        sub_sensors = {}
        data_types = entity_info[ATTR_DATA_TYPE]
        if len(data_types) == 0:
            for data_type in DATA_TYPES:
                if data_type in event.values:
                    data_types = [data_type]
                    break
        for _data_type in data_types:
            new_sensor = RfxtrxSensor(event, entity_info[ATTR_NAME],
                                      _data_type)
            sensors.append(new_sensor)
            sub_sensors[_data_type] = new_sensor
        rfxtrx.RFX_DEVICES[device_id] = sub_sensors

    add_devices_callback(sensors)

    def sensor_update(event):
        """Callback for sensor updates from the RFXtrx gateway."""
        if not isinstance(event, SensorEvent):
            return

        device_id = "sensor_" + slugify(event.device.id_string.lower())

        if device_id in rfxtrx.RFX_DEVICES:
            sensors = rfxtrx.RFX_DEVICES[device_id]
            for key in sensors:
                sensors[key].event = event
            return

        # Add entity if not exist and the automatic_add is True
        if not config[ATTR_AUTOMATIC_ADD]:
            return

        pkt_id = "".join("{0:02x}".format(x) for x in event.data)
        _LOGGER.info("Automatic add rfxtrx.sensor: %s", device_id)

        data_type = "Unknown"
        for _data_type in DATA_TYPES:
            if _data_type in event.values:
                data_type = _data_type
                break
        new_sensor = RfxtrxSensor(event, pkt_id, data_type)
        sub_sensors = {}
        sub_sensors[new_sensor.data_type] = new_sensor
        rfxtrx.RFX_DEVICES[device_id] = sub_sensors
        add_devices_callback([new_sensor])

    if sensor_update not in rfxtrx.RECEIVED_EVT_SUBSCRIBERS:
        rfxtrx.RECEIVED_EVT_SUBSCRIBERS.append(sensor_update)
Esempio n. 30
0
    def owntracks_event_update(topic, payload, qos):
        """MQTT event (geofences) received."""
        # Docs on available data:
        # http://owntracks.org/booklet/tech/json/#_typetransition
        data = validate_payload(payload, 'transition')
        if not data:
            return

        if data.get('desc') is None:
            _LOGGER.error(
                "Location missing from `Entering/Leaving` message - "
                "please turn `Share` on in OwnTracks app")
            return
        # OwnTracks uses - at the start of a beacon zone
        # to switch on 'hold mode' - ignore this
        location = slugify(data['desc'].lstrip("-"))
        if location.lower() == 'home':
            location = STATE_HOME

        dev_id, kwargs = _parse_see_args(topic, data)

        def enter_event():
            """Execute enter event."""
            zone = hass.states.get("zone.{}".format(location))
            with LOCK:
                if zone is None and data.get('t') == 'b':
                    # Not a HA zone, and a beacon so assume mobile
                    beacons = MOBILE_BEACONS_ACTIVE[dev_id]
                    if location not in beacons:
                        beacons.append(location)
                    _LOGGER.info("Added beacon %s", location)
                else:
                    # Normal region
                    regions = REGIONS_ENTERED[dev_id]
                    if location not in regions:
                        regions.append(location)
                    _LOGGER.info("Enter region %s", location)
                    _set_gps_from_zone(kwargs, location, zone)

                see(**kwargs)
                see_beacons(dev_id, kwargs)

        def leave_event():
            """Execute leave event."""
            with LOCK:
                regions = REGIONS_ENTERED[dev_id]
                if location in regions:
                    regions.remove(location)
                new_region = regions[-1] if regions else None

                if new_region:
                    # Exit to previous region
                    zone = hass.states.get("zone.{}".format(new_region))
                    _set_gps_from_zone(kwargs, new_region, zone)
                    _LOGGER.info("Exit to %s", new_region)
                    see(**kwargs)
                    see_beacons(dev_id, kwargs)

                else:
                    _LOGGER.info("Exit to GPS")
                    # Check for GPS accuracy
                    if not ('acc' in data and
                            max_gps_accuracy is not None and
                            data['acc'] > max_gps_accuracy):

                        see(**kwargs)
                        see_beacons(dev_id, kwargs)
                    else:
                        _LOGGER.info("Inaccurate GPS reported")

                beacons = MOBILE_BEACONS_ACTIVE[dev_id]
                if location in beacons:
                    beacons.remove(location)
                    _LOGGER.info("Remove beacon %s", location)

        if data['event'] == 'enter':
            enter_event()
        elif data['event'] == 'leave':
            leave_event()
        else:
            _LOGGER.error(
                'Misformatted mqtt msgs, _type=transition, event=%s',
                data['event'])
            return
Esempio n. 31
0
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
    """Setup the RFXtrx platform."""
    # pylint: disable=too-many-locals
    from RFXtrx import SensorEvent
    sensors = []
    for packet_id, entity_info in config['devices'].items():
        event = rfxtrx.get_rfx_object(packet_id)
        device_id = "sensor_" + slugify(event.device.id_string.lower())
        if device_id in rfxtrx.RFX_DEVICES:
            continue
        _LOGGER.info("Add %s rfxtrx.sensor", entity_info[ATTR_NAME])

        sub_sensors = {}
        data_types = entity_info[ATTR_DATA_TYPE]
        if len(data_types) == 0:
            for data_type in DATA_TYPES:
                if data_type in event.values:
                    data_types = [data_type]
                    break
        for _data_type in data_types:
            new_sensor = RfxtrxSensor(event, entity_info[ATTR_NAME],
                                      _data_type)
            sensors.append(new_sensor)
            sub_sensors[_data_type] = new_sensor
        rfxtrx.RFX_DEVICES[device_id] = sub_sensors

    add_devices_callback(sensors)

    def sensor_update(event):
        """Callback for sensor updates from the RFXtrx gateway."""
        if not isinstance(event, SensorEvent):
            return

        device_id = "sensor_" + slugify(event.device.id_string.lower())

        if device_id in rfxtrx.RFX_DEVICES:
            sensors = rfxtrx.RFX_DEVICES[device_id]
            for key in sensors:
                sensors[key].event = event
            return

        # Add entity if not exist and the automatic_add is True
        if not config[ATTR_AUTOMATIC_ADD]:
            return

        pkt_id = "".join("{0:02x}".format(x) for x in event.data)
        _LOGGER.info("Automatic add rfxtrx.sensor: %s",
                     device_id)

        data_type = "Unknown"
        for _data_type in DATA_TYPES:
            if _data_type in event.values:
                data_type = _data_type
                break
        new_sensor = RfxtrxSensor(event, pkt_id, data_type)
        sub_sensors = {}
        sub_sensors[new_sensor.data_type] = new_sensor
        rfxtrx.RFX_DEVICES[device_id] = sub_sensors
        add_devices_callback([new_sensor])

    if sensor_update not in rfxtrx.RECEIVED_EVT_SUBSCRIBERS:
        rfxtrx.RECEIVED_EVT_SUBSCRIBERS.append(sensor_update)
Esempio n. 32
0
 def test_slugify(self):
     """Test slugify."""
     self.assertEqual("test", util.slugify("T-!@#$!#@$!$est"))
     self.assertEqual("test_more", util.slugify("Test More"))
     self.assertEqual("test_more", util.slugify("Test_(More)"))