// === Início de: components/protocols/src/json.c === #include #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "esp_wifi.h" #include "esp_timer.h" #include "esp_chip_info.h" #include "esp_mac.h" #include "esp_log.h" #include "json.h" #include "mqtt.h" #include "network.h" #include "evse_error.h" #include "evse_api.h" #include "auth.h" #include "evse_limits.h" #include "evse_state.h" #include "evse_config.h" #include "ocpp.h" #include "board_config.h" #include "socket_lock.h" #include "proximity.h" #include "temp_sensor.h" #include "evse_meter.h" static const char *TAG = "json"; // // ===== EVSE CONFIG JSON ===== // cJSON *json_get_evse_config(void) { cJSON *root = cJSON_CreateObject(); if (!root) return NULL; cJSON_AddNumberToObject(root, "maxChargingCurrent", evse_get_max_charging_current()); cJSON_AddNumberToObject(root, "chargingCurrent", evse_get_charging_current()); cJSON_AddNumberToObject(root, "defaultChargingCurrent", evse_get_default_charging_current()); cJSON_AddBoolToObject(root, "requireAuth", auth_get_mode()); cJSON_AddBoolToObject(root, "socketOutlet", evse_get_socket_outlet()); cJSON_AddBoolToObject(root, "rcm", evse_is_rcm()); cJSON_AddNumberToObject(root, "temperatureThreshold", evse_get_temp_threshold()); cJSON_AddNumberToObject(root, "consumptionLimit", evse_get_consumption_limit()); //cJSON_AddNumberToObject(root, "defaultConsumptionLimit", evse_get_default_consumption_limit()); cJSON_AddNumberToObject(root, "chargingTimeLimit", evse_get_charging_time_limit()); //cJSON_AddNumberToObject(root, "defaultChargingTimeLimit", evse_get_default_charging_time_limit()); cJSON_AddNumberToObject(root, "underPowerLimit", evse_get_under_power_limit()); //cJSON_AddNumberToObject(root, "defaultUnderPowerLimit", evse_get_default_under_power_limit()); cJSON_AddNumberToObject(root, "socketLockOperatingTime", socket_lock_get_operating_time()); cJSON_AddNumberToObject(root, "socketLockBreakTime", socket_lock_get_break_time()); cJSON_AddBoolToObject(root, "socketLockDetectionHigh", socket_lock_is_detection_high()); cJSON_AddNumberToObject(root, "socketLockRetryCount", socket_lock_get_retry_count()); char str[64]; cJSON_AddBoolToObject(root, "enabledocpp", ocpp_get_enabled()); ocpp_get_server(str); cJSON_AddStringToObject(root, "serverocpp", str); return root; } // // ===== SET EVSE CONFIG (from MQTT or REST) ===== // esp_err_t json_set_evse_config(cJSON *root) { if (!root) return ESP_ERR_INVALID_ARG; // Alguns setters retornam esp_err_t, outros void. Para manter compatibilidade, // chamamos sem propagar erro (se existir, será tratado internamente). #define SET_NUM(key, fn) \ do \ { \ const cJSON *item = cJSON_GetObjectItem(root, key); \ if (cJSON_IsNumber(item)) \ { \ fn(item->valuedouble); \ } \ } while (0) #define SET_BOOL(key, fn) \ do \ { \ const cJSON *item = cJSON_GetObjectItem(root, key); \ if (cJSON_IsBool(item)) \ { \ fn(cJSON_IsTrue(item)); \ } \ } while (0) SET_NUM("maxChargingCurrent", evse_set_max_charging_current); SET_NUM("chargingCurrent", evse_set_charging_current); SET_NUM("defaultChargingCurrent", evse_set_default_charging_current); SET_BOOL("socketOutlet", evse_set_socket_outlet); SET_BOOL("rcm", evse_set_rcm); SET_NUM("temperatureThreshold", evse_set_temp_threshold); SET_NUM("consumptionLimit", evse_set_consumption_limit); //SET_NUM("defaultConsumptionLimit", evse_set_default_consumption_limit); SET_NUM("chargingTimeLimit", evse_set_charging_time_limit); //SET_NUM("defaultChargingTimeLimit", evse_set_default_charging_time_limit); SET_NUM("underPowerLimit", evse_set_under_power_limit); //SET_NUM("defaultUnderPowerLimit", evse_set_default_under_power_limit); SET_NUM("socketLockOperatingTime", socket_lock_set_operating_time); SET_NUM("socketLockBreakTime", socket_lock_set_break_time); const cJSON *retry = cJSON_GetObjectItem(root, "socketLockRetryCount"); if (cJSON_IsNumber(retry)) socket_lock_set_retry_count(retry->valueint); const cJSON *detect = cJSON_GetObjectItem(root, "socketLockDetectionHigh"); if (cJSON_IsBool(detect)) socket_lock_set_detection_high(cJSON_IsTrue(detect)); const cJSON *ocpp_enabled = cJSON_GetObjectItem(root, "enabledocpp"); if (cJSON_IsBool(ocpp_enabled)) ocpp_set_enabled(cJSON_IsTrue(ocpp_enabled)); const cJSON *ocpp_server = cJSON_GetObjectItem(root, "serverocpp"); if (cJSON_IsString(ocpp_server)) ocpp_set_server(cJSON_GetStringValue(ocpp_server)); ESP_LOGI(TAG, "EVSE configuration updated successfully"); return ESP_OK; } // // ===== EVSE STATE JSON ===== // cJSON *json_get_state(void) { cJSON *root = cJSON_CreateObject(); if (!root) return NULL; cJSON_AddStringToObject(root, "state", evse_state_to_str(evse_get_state())); cJSON_AddBoolToObject(root, "available", evse_config_is_available()); cJSON_AddBoolToObject(root, "enabled", evse_config_is_enabled()); cJSON_AddBoolToObject(root, "pendingAuth", auth_get_mode()); cJSON_AddBoolToObject(root, "limitReached", evse_is_limit_reached()); // Add error list uint32_t error = evse_error_get_bits(); if (error == 0) { cJSON_AddNullToObject(root, "errors"); } else { cJSON *errors = cJSON_CreateArray(); if (error & EVSE_ERR_PILOT_FAULT_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("pilot_fault")); if (error & EVSE_ERR_DIODE_SHORT_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("diode_short")); if (error & EVSE_ERR_LOCK_FAULT_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("lock_fault")); if (error & EVSE_ERR_UNLOCK_FAULT_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("unlock_fault")); if (error & EVSE_ERR_RCM_TRIGGERED_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("rcm_triggered")); if (error & EVSE_ERR_RCM_SELFTEST_FAULT_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("rcm_selftest_fault")); if (error & EVSE_ERR_TEMPERATURE_HIGH_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("temperature_high")); if (error & EVSE_ERR_TEMPERATURE_FAULT_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("temperature_fault")); cJSON_AddItemToObject(root, "errors", errors); } // Session info evse_session_t sess; if (evse_get_session(&sess)) { cJSON_AddNumberToObject(root, "sessionTime", (double)sess.start_tick); cJSON_AddNumberToObject(root, "chargingTime", (double)sess.duration_s); cJSON_AddNumberToObject(root, "consumption", (double)sess.energy_wh); } else { cJSON_AddNullToObject(root, "sessionTime"); cJSON_AddNumberToObject(root, "chargingTime", 0); cJSON_AddNumberToObject(root, "consumption", 0); } // Meter readings float voltage[EVSE_METER_PHASE_COUNT]; float current[EVSE_METER_PHASE_COUNT]; int power[EVSE_METER_PHASE_COUNT]; evse_meter_get_voltage(voltage); evse_meter_get_current(current); evse_meter_get_power(power); cJSON_AddItemToObject(root, "power", cJSON_CreateIntArray(power, EVSE_METER_PHASE_COUNT)); cJSON_AddItemToObject(root, "voltage", cJSON_CreateFloatArray(voltage, EVSE_METER_PHASE_COUNT)); cJSON_AddItemToObject(root, "current", cJSON_CreateFloatArray(current, EVSE_METER_PHASE_COUNT)); return root; } // === Fim de: components/protocols/src/json.c ===