-
Notifications
You must be signed in to change notification settings - Fork 316
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Could setting charging profiles in after transaction post-request hook lead into OCPP protocol level issue? #533
Comments
I think this is fine and correct. As you can see on https://github.com/mobilityhouse/ocpp/blob/master/ocpp/charge_point.py#L257, the response is sent before the after task is created. We are currently investigating issues on the CS side though. |
I agree with @astrand here. The |
I have looked at the client side now. It's a bit tricky, actually. route_message will use (Note however that we are using aiohttp instead of websockets, and thus have a custom start() method, but it calls Initially, I thought that this problem could be solved by adding |
Yes this is what I mean: from logical execution order one could tell |
Just to make sure I understand this right. From the perspective of the CSMS, the SetChargingProfile response sent first, followed by a SetChargingProfile request. The charger receives the 2 message in the same order. However, the charger processes the messages in reverse order. So it handles the SetChargingProfile request before handling the response to the StartTransaction. Is my understanding correct? @apekkar Can you include a debug log of the charger that websocket logs? Those will proof that my understanding is correct. |
Code-wise, I think this patch should be considered. Should I make a PR?
|
I'm hesitant to introduce an artificial sleep. It makes a request/response sequence slower for everyone without guaranteeing the issue is solved in all cases. |
That's a sane gut feeling. However, note that it is not the actual delay that solves this problem. You can use 0.0000001 instead if you want; this is just a somewhat ugly Python syntax to yield to the mainloop. |
I would expect that Can you reproduce the issue isolated in a unit test? That allows me to dig into the issue and play a bit around with code. |
Why sleep(0) does not work is explained in the stackoverflow posting I linked to above. If you want to use sleep(0), you have to use three of them. We can reproduce this in test case which is ~100 lines of code, with simulated CS and CSMS, but this test is built around aiohttp. But I can share the CS part of it: class CS(ChargePoint):
def __init__(self, id, connection, response_timeout=30): # pylint: disable=W0622
super().__init__(id, connection, response_timeout)
self.registration_status = None
self.registration_status_when_ca = None
self.start_task = asyncio.ensure_future(self.start())
self.send_task = asyncio.ensure_future(self.sendloop())
async def run_for(self, timeout):
"Run OCPP for specified time"
# Use asyncio.wait since it does not cancel tasks upon timeout
done, dummy = await asyncio.wait((self.start_task, self.send_task), timeout=timeout,
return_when=asyncio.FIRST_EXCEPTION)
for dtask in done:
dtask.result()
async def sendloop(self):
"Send things using OCPP"
if self.registration_status != RegistrationStatus.accepted:
request = call.BootNotificationPayload(
charge_point_model="Test",
charge_point_vendor="Test"
)
response = await self.call(request)
self.registration_status = response.status
logging.info("Connected to central system.")
while True:
await asyncio.sleep(0.2)
@on(Action.ChangeAvailability)
async def on_change_availability(self, connector_id, type): # pylint: disable=W0622
"Handler for ChangeAvailability"
self.registration_status_when_ca = self.registration_status
return call_result.ChangeAvailabilityPayload(AvailabilityStatus.accepted)
Then connect and:
|
In OCPP 1.6 we have a sequence specified so that SetChargingProfile is sent by Central System after StartTransaction is sent (with transaction id provided)
We have been facing following issues lately. I believe this is happening occasionally:
(pseudo logs from charge point)
We have are doing SetChargingProfile in after transaction post-request hook (pseudocode):
Is this wrong way? Could this end up in situation where after action - as being handled so that they are non blocking whereas on actions are queued - is being sent before response call to start transaction request?
The text was updated successfully, but these errors were encountered: