From f937c172eebbdfb2d90693806bc045e915bf828d Mon Sep 17 00:00:00 2001 From: Sekiya Date: Tue, 18 Jun 2024 15:25:21 +0900 Subject: [PATCH] Related issue39 --- tests/ocpp-server/.gitignore | 2 ++ tests/ocpp-server/README.md | 10 ++++++ tests/ocpp-server/server.py | 60 ++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/tests/ocpp-server/.gitignore b/tests/ocpp-server/.gitignore index 1cec89b2..5d58fc27 100644 --- a/tests/ocpp-server/.gitignore +++ b/tests/ocpp-server/.gitignore @@ -1,3 +1,5 @@ +# Virtual environment +venv/ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/tests/ocpp-server/README.md b/tests/ocpp-server/README.md index bb5d5b17..31504026 100644 --- a/tests/ocpp-server/README.md +++ b/tests/ocpp-server/README.md @@ -1,15 +1,21 @@ # OCPP2 Mock Server This project includes an Open Charge Point Protocol (OCPP) version 2.0.1 mock server implemented in Python. +https://github.com/mobilityhouse/ocpp/blob/master/ocpp/v201/enums.py ## Prerequisites This project requires Python 3.7+ and [poetry](https://python-poetry.org/) to install the required packages: +```shell +pip install poetry +``` +then ```shell poetry install ``` + ## Running the Server To start the server, run the `server.py` script: @@ -17,7 +23,11 @@ To start the server, run the `server.py` script: ```shell poetry run task server ``` +or +```shell +poetry run task server --request GetBaseReport --period 5 +``` The server will start listening for connections on port 9000. ## Overview of the Server Scripts diff --git a/tests/ocpp-server/server.py b/tests/ocpp-server/server.py index 15229a1d..53e47c08 100644 --- a/tests/ocpp-server/server.py +++ b/tests/ocpp-server/server.py @@ -2,6 +2,7 @@ import asyncio import logging from datetime import datetime, timezone from threading import Timer +import argparse import ocpp.v201 import websockets @@ -12,6 +13,7 @@ from ocpp.v201.enums import ( ClearCacheStatusType, RegistrationStatusType, TransactionEventType, + ReportBaseType, ) # Setting up the logging configuration to display debug level messages. @@ -90,6 +92,11 @@ class ChargePoint(ocpp.v201.ChargePoint): logging.info("Received MeterValues") return ocpp.v201.call_result.MeterValues() + @on(Action.GetBaseReport) + async def on_get_base_report(self, request_id: int, report_base: ReportBaseType, **kwargs): + logging.info("Received GetBaseReport") + return ocpp.v201.call_result.GetBaseReport(status="Accepted") + # Request handlers to emit OCPP messages. async def send_clear_cache(self): request = ocpp.v201.call.ClearCache() @@ -100,6 +107,47 @@ class ChargePoint(ocpp.v201.ChargePoint): else: logging.info("Cache clearing failed") + async def send_get_base_report(self): + logging.info("Executing send_get_base_report...") + request = ocpp.v201.call.GetBaseReport(reportBase=ReportBaseType.ConfigurationInventory) # Use correct ReportBaseType + try: + response = await self.call(request) + logging.info("Send GetBaseReport") + + if response.status == "Accepted": # Adjust depending on the structure of your response + logging.info("Send GetBaseReport successful") + else: + logging.info("Send GetBaseReport failed") + except Exception as e: + logging.error(f"Send GetBaseReport failed: {str(e)}") + logging.info("send_get_base_report done.") + +# Define argument parser +parser = argparse.ArgumentParser(description='OCPP Charge Point Simulator') +parser.add_argument('--request', type=str, help='OCPP 2 Command Name') +parser.add_argument('--delay', type=int, help='Delay in seconds') +parser.add_argument('--period', type=int, help='Period in seconds') + +args = parser.parse_args() + +# Function to send OCPP command +async def send_ocpp_command(cp, command_name, delay=None, period=None): + # If delay is not None, sleep for delay seconds + if delay: + await asyncio.sleep(delay) + + # If period is not None, send command repeatedly with period interval + if period: + while True: + if command_name == 'GetBaseReport': + logging.info("GetBaseReport parser working") + await cp.send_get_base_report() + + await asyncio.sleep(period) + else: + if command_name == 'GetBaseReport': + await cp.send_get_base_report() + # Function to handle new WebSocket connections. async def on_connect(websocket, path): @@ -125,6 +173,10 @@ async def on_connect(websocket, path): charge_point_id = path.strip("/") cp = ChargePoint(charge_point_id, websocket) + # Check if request argument is specified + if args.request: + asyncio.create_task(send_ocpp_command(cp, args.request, args.delay, args.period)) + # Start the ChargePoint instance to listen for incoming messages. await cp.start() @@ -139,6 +191,14 @@ async def main(): subprotocols=["ocpp2.0", "ocpp2.0.1"], # Specify OCPP 2.0.1 subprotocols. ) logging.info("WebSocket Server Started") + + # Create a ChargePoint instance + # websocket = await websockets.connect('ws://localhost:9000') + # cp = ChargePoint('test', websocket) + + # Call send_ocpp_command function + # asyncio.create_task(send_ocpp_command(cp, args.request, args.delay, args.period)) + # Wait for the server to close (runs indefinitely). await server.wait_closed() -- 2.34.1