OCPP ChargePoint Call
06:12 17 Jun 2024

I'm building a CMS using Python's OCPP library from mobility house. I wanted to send a RemoteStartTransaction command to the charger (in my case, the charger is just a JS-based simulator I spin up with a browser). The problem I face is that the self.call function takes around 30 seconds to complete, as marked by the # problem comment on the code block attached. The self keyword represents the ChargePoint class provided by the library.

By right, the expected behaviour is that the self.call function will yield results immediately after receiving response from the charger.

async def remote_start_transaction(self, id_tag, connector_id, duration_minute):
    print("remote start transaction")
    request = call.RemoteStartTransaction(id_tag=id_tag, connector_id=connector_id)
    response = await self.call(request) # problem

    print(f"got response: {response}")

    logging.info(response)

    if response.status == RemoteStartStopStatus.accepted:
        self.has_remotely_started = True

        self.charging_port_model_instance.status = "in_use"
        await self.charging_port_model_instance.asave()

        duration_second = duration_minute
        if not settings.CHARGING_DURATION_USE_SECONDS_INSTEAD_OF_MINUTES:
            duration_second = duration_second * 60

        print(f"Charging for {duration_second} seconds")

        await asyncio.sleep(duration_second)
        await self.remote_stop_transaction()

        print("Create Charging session completed")

    else:
        logging.warning(
            f"Remote Start Transaction Failed | ChargePoint ID: {self.unique_identifier}"
        )
        logging.info(response.status)

I've checked and confirmed that the charger has responded to the RemoteStartTransaction call immediately after receiving it, as shown by the log below:

log messages

I've tried to fix it by making sure the async setup is right, but no luck.

As an additional info, I'm running the code in a async thread.

t = threading.Thread(target=asyncio.run, args=(handle_actions(),))
t.start()

async def handle_actions():
    '''
    This function should be called in a separate thread to listen to the redis queue and
    perform the necessary actions.
    '''

    # listen to redis
    db = CleanChargeRedis.redis_db(settings.REDIS_CONFIG)
    queue_name = settings.REDIS_CONFIG['queue_name']

    while True:
        msg_json = CleanChargeRedis.redis_queue_pop(db, queue_name)

        if not msg_json:
            continue

        print(f"Received from Redis queue: {msg_json}")
        msg = json.loads(msg_json)

        if msg['action'] == 'remote_start':
            await handle_remote_start(msg)
        elif msg['action'] == 'reserve_now':
            await handle_reserve_now(msg)

async def handle_remote_start(msg):
    cp = sockets.get(msg['connection_identifier'])

    if cp:
        await cp.remote_start_transaction(msg['id_tag'], msg['connector_id'], msg['duration_minute'])
    else:
        print(f"Charge Point {msg['connection_identifier']} is not connected.")

async def handle_reserve_now(msg):
    cp = sockets.get(msg['connection_identifier'])

    if cp:
        await cp.reserve_now(msg['reservation_id'])
    else:
        print(f"Charge Point {msg['connection_identifier']} is not connected.")
python ocpp