diff options
Diffstat (limited to 'p18.h')
-rw-r--r-- | p18.h | 505 |
1 files changed, 505 insertions, 0 deletions
@@ -0,0 +1,505 @@ +/** + * 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
\ No newline at end of file |