예제 #1
0
    def initGameCallBack(self):

        if isinstance(self.interFrame, Frame):
            self.interFrame.destroy()
            self.timer.destroy()
            self.counter.destroy()

        if isinstance(self.gameFrame, Frame):
            self.gameFrame.destroy()

        storage = Storage()
        self.mines = storage.get("mines")
        h = storage.get("height")
        w = storage.get("width")
        self.isGameStarted = False

        self.tiles = [[j for j in range(w)] for i in range(h)]
        self.bombs = set()
        self.bombsPrediction = set()
        self.tilesAmount = w * h

        self.board = Board(w, h, self.mines)

        self.root.bind_class('Label', '<Button-1>', self.openTileEvent)
        self.root.bind_class('Label', '<Button-2>', self.flagTileEvent)
        self.root.bind('<KeyPress>', self.keyboardEvent)

        self.code = ""
        self.__createFrame()
        self.__initInterface()
예제 #2
0
 def test_get_ttl(self):
     """
     Test Storage.get with ttl.
     :return:
     """
     self.now = time.time()
     with patch('time.time', self.fake_time):
         storage = Storage()
         keys_to_set = {
             '1': 'hello',
             '2': 'bye',
             '3': [1, 2, 'three'],
             '4': {
                 1: 'one',
                 2: 'two'
             }
         }
         moes = {'1': time.time() + 5, '4': time.time() + 10}
         for key in keys_to_set.keys():
             storage.set(key, keys_to_set[key], moes.get(key))
         # test at moment t
         self.assertEqual(keys_to_set['1'], storage.get('1'),
                          "Key '1' should still exist.")
         # test at moment t+6, one key should expire
         self.now += 6
         keys_to_set.pop('1')
         moes.pop('1')
         self.assertRaises(StorageKeyError, storage.get, '1')
         self.assertEqual(keys_to_set['4'], storage.get('4'),
                          "Key '4' should still exist.")
         self.assertEqual(keys_to_set, storage._keys_dict,
                          "Remaining keys are wrong")
         self.assertEqual(moes, storage._moe_dict,
                          "Remaining moes are wrong")
         # test at moment t+11
         self.now += 5
         keys_to_set.pop('4')
         moes.pop('4')
         self.assertRaises(StorageKeyError, storage.get, '1')
         self.assertRaises(StorageKeyError, storage.get, '4')
         self.assertEqual(keys_to_set, storage._keys_dict,
                          "Remaining keys are wrong")
         self.assertEqual(moes, storage._moe_dict,
                          "Remaining moes are wrong")
예제 #3
0
 def test_set_with_get(self):
     """
     Test Storage.set with 'get' option
     :return:
     """
     storage = Storage()
     storage.set('1', 1)
     self.assertEqual(1, storage.set('1', 2, get=True),
                      "Should return previous value")
     self.assertEqual(2, storage.get('1'), 'Should get new value')
     self.assertEqual(None, storage.set('2', 1, get=True),
                      "Should return None as there was no key '2'")
예제 #4
0
    def test_roundtrip(self):
        work_dir = SetupTest.ensure_clean_work_dir()

        storage_path = os.path.join(work_dir, 'storage_test.yaml')
        self.assertFalse(os.path.exists(storage_path))

        p = Storage()
        p.set_file(storage_path)
        p.load()

        data1 = {"abc": 123, "456": "rr", 'list': [1, 2, 3, "str"]}
        p.set("data1", data1)
        data2 = datetime.datetime(2018,
                                  12,
                                  3,
                                  13,
                                  7,
                                  45,
                                  tzinfo=tzoffset(None, 3600))
        p.set("data2", data2)
        data3 = 123
        p.set("data3", data3)

        p.save()
        self.assertTrue(os.path.exists(storage_path))

        p = Storage()
        p.set_file(storage_path)
        p.load()

        comp1 = p.get("data1")
        self.assertEqual(comp1, data1)
        comp2 = p.get("data2")
        self.assertEqual(comp2, data2)
        comp3 = p.get("data3")
        self.assertEqual(comp3, data3)
예제 #5
0
 def test_set_moe(self):
     """
     Test Storage.set_moe method
     :return:
     """
     self.now = time.time()
     with patch('time.time', self.fake_time):
         storage = Storage()
         self.assertRaises(StorageKeyError, storage.set_moe, 1, {'moe': 2})
         storage.set(1, 'one')
         storage.set(2, 'two', 2)
         self.assertEqual(None, storage.set_moe(1, 2))
         self.assertEqual(None, storage.set_moe(2, None))
         self.now += 3
         self.assertRaises(StorageKeyError, storage.get, 1)
         self.assertEqual('two', storage.get(2))
예제 #6
0
 def update_prefixes_in_storage(storage: Storage, prefix: str) -> bool:
     """
     Add a new prefix into database
     return whether the prefix has been registered before
     """
     prefixes_msg = PrefixesInStorage()
     ret = storage.get("prefixes")
     if ret:
         prefixes_msg.ParseFromString(ret)
     for prefix_item in prefixes_msg.prefixes:
         if prefix_item.name == prefix or prefix.startswith(
                 prefix_item.name):
             return True
     new_prefix = prefixes_msg.prefixes.add()
     new_prefix.name = prefix
     storage.put("prefixes", prefixes_msg.SerializeToString())
     logging.info("add a new prefix into the database")
     return False
예제 #7
0
    def test_get(self):
        """
        Test Storage.get basic functionality (without ttl).
        :return:
        """
        storage = Storage()
        keys_to_set = {
            '1': 'hello',
            '2': 'bye',
            '3': [1, 2, 'three'],
            '4': {
                1: 'one',
                2: 'two'
            }
        }
        for key in keys_to_set.keys():
            storage.set(key, keys_to_set[key])

        values = [storage.get(key) for key in keys_to_set.keys()]
        true_values = [keys_to_set[key] for key in keys_to_set.keys()]
        self.assertEqual(true_values, values)
        self.assertRaises(StorageKeyError, storage.get, '0')
예제 #8
0
class FFG7BSensor(Device, CheckCyclicTask):
    """Specialized class to forward notfications of Eltako FFG7B-rw (similar to Eltako TF-FGB) windows/door handles.
    Output is a json dict with values of `HandleValues`. Additionally, there is a `SINCE` field (JSON) which indicates
    the last change time.

    No information is sent back to the device! Not supported by device.
    """

    DEFAULT_EEP = Eep(rorg=0xf6,
                      func=0x10,
                      type=0x00,
                      direction=None,
                      command=None)

    def __init__(self, name):
        Device.__init__(self, name)
        CheckCyclicTask.__init__(self)

        # default config values
        self._eep = self.DEFAULT_EEP.clone()

        self._storage_max_age = None  # type: Optional[int]  # age in seconds

        self._storage = Storage()

    def _set_config(self, config, skip_require_fields: [str]):
        skip_require_fields = [
            *skip_require_fields, CONFKEY_ENOCEAN_SENDER,
            CONFKEY_MQTT_CHANNEL_CMD
        ]

        super()._set_config(config, skip_require_fields)

        schema = self.filter_required_fields(FFG7B_SENSOR_JSONSCHEMA,
                                             skip_require_fields)
        self.validate_config(config, schema)

        self._storage_max_age = config.get(CONFKEY_STORAGE_MAX_AGE_SECS, 60)

        storage_file = config.get(CONFKEY_STORAGE_FILE)
        self._storage.set_file(storage_file)

        try:
            self._storage.load()
        except StorageException as ex:
            self._logger.exception(ex)

    def _determine_and_store_since(self, value_enum: HandleValue):
        success_value = HandleValue.is_success(value_enum)
        if success_value:
            key_state = StorageKey.VALUE_SUCCESS.value
            key_time = StorageKey.TIME_SUCCESS.value
        else:
            key_state = StorageKey.VALUE_ERROR.value
            key_time = StorageKey.TIME_ERROR.value

        if success_value:
            self._storage.delete(StorageKey.VALUE_ERROR.value)
            self._storage.delete(StorageKey.TIME_ERROR.value)

        value_since = self._storage.get(key_state)
        time_since = self._storage.get(key_time)
        if value_since != value_enum.value:
            value_since = value_enum.value
            time_since = None

        if time_since is None:
            time_since = self._now()
            self._storage.set(key_state, value_since)
            self._storage.set(key_time, time_since)

            try:
                self._storage.save()
            except StorageException as ex:
                self._logger.exception(ex)

        return time_since

    def _create_message(self,
                        value: HandleValue,
                        since: Optional[datetime.datetime],
                        timestamp: Optional[datetime.datetime] = None):

        if not timestamp:
            timestamp = self._now()

        data = {
            JsonAttributes.DEVICE: self.name,
            JsonAttributes.STATUS: value.value,
            JsonAttributes.TIMESTAMP: timestamp.isoformat(),
        }
        if since is not None:
            data[JsonAttributes.SINCE] = since.isoformat()

        json_text = json.dumps(data, sort_keys=True)
        return json_text

    def check_cyclic_tasks(self):
        self._check_and_send_offline()

    @classmethod
    def extract_handle_state(cls, value):
        if value == 3:
            return HandleValue.CLOSED
        elif value == 2:
            return HandleValue.OPEN
        elif value == 1:
            return HandleValue.TILTED
        else:
            return HandleValue.ERROR

    def process_enocean_message(self, message: EnoceanMessage):
        packet = message.payload  # type: RadioPacket
        if packet.packet_type != PACKET.RADIO:
            self._logger.debug("skipped packet with packet_type=%s",
                               EnoceanTools.packet_type_to_string(packet.rorg))
            return
        if packet.rorg != self._eep.rorg:
            self._logger.debug("skipped packet with rorg=%s", hex(packet.rorg))
            return

        self._reset_offline_refresh_timer()

        data = EnoceanTools.extract_packet_props(packet, self._eep)
        self._logger.debug("proceed_enocean - got: %s", data)

        try:
            value = self.extract_handle_state(data.get("WIN"))
        except DeviceException as ex:
            self._logger.exception(ex)
            value = HandleValue.ERROR

        if value == HandleValue.ERROR and self._logger.isEnabledFor(
                logging.DEBUG):
            # write ascii representation to reproduce in tests
            self._logger.debug("proceed_enocean - pickled error packet:\n%s",
                               PickleTools.pickle_packet(packet))

        since = self._determine_and_store_since(value)

        message = self._create_message(value, since)
        self._publish_mqtt(message)

    def _restore_last_state(self):
        """restore old STATE when in time"""
        if not self._storage.initilized:
            return  # TODO race condition: MQTT conection or loaded configuration

        last_observation = self._storage.get(
            StorageKey.TIME_LAST_OBSERVATION.value)
        if not last_observation:
            return
        diff_seconds = (self._now() - last_observation).total_seconds()
        if diff_seconds > self._storage_max_age:
            return
        if self._storage.get(StorageKey.TIME_ERROR.value) is not None:
            return

        last_value = self._storage.get(StorageKey.VALUE_SUCCESS.value)
        last_since = self._storage.get(StorageKey.TIME_SUCCESS.value)
        if not last_value or not last_since:
            return

        last_handle_value = HandleValue.parse(last_value)
        if not HandleValue.is_success(last_handle_value):
            return

        self._logger.info("old state '%s' (%s) restored.", last_handle_value,
                          last_observation)
        message = self._create_message(last_handle_value,
                                       last_since,
                                       timestamp=last_observation)
        self._publish_mqtt(message)

    def open_mqtt(self):
        super().open_mqtt()

        self._restore_last_state()

    def process_mqtt_message(self, message):
        pass  # do nothing

    def close_mqtt(self):
        super().close_mqtt()

        self._storage.set(StorageKey.TIME_LAST_OBSERVATION.value, self._now())
        try:
            self._storage.save()
        except StorageException as ex:
            self._logger.exception(ex)