DeaD_EyE

w1_slave

Jan 7th, 2022 (edited)
952
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.76 KB | None | 0 0
  1. import re
  2. import sys
  3. import time
  4. from pathlib import Path
  5.  
  6.  
  7. class CRCError(ValueError):
  8.     pass
  9.  
  10.  
  11. class DeviceNotExistsError(ValueError):
  12.     pass
  13.  
  14.  
  15. class ReadError(ValueError):
  16.     pass
  17.  
  18.  
  19. class W1:
  20.     """
  21.    Temperatur eines w1_slave lesen
  22.  
  23.    Beispieldaten:
  24.  
  25.        24 01 4b 46 7f ff 0c 10 48 : crc=48 YES
  26.        24 01 4b 46 7f ff 0c 10 48 t=18250
  27.  
  28.  
  29.    Ergebnis: 18.25 °C
  30.    """
  31.  
  32.     def __init__(self, device: str, check_crc: bool = False):
  33.         """
  34.        device := eindeutige ID des W1 Sensors
  35.        check_crc := Wenn True, dann wird der CRC check gelesen
  36.                     und bei einem ungültigen CRC wird ein CRCError ausgelöst
  37.        """
  38.         self.device = Path("/sys/bus/w1/devices", device, "w1_slave")
  39.         self.check_crc = check_crc
  40.  
  41.         if not self.device.exists():
  42.             raise DeviceNotExistsError(f"Device {self.device} not found", self.device)
  43.  
  44.     def _crc(self, data: str) -> None:
  45.         """
  46.        Prüfen ob der CRC stimmt.
  47.        Wenn der CRC nicht OK ist, wird ein CRCError ausgelöst.
  48.        """
  49.         if not re.search(r"crc=\d+ YES", data):
  50.             raise CRCError("CRC is not ok", self.device)
  51.  
  52.     def read(self) -> float:
  53.         """
  54.        Temperatur auslesen und als float zurückgeben
  55.        """
  56.         try:
  57.             data = self.device.read_text()
  58.         except PermissionError:
  59.             raise ReadError("Permission denied.", self.device)
  60.  
  61.         if self.check_crc:
  62.             self._crc(data)
  63.  
  64.         if not (match := re.search(r"t=(\d+)", data)):
  65.             raise ReadError("Could not find t=xxxx", self.device)
  66.  
  67.         return int(match.group(1)) / 1_000
  68.  
  69.     __call__ = read
  70.  
  71.  
  72. if __name__ == "__main__":
  73.     FUEHLER = ("28-0217c123ceff", "28-0217c123ceff", "28-0516b586b1ff")
  74.     # ich bevorzuge nicht veränderbare Sequenzen als KONSTANTEN
  75.     # die Tuple ist nicht veränderbar
  76.     # str und bytes sind auch nicht veränderbar
  77.     # die runden Klammern kann man auch weg lassen
  78.  
  79.     # nun die W1 Objekte mit einer List Comprehension erzeugen
  80.     try:
  81.         w1_sensoren = [W1(fuehler) for fuehler in FUEHLER]
  82.     except Exception as e:
  83.         print(e.args[0])
  84.  
  85.         # programm verlassen, da w1_sensoren nicht existiert,
  86.         # wenn beim Erstellen der Liste ein Fehler auftritt
  87.         raise SystemExit()
  88.  
  89.     while True:
  90.         time.sleep(2)
  91.         sensor_values = [sensor() for sensor in w1_sensoren]
  92.         # das Resultierende Objekt der Klasse W1 ist aufrufbar (callable),
  93.         # da die Methode __call__ implementiert ist, die dann
  94.         # die Methode read aufruft.
  95.  
  96.         # Alternativ der direkte Aufruf von read:
  97.         # sensor_values = [sensor.read() for sensor in w1_sensoren]
  98.  
  99.         print(sensor_values)
  100.  
Add Comment
Please, Sign In to add comment