#include #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "esp_wifi.h" #include "esp_ota_ops.h" #include "esp_timer.h" #include "esp_chip_info.h" #include "esp_mac.h" #include "json.h" #include "mqtt.h" #include "wifi.h" #include "timeout_utils.h" #include "evse_error.h" #include "evse_api.h" #include "ocpp.h" #include "board_config.h" #include "energy_meter.h" #include "socket_lock.h" #include "proximity.h" //#include "modbus.h" //#include "modbus_tcp.h" #include "rest.h" #include "temp_sensor.h" // #include "script.h" #include "date_time.h" #define RETURN_ON_ERROR(x) \ do \ { \ esp_err_t err_rc_ = (x); \ if (unlikely(err_rc_ != ESP_OK)) \ { \ return err_rc_; \ } \ } while (0) cJSON *json_get_evse_config(void) { cJSON *root = cJSON_CreateObject(); cJSON_AddNumberToObject(root, "maxChargingCurrent", evse_get_max_charging_current()); cJSON_AddNumberToObject(root, "chargingCurrent", evse_get_charging_current() / 10.0); cJSON_AddNumberToObject(root, "defaultChargingCurrent", evse_get_default_charging_current() / 10.0); cJSON_AddBoolToObject(root, "requireAuth", evse_is_require_auth()); 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()); cJSON_AddStringToObject(root, "modelMeter", meter_model_to_str(meter_get_model())); cJSON_AddNumberToObject(root, "maxGridCurrent", grid_get_max_current()); cJSON_AddStringToObject(root, "stateMeter", meter_state_to_str(meter_get_state())); char str[64]; cJSON_AddBoolToObject(root, "enabledocpp", ocpp_get_enabled()); ocpp_get_server(str); cJSON_AddStringToObject(root, "serverocpp", str); ocpp_get_rfid(str); cJSON_AddStringToObject(root, "rfid", str); return root; } esp_err_t json_set_evse_config(cJSON *root) { if (cJSON_IsNumber(cJSON_GetObjectItem(root, "maxChargingCurrent"))) { RETURN_ON_ERROR(evse_set_max_charging_current(cJSON_GetObjectItem(root, "maxChargingCurrent")->valuedouble)); } if (cJSON_IsNumber(cJSON_GetObjectItem(root, "chargingCurrent"))) { RETURN_ON_ERROR(evse_set_charging_current(cJSON_GetObjectItem(root, "chargingCurrent")->valuedouble * 10)); } if (cJSON_IsNumber(cJSON_GetObjectItem(root, "defaultChargingCurrent"))) { RETURN_ON_ERROR(evse_set_default_charging_current(cJSON_GetObjectItem(root, "defaultChargingCurrent")->valuedouble * 10)); } if (cJSON_IsBool(cJSON_GetObjectItem(root, "requireAuth"))) { evse_set_require_auth(cJSON_IsTrue(cJSON_GetObjectItem(root, "requireAuth"))); } if (cJSON_IsBool(cJSON_GetObjectItem(root, "socketOutlet"))) { RETURN_ON_ERROR(evse_set_socket_outlet(cJSON_IsTrue(cJSON_GetObjectItem(root, "socketOutlet")))); } if (cJSON_IsBool(cJSON_GetObjectItem(root, "rcm"))) { RETURN_ON_ERROR(evse_set_rcm(cJSON_IsTrue(cJSON_GetObjectItem(root, "rcm")))); } if (cJSON_IsNumber(cJSON_GetObjectItem(root, "temperatureThreshold"))) { RETURN_ON_ERROR(evse_set_temp_threshold(cJSON_GetObjectItem(root, "temperatureThreshold")->valuedouble)); } if (cJSON_IsNumber(cJSON_GetObjectItem(root, "consumptionLimit"))) { evse_set_consumption_limit(cJSON_GetObjectItem(root, "consumptionLimit")->valuedouble); } if (cJSON_IsNumber(cJSON_GetObjectItem(root, "defaultConsumptionLimit"))) { evse_set_default_consumption_limit(cJSON_GetObjectItem(root, "defaultConsumptionLimit")->valuedouble); } if (cJSON_IsNumber(cJSON_GetObjectItem(root, "chargingTimeLimit"))) { evse_set_charging_time_limit(cJSON_GetObjectItem(root, "chargingTimeLimit")->valuedouble); } if (cJSON_IsNumber(cJSON_GetObjectItem(root, "defaultChargingTimeLimit"))) { evse_set_default_charging_time_limit(cJSON_GetObjectItem(root, "defaultChargingTimeLimit")->valuedouble); } if (cJSON_IsNumber(cJSON_GetObjectItem(root, "underPowerLimit"))) { evse_set_under_power_limit(cJSON_GetObjectItem(root, "underPowerLimit")->valuedouble); } if (cJSON_IsNumber(cJSON_GetObjectItem(root, "defaultUnderPowerLimit"))) { evse_set_default_under_power_limit(cJSON_GetObjectItem(root, "defaultUnderPowerLimit")->valuedouble); } if (cJSON_IsNumber(cJSON_GetObjectItem(root, "socketLockOperatingTime"))) { RETURN_ON_ERROR(socket_lock_set_operating_time(cJSON_GetObjectItem(root, "socketLockOperatingTime")->valuedouble)); } if (cJSON_IsNumber(cJSON_GetObjectItem(root, "socketLockBreakTime"))) { RETURN_ON_ERROR(socket_lock_set_break_time(cJSON_GetObjectItem(root, "socketLockBreakTime")->valuedouble)); } if (cJSON_IsBool(cJSON_GetObjectItem(root, "socketLockDetectionHigh"))) { socket_lock_set_detection_high(cJSON_IsTrue(cJSON_GetObjectItem(root, "socketLockDetectionHigh"))); } if (cJSON_IsNumber(cJSON_GetObjectItem(root, "socketLockRetryCount"))) { socket_lock_set_retry_count(cJSON_GetObjectItem(root, "socketLockRetryCount")->valuedouble); } if (cJSON_IsString(cJSON_GetObjectItem(root, "modelMeter"))) { RETURN_ON_ERROR(meter_set_model(meter_str_to_model(cJSON_GetObjectItem(root, "modelMeter")->valuestring))); } /* if (cJSON_IsString(cJSON_GetObjectItem(root, "stateMeter"))) { RETURN_ON_ERROR(meter_set_state(meter_str_to_state(cJSON_GetObjectItem(root, "stateMeter")->valuestring))); } */ if (cJSON_IsNumber(cJSON_GetObjectItem(root, "maxGridCurrent"))) { RETURN_ON_ERROR(grid_set_max_current(cJSON_GetObjectItem(root, "maxGridCurrent")->valuedouble)); } if (cJSON_IsBool(cJSON_GetObjectItem(root, "enabledocpp"))) { ocpp_set_enabled(cJSON_IsTrue(cJSON_GetObjectItem(root, "enabledocpp"))); } if (cJSON_IsString(cJSON_GetObjectItem(root, "serverocpp"))) { ocpp_set_server(cJSON_GetStringValue(cJSON_GetObjectItem(root, "serverocpp"))); } if (cJSON_IsString(cJSON_GetObjectItem(root, "rfid"))) { ocpp_set_rfid(cJSON_GetStringValue(cJSON_GetObjectItem(root, "rfid"))); } return ESP_OK; } cJSON *json_get_wifi_config(void) { cJSON *root = cJSON_CreateObject(); char str[32]; cJSON_AddBoolToObject(root, "enabled", wifi_get_enabled()); wifi_get_ssid(str); cJSON_AddStringToObject(root, "ssid", str); return root; } esp_err_t json_set_wifi_config(cJSON *root, bool timeout) { bool enabled = cJSON_IsTrue(cJSON_GetObjectItem(root, "enabled")); char *ssid = cJSON_GetStringValue(cJSON_GetObjectItem(root, "ssid")); char *password = cJSON_GetStringValue(cJSON_GetObjectItem(root, "password")); if (timeout) { return timeout_wifi_set_config(enabled, ssid, password); } else { return wifi_set_config(enabled, ssid, password); } } cJSON *json_get_wifi_scan(void) { cJSON *root = cJSON_CreateArray(); wifi_scan_ap_t scan_aps[WIFI_SCAN_SCAN_LIST_SIZE]; uint16_t number = wifi_scan(scan_aps); for (int i = 0; i < number; i++) { cJSON *item = cJSON_CreateObject(); cJSON_AddStringToObject(item, "ssid", scan_aps[i].ssid); cJSON_AddNumberToObject(item, "rssi", scan_aps[i].rssi); cJSON_AddBoolToObject(item, "auth", scan_aps[i].auth); cJSON_AddItemToArray(root, item); } return root; } cJSON *json_get_mqtt_config(void) { cJSON *root = cJSON_CreateObject(); char str[64]; cJSON_AddBoolToObject(root, "enabled", mqtt_get_enabled()); mqtt_get_server(str); cJSON_AddStringToObject(root, "server", str); mqtt_get_base_topic(str); cJSON_AddStringToObject(root, "baseTopic", str); mqtt_get_user(str); cJSON_AddStringToObject(root, "user", str); mqtt_get_password(str); cJSON_AddStringToObject(root, "password", str); cJSON_AddNumberToObject(root, "periodicity", mqtt_get_periodicity()); return root; } esp_err_t json_set_mqtt_config(cJSON *root) { bool enabled = cJSON_IsTrue(cJSON_GetObjectItem(root, "enabled")); char *server = cJSON_GetStringValue(cJSON_GetObjectItem(root, "server")); char *base_topic = cJSON_GetStringValue(cJSON_GetObjectItem(root, "baseTopic")); char *user = cJSON_GetStringValue(cJSON_GetObjectItem(root, "user")); char *password = cJSON_GetStringValue(cJSON_GetObjectItem(root, "password")); uint16_t periodicity = cJSON_GetNumberValue(cJSON_GetObjectItem(root, "periodicity")); return mqtt_set_config(enabled, server, base_topic, user, password, periodicity); } cJSON *json_get_modbus_config(void) { cJSON *root = cJSON_CreateObject(); //cJSON_AddBoolToObject(root, "tcpEnabled", modbus_tcp_is_enabled()); //cJSON_AddNumberToObject(root, "unitId", modbus_get_unit_id()); cJSON_AddBoolToObject(root, "tcpEnabled", false); cJSON_AddNumberToObject(root, "unitId", 1); return root; } esp_err_t json_set_modbus_config(cJSON *root) { //bool tcp_enabled = cJSON_IsTrue(cJSON_GetObjectItem(root, "tcpEnabled")); //uint8_t unit_id = cJSON_GetObjectItem(root, "unitId")->valuedouble; //modbus_tcp_set_enabled(tcp_enabled); return 0; //modbus_set_unit_id(unit_id); } /* cJSON* json_get_script_config(void) { cJSON* root = cJSON_CreateObject(); cJSON_AddBoolToObject(root, "enabled", script_is_enabled()); return root; } esp_err_t json_set_script_config(cJSON* root) { bool enabled = cJSON_IsTrue(cJSON_GetObjectItem(root, "enabled")); script_set_enabled(enabled); return ESP_OK; }*/ cJSON *json_get_time_config(void) { cJSON *root = cJSON_CreateObject(); char str[64]; cJSON_AddBoolToObject(root, "ntpEnabled", date_time_is_ntp_enabled()); date_time_get_ntp_server(str); cJSON_AddStringToObject(root, "ntpServer", str); cJSON_AddBoolToObject(root, "ntpFromDhcp", date_time_is_ntp_from_dhcp()); date_time_get_timezone(str); cJSON_AddStringToObject(root, "timezone", str); return root; } esp_err_t json_set_time_config(cJSON *root) { char *ntp_server = cJSON_GetStringValue(cJSON_GetObjectItem(root, "ntpServer")); bool ntp_enabled = cJSON_IsTrue(cJSON_GetObjectItem(root, "ntpEnabled")); bool ntp_from_dhcp = cJSON_IsTrue(cJSON_GetObjectItem(root, "ntpFromDhcp")); char *timezone = cJSON_GetStringValue(cJSON_GetObjectItem(root, "timezone")); date_time_set_ntp_config(ntp_enabled, ntp_server, ntp_from_dhcp); return date_time_set_timezone(timezone); } cJSON *json_get_state(void) { cJSON *root = cJSON_CreateObject(); cJSON_AddStringToObject(root, "state", evse_state_to_str(evse_get_state())); cJSON_AddBoolToObject(root, "available", evse_is_available()); cJSON_AddBoolToObject(root, "enabled", evse_is_enabled()); cJSON_AddBoolToObject(root, "pendingAuth", evse_is_pending_auth()); cJSON_AddBoolToObject(root, "limitReached", evse_is_limit_reached()); 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); } cJSON_AddNumberToObject(root, "sessionTime", energy_meter_get_session_time()); cJSON_AddNumberToObject(root, "chargingTime", energy_meter_get_charging_time()); cJSON_AddNumberToObject(root, "consumption", energy_meter_get_consumption()); cJSON_AddNumberToObject(root, "power", energy_meter_get_power()); float values[3]; energy_meter_get_voltage(values); cJSON_AddItemToObject(root, "voltage", cJSON_CreateFloatArray(values, 3)); energy_meter_get_current(values); cJSON_AddItemToObject(root, "current", cJSON_CreateFloatArray(values, 3)); return root; } cJSON *json_get_info(void) { cJSON *root = cJSON_CreateObject(); cJSON_AddNumberToObject(root, "uptime", esp_timer_get_time() / 1000000); const esp_app_desc_t *app_desc = esp_app_get_description(); cJSON_AddStringToObject(root, "appVersion", app_desc->version); cJSON_AddStringToObject(root, "appDate", app_desc->date); cJSON_AddStringToObject(root, "appTime", app_desc->time); cJSON_AddStringToObject(root, "idfVersion", app_desc->idf_ver); cJSON_AddStringToObject(root, "chip", CONFIG_IDF_TARGET); esp_chip_info_t chip_info; esp_chip_info(&chip_info); cJSON_AddNumberToObject(root, "chipCores", chip_info.cores); chip_info.revision = 301; cJSON_AddNumberToObject(root, "chipRevision", chip_info.revision / 100); multi_heap_info_t heap_info; heap_caps_get_info(&heap_info, MALLOC_CAP_INTERNAL); cJSON_AddNumberToObject(root, "heapSize", heap_info.total_allocated_bytes); cJSON_AddNumberToObject(root, "maxHeapSize", heap_info.total_free_bytes + heap_info.total_allocated_bytes); uint8_t mac[6]; char str[32]; esp_wifi_get_mac(ESP_IF_WIFI_STA, mac); sprintf(str, MACSTR, MAC2STR(mac)); cJSON_AddStringToObject(root, "mac", str); esp_netif_ip_info_t ip_info; esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &ip_info); esp_ip4addr_ntoa(&ip_info.ip, str, sizeof(str)); cJSON_AddStringToObject(root, "ip", str); esp_wifi_get_mac(ESP_IF_WIFI_AP, mac); sprintf(str, MACSTR, MAC2STR(mac)); cJSON_AddStringToObject(root, "macAp", str); esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_AP_DEF"), &ip_info); esp_ip4addr_ntoa(&ip_info.ip, str, sizeof(str)); cJSON_AddStringToObject(root, "ipAp", str); cJSON_AddNumberToObject(root, "temperatureSensorCount", temp_sensor_get_count()); cJSON_AddNumberToObject(root, "temperatureLow", temp_sensor_get_low() / 100.0); cJSON_AddNumberToObject(root, "temperatureHigh", temp_sensor_get_high() / 100.0); return root; } static const char *serial_to_str(board_config_serial_t serial) { switch (serial) { case BOARD_CONFIG_SERIAL_UART: return "uart"; case BOARD_CONFIG_SERIAL_RS485: return "rs485"; default: return "none"; } } cJSON *json_get_board_config(void) { cJSON *root = cJSON_CreateObject(); cJSON_AddStringToObject(root, "deviceName", board_config.device_name); cJSON_AddBoolToObject(root, "socketLock", board_config.socket_lock); cJSON_AddBoolToObject(root, "proximity", board_config.proximity); cJSON_AddNumberToObject(root, "socketLockMinBreakTime", board_config.socket_lock_min_break_time); cJSON_AddBoolToObject(root, "rcm", board_config.rcm); cJSON_AddBoolToObject(root, "temperatureSensor", board_config.onewire && board_config.onewire_temp_sensor); switch (board_config.energy_meter) { case BOARD_CONFIG_ENERGY_METER_CUR: cJSON_AddStringToObject(root, "energyMeter", "cur"); break; case BOARD_CONFIG_ENERGY_METER_CUR_VLT: cJSON_AddStringToObject(root, "energyMeter", "cur_vlt"); break; default: cJSON_AddStringToObject(root, "energyMeter", "none"); } cJSON_AddBoolToObject(root, "energyMeterThreePhases", board_config.energy_meter_three_phases); cJSON_AddStringToObject(root, "serial1", serial_to_str(board_config.serial_1)); cJSON_AddStringToObject(root, "serial1Name", board_config.serial_1_name); cJSON_AddStringToObject(root, "serial2", serial_to_str(board_config.serial_2)); cJSON_AddStringToObject(root, "serial2Name", board_config.serial_2_name); #if SOC_UART_NUM > 2 cJSON_AddStringToObject(root, "serial3", serial_to_str(board_config.serial_3)); cJSON_AddStringToObject(root, "serial3Name", board_config.serial_3_name); #else cJSON_AddStringToObject(root, "serial3", serial_to_str(BOARD_CONFIG_SERIAL_NONE)); cJSON_AddStringToObject(root, "serial3Name", ""); #endif cJSON *aux = cJSON_CreateArray(); if (board_config.aux_in_1) { cJSON_AddItemToArray(aux, cJSON_CreateString(board_config.aux_in_1_name)); } if (board_config.aux_in_2) { cJSON_AddItemToArray(aux, cJSON_CreateString(board_config.aux_in_2_name)); } if (board_config.aux_in_3) { cJSON_AddItemToArray(aux, cJSON_CreateString(board_config.aux_in_3_name)); } if (board_config.aux_in_4) { cJSON_AddItemToArray(aux, cJSON_CreateString(board_config.aux_in_4_name)); } cJSON_AddItemToObject(root, "auxIn", aux); aux = cJSON_CreateArray(); if (board_config.aux_out_1) { cJSON_AddItemToArray(aux, cJSON_CreateString(board_config.aux_out_1_name)); } if (board_config.aux_out_2) { cJSON_AddItemToArray(aux, cJSON_CreateString(board_config.aux_out_2_name)); } if (board_config.aux_out_3) { cJSON_AddItemToArray(aux, cJSON_CreateString(board_config.aux_out_3_name)); } if (board_config.aux_out_4) { cJSON_AddItemToArray(aux, cJSON_CreateString(board_config.aux_out_4_name)); } cJSON_AddItemToObject(root, "auxOut", aux); aux = cJSON_CreateArray(); if (board_config.aux_ain_1) { cJSON_AddItemToArray(aux, cJSON_CreateString(board_config.aux_ain_1_name)); } if (board_config.aux_ain_2) { cJSON_AddItemToArray(aux, cJSON_CreateString(board_config.aux_ain_2_name)); } cJSON_AddItemToObject(root, "auxAin", aux); return root; }