From d27e373a5aeff46a149543db5b85c6dc1af94b88 Mon Sep 17 00:00:00 2001 From: Gijs Molenaar Date: Thu, 2 May 2024 09:58:58 +0200 Subject: [PATCH] add set date logic (#494) --- snap7/util/db.py | 7 +++++-- snap7/util/setters.py | 26 ++++++++++++++++++++++++++ tests/test_util.py | 6 ++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/snap7/util/db.py b/snap7/util/db.py index f782e882..04cb54b8 100644 --- a/snap7/util/db.py +++ b/snap7/util/db.py @@ -1,6 +1,6 @@ import re from collections import OrderedDict -from datetime import datetime +from datetime import datetime, date from typing import Optional, Union, Dict, Callable from logging import getLogger @@ -46,7 +46,7 @@ set_sint, set_time, ) -from snap7.util.setters import set_lreal +from snap7.util.setters import set_lreal, set_date logger = getLogger(__name__) @@ -540,6 +540,9 @@ def set_value(self, byte_index: Union[str, int], type_: str, value: Union[bool, if type_ == "TIME" and isinstance(value, str): return set_time(bytearray_, byte_index, value) + if type_ == "DATE" and isinstance(value, date): + return set_date(bytearray_, byte_index, value) + raise ValueError def write(self, client: Client) -> None: diff --git a/snap7/util/setters.py b/snap7/util/setters.py index dffc96e7..83272ea5 100644 --- a/snap7/util/setters.py +++ b/snap7/util/setters.py @@ -1,5 +1,6 @@ import re import struct +from datetime import date from typing import Union from .getters import get_bool @@ -508,3 +509,28 @@ def set_char(bytearray_: bytearray, byte_index: int, chr_: str) -> Union[ValueEr bytearray_[byte_index] = ord(chr_) return bytearray_ raise ValueError(f"chr_ : {chr_} contains a None-Ascii value, but ASCII-only is allowed.") + + +def set_date(bytearray_: bytearray, byte_index: int, date_: date) -> bytearray: + """Set value in bytearray to date + Notes: + Datatype `date` consists in the number of days elapsed from 1990-01-01. + It is stored as an int (2 bytes) in the PLC. + Args: + bytearray_: buffer to write. + byte_index: byte index from where to start writing. + date: date object + Examples: + >>> data = bytearray(2) + >>> snap7.util.set_date(data, 0, date(2024, 3, 27)) + >>> data + bytearray(b'\x30\xd8') + """ + if date_ < date(1990, 1, 1): + raise ValueError("date is lower than specification allows.") + elif date_ > date(2168, 12, 31): + raise ValueError("date is higher than specification allows.") + _days = (date_ - date(1990, 1, 1)).days + _bytes = struct.unpack("2B", struct.pack(">h", _days)) + bytearray_[byte_index : byte_index + 2] = _bytes + return bytearray_ diff --git a/tests/test_util.py b/tests/test_util.py index 81d41de6..050df169 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -597,6 +597,12 @@ def test_get_dtl(self): val = row["testDtl"] self.assertEqual(val, datetime.datetime(year=2022, month=3, day=9, hour=12, minute=34, second=45)) + def test_set_date(self): + test_array = bytearray(_bytearray) + row = snap7.util.db.DB_Row(test_array, test_spec_indented, layout_offset=4) + row["testDate"] = datetime.date(day=28, month=3, year=2024) + self.assertEqual(row["testDate"], datetime.date(day=28, month=3, year=2024)) + if __name__ == "__main__": unittest.main()