예제 #1
0
    def _shuffle_group(self, group_id):
        lights = utils.get_lights()
        lids = utils.get_group_lids(group_id)

        # Only shuffle the lights that are on
        on_lids = [lid for lid in lids if lights[lid]['state']['on']]
        on_xy = [lights[lid]['state']['xy'] for lid in on_lids]
        shuffled = list(on_xy)

        # Shuffle until all indexes are different (generate a derangement)
        while not all([on_xy[i] != shuffled[i] for i in range(len(on_xy))]):
            random.shuffle(shuffled)

        self._set_palette(on_lids, shuffled)
예제 #2
0
    def _shuffle_group(self, group_id):
        lights = utils.get_lights()
        lids = utils.get_group_lids(group_id)

        # Only shuffle the lights that are on
        on_lids = [lid for lid in lids if lights[lid]['state']['on']]
        on_xy = [lights[lid]['state']['xy'] for lid in on_lids]
        shuffled = list(on_xy)

        # Shuffle until all indexes are different (generate a derangement)
        while not all([on_xy[i] != shuffled[i] for i in range(len(on_xy))]):
            random.shuffle(shuffled)

        self._set_palette(on_lids, shuffled)
예제 #3
0
    def _set_harmony(self, group_id, mode, root):
        lights = utils.get_lights()
        lids = utils.get_group_lids(group_id)
        palette = []

        on_lids = [lid for lid in lids if lights[lid]['state']['on']]
        args = (len(on_lids), '#%s' % utils.get_color_value(root))
        harmony_colors = getattr(harmony, mode)(*args)

        for lid in on_lids:
            gamut = colors.get_light_gamut(lights[lid]['modelid'])
            xy = self._get_xy_color(harmony_colors.pop(), gamut)
            palette.append(xy)

        self._set_palette(on_lids, palette)
예제 #4
0
    def _set_harmony(self, group_id, mode, root):
        lights = utils.get_lights()
        lids = utils.get_group_lids(group_id)
        palette = []

        on_lids = [lid for lid in lids if lights[lid]['state']['on']]
        args = (len(on_lids), '#%s' % utils.get_color_value(root))
        harmony_colors = getattr(harmony, mode)(*args)

        for lid in on_lids:
            gamut = colors.get_light_gamut(lights[lid]['modelid'])
            xy = self._get_xy_color(harmony_colors.pop(), gamut)
            palette.append(xy)

        self._set_palette(on_lids, palette)
예제 #5
0
    def get_items(self):
        query = self._get_active_query()

        if ((query.startswith('lights') or query.startswith('groups')) and len(query.split(':')) >= 3):
            action_filter = HueActionFilter(self.workflow)
            control = query.split(':')
            lights = utils.get_lights(from_cache=True)
            groups = utils.get_groups()
            rid = control[1]

            self.items = action_filter.get_items(
                query=':'.join(control[2:]),  # lights:1:<light_query>
                id=rid,
                type=HueActionFilter.LIGHT_TYPE if query.startswith('lights') else HueActionFilter.GROUP_TYPE,
                resource=lights.get(rid, None) if query.startswith('lights') else groups.get(rid, None))

        else:  # Show index
            if not self.workflow.settings.get('username'):
                self._add_item(
                    'bridge_failed',
                    valid=True,
                    title='Link with Hue bridge',
                    arg='set_bridge:%s' % query)

            else:
                lights = utils.get_lights()
                groups = utils.get_groups()

                if not lights:
                    self._add_item(
                        'bridge_failed',
                        valid=True,
                        arg='set_bridge:%s' % query)

                else:
                    self._add_item('all_lights')

                    for rid, room in groups.items():
                        self._add_item(
                            title=room['name'],
                            autocomplete='groups:%s:' % rid)

                    if query.startswith('lights:') or query.startswith('groups:'):
                        self.partial_query = query.split(':')[1]

                    for lid, light in lights.items():
                        title = light['name']

                        if light['state']['on']:
                            subtitle = []
                            if light['state'].get('hue'):
                                subtitle.append('hue: {hue}'.format(
                                    hue='{0:.0f}°'.format(float(light['state']['hue']) / 65535 * 360)))
                            if light['state'].get('bri') is not None:
                                subtitle.append('bri: {bri}'.format(
                                    bri='{0:.0f}%'.format(float(light['state']['bri']) / 255 * 100)))
                            if light['state'].get('sat') is not None:
                                subtitle.append('sat: {sat}'.format(
                                    sat='{0:.0f}%'.format(float(light['state']['sat']) / 255 * 100)))
                            subtitle = ', '.join(subtitle) or 'on'
                            icon = '%s.png' % lid
                        else:
                            subtitle = 'off'
                            icon = 'off.png'

                        if not light['state'].get('reachable'):
                            title += ' **'
                            subtitle += ' — may not be reachable'

                        self._add_item(
                            title=title,
                            subtitle='({lid}) {subtitle}'.format(
                                lid=lid,
                                subtitle=subtitle,
                            ),
                            icon=icon,
                            autocomplete='lights:%s:' % lid)

                    # self._add_item('help')

        self._filter_items()
        return self.items
예제 #6
0
    def execute(self, action):
        is_light = action[0] == 'lights'
        is_group = action[0] == 'groups'

        if not is_light and not is_group:
            return

        rid = action[1]
        function = action[2]
        value = action[3] if len(action) > 3 else None
        lights = utils.get_lights()
        groups = utils.get_groups()

        # Default API request parameters
        method = 'put'
        endpoint = '/groups/%s/action' % rid if is_group else '/lights/%s/state' % rid

        if function == 'off':
            data = {'on': False}

        elif function == 'on':
            data = {'on': True}

        elif function == 'bri':
            value = int((float(value) / 100) * 255) if value else 255
            data = {'bri': value}

        elif function == 'shuffle':
            if not is_group:
                print('Shuffle can only be called on groups.'.encode('utf-8'))
                return

            self._shuffle_group(rid)
            return True

        elif function == 'rename':
            endpoint = '/lights/%s' % rid
            data = {'name': value}

        elif function == 'effect':
            data = {'effect': value}

        elif function == 'color':
            if value == 'random':
                if is_group:
                    gamut = colors.GamutA
                    data = {'xy': self._get_random_xy_color(gamut)}
                else:
                    gamut = colors.get_light_gamut(lights[rid]['modelid'])
                    data = {'xy': self._get_random_xy_color(gamut)}
            else:
                try:
                    if is_group:
                        gamut = colors.GamutA
                    else:
                        gamut = colors.get_light_gamut(lights[rid]['modelid'])
                    data = {'xy': self._get_xy_color(value, gamut)}
                except ValueError:
                    print(
                        'Error: Invalid color. Please use a 6-digit hex color.'
                        .encode('utf-8'))
                    return

        elif function == 'harmony':
            if not is_group:
                print('Color harmonies can only be set on groups.'.encode(
                    'utf-8'))
                return

            root = action[4] if len(action) > 3 else None

            if value not in harmony.MODES:
                print('Invalid harmony mode.'.encode('utf-8'))
                return

            self._set_harmony(rid, value, root)
            return

        elif function == 'reminder':
            try:
                time_delta_int = int(value)
            except ValueError:
                print(
                    'Error: Invalid time delta for reminder.'.encode('utf-8'))
                return

            reminder_time = datetime.datetime.utcfromtimestamp(time.time() +
                                                               time_delta_int)

            method = 'post'
            data = {
                'name': 'Alfred Hue Reminder',
                'command': {
                    'address': self.hue_request.api_path + endpoint,
                    'method': 'PUT',
                    'body': {
                        'alert': 'lselect'
                    },
                },
                'time': reminder_time.replace(microsecond=0).isoformat(),
            }
            endpoint = '/schedules'

        elif function == 'set':
            data = {'scene': value}

        elif function == 'save':
            lids = utils.get_group_lids(rid)
            method = 'post'
            endpoint = '/scenes'
            data = {'name': value, 'lights': lids, 'recycle': False}

        else:
            return

        # Make the request
        self.hue_request.request(method, endpoint, json.dumps(data))

        return
예제 #7
0
    def execute(self, action):
        is_light = action[0] == 'lights'
        is_group = action[0] == 'groups'

        if not is_light and not is_group:
            return

        rid = action[1]
        function = action[2]
        value = action[3] if len(action) > 3 else None
        lights = utils.get_lights()
        groups = utils.get_groups()

        # Default API request parameters
        method = 'put'
        endpoint = '/groups/%s/action' % rid if is_group else '/lights/%s/state' % rid

        if function == 'off':
            data = {'on': False}

        elif function == 'on':
            data = {'on': True}

        elif function == 'bri':
            value = int((float(value) / 100) * 255) if value else 255
            data = {'bri': value}

        elif function == 'shuffle':
            if not is_group:
                print('Shuffle can only be called on groups.'.encode('utf-8'))
                return

            self._shuffle_group(rid)
            return True

        elif function == 'rename':
            endpoint = '/lights/%s' % rid
            data = {'name': value}

        elif function == 'effect':
            data = {'effect': value}

        elif function == 'color':
            if value == 'random':
                if is_group:
                    gamut = colors.GamutA
                    data = {'xy': self._get_random_xy_color(gamut)}
                else:
                    gamut = colors.get_light_gamut(lights[rid]['modelid'])
                    data = {'xy': self._get_random_xy_color(gamut)}
            else:
                try:
                    if is_group:
                        gamut = colors.GamutA
                    else:
                        gamut = colors.get_light_gamut(lights[rid]['modelid'])
                    data = {'xy': self._get_xy_color(value, gamut)}
                except ValueError:
                    print('Error: Invalid color. Please use a 6-digit hex color.'.encode('utf-8'))
                    return

        elif function == 'harmony':
            if not is_group:
                print('Color harmonies can only be set on groups.'.encode('utf-8'))
                return

            root = action[4] if len(action) > 3 else None

            if value not in harmony.MODES:
                print('Invalid harmony mode.'.encode('utf-8'))
                return

            self._set_harmony(rid, value, root)
            return

        elif function == 'reminder':
            try:
                time_delta_int = int(value)
            except ValueError:
                print('Error: Invalid time delta for reminder.'.encode('utf-8'))
                return

            reminder_time = datetime.datetime.utcfromtimestamp(time.time() + time_delta_int)

            method = 'post'
            data = {
                'name': 'Alfred Hue Reminder',
                'command': {
                    'address': self.hue_request.api_path + endpoint,
                    'method': 'PUT',
                    'body': {'alert': 'lselect'},
                },
                'time': reminder_time.replace(microsecond=0).isoformat(),
            }
            endpoint = '/schedules'

        elif function == 'set':
            data = {'scene': value}

        elif function == 'save':
            lids = utils.get_group_lids(rid)
            method = 'post'
            endpoint = '/scenes'
            data = {'name': value, 'lights': lids, 'recycle': False}

        else:
            return

        # Make the request
        self.hue_request.request(method, endpoint, json.dumps(data))

        return
예제 #8
0
    def get_items(self):
        query = self._get_active_query()

        if ((query.startswith('lights') or query.startswith('groups')) and len(query.split(':')) >= 3):
            action_filter = HueActionFilter(self.workflow)
            control = query.split(':')
            lights = utils.get_lights(from_cache=True)
            groups = utils.get_groups()
            rid = control[1]

            self.items = action_filter.get_items(
                query=':'.join(control[2:]),  # lights:1:<light_query>
                id=rid,
                type=HueActionFilter.LIGHT_TYPE if query.startswith('lights') else HueActionFilter.GROUP_TYPE,
                resource=lights.get(rid, None) if query.startswith('lights') else groups.get(rid, None))

        else:  # Show index
            if not self.workflow.settings.get('username'):
                self._add_item(
                    'bridge_failed',
                    valid=True,
                    title='Link with Hue bridge',
                    arg='set_bridge:%s' % query)

            else:
                lights = utils.get_lights()
                groups = utils.get_groups()

                if not lights:
                    self._add_item(
                        'bridge_failed',
                        valid=True,
                        arg='set_bridge:%s' % query)

                else:
                    self._add_item('all_lights')

                    for rid, room in groups.items():
                        self._add_item(
                            title=room['name'],
                            autocomplete='groups:%s:' % rid)

                    if query.startswith('lights:') or query.startswith('groups:'):
                        self.partial_query = query.split(':')[1]

                    for lid, light in lights.items():
                        title = light['name']

                        if light['state']['on']:
                            subtitle = []
                            if light['state'].get('hue'):
                                subtitle.append('hue: {hue}'.format(
                                    hue='{0:.0f}°'.format(float(light['state']['hue']) / 65535 * 360)))
                            if light['state'].get('bri') is not None:
                                subtitle.append('bri: {bri}'.format(
                                    bri='{0:.0f}%'.format(float(light['state']['bri']) / 255 * 100)))
                            if light['state'].get('sat') is not None:
                                subtitle.append('sat: {sat}'.format(
                                    sat='{0:.0f}%'.format(float(light['state']['sat']) / 255 * 100)))
                            subtitle = ', '.join(subtitle) or 'on'
                            icon = '%s.png' % lid
                        else:
                            subtitle = 'off'
                            icon = 'off.png'

                        if not light['state'].get('reachable'):
                            title += ' **'
                            subtitle += ' — may not be reachable'

                        self._add_item(
                            title=title,
                            subtitle='({lid}) {subtitle}'.format(
                                lid=lid,
                                subtitle=subtitle,
                            ),
                            icon=icon,
                            autocomplete='lights:%s:' % lid)

                    # self._add_item('help')

        self._filter_items()
        return self.items