Skip to content

Commit

Permalink
closes #136 (#137)
Browse files Browse the repository at this point in the history
  • Loading branch information
M0r13n authored May 10, 2024
1 parent b338dc3 commit 19d8cc1
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 4 deletions.
20 changes: 16 additions & 4 deletions pyais/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -797,10 +797,14 @@ class CommunicationStateMixin:
https://www.itu.int/dms_pubrec/itu-r/rec/m/R-REC-M.1371-1-200108-S!!PDF-E.pdf
"""

msg_type: int # Type hint to make mypy happy
radio: int # Type hint to make mypy happy

MAX_COMM_STATE_VALUE = 0x7ffff

SOTDMA_TYPES = (1, 2, 4, 11)
SOTDMA_ITDMA_TYPES = (9, 18, 26)

def get_communication_state(self) -> Dict[str, typing.Optional[int]]:
"""Returns information used by the slot allocation algorithm as a dict."""
result: Dict[str, typing.Optional[int]] = {
Expand All @@ -825,13 +829,21 @@ def get_communication_state(self) -> Dict[str, typing.Optional[int]]:

@property
def is_sotdma(self) -> bool:
"""The radio status field has it's 20th bit (MSB) set to 0 or has less than 20 bits"""
return self.radio <= self.MAX_COMM_STATE_VALUE
"""Messages of type 1, 2, 4, 11 use SOTDMA or 9, 18, 26 if 20th bit is set."""
if self.msg_type in self.SOTDMA_TYPES:
return True
if self.msg_type in self.SOTDMA_ITDMA_TYPES:
return self.radio <= self.MAX_COMM_STATE_VALUE
return False

@property
def is_itdma(self) -> bool:
"""The radio status field has it's 20th bit (MSB) set to 1"""
return self.radio > self.MAX_COMM_STATE_VALUE
"""Messages of type 3 use ITDMA or 9, 18, 26 if 20th bit is set."""
if self.msg_type == 3:
return True
if self.msg_type in self.SOTDMA_ITDMA_TYPES:
return self.radio > self.MAX_COMM_STATE_VALUE
return False

@property
def communication_state_raw(self) -> int:
Expand Down
34 changes: 34 additions & 0 deletions tests/test_decode.py
Original file line number Diff line number Diff line change
Expand Up @@ -1385,6 +1385,14 @@ def test_rot_decode_yields_expected_values(self):
assert decode(b"!AIVDM,1,1,,A,16:VFv0k0I`KQPpFATG4SgvT40:v,0*7B").turn == -121.0
assert decode(b"!AIVDM,1,1,,B,16:D3F0:15`5ogh<O?bk>1Dd2L1<,0*0B").turn == 71.0

def test_sotdma_time_conversion(self):
"""Prevent regressions for: https://github.com/M0r13n/pyais/pull/135"""
decoded = decode('!AIVDM,1,1,,B,133ga6PP0lPPE>4M3G@DpOwTR61p,0*33')
cs = decoded.get_communication_state()

assert cs['utc_hour'] == 16
assert cs['utc_minute'] == 30

def test_get_sotdma_comm_state_utc_direct(self):
msg = "!AIVDM,1,1,,A,13HOI:0P0000VOHLCnHQKwvL05Ip,0*23"
decoded = decode(msg)
Expand Down Expand Up @@ -1457,6 +1465,32 @@ def test_get_sotdma_comm_state_utc_direct_slot_timeout(self):
},
)

def test_is_sotdma_or_itdma(self):
""" Verify that messages are correctly identified as either ITDMA or SOTDMA.
Details: https://github.com/M0r13n/pyais/issues/136."""

# 1
assert decode(b"!AIVDM,1,1,,A,13n3aW0PCkPJS8>Qhc2<urG02D13,0*18").is_sotdma
assert not decode(b"!AIVDM,1,1,,A,13n3aW0PCkPJS8>Qhc2<urG02D13,0*18").is_itdma
# 2
assert decode(b"!AIVDM,1,1,,A,23aFfl0P00PCR?0MEB@h0?w020S7,0*68").is_sotdma
assert not decode(b"!AIVDM,1,1,,A,23aFfl0P00PCR?0MEB@h0?w020S7,0*68").is_itdma
# 3
assert not decode(b"!AIVDM,1,1,,B,33UTPD5000G<@aTL3:?0010j0000,0*2A").is_sotdma
assert decode(b"!AIVDM,1,1,,B,33UTPD5000G<@aTL3:?0010j0000,0*2A").is_itdma
# 4
assert decode(b"!AIVDM,1,1,,B,4h2=aCAuho;QNOUQrvQ6?a1000S:,0*5D").is_sotdma
assert not decode(b"!AIVDM,1,1,,B,4h2=aCAuho;QNOUQrvQ6?a1000S:,0*5D").is_itdma
# 9
assert decode(b"!AIVDM,1,1,,A,91b55vRCQvOo4PLLww<3cGh20@Br,0*79").is_sotdma
assert not decode(b"!AIVDM,1,1,,A,91b55vRCQvOo4PLLww<3cGh20@Br,0*79").is_itdma
# 11
assert decode(b"!AIVDM,1,1,,A,;03t=KQuho;QM`d:WFAtwnW00000,0*7C").is_sotdma
assert not decode(b"!AIVDM,1,1,,A,;03t=KQuho;QM`d:WFAtwnW00000,0*7C").is_itdma
# 18
assert decode(b" !AIVDM,1,1,,A,B6:a?;03wk?8mP=18D3Q3wP61P06,0*7F").is_sotdma
assert not decode(b" !AIVDM,1,1,,A,B6:a?;03wk?8mP=18D3Q3wP61P06,0*7F").is_itdma

def test_get_comm_state_type_18_itdma_base_indirect(self):
msg = "!AIVDM,1,1,,A,B5NJ;PP005l4ot5Isbl03wsUkP06,0*76"
decoded = decode(msg)
Expand Down

0 comments on commit 19d8cc1

Please sign in to comment.