Skip to content

Commit 001c718

Browse files
committed
load protocpoldata from json file
1 parent 0592449 commit 001c718

1 file changed

Lines changed: 61 additions & 3 deletions

File tree

sd_protocols/sd_protocols.py

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import copy
2-
from .sd_protocol_data import protocols
2+
import json
3+
from pathlib import Path
4+
from typing import Any, Dict
35
from .helpers import ProtocolHelpersMixin
46
from .manchester import ManchesterMixin
57
from .postdemodulation import PostdemodulationMixin
@@ -17,10 +19,23 @@ class SDProtocols(ProtocolHelpersMixin, ManchesterMixin, PostdemodulationMixin,
1719
"""
1820

1921
def __init__(self):
20-
self._protocols = copy.deepcopy(protocols)
22+
self._protocols = self._load_protocols()
2123
self._log_callback = None
2224
self.set_defaults()
2325

26+
def _load_protocols(self) -> Dict[str, Any]:
27+
"""Loads protocols from protocols.json."""
28+
json_path = Path(__file__).resolve().parent / "protocols.json"
29+
try:
30+
with open(json_path, "r", encoding="utf-8") as f:
31+
data = json.load(f)
32+
return data.get("protocols", {})
33+
except Exception as e:
34+
# Fallback or error logging if needed, though for now we raise
35+
# or return empty dict if file missing (should not happen in prod)
36+
print(f"Error loading protocols.json: {e}")
37+
return {}
38+
2439
def protocol_exists(self, pid: str) -> bool:
2540
return pid in self._protocols
2641

@@ -38,6 +53,50 @@ def check_property(self, pid: str, value_name: str, default=None):
3853
def get_property(self, pid: str, value_name: str):
3954
return self._protocols.get(pid, {}).get(value_name)
4055

56+
def demodulate_mn(self, msg_data: Dict[str, Any], msg_type: str) -> list:
57+
"""Attempts to demodulate an MN message using registered protocols."""
58+
if "protocol_id" not in msg_data:
59+
self._logging(f"MN Demodulation failed: Missing protocol_id in msg_data: {msg_data}", 3)
60+
return []
61+
62+
protocol_id = msg_data["protocol_id"]
63+
64+
if not self.protocol_exists(protocol_id):
65+
self._logging(f"MN Demodulation: Protocol ID {protocol_id} not found.", 3)
66+
return []
67+
68+
method_name_full = self.get_property(protocol_id, 'method')
69+
70+
if not method_name_full:
71+
self._logging(f"MN Demodulation: No method defined for protocol {protocol_id}. Data: {msg_data.get('data', '')}", 3)
72+
return []
73+
74+
# MN messages usually pass the raw data directly (no bit conversion)
75+
# We assume the method handles raw hex/data string or needs it as hex.
76+
# The method name is expected to be 'method_name' or 'module.method_name'
77+
method_name = method_name_full.split('.')[-1]
78+
79+
if hasattr(self, method_name) and callable(getattr(self, method_name)):
80+
method_func = getattr(self, method_name)
81+
82+
# MN methods might be called differently than MC methods, let's check existing ones
83+
# For now, we will assume they take msg_data and return a list of decoded messages/dicts
84+
try:
85+
# Generic call signature for new methods, using msg_data and msg_type for context
86+
demodulated_list = method_func(msg_data, msg_type)
87+
except TypeError:
88+
self._logging(f"MN Demodulation: Method {method_name} failed due to wrong signature/arguments.", 3)
89+
return []
90+
else:
91+
self._logging(f"MN Demodulation: Unknown method {method_name} referenced by '{method_name_full}'.", 3)
92+
return []
93+
94+
if not isinstance(demodulated_list, list):
95+
self._logging(f"MN Demodulation: Method {method_name} returned non-list: {type(demodulated_list)}.", 3)
96+
return []
97+
98+
return demodulated_list
99+
41100
def set_defaults(self):
42101
for pid, proto in self._protocols.items():
43102
proto.setdefault("active", True)
@@ -52,4 +111,3 @@ def _logging(self, message: str, level: int = 3):
52111
"""Log a message if a callback is registered."""
53112
if self._log_callback:
54113
self._log_callback(message, level)
55-

0 commit comments

Comments
 (0)