Skip to content

Add module check image settings on a real device - #154

Open
baylanger wants to merge 10 commits into
mezz64:masterfrom
baylanger:tool-live_image_check
Open

baylanger wants to merge 10 commits into
mezz64:masterfrom
baylanger:tool-live_image_check

Conversation

@baylanger

@baylanger baylanger commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

Add python -m pyhik check

A check to run by hand against a real camera or NVR. Unit tests have to run
without hardware. This is for people with a device who want to try the
image settings code or report a problem.

python -m pyhik <command> is a small dispatcher (pyhik/__main__.py) that imports a
command only when it is asked for. check is the first command, so others (for example
dump) can be added later.

Run

export CAMERA_HOST=192.168.1.100
export CAMERA_USERNAME=admin
export CAMERA_PASSWORD='passwd123'
python -m pyhik check

Optional: CAMERA_PORT (80, or 443 with HTTPS), CAMERA_SSL=1, CAMERA_VERIFY_SSL=0 for a
self-signed certificate. --host, --port, --username, --ssl and --no-verify do the same as
CAMERA_HOST, CAMERA_PORT, CAMERA_USERNAME, CAMERA_SSL=1 and CAMERA_VERIFY_SSL=0, and win over
them. The password is read only from the environment, never from the command line, and never printed.

What it does

Command Effect
python -m pyhik check Read-only. Lists channels and every image setting with its path and value.
... --write Changes Color/brightnessLevel by one step, reads it back, restores it.
... --write --path Color/contrastLevel Same, for the setting you choose: take its path from the read-only list. A number moves one step, a switch flips (true to false or false to true) and a select takes the first option that is not the current one. --path is only used with --write.
... --conflicts WDR / HLC / BLC / defog conflict matrix.
... --bad-password A wrong password, tried through ISAPIClient and HikCamera: at least two failed logins.
... --all All of the above.
... -v Also shows pyhik's debug log (the retries).

A plain --write ends by naming a few switch and select paths to try with --path. If a change
switches another setting off to make room (WDR, BLC, HLC and defog exclude each other), that setting
is put back too and listed.

One channel is checked per run (the first listed unless --channel is
given). On an NVR or DVR the attached camera is used through the ImageProxy
endpoints:

python -m pyhik check --channel 3 --write --path Color/contrastLevel
python -m pyhik check --channel 1 --write --path enableImageLossDetection

The NVR is detected from the device type. That is not enough on its own: some NVRs report
IPC, and the device information may not be readable at all. When the camera image endpoints fail
and the NVR ones work, the NVR endpoints are used, and it prints which it chose and why.
--proxy / --no-proxy override the detection.

The device information is asked once per run, whether it answers or not. When it fails, the device
line shows the error with its HTTP status (for example
model=? (ISAPIError: Request failed with status 503)) and the run goes on.

Safety

  • Everything that changes a value puts the original back afterwards, even
    after an error, and prints NOT RESTORED, set it back by hand if it
    could not.
  • It stops at the first authentication error, since repeated failures can
    lock an account. --bad-password makes at least two failed logins (one per
    client, more if a client retries); do not use it on an account that is close
    to being locked.

Tested

Unit tests (test/test_check.py) cover the NVR detection, the write path (number, switch, select, a conflict, a failed restore), the connection options (host, port, username, HTTPS, certificate check) and the python -m pyhik dispatch, with fake devices.
On real camera DS-2CD2385G1
On a DS-7608NI-EV2/8P NVR (V3.4.96): 8 channels listed, a read, and a write of a switch
(enableImageLossDetection) through ImageProxy with the read back and the restore both
checked.

Dependencies

[ ] Requires #151 (PR4 List image channels and support NVR-attached cameras through ImageProxy) to be merged first.

Unit tests can't tell us how a given camera or NVR behaves; this script
runs the image settings code against real hardware and prints a short
PASS/FAIL report that can be pasted into a bug report.

Read-only by default: lists the channels, every image setting with its
path and current value, and the device type.

Options that change something (only numeric settings) put the original
value back afterwards, will report on an error.

  --write           change one numeric setting by one step (default
                    Color/brightnessLevel, or pick one with --path) and
                    read it back
  --conflicts       WDR / HLC / BLC / defog conflict matrix
  --bad-password    tries one login with a wrong password
  --all             everything above

An NVR or DVR is detected from the device type and its attached cameras
are used through the ImageProxy endpoints (--proxy / --no-proxy override
this, --channel selects the camera).
NVR or DVR still turns the proxy on straight away.

For any other type, the script tries the camera image endpoints.
If they fail with a plain ISAPIError, such as the 503 and 400,
it tries the proxy endpoints.

If those list channels, it prints camera image endpoints failed (...);
trying the proxy endpoints.
Some recorders (ex. DS-7608NI-EV2/8P V3.4.96) report the type of a
camera - or fail the device information request altogether - and
answer for the camera image endpoints w/ 503 serviceUnavailable.

Auto-detection gave up when the device type could not be read;
the read-only run failed even though --proxy passed.

fix - Read the device type if possible but do not depend on it:
unless it says NVR or DVR, try the camera image endpoints and
if they fail with a device error (not a rejected login or a conn
err), try the proxy endpoints before giving up.
@baylanger
baylanger force-pushed the tool-live_image_check branch from 24d641d to c6b1967 Compare November 7, 2026 19:07
@baylanger baylanger changed the title Add tools/live_image_check.py to check image settings on a real device Add module check image settings on a real device Nov 11, 2026

@mezz64 mezz64 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I'm onboard with adding this, but considering the ISAPI functionality is only a subset of what pyHik can do, I don't know that the path should be simply called "check" as i'd expect that to check the basic event stream functionality. I think this is better suited as "checkiaspi" or something similar so a separate module can be added later to perform the same function on the base event stream monitoring code.

Also, the readme changes need cleaned up now that #151 is merged and I'd prefer you split out the xmldict change into a separate PR.

Otherwise a review flagged a couple small issues:

  • An error during the restore step in check_write can hide the original error, and the restore keeps sending requests after an auth error.
  • The restore writes back every value that changed, not just the ones in result.also_changed.
  • TESTING.md says cd pyhik; it should be cd pyHik.

This branch has not been deployed

No deployments
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