Exemple #1
0
 def __init__(self):
     self._light_dict = {}
     self._group_dict = {}
     self._location_dict = {}
     self._light_names = SortedList()
     self._num_successful_discovers = 0
     self._num_failed_discovers = 0
Exemple #2
0
 def _update_memberships(light, current_set_name, set_dict):
     LightSet._remove_memberships(light, set_dict)
     if current_set_name not in set_dict:
         set_dict[current_set_name] = SortedList(light.name)
     else:
         set_dict[current_set_name].add(light.name)
Exemple #3
0
class LightSet(i_controller.LightSet):
    """
    The lights are stored in _light_dict, keyed on light name. Locations and
    groups are stored in _location_dict and _group_dict as lists of strings
    containing light names.
    """
    the_instance = None

    def __init__(self):
        self._light_dict = {}
        self._group_dict = {}
        self._location_dict = {}
        self._light_names = SortedList()
        self._num_successful_discovers = 0
        self._num_failed_discovers = 0

    @staticmethod
    def configure():
        LightSet.the_instance = LightSet()

    @staticmethod
    def get_instance():
        return LightSet.the_instance

    @inject(Lifx)
    def discover(self, lifx):
        logging.debug(
            'start discover. so far, successes = {}, fails = {}'.format(
                self._num_successful_discovers, self._num_failed_discovers))
        try:
            for lifx_light in lifx.get_lights():
                light = Light(lifx_light)
                self._light_dict[light.name] = light
                self._light_names.add(light.name)
                LightSet._update_memberships(light, light.group,
                                             self._group_dict)
                LightSet._update_memberships(light, light.location,
                                             self._location_dict)
        except lifxlan.errors.WorkflowException as ex:
            self._num_failed_discovers += 1
            logging.warning("In discover():\n{}".format(ex))
            return False

        self._num_successful_discovers += 1
        return True

    def refresh(self):
        self.discover()
        self._garbage_collect()

    @staticmethod
    def _update_memberships(light, current_set_name, set_dict):
        LightSet._remove_memberships(light, set_dict)
        if current_set_name not in set_dict:
            set_dict[current_set_name] = SortedList(light.name)
        else:
            set_dict[current_set_name].add(light.name)

    @staticmethod
    def _remove_memberships(light, set_dict):
        # Remove the light from every set in set_dict that it belongs to.
        target_set_names = []
        for list_name in set_dict.keys():
            the_list = set_dict[list_name]
            the_list.remove(light.name)
            if len(the_list) == 0:
                target_set_names.append(list_name)
        for set_name in target_set_names:
            del set_dict[set_name]

    @inject(Settings)
    def _garbage_collect(self, settings):
        # Get rid of a light's proxy if it hasn't responded for a while.
        logging.debug("garbage collect, currently have {} lights".format(
            len(self._light_dict)))
        max_age = int(settings.get_value('light_gc_time', 20 * 60))
        target_lights = []
        for light in self._light_dict.values():
            if light.get_age() > max_age:
                LightSet._remove_memberships(light, self._group_dict)
                LightSet._remove_memberships(light, self._location_dict)
                target_lights.append(light.name)
        for light_name in target_lights:
            logging.debug("_garbage_collect() deleting {}".format(light_name))
            self._light_names.remove(light_name)
            self._light_dict[light_name] = None
            del self._light_dict[light_name]

    @property
    def light_names(self) -> SortedList:
        """ list of strings """
        return self._light_names

    @property
    def group_names(self):
        """ list of strings """
        return SortedList(self._group_dict.keys())

    @property
    def location_names(self):
        """ list of strings """
        return SortedList(self._location_dict.keys())

    @property
    def count(self):
        return len(self._light_list)

    @property
    def successful_discovers(self):
        return self._num_successful_discovers

    @property
    def failed_discovers(self):
        return self._num_failed_discovers

    def get_light(self, name):
        """ returns an instance of i_lib.Light, or None if it's not there """
        return self._light_dict.get(name)

    def get_group(self, name):
        """ list of light names """
        return self._group_dict.get(name)

    def get_location(self, name):
        """ list of light names. """
        return self._location_dict.get(name)

    @inject(Lifx)
    def set_color(self, color, duration, lifx):
        lifx.set_color_all_lights(rounded_color(color), duration)
        return True

    @inject(Lifx)
    def set_power(self, power_level, duration, lifx):
        lifx.set_power_all_lights(round(power_level), duration)
        return True
Exemple #4
0
 def location_names(self):
     """ list of strings """
     return SortedList(self._location_dict.keys())
Exemple #5
0
 def group_names(self):
     """ list of strings """
     return SortedList(self._group_dict.keys())
Exemple #6
0
 def setUp(self):
     self._list = SortedList()
     for value in ('b', 'c', 'a', 'c', 'd'):
         self._list.add(value)
Exemple #7
0
class SortedListTest(unittest.TestCase):
    def setUp(self):
        self._list = SortedList()
        for value in ('b', 'c', 'a', 'c', 'd'):
            self._list.add(value)

    def test_forward(self):
        self.assertEqual(self._list.first(), 'a')
        self.assertEqual(self._list.next('b'), 'c')
        self.assertIsNone(self._list.next('d'))

        self._list.remove('d')
        self.assertIsNone(self._list.next('d'))
        self.assertIsNone(self._list.next('c'))

        self._list.remove('b')
        self.assertEqual(self._list.next('b'), 'c')

    def test_reverse(self):
        self.assertEqual(self._list.last(), 'd')
        self.assertEqual(self._list.prev('d'), 'c')
        self.assertIsNone(self._list.prev('a'))

        self._list.remove('a')
        self.assertIsNone(self._list.prev('a'))
        self.assertIsNone(self._list.prev('b'))

        self._list.remove('d')
        self.assertEqual(self._list.prev('d'), 'c')

    def test_empty(self):
        for value in ('c', 'b', 'a', 'd'):
            self._list.remove(value)
        self.assertIsNone(self._list.first())
        self.assertIsNone(self._list.last())
        self._list.add('e')
        self.assertEqual(self._list.first(), 'e')
        self.assertEqual(self._list.last(), 'e')