Skip to content

Troubleshooting

stevenboyd78 edited this page Aug 10, 2026 · 5 revisions

Troubleshooting

Important

This page provides common diagnostic steps. The repository documentation and current command help are authoritative for exact options and behavior.

Collect the environment first

Record the software and scanner context before changing the system:

sdsctl --version
python --version
uname -a

For an SDS200 Ethernet connection:

sdsctl --host SCANNER_IP health
sdsctl -vv --host SCANNER_IP scanner-info

Include the scanner model and firmware reported by:

sdsctl --host SCANNER_IP info

USB scanner is not discovered

Inspect 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 \
  info

SDS200 Ethernet discovery fails

Search only the directly relevant authorized network:

sdsctl discover \
  --network 192.168.0.0/24 \
  --network-only

Then test the known address directly:

sdsctl --host SCANNER_IP info
sdsctl --host SCANNER_IP health

Confirm 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-run

Remove --dry-run only after reviewing the proposed repair.

TUI reports stale PSI data

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 tui

Read 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.

SDS200 network audio will not start

Stop other processes that may already own an SDS200 RTSP/RTP audio session. Examples include:

  • another sdsctl audio process;
  • 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 10

Review the canonical network audio guide for transport behavior, reliability counters, Broadcastify, and Asterisk configuration.

Local playback fails

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 10

If recording succeeds but --play fails, capture the complete playback error, operating system, audio backend, and selected output device.

Broadcastify-compatible encoding fails

Confirm that FFmpeg and libmp3lame are available:

ffmpeg -version | head -n 1
ffmpeg -hide_banner -encoders 2>/dev/null | grep -F libmp3lame

Keep 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.

Asterisk Music-on-Hold source fails

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 sdsctl executable;
  • 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.

Daemon or web dashboard will not start

First confirm that the foreground daemon is healthy:

sdsctl daemon-client status

The 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 web

The 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.

Home Assistant App problems

Repository is not visible

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.

App does not start

Confirm:

  • scanner_host contains the reachable SDS200 LAN hostname or address;
  • any custom recording_directory is 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 50000 is available.

The App intentionally fails startup rather than persisting the Supervisor MQTT password or silently weakening an unsupported MQTT transport configuration.

Scanner state works but audio stays buffering

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.

Recordings are not visible through Samba or SSH

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.

MQTT Discovery entities or scanner controls are missing

Confirm Home Assistant's MQTT integration is active and inspect the App log for MQTT service or broker connection errors. The current SDS200 device contains seventeen Discovery components: ten state/diagnostic components plus four Hold switches and Previous Channel, Next Channel, and Reconnect Scanner buttons.

The seven controls use dedicated QoS 0 non-retained Home Assistant topics. The App intentionally keeps the independent generic daemon MQTT <mqtt_topic_prefix>/commands request-envelope input disabled.

If a Hold switch is unavailable, confirm the scanner is connected and that the corresponding authoritative hold field is meaningful for the current scanner state. Previous/Next are available only for a current documented TGID or conventional-frequency channel with a valid scanner index. Reconnect remains subject to the daemon's transport capability check.

SDS200 Lovelace card is missing

Confirm the App log did not report a card-installation warning and verify /local/sds200/sds200-card.js is registered under Settings > Dashboards > Resources as a JavaScript Module. If the App created Home Assistant's www directory for the first time, restart Home Assistant Core once before registering the resource.

After registration, SDS200 Scanner should appear in the card picker. The card is intentionally read-only; scanner controls are separate standard Home Assistant switch and button entities.

Capture detailed diagnostics

Operational logs exclude raw scanner traffic by default:

sdsctl --log-level DEBUG --host SCANNER_IP monitor

Create a protocol trace only when needed:

sdsctl --trace scanner.trace --host SCANNER_IP monitor

Traces and captures can contain scanner names, channel names, unit identifiers, and network addresses. Review and sanitize them before sharing.

Open a useful issue

Before opening an issue:

  1. Test the latest code from the default branch.
  2. Search existing issues.
  3. Run sdsctl health for the affected connection.
  4. 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.

Clone this wiki locally