From 4dc42ee6f5a9990078b548ef609ca2438233ba83 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Odd=20Str=C3=A5b=C3=B8?= <oddstr13@openshell.no>
Date: Sun, 10 Dec 2023 23:54:13 +0100
Subject: [PATCH] Aggressively cache properties which are not expected to
 change at run time

---
 srnemqtt/protocol.py | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/srnemqtt/protocol.py b/srnemqtt/protocol.py
index ff52a13..fab654a 100644
--- a/srnemqtt/protocol.py
+++ b/srnemqtt/protocol.py
@@ -232,8 +232,13 @@ class ChargeController:
     def __init__(self, device: BaseInterface):
         self.device = device
 
+    _cached_serial: str | None = None
+
     @property
     def serial(self) -> str:
+        if self._cached_serial is not None:
+            return self._cached_serial
+
         data = readMemory(self.device, 0x18, 3)
         if data is None:
             raise IOError  # FIXME: Raise specific error in readMemory
@@ -241,18 +246,31 @@ class ChargeController:
         p1 = data[0]
         p2 = data[1]
         p3 = (data[2] << 8) + data[3]
-        return f"{p1}-{p2}-{p3}"
+
+        self._cached_serial = f"{p1}-{p2}-{p3}"
+        return self._cached_serial
+
+    _cached_model: str | None = None
 
     @property
     def model(self) -> str:
+        if self._cached_model is not None:
+            return self._cached_model
+
         data = readMemory(self.device, 0x0C, 8)
         if data is None:
             raise IOError  # FIXME: Raise specific error in readMemory
 
-        return data.decode("utf-8").strip()
+        self._cached_model = data.decode("utf-8").strip()
+        return self._cached_model
+
+    _cached_version: str | None = None
 
     @property
     def version(self) -> str:
+        if self._cached_version is not None:
+            return self._cached_version
+
         data = readMemory(self.device, 0x14, 4)
         if data is None:
             raise IOError  # FIXME: Raise specific error in readMemory
@@ -261,7 +279,8 @@ class ChargeController:
         minor = data[2]
         patch = data[3]
 
-        return f"{major}.{minor}.{patch}"
+        self._cached_version = f"{major}.{minor}.{patch}"
+        return self._cached_version
 
     @property
     def load_enabled(self) -> bool: