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(
             [