8
8
from matter_server .common .models import UpdateSource
9
9
from matter_server .server .ota import dcl
10
10
11
- _local_updates : dict [tuple [int , int ], dict ] = {}
11
+ MatterProduct = tuple [int , int ]
12
+
13
+ _local_updates : dict [MatterProduct , dict [int | str , dict ]] = {}
12
14
13
15
14
16
async def load_local_updates (ota_provider_dir : Path ) -> None :
@@ -21,9 +23,12 @@ def _load_update(ota_provider_dir: Path) -> None:
21
23
with open (update_file ) as f :
22
24
update = json .load (f )
23
25
model_version = update ["modelVersion" ]
24
- _local_updates [(model_version ["vid" ], model_version ["pid" ])] = (
25
- model_version
26
- )
26
+ model_key = (model_version ["vid" ], model_version ["pid" ])
27
+ update_dict = _local_updates .get (model_key , {})
28
+ # Store by string or integer, this allows update by both
29
+ update_dict [model_version ["softwareVersion" ]] = model_version
30
+ update_dict [model_version ["softwareVersionString" ]] = model_version
31
+ _local_updates [model_key ] = update_dict
27
32
28
33
await asyncio .get_running_loop ().run_in_executor (
29
34
None , _load_update , ota_provider_dir
@@ -38,14 +43,16 @@ async def check_for_update(
38
43
requested_software_version : int | str | None = None ,
39
44
) -> tuple [UpdateSource , dict ] | tuple [None , None ]:
40
45
"""Check for software updates."""
41
- if (vid , pid ) in _local_updates :
42
- local_update = _local_updates [(vid , pid )]
43
- if (
44
- requested_software_version is None
45
- or local_update ["softwareVersion" ] == requested_software_version
46
- or local_update ["softwareVersionString" ] == requested_software_version
47
- ):
48
- return UpdateSource .LOCAL , local_update
46
+ if local_updates := _local_updates .get ((vid , pid )):
47
+ logger .info ("Local updates found for this device" )
48
+ if requested_software_version is None :
49
+ # Use integer version to reliably determine absolute latest version
50
+ versions = filter (
51
+ lambda version : isinstance (version , int ), local_updates .keys ()
52
+ )
53
+ return UpdateSource .LOCAL , local_updates [max (versions )]
54
+ if requested_software_version in local_updates :
55
+ return UpdateSource .LOCAL , local_updates [requested_software_version ]
49
56
50
57
if dcl_update := await dcl .check_for_update (
51
58
logger , vid , pid , current_software_version , requested_software_version
0 commit comments