-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathradio_command_handler.py
More file actions
98 lines (82 loc) · 3.44 KB
/
Copy pathradio_command_handler.py
File metadata and controls
98 lines (82 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
from typing import List, Dict
from radio import Radio
class ButtonState:
def __init__(self, button_states: List[bool]):
self.states = button_states
def __str__(self):
return f"Buttons: {self.states}"
class RadioCommandHandler:
def __init__(self, radio: Radio, rig_controller=None, display=None):
self.radio = radio
self.rig_controller = rig_controller
self.display = display
self._last_state_tuple = (False, False, False, False)
self._command_map: Dict = self._init_command_map()
def _init_command_map(self) -> Dict:
return {
# Single-button profile for FT-818 control features.
(True, False, False, False): self._force_full_refresh,
(False, True, False, False): self._band_up,
(False, False, True, False): self._cycle_tuning_step,
(False, False, False, True): self._shutdown,
# Keep common combos available.
(True, True, False, False): self._band_up,
(False, False, True, True): self._band_down,
(True, False, True, False): self._increment_frequency,
(False, True, False, True): self._decrement_frequency,
}
def handle_button_state(self, button_state: ButtonState) -> None:
# Convert button state to tuple for mapping
state_tuple = tuple(button_state.states)
# Fire only on a state transition to avoid repeated toggles while held.
if state_tuple == self._last_state_tuple:
return
self._last_state_tuple = state_tuple
if not any(state_tuple):
return
if state_tuple in self._command_map:
command = self._command_map[state_tuple]
command()
def _force_full_refresh(self):
if self.display:
self.display.force_full_refresh(immediate=True)
else:
self.radio.set_status_message("Full refresh unavailable")
def _cycle_tuning_step(self):
if self.rig_controller:
step = self.rig_controller.cycle_step()
self.radio.set_tuning_step(step)
self.radio.set_status_message(f"Step {step * 1_000_000:.0f} Hz")
else:
current = self.radio.tuning_step_mhz
next_step = 0.0010 if current < 0.0010 else 0.0001
self.radio.set_tuning_step(next_step)
self.radio.set_status_message(f"Step {next_step * 1_000_000:.0f} Hz")
def _shutdown(self):
if self.display:
self.display.QRT()
raise SystemExit(0)
def _increment_frequency(self):
if self.rig_controller:
self.rig_controller.tune_by_step(+1)
else:
self.radio.increment_frequency(self.radio.tuning_step_mhz)
def _decrement_frequency(self):
if self.rig_controller:
self.rig_controller.tune_by_step(-1)
else:
self.radio.increment_frequency(-self.radio.tuning_step_mhz)
def _band_up(self):
if self.rig_controller:
message = self.rig_controller.band_up()
if "failed" in message.lower():
self.radio.set_status_message(message)
else:
self.radio.change_band("up")
def _band_down(self):
if self.rig_controller:
message = self.rig_controller.band_down()
if "failed" in message.lower():
self.radio.set_status_message(message)
else:
self.radio.change_band("down")