Skip to content

naneos.diagnostics

The two diagnostics a Partector 2 reads out on request: the UI curve and the pulse form.

Both need firmware 418 or newer and are read the same way over USB and BLE (see PartectorDevice.read_ui_curve / read_pulse_form). Each goes to the naneos IoT service as a message of its own, apart from the measurement data.

PulseForm dataclass

The electrometer current along one charging pulse, 200 samples in time order.

Source code in src/naneos/diagnostics.py
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
@dataclass(frozen=True)
class PulseForm:
    """The electrometer current along one charging pulse, 200 samples in time order."""

    EXPECTED_ENTRIES: ClassVar[str] = f"{PULSE_FORM_VALUES} I values"

    device_type: DeviceType
    serial_number: int
    unix_timestamp: int  # seconds, when the form was read
    currents: tuple[float, ...]  # nA

    @property
    def is_complete(self) -> bool:
        return len(self.currents) == PULSE_FORM_VALUES

    @property
    def entries(self) -> str:
        """What the form holds, for the log: "200 I values"."""
        return f"{len(self.currents)} I values"

entries property

What the form holds, for the log: "200 I values".

UiCurve dataclass

The electrometer current over the corona voltage, 100 points sorted by voltage.

Source code in src/naneos/diagnostics.py
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
@dataclass(frozen=True)
class UiCurve:
    """The electrometer current over the corona voltage, 100 points sorted by voltage."""

    EXPECTED_ENTRIES: ClassVar[str] = f"{UI_CURVE_POINTS} U + {UI_CURVE_POINTS} I values"

    device_type: DeviceType
    serial_number: int
    unix_timestamp: int  # seconds, when the curve was read
    voltages: tuple[int, ...]  # V
    currents: tuple[float, ...]  # nA

    @property
    def is_complete(self) -> bool:
        return len(self.voltages) == UI_CURVE_POINTS and len(self.currents) == UI_CURVE_POINTS

    @property
    def entries(self) -> str:
        """What the curve holds, for the log: "100 U + 100 I values"."""
        return f"{len(self.voltages)} U + {len(self.currents)} I values"

entries property

What the curve holds, for the log: "100 U + 100 I values".

check_firmware(firmware_version, feature)

Raise NotSupportedError unless the firmware is new enough for the feature.

Source code in src/naneos/diagnostics.py
74
75
76
77
78
79
80
81
82
83
84
def check_firmware(firmware_version: int | None, feature: str) -> None:
    """Raise NotSupportedError unless the firmware is new enough for the feature."""
    from naneos.device import NotSupportedError  # circular at module level

    if firmware_version is None:
        raise NotSupportedError(f"The firmware version is not known yet: no {feature} until then.")
    if firmware_version < MIN_FIRMWARE:
        raise NotSupportedError(
            f"The {feature} needs firmware {MIN_FIRMWARE} or newer, "
            f"this device has {firmware_version}."
        )

raw_to_nanoamperes(raw)

The devices report their electrometer currents as nA * 100.

Source code in src/naneos/diagnostics.py
69
70
71
def raw_to_nanoamperes(raw: int) -> float:
    """The devices report their electrometer currents as nA * 100."""
    return raw / 100.0