Coverage for kv4p/messages/desired_state.py: 89%

27 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-13 13:27 +0000

1"""Host desired radio/control state.""" 

2 

3from __future__ import annotations 

4 

5import struct 

6from dataclasses import dataclass 

7 

8from kv4p.constants.messages import DRA818_12K5, DRA818_25K 

9 

10_HOST_DESIRED_STATE = struct.Struct("<IiHBffBBB") 

11 

12 

13def bandwidth_to_dra818(value: str) -> int: 

14 """Translate a bandwidth string into a DRA818_* constant.""" 

15 normalized = value.lower() 

16 if normalized in {"25k", "25", "wide"}: 

17 return DRA818_25K 

18 if normalized in {"12k5", "12.5k", "narrow"}: 

19 return DRA818_12K5 

20 raise ValueError(f"unsupported bandwidth: {value}") 

21 

22 

23def dra818_to_bandwidth(value: int) -> str: 

24 """Translate a DRA818_* constant into a bandwidth string.""" 

25 return "25k" if value == DRA818_25K else "12.5k" 

26 

27 

28@dataclass(frozen=True, slots=True) 

29class HostDesiredState: 

30 """Host desired radio/control state.""" 

31 

32 sequence: int 

33 memory_id: int 

34 flags: int 

35 bw: int 

36 freq_tx: float 

37 freq_rx: float 

38 ctcss_tx: int 

39 squelch: int 

40 ctcss_rx: int 

41 

42 def to_bytes(self) -> bytes: 

43 """Serialize HostDesiredState.""" 

44 return _HOST_DESIRED_STATE.pack( 

45 self.sequence, 

46 self.memory_id, 

47 self.flags, 

48 self.bw, 

49 self.freq_tx, 

50 self.freq_rx, 

51 self.ctcss_tx, 

52 self.squelch, 

53 self.ctcss_rx, 

54 )