From 000aaa1e9e1a9a226dfc01a3fb8acabf19399cba Mon Sep 17 00:00:00 2001 From: CL Date: Sun, 11 Feb 2024 22:12:25 +0100 Subject: [PATCH 1/4] fix variable update values type checks --- pyscada/models.py | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/pyscada/models.py b/pyscada/models.py index 074b14b6..b64bbd0f 100755 --- a/pyscada/models.py +++ b/pyscada/models.py @@ -1916,7 +1916,11 @@ def _update_value(self, value=None, timestamp=None): self.value = value else: self.value = self.scaling.scale_value(value) - self.timestamp = timestamp + try: + self.timestamp = float(timestamp) + except ValueError as e: + logger.error(f"{self} - wrong timestamp : {e}") + return False self.store_value = False if self.prev_value is None: # no prev value in the cache, always store the value @@ -1947,18 +1951,28 @@ def update_values(self, value_list, timestamp_list, erase_cache=True): if erase_cache: self.cached_values_to_write = [] has_value = False - if isinstance(value_list.__class__, list): - logger.error( - f"{self} - Value list must be a list, it is a {type(value_list)}" - ) - return False - if isinstance(timestamp_list.__class__, list): - logger.error( - f"{self} - Timestamp list must be a list, it is a {type(timestamp_list)}" - ) - return False + if not isinstance(value_list, list): + if isinstance(value_list, bool) or isinstance(value_list, int) or isinstance(value_list, float) or isinstance(value_list, str): + value_list = [value_list] + else: + logger.warning( + f"{self} - Value list wrong type : {type(value_list)}" + ) + return False + if not isinstance(timestamp_list, list): + if isinstance(timestamp_list, bool) or isinstance(timestamp_list, int) or isinstance(timestamp_list, float) or isinstance(timestamp_list, str): + try: + timestamp_list = [float(timestamp_list)] + except ValueError as e: + logger.warning(f"{self} - wrong timestamp : {e}") + return False + else: + logger.warning( + f"{self} - Timestamp list wrong type : {type(timestamp_list)}" + ) + return False if len(value_list) != len(timestamp_list): - logger.error( + logger.warning( f"{self} - value and timestamp lists have not the same length ({len(value_list)}, {len(timestamp_list)})" ) return False From 2056081a33cfc3ff69a6316f1e8b025df7b4d20a Mon Sep 17 00:00:00 2001 From: clavay Date: Mon, 12 Feb 2024 15:55:32 +0100 Subject: [PATCH 2/4] update default handler connect and disconnect returns --- pyscada/device.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyscada/device.py b/pyscada/device.py index 8dbaf9d4..f24a409b 100644 --- a/pyscada/device.py +++ b/pyscada/device.py @@ -48,6 +48,7 @@ def connect(self): return False # self.accessibility() + return True def accessibility(self): if self.inst is not None: @@ -67,8 +68,7 @@ def accessibility(self): def disconnect(self): if self.inst is not None: self.inst = None - return True - return False + return True def before_read(self): """ From 2d1ab6b359ddf7373350d7f267bf870459a30e0c Mon Sep 17 00:00:00 2001 From: clavay Date: Mon, 12 Feb 2024 15:58:55 +0100 Subject: [PATCH 3/4] check read time as not None and directly pass result to update_values update_values will : check if value and read time are list or not if they are list, check if length are the same --- pyscada/device.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyscada/device.py b/pyscada/device.py index f24a409b..37da0ee7 100644 --- a/pyscada/device.py +++ b/pyscada/device.py @@ -104,7 +104,7 @@ def read_data_all(self, variables_dict): if self.before_read(): for item in variables_dict.values(): value, read_time = self.read_data_and_time(item) - if value is not None and item.update_values([value], [read_time]): + if value is not None and read_time is not None and item.update_values(value, read_time): output.append(item) self.after_read() return output From 6259b3f4d3d552d87182e70a1964aacd1313ff89 Mon Sep 17 00:00:00 2001 From: clavay Date: Mon, 12 Feb 2024 18:21:39 +0100 Subject: [PATCH 4/4] handler: add erase cache option in read data all in order to call various times read data all in a handler, allow to not erase the cached results --- pyscada/device.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyscada/device.py b/pyscada/device.py index 37da0ee7..bc14c572 100644 --- a/pyscada/device.py +++ b/pyscada/device.py @@ -98,13 +98,13 @@ def read_data_and_time(self, variable_instance): return self.read_data(variable_instance), self.time() - def read_data_all(self, variables_dict): + def read_data_all(self, variables_dict, erase_cache=True): output = [] if self.before_read(): for item in variables_dict.values(): value, read_time = self.read_data_and_time(item) - if value is not None and read_time is not None and item.update_values(value, read_time): + if value is not None and read_time is not None and item.update_values(value, read_time, erase_cache=erase_cache): output.append(item) self.after_read() return output