From d29eb17d651061bb1d8f2be3bc83f154e62df363 Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Thu, 19 Oct 2023 22:56:44 +1300 Subject: [PATCH 01/21] Add NotImplemented exception --- ocpp/charge_point.py | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/ocpp/charge_point.py b/ocpp/charge_point.py index 78f56549e..f951f1dbb 100644 --- a/ocpp/charge_point.py +++ b/ocpp/charge_point.py @@ -7,9 +7,11 @@ from dataclasses import asdict from typing import Dict, List, Union -from ocpp.exceptions import NotSupportedError, OCPPError +from ocpp.exceptions import NotImplementedError, NotSupportedError, OCPPError from ocpp.messages import Call, MessageType, unpack, validate_payload from ocpp.routing import create_route_map +from ocpp.v16.enums import Action as v16_Action +from ocpp.v201.enums import Action as v201_Action LOGGER = logging.getLogger("ocpp") @@ -165,7 +167,8 @@ async def _handle_call(self, msg): First the '_on_action' hook is executed and its response is returned to the client. If there is no '_on_action' hook for Action in the message - a CallError with a NotSupportedError is returned. + a CallError with a NotImplementedError is returned. If the Action is + not supported by the OCPP version a NotSupportedError is returned. Next the '_after_action' hook is executed. @@ -173,9 +176,20 @@ async def _handle_call(self, msg): try: handlers = self.route_map[msg.action] except KeyError: - raise NotSupportedError( - details={"cause": f"No handler for {msg.action} registered."} - ) + if self._ocpp_version == "1.6": + if hasattr(v16_Action, msg.action): + raise NotImplementedError( + details={"cause": f"No handler for {msg.action} registered."} + ) + elif self._ocpp_version in ["2.0", "2.0.1"]: + if hasattr(v201_Action, msg.action): + raise NotImplementedError( + details={"cause": f"No handler for {msg.action} registered."} + ) + else: + raise NotSupportedError( + details={"cause": f"{msg.action} not supported by OCPP{self._ocpp_version}."} + ) if not handlers.get("_skip_schema_validation", False): validate_payload(msg, self._ocpp_version) @@ -190,9 +204,20 @@ async def _handle_call(self, msg): try: handler = handlers["_on_action"] except KeyError: - raise NotSupportedError( - details={"cause": f"No handler for {msg.action} registered."} - ) + if self._ocpp_version == "1.6": + if hasattr(v16_Action, msg.action): + raise NotImplementedError( + details={"cause": f"No handler for {msg.action} registered."} + ) + elif self._ocpp_version in ["2.0", "2.0.1"]: + if hasattr(v201_Action, msg.action): + raise NotImplementedError( + details={"cause": f"No handler for {msg.action} registered."} + ) + else: + raise NotSupportedError( + details={"cause": f"{msg.action} not supported by OCPP{self._ocpp_version}."} + ) try: response = handler(**snake_case_payload) From 27331c8664ba1ad58d06e8995a7ce3fb4555e736 Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Thu, 19 Oct 2023 23:02:08 +1300 Subject: [PATCH 02/21] fix linting --- ocpp/charge_point.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ocpp/charge_point.py b/ocpp/charge_point.py index f951f1dbb..f8599b8c2 100644 --- a/ocpp/charge_point.py +++ b/ocpp/charge_point.py @@ -188,7 +188,9 @@ async def _handle_call(self, msg): ) else: raise NotSupportedError( - details={"cause": f"{msg.action} not supported by OCPP{self._ocpp_version}."} + details={ + "cause": f"{msg.action} not supported by OCPP{self._ocpp_version}." + } ) if not handlers.get("_skip_schema_validation", False): @@ -216,7 +218,9 @@ async def _handle_call(self, msg): ) else: raise NotSupportedError( - details={"cause": f"{msg.action} not supported by OCPP{self._ocpp_version}."} + details={ + "cause": f"{msg.action} not supported by OCPP{self._ocpp_version}." + } ) try: From 3786cdc3bef95b26165bda6c0c3bf2d5d9910ca4 Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Thu, 19 Oct 2023 23:06:15 +1300 Subject: [PATCH 03/21] fix linting --- ocpp/charge_point.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ocpp/charge_point.py b/ocpp/charge_point.py index f8599b8c2..20dec6fa6 100644 --- a/ocpp/charge_point.py +++ b/ocpp/charge_point.py @@ -189,7 +189,8 @@ async def _handle_call(self, msg): else: raise NotSupportedError( details={ - "cause": f"{msg.action} not supported by OCPP{self._ocpp_version}." + "cause": + f"{msg.action} not supported by OCPP{self._ocpp_version}." } ) @@ -219,7 +220,8 @@ async def _handle_call(self, msg): else: raise NotSupportedError( details={ - "cause": f"{msg.action} not supported by OCPP{self._ocpp_version}." + "cause": + f"{msg.action} not supported by OCPP{self._ocpp_version}." } ) From 515370915dcdb1e1e870a1cd6382f22e3aa55427 Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Thu, 19 Oct 2023 23:09:20 +1300 Subject: [PATCH 04/21] alt linting fix --- ocpp/charge_point.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ocpp/charge_point.py b/ocpp/charge_point.py index 20dec6fa6..862181c9c 100644 --- a/ocpp/charge_point.py +++ b/ocpp/charge_point.py @@ -189,8 +189,8 @@ async def _handle_call(self, msg): else: raise NotSupportedError( details={ - "cause": - f"{msg.action} not supported by OCPP{self._ocpp_version}." + "cause": f"{msg.action} not supported by OCPP" + "{self._ocpp_version}." } ) @@ -220,8 +220,8 @@ async def _handle_call(self, msg): else: raise NotSupportedError( details={ - "cause": - f"{msg.action} not supported by OCPP{self._ocpp_version}." + "cause": f"{msg.action} not supported by OCPP" + "{self._ocpp_version}." } ) From ceb4055a2b521e21c53b0a27ad81fc7628d5e312 Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Fri, 20 Oct 2023 08:45:38 +1300 Subject: [PATCH 05/21] Shift to private function --- ocpp/charge_point.py | 64 +++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/ocpp/charge_point.py b/ocpp/charge_point.py index 862181c9c..7f510a1f9 100644 --- a/ocpp/charge_point.py +++ b/ocpp/charge_point.py @@ -81,6 +81,34 @@ def remove_nones(data: Union[List, Dict]) -> Union[List, Dict]: return data +def _raise_keyerror(action, version): + """ + Checks whether a keyerror returned by _handle_call + is supported by the OCPP version or is simply + not implemented by the server/client and raises + the appropriate error. + """ + + if version == "1.6": + if hasattr(v16_Action, action): + raise NotImplementedError( + details={"cause": f"No handler for {action} registered."} + ) + elif version in ["2.0", "2.0.1"]: + if hasattr(v201_Action, action): + raise NotImplementedError( + details={"cause": f"No handler for {action} registered."} + ) + else: + raise NotSupportedError( + details={ + "cause": f"{msg.action} not supported by OCPP{version}." + } + ) + + return + + class ChargePoint: """ Base Element containing all the necessary OCPP1.6J messages for messages @@ -176,23 +204,7 @@ async def _handle_call(self, msg): try: handlers = self.route_map[msg.action] except KeyError: - if self._ocpp_version == "1.6": - if hasattr(v16_Action, msg.action): - raise NotImplementedError( - details={"cause": f"No handler for {msg.action} registered."} - ) - elif self._ocpp_version in ["2.0", "2.0.1"]: - if hasattr(v201_Action, msg.action): - raise NotImplementedError( - details={"cause": f"No handler for {msg.action} registered."} - ) - else: - raise NotSupportedError( - details={ - "cause": f"{msg.action} not supported by OCPP" - "{self._ocpp_version}." - } - ) + _raise_keyerror(msg.action, self._ocpp_version) if not handlers.get("_skip_schema_validation", False): validate_payload(msg, self._ocpp_version) @@ -207,23 +219,7 @@ async def _handle_call(self, msg): try: handler = handlers["_on_action"] except KeyError: - if self._ocpp_version == "1.6": - if hasattr(v16_Action, msg.action): - raise NotImplementedError( - details={"cause": f"No handler for {msg.action} registered."} - ) - elif self._ocpp_version in ["2.0", "2.0.1"]: - if hasattr(v201_Action, msg.action): - raise NotImplementedError( - details={"cause": f"No handler for {msg.action} registered."} - ) - else: - raise NotSupportedError( - details={ - "cause": f"{msg.action} not supported by OCPP" - "{self._ocpp_version}." - } - ) + _raise_keyerror(msg.action, self._ocpp_version) try: response = handler(**snake_case_payload) From b933aa46e0f4da882c5fcf05b0c2e832cdbf85b8 Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Fri, 20 Oct 2023 08:48:03 +1300 Subject: [PATCH 06/21] fix linting --- ocpp/charge_point.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ocpp/charge_point.py b/ocpp/charge_point.py index 7f510a1f9..4b84ff4da 100644 --- a/ocpp/charge_point.py +++ b/ocpp/charge_point.py @@ -101,11 +101,9 @@ def _raise_keyerror(action, version): ) else: raise NotSupportedError( - details={ - "cause": f"{msg.action} not supported by OCPP{version}." - } + details={"cause": f"{msg.action} not supported by OCPP{version}."} ) - + return From d6b745eb2bdab318cdecd0a3d3513d1da34d428f Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Fri, 20 Oct 2023 08:50:08 +1300 Subject: [PATCH 07/21] remove incorrect ref --- ocpp/charge_point.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ocpp/charge_point.py b/ocpp/charge_point.py index 4b84ff4da..e7d6d3771 100644 --- a/ocpp/charge_point.py +++ b/ocpp/charge_point.py @@ -101,7 +101,7 @@ def _raise_keyerror(action, version): ) else: raise NotSupportedError( - details={"cause": f"{msg.action} not supported by OCPP{version}."} + details={"cause": f"{action} not supported by OCPP{version}."} ) return From 364b5ab0aa416b60f9e63ac4d432350402428db1 Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Fri, 20 Oct 2023 08:53:45 +1300 Subject: [PATCH 08/21] Move circ import to func --- ocpp/charge_point.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ocpp/charge_point.py b/ocpp/charge_point.py index e7d6d3771..a8d3c5da5 100644 --- a/ocpp/charge_point.py +++ b/ocpp/charge_point.py @@ -10,8 +10,6 @@ from ocpp.exceptions import NotImplementedError, NotSupportedError, OCPPError from ocpp.messages import Call, MessageType, unpack, validate_payload from ocpp.routing import create_route_map -from ocpp.v16.enums import Action as v16_Action -from ocpp.v201.enums import Action as v201_Action LOGGER = logging.getLogger("ocpp") @@ -89,6 +87,9 @@ def _raise_keyerror(action, version): the appropriate error. """ + from ocpp.v16.enums import Action as v16_Action + from ocpp.v201.enums import Action as v201_Action + if version == "1.6": if hasattr(v16_Action, action): raise NotImplementedError( From a12d2d50a42905268f9b4101df14c81714f073b7 Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Fri, 20 Oct 2023 10:54:12 +1300 Subject: [PATCH 09/21] Update existing tests --- tests/v16/test_v16_charge_point.py | 4 ++-- tests/v20/test_v20_charge_point.py | 4 ++-- tests/v201/test_v201_charge_point.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/v16/test_v16_charge_point.py b/tests/v16/test_v16_charge_point.py index 5471e1618..6e002ffe8 100644 --- a/tests/v16/test_v16_charge_point.py +++ b/tests/v16/test_v16_charge_point.py @@ -124,8 +124,8 @@ async def test_route_message_with_no_route(base_central_system, heartbeat_call): [ 4, 1, - "NotSupported", - "Request Action is recognized but not supported by the receiver", + "NotImplemented", + "Requested Action is not known by receiver", {"cause": "No handler for Heartbeat registered."}, ], separators=(",", ":"), diff --git a/tests/v20/test_v20_charge_point.py b/tests/v20/test_v20_charge_point.py index 9226b8ba4..56c49a9ec 100644 --- a/tests/v20/test_v20_charge_point.py +++ b/tests/v20/test_v20_charge_point.py @@ -76,8 +76,8 @@ async def test_route_message_with_no_route(base_central_system, heartbeat_call): [ 4, 1, - "NotSupported", - "Request Action is recognized but not supported by the receiver", + "NotImplemented", + "Requested Action is not known by receiver", {"cause": "No handler for Heartbeat registered."}, ], separators=(",", ":"), diff --git a/tests/v201/test_v201_charge_point.py b/tests/v201/test_v201_charge_point.py index 8624c90ca..eacc22d7a 100644 --- a/tests/v201/test_v201_charge_point.py +++ b/tests/v201/test_v201_charge_point.py @@ -76,8 +76,8 @@ async def test_route_message_with_no_route(base_central_system, heartbeat_call): [ 4, 1, - "NotSupported", - "Request Action is recognized but not supported by the receiver", + "NotImplemented", + "Requested Action is not known by receiver", {"cause": "No handler for Heartbeat registered."}, ], separators=(",", ":"), From dfa6b1fd0b324819279d60ab11337ee466e4c539 Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Fri, 20 Oct 2023 11:39:19 +1300 Subject: [PATCH 10/21] Add extra test, align defs with spec --- ocpp/exceptions.py | 8 ++++---- tests/v16/conftest.py | 3 +++ tests/v16/test_v16_charge_point.py | 25 ++++++++++++++++++++++++- tests/v20/test_v20_charge_point.py | 2 +- tests/v201/test_v201_charge_point.py | 2 +- 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/ocpp/exceptions.py b/ocpp/exceptions.py index 6c570425f..e2e331cc4 100644 --- a/ocpp/exceptions.py +++ b/ocpp/exceptions.py @@ -35,14 +35,14 @@ def __str__(self): class NotImplementedError(OCPPError): code = "NotImplemented" - default_description = "Requested Action is not known by receiver" + default_description = ( + "Request Action is recognized but not supported by the receiver" + ) class NotSupportedError(OCPPError): code = "NotSupported" - default_description = ( - "Request Action is recognized but not supported by " "the receiver" - ) + default_description = "Requested Action is not known by receiver" class InternalError(OCPPError): diff --git a/tests/v16/conftest.py b/tests/v16/conftest.py index d747bf420..41c4eb290 100644 --- a/tests/v16/conftest.py +++ b/tests/v16/conftest.py @@ -16,6 +16,9 @@ def heartbeat_call(): return Call(unique_id=1, action=Action.Heartbeat, payload={}).to_json() +@pytest.fixture +def notsupported_call(): + return Call(unique_id=1, action="InvalidAction", payload={}).to_json() @pytest.fixture def boot_notification_call(): diff --git a/tests/v16/test_v16_charge_point.py b/tests/v16/test_v16_charge_point.py index 6e002ffe8..d08a6a408 100644 --- a/tests/v16/test_v16_charge_point.py +++ b/tests/v16/test_v16_charge_point.py @@ -125,13 +125,36 @@ async def test_route_message_with_no_route(base_central_system, heartbeat_call): 4, 1, "NotImplemented", - "Requested Action is not known by receiver", + "Request Action is recognized but not supported by the receiver", {"cause": "No handler for Heartbeat registered."}, ], separators=(",", ":"), ) ) +@pytest.mark.asyncio +async def test_route_message_not_supported(base_central_system, notsupported_call): + """ + Test that a CALLERROR is sent back, reporting that it is + not supported by OCPP version. + + """ + # Empty the route map + base_central_system.route_map = {} + + await base_central_system.route_message(notsupported_call) + base_central_system._connection.send.assert_called_once_with( + json.dumps( + [ + 4, + 1, + "NotSupported", + "Requested Action is not known by receiver", + {"cause": "InvalidAction not supported by OCPP1.6."}, + ], + separators=(",", ":"), + ) + ) @pytest.mark.asyncio async def test_send_call_with_timeout(connection): diff --git a/tests/v20/test_v20_charge_point.py b/tests/v20/test_v20_charge_point.py index 56c49a9ec..bb0a04aa2 100644 --- a/tests/v20/test_v20_charge_point.py +++ b/tests/v20/test_v20_charge_point.py @@ -77,7 +77,7 @@ async def test_route_message_with_no_route(base_central_system, heartbeat_call): 4, 1, "NotImplemented", - "Requested Action is not known by receiver", + "Request Action is recognized but not supported by the receiver", {"cause": "No handler for Heartbeat registered."}, ], separators=(",", ":"), diff --git a/tests/v201/test_v201_charge_point.py b/tests/v201/test_v201_charge_point.py index eacc22d7a..ddbd33808 100644 --- a/tests/v201/test_v201_charge_point.py +++ b/tests/v201/test_v201_charge_point.py @@ -77,7 +77,7 @@ async def test_route_message_with_no_route(base_central_system, heartbeat_call): 4, 1, "NotImplemented", - "Requested Action is not known by receiver", + "Request Action is recognized but not supported by the receiver", {"cause": "No handler for Heartbeat registered."}, ], separators=(",", ":"), From 2d7bd7572bb0fb0ea7a1f854e34a51ae97d24988 Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Fri, 20 Oct 2023 11:42:24 +1300 Subject: [PATCH 11/21] fix linting --- tests/v16/conftest.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/v16/conftest.py b/tests/v16/conftest.py index 41c4eb290..70faecd45 100644 --- a/tests/v16/conftest.py +++ b/tests/v16/conftest.py @@ -16,10 +16,12 @@ def heartbeat_call(): return Call(unique_id=1, action=Action.Heartbeat, payload={}).to_json() + @pytest.fixture def notsupported_call(): return Call(unique_id=1, action="InvalidAction", payload={}).to_json() + @pytest.fixture def boot_notification_call(): return Call( From c861e36dbefca8109838529a87ed0f48aeb64a74 Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Fri, 20 Oct 2023 11:42:42 +1300 Subject: [PATCH 12/21] fix linting --- tests/v16/test_v16_charge_point.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/v16/test_v16_charge_point.py b/tests/v16/test_v16_charge_point.py index d08a6a408..a38bcb720 100644 --- a/tests/v16/test_v16_charge_point.py +++ b/tests/v16/test_v16_charge_point.py @@ -132,6 +132,7 @@ async def test_route_message_with_no_route(base_central_system, heartbeat_call): ) ) + @pytest.mark.asyncio async def test_route_message_not_supported(base_central_system, notsupported_call): """ @@ -156,6 +157,7 @@ async def test_route_message_not_supported(base_central_system, notsupported_cal ) ) + @pytest.mark.asyncio async def test_send_call_with_timeout(connection): cs = ChargePoint(id=1234, connection=connection, response_timeout=0.1) From 7269fa82807a03a04939da00f60271efa746a1bf Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Fri, 20 Oct 2023 11:50:23 +1300 Subject: [PATCH 13/21] fix unbounderror in _handle_call --- ocpp/charge_point.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ocpp/charge_point.py b/ocpp/charge_point.py index a8d3c5da5..863010db4 100644 --- a/ocpp/charge_point.py +++ b/ocpp/charge_point.py @@ -204,6 +204,7 @@ async def _handle_call(self, msg): handlers = self.route_map[msg.action] except KeyError: _raise_keyerror(msg.action, self._ocpp_version) + return if not handlers.get("_skip_schema_validation", False): validate_payload(msg, self._ocpp_version) From 67eaa1e34ef7fed19d21e7d028107b54a07ef83a Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Fri, 20 Oct 2023 13:05:11 +1300 Subject: [PATCH 14/21] keep routemap --- tests/v16/test_v16_charge_point.py | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/tests/v16/test_v16_charge_point.py b/tests/v16/test_v16_charge_point.py index a38bcb720..b120bd8ae 100644 --- a/tests/v16/test_v16_charge_point.py +++ b/tests/v16/test_v16_charge_point.py @@ -109,24 +109,22 @@ def on_boot_notification(**kwargs): # noqa @pytest.mark.asyncio -async def test_route_message_with_no_route(base_central_system, heartbeat_call): +async def test_route_message_not_supported(base_central_system, notsupported_call): """ - Test that a CALLERROR is sent back, reporting that no handler is - registred for it. + Test that a CALLERROR is sent back, reporting that it is + not supported by OCPP version. """ - # Empty the route map - base_central_system.route_map = {} - await base_central_system.route_message(heartbeat_call) + await base_central_system.route_message(notsupported_call) base_central_system._connection.send.assert_called_once_with( json.dumps( [ 4, 1, - "NotImplemented", - "Request Action is recognized but not supported by the receiver", - {"cause": "No handler for Heartbeat registered."}, + "NotSupported", + "Requested Action is not known by receiver", + {"cause": "InvalidAction not supported by OCPP1.6."}, ], separators=(",", ":"), ) @@ -134,24 +132,24 @@ async def test_route_message_with_no_route(base_central_system, heartbeat_call): @pytest.mark.asyncio -async def test_route_message_not_supported(base_central_system, notsupported_call): +async def test_route_message_with_no_route(base_central_system, heartbeat_call): """ - Test that a CALLERROR is sent back, reporting that it is - not supported by OCPP version. + Test that a CALLERROR is sent back, reporting that no handler is + registred for it. """ # Empty the route map base_central_system.route_map = {} - await base_central_system.route_message(notsupported_call) + await base_central_system.route_message(heartbeat_call) base_central_system._connection.send.assert_called_once_with( json.dumps( [ 4, 1, - "NotSupported", - "Requested Action is not known by receiver", - {"cause": "InvalidAction not supported by OCPP1.6."}, + "NotImplemented", + "Request Action is recognized but not supported by the receiver", + {"cause": "No handler for Heartbeat registered."}, ], separators=(",", ":"), ) From 256d7a32b196477b309efada133f9fcbac22f40a Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Fri, 20 Oct 2023 13:10:05 +1300 Subject: [PATCH 15/21] create routemap in test --- tests/v16/test_v16_charge_point.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/v16/test_v16_charge_point.py b/tests/v16/test_v16_charge_point.py index b120bd8ae..adb74849a 100644 --- a/tests/v16/test_v16_charge_point.py +++ b/tests/v16/test_v16_charge_point.py @@ -115,6 +115,19 @@ async def test_route_message_not_supported(base_central_system, notsupported_cal not supported by OCPP version. """ + @on(Action.BootNotification) + def on_boot_notification(**kwargs): # noqa + assert kwargs["firmware_version"] == "#1:3.4.0-2990#N:217H;1.0-223" + + return call_result.BootNotificationPayload( + current_time="2018-05-29T17:37:05.495259", + interval=350, + # 'Yolo' is not a valid value for for field status. + status="Yolo", + ) + + setattr(base_central_system, "on_boot_notification", on_boot_notification) + base_central_system.route_map = create_route_map(base_central_system) await base_central_system.route_message(notsupported_call) base_central_system._connection.send.assert_called_once_with( From 7fae169b4f1e91837967258f40bcedfb282f5b1d Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Fri, 20 Oct 2023 13:11:24 +1300 Subject: [PATCH 16/21] fix linting --- tests/v16/test_v16_charge_point.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/v16/test_v16_charge_point.py b/tests/v16/test_v16_charge_point.py index adb74849a..020eeb3aa 100644 --- a/tests/v16/test_v16_charge_point.py +++ b/tests/v16/test_v16_charge_point.py @@ -115,6 +115,7 @@ async def test_route_message_not_supported(base_central_system, notsupported_cal not supported by OCPP version. """ + @on(Action.BootNotification) def on_boot_notification(**kwargs): # noqa assert kwargs["firmware_version"] == "#1:3.4.0-2990#N:217H;1.0-223" From 6186d2e18bfdac2e18d1a8c8add4d64c5ee0fdfb Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Fri, 20 Oct 2023 13:12:49 +1300 Subject: [PATCH 17/21] fix linting --- tests/v16/test_v16_charge_point.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/v16/test_v16_charge_point.py b/tests/v16/test_v16_charge_point.py index 020eeb3aa..4fa402fc6 100644 --- a/tests/v16/test_v16_charge_point.py +++ b/tests/v16/test_v16_charge_point.py @@ -115,7 +115,7 @@ async def test_route_message_not_supported(base_central_system, notsupported_cal not supported by OCPP version. """ - + @on(Action.BootNotification) def on_boot_notification(**kwargs): # noqa assert kwargs["firmware_version"] == "#1:3.4.0-2990#N:217H;1.0-223" From 08a548857813ae9e8f91c4c2bcee0c3a2b28eff1 Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Fri, 20 Oct 2023 13:37:17 +1300 Subject: [PATCH 18/21] Change uniqueid to string --- tests/v16/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/v16/conftest.py b/tests/v16/conftest.py index 70faecd45..25ec09dc0 100644 --- a/tests/v16/conftest.py +++ b/tests/v16/conftest.py @@ -19,7 +19,7 @@ def heartbeat_call(): @pytest.fixture def notsupported_call(): - return Call(unique_id=1, action="InvalidAction", payload={}).to_json() + return Call(unique_id="1", action="InvalidAction", payload={}).to_json() @pytest.fixture From adb185c7077e08175c874372f9471053dd362224 Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Fri, 20 Oct 2023 13:55:07 +1300 Subject: [PATCH 19/21] fix if-then logic --- ocpp/charge_point.py | 12 ++++++++---- tests/v16/conftest.py | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ocpp/charge_point.py b/ocpp/charge_point.py index 863010db4..aca794353 100644 --- a/ocpp/charge_point.py +++ b/ocpp/charge_point.py @@ -95,15 +95,19 @@ def _raise_keyerror(action, version): raise NotImplementedError( details={"cause": f"No handler for {action} registered."} ) + else: + raise NotSupportedError( + details={"cause": f"{action} not supported by OCPP{version}."} + ) elif version in ["2.0", "2.0.1"]: if hasattr(v201_Action, action): raise NotImplementedError( details={"cause": f"No handler for {action} registered."} ) - else: - raise NotSupportedError( - details={"cause": f"{action} not supported by OCPP{version}."} - ) + else: + raise NotSupportedError( + details={"cause": f"{action} not supported by OCPP{version}."} + ) return diff --git a/tests/v16/conftest.py b/tests/v16/conftest.py index 25ec09dc0..70faecd45 100644 --- a/tests/v16/conftest.py +++ b/tests/v16/conftest.py @@ -19,7 +19,7 @@ def heartbeat_call(): @pytest.fixture def notsupported_call(): - return Call(unique_id="1", action="InvalidAction", payload={}).to_json() + return Call(unique_id=1, action="InvalidAction", payload={}).to_json() @pytest.fixture From 5f4b3410ce1f01ccad531d258490d1ad3efd2d91 Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Wed, 1 Nov 2023 11:07:35 +1300 Subject: [PATCH 20/21] fix snake case --- ocpp/charge_point.py | 6 +++--- tests/v16/conftest.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ocpp/charge_point.py b/ocpp/charge_point.py index aca794353..5e31f3fe7 100644 --- a/ocpp/charge_point.py +++ b/ocpp/charge_point.py @@ -79,7 +79,7 @@ def remove_nones(data: Union[List, Dict]) -> Union[List, Dict]: return data -def _raise_keyerror(action, version): +def _raise_key_error(action, version): """ Checks whether a keyerror returned by _handle_call is supported by the OCPP version or is simply @@ -207,7 +207,7 @@ async def _handle_call(self, msg): try: handlers = self.route_map[msg.action] except KeyError: - _raise_keyerror(msg.action, self._ocpp_version) + _raise_key_error(msg.action, self._ocpp_version) return if not handlers.get("_skip_schema_validation", False): @@ -223,7 +223,7 @@ async def _handle_call(self, msg): try: handler = handlers["_on_action"] except KeyError: - _raise_keyerror(msg.action, self._ocpp_version) + _raise_key_error(msg.action, self._ocpp_version) try: response = handler(**snake_case_payload) diff --git a/tests/v16/conftest.py b/tests/v16/conftest.py index 70faecd45..a8dfc365f 100644 --- a/tests/v16/conftest.py +++ b/tests/v16/conftest.py @@ -18,7 +18,7 @@ def heartbeat_call(): @pytest.fixture -def notsupported_call(): +def not_supported_call(): return Call(unique_id=1, action="InvalidAction", payload={}).to_json() From 8e30177b6cb51f56865b3eada562eb98a9a83365 Mon Sep 17 00:00:00 2001 From: drc38 <20024196+drc38@users.noreply.github.com> Date: Wed, 1 Nov 2023 13:31:56 +1300 Subject: [PATCH 21/21] fix missing call update --- tests/v16/test_v16_charge_point.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/v16/test_v16_charge_point.py b/tests/v16/test_v16_charge_point.py index 4fa402fc6..9d07acf23 100644 --- a/tests/v16/test_v16_charge_point.py +++ b/tests/v16/test_v16_charge_point.py @@ -109,7 +109,7 @@ def on_boot_notification(**kwargs): # noqa @pytest.mark.asyncio -async def test_route_message_not_supported(base_central_system, notsupported_call): +async def test_route_message_not_supported(base_central_system, not_supported_call): """ Test that a CALLERROR is sent back, reporting that it is not supported by OCPP version. @@ -130,7 +130,7 @@ def on_boot_notification(**kwargs): # noqa setattr(base_central_system, "on_boot_notification", on_boot_notification) base_central_system.route_map = create_route_map(base_central_system) - await base_central_system.route_message(notsupported_call) + await base_central_system.route_message(not_supported_call) base_central_system._connection.send.assert_called_once_with( json.dumps( [