@@ -129,27 +129,33 @@ def __setattr__(self, attr, value):
129
129
super ().__setattr__ (attr , value )
130
130
131
131
def _build_rec_dict (self , naming_map , appendTo ):
132
+ # This function builds a dict of records from a pack, which gets converted to CBOR and
133
+ # pushed to the cloud on the next update.
132
134
if isinstance (self .value , dict ):
133
135
for r in self .value .values ():
134
- if r .value is not None : # NOTE: should filter by updated when it's supported.
135
- r ._build_rec_dict (naming_map , appendTo )
136
- elif self ._value is not None :
136
+ r ._build_rec_dict (naming_map , appendTo )
137
+ else :
137
138
super ()._build_rec_dict (naming_map , appendTo )
138
139
139
- def add_to_pack (self , pack ):
140
+ def add_to_pack (self , pack , push = False ):
141
+ # This function adds records that will be pushed to (or updated from) the cloud, to the SenML pack.
142
+ # NOTE: When adding records to be pushed to the cloud (push=True) Only initialized records are added
143
+ # to the pack. And when adding records to be updated from the cloud (push=False), records whose values
144
+ # are None are allowed to be added to the pack, so they can be initialized from the cloud.
145
+ # NOTE: all initialized sub-records are added to the pack whether they changed their state since the
146
+ # last update or not, because the cloud currently does not support partial objects updates.
140
147
if isinstance (self .value , dict ):
141
148
for r in self .value .values ():
142
- # NOTE: If record value is None it can still be added to the pack for initialization.
143
- pack .add (r ) # NOTE: should filter by updated when it's supported.
144
- else :
149
+ if r . _value is not None or ( r . _value is None and not push ):
150
+ pack .add (r )
151
+ elif self . _value is not None or ( self . _value is None and not push ) :
145
152
pack .add (self )
146
153
self .updated = False
147
154
148
155
def senml_callback (self , record , ** kwargs ):
149
- """
150
- This is called after the record is updated from the cloud. Clear the updated flag to
151
- avoid sending the same value back to the cloud, and schedule the on_write callback.
152
- """
156
+ # This function gets called after a record is updated from the cloud (from_cbor).
157
+ # The updated flag is cleared to avoid sending the same value again to the cloud,
158
+ # and the on_write function flag is set to so it gets called on the next run.
153
159
self .updated = False
154
160
self .on_write_scheduled = True
155
161
@@ -235,9 +241,7 @@ def register(self, aiotobj, **kwargs):
235
241
self .register ("r:m" , value = "getLastValues" )
236
242
237
243
def senml_generic_callback (self , record , ** kwargs ):
238
- """
239
- This callback catches all unknown/umatched records that were not part the pack.
240
- """
244
+ # This callback catches all unknown/umatched sub/records that were not part of the pack.
241
245
rname , sname = record .name .split (":" ) if ":" in record .name else [record .name , None ]
242
246
if rname in self .records :
243
247
logging .debug (f"Ignoring cloud initialization for record: { record .name } " )
@@ -278,7 +282,7 @@ async def mqtt_task(self, interval=0.100):
278
282
self .senmlpack .clear ()
279
283
for record in self .records .values ():
280
284
if record .updated :
281
- record .add_to_pack (self .senmlpack )
285
+ record .add_to_pack (self .senmlpack , push = True )
282
286
if len (self .senmlpack ._data ):
283
287
logging .debug ("Pushing records to Arduino IoT cloud:" )
284
288
for record in self .senmlpack :
0 commit comments