matth-x / MicroOcpp

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

Clock Aligned Meter values request #225

Open priya2212 opened 8 months ago

priya2212 commented 8 months ago

Hi @matth-x , I want to send meter values at every 30 min when there is no active transaction and during transaction, want to send meter values every 1 minute. I checked that we can do it with clock aligned data and sampled data respectively. But when I configure clock aligned data remotely through server, then charge point is sending the sample.clock and sample.periodic - both data during active transaction only. Not sure, If I am understanding and implementing it correctly. Would really appreciate your valuable inputs on it.

Thank you Priya.

matth-x commented 8 months ago

Hi @priya2212,

Sending MeterValues outside of transaction is good discussion material. See here for example some feedback: https://github.com/matth-x/MicroOcpp/issues/66

In case your backend tolerates MVs while there's no charging session, you could try changing the config Cst_MeterValuesInTxOnly to false. The charger will send some superfluous data (most readings are irrelevant while not charging), but I would argue that this is really little payload (probably too little to care about) and the true bottleneck of WebSocket-based charging networks is more the number of simultaneous open connections, where reducing traffic doesn't really help. Anyway, if the backend supports this behavior, then it should work as expected.

If that doesn't work, would it be an option to duplicate the energy meter inputs for connectorId 0? (i.e. add the same callback, but pass the parameter 0 for connectorId to addMeterValueInput(...)) That should send clock-aligned meterings regardless of open transactions.

priya2212 commented 8 months ago

So Sorry I got busy in some work here. Will check it today and confirm it here.

priya2212 commented 8 months ago

Dear @matth-x , Setting the Cst_MeterValuesInTxOnly to false works. Thank you very much for your support and help.

priya2212 commented 5 months ago

Dear @matth-x , I am configuring connector 0 to get the meter values irrespective of transactions. I have configured ClockAlignedDataInterval to 600 sec and MeterValueSampleInterval to 30 sec (to get frequent meter data when TX is there) Expected output - When no tx is active, the charge point should only send clock-align data, and when tx is active - it should send sample data and may send clock-align data.

Actual output - When no tx is active, it is sending clock-align and sample data both. Because of this, I am having request queue highly populated and when I am trying to send RFID data for authorization, sometimes facing operation timeout issue.

I see the websocket connection is stable and tested with separate script, it works fine. But with OCPP, once I start receiving operation timeout, I get for every meter reading.

Code snippet for reference - `OCPP_Connection *osock = ocpp_makeConnection(&mgr, EXAMPLE_MO_OCPP_BACKEND, EXAMPLE_MO_CHARGEBOXID, EXAMPLE_MO_AUTHORIZATIONKEY, "", fsopt); ocpp_initialize(osock, "ESP-IDF charger", "Your brand name here", fsopt, false);

ocpp_endTransaction(NULL, "Reboot");

ocpp_setEvseReadyInput_m(OCPP_ID_OF_CONNECTOR_1, evse_ready_check);

ocpp_setSmartChargingOutput_m(OCPP_ID_OF_CONNECTOR_1, smart_charging_power_set_callback);
// ocpp_setSmartChargingOutput_m(OCPP_ID_OF_CONNECTOR_2, smart_charging_power_set_callback);

ocpp_setConnectorPluggedInput_m(OCPP_ID_OF_CONNECTOR_1, ev_plugged_input_check_CP1);
ocpp_setConnectorPluggedInput_m(OCPP_ID_OF_CONNECTOR_2, ev_plugged_input_check_CP2);

ocpp_setEvReadyInput_m(OCPP_ID_OF_CONNECTOR_1, ev_ready_check_CP1);
ocpp_setEvReadyInput_m(OCPP_ID_OF_CONNECTOR_2, ev_ready_check_CP2);

// ocpp_addMeterValueInputFloat_m(OCPP_ID_OF_CHARGE_POINT, get_energy_callback, "Energy.Active.Import.Register", "V", NULL, NULL);

ocpp_addMeterValueInputFloat_m(OCPP_ID_OF_CONNECTOR_1, get_energy_callback, "Energy.Active.Import.Register", "V", NULL, NULL);
ocpp_addMeterValueInputFloat_m(OCPP_ID_OF_CONNECTOR_1, get_ampere_callback, "Energy.Active.Import.Register", "A", NULL, NULL);
ocpp_addMeterValueInputFloat_m(OCPP_ID_OF_CONNECTOR_1, get_power_callback, "Energy.Active.Import.Register", "Wh", NULL, NULL);

ocpp_addMeterValueInputFloat_m(OCPP_ID_OF_CONNECTOR_2, get_energy_callback, "Energy.Active.Import.Register", "V", NULL, NULL);
ocpp_addMeterValueInputFloat_m(OCPP_ID_OF_CONNECTOR_2, get_ampere_callback, "Energy.Active.Import.Register", "A", NULL, NULL);
ocpp_addMeterValueInputFloat_m(OCPP_ID_OF_CONNECTOR_2, get_power_callback, "Energy.Active.Import.Register", "Wh", NULL, NULL);

// ocpp_addErrorCodeInput(gndFaultErrCheck);

// led_strip_control_rgb(0, 0, 255, true);

while (1)
{
    mg_mgr_poll(&mgr, 10);
    ocpp_loop();

    rfid_card_read();
    if (idTag_read[0] != '\0')
    {
        ESP_LOGI("TAG", "User ID tag received is %s", idTag_read);
        ocpp_authorize(idTag_read, idtag_confirmationCallback, NULL, NULL, idTag_errorCallback, NULL);
        idTag_read[0] = '\0';
    }

    bool isOperative_CP1 = ocpp_isOperative_m(OCPP_ID_OF_CONNECTOR_1);
    bool isTransactionRunning_CP1 = ocpp_isTransactionRunning_m(OCPP_ID_OF_CONNECTOR_1);

    if (ev_plugged_flag_CP1 == 1 && id_tag_success_status_flag == 1)
    {
        ESP_LOGI(TAG, "Connector %d isOperative_CP1 %d", OCPP_ID_OF_CONNECTOR_1, isOperative_CP1);
        if (isOperative_CP1 == 1 && isTransactionRunning_CP1 == 0)
        {
            id_tag_success_status_flag = 0;
            ESP_LOGI(TAG, "Calling the server to start the Transaction with connector ID - %d and idTag - %s", OCPP_ID_OF_CONNECTOR_1, destination_idTag_read);
            remote_api_tx_status_flag_CP1 = https_firmware_url(REMOTE_TRANSACTION_API_URL, EXAMPLE_MO_CHARGEBOXID, OCPP_ID_OF_CONNECTOR_1, destination_idTag_read);
            destination_idTag_read[0] = '\0';
        }
    }

    bool isOperative_CP2 = ocpp_isOperative_m(OCPP_ID_OF_CONNECTOR_2);
    bool isTransactionRunning_CP2 = ocpp_isTransactionRunning_m(OCPP_ID_OF_CONNECTOR_2);

    if (ev_plugged_flag_CP2 == 1 && id_tag_success_status_flag == 1)
    {
        ESP_LOGI(TAG, "Connector %d isOperative_CP2 %d", OCPP_ID_OF_CONNECTOR_2, isOperative_CP2);
        if (isOperative_CP2 == 1 && isTransactionRunning_CP2 == 0)
        {
            id_tag_success_status_flag = 0;
            ESP_LOGI(TAG, "Calling the server to start the Transaction with connector ID - %d and idTag - %s", OCPP_ID_OF_CONNECTOR_2, destination_idTag_read);
            remote_api_tx_status_flag_CP2 = https_firmware_url(REMOTE_TRANSACTION_API_URL, EXAMPLE_MO_CHARGEBOXID, OCPP_ID_OF_CONNECTOR_2, destination_idTag_read);
            destination_idTag_read[0] = '\0';
        }
    }

    track_ocpp_permits_charge_CP1 = ocpp_ocppPermitsCharge_m(OCPP_ID_OF_CONNECTOR_1);
    ESP_LOGI(TAG, "%d %d %d %d",remote_api_tx_status_flag_CP1, track_ocpp_permits_charge_CP1, relay_on_ev_ready_flag_CP1, relay_ON_at_permit_charge_flag_CP1);
    if (remote_api_tx_status_flag_CP1 == 1 && track_ocpp_permits_charge_CP1 == 1 && relay_on_ev_ready_flag_CP1 == 1 && relay_ON_at_permit_charge_flag_CP1 == 0)
    {
        ESP_LOGI(TAG, "Transaction started, relay ON at %d connector", OCPP_ID_OF_CONNECTOR_1);
        remote_api_tx_status_flag_CP1 = 0;
        relay_ON_at_permit_charge_flag_CP1 = 1;
        ev_charging_control_relay_CP1(RELAY_ON);
    }
    else if (relay_on_ev_ready_flag_CP1 == 0 && relay_ON_at_permit_charge_flag_CP1 == 1)
    {
        ESP_LOGI(TAG, "EV is not ready, relay OFF at %d connector", OCPP_ID_OF_CONNECTOR_1);
        relay_ON_at_permit_charge_flag_CP1 = 0;
        ev_charging_control_relay_CP1(RELAY_OFF);
    }
    else if (track_ocpp_permits_charge_CP1 == 0 && relay_ON_at_permit_charge_flag_CP1 == 1)
    {
        ESP_LOGI(TAG, "Transaction stopped, relay OFF at %d connector", OCPP_ID_OF_CONNECTOR_1);
        relay_ON_at_permit_charge_flag_CP1 = 0;
        ev_charging_control_relay_CP1(RELAY_OFF);
    }

    if (isOperative_CP1 == 1 && isTransactionRunning_CP1 == 1 && id_tag_success_status_flag == 1 && relay_ON_at_permit_charge_flag_CP1 == 1)
    {
        ESP_LOGI(TAG, "Tag received to stop Tx at %d connector with idtag - %s", OCPP_ID_OF_CONNECTOR_1, destination_idTag_read);
        ocpp_endTransaction_m(OCPP_ID_OF_CONNECTOR_1, destination_idTag_read, "Local");
        destination_idTag_read[0] = '\0';
    }

    track_ocpp_permits_charge_CP2 = ocpp_ocppPermitsCharge_m(OCPP_ID_OF_CONNECTOR_2);
    if (remote_api_tx_status_flag_CP2 == 1 && track_ocpp_permits_charge_CP2 == 1 && relay_on_ev_ready_flag_CP2 == 1 && relay_ON_at_permit_charge_flag_CP2 == 0)
    {
        ESP_LOGI(TAG, "Transaction started, relay ON at %d connector", OCPP_ID_OF_CONNECTOR_2);
        remote_api_tx_status_flag_CP2 = 0;
        relay_ON_at_permit_charge_flag_CP2 = 1;
        ev_charging_control_relay_CP2(RELAY_ON);
    }
    else if (relay_on_ev_ready_flag_CP2 == 0 && relay_ON_at_permit_charge_flag_CP2 == 1)
    {
        ESP_LOGI(TAG, "EV is not ready, relay OFF at %d connector", OCPP_ID_OF_CONNECTOR_2);
        relay_ON_at_permit_charge_flag_CP2 = 0;
        ev_charging_control_relay_CP2(RELAY_OFF);
    }
    else if (track_ocpp_permits_charge_CP2 == 0 && relay_ON_at_permit_charge_flag_CP2 == 1)
    {
        ESP_LOGI(TAG, "Transaction stopped, relay OFF at %d connector", OCPP_ID_OF_CONNECTOR_2);
        relay_ON_at_permit_charge_flag_CP2 = 0;
        ev_charging_control_relay_CP2(RELAY_OFF);
    }

    if (isOperative_CP2 == 1 && isTransactionRunning_CP2 == 1 && id_tag_success_status_flag == 1 && relay_ON_at_permit_charge_flag_CP2 == 1)
    {
        ESP_LOGI(TAG, "Tag received to stop Tx at %d connector with idtag - %s", OCPP_ID_OF_CONNECTOR_2, destination_idTag_read);
        ocpp_endTransaction_m(OCPP_ID_OF_CONNECTOR_2, destination_idTag_read, "Local");
        destination_idTag_read[0] = '\0';
    }
}`

Please provide me your suggestion to resolve this issue. This is impacting my application alot.