-
Notifications
You must be signed in to change notification settings - Fork 1
Troubleshooting
Important
This page provides common diagnostic steps. The repository documentation and current command help are authoritative for exact options and behavior.
Record the software and scanner context before changing the system:
sdsctl --version
python --version
uname -aFor an SDS200 Ethernet connection:
sdsctl --host SCANNER_IP health
sdsctl -vv --host SCANNER_IP scanner-infoInclude the scanner model and firmware reported by:
sdsctl --host SCANNER_IP infoInspect stable Linux serial-device paths:
ls -l /dev/serial/by-id/Check whether the current user can read and write the resolved device:
test -r /dev/ttyACM0 && test -w /dev/ttyACM0 \
&& echo "Scanner is accessible" \
|| echo "Scanner is not accessible"Use the project's optional udev rule when the device exists but the active user lacks access. Do not solve the problem by making the serial device globally writable.
Select a scanner explicitly when several devices are attached:
sdsctl --model SDS100 info
sdsctl --model SDS150 --port /dev/ttyACM0 info
sdsctl --model SDS200 \
--port /dev/serial/by-id/SCANNER_DEVICE \
infoSearch only the directly relevant authorized network:
sdsctl discover \
--network 192.168.0.0/24 \
--network-onlyThen test the known address directly:
sdsctl --host SCANNER_IP info
sdsctl --host SCANNER_IP healthConfirm that:
- the scanner and host are on reachable local networks;
- the scanner's Ethernet features are enabled;
- local firewall policy permits the SDS200 control and audio traffic;
- the address has not changed since a profile was saved.
Repair a stale profile through authorized discovery:
sdsctl profile repair PROFILE_NAME \
--network 192.168.0.0/24 \
--dry-runRemove --dry-run only after reviewing the proposed repair.
The Textual TUI can warn about stale scanner-information updates and perform a rate-limited control reconnect. Enable informational logging to see the lifecycle:
sdsctl --log-level INFO --host SCANNER_IP tuiRead the canonical operational logging guide for expected recovery entries and configuration options.
SDS200 control recovery is independent from an active RTSP/RTP audio session, so an ongoing WAV recording should not be stopped by PSI recovery.
Stop other processes that may already own an SDS200 RTSP/RTP audio session. Examples include:
- another
sdsctl audioprocess; - a TUI session with active network audio;
- an Asterisk custom Music-on-Hold source;
- a validation or integration process.
Then retry a minimal recording:
sdsctl --host SCANNER_IP audio \
--output /tmp/scanner-test.wav \
--duration 10Review the canonical network audio guide for transport behavior, reliability counters, Broadcastify, and Asterisk configuration.
Confirm that the playback extra is installed in the active environment:
python -m pip install "sds200[playback]"Test recording without playback to distinguish an RTSP/RTP problem from a local PortAudio problem:
sdsctl --host SCANNER_IP audio \
--output /tmp/scanner-test.wav \
--duration 10If recording succeeds but --play fails, capture the complete playback error,
operating system, audio backend, and selected output device.
Confirm that FFmpeg and libmp3lame are available:
ffmpeg -version | head -n 1
ffmpeg -hide_banner -encoders 2>/dev/null | grep -F libmp3lameKeep source passwords out of command history and logs. Supply secrets through the documented environment-backed secret mechanism. Never attach an unredacted environment listing or Icecast authorization header to an issue.
Production Broadcastify testing requires an approved feed and the assigned Technicals settings.
Verify that Asterisk can see the custom class:
sudo asterisk -rx "module show like res_musiconhold"
sudo asterisk -rx "moh show classes"Use:
- an absolute path to the installed
sdsctlexecutable; - a profile readable by the Asterisk service account;
-
format=slin; - process-group termination for the custom source.
Inspect service logs with the system's normal journal tooling. Do not place a required executable or profile under a home directory the service account cannot traverse.
The canonical configuration is in the network audio guide.
First confirm that the foreground daemon is healthy:
sdsctl daemon-client statusThe normal daemon owns four private local services: daemon.sock,
events.sock, pcmu.sock, and recordings.sock. A daemon-backed client must
run with filesystem permission to connect to the required sockets. Do not make
the socket directory or socket files world-writable to work around an ownership
problem.
If the daemon is healthy but the browser service fails, run the loopback web service directly and review its sanitized error:
sdsctl webThe standalone sdsctl web service binds only to localhost or an explicit
loopback address. Wildcard, LAN, and public standalone binds remain intentionally
rejected until authentication and transport-security support exists. The Home
Assistant App uses a separate explicit Ingress mode and does not publish the
dashboard port directly to the LAN.
See the canonical web dashboard guide and daemon deployment guide for exact socket paths, permissions, and service behavior.
After adding https://github.com/stevenboyd78/sds200-python under
Settings > Apps > App store > Repositories, refresh the browser. If the
repository still does not appear, inspect the Supervisor log under
Settings > System > Logs for repository or App configuration errors.
Confirm:
-
scanner_hostcontains the reachable SDS200 LAN hostname or address; - any custom
recording_directoryis a relative path below/media; - the Home Assistant MQTT service is available;
- the App log does not report an unsupported TLS-enabled MQTT service; and
- host UDP
50000is available.
The App intentionally fails startup rather than persisting the Supervisor MQTT password or silently weakening an unsupported MQTT transport configuration.
Start a daemon-owned recording from the dashboard and watch its packet and sample
counters. If both remain at zero, verify the App Network configuration maps
50000/udp to host UDP 50000 and confirm the scanner can route RTP to the Home
Assistant host.
If recording packets advance but live Browser Audio is silent, verify saved recording playback plus browser, tab, and system audio output before changing the RTP mapping. Live Browser Audio uses Web Audio, while finalized recordings use the browser's native media playback path, so a browser audio-service problem can affect only the live path.
The default recording library is /media/sdsctl/recordings, not the legacy
/data/recordings path. A custom recording_directory is also relative to
/media. Confirm the Samba or SSH service being used exposes Home Assistant
media storage.
When upgrading from v0.20.0, the App migrates the legacy recording tree during startup. A differing destination file stops migration rather than being overwritten; inspect the App log and resolve the conflict deliberately.
Confirm Home Assistant's MQTT integration is active and inspect the App log for MQTT service or broker connection errors. The App publishes ten read-only Discovery entities and does not enable semantic MQTT command subscriptions.
Operational logs exclude raw scanner traffic by default:
sdsctl --log-level DEBUG --host SCANNER_IP monitorCreate a protocol trace only when needed:
sdsctl --trace scanner.trace --host SCANNER_IP monitorTraces and captures can contain scanner names, channel names, unit identifiers, and network addresses. Review and sanitize them before sharing.
Before opening an issue:
- Test the latest code from the default branch.
- Search existing issues.
- Run
sdsctl healthfor the affected connection. - Capture a minimal reproducible command and complete error.
Include:
- installed package version or commit;
- Python and operating-system versions;
- scanner model and firmware;
- USB or Ethernet transport;
- exact command;
- complete sanitized error or traceback;
- minimal reproduction steps;
- whether another supported transport behaves differently.
See the repository support policy and GitHub Issues.