isv/p18.h
2020-10-24 02:38:24 +03:00

505 lines
18 KiB
C

/**
* Copyright (C) 2020 Evgeny Zinoviev
* This file is part of isv <https://github.com/gch1p/isv>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ISV_P18_H
#define ISV_P18_H
#include <stdbool.h>
#include <string.h>
#include "util.h"
#define P18_QUERY_CMDS_ENUM_OFFSET 1000
#define P18_SET_CMDS_ENUM_OFFSET 1100
#define MK_P18_UNPACK_FN_NAME(msg_type) p18_unpack_ ## msg_type ## _msg
#define MK_P18_PARSE_CB_FN_NAME(msg_type) p18_parse_cb_ ## msg_type ## _msg
#define MK_P18_MSG_T(msg_type) p18_ ## msg_type ## _msg_t
#define P18_MSG_T(msg_type) MK_P18_MSG_T(msg_type)
#define P18_UNPACK_FN_NAME(msg_type) MK_P18_UNPACK_FN_NAME(msg_type)
#define P18_PARSE_CB_FN_NAME(msg_type) MK_P18_PARSE_CB_FN_NAME(msg_type)
#define P18_UNPACK_FN(msg_type) \
P18_MSG_T(msg_type) P18_UNPACK_FN_NAME(msg_type)(const char *data)
#define P18_PARSE_CB_FN(msg_type) \
static void P18_PARSE_CB_FN_NAME(msg_type)(const char *value, \
size_t value_len, \
unsigned int index, \
void *message_ptr)
#define P18_PARSE_LIST_AND_RETURN(msg_type, exp_items_count) \
P18_MSG_T(msg_type) m = {0}; \
p18_parse_list(data, &m, (exp_items_count), P18_PARSE_CB_FN_NAME(msg_type)); \
return m;
#define P18_EXPECT_LISTITEM_LENGTH(len) \
p18_expect_listitem_length((const char *)__func__, index, (len), value_len)
typedef void (*p18_parse_cb_t)(const char *, size_t, unsigned int, void *);
/* ------------------------------------------ */
/* Commands list */
enum p18_query_command {
P18_QUERY_PROTOCOL_ID = P18_QUERY_CMDS_ENUM_OFFSET,
P18_QUERY_CURRENT_TIME,
P18_QUERY_TOTAL_GENERATED,
P18_QUERY_YEAR_GENERATED,
P18_QUERY_MONTH_GENERATED,
P18_QUERY_DAY_GENERATED,
P18_QUERY_SERIES_NUMBER,
P18_QUERY_CPU_VERSION,
P18_QUERY_RATED_INFORMATION,
P18_QUERY_GENERAL_STATUS,
P18_QUERY_WORKING_MODE,
P18_QUERY_FAULTS_WARNINGS,
P18_QUERY_FLAGS_STATUSES,
P18_QUERY_DEFAULTS,
P18_QUERY_MAX_CHARGING_CURRENT_SELECTABLE_VALUES,
P18_QUERY_MAX_AC_CHARGING_CURRENT_SELECTABLE_VALUES,
P18_QUERY_PARALLEL_RATED_INFORMATION,
P18_QUERY_PARALLEL_GENERAL_STATUS,
P18_QUERY_AC_CHARGE_TIME_BUCKET,
P18_QUERY_AC_SUPPLY_LOAD_TIME_BUCKET,
};
enum p18_set_command {
P18_SET_LOADS = P18_SET_CMDS_ENUM_OFFSET,
P18_SET_FLAG,
P18_SET_DEFAULTS,
P18_SET_BAT_MAX_CHARGE_CURRENT,
P18_SET_BAT_MAX_AC_CHARGE_CURRENT,
P18_SET_AC_OUTPUT_FREQ,
P18_SET_BAT_MAX_CHARGE_VOLTAGE,
P18_SET_AC_OUTPUT_RATED_VOLTAGE,
P18_SET_OUTPUT_SOURCE_PRIORITY,
P18_SET_BAT_CHARGING_THRESHOLDS_WHEN_UTILITY_AVAIL, /* Battery re-charging and re-discharing voltage when utility is available */
P18_SET_CHARGING_SOURCE_PRIORITY,
P18_SET_SOLAR_POWER_PRIORITY,
P18_SET_AC_INPUT_VOLTAGE_RANGE,
P18_SET_BAT_TYPE,
P18_SET_OUTPUT_MODEL,
P18_SET_BAT_CUTOFF_VOLTAGE,
P18_SET_SOLAR_CONFIG,
P18_SET_CLEAR_GENERATED,
P18_SET_DATE_TIME,
P18_SET_AC_CHARGE_TIME_BUCKET,
P18_SET_AC_SUPPLY_LOAD_TIME_BUCKET,
};
typedef enum {
P18_BT_AGM = 0,
P18_BT_FLOODED = 1,
P18_BT_USER = 2,
} p18_battery_type_t;
typedef enum {
P18_IVR_APPLIANCE = 0,
P18_IVR_UPS = 1,
} p18_input_voltage_range_t;
typedef enum {
P18_OSP_SOLAR_UTILITY_BATTERY = 0,
P18_OSP_SOLAR_BATTERY_UTILITY = 1,
} p18_output_source_priority_t;
typedef enum {
P18_CSP_SOLAR_FIRST = 0,
P18_CSP_SOLAR_AND_UTILITY = 1,
P18_CSP_SOLAR_ONLY = 2,
} p18_charger_source_priority_t;
typedef enum {
P18_MT_OFF_GRID_TIE = 0,
P18_MT_GRID_TIE = 1,
} p18_machine_type_t;
typedef enum {
P18_TRANSFORMERLESS = 0,
P18_TRANSFORMER = 1,
} p18_topology_t;
typedef enum {
P18_OMS_SINGLE_MODULE = 0,
P18_OMS_PARALLEL_OUTPUT = 1,
P18_OMS_PHASE1_OF_3PHASE_OUTPUT = 2,
P18_OMS_PHASE2_OF_3PHASE_OUTPUT = 3,
P18_OMS_PHASE3_OF_3PHASE_OUTPUT = 4,
} p18_output_model_setting_t;
typedef enum {
P18_SPP_BATTERY_LOAD_UTILITY = 0,
P18_SPP_LOAD_BATTERY_UTILITY = 1,
} p18_solar_power_priority_t;
typedef enum {
P18_MPPT_CS_ABNORMAL = 0,
P18_MPPT_CS_NOT_CHARGED = 1,
P18_MPPT_CS_CHARGED = 2,
} p18_mppt_charger_status_t;
typedef enum {
P18_BPD_DONOTHING = 0,
P18_BPD_CHARGE = 1,
P18_BPD_DISCHARGE = 2,
} p18_battery_power_direction_t;
typedef enum {
P18_DAPD_DONOTHING = 0,
P18_DAPD_AC_DC = 1,
P18_DAPD_DC_AC = 2,
} p18_dc_ac_power_direction_t;
typedef enum {
P18_LPD_DONOTHING = 0,
P18_LPD_INPUT = 1,
P18_LPD_OUTPUT = 2,
} p18_line_power_direction_t;
typedef enum {
P18_WM_POWER_ON_MODE = 0,
P18_WM_STANDBY_MODE = 1,
P18_WM_BYPASS_MODE = 2,
P18_WM_BATTERY_MODE = 3,
P18_WM_FAULT_MODE = 4,
P18_WM_HYBRID_MODE = 5,
} p18_working_mode_t;
typedef enum {
P18_PCS_NON_EXISTENT = 0,
P18_PCS_EXISTENT = 1,
} p18_parallel_id_connection_status_t;
/* ------------------------------------------ */
/* Message structs */
typedef struct {
unsigned int id;
} p18_protocol_id_msg_t;
typedef struct {
unsigned int year;
unsigned short month;
unsigned short day;
unsigned short hour;
unsigned short minute;
unsigned short second;
} p18_current_time_msg_t;
typedef struct {
unsigned long kwh;
} p18_total_generated_msg_t;
typedef struct {
unsigned long kwh;
} p18_year_generated_msg_t;
typedef struct {
unsigned long kwh;
} p18_month_generated_msg_t;
typedef struct {
unsigned long kwh;
} p18_day_generated_msg_t;
typedef struct {
short length;
char id[32];
} p18_series_number_msg_t;
typedef struct {
char main_cpu_version[6];
char slave1_cpu_version[6];
char slave2_cpu_version[6];
} p18_cpu_version_msg_t;
typedef struct {
unsigned int ac_input_rating_voltage; /* unit: 0.1V */
unsigned int ac_input_rating_current; /* unit: 0.1A */
unsigned int ac_output_rating_voltage; /* unit: 0.1A */
unsigned int ac_output_rating_freq; /* unit: 0.1Hz */
unsigned int ac_output_rating_current; /* unit: 0.1A */
unsigned int ac_output_rating_apparent_power; /* unit: VA */
unsigned int ac_output_rating_active_power; /* unit: W */
unsigned int battery_rating_voltage; /* unit: 0.1V */
unsigned int battery_recharge_voltage; /* unit: 0.1V */
unsigned int battery_redischarge_voltage; /* unit: 0.1V */
unsigned int battery_under_voltage; /* unit: 0.1V */
unsigned int battery_bulk_voltage; /* unit: 0.1V */
unsigned int battery_float_voltage; /* unit: 0.1V */
p18_battery_type_t battery_type;
unsigned int max_ac_charging_current; /* unit: A */
unsigned int max_charging_current; /* unit: A */
p18_input_voltage_range_t input_voltage_range;
p18_output_source_priority_t output_source_priority;
p18_charger_source_priority_t charger_source_priority;
unsigned int parallel_max_num;
p18_machine_type_t machine_type;
p18_topology_t topology;
p18_output_model_setting_t output_model_setting;
p18_solar_power_priority_t solar_power_priority;
char mppt[4];
} p18_rated_information_msg_t;
typedef struct {
unsigned int grid_voltage; /* unit: 0.1V */
unsigned int grid_freq; /* unit: 0.1Hz */
unsigned int ac_output_voltage; /* unit: 0.1V */
unsigned int ac_output_freq; /* unit: 0.1Hz */
unsigned int ac_output_apparent_power; /* unit: VA */
unsigned int ac_output_active_power; /* unit: W */
unsigned int output_load_percent; /* unit: % */
unsigned int battery_voltage; /* unit: 0.1V */
unsigned int battery_voltage_scc; /* unit: 0.1V */
unsigned int battery_voltage_scc2; /* unit: 0.1V */
unsigned int battery_discharge_current; /* unit: A */
unsigned int battery_charging_current; /* unit: A */
unsigned int battery_capacity; /* unit: % */
unsigned int inverter_heat_sink_temp; /* unit: C */
unsigned int mppt1_charger_temp; /* unit: C */
unsigned int mppt2_charger_temp; /* unit: C */
unsigned int pv1_input_power; /* unit: W */
unsigned int pv2_input_power; /* unit: W */
unsigned int pv1_input_voltage; /* unit: 0.1V */
unsigned int pv2_input_voltage; /* unit: 0.1V */
bool settings_values_changed; /* inverter returns:
0: nothing changed
1: something changed */
p18_mppt_charger_status_t mppt1_charger_status;
p18_mppt_charger_status_t mppt2_charger_status;
bool load_connected; /* inverter returns:
0: disconnected
1: connected */
p18_battery_power_direction_t battery_power_direction;
p18_dc_ac_power_direction_t dc_ac_power_direction;
p18_line_power_direction_t line_power_direction;
unsigned int local_parallel_id; /* 0 .. (parallel number - 1) */
} p18_general_status_msg_t;
typedef struct {
p18_working_mode_t mode;
} p18_working_mode_msg_t;
typedef struct {
unsigned int fault_code;
bool line_fail;
bool output_circuit_short;
bool inverter_over_temperature;
bool fan_lock;
bool battery_voltage_high;
bool battery_low;
bool battery_under;
bool over_load;
bool eeprom_fail;
bool power_limit;
bool pv1_voltage_high;
bool pv2_voltage_high;
bool mppt1_overload_warning;
bool mppt2_overload_warning;
bool battery_too_low_to_charge_for_scc1;
bool battery_too_low_to_charge_for_scc2;
} p18_faults_warnings_msg_t;
typedef struct {
bool buzzer;
bool overload_bypass;
bool lcd_escape_to_default_page_after_1min_timeout;
bool overload_restart;
bool over_temp_restart;
bool backlight_on;
bool alarm_on_primary_source_interrupt;
bool fault_code_record;
char reserved;
} p18_flags_statuses_msg_t;
typedef struct {
unsigned int ac_output_voltage; /* unit: 0.1V */
unsigned int ac_output_freq;
p18_input_voltage_range_t ac_input_voltage_range;
unsigned int battery_under_voltage;
unsigned int charging_float_voltage;
unsigned int charging_bulk_voltage;
unsigned int battery_recharge_voltage;
unsigned int battery_redischarge_voltage;
unsigned int max_charging_current;
unsigned int max_ac_charging_current;
p18_battery_type_t battery_type;
p18_output_source_priority_t output_source_priority;
p18_charger_source_priority_t charger_source_priority;
p18_solar_power_priority_t solar_power_priority;
p18_machine_type_t machine_type;
p18_output_model_setting_t output_model_setting;
bool flag_buzzer;
bool flag_overload_restart;
bool flag_over_temp_restart;
bool flag_backlight_on;
bool flag_alarm_on_primary_source_interrupt;
bool flag_fault_code_record;
bool flag_overload_bypass;
bool flag_lcd_escape_to_default_page_after_1min_timeout;
} p18_defaults_msg_t;
typedef struct {
size_t len;
int amps[32];
} p18_max_charging_current_selectable_values_msg_t;
typedef struct {
size_t len;
int amps[32];
} p18_max_ac_charging_current_selectable_values_msg_t;
typedef struct {
p18_parallel_id_connection_status_t parallel_id_connection_status;
int serial_number_valid_length;
char serial_number[32];
p18_charger_source_priority_t charger_source_priority;
unsigned int max_ac_charging_current; /* unit: A */
unsigned int max_charging_current; /* unit: A */
p18_output_model_setting_t output_model_setting;
} p18_parallel_rated_information_msg_t;
typedef struct {
p18_parallel_id_connection_status_t parallel_id_connection_status;
p18_working_mode_t work_mode;
unsigned int fault_code;
unsigned int grid_voltage; /* unit: 0.1V */
unsigned int grid_freq; /* unit: 0.1Hz */
unsigned int ac_output_voltage; /* unit: 0.1V */
unsigned int ac_output_freq; /* unit: 0.1Hz */
unsigned int ac_output_apparent_power; /* unit: VA */
unsigned int ac_output_active_power; /* unit: W */
unsigned int total_ac_output_apparent_power; /* unit: VA */
unsigned int total_ac_output_active_power; /* unit: W */
unsigned int output_load_percent; /* unit: % */
unsigned int total_output_load_percent; /* unit: % */
unsigned int battery_voltage; /* unit: 0.1V */
unsigned int battery_discharge_current; /* unit: A */
unsigned int battery_charging_current; /* unit: A */
unsigned int total_battery_charging_current; /* unit: A */
unsigned int battery_capacity; /* unit: % */
unsigned int pv1_input_power; /* unit: W */
unsigned int pv2_input_power; /* unit: W */
unsigned int pv1_input_voltage; /* unit: 0.1V */
unsigned int pv2_input_voltage; /* unit: 0.1V */
p18_mppt_charger_status_t mppt1_charger_status;
p18_mppt_charger_status_t mppt2_charger_status;
bool load_connected; /* inverter returns:
0: disconnected
1: connected */
p18_battery_power_direction_t battery_power_direction;
p18_dc_ac_power_direction_t dc_ac_power_direction;
p18_line_power_direction_t line_power_direction;
unsigned int max_temp; /* unit: C */
} p18_parallel_general_status_msg_t;
typedef struct {
unsigned short start_h;
unsigned short start_m;
unsigned short end_h;
unsigned short end_m;
} p18_ac_charge_time_bucket_msg_t;
typedef struct {
unsigned short start_h;
unsigned short start_m;
unsigned short end_h;
unsigned short end_m;
} p18_ac_supply_load_time_bucket_msg_t;
/* ------------------------------------------ */
/* Some constants and allowed values */
typedef struct {
unsigned int id;
char message[64];
} p18_fault_code_list_item_t;
typedef struct {
char *key;
char *p18_key;
char *title;
} p18_flag_printable_list_item_t;
extern const p18_flag_printable_list_item_t p18_flags_printable_list[9];
extern const int p18_ac_output_rated_voltages[5];
extern const char *p18_battery_util_recharging_voltages_12v_unit[8];
extern const char *p18_battery_util_recharging_voltages_24v_unit[8];
extern const char *p18_battery_util_recharging_voltages_48v_unit[8];
extern const char *p18_battery_util_redischarging_voltages_12v_unit[12];
extern const char *p18_battery_util_redischarging_voltages_24v_unit[12];
extern const char *p18_battery_util_redischarging_voltages_48v_unit[12];
/* ------------------------------------------ */
/* Common methods */
bool p18_build_command(int command, const char **args, size_t args_size, char *buf);
bool p18_validate_query_response(const char *buf, size_t size, size_t *data_size);
bool p18_set_result(const char *buf, size_t size);
/* ------------------------------------------ */
/* Command-specific methods */
P18_UNPACK_FN(protocol_id);
P18_UNPACK_FN(current_time);
P18_UNPACK_FN(total_generated);
P18_UNPACK_FN(year_generated);
P18_UNPACK_FN(month_generated);
P18_UNPACK_FN(day_generated);
P18_UNPACK_FN(series_number);
P18_UNPACK_FN(cpu_version);
P18_UNPACK_FN(rated_information);
P18_UNPACK_FN(general_status);
P18_UNPACK_FN(working_mode);
P18_UNPACK_FN(faults_warnings);
P18_UNPACK_FN(flags_statuses);
P18_UNPACK_FN(defaults);
P18_UNPACK_FN(max_charging_current_selectable_values);
P18_UNPACK_FN(max_ac_charging_current_selectable_values);
P18_UNPACK_FN(parallel_rated_information);
P18_UNPACK_FN(parallel_general_status);
P18_UNPACK_FN(ac_charge_time_bucket);
P18_UNPACK_FN(ac_supply_load_time_bucket);
/* ------------------------------------------ */
/* Label getters */
const char *p18_battery_type_label(p18_battery_type_t type);
const char *p18_input_voltage_range_label(p18_input_voltage_range_t range);
const char *p18_output_source_priority_label(p18_output_source_priority_t priority);
const char *p18_charge_source_priority_label(p18_charger_source_priority_t priority);
const char *p18_machine_type_label(p18_machine_type_t type);
const char *p18_topology_label(p18_topology_t topology);
const char *p18_output_model_setting_label(p18_output_model_setting_t setting);
const char *p18_solar_power_priority_label(p18_solar_power_priority_t priority);
const char *p18_mppt_charger_status_label(p18_mppt_charger_status_t status);
const char *p18_battery_power_direction_label(p18_battery_power_direction_t direction);
const char *p18_dc_ac_power_direction_label(p18_dc_ac_power_direction_t direction);
const char *p18_line_power_direction_label(p18_line_power_direction_t direction);
const char *p18_working_mode_label(p18_working_mode_t mode);
const char *p18_fault_code_label(unsigned int code);
const char *p18_parallel_connection_status_label(p18_parallel_id_connection_status_t status);
#endif //ISV_P18_H