From 683c21124114a25f9d0bdfd3a9712a9dc7095fb9 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 23 Sep 2018 16:41:22 +0200 Subject: [PATCH] Fix Shelly2 wrong FrequencySet Fix Shelly2 wrong FrequencySet calculation and add input range checks (#3882) --- sonoff/_changelog.ino | 1 + sonoff/xnrg_04_mcp39f501.ino | 45 +++++++++++++++++++++++++----------- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index f38b68153..b7988c69c 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -6,6 +6,7 @@ * Add force_update to Home Assistant discovery (#3873) * Fix rule trigger POWER1#STATE execution after restart and SetOption0 is 0 (#3856) * Disable serial logging on Shelly2 as serial is being used by energy monitoring (#3878) + * Fix Shelly2 wrong FrequencySet calculation and add input range checks (#3882) * * 6.2.1.5 20180921 * Add authentication to HTTP web pages diff --git a/sonoff/xnrg_04_mcp39f501.ino b/sonoff/xnrg_04_mcp39f501.ino index 408e0ca26..3fa12da26 100644 --- a/sonoff/xnrg_04_mcp39f501.ino +++ b/sonoff/xnrg_04_mcp39f501.ino @@ -239,8 +239,12 @@ void McpCalibrationReactivePower() mcp_calibration_registers.gain_reactive_power = mcp_calibration_registers.gain_reactive_power * mcp_calibration_registers.calibration_reactive_power / mcp_output_registers.reactive_power; } -void McpCalibrationLineFreqency() +void McpCalibrationLineFrequency() { + if ((0xFFFF == mcp_output_registers.line_frequency) || (0 == mcp_frequency_registers.gain_line_frequency)) { // Reset values to 50Hz + mcp_output_registers.line_frequency = 50000; + mcp_frequency_registers.gain_line_frequency = 0x8000; + } mcp_frequency_registers.gain_line_frequency = mcp_frequency_registers.gain_line_frequency * mcp_frequency_registers.line_frequency_ref / mcp_output_registers.line_frequency; } @@ -481,7 +485,7 @@ void McpParseFrequency() if (mcp_calibration_setpoint.line_frequency_ref) { mcp_frequency_registers.line_frequency_ref = mcp_calibration_setpoint.line_frequency_ref; - McpCalibrationLineFreqency(); + McpCalibrationLineFrequency(); mcp_timeout = 0; McpSetFrequency(); } @@ -637,33 +641,46 @@ void McpDrvInit() boolean McpCommand() { boolean serviced = true; + unsigned long value = 0; if (CMND_POWERSET == energy_command_code) { if (XdrvMailbox.data_len && mcp_output_registers.active_power) { - Settings.energy_power_calibration = (unsigned long)(CharToDouble(XdrvMailbox.data) * 100); - mcp_calibration_setpoint.calibration_active_power = Settings.energy_power_calibration; - McpGetCalibration(); + value = (unsigned long)(CharToDouble(XdrvMailbox.data) * 100); + if ((value > 100) && (value < 200000)) { // Between 1W and 2000W + Settings.energy_power_calibration = value; + mcp_calibration_setpoint.calibration_active_power = value; + McpGetCalibration(); + } } } else if (CMND_VOLTAGESET == energy_command_code) { if (XdrvMailbox.data_len && mcp_output_registers.voltage_rms) { - Settings.energy_voltage_calibration = (unsigned long)(CharToDouble(XdrvMailbox.data) * 10); - mcp_calibration_setpoint.calibration_voltage = Settings.energy_voltage_calibration; - McpGetCalibration(); + value = (unsigned long)(CharToDouble(XdrvMailbox.data) * 10); + if ((value > 1000) && (value < 2600)) { // Between 100V and 260V + Settings.energy_voltage_calibration = value; + mcp_calibration_setpoint.calibration_voltage = value; + McpGetCalibration(); + } } } else if (CMND_CURRENTSET == energy_command_code) { if (XdrvMailbox.data_len && mcp_output_registers.current_rms) { - Settings.energy_current_calibration = (unsigned long)(CharToDouble(XdrvMailbox.data) * 10); - mcp_calibration_setpoint.calibration_current = Settings.energy_current_calibration; - McpGetCalibration(); + value = (unsigned long)(CharToDouble(XdrvMailbox.data) * 10); + if ((value > 100) && (value < 80000)) { // Between 10mA and 8A + Settings.energy_current_calibration = value; + mcp_calibration_setpoint.calibration_current = value; + McpGetCalibration(); + } } } else if (CMND_FREQUENCYSET == energy_command_code) { if (XdrvMailbox.data_len && mcp_output_registers.line_frequency) { - Settings.energy_frequency_calibration = (unsigned long)(CharToDouble(XdrvMailbox.data) * 10); - mcp_calibration_setpoint.line_frequency_ref = Settings.energy_frequency_calibration; - McpGetFrequency(); + value = (unsigned long)(CharToDouble(XdrvMailbox.data) * 1000); + if ((value > 45000) && (value < 65000)) { // Between 45Hz and 65Hz + Settings.energy_frequency_calibration = value; + mcp_calibration_setpoint.line_frequency_ref = value; + McpGetFrequency(); + } } } else serviced = false; // Unknown command