88import sys
99import webbrowser
1010from dataclasses import replace
11- from typing import TYPE_CHECKING
11+ from typing import TYPE_CHECKING , NamedTuple
1212
1313if TYPE_CHECKING :
1414 from collections .abc import Awaitable , Callable
1515
1616from flameconnect .auth import MsalAuth
1717from flameconnect .client import FlameConnectClient
18+ from flameconnect .const import (
19+ DEFAULT_TARGET_TEMPERATURE ,
20+ MAX_BOOST_DURATION ,
21+ MAX_FLAME_SPEED ,
22+ MIN_BOOST_DURATION ,
23+ MIN_FLAME_SPEED ,
24+ )
1825from flameconnect .models import (
1926 NAMED_COLORS ,
2027 Brightness ,
97104 "celsius" : TempUnit .CELSIUS ,
98105}
99106
107+
108+ class _FlameEffectSetter (NamedTuple ):
109+ field : str
110+ lookup : dict [str , object ]
111+ label : str
112+
113+
100114_SET_PARAM_NAMES = (
101115 "mode, flame-speed, brightness, pulsating, flame-color,"
102116 " media-theme, heat-status, heat-mode, heat-temp, timer,"
@@ -149,7 +163,7 @@ def _display_flame_effect(param: FlameEffectParam) -> None:
149163 print (f" { '─' * 40 } " )
150164 flame = display_name (param .flame_effect )
151165 print (f" Flame: { flame } " )
152- print (f" Flame Speed: { param .flame_speed } / 5 " )
166+ print (f" Flame Speed: { param .flame_speed } / { MAX_FLAME_SPEED } " )
153167 brightness = display_name (param .brightness )
154168 pulsating = display_name (param .pulsating_effect )
155169 print (f" Brightness: { brightness } " )
@@ -374,43 +388,43 @@ async def cmd_status(client: FlameConnectClient, fire_id: str) -> None:
374388 _display_parameter (param , temp_unit )
375389
376390
377- _FLAME_EFFECT_SETTERS : dict [str , tuple [ str , dict [ str , object ], str ] ] = {
378- "brightness" : (
391+ _FLAME_EFFECT_SETTERS : dict [str , _FlameEffectSetter ] = {
392+ "brightness" : _FlameEffectSetter (
379393 "brightness" ,
380394 {"low" : Brightness .LOW , "high" : Brightness .HIGH },
381395 "Brightness" ,
382396 ),
383- "pulsating" : (
397+ "pulsating" : _FlameEffectSetter (
384398 "pulsating_effect" ,
385399 dict [str , object ](_PULSATING_LOOKUP ),
386400 "Pulsating effect" ,
387401 ),
388- "flame-color" : (
402+ "flame-color" : _FlameEffectSetter (
389403 "flame_color" ,
390404 dict [str , object ](_FLAME_COLOR_LOOKUP ),
391405 "Flame color" ,
392406 ),
393- "media-theme" : (
407+ "media-theme" : _FlameEffectSetter (
394408 "media_theme" ,
395409 dict [str , object ](_MEDIA_THEME_LOOKUP ),
396410 "Media theme" ,
397411 ),
398- "flame-effect" : (
412+ "flame-effect" : _FlameEffectSetter (
399413 "flame_effect" ,
400414 {"on" : FlameEffect .ON , "off" : FlameEffect .OFF },
401415 "Flame effect" ,
402416 ),
403- "media-light" : (
417+ "media-light" : _FlameEffectSetter (
404418 "media_light" ,
405419 {"on" : LightStatus .ON , "off" : LightStatus .OFF },
406420 "Media light" ,
407421 ),
408- "overhead-light" : (
422+ "overhead-light" : _FlameEffectSetter (
409423 "light_status" ,
410424 {"on" : LightStatus .ON , "off" : LightStatus .OFF },
411425 "Overhead light" ,
412426 ),
413- "ambient-sensor" : (
427+ "ambient-sensor" : _FlameEffectSetter (
414428 "ambient_sensor" ,
415429 {"on" : LightStatus .ON , "off" : LightStatus .OFF },
416430 "Ambient sensor" ,
@@ -477,7 +491,9 @@ async def _set_mode(client: FlameConnectClient, fire_id: str, value: str) -> Non
477491 current_mode = param
478492 break
479493
480- temperature = current_mode .target_temperature if current_mode else 22.0
494+ temperature = (
495+ current_mode .target_temperature if current_mode else DEFAULT_TARGET_TEMPERATURE
496+ )
481497 mode = FireMode .STANDBY if value == "standby" else FireMode .MANUAL
482498 mode_param = ModeParam (mode = mode , target_temperature = temperature )
483499 await client .write_parameters (fire_id , [mode_param ])
@@ -489,8 +505,11 @@ async def _set_flame_speed(
489505) -> None :
490506 """Set flame speed (1-5)."""
491507 speed = int (value )
492- if speed < 1 or speed > 5 :
493- print ("Error: flame-speed must be between 1 and 5." )
508+ if speed < MIN_FLAME_SPEED or speed > MAX_FLAME_SPEED :
509+ print (
510+ f"Error: flame-speed must be between"
511+ f" { MIN_FLAME_SPEED } and { MAX_FLAME_SPEED } ."
512+ )
494513 sys .exit (1 )
495514 overview = await client .get_fire_overview (fire_id )
496515 current = _find_param (overview .parameters , FlameEffectParam )
@@ -540,8 +559,12 @@ async def _set_heat_mode(client: FlameConnectClient, fire_id: str, value: str) -
540559 except (ValueError , IndexError ):
541560 print ("Error: boost format is boost:<minutes> (e.g., boost:15)." )
542561 sys .exit (1 )
543- if not 1 <= boost_minutes <= 20 :
544- print ("Error: boost duration must be 1-20 minutes." )
562+ if not MIN_BOOST_DURATION <= boost_minutes <= MAX_BOOST_DURATION :
563+ print (
564+ f"Error: boost duration must be"
565+ f" { MIN_BOOST_DURATION } -{ MAX_BOOST_DURATION } "
566+ " minutes."
567+ )
545568 sys .exit (1 )
546569 heat_mode = HeatMode .BOOST
547570 elif value in _HEAT_MODE_LOOKUP :
0 commit comments