MicroOcpp icon indicating copy to clipboard operation
MicroOcpp copied to clipboard

Unable to cancel Reservation post reboot

Open chandan-ultraviolette opened this issue 2 years ago • 6 comments

Hello, I sent reservation command from CMS and charger went to charging state, post I reboot the system still auto charger going to charging state post connected to CMS. I tried cancel reservation but falling, When I checked the reason, In ReservationService::getReservationById, reservation.isActive() is false. I am sharing important logs.

[15:32:47.379] [ 3294] [ 1003] [ ] [ ] [ ] QOPN/D : MOCPP:loadJson 75: Loaded JSON file: /reservations.jsn [15:32:47.379] [ 3298] [ 1004] [ ] [ ] [ ] QOPN/D : MOCPP:loadJson 81: doc: {"head":{"content-type":"ocpp_config_file","version":"2.0"},"configurations":[{"type":"int","key":"cid_0","value":0},{"type":"string","key":"expdt_0","value":"2023-11-09T07:55:00.000Z"},{"type":"string","key":"idt_0","value":"123_test"},{"type":"int","key":"rsvid_0","value":23222},{"type":"string","key":"pidt_0","value":"123"}]} [15:32:47.379] [ 3299] [ 1005] [ ] [ ] [ ] QFIL/I : 60029A44 344 close fd 1027 [15:32:47.379] [ 3304] [ 1006] [ ] [ ] [ ] QOPN/D : MOCPP:operator= 97: add config: key = cid_0, value = 0 [15:32:47.379] [ 3305] [ 1007] [ ] [ ] [ ] QOPN/D : MOCPP:operator= 227: add config: key = expdt_0, value = 2023-11-09T07:55:00.000Z [15:32:47.379] [ 3306] [ 1008] [ ] [ ] [ ] QOPN/D : MOCPP:operator= 227: add config: key = idt_0, value = 123_test [15:32:47.379] [ 3307] [ 1009] [ ] [ ] [ ] QOPN/D : MOCPP:operator= 97: add config: key = rsvid_0, value = 23222 [15:32:47.379] [ 3307] [ 1010] [ ] [ ] [ ] QOPN/D : MOCPP:operator= 227: add config: key = pidt_0, value = 123

image

trac_logs.txt

chandan-ultraviolette avatar Nov 09 '23 11:11 chandan-ultraviolette

The WebSocket driver looks great, good job!

In the logs I can see that the Reservation is already expired at this point. You already found the interesting data structure. It stores the data of the ReserveNow request on flash. The fields are an abbreviation of the ReserveNow parameters and an internal slot number <num>:

  • cid_<num>: connectorId
  • expdt_<num>: expiryDate. In your case, the expiry date is in the past (before currentTime in BootNotification.conf) so the Reservation has expired. Although this Reservation record remains in the memory, the OCPP lib will ignore it and make the charger Available again
  • idt_<num>: idTag
  • rsvid_<num>: reservationId
  • pidt_<num>: parentIdTag

The internal slot number does not relate to the connectorId but is just an index. A charger with one physical connector can store at most one Reservation so <num> is always 0. If the charger has two connectors, then the OCPP lib can store two Reservations so you will find the same fields where <num> is 1.

CancelReservation is rejected because the Reservation is invalid at this point.

matth-x avatar Nov 09 '23 17:11 matth-x

Issue is that connector 1 state is going to charging which is not correct post restart, please check the logs at below in shared logs. Techinally it shouldn't as time is already experied but Post I restart, its going to charging state.

[16:48:46.762] [43981] [21774] [ ] [ ] [ ] QOPN/I : MOCPP:StatusNotification 49: New status: Available (connectorId 0) [16:48:46.762] [43987] [21775] [ ] [ ] [ ] QOPN/D : MOCPP:loop 375: Status changed [16:48:46.762] [43988] [21776] [ ] [ ] [ ] QOPN/I : MOCPP:StatusNotification 49: New status: Charging (connectorId 1)

[16:48:47.758] [60367] [21872] [ ] [ ] [ ] QOPN/I : websocket_cpp:sendTXT 148: [2,"1000004","StatusNotification",{"connectorId":1,"errorCode":"NoError","status":"Charging","timestamp":"2023-11-09T11:18:47.355Z"}]

chandan-ultraviolette avatar Nov 09 '23 18:11 chandan-ultraviolette

Additionally few more points expect the above noticed issue.

  1. I wanted to charger to auto start charging based on the communication with vehicle. I think below sample code will work, let me know if I am missing anything.

image

  1. I am looking for a callback whenever charger status changes from CMS side this callback will update the hardware based on the CMS command: charging/stop charging. I tried belwo method to get callback but not working. may be its not the right way.

image

  1. I think status to charger status shouldn’t just update to charging or available based on the request received by the CMS. There should be a callback from MOCPP which basically ask for the current actual status of the connector and update the same. Any suggestion on modifying code for this?

chandan-ultraviolette avatar Nov 10 '23 12:11 chandan-ultraviolette

The transaction status is persistent over reboots. When the controller starts a transaction and gets reset, then the transaction is still active after the controller has booted. To suppress this behavior, place an endTransaction(...) call somewhere after mocpp_initialize(...):

//end a potentially pending tx. If there's no tx, nothing happens. If there is a tx, then it sends a StopTransaction
endTransaction(nullptr, "PowerLoss"); 

To answer the other questions, the callback ConnectionPluggedInput is intended to be the same over the runtime of the OCPP lib and query something in your firmware which might change. E.g.

//example part of your firmware which reads the J1772 status (i.e. 'A', 'B', ...) at any time
char getJ1772Status() {
    char status;
    //... something reads the status here
    return status;
}

//setup function of MicroOcpp
void setup() {
    //... mocpp_initialize(...)

    setConnectorPluggedInput([] () {
        if (getJ1772Status() == 'B' || getJ1772Status() == 'C') {
            return true;
        } else {
            return false;
        }
    });
}

For testing it's okay to overwrite the callback like you do, but it's not exactly a best practice.

The beginTransaction(...) call is also good. Its counterpart is endTransaction(...). If you used startTransaction(...) instead, then it would be stopTransaction(...). But the begin- and end-functions are a lot more feature-rich, e.g. they provide offline handling, Reservation and Local Authorization support and keep the synchronocity with the OCPP server over reboots.

Incoming RemoteStartTransaction requests don't need to be handled separately. The function ocppPermitsCharge() tells you whether there's a valid transaction at the moment and the charging hardware can start the actual charging. Also use ocppPermitsCharge() to check if a locally initated transaction finally succeeded.

matth-x avatar Nov 10 '23 20:11 matth-x

Sure I will try for endTransaction(nullptr, "PowerLoss"). I am busy in Indian festival time so could test. I will update you tomorrow on this.

Also I want to edit the MicroOcpp code for my 3rd query "I think status to charger status shouldn’t just update to charging or available based on the request received by the CMS. There should be a callback from MOCPP which basically ask for the current actual status of the connector and update the same". Basically CMS can request to change the status of charger from available to charging but current status packet charger packet to CMS should be asked from the application code which is basically actual real status. Please suggest which functions should I check. PS: I am kind of beginner in C++, mostly use C but still try best to do it.

chandan-ultraviolette avatar Nov 12 '23 10:11 chandan-ultraviolette

Please ignore My last msg. Also regarding my 3rd query, I am thinking to update below highlighted code in Connector::loop(). In place of getStatus(), I am planing to add fucntion getHardwareStatus which will return current hardware actual status. Please let mw know if this can cause any issue.

image

chandan-ultraviolette avatar Nov 13 '23 10:11 chandan-ultraviolette