Giter Club home page Giter Club logo

kiwiclient's Introduction

KiwiClient

This is a Python client for KiwiSDR. It allows you to:

  • Receive data streams with audio samples, IQ samples, and waterfall data
  • Issue commands to the KiwiSDR

Dependencies

Although the code has some backward compatibility with Python2 it is recommended you use Python3.

Make sure the Python package 'numpy' is installed.
On many Linux distributions the command would be similar to 'apt install python3-numpy'
On macOS try 'pip3 install numpy'

Demo code

The following demo programs are provided. Use the --help argument to see all program options.

  • kiwirecorder: Record audio to WAV files, with squelch. Option --wf prints various waterfall statistics.
    Adding option --wf-png records the waterfall as a PNG file. --help for more info.
  • kiwiwfrecorder: Specialty program. Saves waterfall data and GPS timestamps to .npy format file.
  • kiwifax: Decode radiofax and save as PNGs, with auto start, stop, and phasing.
  • kiwiclientd: Plays Kiwi audio on sound cards (real & virtual) for use by programs like fldigi and wsjtx. Implements hamlib rigctl network interface so the Kiwi freq & mode can be controlled by these programs.
  • kiwi_nc: Command line pipeline tool in the style of netcat. Example: stream IQ samples to dumphfdl.

The Makefile contains numerous examples of how to use these programs.

IS0KYB micro tools

Two utilities have been added to simplify the waterfall data acquisition/storage and data analysis. The SNR ratio (a la Pierre Ynard) is computed each time. There is now the possibility to change zoom level and offset frequency.

  • microkiwi_waterfall.py: launch this program with no filename and just the SNR will be computed, with a filename, the raw waterfall data is saved. Launch with --help to list all options.
  • waterfall_data_analysis.ipynb: this is a demo jupyther notebook to interactively analyze waterfall data. Easily transformable into a standalone python program.

The data is, at the moment, transferred in uncompressed format.

Guide to the code

kiwiclient.py

Base class for receiving websocket data from a KiwiSDR. It provides the following methods which can be used in derived classes:

  • _process_audio_samples(self, seq, samples, rssi): audio samples
  • _process_iq_samples(self, seq, samples, rssi, gps): IQ samples
  • _process_waterfall_samples(self, seq, samples): waterfall data

kiwirecorder.py

  • Can record audio data, IQ samples, and waterfall data (work in progress).
  • The complete list of options can be obtained by python kiwirecorder.py --help.
  • It is possible to record from more than one KiwiSDR simultaneously, see again --help.
  • For recording IQ samples there is the -w or --kiwi-wav option: this write a .wav file which includes GNSS timestamps (see below).
  • AGC options can be specified in a YAML-formatted file, --agc-yaml option, see default_agc.yaml. Note that this option needs PyYAML to be installed

IQ .wav files with GNSS timestamps

kiwirecorder.py configuration

  • Use the option -m iq --kiwi-wav --station=[name] for recording IQ samples with GNSS time stamps.
  • The resulting .wav files contains non-standard WAV chunks with GNSS timestamps.
  • If a directory with name gnss_pos/ exists, a text file gnss_pos/[name].txt will be created which contains latitude and longitude as provided by the KiwiSDR; existing files are overwritten.

Working with the recorded .wav files

  • There is an octave extension for reading such WAV files, see read_kiwi_wav.cc where the details of the non-standard WAV chunk can be found; it needs to be compiled in this way mkoctfile read_kiwi_wav.cc.
  • For using read_kiwi_wav an octave function proc_kiwi_iq_wav.m is provided; type help proc_kiwi_iq_wav in octave for documentation.

kiwiclient's People

Contributors

aidanmontare avatar dev-zzo avatar hcab14 avatar jks-prv avatar mcogoni avatar rikvanriel avatar szpajder avatar yesand92 avatar

kiwiclient's Issues

kiwiclientd.py failed to run

Hi Rik,

I wanted to use your kiwiclientd.py script for listening without a browser.
I'm using Manjaro linux 20.2.1 with Python 3.9 installed.
The kiwiclient repository is cloned into the home directory.

When I run kiwiclientd.py with just server name, port, frequency and a mode it throws an error:

$ kiwiclient/kiwiclientd.py -s kiwi.24x7.hk -p 8073 -f 10000 -m usb 
/home/user1/kiwiclient/kiwiclientd.py:134: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if self._options.resample is 0:
Traceback (most recent call last):
  File "/home/user1/kiwiclient/kiwiclientd.py", line 433, in <module>
    main()
  File "/home/user1/kiwiclient/kiwiclientd.py", line 405, in main
    snd_recorders.append(KiwiWorker(args=(KiwiSoundRecorder(opt),opt,run_event)))
  File "/home/user1/kiwiclient/kiwi/worker.py", line 18, in __init__
    self._rigctld = Rigctld(self._recorder, self._options.rigctl_port, self._options.rigctl_address)
  File "/home/user1/kiwiclient/kiwi/rigctld.py", line 75, in __init__
    s.bind(addr)
TypeError: an integer is required (got type str)

I'm a complete idiot in Python, and my thoughts were that it throws an error because rigctl ports are not specified as in example. I added rigctl ports and now the error is different:

$ kiwiclient/kiwiclientd.py -s kiwi.24x7.hk -p 8073 -f 10000 -m usb --rigctl-port 6400,6401 /home/user1/kiwiclient/kiwiclientd.py:134: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if self._options.resample is 0:
Traceback (most recent call last):
  File "/home/user1/kiwiclient/kiwi/worker.py", line 42, in run
    self._recorder.open()
  File "/home/user1/kiwiclient/kiwi/client.py", line 506, in open
    self._set_auth('kiwi', self._options.password, self._options.tlimit_password)
  File "/home/user1/kiwiclient/kiwi/client.py", line 173, in _set_auth
    self._send_message('SET auth t=%s p=%s' % (client_type, password))
  File "/home/user1/kiwiclient/kiwi/client.py", line 163, in _send_message
    self._stream.send_message(msg)
  File "/home/user1/kiwiclient/mod_pywebsocket/_stream_hybi.py", line 523, in send_message
    self._write(self._writer.build(message, end, binary))
  File "/home/user1/kiwiclient/mod_pywebsocket/_stream_hybi.py", line 343, in build
    return create_text_frame(
  File "/home/user1/kiwiclient/mod_pywebsocket/_stream_hybi.py", line 165, in create_text_frame
    return create_binary_frame(encoded_message, opcode, fin, mask,
  File "/home/user1/kiwiclient/mod_pywebsocket/_stream_hybi.py", line 157, in create_binary_frame
    return _filter_and_format_frame_object(frame, mask, frame_filters)
  File "/home/user1/kiwiclient/mod_pywebsocket/_stream_hybi.py", line 149, in _filter_and_format_frame_object
    return _build_frame(header, frame.payload, mask)
  File "/home/user1/kiwiclient/mod_pywebsocket/_stream_hybi.py", line 139, in _build_frame
    return header + masking_nonce + masker.mask(body)
  File "/home/user1/kiwiclient/mod_pywebsocket/util.py", line 201, in _mask_using_array
    result.fromstring(bytes(s))
AttributeError: 'array.array' object has no attribute 'fromstring'
2021-01-30 22:29:35,618 pid 70739 websocket close: "'array.array' object has no attribute 'fromstring'"
Traceback (most recent call last):
  File "/home/user1/kiwiclient/kiwi/worker.py", line 42, in run
    self._recorder.open()
  File "/home/user1/kiwiclient/kiwi/client.py", line 506, in open
    self._set_auth('kiwi', self._options.password, self._options.tlimit_password)
  File "/home/user1/kiwiclient/kiwi/client.py", line 173, in _set_auth
    self._send_message('SET auth t=%s p=%s' % (client_type, password))
  File "/home/user1/kiwiclient/kiwi/client.py", line 163, in _send_message
    self._stream.send_message(msg)
  File "/home/user1/kiwiclient/mod_pywebsocket/_stream_hybi.py", line 523, in send_message
    self._write(self._writer.build(message, end, binary))
  File "/home/user1/kiwiclient/mod_pywebsocket/_stream_hybi.py", line 343, in build
    return create_text_frame(
  File "/home/user1/kiwiclient/mod_pywebsocket/_stream_hybi.py", line 165, in create_text_frame
    return create_binary_frame(encoded_message, opcode, fin, mask,
  File "/home/user1/kiwiclient/mod_pywebsocket/_stream_hybi.py", line 157, in create_binary_frame
    return _filter_and_format_frame_object(frame, mask, frame_filters)
  File "/home/user1/kiwiclient/mod_pywebsocket/_stream_hybi.py", line 149, in _filter_and_format_frame_object
    return _build_frame(header, frame.payload, mask)
  File "/home/user1/kiwiclient/mod_pywebsocket/_stream_hybi.py", line 139, in _build_frame
    return header + masking_nonce + masker.mask(body)
  File "/home/user1/kiwiclient/mod_pywebsocket/util.py", line 201, in _mask_using_array
    result.fromstring(bytes(s))
AttributeError: 'array.array' object has no attribute 'fromstring'
2021-01-30 22:29:35,627 pid 70739 websocket close: "'array.array' object has no attribute 'fromstring'"

Can you suggest, what's wrong with my invocation of kiwiclientd.py?

Thanks,
Ivan

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.