diff --git a/components/modbus_slave/include/modbus.h b/components/modbus_slave/include/modbus.h index 9258f57..fd10f05 100644 --- a/components/modbus_slave/include/modbus.h +++ b/components/modbus_slave/include/modbus.h @@ -13,7 +13,7 @@ //#define MB_SUPPORT_FC01 // READ_COILS //#define MB_SUPPORT_FC02 // READ_DISCRETES #define MB_SUPPORT_FC03 // READ_HOLDING_REGISTERS -//#define MB_SUPPORT_FC04 // READ_INPUT_REGISTERS +#define MB_SUPPORT_FC04 // READ_INPUT_REGISTERS //#define MB_SUPPORT_FC05 // WRITE_SINGLE_COIL #define MB_SUPPORT_FC06 // WRITE_SINGLE_REGISTER //#define MB_SUPPORT_FC15 // WRITE_MULTIPLE_COILS diff --git a/main/fancontrol.c b/main/fancontrol.c index 8d63b58..4641c2a 100644 --- a/main/fancontrol.c +++ b/main/fancontrol.c @@ -166,6 +166,11 @@ static void timerCallback(TimerHandle_t xTimer) if (do_switch) { // zmena smeru + if (gAct.dir == MOTOR_DIR_IN) { + gState.real_recup_time_in = gState.run_time; + } else { + gState.real_recup_time_out = gState.run_time; + } gState.run_time = 0; act_motor_direction_set(1 - gAct.dir); end_temp_meas = true; @@ -220,10 +225,10 @@ static void timerCallback(TimerHandle_t xTimer) int16_t t1 = act_temp_in(); int16_t t2 = act_temp_out(); - gState.t_actual_1 = t1; - gState.t_actual_2 = t2; + gState.t_actual_in = t1; + gState.t_actual_out = t2; - gState.valid_t_actual_1 = gState.valid_t_actual_2 = true; + gState.valid_t_actual_in = gState.valid_t_actual_out = true; if (gAct.dir == gState.real_direction && gState.ramp >= gSettings.ramp_time) @@ -233,7 +238,7 @@ static void timerCallback(TimerHandle_t xTimer) gState.t_aggr_cnt++; } } else { - gState.valid_t_actual_1 = gState.valid_t_actual_2 = false; + gState.valid_t_actual_in = gState.valid_t_actual_out = false; } } @@ -262,8 +267,8 @@ static void invalidate_temps() gState.valid_t_outdoor = false; gState.valid_t_inflow = false; gState.valid_t_exhaust = false; - gState.valid_t_actual_1 = false; - gState.valid_t_actual_2 = false; + gState.valid_t_actual_in = false; + gState.valid_t_actual_out = false; } void fan_set_power(uint16_t power) diff --git a/main/fancontrol.h b/main/fancontrol.h index 63b741a..2eee3cd 100644 --- a/main/fancontrol.h +++ b/main/fancontrol.h @@ -45,16 +45,19 @@ struct FanControlState { bool valid_t_outdoor; bool valid_t_inflow; bool valid_t_exhaust; - bool valid_t_actual_1; - bool valid_t_actual_2; + bool valid_t_actual_in; + bool valid_t_actual_out; int16_t t_indoor; int16_t t_outdoor; int16_t t_inflow; int16_t t_exhaust; - int16_t t_actual_1; - int16_t t_actual_2; + int16_t t_actual_in; + int16_t t_actual_out; + + uint16_t real_recup_time_in; + uint16_t real_recup_time_out; // Private /** diff --git a/main/mbiface.c b/main/mbiface.c index 0672c7b..d61848a 100644 --- a/main/mbiface.c +++ b/main/mbiface.c @@ -3,12 +3,44 @@ #include "socket_server.h" #include "tasks.h" #include "modbus.h" +#include "fancontrol.h" +#include "settings.h" static const char * TAG = "mb"; Tcpd_t g_mbifc_server = NULL; -ModbusSlave_t g_modbus; -static volatile uint16_t register2 = 0; +ModbusSlave_t gModbus; + +enum HoldingRegisters { + H_MODE = 1, + H_POWER, + H_SUMMER, + H_INITIAL_MODE, + H_INITIAL_POWER, + H_RECUP_MODE, + H_RECUP_TIME, + H_RECUP_TIME_MIN, + H_RECUP_TIME_MAX, + H_RECUP_FACTOR, + H_RAMP_TIME, + H_BLIND_TIME, + H_MIN_POWER, +}; + +enum InputRegisters { + I_RECUP_TIME_IN = 1, + I_RECUP_TIME_OUT, + I_T_VALIDITY, + I_T_IN_INST, + I_T_OUT_INST, + I_T_INDOOR, + I_T_OUTDOOR, + I_T_INFLOW, + I_T_EXHAUST, + I_MODE_INST, + I_MOTOR_RAMP, + I_BLIND_RAMP, +}; /** * Socket read handler @@ -21,7 +53,7 @@ static esp_err_t read_fn(Tcpd_t serv, TcpdClient_t client, int sockfd) if (nbytes <= 0) return ESP_FAIL; size_t resp_len = 0; - ModbusError_t e = mb_handleRequest(&g_modbus, buf, nbytes, buf2, 1024, &resp_len); + ModbusError_t e = mb_handleRequest(&gModbus, buf, nbytes, buf2, 1024, &resp_len); if (e == 0) { tcpd_send(client, buf2, (ssize_t) resp_len); } else { @@ -40,41 +72,230 @@ void endOfAccess(ModbusSlave_t *ms) { // } +ModbusException_t ri(ModbusSlave_t *pSlave, uint16_t ref, uint16_t *pValue) { + ESP_LOGD(TAG, "Read input %d", ref); + uint16_t scratch = 0; + + switch (ref) { + case I_RECUP_TIME_IN: + *pValue = gState.real_recup_time_in; + break; + case I_RECUP_TIME_OUT: + *pValue = gState.real_recup_time_out; + break; + case I_T_VALIDITY: + scratch |= (int)gState.valid_t_actual_in; + scratch |= (int)gState.valid_t_actual_out << 1; + scratch |= (int)gState.valid_t_indoor << 2; + scratch |= (int)gState.valid_t_outdoor << 3; + scratch |= (int)gState.valid_t_inflow << 4; + scratch |= (int)gState.valid_t_exhaust << 5; + *pValue = scratch; + break; + case I_T_IN_INST: + *pValue = gState.t_actual_in; + break; + case I_T_OUT_INST: + *pValue = gState.t_actual_out; + break; + case I_T_INDOOR: + *pValue = gState.t_indoor; + break; + case I_T_OUTDOOR: + *pValue = gState.t_outdoor; + break; + case I_T_INFLOW: + *pValue = gState.t_inflow; + break; + case I_T_EXHAUST: + *pValue = gState.t_exhaust; + break; + case I_MODE_INST: + *pValue = gState.instantaneous_vent_mode; + break; + case I_MOTOR_RAMP: + *pValue = gState.ramp; + break; + case I_BLIND_RAMP: + *pValue = gState.blind_position; + break; + + default: + return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS; + } + + return MB_EXCEPTION_OK; +} + ModbusException_t rh(ModbusSlave_t *pSlave, uint16_t ref, uint16_t *pValue) { ESP_LOGD(TAG, "Read holding %d", ref); - if (ref == 1) { - *pValue = 1042; // device ID - return 0; - } - if (ref == 2) { - *pValue = register2; - return 0; + switch (ref) { + case H_MODE: + *pValue = (int) gState.set_vent_mode; + break; + case H_POWER: + *pValue = gState.set_power; + break; + case H_SUMMER: + *pValue = (int) gSettings.summer_mode; + break; + case H_INITIAL_MODE: + *pValue = (int) gSettings.initial_mode; + break; + case H_INITIAL_POWER: + *pValue = gSettings.initial_power; + break; + case H_RECUP_MODE: + *pValue = gSettings.recup_mode; + break; + case H_RECUP_TIME: + *pValue = gSettings.recup_time; + break; + case H_RECUP_TIME_MIN: + *pValue = gSettings.min_recup_time; + break; + case H_RECUP_TIME_MAX: + *pValue = gSettings.max_recup_time; + break; + case H_RECUP_FACTOR: + *pValue = gSettings.recup_factor; + break; + case H_RAMP_TIME: + *pValue = gSettings.ramp_time; + break; + case H_BLIND_TIME: + *pValue = gSettings.blind_time; + break; + case H_MIN_POWER: + *pValue = gSettings.min_power; + break; + default: + // inputs are mapped to the holding address space + if (ref >= 100) { + return ri(pSlave, ref - 100, pValue); + } + + return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS; } - return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS; + return MB_EXCEPTION_OK; +} + +static bool is_valid_vent_mode(int value) { + switch (value) { + case VENT_MODE_OFF: + case VENT_MODE_FREE: + case VENT_MODE_OUT: + case VENT_MODE_IN: + case VENT_MODE_RECUP: + return true; + default: + return false; + } } ModbusException_t wh(ModbusSlave_t *pSlave, uint16_t ref, uint16_t value) { ESP_LOGD(TAG, "Write holding %d := %02x", ref, value); - if (ref == 2) { - register2 = value; - return 0; + switch (ref) { + case H_MODE: + if (!is_valid_vent_mode(value)) { + return MB_EXCEPTION_ILLEGAL_DATA_VALUE; + } + fan_set_vent_mode(value); + break; + case H_POWER: + if (value > 100) { + return MB_EXCEPTION_ILLEGAL_DATA_VALUE; + } + fan_set_power(value); + break; + case H_SUMMER: + gSettings.summer_mode = (value != 0); + settings_persist(SETTINGS_summer_mode); + break; + case H_INITIAL_MODE: + if (!is_valid_vent_mode(value)) { + return MB_EXCEPTION_ILLEGAL_DATA_VALUE; + } + gSettings.initial_mode = value; + settings_persist(SETTINGS_initial_mode); + break; + case H_INITIAL_POWER: + if (value > 100) { + return MB_EXCEPTION_ILLEGAL_DATA_VALUE; + } + gSettings.initial_power = value; + settings_persist(SETTINGS_initial_power); + break; + case H_RECUP_MODE: + if (value == RECUP_MODE_TEMP || value == RECUP_MODE_TIME) { + gSettings.recup_mode = value; + } else { + return MB_EXCEPTION_ILLEGAL_DATA_VALUE; + } + break; + case H_RECUP_TIME: + if (value == 0) { + return MB_EXCEPTION_ILLEGAL_DATA_VALUE; + } + gSettings.recup_time = value; + settings_persist(SETTINGS_recup_time); + break; + case H_RECUP_TIME_MIN: + if (value == 0) { + return MB_EXCEPTION_ILLEGAL_DATA_VALUE; + } + gSettings.min_recup_time = value; + settings_persist(SETTINGS_min_recup_time); + break; + case H_RECUP_TIME_MAX: + if (value == 0) { + return MB_EXCEPTION_ILLEGAL_DATA_VALUE; + } + gSettings.max_recup_time = value; + settings_persist(SETTINGS_max_recup_time); + break; + case H_RECUP_FACTOR: + if (value > 100) { + return MB_EXCEPTION_ILLEGAL_DATA_VALUE; + } + gSettings.recup_factor = value; + settings_persist(SETTINGS_recup_factor); + break; + case H_RAMP_TIME: + gSettings.ramp_time = value; + settings_persist(SETTINGS_ramp_time); + break; + case H_BLIND_TIME: + gSettings.blind_time = value; + settings_persist(SETTINGS_blind_time); + break; + case H_MIN_POWER: + if (value > 100) { + return MB_EXCEPTION_ILLEGAL_DATA_VALUE; + } + gSettings.min_power = value; + settings_persist(SETTINGS_min_power); + break; + default: + return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS; } - return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS; + return MB_EXCEPTION_OK; } void mbiface_setup() { ESP_LOGI(TAG, "initing MB iface"); - g_modbus.proto = MB_PROTO_TCP; - g_modbus.addr = 1; - g_modbus.startOfAccess = startOfAccess; - g_modbus.endOfAccess = endOfAccess; - g_modbus.readHolding = rh; - g_modbus.writeHolding = wh; + gModbus.proto = MB_PROTO_TCP; + gModbus.addr = 1; + gModbus.startOfAccess = startOfAccess; + gModbus.endOfAccess = endOfAccess; + gModbus.readHolding = rh; + gModbus.writeHolding = wh; + gModbus.readInput = ri; tcpd_config_t server_config = TCPD_INIT_DEFAULT(); server_config.max_clients = 1; diff --git a/main/mbiface.h b/main/mbiface.h index eb7697f..f6a9427 100644 --- a/main/mbiface.h +++ b/main/mbiface.h @@ -9,7 +9,7 @@ #include "modbus.h" extern Tcpd_t g_mbifc_server; -extern ModbusSlave_t g_modbus; +extern ModbusSlave_t gModbus; void mbiface_setup(); diff --git a/main/user_main.c b/main/user_main.c index 0a9a121..6730254 100644 --- a/main/user_main.c +++ b/main/user_main.c @@ -18,7 +18,6 @@ #include "wifi_conn.h" #include "console/register_cmds.h" -#include "irblast.h" #include "mbiface.h" #include "actuators.h" #include "fancontrol.h"