Source code for drivers.Elt_ch4.check_string

  1"""Serial-frame validator helper for the ELT CH4 (methane) sensor.
  2
  3Standalone development utility for debugging the ASCII-to-numeric
  4conversion of ELT CH4 sensor serial output. The module simulates a raw
  5byte stream as it would be received by
  6:class:`SensorBase.SensorBase.GenericSensor`-style consumers via the
  7production driver in :mod:`drivers.Elt_ch4.Elt_ch4`, and verifies that
  8numeric values are correctly extracted from the ASCII payload.
  9
 10This is a pure validation helper — it has no side effects on hardware
 11and is not used in production. It is safe to import and execute in unit
 12tests and doctests without a serial port present.
 13
 14Example:
 15    >>> from drivers.Elt_ch4.check_string import convert_elt_data
 16    >>> convert_elt_data("__1500_ppm")  # doctest: +SKIP
 17    string char:_ False
 18    string char:_ False
 19    string char:1 True
 20    1
 21    ...
 22    Sensor Val:1500
 23
 24Note:
 25    Mirrors the parsing logic of
 26    :meth:`drivers.Elt_ch4.Elt_ch4.Elt_ch4.convert_elt_data` but prints
 27    intermediate state to ``stdout`` for human inspection rather than
 28    returning a value.
 29"""
 30
 31
[docs] 32def convert_elt_data(string_data: str) -> None: 33 """Parse an ASCII sensor frame and print the extracted ppm value. 34 35 Debugging counterpart to 36 :meth:`drivers.Elt_ch4.Elt_ch4.Elt_ch4.convert_elt_data`. Iterates 37 over each character in ``string_data``, prints whether the 38 character is numeric, accumulates the digits into a single integer, 39 and prints the resulting ppm value. Useful for verifying frame 40 layout when bringing up a new sensor unit. 41 42 Args: 43 string_data (str): UTF-8 decoded ASCII payload from the ELT 44 sensor's serial output (e.g. ``"__1500_ppm"``). 45 46 Returns: 47 None: The parsed value is printed to ``stdout``; nothing is 48 returned to the caller. 49 50 Raises: 51 ValueError: If ``string_data`` contains no numeric characters, 52 because ``int("")`` cannot be evaluated when computing 53 ``final_sensor_value``. 54 55 Example: 56 >>> convert_elt_data("12") 57 string char:1 True 58 1 59 string char:2 True 60 2 61 Sensor Val:12 62 63 Note: 64 Like the production parser, digits are concatenated rather than 65 tokenised: ``"1 2"`` becomes ``12``, not ``1`` and ``2``. 66 """ 67 sensor_value = "" 68 for char in string_data: 69 print(f"string char:{char} {char.isnumeric()}") 70 if char.isnumeric(): 71 print(int(char)) 72 sensor_value += str(int(char)) 73 final_sensor_value = int(sensor_value) 74 print(f"Sensor Val:{final_sensor_value}")
75 76
[docs] 77def main(): 78 """Run :func:`convert_elt_data` against a canned ELT byte payload. 79 80 Reconstructs a representative ELT CH4 serial frame from a list of 81 single-byte ``bytes`` objects, decodes the stream as UTF-8, and 82 forwards the resulting string to :func:`convert_elt_data` for 83 parsing. Acts as the script entry point so the file can be run with 84 ``python check_string.py``. 85 86 Args: 87 None. 88 89 Returns: 90 None: Output is produced via ``print`` inside 91 :func:`convert_elt_data`. 92 93 Raises: 94 UnicodeDecodeError: If the canned ``list_raw_data`` is altered 95 to include a non-UTF-8 byte. 96 ValueError: Propagated from :func:`convert_elt_data` when the 97 decoded frame contains no digits. 98 99 Example: 100 >>> main() 101 string char:_ False 102 string char:_ False 103 string char:1 True 104 1 105 string char:5 True 106 5 107 string char:0 True 108 0 109 string char:0 True 110 0 111 string char:_ False 112 string char:p False 113 string char:p False 114 string char:m False 115 Sensor Val:1500 116 117 Note: 118 The alternative ``list_raw_data`` definition kept as a comment 119 documents a real-world capture that intentionally exercises the 120 non-printable byte path; it is left in place for future 121 regression checks. 122 """ 123 # list_raw_data = [b'\x16', b'5', b'\x0b', b'\x00', b'\x00', b'\x00', b'\r', b'\x00', b'\x00', b'\x00', b'\x0f', b'\x00', b'\x00', b'\x00', b'\x14', b'\x00', b'\x00', b'\x00', b'\x14', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x81', b'\xfa', b'\x00', b'\x00', b'\x01', b'\x8d', b'\x00', b'\x00', b'\x00', b'\x87', b'\x00', b'\x00', b'\x00', b'.', b'\x00', b'\x00', b'\x00', b'\x14', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x02', b'\x92'] 124 list_raw_data = [b"\x5f", b"\x5f", b"\x31", b"\x35", b"\x30", b"\x30", b"\x5f", b"\x70", b"\x70", b"\x6d"] 125 data = "" 126 for _data in list_raw_data: 127 data += _data.decode("utf-8") 128 # convert_elt_data(" 1500 _ ppm") 129 convert_elt_data(data)
130 131 132if __name__ == "__main__": 133 main()