@@ -61,10 +61,13 @@ class NovastarState:
6161 ftb_active : bool = False # Fade to black (blackout) active
6262 freeze_active : bool = False # Screen freeze active
6363 current_preset_id : int = - 1 # -1 means no preset active
64+ background_enabled : bool = False
65+ background_id : int = 0
6466 screens : list [NovastarScreen ] = field (default_factory = list )
6567 presets : list [NovastarPreset ] = field (default_factory = list )
6668 inputs : list [dict [str , Any ]] = field (default_factory = list )
6769 layers : list [dict [str , Any ]] = field (default_factory = list )
70+ backgrounds : list [dict [str , Any ]] = field (default_factory = list )
6871
6972
7073class NovastarClient :
@@ -109,6 +112,9 @@ def __init__(
109112 self ._last_preset_id : int | None = None
110113 self ._force_refresh_input_details = False
111114 self ._force_refresh_layer_details = False
115+ self ._background_list_cache : list [dict [str , Any ]] = []
116+ self ._background_refresh_counter = 0
117+ self ._force_refresh_backgrounds = False
112118
113119 @property
114120 def host (self ) -> str :
@@ -196,7 +202,7 @@ def _build_request(self, body: dict[str, Any]) -> dict[str, Any]:
196202
197203 async def _async_request (
198204 self , endpoint : str , body : dict [str , Any ]
199- ) -> dict [ str , Any ] | None :
205+ ) -> Any | None :
200206 """Send POST request to Novastar API.
201207
202208 Args:
@@ -235,7 +241,9 @@ async def _async_request(
235241 body_data = data .get ("body" ) or data .get ("data" ) or {}
236242 if self ._encryption and isinstance (body_data , str ):
237243 return self ._decrypt_body (body_data )
238- return body_data if isinstance (body_data , dict ) else {}
244+ if isinstance (body_data , (dict , list )):
245+ return body_data
246+ return {}
239247
240248 except aiohttp .ClientError as ex :
241249 _LOGGER .debug ("Connection error to %s: %s" , url , ex )
@@ -431,9 +439,44 @@ async def async_get_state(
431439 state .signal_status = temp_data .get ("signal_status" )
432440 state .inputs = await self .async_get_inputs_with_details (device_id )
433441 state .layers = await self .async_get_layers_with_details (device_id , screen_id )
442+ state .backgrounds = await self .async_get_background_list (device_id )
434443
435444 return state
436445
446+ async def async_get_background_list (
447+ self , device_id : int = 0
448+ ) -> list [dict [str , Any ]]:
449+ """Get available backgrounds from bkg/readAllList with lightweight caching."""
450+ self ._background_refresh_counter += 1
451+ periodic_refresh = self ._background_refresh_counter % 12 == 0
452+ should_refresh = periodic_refresh or self ._force_refresh_backgrounds
453+
454+ if not self ._background_list_cache or should_refresh :
455+ self ._force_refresh_backgrounds = False
456+ data = await self ._async_request ("bkg/readAllList" , {"deviceId" : device_id })
457+ if isinstance (data , list ):
458+ parsed : list [dict [str , Any ]] = []
459+ for item in data :
460+ if not isinstance (item , dict ):
461+ continue
462+ bkg_id = item .get ("bkgId" )
463+ if not isinstance (bkg_id , int ):
464+ continue
465+ general = item .get ("general" )
466+ name = item .get ("name" )
467+ if isinstance (general , dict ) and isinstance (general .get ("name" ), str ):
468+ name = general .get ("name" )
469+ parsed .append (
470+ {
471+ "bkgId" : bkg_id ,
472+ "name" : name if isinstance (name , str ) else f"BKG { bkg_id } " ,
473+ }
474+ )
475+ parsed .sort (key = lambda item : item .get ("bkgId" , 0 ))
476+ self ._background_list_cache = parsed
477+
478+ return list (self ._background_list_cache )
479+
437480 async def async_get_input_list (self , device_id : int = 0 ) -> list [dict [str , Any ]]:
438481 """Read all available inputs from input/readList."""
439482 data = await self ._async_request ("input/readList" , {"deviceId" : device_id })
@@ -654,7 +697,7 @@ async def async_get_device_status_info(
654697
655698 async def async_send_raw_command (
656699 self , endpoint : str , body : dict [str , Any ]
657- ) -> dict [ str , Any ] | None :
700+ ) -> Any | None :
658701 """Send a raw API command.
659702
660703 Args:
@@ -666,6 +709,26 @@ async def async_send_raw_command(
666709 """
667710 return await self ._async_request (endpoint , body )
668711
712+ async def async_set_background (
713+ self ,
714+ background_id : int ,
715+ enabled : bool ,
716+ screen_id : int = 0 ,
717+ device_id : int = 0 ,
718+ ) -> bool :
719+ """Set screen background using screen/writeBKG."""
720+ payload = {
721+ "screenId" : int (screen_id ),
722+ "deviceId" : int (device_id ),
723+ "enable" : 0 if enabled else 1 ,
724+ "bkgId" : max (0 , int (background_id )),
725+ }
726+ data = await self ._async_request ("screen/writeBKG" , payload )
727+ if data is not None :
728+ self ._force_refresh_backgrounds = True
729+ return True
730+ return False
731+
669732 async def async_set_layer_source (
670733 self ,
671734 layer_id : int ,
0 commit comments