substation.osc_sender
The API reference for OscEventSender.
OscEventSender
class OscEventSender(
host: str | None = '127.0.0.1',
port: int = 9000,
sampler_host: str | None = None,
sampler_port: int = 9002,
)
Send the scanner's events as OSC messages, to a sequencer and, optionally, a sampler.
osc = substation.osc_sender.OscEventSender(
host="127.0.0.1", port=9000,
sampler_host="127.0.0.1", sampler_port=9002,
)
osc.attach(scanner)
The messages it sends:
/radio/state, to the sequencer when a radio channel turns ON or OFF:band_name(str),channel_index(int),is_active(int, 1 or 0),snr_db(float),ctcss_hz(float),dcs_code(int)./radio/recording, to the sequencer when a recording is saved:band_name(str),channel_index(int),file_path(str),ctcss_hz(float),dcs_code(int)./sample/import, to the sampler when a recording is saved:file_path(str), the recording's full path on this computer.
A sequencer receives nothing when host is None, and a sampler receives
nothing unless sampler_host is set.
ctcss_hz and dcs_code carry any subaudible tone detected on the
activation. OSC has no null, so 0.0 and 0 mean that no tone was detected:
CTCSS tones start at 67 Hz, and no DCS code is 0. A DCS code is octal,
and dcs_code is its integer value, so DCS 023 arrives as 19; format it in
octal, as f"{dcs_code:03o}", to show it as a radio does. Tone detection
has not yet been thoroughly tested with real radios.
Each message goes over UDP without waiting for a reply. A send that fails, such as one to a host that cannot be reached, is logged as a warning and never stops the scan.
A scanner builds a sender of its own when its configuration's osc
settings turn sending on, so a script needs this class only to send
somewhere those settings do not.
Set up the sender, opening a UDP client for each receiver.
Parameters
host: The sequencer's host name or IP address. The default, localhost, suits Subsequence running on the same machine. None sends nothing to a sequencer, for a sampler alone.port: The sequencer's UDP port, used only whenhostis set. The default is Subsequence's.sampler_host: The sampler's host name or IP address. When it is set, each saved recording is also sent to it as/sample/import, so the sampler can import the file. None sends nothing to a sampler.sampler_port: The sampler's UDP port, used only whensampler_hostis set. The default is Subsample's.
Raises
OSError: A host name cannot be found.
Members: attach, on_recording_saved, on_state_change
OscEventSender.on_state_change
OscEventSender.on_state_change(
band_name: str,
channel_index: int,
is_active: bool,
snr_db: float,
ctcss_hz: float | None = None,
dcs_code: int | None = None,
) -> None
Send /radio/state to the sequencer: the handler for channel_state
that attach() subscribes.
The message's arguments are band_name, channel_index, is_active as
1 or 0, snr_db, ctcss_hz and dcs_code, with 0.0 and 0 for no tone.
Nothing is sent when the sender has no sequencer.
It runs on the scanner's event loop, so it returns quickly. A failed send is caught and logged; anything else is a fault in Substation, and reaches the scanner, which logs it with its traceback.
Parameters
band_name: The band's name.channel_index: The radio channel's index in the band.is_active: Whether the radio channel turned ON.snr_db: The radio channel's signal-to-noise ratio, in dB.ctcss_hz: The CTCSS tone detected, in Hz, or None.dcs_code: The DCS code detected, as its integer value, or None.
OscEventSender.on_recording_saved
OscEventSender.on_recording_saved(
band_name: str,
channel_index: int,
file_path: str,
ctcss_hz: float | None = None,
dcs_code: int | None = None,
) -> None
Send /radio/recording to the sequencer, and /sample/import to the
sampler, to each that the sender has: the handler for recording_saved
that attach() subscribes.
/radio/recording's arguments are band_name, channel_index,
file_path, ctcss_hz and dcs_code, with 0.0 and 0 for no tone.
/sample/import carries only file_path; the sampler can read a tone from
the recording's metadata.
It runs on the scanner's event loop.
Parameters
band_name: The band's name.channel_index: The radio channel's index in the band.file_path: The saved recording.ctcss_hz: The CTCSS tone detected during the activation, in Hz, or None.dcs_code: The DCS code detected, as its integer value, or None.
OscEventSender.attach
OscEventSender.attach(scanner: substation.scanner.RadioScanner) -> None
Subscribe this sender to a scanner's channel_state and
recording_saved events, so each is sent as it happens.
Parameters
scanner: The scanner to send events from.