1- """Fetch one or more BSB-LAN parameters and print the raw API response.
1+ """Fetch BSB-LAN parameters and print the raw API response.
2+
3+ Uses BSB-LAN's URL commands (https://docs.bsb-lan.de/using.html):
4+
5+ - ``/JQ`` (default): query current parameter values.
6+ - ``/JC`` (``--structure``): dump the parameter structure, including data
7+ type, read/write flag, unit, and enum ``possibleValues``. Useful for
8+ verifying that a parameter ID is correct and learning its valid options.
9+ - ``/JK`` (``--category``): dump every parameter in a category.
210
311Usage:
412 export BSBLAN_HOST=192.0.2.1
513 export BSBLAN_PASSKEY=your_passkey # if needed
614
7- # Single parameter
15+ # Single parameter (current value)
816 cd examples && python fetch_param.py 3113
917
1018 # Multiple parameters
1119 cd examples && python fetch_param.py 3113 8700 8740
20+
21+ # Parameter structure (type, unit, read/write, enum options)
22+ cd examples && python fetch_param.py --structure 700 902
23+
24+ # All parameters of a category (e.g. category 1)
25+ cd examples && python fetch_param.py --category 1
1226"""
1327
1428from __future__ import annotations
2135from discovery import get_bsblan_host , get_config_from_env
2236
2337
24- async def fetch_parameters ( param_ids : list [ str ] ) -> None :
25- """Fetch and print raw API response for the given parameter IDs .
38+ async def _build_client ( ) -> BSBLAN :
39+ """Create a configured BSBLAN client from env/mDNS discovery .
2640
27- Args :
28- param_ids: List of BSB-LAN parameter IDs to fetch .
41+ Returns :
42+ A BSBLAN client to use as an async context manager .
2943
3044 """
3145 host , port = await get_bsblan_host ()
@@ -38,29 +52,113 @@ async def fetch_parameters(param_ids: list[str]) -> None:
3852 username = str (env ["username" ]) if env .get ("username" ) else None ,
3953 password = str (env ["password" ]) if env .get ("password" ) else None ,
4054 )
55+ return BSBLAN (config )
4156
42- params_string = "," .join (param_ids )
4357
44- async with BSBLAN (config ) as client :
58+ def _print_result (label : str , result : dict [str , object ]) -> None :
59+ """Pretty-print a raw API response."""
60+ print (label )
61+ print (json .dumps (result , indent = 2 , ensure_ascii = False ))
62+
63+
64+ async def fetch_values (param_ids : list [str ]) -> None :
65+ """Fetch and print current values for the given parameter IDs (/JQ).
66+
67+ Args:
68+ param_ids: List of BSB-LAN parameter IDs to fetch.
69+
70+ """
71+ params_string = "," .join (param_ids )
72+ client = await _build_client ()
73+ async with client :
4574 result = await client ._request ( # noqa: SLF001
4675 params = {"Parameter" : params_string },
4776 )
48- print (f"Raw API response for parameter(s) { params_string } :" )
49- print (json .dumps (result , indent = 2 , ensure_ascii = False ))
77+ _print_result (f"Values for parameter(s) { params_string } :" , result )
78+
79+
80+ async def fetch_structure (param_ids : list [str ]) -> None :
81+ """Fetch and print the parameter structure for the given IDs (/JC).
82+
83+ Shows data type, read/write flag, unit and enum ``possibleValues``.
84+
85+ Args:
86+ param_ids: List of BSB-LAN parameter IDs to inspect.
87+
88+ """
89+ params_string = "," .join (param_ids )
90+ client = await _build_client ()
91+ async with client :
92+ result = await client ._request ( # noqa: SLF001
93+ method = "GET" ,
94+ base_path = f"/JC={ params_string } " ,
95+ params = None ,
96+ )
97+ _print_result (f"Structure for parameter(s) { params_string } :" , result )
98+
99+
100+ async def fetch_category (category : str ) -> None :
101+ """Fetch and print every parameter of a category (/JK).
102+
103+ Args:
104+ category: The BSB-LAN category ID to dump.
105+
106+ """
107+ client = await _build_client ()
108+ async with client :
109+ result = await client ._request ( # noqa: SLF001
110+ method = "GET" ,
111+ base_path = f"/JK={ category } " ,
112+ params = None ,
113+ )
114+ _print_result (f"Parameters in category { category } :" , result )
50115
51116
52117def main () -> None :
53- """Parse arguments and run the fetch ."""
118+ """Parse arguments and run the requested query ."""
54119 parser = argparse .ArgumentParser (
55- description = "Fetch BSB-LAN parameters and print raw JSON response." ,
120+ description = (
121+ "Fetch BSB-LAN parameters and print the raw JSON response. "
122+ "Defaults to current values (/JQ); use --structure (/JC) or "
123+ "--category (/JK) for metadata."
124+ ),
56125 )
57126 parser .add_argument (
58127 "params" ,
59- nargs = "+ " ,
128+ nargs = "* " ,
60129 help = "One or more BSB-LAN parameter IDs (e.g. 3113 8700)" ,
61130 )
131+ mode = parser .add_mutually_exclusive_group ()
132+ mode .add_argument (
133+ "-s" ,
134+ "--structure" ,
135+ action = "store_true" ,
136+ help = (
137+ "Dump parameter structure (data type, unit, read/write, enum "
138+ "options) via /JC instead of current values."
139+ ),
140+ )
141+ mode .add_argument (
142+ "-c" ,
143+ "--category" ,
144+ metavar = "ID" ,
145+ help = "Dump all parameters of the given category ID via /JK." ,
146+ )
62147 args = parser .parse_args ()
63- asyncio .run (fetch_parameters (args .params ))
148+
149+ if args .category is not None :
150+ if args .params :
151+ parser .error ("--category cannot be combined with parameter IDs" )
152+ asyncio .run (fetch_category (args .category ))
153+ return
154+
155+ if not args .params :
156+ parser .error ("at least one parameter ID is required" )
157+
158+ if args .structure :
159+ asyncio .run (fetch_structure (args .params ))
160+ else :
161+ asyncio .run (fetch_values (args .params ))
64162
65163
66164if __name__ == "__main__" :
0 commit comments