matth-x / MicroOcpp

OCPP 1.6 client for microcontrollers
MIT License
306 stars 133 forks source link

Getting an error of Could not allocate Tx #246

Closed Avi241 closed 6 months ago

Avi241 commented 6 months ago

I am trying to use the sample ESP code with my ESp32 board. Using Arduino IDE. I am using Steve as my CMS.

I am facing this error can any one please help me with this ?

[main] Begin Transaction with idTag 0123456789ABCD
[MO] ERROR (Connector.cpp:597): could not allocate Tx
[main] No transaction initiated

This is my complete Arduino Code

// matth-x/MicroOcpp
// Copyright Matthias Akstaller 2019 - 2023
// MIT License

#include <Arduino.h>
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti WiFiMulti;
#elif defined(ESP32)
#include <WiFi.h>
#else
#error only ESP32 or ESP8266 supported at the moment
#endif

#include <MicroOcpp.h>

#define STASSID "Avi"
#define STAPSK  "12345678"

//#define OCPP_BACKEND_URL   "ws://echo.websocket.events"
//#define OCPP_CHARGE_BOX_ID ""

//
//  Settings which worked for my SteVe instance:

#define OCPP_BACKEND_URL   "ws://192.168.0.106:8180/steve/websocket/CentralSystemService/"
#define OCPP_CHARGE_BOX_ID "esp-charger"

void setup() {

    /*
     * Initialize Serial and WiFi
     */ 

    Serial.begin(115200);

    Serial.print(F("[main] Wait for WiFi: "));

#if defined(ESP8266)
    WiFiMulti.addAP(STASSID, STAPSK);
    while (WiFiMulti.run() != WL_CONNECTED) {
        Serial.print('.');
        delay(1000);
    }
#elif defined(ESP32)
    WiFi.begin(STASSID, STAPSK);
    while (!WiFi.isConnected()) {
        Serial.print('.');
        delay(1000);
    }
#else
#error only ESP32 or ESP8266 supported at the moment
#endif

    Serial.println(F(" connected!"));

    /*
     * Initialize the OCPP library
     */
    mocpp_initialize(OCPP_BACKEND_URL, OCPP_CHARGE_BOX_ID, "My Charging Station", "My company name");

    /*
     * Integrate OCPP functionality. You can leave out the following part if your EVSE doesn't need it.
     */
    setEnergyMeterInput([]() {
        //take the energy register of the main electricity meter and return the value in watt-hours
        return 0.f;
    });

    setSmartChargingCurrentOutput([](float limit) {
        //set the SAE J1772 Control Pilot value here
        Serial.printf("[main] Smart Charging allows maximum charge rate: %.0f\n", limit);
    });

    setConnectorPluggedInput([]() {
        //return true if an EV is plugged to this EVSE
        return false;
    });

    //... see MicroOcpp.h for more settings
}

void loop() {

    /*
     * Do all OCPP stuff (process WebSocket input, send recorded meter values to Central System, etc.)
     */
    mocpp_loop();

    /*
     * Energize EV plug if OCPP transaction is up and running
     */
    if (ocppPermitsCharge()) {
        //OCPP set up and transaction running. Energize the EV plug here
        Serial.println("permit");
    } else {
        //No transaction running at the moment. De-energize EV plug
    }

    /*
     * Use NFC reader to start and stop transactions
     */
    if (/* RFID chip detected? */ true) {
        String idTag = "0123456789ABCD"; //e.g. idTag = RFID.readIdTag();

        if (!getTransaction()) {
            //no transaction running or preparing. Begin a new transaction
            Serial.printf("[main] Begin Transaction with idTag %s\n", idTag.c_str());

            /*
             * Begin Transaction. The OCPP lib will prepare transaction by checking the Authorization
             * and listen to the ConnectorPlugged Input. When the Authorization succeeds and an EV
             * is plugged, the OCPP lib will send the StartTransaction
             */
            auto ret = beginTransaction(idTag.c_str());

            if (ret) {
                Serial.println(F("[main] Transaction initiated. OCPP lib will send a StartTransaction when" \
                                 "ConnectorPlugged Input becomes true and if the Authorization succeeds"));
            } else {
                Serial.println(F("[main] No transaction initiated"));
            }

        } else {
            //Transaction already initiated. Check if to stop current Tx by RFID card
            if (idTag.equals(getTransactionIdTag())) {
                //card matches -> user can stop Tx
                Serial.println(F("[main] End transaction by RFID card"));

                endTransaction(idTag.c_str());
            } else {
                Serial.println(F("[main] Cannot end transaction by RFID card (different card?)"));
            }
        }
    }

    //... see MicroOcpp.h for more possibilities
}
pedro-fuoco commented 6 months ago

I am facing a similar issue after solving #244 (likely unrelated). Seems like a cache problem. Here are my logs:

[MO] info (StatusNotification.cpp:50): New status: Available (connectorId 0)
[MO] info (StatusNotification.cpp:50): New status: Available (connectorId 1)
[MO] info (Connector.cpp:355): begin FreeVend Tx using idTag MEDIDOR-T03
[MO] info (StatusNotification.cpp:50): New status: Preparing (connectorId 1)
[MO] info (Connector.cpp:240): Session mngt: trigger StartTransaction
[MO] info (StartTransaction.cpp:48): StartTransaction initiated
[MO] info (StatusNotification.cpp:50): New status: Charging (connectorId 1)
[MO] info (StartTransaction.cpp:142): Request has been accepted
[MO] info (Connector.cpp:293): Session mngt: trigger StopTransaction
[MO] info (StopTransaction.cpp:50): StopTransaction initiated
[MO] info (StatusNotification.cpp:50): New status: Available (connectorId 1)
[MO] info (Connector.cpp:355): begin FreeVend Tx using idTag MEDIDOR-T03
[MO] info (StatusNotification.cpp:50): New status: Preparing (connectorId 1)
[MO] info (Connector.cpp:240): Session mngt: trigger StartTransaction
[MO] info (StartTransaction.cpp:48): StartTransaction initiated
[MO] info (StatusNotification.cpp:50): New status: Charging (connectorId 1)
[MO] info (Connector.cpp:293): Session mngt: trigger StopTransaction
[MO] info (StopTransaction.cpp:50): StopTransaction initiated
[MO] info (StatusNotification.cpp:50): New status: Available (connectorId 1)
[MO] info (Connector.cpp:355): begin FreeVend Tx using idTag MEDIDOR-T03
[MO] info (StatusNotification.cpp:50): New status: Preparing (connectorId 1)
[MO] info (Connector.cpp:240): Session mngt: trigger StartTransaction
[MO] info (StartTransaction.cpp:48): StartTransaction initiated
[MO] info (StatusNotification.cpp:50): New status: Charging (connectorId 1)
[MO] info (Connector.cpp:293): Session mngt: trigger StopTransaction
[MO] info (StopTransaction.cpp:50): StopTransaction initiated
[MO] info (RequestQueueStorageStrategy.cpp:162): Replace cached operation (cache full): StatusNotification
[MO] info (StatusNotification.cpp:50): New status: Available (connectorId 1)
[MO] info (RequestQueueStorageStrategy.cpp:162): Replace cached operation (cache full): StatusNotification
[MO] info (StatusNotification.cpp:50): New status: Preparing (connectorId 1)
[MO] info (RequestQueueStorageStrategy.cpp:162): Replace cached operation (cache full): StartTransaction
[MO] info (Connector.cpp:355): begin FreeVend Tx using idTag MEDIDOR-T03
[MO] info (Connector.cpp:240): Session mngt: trigger StartTransaction
[MO] info (StartTransaction.cpp:48): StartTransaction initiated
[MO] info (RequestQueueStorageStrategy.cpp:162): Replace cached operation (cache full): StatusNotification
[MO] info (StatusNotification.cpp:50): New status: Charging (connectorId 1)
[MO] info (RequestQueueStorageStrategy.cpp:162): Replace cached operation (cache full): StopTransaction
[MO] info (RequestQueue.cpp:45): operation timeout: Heartbeat
[MO] info (Connector.cpp:293): Session mngt: trigger StopTransaction
[MO] info (StopTransaction.cpp:50): StopTransaction initiated
[MO] info (StatusNotification.cpp:50): New status: Available (connectorId 1)
[MO] info (RequestQueueStorageStrategy.cpp:162): Replace cached operation (cache full): StatusNotification
[MO] info (Connector.cpp:355): begin FreeVend Tx using idTag MEDIDOR-T03
[MO] ERROR (Connector.cpp:742): could not allocate Tx
[MO] ERROR (Connector.cpp:359): could not begin FreeVend Tx

Waiting a bit between transactions solved it in my case, as the cache empties itself. Are you seeing a similar behavior ? @Avi241

matth-x commented 6 months ago

Yes, this is related. To give a little explanation: MicroOcpp has a transaction journal, i.e. it keeps track of the most recent transactions, until they are sent to the server and then acknowledged by the server. That part can take a few hundred milliseconds, and is spread over many mocpp_loop() calls. But the sketch above keeps initiating a new transaction per main-loop iteration and consequently creating transactions much faster than they can be processed by MicroOcpp. The transaction journal caches at most 4 pending transactions (per default configuration) and rejects any further transactions.

To fix this sketch, I would add some logic that starts only one transaction (e.g. by adding a flag and setting it false after the beginTransaction call).

Avi241 commented 6 months ago

Thank you so much @matth-x and @pedro-fuoco . I got my mistake as you said I was perfoming begin trasaction too quickly which created and issue