Releases: Rouzax/Rename-Domoticz-From-ZwaveJSON
Release list
v2.13.1 - Log in from a shell prompt
Patch release.
Logging in now works when you start the script from a shell prompt.
-ZwaveJsCredential (Get-Credential) only works from inside a PowerShell session. Started the way most people run it on a Raspberry Pi, bash parses the command line before PowerShell ever sees it and stops on the parentheses:
$ pwsh ./Rename-Domoticz-From-ZwaveJSON.ps1 -ZwaveJsUrl "http://localhost:8091" -ZwaveJsCredential (Get-Credential) ...
bash: syntax error near unexpected token `('Pass a username instead
pwsh ./Rename-Domoticz-From-ZwaveJSON.ps1 -ZwaveJsUrl "http://localhost:8091" \
-DbPath "/home/user/domoticz.db" -ZwaveJsUser admin -DryRun-ZwaveJsUser takes a plain username (admin on a default zwave-js-ui install), so it reaches PowerShell untouched. The password is prompted for, and never appears in your shell history, the process list, the log, or the HTML report.
-ZwaveJsCredential is unchanged and still takes a PSCredential, for when you already hold one, want to be prompted for the username too, or are running unattended with Import-CliXml. Supplying both is an error.
Why a new parameter rather than accepting a username on the old one
PowerShell's [Credential()] transformation attribute would have accepted a username on -ZwaveJsCredential with no new parameter. It was tried first and rejected: when it cannot prompt, it aborts during parameter binding, before the script runs, and the process exits 0. A scheduled run that renamed nothing while reporting success is the one outcome this tool's exit codes must never produce.
Prompting from the script body keeps every failure loud. -ZwaveJsUser with no console to prompt at exits 1 and points you at Import-CliXml; combining it with -ZwaveJsCredential exits 1 rather than silently preferring one.
Also in this release
- A rejected connection names the option to reach for next. The error said "requires authentication - pass -ZwaveJsToken" whatever you had supplied, sending anyone using a credential back to the token workflow the credential exists to replace. It now distinguishes no login supplied, a token that was not accepted (usually expired), and a credential whose login succeeded but whose token was then refused.
- Docs: a new section on running from bash, zsh or a Pi terminal, plus troubleshooting entries for each symptom this produced.
- Internal: the version number lived in three places and had already drifted; the banner and the report footer now read one constant.
Verified against a live authenticated zwave-js-ui: -ZwaveJsUser prompts, logs in, and dry-runs to 63 renames, 0 collisions, 0 errors, matching the v2.13 result. No behaviour changes to renaming, rules, collisions, or the database.
v2.13 - Credential-based zwave-js-ui login
Authenticating no longer means handling a token yourself.
If your zwave-js-ui has authentication enabled, you previously had to fetch a JWT out of band, paste it into an environment variable, and repeat that whenever it expired. The script was offloading its own problem, and a scheduled run would quietly start failing weeks later with an error that reads like a regression.
Log in instead
.\Rename-Domoticz-From-ZwaveJSON.ps1 -ZwaveJsUrl "https://zwave-host:8091" `
-ZwaveJsCredential (Get-Credential) -DbPath "domoticz.db" -DryRunGet-Credential prompts for the username and password without either reaching your shell history or the process list. The script exchanges them for a session token itself, so you never obtain or store one, and expiry stops mattering because every run logs in fresh.
For an unattended run, save the credential once:
Get-Credential | Export-CliXml ./zwave.cred # once, interactively
.\Rename-Domoticz-From-ZwaveJSON.ps1 -ZwaveJsUrl "https://zwave-host:8091" `
-ZwaveJsCredential (Import-CliXml ./zwave.cred) -DbPath "domoticz.db"Export-CliXml encrypts the password so only the same user on the same machine can read it back. Keep that file out of version control.
How the secret is handled
The password stays in a SecureString and is converted to plaintext only for the login request body. It is never returned, logged, or written to any output file.
Sending a password over http:// warns more sharply than sending a token did, and deliberately so: a captured token expires, a captured password works until you change it. As before, the script warns rather than refusing, because a trusted LAN or localhost is a common and reasonable case.
Compatibility
-ZwaveJsToken is unchanged and still works. Supplying both a credential and a token is an error rather than a silent preference, so a script that sets both gets told rather than guessed at.
Nothing else in this release changes how devices are selected or renamed.
v2.12 - Per-unit naming for multi-unit devices
Read this before updating if you use a Central Scene remote. This is the first release that renames devices you were already using. If a dzVents script or scene looks a device up by name, that name may change. Run with
-DryRunfirst, check the listed names against your automations, and remember the undo script reverses the run. Automations that reference devices byidxare unaffected.
The problem
A DeviceID is not unique in Domoticz. A multi-unit device, most visibly a Central Scene remote, is stored as one DeviceID with several Unit rows, and Domoticz names all of them from a single MQTT discovery payload. The result is three identically named devices in your UI:
Living Room - Remote - Scene 001
Living Room - Remote - Scene 001
Living Room - Remote - Scene 001
v2.11 made this safe by skipping such devices. It did not make it useful.
What changes
Each row now gets its own name, derived from the Z-Wave state the unit represents:
Living Room - Remote - Scene 001 - Short
Living Room - Remote - Scene 001 - Released
Living Room - Remote - Scene 001 - Held
The meanings come from the value's own states array (KeyPressed, KeyReleased, KeyHeldDown), and bundled rules rewrite them to Short, Released and Held. Those words are yours to change: it is one with value in rename_rules.json, no different from any other label the tool rewrites. If you trigger long presses on KeyReleased, as many WallMote setups do, you may prefer Long there.
The mapping is treated as untrusted
Domoticz numbers Unit rows by state value, but that is an observed correspondence, not a documented contract. Mislabelling a real light switch is worse than leaving it duplicated, so per-unit naming applies only when the row count matches the state count and every Unit maps to a state value. If a state's value is not a whole number, its label is missing or blank, or a Unit has no matching state, the tool falls back to v2.11's behaviour: skip the device, leave every row exactly as it was, and say so.
Writes and undo are now per row
Every UPDATE and every undo statement carries AND Unit = N. This closes the v2.11 bug structurally rather than by guarding against it: the undo script now restores each unit its own name, where previously it would have rewritten every row with whichever single name happened to be captured.
Also in this release
UnchangedandRenamedcount rows, not devices, for a mapped multi-unit device. A re-run may report a smallerUnchangedfigure than before; no devices have gone missing.- A rules-engine compatibility change. A rule that matches a DeviceID pattern but changes nothing and sets no
switchType/customImagenow falls through to the next rule instead of ending the chain. No bundled rule changes behaviour as a result. If you used a broad no-op rule to shadow later rules, use-ExcludePatterninstead. - The CSV summary gains a
Unitcolumn and no longer risks serializing internal fields. - If you already hand-named individual units, you may see a collision reported rather than a rename. That is expected and safe: the tool never creates a silent duplicate.
Preview with -DryRun first, as always.
v2.11 - Multi-row devices are no longer collapsed
Fixes a data-loss bug. Update if you have any multi-unit device, most commonly a Central Scene remote.
What went wrong
A DeviceID is not unique in Domoticz. A multi-unit device is stored as one DeviceID with several Unit rows. The tool read only one of those rows, but wrote with WHERE DeviceID = ..., hitting all of them.
If you had named the units individually, a rename silently collapsed them:
BEFORE AFTER
Scene 1 Pressed Living Room - Remote - Scene 1
Scene 1 Held ───▶ Living Room - Remote - Scene 1
Scene 1 Released Living Room - Remote - Scene 1
reported as Collisions: 0, defeating the guarantee the tool exists to provide. The undo statement also matched on DeviceID alone, so running the undo script overwrote all three rows with whichever single name had been captured, rather than restoring the originals. The documented recovery path destroyed the evidence.
What changes
The tool cannot rename these correctly. A single Z-Wave value yields a single label, so there is no information available to give three units three names, and someone who named them individually did so on purpose. Rows that disagree on name, switch type or custom image are now detected and skipped:
! 1 device(s) skipped: several Domoticz rows share the DeviceID and disagree
Renaming would collapse them into one name, and the undo script could not restore them.
Only devices the run would otherwise have renamed are reported. A Domoticz database holds devices from other hardware whose rows may also disagree, and warning about devices this tool never touches would just be noise.
Collision detection now also treats every distinct name in DeviceStatus as taken, rather than one name per DeviceID. Names owned by a non-primary row were previously invisible, so another device could be renamed onto one and create exactly the duplicate the detection prevents.
Devices whose rows agree are unaffected and rename exactly as before. The summary gains an Ambiguous field that appears only when it is above zero, so an ordinary run's output is unchanged.
Also in this release
- A documentation site at https://rouzax.github.io/Rename-Domoticz-From-ZwaveJSON/, with a per-platform install guide covering Windows, macOS, Debian/Ubuntu, ARM Linux and Fedora/RHEL. The README is now a 78-line shop window instead of 616 lines.
- A runtime-only
distbranch, re-synced on every release, sogit clone -b distgives you just the files needed to run the tool. - Corrected reference data. Writing the docs against the script rather than the old README surfaced several long-standing errors: CustomImage value 9 was labelled "Fire" but is "Computer", the SwitchType and CustomImage tables held only 7 of 21 and 3 of 7 rows, and
rename_rules.jsonloads from the script's own directory rather than the working directory. - Comment-based help no longer advertises a
-WhatIfalias for-DryRun. It was removed in 2.4 and the help was never updated.
Preview with -DryRun first, as always.
v2.10 - Readable rename reports
The report now explains itself. Two changes, both about making the rename list readable.
Full names in the HTML report
The Name change previously showed only the text after the last " - " on each side of the arrow. A device going from Living Room-Lamp (Living Room - Lamp - Electric Consumption [W]) to Living Room - Lamp [W] - EP0 rendered as:
Electric Consumption [W]) → EP0
which reads as if the device is being renamed to EP0. Both names are now shown in full, long names wrap, and the collapsed header carries the full new name as a tooltip.
Collisions say who is to blame
Auto-resolved collisions were counted but never reported, so the endpoint suffix that caused that confusion had no explanation anywhere. A new Names Disambiguated section names, for each collision, the device that wanted the name and the device holding it, whether the node source still reports that device, and its Used flag and LastUpdate:
Living Room - Lamp [W] Endpoint suffix EP0 appended
WANTED BY zwavejs2mqtt_0xc15d8aa6_24-50-0-value-66049 [in node source]
HELD BY zwavejs2mqtt_0xc15d8aa6_24-50-1-value-66049 [not in node source, Used=0, last update 2026-05-14 00:06]
This is the case that motivated the release: when a Z-Wave value moves endpoint or disappears, Domoticz keeps the old DeviceStatus row forever. It never returns in the node source but still owns its name, so the live device can only be renamed with an endpoint suffix. That device is now named on the console and in the report, along with the fix (delete it in Setup → Devices and re-run). Unresolvable collisions gained the same detail.
Treat "not in node source" as a strong hint, not proof. zwave-js only creates notification, battery and smoke sub-values once a node first reports them, so a healthy but quiet device can be absent; Used and LastUpdate are shown so the call stays yours.
Notes
DeviceStatus is now read with Used and LastUpdate alongside the existing columns. Both are standard Domoticz columns and are used only for reporting, so which devices get renamed is unchanged. Preview with -DryRun first, as always.
v2.9 - Node-level device renaming
Node-level device renaming. The tool now also renames the node-level device Domoticz creates for a node, most importantly the combined Temp+Humidity device it builds from a multisensor (Domoticz Type 82, or Type 84 for Temp+Humidity+Baro). That device has no individual Z-Wave value behind it, so previous versions never matched it (the temperature/humidity values were just counted as "Missing"), and it kept zwave-js-ui's hyphen-no-space name like Kantoor-Sensor.
- Temp+Humidity / Temp+Humidity+Baro devices become
{location} - {name} - Climate. - Any other node-level device becomes
{location} - {name}.
It runs through the normal dry-run, rules, and collision detection, and can be excluded with -ExcludePattern 'node\d+$'. Preview with -DryRun first.
v2.8.1 - Token support over http
Patch release.
-ZwaveJsTokenover http: the token is now allowed overhttp://with a cleartext warning instead of being refused. A zwave-js-ui instance is usually on a trusted LAN or localhost, so the previous https-only requirement was too strict. Preferhttps://on untrusted networks. The token stays in the connect payload and is never logged.
v2.8 - Live zwave-js-ui reading and ARM support
This release bundles two milestones that had not yet shipped (2.7 and 2.8).
Read directly from zwave-js-ui (new)
-
New
-ZwaveJsUrlmode fetches node data live over zwave-js-ui's socket.io API (engine.io v4 WebSocket, no dependency), so a manualnodes_dump.jsonexport is no longer required:.\Rename-Domoticz-From-ZwaveJSON.ps1 -ZwaveJsUrl "https://your-host:8091" -DbPath "domoticz.db" -DryRun
-
-ZwaveJsTokenfor authenticated instances (https only; refused over http, since the token is a credential).-SkipCertificateCheckfor self-signed HTTPS. -
Read-only, and the fetch runs before any backup, so a failed fetch changes nothing.
ARM / Raspberry Pi support
- Replaced the PSSQLite module with Microsoft.Data.Sqlite + SQLitePCLRaw, provisioned by a new pinned, checksum-verified
setup.ps1that selects the native SQLite for your platform (linux-arm64,linux-arm,linux-x64,win-x64,osx-arm64, and more). The tool now runs natively on Raspberry Pi. - The SQLite data layer moved into a
DomoticzSqlitemodule with Pester tests. - Cross-platform database-in-use detection (Linux
/procscan, Windows exclusive-open, macOSlsof) replaces the previous Windows-only lock check and names the process holding the database.
Correctness
- Collision detection now checks a proposed name against the full end state (including devices that keep their name), so it can no longer silently create a duplicate.
Upgrade note
- Run
pwsh ./setup.ps1once per machine after updating: the SQLite engine is now vendored intolib/instead of relying on the PSSQLite PowerShell module.
v2.6 - Node-scoped rules
What's New
Node-scoped rules with nodeMatch
Rules can now include an optional nodeMatch object that restricts the rule to specific device types by matching Z-Wave node properties. All specified properties must match (AND logic). Rules without nodeMatch work exactly as before.
Available properties: productLabel, productDescription, manufacturer.
Example:
{
"name": "RGBW Red Channel",
"pattern": "38-2-currentValue$",
"replace": " - Current value$",
"with": " - Red",
"nodeMatch": { "productLabel": "FGRGBW" }
}Without nodeMatch, a rule targeting endpoint 2 would match every dimmer. With nodeMatch, it only applies to Fibaro RGBW controllers.
RGBW color channel rules
Added 8 rules for the Fibaro FGRGBW-442 that use nodeMatch to correctly name color channels:
- CC38 endpoints 2-5:
Red,Green,Blue,White - CC49 endpoints 6-9:
Voltage Red,Voltage Green,Voltage Blue,Voltage White
This eliminates all name collisions on RGBW controllers without affecting regular dimmers or blinds.
Validation
- Invalid regex in
nodeMatchvalues is caught at load time (exit 1 with clear error message) - Unknown property names in
nodeMatchproduce a console warning and are ignored - Empty
nodeMatchobjects and empty string values are treated as unset
Full Changelog: v2.5...v2.6
v2.5 - Usability pass
What's New
Consistent summary box
Summary fields now display in a stable, predictable order every run (was randomized due to a hashtable ordering bug).
Better log file defaults
Log file now defaults to the database folder with a timestamp in the filename (matching HTML report and undo script). Previously it went to the script directory without a timestamp, overwriting on every run.
Rules file error handling
When -RulesFile points to a malformed or missing file, the script now shows an error and exits instead of silently falling back to built-in defaults.
Auto-loading rules
rename_rules.json is now automatically loaded from the script directory when present and -RulesFile is not specified. This gives users the full 29-rule set (including switchType/customImage for smoke detectors, motion sensors, etc.) without needing to pass -RulesFile explicitly. Falls back to 7 built-in rules for standalone .ps1 downloads.
Smarter exit codes
Exit code now considers TypeChanged and ImageChanged in addition to Renamed. A run that only changes switch types no longer incorrectly reports "no changes needed."
Cleaner summary and log output
- Removed the non-actionable "Missing" count from the summary box (was showing thousands of expected Z-Wave config parameters that don't map to Domoticz devices).
- Consolidated thousands of individual MISSING log lines into a single summary line, reducing log size from ~5400 lines to ~1000.
Informed confirmation prompt
The confirmation prompt now appears after analysis and shows actual change counts (renames, type changes, image changes) instead of a raw value-entry count.
Full Changelog: v2.4...v2.5