Exemple #1
0
    def update_sun_state(now):    # pylint: disable=unused-argument
        """ Method to update the current state of the sun and
            set time of next setting and rising. """
        observer = ephem.Observer()
        observer.lat = latitude
        observer.long = longitude

        next_rising_dt = ephem.localtime(observer.next_rising(sun))
        next_setting_dt = ephem.localtime(observer.next_setting(sun))

        if next_rising_dt > next_setting_dt:
            new_state = STATE_ABOVE_HORIZON
            next_change = next_setting_dt

        else:
            new_state = STATE_BELOW_HORIZON
            next_change = next_rising_dt

        logger.info(
            "Sun:{}. Next change: {}".format(new_state,
                                             next_change.strftime("%H:%M")))

        state_attributes = {
            STATE_ATTR_NEXT_RISING: ha.datetime_to_str(next_rising_dt),
            STATE_ATTR_NEXT_SETTING: ha.datetime_to_str(next_setting_dt)
        }

        statemachine.set_state(STATE_CATEGORY, new_state, state_attributes)

        # +10 seconds to be sure that the change has occured
        ha.track_time_change(bus, update_sun_state,
                             point_in_time=next_change + timedelta(seconds=10))
Exemple #2
0
    def __init__(self, bus, statemachine, device_scanner):
        self.statemachine = statemachine
        self.bus = bus
        self.device_scanner = device_scanner
        self.logger = logging.getLogger(__name__)

        self.lock = threading.Lock()

        # Dictionary to keep track of known devices and devices we track
        self.known_devices = {}

        # Did we encounter a valid known devices file
        self.invalid_known_devices_file = False

        self._read_known_devices_file()

        ha.track_time_change(bus,
                             lambda time:
                             self.update_devices(
                                 device_scanner.scan_devices()))

        bus.register_service(DOMAIN_DEVICE_TRACKER,
                             SERVICE_DEVICE_TRACKER_RELOAD,
                             lambda service: self._read_known_devices_file())

        self.update_devices(device_scanner.scan_devices())
    def handle_sun_rising(category, old_state, new_state):
        """The moment sun sets we want to have all the lights on.
           We will schedule to have each light start after one another
           and slowly transition in."""

        def turn_light_on_before_sunset(light_id):
            """ Helper function to turn on lights slowly if there
                are devices home and the light is not on yet. """
            if (device.is_home(statemachine) and
               not light.is_on(statemachine, light_id)):

                light.turn_on(bus, light_id, LIGHT_TRANSITION_TIME.seconds)

        def turn_on(light_id):
            """ Lambda can keep track of function parameters but not local
            parameters. If we put the lambda directly in the below statement
            only the last light will be turned on.. """
            return lambda now: turn_light_on_before_sunset(light_id)

        start_point = time_for_light_before_sun_set()

        for index, light_id in enumerate(light_ids):
            ha.track_time_change(bus, turn_on(light_id),
                                 point_in_time=(start_point +
                                                index * LIGHT_TRANSITION_TIME))
Exemple #4
0
def setup(bus, statemachine, light_control):
    """ Exposes light control via statemachine and services. """

    def update_light_state(time):  # pylint: disable=unused-argument
        """ Track the state of the lights. """
        try:
            should_update = datetime.now() - update_light_state.last_updated \
                > MIN_TIME_BETWEEN_SCANS

        except AttributeError:  # if last_updated does not exist
            should_update = True

        if should_update:
            update_light_state.last_updated = datetime.now()

            status = {light_id: light_control.is_light_on(light_id)
                      for light_id in light_control.light_ids}

            for light_id, state in status.items():
                state_category = STATE_CATEGORY_FORMAT.format(light_id)

                statemachine.set_state(state_category,
                                       STATE_ON if state
                                       else STATE_OFF)

            statemachine.set_state(STATE_CATEGORY_ALL_LIGHTS,
                                   STATE_ON if True in status.values()
                                   else STATE_OFF)

    ha.track_time_change(bus, update_light_state, second=[0, 30])

    def handle_light_event(service):
        """ Hande a turn light on or off service call. """
        light_id = service.data.get("light_id", None)
        transition_seconds = service.data.get("transition_seconds", None)

        if service.service == ha.SERVICE_TURN_ON:
            light_control.turn_light_on(light_id, transition_seconds)
        else:
            light_control.turn_light_off(light_id, transition_seconds)

        update_light_state(None)

    # Listen for light on and light off events
    bus.register_service(DOMAIN, ha.SERVICE_TURN_ON,
                         handle_light_event)

    bus.register_service(DOMAIN, ha.SERVICE_TURN_OFF,
                         handle_light_event)

    update_light_state(None)

    return True
def setup(bus, statemachine, host):
    """ Listen for chromecast events. """
    device = pychromecast.get_device_status(host)

    if not device:
        return False

    category = STATE_CATEGORY_FORMAT.format(util.slugify(
        device.friendly_name))

    bus.register_service(DOMAIN_CHROMECAST, ha.SERVICE_TURN_OFF,
                         lambda service:
                         turn_off(statemachine,
                                  service.data.get("cc_id", None)))

    bus.register_service(DOMAIN_CHROMECAST, "start_fireplace",
                         lambda service:
                         pychromecast.play_youtube_video(host, "eyU3bRy2x44"))

    bus.register_service(DOMAIN_CHROMECAST, "start_epic_sax",
                         lambda service:
                         pychromecast.play_youtube_video(host, "kxopViU98Xo"))

    bus.register_service(DOMAIN_CHROMECAST, SERVICE_YOUTUBE_VIDEO,
                         lambda service:
                         pychromecast.play_youtube_video(
                             host, service.data['video']))

    def update_chromecast_state(time):  # pylint: disable=unused-argument
        """ Retrieve state of Chromecast and update statemachine. """
        status = pychromecast.get_app_status(host)

        if status:
            statemachine.set_state(category, status.name,
                                   {ATTR_FRIENDLY_NAME:
                                       pychromecast.get_friendly_name(
                                           status.name),
                                    ATTR_HOST: host,
                                    ATTR_STATE: status.state,
                                    ATTR_OPTIONS: status.options})
        else:
            statemachine.set_state(category, STATE_NO_APP)

    ha.track_time_change(bus, update_chromecast_state)

    update_chromecast_state(None)

    return True
Exemple #6
0
    def _handle_sun_rising(self, category, old_state, new_state):
        """The moment sun sets we want to have all the lights on.
           We will schedule to have each light start after one another
           and slowly transition in."""

        start_point = self._time_for_light_before_sun_set()

        def turn_on(light):
            """ Lambda can keep track of function parameters but not local
            parameters. If we put the lambda directly in the below statement
            only the last light would be turned on.. """
            return lambda now: self._turn_light_on_before_sunset(light)

        for index, light_id in enumerate(self.light_control.light_ids):
            ha.track_time_change(self.eventbus, turn_on(light_id),
                                 point_in_time=(start_point +
                                                index * LIGHT_TRANSITION_TIME))
    def __init__(self, eventbus, statemachine, device_scanner):
        self.statemachine = statemachine
        self.eventbus = eventbus
        self.device_scanner = device_scanner
        self.logger = logging.getLogger(__name__)

        self.lock = threading.Lock()

        # Dictionary to keep track of known devices and devices we track
        self.known_devices = {}

        # Did we encounter a valid known devices file
        self.invalid_known_devices_file = False

        # Read known devices if file exists
        if os.path.isfile(KNOWN_DEVICES_FILE):
            with open(KNOWN_DEVICES_FILE) as inp:
                default_last_seen = datetime(1990, 1, 1)

                # Temp variable to keep track of which categories we use
                # so we can ensure we have unique categories.
                used_categories = []

                try:
                    for row in csv.DictReader(inp):
                        device = row['device']

                        row['track'] = True if row['track'] == '1' else False

                        # If we track this device setup tracking variables
                        if row['track']:
                            row['last_seen'] = default_last_seen

                            # Make sure that each device is mapped
                            # to a unique category name
                            name = row['name']

                            if not name:
                                name = "unnamed_device"

                            tries = 0
                            suffix = ""
                            while True:
                                tries += 1

                                if tries > 1:
                                    suffix = "_{}".format(tries)

                                category = STATE_CATEGORY_DEVICE_FORMAT.format(
                                    name + suffix)

                                if category not in used_categories:
                                    break

                            row['category'] = category
                            used_categories.append(category)

                        self.known_devices[device] = row

                except KeyError:
                    self.invalid_known_devices_file = False
                    self.logger.warning((
                        "Invalid {} found. "
                        "We won't update it with new found devices.").
                        format(KNOWN_DEVICES_FILE))

        if len(self.device_state_categories) == 0:
            self.logger.warning(
                "No devices to track. Please update {}.".format(
                    KNOWN_DEVICES_FILE))

        ha.track_time_change(eventbus,
                             lambda time:
                             self.update_devices(
                                 device_scanner.scan_devices()))