not1mm 25.6.10__tar.gz → 25.6.11.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {not1mm-25.6.10 → not1mm-25.6.11.1}/PKG-INFO +17 -3
- {not1mm-25.6.10 → not1mm-25.6.11.1}/README.md +16 -2
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/__main__.py +45 -2
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/main.ui +12 -0
- not1mm-25.6.11.1/not1mm/data/map3.png +0 -0
- not1mm-25.6.11.1/not1mm/data/rotator.ui +144 -0
- not1mm-25.6.11.1/not1mm/lib/rot_interface.py +101 -0
- not1mm-25.6.11.1/not1mm/lib/version.py +3 -0
- not1mm-25.6.11.1/not1mm/rotator.py +323 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm.egg-info/PKG-INFO +17 -3
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm.egg-info/SOURCES.txt +4 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/pyproject.toml +1 -1
- not1mm-25.6.10/not1mm/lib/version.py +0 -3
- {not1mm-25.6.10 → not1mm-25.6.11.1}/LICENSE +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/__init__.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/bandmap.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/checkwindow.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/JetBrainsMono-Thin.ttf +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/MASTER.SCP +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/about.ui +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/alpha bravo charlie delta.txt +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/bandmap.ui +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/check.png +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/checkwindow.ui +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/cloud_green.png +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/cloud_red.png +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/configuration.ui +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/contests.sql +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/cty.json +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/cwmacros.txt +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/donors.html +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/dxcc_tracker.ui +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/editcontact.ui +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/editmacro.ui +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/greendot.png +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/k6gte-not1mm.desktop +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/k6gte.not1mm-128.png +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/k6gte.not1mm-32.png +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/k6gte.not1mm-64.png +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/logwindow.ui +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/logwindowx.ui +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/new_contest.ui +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/not1mm.html +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/opon.ui +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/0.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/1.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/2.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/3.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/4.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/5.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/6.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/7.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/73.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/8.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/9.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/a.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/again.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/b.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/c.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/contest.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/cq.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/cq2.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/d.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/e.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/f.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/g.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/h.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/i.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/j.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/k.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/k6gte.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/l.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/m.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/mynumber.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/n.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/nil.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/o.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/p.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/q.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/r.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/roger.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/s.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/space.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/t.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/thankyou.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/thankyouqrz.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/u.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/v.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/w.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/x.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/y.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/yourcall.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/phonetics/z.wav +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/pickcontest.ui +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/radio_green.png +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/radio_grey.png +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/radio_red.png +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/ratewindow.ui +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/reddot.png +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/rttymacros.txt +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/settings.ui +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/splash.png +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/ssbmacros.txt +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/statistics.ui +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/data/vfo.ui +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/dxcc_tracker.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/fsutils.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/__init__.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/about.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/cat_interface.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/cwinterface.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/database.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/edit_contact.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/edit_macro.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/edit_opon.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/edit_station.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/fldigi_sendstring.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/ft8_watcher.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/ham_utility.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/lookup.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/multicast.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/n1mm.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/new_contest.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/plugin_common.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/select_contest.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/settings.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/super_check_partial.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lib/versiontest.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/logwindow.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/lookupservice.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/10_10_fall_cw.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/10_10_spring_cw.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/10_10_summer_phone.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/10_10_winter_phone.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/__init__.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/ari_40_80.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/ari_dx.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/arrl_10m.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/arrl_160m.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/arrl_dx_cw.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/arrl_dx_ssb.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/arrl_field_day.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/arrl_rtty_ru.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/arrl_ss_cw.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/arrl_ss_phone.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/arrl_vhf_jan.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/arrl_vhf_jun.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/arrl_vhf_sep.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/canada_day.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/cq_160_cw.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/cq_160_ssb.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/cq_wpx_cw.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/cq_wpx_rtty.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/cq_wpx_ssb.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/cq_ww_cw.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/cq_ww_rtty.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/cq_ww_ssb.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/cwt.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/darc_vhf.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/darc_xmas.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/ea_majistad_cw.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/ea_majistad_ssb.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/ea_rtty.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/es_field_day.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/es_open.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/general_logging.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/helvetia.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/iaru_fieldday_r1_cw.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/iaru_fieldday_r1_ssb.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/iaru_hf.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/icwc_mst.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/jidx_cw.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/jidx_ph.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/k1usn_sst.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/labre_rs_digi.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/lz-dx.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/naqp_cw.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/naqp_rtty.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/naqp_ssb.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/phone_weekly_test.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/raem.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/randomgram.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/ref_cw.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/ref_ssb.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/sac_cw.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/sac_ssb.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/spdx.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/stew_perry_topband.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/ukeidx.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/vhf_sprint.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/weekly_rtty.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/plugins/winter_field_day.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/radio.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/ratewindow.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/rtc_service.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/statistics.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/test.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/vfo.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm/voice_keying.py +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm.egg-info/dependency_links.txt +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm.egg-info/entry_points.txt +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm.egg-info/requires.txt +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/not1mm.egg-info/top_level.txt +0 -0
- {not1mm-25.6.10 → not1mm-25.6.11.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: not1mm
|
3
|
-
Version: 25.6.
|
3
|
+
Version: 25.6.11.1
|
4
4
|
Summary: NOT1MM Logger
|
5
5
|
Author-email: Michael Bridak <michael.bridak@gmail.com>
|
6
6
|
License: GPL-3.0-or-later
|
@@ -108,6 +108,7 @@ Dynamic: license-file
|
|
108
108
|
- [The Check Partial Window](#the-check-partial-window)
|
109
109
|
- [The Rate Window](#the-rate-window)
|
110
110
|
- [The DXCC window](#the-dxcc-window)
|
111
|
+
- [The Rotator Window (Work In Progress)](#the-rotator-window-work-in-progress)
|
111
112
|
- [The Remote VFO Window](#the-remote-vfo-window)
|
112
113
|
- [Cabrillo](#cabrillo)
|
113
114
|
- [ADIF](#adif)
|
@@ -245,6 +246,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
245
246
|
|
246
247
|
## Recent Changes
|
247
248
|
|
249
|
+
- [25-6-11] Added a rotator control widget.
|
248
250
|
- [25-6-10] Merged PR from @dj1yfk correcting WPX prefix calculation.
|
249
251
|
- [25-6-8] Revmoved SQLite WAL mode.
|
250
252
|
- Rewrote DXCC tracker.
|
@@ -385,8 +387,8 @@ Under the `CW` tab, there are three options: i) `cwdaemon` that normally uses IP
|
|
385
387
|
iii) `CAT` that sends Morse characters via rigctld if your radio supports it.
|
386
388
|
|
387
389
|
For contests that require a serial number as part of the exchange, there is an option to pad it with leading zeroes,
|
388
|
-
typically represented by the cut number "T". For example, serial number "001" can be sent as "TT1". The user can
|
389
|
-
configure the `CW Sent Nr Padding` character (default: T) and `CW Sent Nr Padding
|
390
|
+
typically represented by the cut number "T". For example, serial number "001" can be sent as "TT1". The user can
|
391
|
+
configure the `CW Sent Nr Padding` character (default: T) and `CW Sent Nr Padding
|
390
392
|
Length` (default: 3) or specify no padding by entering length "0".
|
391
393
|
|
392
394
|
### Cluster
|
@@ -696,6 +698,18 @@ This window shows you a grid of DXCC entities you've aquired and on what bands.
|
|
696
698
|
|
697
699
|

|
698
700
|
|
701
|
+
### The Rotator Window (Work In Progress)
|
702
|
+
|
703
|
+
`Window`>`Rotator`
|
704
|
+
|
705
|
+
The Rotator window is a work in progress. Currently it blindly connects to a rigctld
|
706
|
+
instance on it's default port of 4533.
|
707
|
+
|
708
|
+

|
709
|
+
|
710
|
+
I myself don't have a rotator to test with. I'm a QRP wires in the trees, if only I
|
711
|
+
had a tree, kind of guy. So we're kind of hoping this works. If not, don't use it.
|
712
|
+
|
699
713
|
### The Remote VFO Window
|
700
714
|
|
701
715
|
You can control the VFO on a remote rig by following the directions listed in
|
@@ -76,6 +76,7 @@
|
|
76
76
|
- [The Check Partial Window](#the-check-partial-window)
|
77
77
|
- [The Rate Window](#the-rate-window)
|
78
78
|
- [The DXCC window](#the-dxcc-window)
|
79
|
+
- [The Rotator Window (Work In Progress)](#the-rotator-window-work-in-progress)
|
79
80
|
- [The Remote VFO Window](#the-remote-vfo-window)
|
80
81
|
- [Cabrillo](#cabrillo)
|
81
82
|
- [ADIF](#adif)
|
@@ -213,6 +214,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
213
214
|
|
214
215
|
## Recent Changes
|
215
216
|
|
217
|
+
- [25-6-11] Added a rotator control widget.
|
216
218
|
- [25-6-10] Merged PR from @dj1yfk correcting WPX prefix calculation.
|
217
219
|
- [25-6-8] Revmoved SQLite WAL mode.
|
218
220
|
- Rewrote DXCC tracker.
|
@@ -353,8 +355,8 @@ Under the `CW` tab, there are three options: i) `cwdaemon` that normally uses IP
|
|
353
355
|
iii) `CAT` that sends Morse characters via rigctld if your radio supports it.
|
354
356
|
|
355
357
|
For contests that require a serial number as part of the exchange, there is an option to pad it with leading zeroes,
|
356
|
-
typically represented by the cut number "T". For example, serial number "001" can be sent as "TT1". The user can
|
357
|
-
configure the `CW Sent Nr Padding` character (default: T) and `CW Sent Nr Padding
|
358
|
+
typically represented by the cut number "T". For example, serial number "001" can be sent as "TT1". The user can
|
359
|
+
configure the `CW Sent Nr Padding` character (default: T) and `CW Sent Nr Padding
|
358
360
|
Length` (default: 3) or specify no padding by entering length "0".
|
359
361
|
|
360
362
|
### Cluster
|
@@ -664,6 +666,18 @@ This window shows you a grid of DXCC entities you've aquired and on what bands.
|
|
664
666
|
|
665
667
|

|
666
668
|
|
669
|
+
### The Rotator Window (Work In Progress)
|
670
|
+
|
671
|
+
`Window`>`Rotator`
|
672
|
+
|
673
|
+
The Rotator window is a work in progress. Currently it blindly connects to a rigctld
|
674
|
+
instance on it's default port of 4533.
|
675
|
+
|
676
|
+

|
677
|
+
|
678
|
+
I myself don't have a rotator to test with. I'm a QRP wires in the trees, if only I
|
679
|
+
had a tree, kind of guy. So we're kind of hoping this works. If not, don't use it.
|
680
|
+
|
667
681
|
### The Remote VFO Window
|
668
682
|
|
669
683
|
You can control the VFO on a remote rig by following the directions listed in
|
@@ -69,6 +69,7 @@ import not1mm.fsutils as fsutils
|
|
69
69
|
from not1mm.logwindow import LogWindow
|
70
70
|
from not1mm.checkwindow import CheckWindow
|
71
71
|
from not1mm.dxcc_tracker import DXCCWindow
|
72
|
+
from not1mm.rotator import RotatorWindow
|
72
73
|
from not1mm.bandmap import BandMapWindow
|
73
74
|
from not1mm.vfo import VfoWindow
|
74
75
|
from not1mm.ratewindow import RateWindow
|
@@ -187,6 +188,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
187
188
|
rate_window = None
|
188
189
|
statistics_window = None
|
189
190
|
dxcc_window = None
|
191
|
+
rotator_window = None
|
192
|
+
voice_window = None
|
190
193
|
settings = None
|
191
194
|
lookup_service = None
|
192
195
|
fldigi_util = None
|
@@ -311,6 +314,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
311
314
|
self.actionStatistics.triggered.connect(self.launch_stats_window)
|
312
315
|
self.actionVFO.triggered.connect(self.launch_vfo)
|
313
316
|
self.actionDXCC.triggered.connect(self.launch_dxcc_window)
|
317
|
+
self.actionRotator.triggered.connect(self.launch_rotator_window)
|
314
318
|
self.actionRecalculate_Mults.triggered.connect(self.recalculate_mults)
|
315
319
|
self.actionLoad_Call_History_File.triggered.connect(self.load_call_history)
|
316
320
|
|
@@ -679,6 +683,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
679
683
|
self.station = self.database.fetch_station()
|
680
684
|
if self.station is None:
|
681
685
|
self.station = {}
|
686
|
+
if self.rotator_window is not None:
|
687
|
+
self.rotator_window.set_mygrid(self.station.get("GridSquare", ""))
|
682
688
|
self.contact = self.database.empty_contact.copy()
|
683
689
|
self.current_op = self.station.get("Call", "")
|
684
690
|
self.voice_process.current_op = self.current_op
|
@@ -750,6 +756,16 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
750
756
|
self.dxcc_window.hide()
|
751
757
|
self.dxcc_window.message.connect(self.dockwidget_message)
|
752
758
|
|
759
|
+
self.show_splash_msg("Setting up RotatorWindow.")
|
760
|
+
self.rotator_window = RotatorWindow()
|
761
|
+
self.rotator_window.setObjectName("rotator-window")
|
762
|
+
if os.environ.get("WAYLAND_DISPLAY") and old_Qt is True:
|
763
|
+
self.rotator_window.setFeatures(dockfeatures)
|
764
|
+
self.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, self.rotator_window)
|
765
|
+
self.rotator_window.hide()
|
766
|
+
self.rotator_window.message.connect(self.dockwidget_message)
|
767
|
+
self.rotator_window.set_mygrid(self.station.get("GridSquare", ""))
|
768
|
+
|
753
769
|
self.show_splash_msg("Setting up VFOWindow.")
|
754
770
|
self.vfo_window = VfoWindow()
|
755
771
|
self.vfo_window.setObjectName("vfo-window")
|
@@ -823,11 +839,18 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
823
839
|
if self.actionDXCC.isChecked():
|
824
840
|
self.dxcc_window.show()
|
825
841
|
self.dxcc_window.setActive(True)
|
826
|
-
# self.dxcc_window.get_run_and_total_qs()
|
827
842
|
else:
|
828
843
|
self.dxcc_window.hide()
|
829
844
|
self.dxcc_window.setActive(False)
|
830
845
|
|
846
|
+
self.actionRotator.setChecked(self.pref.get("rotatorwindow", False))
|
847
|
+
if self.actionRotator.isChecked():
|
848
|
+
self.rotator_window.show()
|
849
|
+
self.rotator_window.setActive(True)
|
850
|
+
else:
|
851
|
+
self.rotator_window.hide()
|
852
|
+
self.rotator_window.setActive(False)
|
853
|
+
|
831
854
|
self.actionVFO.setChecked(self.pref.get("vfowindow", False))
|
832
855
|
if self.actionVFO.isChecked():
|
833
856
|
self.vfo_window.show()
|
@@ -1236,7 +1259,9 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1236
1259
|
self.heading_distance.setText(
|
1237
1260
|
f"{grid} Hdg {heading}° LP {reciprocol(heading)}° / "
|
1238
1261
|
f"distance {int(kilometers*0.621371)}mi {kilometers}km"
|
1262
|
+
f" {msg.get('result', {}).get('name_fmt', '')}"
|
1239
1263
|
)
|
1264
|
+
self.rotator_window.set_requested_azimuth(float(heading))
|
1240
1265
|
|
1241
1266
|
def cluster_expire_updated(self, number):
|
1242
1267
|
"""signal from bandmap"""
|
@@ -1631,6 +1656,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1631
1656
|
self.station = self.database.fetch_station()
|
1632
1657
|
if self.station is None:
|
1633
1658
|
self.station = {}
|
1659
|
+
if self.rotator_window is not None:
|
1660
|
+
self.rotator_window.set_mygrid(self.station.get("GridSquare", ""))
|
1634
1661
|
self.current_op = self.station.get("Call", "")
|
1635
1662
|
self.voice_process.current_op = self.current_op
|
1636
1663
|
self.make_op_dir()
|
@@ -1673,6 +1700,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1673
1700
|
self.station = self.database.fetch_station()
|
1674
1701
|
if self.station is None:
|
1675
1702
|
self.station = {}
|
1703
|
+
if self.rotator_window is not None:
|
1704
|
+
self.rotator_window.set_mygrid(self.station.get("GridSquare", ""))
|
1676
1705
|
if self.station.get("Call", "") == "":
|
1677
1706
|
self.edit_station_settings()
|
1678
1707
|
self.current_op = self.station.get("Call", "")
|
@@ -2245,11 +2274,21 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2245
2274
|
if self.actionDXCC.isChecked():
|
2246
2275
|
self.dxcc_window.show()
|
2247
2276
|
self.dxcc_window.setActive(True)
|
2248
|
-
# self.dxcc_window.get_run_and_total_qs()
|
2249
2277
|
else:
|
2250
2278
|
self.dxcc_window.hide()
|
2251
2279
|
self.dxcc_window.setActive(False)
|
2252
2280
|
|
2281
|
+
def launch_rotator_window(self) -> None:
|
2282
|
+
"""Launch the rotator window"""
|
2283
|
+
self.pref["rotatorwindow"] = self.actionRotator.isChecked()
|
2284
|
+
self.write_preference()
|
2285
|
+
if self.actionRotator.isChecked():
|
2286
|
+
self.rotator_window.show()
|
2287
|
+
self.rotator_window.setActive(True)
|
2288
|
+
else:
|
2289
|
+
self.rotator_window.hide()
|
2290
|
+
self.rotator_window.setActive(False)
|
2291
|
+
|
2253
2292
|
def launch_vfo(self) -> None:
|
2254
2293
|
"""Launch the VFO window"""
|
2255
2294
|
self.pref["vfowindow"] = self.actionVFO.isChecked()
|
@@ -3099,6 +3138,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
3099
3138
|
self.station["Club"] = self.settings_dialog.Club.text()
|
3100
3139
|
self.station["Email"] = self.settings_dialog.Email.text()
|
3101
3140
|
self.database.add_station(self.station)
|
3141
|
+
if self.rotator_window is not None:
|
3142
|
+
self.rotator_window.set_mygrid(self.settings_dialog.GridSquare.text())
|
3102
3143
|
self.settings_dialog.close()
|
3103
3144
|
if self.current_op == "":
|
3104
3145
|
self.current_op = self.station.get("Call", "")
|
@@ -4060,6 +4101,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
4060
4101
|
f"Regional Hdg {heading}° LP {reciprocol(heading)}° / "
|
4061
4102
|
f"distance {int(kilometers*0.621371)}mi {kilometers}km"
|
4062
4103
|
)
|
4104
|
+
if self.rotator_window is not None:
|
4105
|
+
self.rotator_window.set_requested_azimuth(float(heading))
|
4063
4106
|
self.contact["CountryPrefix"] = primary_pfx
|
4064
4107
|
self.contact["ZN"] = int(cq)
|
4065
4108
|
if self.contest:
|
@@ -1573,6 +1573,7 @@
|
|
1573
1573
|
<addaction name="actionStatistics"/>
|
1574
1574
|
<addaction name="actionVFO"/>
|
1575
1575
|
<addaction name="actionDXCC"/>
|
1576
|
+
<addaction name="actionRotator"/>
|
1576
1577
|
</widget>
|
1577
1578
|
<widget class="QMenu" name="menuOther">
|
1578
1579
|
<property name="title">
|
@@ -2144,6 +2145,17 @@
|
|
2144
2145
|
<string>Alt+D</string>
|
2145
2146
|
</property>
|
2146
2147
|
</action>
|
2148
|
+
<action name="actionRotator">
|
2149
|
+
<property name="checkable">
|
2150
|
+
<bool>true</bool>
|
2151
|
+
</property>
|
2152
|
+
<property name="text">
|
2153
|
+
<string>Rotator</string>
|
2154
|
+
</property>
|
2155
|
+
<property name="shortcut">
|
2156
|
+
<string>Alt+P</string>
|
2157
|
+
</property>
|
2158
|
+
</action>
|
2147
2159
|
</widget>
|
2148
2160
|
<resources/>
|
2149
2161
|
<connections/>
|
Binary file
|
@@ -0,0 +1,144 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<ui version="4.0">
|
3
|
+
<class>RotatorWidget</class>
|
4
|
+
<widget class="QDockWidget" name="RotatorWidget">
|
5
|
+
<property name="geometry">
|
6
|
+
<rect>
|
7
|
+
<x>0</x>
|
8
|
+
<y>0</y>
|
9
|
+
<width>352</width>
|
10
|
+
<height>248</height>
|
11
|
+
</rect>
|
12
|
+
</property>
|
13
|
+
<property name="windowTitle">
|
14
|
+
<string>Rotator</string>
|
15
|
+
</property>
|
16
|
+
<widget class="QWidget" name="centralwidget">
|
17
|
+
<layout class="QVBoxLayout" name="verticalLayout">
|
18
|
+
<property name="leftMargin">
|
19
|
+
<number>0</number>
|
20
|
+
</property>
|
21
|
+
<property name="topMargin">
|
22
|
+
<number>0</number>
|
23
|
+
</property>
|
24
|
+
<property name="rightMargin">
|
25
|
+
<number>0</number>
|
26
|
+
</property>
|
27
|
+
<property name="bottomMargin">
|
28
|
+
<number>0</number>
|
29
|
+
</property>
|
30
|
+
<item>
|
31
|
+
<layout class="QHBoxLayout" name="horizontalLayout">
|
32
|
+
<item>
|
33
|
+
<widget class="QPushButton" name="move_button">
|
34
|
+
<property name="focusPolicy">
|
35
|
+
<enum>Qt::FocusPolicy::NoFocus</enum>
|
36
|
+
</property>
|
37
|
+
<property name="text">
|
38
|
+
<string>Move</string>
|
39
|
+
</property>
|
40
|
+
</widget>
|
41
|
+
</item>
|
42
|
+
</layout>
|
43
|
+
</item>
|
44
|
+
<item>
|
45
|
+
<widget class="QGraphicsView" name="compassView">
|
46
|
+
<property name="focusPolicy">
|
47
|
+
<enum>Qt::FocusPolicy::ClickFocus</enum>
|
48
|
+
</property>
|
49
|
+
<property name="frameShape">
|
50
|
+
<enum>QFrame::Shape::NoFrame</enum>
|
51
|
+
</property>
|
52
|
+
<property name="frameShadow">
|
53
|
+
<enum>QFrame::Shadow::Plain</enum>
|
54
|
+
</property>
|
55
|
+
<property name="renderHints">
|
56
|
+
<set>QPainter::RenderHint::Antialiasing|QPainter::RenderHint::SmoothPixmapTransform|QPainter::RenderHint::TextAntialiasing</set>
|
57
|
+
</property>
|
58
|
+
</widget>
|
59
|
+
</item>
|
60
|
+
<item>
|
61
|
+
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
62
|
+
<item>
|
63
|
+
<spacer name="horizontalSpacer">
|
64
|
+
<property name="orientation">
|
65
|
+
<enum>Qt::Orientation::Horizontal</enum>
|
66
|
+
</property>
|
67
|
+
<property name="sizeHint" stdset="0">
|
68
|
+
<size>
|
69
|
+
<width>40</width>
|
70
|
+
<height>20</height>
|
71
|
+
</size>
|
72
|
+
</property>
|
73
|
+
</spacer>
|
74
|
+
</item>
|
75
|
+
<item>
|
76
|
+
<widget class="QPushButton" name="north_button">
|
77
|
+
<property name="focusPolicy">
|
78
|
+
<enum>Qt::FocusPolicy::NoFocus</enum>
|
79
|
+
</property>
|
80
|
+
<property name="text">
|
81
|
+
<string>N</string>
|
82
|
+
</property>
|
83
|
+
<property name="iconSize">
|
84
|
+
<size>
|
85
|
+
<width>16</width>
|
86
|
+
<height>16</height>
|
87
|
+
</size>
|
88
|
+
</property>
|
89
|
+
<property name="flat">
|
90
|
+
<bool>false</bool>
|
91
|
+
</property>
|
92
|
+
</widget>
|
93
|
+
</item>
|
94
|
+
<item>
|
95
|
+
<widget class="QPushButton" name="south_button">
|
96
|
+
<property name="focusPolicy">
|
97
|
+
<enum>Qt::FocusPolicy::NoFocus</enum>
|
98
|
+
</property>
|
99
|
+
<property name="text">
|
100
|
+
<string>S</string>
|
101
|
+
</property>
|
102
|
+
</widget>
|
103
|
+
</item>
|
104
|
+
<item>
|
105
|
+
<widget class="QPushButton" name="west_button">
|
106
|
+
<property name="focusPolicy">
|
107
|
+
<enum>Qt::FocusPolicy::NoFocus</enum>
|
108
|
+
</property>
|
109
|
+
<property name="text">
|
110
|
+
<string>W</string>
|
111
|
+
</property>
|
112
|
+
</widget>
|
113
|
+
</item>
|
114
|
+
<item>
|
115
|
+
<widget class="QPushButton" name="east_button">
|
116
|
+
<property name="focusPolicy">
|
117
|
+
<enum>Qt::FocusPolicy::NoFocus</enum>
|
118
|
+
</property>
|
119
|
+
<property name="text">
|
120
|
+
<string>E</string>
|
121
|
+
</property>
|
122
|
+
</widget>
|
123
|
+
</item>
|
124
|
+
<item>
|
125
|
+
<spacer name="horizontalSpacer_2">
|
126
|
+
<property name="orientation">
|
127
|
+
<enum>Qt::Orientation::Horizontal</enum>
|
128
|
+
</property>
|
129
|
+
<property name="sizeHint" stdset="0">
|
130
|
+
<size>
|
131
|
+
<width>40</width>
|
132
|
+
<height>20</height>
|
133
|
+
</size>
|
134
|
+
</property>
|
135
|
+
</spacer>
|
136
|
+
</item>
|
137
|
+
</layout>
|
138
|
+
</item>
|
139
|
+
</layout>
|
140
|
+
</widget>
|
141
|
+
</widget>
|
142
|
+
<resources/>
|
143
|
+
<connections/>
|
144
|
+
</ui>
|
@@ -0,0 +1,101 @@
|
|
1
|
+
import socket
|
2
|
+
import logging
|
3
|
+
|
4
|
+
if __name__ == "__main__":
|
5
|
+
print("I'm not the program you are looking for.")
|
6
|
+
|
7
|
+
logger = logging.getLogger("rot_interface")
|
8
|
+
|
9
|
+
|
10
|
+
class RotatorInterface:
|
11
|
+
"""
|
12
|
+
A class to interface with a rotator control program (like rotctld).
|
13
|
+
"""
|
14
|
+
|
15
|
+
def __init__(self, host="127.0.0.1", port=4533):
|
16
|
+
self.host = host
|
17
|
+
self.port = port
|
18
|
+
self.socket = None
|
19
|
+
self.connected = False
|
20
|
+
self.connect()
|
21
|
+
|
22
|
+
def connect(self):
|
23
|
+
"""Connect to the rotator control program."""
|
24
|
+
try:
|
25
|
+
self.socket = socket.create_connection((self.host, self.port), timeout=1)
|
26
|
+
self.connected = True
|
27
|
+
logger.info(f"Connected to rotator at {self.host}:{self.port}")
|
28
|
+
except (socket.timeout, ConnectionRefusedError, OSError) as e:
|
29
|
+
self.connected = False
|
30
|
+
logger.warning(
|
31
|
+
f"Failed to connect to rotator at {self.host}:{self.port}: {e}"
|
32
|
+
)
|
33
|
+
self.socket = None
|
34
|
+
|
35
|
+
def disconnect(self):
|
36
|
+
"""Disconnect from the rotator control program."""
|
37
|
+
if self.socket:
|
38
|
+
try:
|
39
|
+
self.socket.close()
|
40
|
+
logger.info("Disconnected from rotator")
|
41
|
+
except OSError as e:
|
42
|
+
logger.warning(f"Error closing rotator socket: {e}")
|
43
|
+
self.socket = None
|
44
|
+
self.connected = False
|
45
|
+
|
46
|
+
def send_command(self, command):
|
47
|
+
"""Send a command to the rotator control program and return the response."""
|
48
|
+
if not self.connected or not self.socket:
|
49
|
+
self.connect()
|
50
|
+
if not self.connected or not self.socket:
|
51
|
+
logger.warning("Not connected to rotator. Command not sent.")
|
52
|
+
return None
|
53
|
+
|
54
|
+
try:
|
55
|
+
self.socket.sendall((command + "\n").encode())
|
56
|
+
response = self.socket.recv(1024).decode().strip()
|
57
|
+
logger.debug(f"Sent: {command}, Received: {response}")
|
58
|
+
return response
|
59
|
+
except OSError as e:
|
60
|
+
logger.warning(f"Error sending command to rotator: {e}")
|
61
|
+
self.disconnect()
|
62
|
+
return None
|
63
|
+
|
64
|
+
def get_position(self):
|
65
|
+
"""Get the current azimuth and elevation from the rotator."""
|
66
|
+
response = self.send_command("p")
|
67
|
+
logger.debug(f"get_position response: {response}")
|
68
|
+
if response:
|
69
|
+
if response == "RPRT -1":
|
70
|
+
return None, None
|
71
|
+
try:
|
72
|
+
azimuth, elevation = map(float, response.split("\n"))
|
73
|
+
return azimuth, elevation
|
74
|
+
except ValueError:
|
75
|
+
logger.warning(f"Invalid response from rotator: {response}")
|
76
|
+
return None, None
|
77
|
+
|
78
|
+
def set_position(self, azimuth, elevation=0.0) -> bool:
|
79
|
+
"""Set the azimuth and elevation on the rotator."""
|
80
|
+
response = self.send_command(f"P {azimuth} {elevation}")
|
81
|
+
return response is not None
|
82
|
+
|
83
|
+
def park_rotator(self) -> bool:
|
84
|
+
"""Park the rotator."""
|
85
|
+
response = self.send_command("K")
|
86
|
+
return response is not None
|
87
|
+
|
88
|
+
def reset_rotator(self) -> bool:
|
89
|
+
"""Reset the rotator."""
|
90
|
+
response = self.send_command("R")
|
91
|
+
return response is not None
|
92
|
+
|
93
|
+
def move_rotator(self, direction, speed) -> bool:
|
94
|
+
"""Move the rotator in the specified direction at the specified speed."""
|
95
|
+
response = self.send_command(f"M {direction} {speed}")
|
96
|
+
return response is not None
|
97
|
+
|
98
|
+
def stop_rotator(self) -> bool:
|
99
|
+
"""Stop the rotator."""
|
100
|
+
response = self.send_command("S")
|
101
|
+
return response is not None
|