def test_unpack_with_invalid_json(): """ Test that correct exception is raised when unpack is called with invalid JSON. """ with pytest.raises(FormatViolationError): unpack(b'\x01')
def test_unpack_without_jsonified_list(): """ OCPP messages are JSONified lists. This test make sure that the correct exception is raised when input is not a JSONified list. """ with pytest.raises(ProtocolError): unpack(json.dumps('3'))
async def test_send_receive(): async with websockets.connect(WEBSOCKET_URL) as websocket: boot_notification_payload = call.BootNotificationPayload( charge_point_model="Test", charge_point_vendor="Test") get_configuration_payload = call_result.GetConfigurationPayload( configuration_key=[{ "key": "GetConfigurationMaxKeys", "readonly": True, "value": "10", }]) ocppj_message = payload_to_ocppj_message(boot_notification_payload, class_type=Call, unique_id=str(uuid4())) await websocket.send(ocppj_message) # -> Call/BootNotificationPayload call_result_msg = (await websocket.recv() ) # <- CallResult/BootNotificationPayload call_result_obj = unpack(call_result_msg) log.info(call_result_obj) assert type(call_result_obj) == CallResult call_msg = await websocket.recv() # <- Call/GetConfiguration call_obj = unpack(call_msg) log.info(call_obj) assert type(call_obj) == Call unique_id = call_obj.unique_id # use Call's unique_id in CallResult ocppj_message = payload_to_ocppj_message(get_configuration_payload, class_type=CallResult, unique_id=unique_id) log.info(ocppj_message) await websocket.send(ocppj_message) # -> CallResult/GetConfiguration
def test_unpack_with_invalid_message_type_id_in_json(): """ OCPP messages only have 3 valid values for MessageTypeID, that is the first element of the OCPP message. This test validates that correct exception is raised when this value is invalid. """ with pytest.raises(PropertyConstraintViolationError): unpack(json.dumps([5, 1]))
def test_unpack_without_message_type_id_in_json(): """ OCPP must contain the MessageTypeID as first element of the message. This test validates if correct exception is raised when this is not the case """ with pytest.raises(ProtocolError): unpack(json.dumps([]))
async def route_message(self, raw_msg): """ Route a message received from a CP. If the message is a of type Call the corresponding hooks are executed. If the message is of type CallResult or CallError the message is passed to the call() function via the response_queue. """ try: msg = unpack(raw_msg) except OCPPError as e: LOGGER.exception( "Unable to parse message: '%s', it doesn't seem " "to be valid OCPP: %s", raw_msg, e) return if msg.message_type_id == MessageType.Call: try: await self._handle_call(msg) except OCPPError as error: LOGGER.exception("Error while handling request '%s'", msg) response = msg.create_call_error(error).to_json() await self._send(response) elif msg.message_type_id in \ [MessageType.CallResult, MessageType.CallError]: self._response_queue.put_nowait(msg)
async def route_message(self, raw_msg): """ Route a message received from a CP. If the message is a of type Call the corresponding hooks are executed. If the message is of type CallResult or CallError the message is passed to the call() function via the response_queue. """ try: msg = unpack(raw_msg) except OCPPError as e: LOGGER.exception( "Unable to parse message: '%s', it doesn't seem " "to be valid OCPP: %s", raw_msg, e, ) return if msg.message_type_id == MessageType.Call: # await self._handle_call(msg) response = await self._handle_call(msg) return response elif msg.message_type_id in [ MessageType.CallResult, MessageType.CallError ]: self._response_queue.put_nowait(msg)
async def route_message(self, *, message: str, context: RouterContext): """ Route a message received from a Charging Station. If the message is a of type Call the corresponding hooks are executed. If the message is of type CallResult or CallError the message is passed to the call() function via the response_queue. """ try: msg = unpack(message) except OCPPError as e: log.exception( "Unable to parse message: '%s', it doesn't seem " "to be valid OCPP: %s", message, e, ) return if msg.message_type_id == MessageType.Call: await self._handle_call(msg, context=context) elif msg.message_type_id in [ MessageType.CallResult, MessageType.CallError, ]: if msg.unique_id in self.subscriptions: self.subscriptions[msg.unique_id].put_nowait(msg)
def message_to_payload(message: str, action: str) -> Any: response = unpack(message) response.action = action validate_payload(response, "1.6") snake_case_payload = camel_to_snake_case(response.payload) cls = getattr(call_result, f"{action}Payload") payload = cls(**snake_case_payload) return payload
def create_call_error(message: str) -> str: """Create CallError serialized representation based on serialize Call. Raises ValueError if message is not type Call. CallResult and CallError don't require response. """ call: Call = unpack(message) if isinstance(call, Call): call_error: CallError = call.create_call_error(None) return call_error.to_json() else: raise ValueError("message is not type Call")
async def get(self) -> str: print(f"get: {self.connection_id}") # What is optimal sleep time while waiting response? # Here we have gradually increasing sleep time up to 1s max sleep_duration = 0.2 sleep_duration_max = 1 while True: msg = self.redis.rpop(self.connection_id) if msg is None or type(msg) is not bytes: print(f"sleep. type(msg): {type(msg)} msg: {msg}") await asyncio.sleep(sleep_duration) if sleep_duration_max < sleep_duration_max: sleep_duration_max += 0.2 else: print(f"get (result): {msg}") return unpack(msg)