pyfastnet 1.2.3__tar.gz → 1.2.4__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.
Files changed (25) hide show
  1. {pyfastnet-1.2.3/pyfastnet.egg-info → pyfastnet-1.2.4}/PKG-INFO +1 -1
  2. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/fastnet_decoder/decode_fastnet.py +2 -1
  3. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/fastnet_decoder/utils.py +1 -0
  4. {pyfastnet-1.2.3 → pyfastnet-1.2.4/pyfastnet.egg-info}/PKG-INFO +1 -1
  5. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/pyfastnet.egg-info/SOURCES.txt +1 -0
  6. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/setup.py +1 -1
  7. pyfastnet-1.2.4/tests/test_format08_layout.py +61 -0
  8. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/LICENSE +0 -0
  9. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/MANIFEST.in +0 -0
  10. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/README.md +0 -0
  11. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/fastnet_decoder/__init__.py +0 -0
  12. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/fastnet_decoder/frame_buffer.py +0 -0
  13. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/fastnet_decoder/logger.py +0 -0
  14. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/fastnet_decoder/mappings.py +0 -0
  15. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/pyfastnet.egg-info/dependency_links.txt +0 -0
  16. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/pyfastnet.egg-info/top_level.txt +0 -0
  17. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/setup.cfg +0 -0
  18. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/tests/test_apparent_frame.py +0 -0
  19. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/tests/test_autopilot_frame.py +0 -0
  20. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/tests/test_depth_frame.py +0 -0
  21. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/tests/test_format07_msb_regression.py +0 -0
  22. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/tests/test_heel_frame.py +0 -0
  23. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/tests/test_rudder_frame.py +0 -0
  24. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/tests/test_tide_frame.py +0 -0
  25. {pyfastnet-1.2.3 → pyfastnet-1.2.4}/tests/test_true_frame.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyfastnet
3
- Version: 1.2.3
3
+ Version: 1.2.4
4
4
  Summary: A Python library for decoding FastNet protocol data streams.
5
5
  Home-page: https://github.com/ghotihook/pyfastnet
6
6
  Author: Alex Salmon
@@ -369,7 +369,8 @@ def decode_format_and_data(channel_id, format_byte, data_bytes):
369
369
  segment_code = (data_bytes[0] >> 1) & 0b01111111 # 7-bit segment
370
370
  unsigned_value = ((data_bytes[0] & 0b1) << 8) | data_bytes[1] # 9-bit unsigned value
371
371
  interpreted_value = unsigned_value / divisor
372
- raw_value = {"segment_code": segment_code, "unsigned_value": unsigned_value}
372
+ layout = convert_segment_a_to_char(segment_code)
373
+ raw_value = {"segment_code": segment_code, "layout": layout, "unsigned_value": unsigned_value}
373
374
 
374
375
  elif format_bits == 0x0A: # 16-bit signed + 16-bit signed
375
376
  if len(data_bytes) != 4:
@@ -62,6 +62,7 @@ def convert_segment_a_to_char(segment_byte):
62
62
  #}
63
63
 
64
64
  segment_mapping = {
65
+ 0x66: "°M", # magnetic bearing indicator (seen on Heading, Course, TWD, Tidal Set)
65
66
  0x28: "[data]=",
66
67
  0xa8: "=[data]",
67
68
  0x20: "[data]-",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyfastnet
3
- Version: 1.2.3
3
+ Version: 1.2.4
4
4
  Summary: A Python library for decoding FastNet protocol data streams.
5
5
  Home-page: https://github.com/ghotihook/pyfastnet
6
6
  Author: Alex Salmon
@@ -16,6 +16,7 @@ tests/test_apparent_frame.py
16
16
  tests/test_autopilot_frame.py
17
17
  tests/test_depth_frame.py
18
18
  tests/test_format07_msb_regression.py
19
+ tests/test_format08_layout.py
19
20
  tests/test_heel_frame.py
20
21
  tests/test_rudder_frame.py
21
22
  tests/test_tide_frame.py
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="pyfastnet",
5
- version="1.2.3", # Ensure this matches your intended version
5
+ version="1.2.4", # Ensure this matches your intended version
6
6
  author="Alex Salmon",
7
7
  author_email="alex@ivila.net",
8
8
  description="A Python library for decoding FastNet protocol data streams.",
@@ -0,0 +1,61 @@
1
+ import unittest
2
+ from fastnet_decoder.decode_fastnet import decode_frame
3
+
4
+
5
+ class TestFormat08Layout(unittest.TestCase):
6
+ """
7
+ Tests for format 0x08 layout field (magnetic bearing indicator).
8
+
9
+ Format 0x08: SEGCODE_B-derived 7-bit segment code + 9-bit unsigned value.
10
+ Segment code 0x66 (segments f+g+a+b = degree symbol) activates the "°M"
11
+ annunciator on the Hydra 2000 FFD, indicating a magnetic-referenced bearing.
12
+
13
+ Frame "ff120e01e00b038c274908cc294a0a1cdd6067e5" contains:
14
+ - Rudder Angle (0x0b), format 0x03
15
+ - Heading (0x49), format 0x08, data=[0xCC, 0x29]
16
+ data[0]=0xCC → segment_code = (0xCC >> 1) & 0x7F = 0x66 → layout "°M"
17
+ unsigned_value = 0x29 = 41 → interpreted 41.0°
18
+ - Heading Raw (0x4a), format 0x0a
19
+ """
20
+
21
+ FRAME_HEX = "ff120e01e00b038c274908cc294a0a1cdd6067e5"
22
+
23
+ def setUp(self):
24
+ self.decoded = decode_frame(bytes.fromhex(self.FRAME_HEX))
25
+ self.heading = self.decoded["values"]["Heading"]
26
+
27
+ def test_no_decode_error(self):
28
+ self.assertNotIn("error", self.decoded)
29
+
30
+ def test_heading_present(self):
31
+ self.assertIn("Heading", self.decoded["values"])
32
+
33
+ def test_heading_interpreted_value(self):
34
+ self.assertEqual(self.heading["interpreted"], 41.0)
35
+
36
+ def test_heading_format_is_08(self):
37
+ self.assertEqual(self.heading["format_bits"], 8)
38
+
39
+ def test_heading_raw_has_layout(self):
40
+ self.assertIn("layout", self.heading["raw"])
41
+
42
+ def test_heading_layout_is_magnetic(self):
43
+ self.assertEqual(self.heading["raw"]["layout"], "°M")
44
+
45
+ def test_heading_segment_code(self):
46
+ # 0x66 = segments f+g+a+b = degree symbol, co-activates Hydra 2000 "M" annunciator
47
+ self.assertEqual(self.heading["raw"]["segment_code"], 0x66)
48
+
49
+ def test_cog_true_has_blank_layout(self):
50
+ # COG True is GPS-derived — no magnetic indicator, segment code 0x00 = blank
51
+ # Frame: ff051601e5 ... e9 08 00 XX ... (COG True channel 0xe9)
52
+ # Use a frame that contains COG True with blank segment code
53
+ cog_frame = bytes.fromhex("FF051601E555610030566100185903A86B7F8700BB00016D08CD0DCB")
54
+ decoded = decode_frame(cog_frame)
55
+ cog = decoded["values"].get("Course Over Ground (True)")
56
+ if cog:
57
+ self.assertEqual(cog["raw"]["layout"], " ", "GPS COG should have blank layout (no magnetic indicator)")
58
+
59
+
60
+ if __name__ == "__main__":
61
+ unittest.main()
File without changes
File without changes
File without changes
File without changes