Skip to content

fix: restart zmcontrol.pl when a monitor is edited through the API - #5205

Merged
connortechnology merged 1 commit into
ZoneMinder:masterfrom
nabbi:fix/b7-api-edit-zmcontrol
Oct 11, 2026
Merged

connortechnology merged 1 commit into
ZoneMinder:masterfrom
nabbi:fix/b7-api-edit-zmcontrol

Conversation

@nabbi

@nabbi nabbi commented Oct 11, 2026

Copy link
Copy Markdown
Contributor

Automated PR, tested in a zm-holodeck sandbox. An AI agent (Claude Opus 5.5) reproduced the bug on a disposable ZoneMinder built from upstream master 6c0f976c2, wrote this fix and ran the checks below on the same lab. Minimal human review before opening: please review it as you would any contributor's PR.

TL;DR

  • Fixes: API monitor edit doesn't restart zmcontrol.pl, so PTZ keeps the old camera settings #5204: an API monitor edit doesn't restart zmcontrol.pl, so PTZ keeps the old camera settings.
  • Change: the API's edit() stops and starts the monitor's daemons through ZM\Monitor, the same way the console save does, so zmcontrol.pl is restarted too and the commands reach the monitor's own server. 1 file, +20/-7.
  • Risk: every API monitor edit goes through this path. The edit's response is unchanged ({"message":"Saved"}). Checked on one and two nodes, with the API contract tests and the client suites.
  • Tested: reproduced before, passes after (single and two-node probes); script tests, smoke, contract and clients as on master.
Details: change, behaviour changes, checks

Before

Upstream master 6c0f976c2: ControlAddress changed through the API to a wrong password, then PTZ: zmcontrol.pl pid 593 (then 593); camera saw [... 200, ... 200]: the old process, still logging in with the old password.

Change

  • web/api/app/Controller/MonitorsController.php edit(): before saving, a ZM\Monitor for the old row stops zmc and, if it was controllable, zmcontrol.pl; after saving, a ZM\Monitor from the saved row starts them unless Capturing is None, or the monitor is a WebSite or Deleted, the same rules as includes/actions/monitor.php.
  • Test: none in the API unit tests (it needs running daemons); covered by the lab probes below.

Behaviour changes

Change Who sees it Intended / collateral Alternatives looked into Chosen, why Tested by
An API edit of a controllable monitor also restarts zmcontrol.pl API clients (HA, zmNinjaNg, scripts) intended restart only when Control fields change same as the console single-node probe
An edit sent to another node restarts the daemons on the monitor's own server multi-server installs intended — ZM\Monitor already routes by server two-node probe
Deleted and WebSite monitors are no longer started by an API edit nobody in practice collateral, matches the console — — smoke

After

Branch at 88cc49e34 (base 6c0f976c2).

Check Result
Single node, wrong password set through the API zmcontrol.pl pid 508 (then 508); camera saw [401 x6]: PASS (a new process, using the new settings)
zmc restart zmc 282 → 646, zmcontrol.pl 650, Connected: PASS
Two nodes, edit via zm1 for a zm2 monitor zm2 zmc 292 → 502, zmcontrol.pl 440 → 506, PTZ [401 x6]: PASS
holodeck checks script tests PASS=28; smoke PASS=11 XFAIL=1 (known); contract 522 passed, 30 errors (the same 30 on master: baseline drift from schema changes, not this diff)
clients pyzmNg 61 passed / 4 skipped; ha-zoneminder 20 passed / 1 skipped; zmNinjaNg 18 passed, 1 xpass

Not run: release-1.38 (same code; the patch applies with git am -3), resilience.

Possible follow-ups

Offered for discussion, not part of this change:

  • monitors/daemonControl for another server's monitor answers 200 status: ok and does nothing (it logs an error; Model/Monitor.php:195-198, MonitorsController.php:493-503). Options: answer 400 naming the monitor's server, or forward the request to it. Benefit: callers learn the command didn't run. Risk: an API answer changes; ZoneMinder's own callers already target the right server, and of the known clients only zmNinjaNg calls daemon control, through host/daemonControl. A lab-tested 400 version exists; it would be its own PR with a release note.

refs #5204

🤖 Generated with Claude Code

MonitorsController::edit() restarted zmc through the CakePHP model but
left the monitor's control server running. zmcontrol.pl reads
ControlAddress, ControlDevice and the Control when it starts, so after
an API edit PTZ kept using the old values: a camera password changed
through the API kept failing PTZ with 401 until zmcontrol.pl was
restarted by hand.

Restart the daemons the way the console's save does
(includes/actions/monitor.php), through ZM\Monitor: stop zmc and, for a
controllable monitor, zmcontrol.pl; start them again from the saved row
unless the monitor does not capture, is a WebSite or is deleted.
ZM\Monitor also sends the commands to the monitor's own server in a
multi-server setup, where the model's daemonControl() logged an error and
did nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@connortechnology
connortechnology merged commit 25dba32 into ZoneMinder:master Oct 11, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants