Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions lib/wsen-hids/wsen_hids/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ def __init__(
self._calibration = {}
self._temp_gain = 1.0
self._temp_offset = 0.0
self._avg_t = avg_t
self._avg_h = avg_h
self._bdu = enable_bdu

if check_device:
self.check_device()
Expand Down Expand Up @@ -167,10 +170,13 @@ def _read_calibration(self):
# -------------------------------------------------------------------------

def enable_bdu(self, enabled=True):
self._bdu = enabled
value = CTRL_1_BDU if enabled else 0
self._update_reg(REG_CTRL_1, CTRL_1_BDU, value)

def set_average(self, avg_t=AVG_T_DEFAULT, avg_h=AVG_H_DEFAULT):
self._avg_t = avg_t
self._avg_h = avg_h
avg_t &= 0x07
avg_h &= 0x07
value = (avg_t << 3) | avg_h
Expand Down Expand Up @@ -201,6 +207,10 @@ def power_on(self):
ctrl1 = self._read_reg(REG_CTRL_1)
ctrl1 |= CTRL_1_PD
self._write_reg(REG_CTRL_1, ctrl1)
self.set_average(self._avg_t, self._avg_h)
if self._bdu:
self.enable_bdu(True)
Comment on lines +210 to +212
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve runtime config before restoring in power_on

power_on() now reapplies self._avg_t, self._avg_h, and self._bdu, but those fields are only initialized in __init__ and never updated by set_average()/enable_bdu(). After a caller changes averaging or BDU at runtime, a power_off()/power_on() cycle silently reverts to constructor-time settings (for example, enable_bdu(False) can be undone if the instance was created with enable_bdu=True), so the driver mutates user-selected configuration unexpectedly.

Useful? React with 👍 / 👎.

self._read_calibration()
Comment on lines 209 to +213
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

power_on() now restores averaging/BDU using _avg_t/_avg_h/_bdu, but those attributes are only set once in __init__. If a user calls set_average(...) or enable_bdu(False/True) after initialization, a later power_on() will restore the initial settings (and can even re-enable BDU after it was disabled). Consider updating _avg_t/_avg_h inside set_average() and _bdu inside enable_bdu(), and have power_on() apply enable_bdu(self._bdu) (both enable and disable) to reflect the current configuration.

Copilot uses AI. Check for mistakes.

def enable_heater(self, enabled=True):
value = CTRL_2_HEATER if enabled else 0
Expand Down
70 changes: 70 additions & 0 deletions tests/scenarios/wsen_hids.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,76 @@ tests:
expect_true: true
mode: [mock]

- name: "Power on restores averaging config after register loss"
action: script
script: |
dev.power_off()
i2c.writeto_mem(dev.address, 0x10, bytes([0x00]))
dev.power_on()
av_conf = i2c.readfrom_mem(dev.address, 0x10, 1)[0]
result = av_conf == 0x1B
expect_true: true
mode: [mock]

- name: "Power on restores BDU after register loss"
action: script
script: |
dev.power_off()
i2c.writeto_mem(dev.address, 0x20, bytes([0x00]))
dev.power_on()
ctrl1 = i2c.readfrom_mem(dev.address, 0x20, 1)[0]
result = (ctrl1 & 0x04) != 0
expect_true: true
mode: [mock]

- name: "Power on preserves runtime config changes"
action: script
script: |
dev.enable_bdu(False)
dev.power_off()
i2c.writeto_mem(dev.address, 0x20, bytes([0x00]))
dev.power_on()
ctrl1 = i2c.readfrom_mem(dev.address, 0x20, 1)[0]
result = (ctrl1 & 0x04) == 0
expect_true: true
mode: [mock]

- name: "Power on preserves runtime averaging changes"
action: script
script: |
dev.set_average(dev.AVG_64, dev.AVG_32)
dev.power_off()
i2c.writeto_mem(dev.address, 0x10, bytes([0x00]))
dev.power_on()
av_conf = i2c.readfrom_mem(dev.address, 0x10, 1)[0]
result = av_conf == ((dev.AVG_64 << 3) | dev.AVG_32)
expect_true: true
mode: [mock]

- name: "Read one-shot works after register loss"
action: script
script: |
dev.power_off()
i2c.writeto_mem(dev.address, 0x10, bytes([0x00]))
i2c.writeto_mem(dev.address, 0x20, bytes([0x00]))
dev.power_on()
h, t = dev.read_one_shot()
result = isinstance(h, float) and isinstance(t, float)
expect_true: true
mode: [mock]

- name: "Read one-shot after power cycle (hardware)"
action: script
script: |
from time import sleep_ms
dev.power_off()
sleep_ms(50)
dev.power_on()
h, t = dev.read_one_shot()
result = 10.0 < h < 90.0 and 10.0 < t < 50.0
expect_true: true
mode: [hardware]

- name: "Temperature with offset"
action: script
script: |
Expand Down
Loading