Skip to content

Commit

Permalink
RecordedData: store uint64 as int64 shifted - unknown class as float
Browse files Browse the repository at this point in the history
uint64 are shifted by -9223372036854775808 = 2**63 to be stored as a
django BigIntegerField
  • Loading branch information
clavay authored and trombastic committed Feb 12, 2024
1 parent 7d272b6 commit 067f978
Showing 1 changed file with 22 additions and 1 deletion.
23 changes: 22 additions & 1 deletion pyscada/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2642,6 +2642,17 @@ def __init__(self, *args, **kwargs):
"variable"
].value_class.upper() in ["BOOL", "BOOLEAN"]:
kwargs["value_float64"] = float(kwargs.pop("value"))
elif kwargs["variable"].value_class.upper() in ["UINT64"]:
# moving the uint64 range [0, 2**64 - 1] to the int64 [-2**63, 2**63 - 1] to be stored as a django BigIntegerField
kwargs["value_int64"] = int(kwargs.pop("value")) - 2**63
# See https://docs.djangoproject.com/en/stable/ref/models/fields/#bigintegerfield
if (
kwargs["value_int64"] < -9223372036854775808
or kwargs["value_int64"] > 9223372036854775807
):
raise ValueError(
f"Saving value to RecordedData for {kwargs['variable']} with value class {kwargs['variable'].value_class.upper()} should be in the interval [0:18446744073709551616], it is {kwargs['value_int64'] + 2**63}"
)
elif kwargs["variable"].value_class.upper() in [
"INT64",
"UINT32",
Expand Down Expand Up @@ -2686,6 +2697,9 @@ def __init__(self, *args, **kwargs):
)
elif kwargs["variable"].value_class.upper() in ["BOOL", "BOOLEAN"]:
kwargs["value_boolean"] = bool(kwargs.pop("value"))
else:
logger.warning(f"The {kwargs['variable'].value_class.upper()} variable value class is not defined in RecordedData __init__ function. Default storing value as float.")
kwargs["value_float64"] = float(kwargs.pop("value"))

# call the django model __init__
super(RecordedData, self).__init__(*args, **kwargs)
Expand Down Expand Up @@ -2733,6 +2747,12 @@ def value(self, value_class=None):
return self.value_float64
elif self.variable.scaling and not value_class.upper() in ["BOOL", "BOOLEAN"]:
return self.value_float64
elif value_class.upper() in ["UINT64"]:
# moving the int64 range [2**63, 2**63 - 1] stored as a django BigIntegerField to the int64 [0, 2**64 - 1]
value = self.value_int64
if value is None:
return value
return value + 2**63
elif value_class.upper() in ["INT64", "UINT32", "DWORD", "INT48"]:
return self.value_int64
elif value_class.upper() in ["WORD", "UINT", "UINT16", "INT32"]:
Expand All @@ -2742,7 +2762,8 @@ def value(self, value_class=None):
elif value_class.upper() in ["BOOL", "BOOLEAN"]:
return self.value_boolean
else:
return None
logger.warning(f"The {value_class.upper()} variable value class is not defined in RecordedData value function. Default reading value as float.")
return self.value_float64

def save(self, *args, **kwargs):
if self.date_saved is None:
Expand Down

0 comments on commit 067f978

Please sign in to comment.