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()
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")
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'")
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)
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))
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
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')
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)