def _get_tag_reader(self, path: str, data_type: tbase.DataType) -> "tbase.TagValueReader": """Get a :class:`TagValueReader` for this path. Args: path: The path of the tag to read. data_type: The data type of the value to read. """ return tbase.TagValueReader(self, tbase.TagData(path, data_type))
def _create_value_reader( self, tag: tbase.TagData) -> Optional[tbase.TagValueReader]: if tag is None: raise ValueError("tag cannot be None") if tag.data_type == tbase.DataType.UNKNOWN: return None else: return tbase.TagValueReader(self, tag)
def test__write_read_bool_tag__values_are_correct(self, generate_tag_path): with self.tag_manager.create_writer(buffer_size=1) as writer: tag = tbase.TagData(generate_tag_path(), tbase.DataType.BOOLEAN) tag.collect_aggregates = True self.tag_manager.update([tag]) self.internal_test_write_and_read_tag( tag, writer, tbase.TagValueReader(self.tag_manager, tag), value_to_write=True, )
def test__write_read_date_time_tag__values_are_correct(self, generate_tag_path): with self.tag_manager.create_writer(buffer_size=1) as writer: tag = tbase.TagData(generate_tag_path(), tbase.DataType.DATE_TIME) tag.collect_aggregates = True self.tag_manager.update([tag]) self.internal_test_write_and_read_tag( tag, writer, tbase.TagValueReader(self.tag_manager, tag), value_to_write=datetime.now(timezone.utc), )
def test__write_read_double_tag__values_are_correct(self, generate_tag_path): with self.tag_manager.create_writer(buffer_size=1) as writer: tag = tbase.TagData(generate_tag_path(), tbase.DataType.DOUBLE) tag.collect_aggregates = True self.tag_manager.update([tag]) aggregates = self.internal_test_write_and_read_tag( tag, writer, tbase.TagValueReader(self.tag_manager, tag), value_to_write=math.pi, ) assert math.pi == aggregates.min assert math.pi == aggregates.max assert math.pi == aggregates.mean
def test__write_read_uint64_tag__values_are_correct(self, generate_tag_path): with self.tag_manager.create_writer(buffer_size=1) as writer: tag = tbase.TagData(generate_tag_path(), tbase.DataType.UINT64) tag.collect_aggregates = True value = 2 ** 64 - 1 self.tag_manager.update([tag]) aggregates = self.internal_test_write_and_read_tag( tag, writer, tbase.TagValueReader(self.tag_manager, tag), value_to_write=value, ) assert value == aggregates.min assert value == aggregates.max assert math.isclose(value, aggregates.mean)
def test__special_tag_paths_used__apis_work(self, generate_tag_path): paths = ["basic", "space path", "slash/path", "underscore_path"] with self.tag_manager.create_writer(buffer_size=1) as writer: for path in paths: tag = self.tag_manager.open(generate_tag_path(path), tbase.DataType.DOUBLE, create=True) tag.collect_aggregates = True self.tag_manager.update(updates=[ tbase.TagDataUpdate.from_tagdata( tag, tbase.TagUpdateFields.COLLECT_AGGREGATES) ]) self.internal_test_write_and_read_tag( tag, writer, tbase.TagValueReader(self.tag_manager, tag), 3.0, ) self.tag_manager.delete([tag])
def test__uint64_aggregates(self, generate_tag_path): min = random.randrange(0, 2**31) max = random.randrange(2**31, 2**32) mean = (min + max + 2**31) / 3.0 with self.tag_manager.create_writer(buffer_size=3) as writer: tag = tbase.TagData(generate_tag_path(), tbase.DataType.UINT64) tag.collect_aggregates = True self.tag_manager.update([tag]) aggregates = self.internal_test_numeric_aggregates( tag, writer, tbase.TagValueReader(self.tag_manager, tag), mean, (max, min, 2**31), ) assert min == aggregates.min assert max == aggregates.max
def test__set_int_values__aggregate_values_are_correct(self, generate_tag_path): min = random.randrange(-(2 ** 31), 0) max = random.randrange(0, 2 ** 31 - 1) mean = (min + max) / 3.0 with self.tag_manager.create_writer(buffer_size=3) as writer: tag = tbase.TagData(generate_tag_path(), tbase.DataType.INT32) tag.collect_aggregates = True self.tag_manager.update([tag]) aggregates = self.internal_test_numeric_aggregates( tag, writer, tbase.TagValueReader(self.tag_manager, tag), mean, (min, 0, max), ) assert min == aggregates.min assert max == aggregates.max
def test__set_double_values__aggregate_values_are_correct(self, generate_tag_path): min = -random.random() * sys.float_info.max / 2 max = random.random() * sys.float_info.max / 2 mean = (min + max) / 3 with self.tag_manager.create_writer(buffer_size=3) as writer: tag = tbase.TagData(generate_tag_path(), tbase.DataType.DOUBLE) tag.collect_aggregates = True self.tag_manager.update([tag]) aggregates = self.internal_test_numeric_aggregates( tag, writer, tbase.TagValueReader(self.tag_manager, tag), mean, (0.0, max, min), ) assert math.isclose(min, aggregates.min), (min, aggregates.min) assert math.isclose(max, aggregates.max), (max, aggregates.max)
def _update_timer_elapsed(self) -> None: try: token = self._token if token is None: return try: response, _ = self._api.get("/{id}/values/current", params={"id": token}) except core.ApiException: return if response is None: return subscriptions = response.get("subscriptionUpdates") if subscriptions is None: return for subscription in subscriptions: if subscription is None: continue updates = subscription.get("updates") if updates is None: continue for update in updates: if update is None: continue tag = update.get("tag") timestamp = update.get("timestamp") if tag is None or timestamp is None: continue tag = tbase.TagData.from_json_dict(tag) try: tag.validate_path() except ValueError: continue aggregates = update.get("aggregates") or {} if tag.data_type == tbase.DataType.UNKNOWN: self._on_tag_changed(tag, None) else: value = SerializedTagWithAggregates( tag.path, tag.data_type, update.get("value"), TimestampUtilities.str_to_datetime(timestamp), aggregates.get("count"), aggregates.get("min"), aggregates.get("max"), (float(aggregates["avg"]) if aggregates.get("avg") is not None else None), ) reader = tbase.TagValueReader( SerializedTagWithAggregatesReader(value), tag) # type: tbase.TagValueReader self._on_tag_changed(tag, reader) finally: self._update_timer.start()