Right-click a row in the "Setting history…" dialog to write that historical
value back to the connected station. The dialog stays module-agnostic via an
injected writer_for(setting_key) resolver; each module's repo_snapshot maps
writable keys to their set_* method and returns None for read-only ones
(MAC/firmware/serial/stats, type_code<0 station lines). Read-only rows show a
disabled menu item with a tooltip.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Inno Setup script hardcoded AppVersion '0.1.0' - a stale second source of truth that would ship the wrong version in Add/Remove Programs. It now takes the version at compile time via /DAppVersion (0.0.0-dev sentinel if omitted), and the README/CLAUDE.md build commands derive it from cim_suite.__version__. Also documents the full release sequence and notes-before-bump ordering in the README.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
bump.py wrote via Python text mode, which translated newlines to CRLF on Windows and produced a 'CRLF will be replaced by LF' warning on every release. Write with newline='' so the file stays LF, matching .gitattributes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The em-dash in the 'nothing to bump' message rendered as a replacement char on Windows' cp1252 console; use a plain hyphen.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Conventional-Commit-driven version bumps (scripts/bump.py), a commit-msg validation hook, and a /release-notes workflow that produces a human-reviewed CHANGELOG.md. Adds an in-app version badge + 'What's new' dialog on the launcher. The version is single-sourced from pyproject.toml (cim_suite.__version__), and the deterministic bump backbone lives in scripts/release/ with tests in tests/release/. Marks the 1.0.0 baseline.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The dialog stretched the middle "Setting" column, leaving "Value" stuck at
the ~100px default with no draggable handle (it's the last column next to a
stretch section). Switch to the codebase convention used by the sibling
da12 history dialog: stretch the last column ("Value"), keep sections
Interactive (resizable), and resizeColumnsToContents for sensible initial
widths. Value now fills the space, Setting fits its label, columns resize.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a shared SQLite store that change-logs DA-12/DA-07 configuration
settings keyed by station MAC (first sighting + on change; live values
excluded), surfaced via a reusable "Setting history..." dialog (per-row +
whole-device). Simulator runs use a separate devices.sim.db. Revert-to-
previous is tracked as BL-R1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- SettingHistoryDialog.export_to now writes the currently-shown (filtered)
rows instead of always the full set, matching what the user sees.
- Flag the station-settings wholesale-record assumption in
HARDWARE-VERIFICATION.md for confirmation against real D/E/B/C frames.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Construct DeviceRepository + RepositoryRecorder in create_widget (before
refresh()) so loadFinished is caught; stop/close both in shutdown() to
prevent a pending debounce flush hitting a closed connection. Mirrors the
DA-12 Task 8 wiring. Integration test confirms first > 0 and idempotency.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the module reaching into _recorder._timer with a public stop()
called before closing the repo, so a pending debounced flush can't hit a
closed SQLite connection. Reused by both module shutdowns.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Build DeviceRepository + RepositoryRecorder in create_widget so all
live sessions record config changes; stop the recorder debounce timer
before closing the repo in shutdown to prevent use-after-close errors.
Add integration tests that exercise make_recorder end-to-end against
the simulator (refresh dedup + sensor-name edit round-trip via refresh).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
In --simulate mode the repository points at a separate devices.sim.db so
the simulator's fixed MAC never pollutes real device history, while the
record/history feature stays interactively testable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Suite-wide SQLite store keyed by MAC that change-logs DA-12/DA-07
configuration settings (first sighting + on change), with a reusable
"Setting history..." dialog (per-row + whole-device) and a placeholder
backlog item for reverting to a previous value.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Folds the missing PA-35 device from the supplied docs/IOModbus.txt into the
bundled factory catalog, and renames the existing PA Visual/PA Audible entries
(id 0x2/0x1) to PA-01/14/15 and PA-02 to match the supplied naming.
Folds the missing device from the supplied docs/IOModbus.txt into the bundled
factory catalog. Only PA-35 (id 0x35) was genuinely absent; PA-01/14/15 (id 0x2)
and PA-02 (id 0x1) already shipped under the names "PA Visual" and "PA Audible"
with identical register maps, so they are renamed (device names + the
"Timeout"->"Communication Timeout" channel label) rather than duplicated.
Register attributes of the renamed entries are left as the factory's (e.g. the
static firmware-version flag). All 138 iomodbus tests pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Read-only catalog browser listing every factory + user device in a
sortable table (Name/ID/Manufacturer/Min FW/Channels/Settings/Origin),
evolving the Manage User Devices dialog. Delete limited to user rows;
overridden factory rows marked. Backed by pure catalog_view.build_device_rows
and config.supported_devices().
- _populate_supported_table: Channels/Settings use int DisplayRole for numeric
header-click sorting; ID and Min FW zero-padded to 4 hex digits so
lexicographic order equals numeric order.
- _build_supported_dialog: test-access refs (_table, _delete_btn) stored on
the dialog object rather than self, so they don't outlive the widgets.
- Tests updated to read from dlg._table / dlg._delete_btn accordingly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>