@@ -194,8 +194,9 @@ def add_handler(self, handler, callback):
194194 """
195195 Add a callback for the given situation
196196 """
197- if handler not in ('on_event' , 'on_update_event' ):
198- logger .error ("'handler' must be either on_event or on_update_event" )
197+ valid = ('on_event' , 'on_update_event' , 'on_register_report' , 'on_report_update' )
198+ if handler not in valid :
199+ logger .error ("'handler' must be in %s" % (valid ,))
199200 return
200201
201202 setattr (self , handler , callback )
@@ -713,7 +714,7 @@ async def register_reports(self, reports):
713714 # Handle the subscriptions that the VTN is interested in.
714715 if 'report_requests' in response_payload :
715716 await self .create_report (response_payload )
716-
717+
717718 async def create_report (self , response_payload ):
718719 """
719720 Add the requested reports to the reporting mechanism.
@@ -799,7 +800,7 @@ async def create_report(self, response_payload):
799800
800801 if not single and report_back_duration .total_seconds () > 0 :
801802 callback = partial (self .update_report , report_request_id = report_request_id )
802-
803+
803804 reporting_interval = granularity or report_back_duration
804805 job = self .scheduler .add_job (func = callback ,
805806 trigger = 'cron' ,
@@ -817,15 +818,15 @@ async def create_report(self, response_payload):
817818 'r_ids' : requested_r_ids ,
818819 'granularity' : granularity ,
819820 'job' : None })
820-
821+
821822 async def report_callback ():
822823 await self .update_report (report_request_id )
823824
824825 if 'report_interval' in report_request ['report_specifier' ]:
825826 self .scheduler .add_job (report_callback , 'date' , run_date = report_request ['report_specifier' ]['report_interval' ]['dtstart' ])
826827 else :
827828 await self .update_report (report_request_id )
828-
829+
829830 # Send the oadrCreatedReport message
830831 message_type = 'oadrCreatedReport'
831832 message_payload = {'pending_reports' :
@@ -1021,6 +1022,24 @@ async def on_update_event(self, event):
10211022 if event ['event_descriptor' ]['event_id' ] in self .responded_events :
10221023 return self .responded_events .get (event ['event_descriptor' ]['event_id' ])
10231024
1025+ async def on_report_update (self , report_update ):
1026+ """
1027+ Placeholder for the on_report_update handler.
1028+ """
1029+ logger .warning ("A report update was sent but you don't have an on_report_update handler configured. "
1030+ "You should implement your own on_report_update handler. This handler receives "
1031+ "an oadrReport dict and should not return anything in response." )
1032+ return
1033+
1034+ async def on_register_report (self , report_metadata ):
1035+ """
1036+ Placeholder for the on_register_report handler.
1037+ """
1038+ logger .warning ("A report update was sent but you don't have an on_register_report handler configured. "
1039+ "You should implement your own on_report_update handler. This handler receives "
1040+ "an oadrReport dict and should not return anything in response." )
1041+ return None
1042+
10241043 async def on_cancel_party_registration (self , message ):
10251044 if self .registration_id is None :
10261045 logger .info ('VEN is not registered, doing nothing' )
@@ -1141,6 +1160,35 @@ async def _execute_hooks(self, hook_name, *args, **kwargs):
11411160 logger .error (f"An error occurred while executing your '{ hook_name } ': { hook } :"
11421161 f"{ err .__class__ .__name__ } : { err } " )
11431162
1163+ async def _on_register_report (self , response_payload ):
1164+ report_requests = []
1165+ for report_metadata in response_payload ['reports' ]:
1166+ request = await self .on_register_report (response_payload )
1167+ if request :
1168+ report_requests .append (request )
1169+
1170+ message = self ._create_message ('oadrRegisteredReport' ,
1171+ report_requests = report_requests ,
1172+ ven_id = self .ven_id ,
1173+ response = {'response_code' : 200 ,
1174+ 'response_description' : 'OK' ,
1175+ 'request_id' : response_payload ['request_id' ]})
1176+ service = 'EiReport'
1177+ await self ._perform_request (service , message )
1178+
1179+ async def _on_report_update (self , response_payload ):
1180+ for report_update in response_payload ['reports' ]:
1181+ await self .on_report (response_payload )
1182+ message = self ._create_message ('oadrUpdatedReport' ,
1183+ ven_id = self .ven_id ,
1184+ response = {
1185+ 'request_id' : response_payload ['request_id' ],
1186+ 'response_code' : 200 ,
1187+ 'response_description' : 'OK'
1188+ })
1189+ service = 'EiReport'
1190+ await self ._perform_request (service , message )
1191+
11441192 async def _on_event (self , message ):
11451193 events = message ['events' ]
11461194 invalid_vtn_id = False
@@ -1242,7 +1290,7 @@ async def _event_status_log(self):
12421290 # ignoring the cancelled case
12431291 if event ['event_descriptor' ]['event_status' ] == 'cancelled' :
12441292 continue
1245-
1293+
12461294 event_status = utils .determine_event_status (event ['active_period' ])
12471295 if event_status != event ['event_descriptor' ]['event_status' ]:
12481296 event ['event_descriptor' ]['event_status' ] = event_status
@@ -1279,24 +1327,14 @@ async def _poll(self):
12791327 await self ._on_event (response_payload )
12801328
12811329 elif response_type == 'oadrUpdateReport' :
1282- await self ._on_report (response_payload )
1330+ await self ._on_report_update (response_payload )
12831331
12841332 elif response_type == 'oadrCreateReport' :
12851333 if 'report_requests' in response_payload :
12861334 await self .create_report (response_payload )
12871335
12881336 elif response_type == 'oadrRegisterReport' :
1289- # We don't support receiving reports from the VTN at this moment
1290- logger .warning ("The VTN offered reports, but OpenLEADR "
1291- "does not support reports in this direction." )
1292- message = self ._create_message ('oadrRegisteredReport' ,
1293- report_requests = [],
1294- ven_id = self .ven_id ,
1295- response = {'response_code' : 200 ,
1296- 'response_description' : 'OK' ,
1297- 'request_id' : response_payload ['request_id' ]})
1298- service = 'EiReport'
1299- reponse_type , response_payload = await self ._perform_request (service , message )
1337+ await self ._on_register_report (response_payload )
13001338
13011339 elif response_type == 'oadrCancelPartyRegistration' :
13021340 logger .info ("The VTN required us to cancel the registration. Calling the cancel party registration procedure." )
@@ -1305,7 +1343,7 @@ async def _poll(self):
13051343 elif response_type == 'oadrCancelReport' :
13061344 logger .info ("The VTN required us to cancel a report. Calling the cancel report procedure." )
13071345 await self .cancel_report (response_payload )
1308-
1346+
13091347 else :
13101348 logger .warning (f"No handler implemented for incoming message "
13111349 f"of type { response_type } , ignoring." )
0 commit comments