@@ -94,7 +94,18 @@ async def __aexit__(self, exc_t, exc_v, exc_tb):
9494 def attach_to_server (
9595 self , server : ThingServer , path : str , setting_storage_path : str
9696 ):
97- """Add HTTP handlers to an app for all Interaction Affordances"""
97+ """Attatch this thing to the server.
98+
99+ Things need to be attached to a server before use to function correctly.
100+
101+ :param server: The server to attach this Thing to
102+ :param settings_storage_path: The path on disk to save the any Thing Settings
103+ to. This should be the path to a json file. If it does not exist it will be
104+ created.
105+
106+ Wc3 Web Of Things explanation:
107+ This will add HTTP handlers to an app for all Interaction Affordances
108+ """
98109 self .path = path
99110 self .action_manager : ActionManager = server .action_manager
100111 self .load_settings (setting_storage_path )
@@ -122,28 +133,37 @@ def thing_description(request: Request) -> ThingDescription:
122133 async def websocket (ws : WebSocket ):
123134 await websocket_endpoint (self , ws )
124135
125- _settings : Optional [list [str ]] = None
136+ # A private variable to hold the list of settings so it doesn't need to be
137+ # iterated through each time it is read
138+ _settings_store : Optional [dict [str , ThingSetting ]] = None
126139
127140 @property
128- def settings (self ):
129- if self ._settings is not None :
130- return self ._settings
141+ def _settings (self ) -> Optional [dict [str , ThingSetting ]]:
142+ """A private property that returns a dict of all settings for this Thing
143+
144+ Each dict key is the name of the setting, the corresponding value is the
145+ ThingSetting class (a descriptor). This can be used to directly get the
146+ descriptor so that the value can be set without emitting signals, such
147+ as on startup.
148+ """
149+ if self ._settings_store is not None :
150+ return self ._settings_store
131151
132- self ._settings = {}
152+ self ._settings_store = {}
133153 for name , attr in class_attributes (self ):
134154 if isinstance (attr , ThingSetting ):
135- self ._settings [name ] = attr
136- return self ._settings
155+ self ._settings_store [name ] = attr
156+ return self ._settings_store
137157
138158 _setting_storage_path : Optional [str ] = None
139159
140160 @property
141161 def setting_storage_path (self ) -> Optional [str ]:
142- """The storage path for settings. This is set at runtime. """
162+ """The storage path for settings. This is set as the Thing is added to a server """
143163 return self ._setting_storage_path
144164
145165 def load_settings (self , setting_storage_path ):
146- """Load settings from json. Called when connecting to the server. """
166+ """Load settings from json. This is run when the Thing is added to a server"""
147167 # Ensure that the settings path isn't set during loading or saving will be triggered
148168 self ._setting_storage_path = None
149169 thing_name = type (self ).__name__
@@ -152,8 +172,8 @@ def load_settings(self, setting_storage_path):
152172 with open (setting_storage_path , "r" , encoding = "utf-8" ) as file_obj :
153173 setting_dict = json .load (file_obj )
154174 for key , value in setting_dict .items ():
155- if key in self .settings :
156- self .settings [key ].set_without_emit (self , value )
175+ if key in self ._settings :
176+ self ._settings [key ].set_without_emit (self , value )
157177 else :
158178 _LOGGER .warning (
159179 "Cannot set %s from persistent storage as %s has no matching setting." ,
@@ -165,10 +185,10 @@ def load_settings(self, setting_storage_path):
165185 self ._setting_storage_path = setting_storage_path
166186
167187 def save_settings (self ):
168- """Save settings to JSON. This is called when a setting is updated with a setter """
169- if self .settings is not None :
188+ """Save settings to JSON. This is called whenever a setting is updated"""
189+ if self ._settings is not None :
170190 setting_dict = {}
171- for name in self .settings .keys ():
191+ for name in self ._settings .keys ():
172192 value = getattr (self , name )
173193 if isinstance (value , BaseModel ):
174194 value = value .model_dump ()
0 commit comments