s7_codec.py 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. from __future__ import annotations
  2. import struct
  3. from typing import Any
  4. def byte_size_for_type(point_type: str) -> int:
  5. if point_type in {"bool", "byte", "int8"}:
  6. return 1
  7. if point_type in {"int16", "uint16"}:
  8. return 2
  9. if point_type in {"int64", "uint64", "float64"}:
  10. return 8
  11. return 4
  12. def bytes_to_hex(data: bytes | bytearray) -> str:
  13. return " ".join(f"{value:02X}" for value in data)
  14. def convert_s7_value(data: bytes | bytearray, point_type: str, bit: int | None) -> Any:
  15. payload = bytes(data)
  16. if point_type == "bool":
  17. value = payload[0]
  18. if bit is None:
  19. return value != 0
  20. return ((value >> bit) & 1) == 1
  21. if point_type == "byte":
  22. return payload[0]
  23. if point_type == "int8":
  24. return int.from_bytes(payload, byteorder="big", signed=True)
  25. if point_type == "int16":
  26. return int.from_bytes(payload, byteorder="big", signed=True)
  27. if point_type == "uint16":
  28. return int.from_bytes(payload, byteorder="big", signed=False)
  29. if point_type == "int32":
  30. return int.from_bytes(payload, byteorder="big", signed=True)
  31. if point_type == "uint32":
  32. return int.from_bytes(payload, byteorder="big", signed=False)
  33. if point_type == "int64":
  34. return int.from_bytes(payload, byteorder="big", signed=True)
  35. if point_type == "uint64":
  36. return int.from_bytes(payload, byteorder="big", signed=False)
  37. if point_type == "float32":
  38. return struct.unpack(">f", payload)[0]
  39. if point_type == "float64":
  40. return struct.unpack(">d", payload)[0]
  41. raise ValueError(f"unsupported point type: {point_type}")