Tuya Serial: Add support for power metering

Capable Tuya serial devices send power metering data over serial interface. User needs to identify the ids of all power metering functions and set as
SetOption44 -> Voltage
SetOption45 -> Current
SetOption46 -> Power
This commit is contained in:
Shantur Rathore 2019-08-27 10:50:34 +01:00
parent 579f68cf2f
commit 231a1ba137
3 changed files with 46 additions and 3 deletions

View File

@ -232,7 +232,7 @@ enum ButtonStates { PRESSED, NOT_PRESSED };
enum Shortcuts { SC_CLEAR, SC_DEFAULT, SC_USER };
enum SettingsParmaIndex {P_HOLD_TIME, P_MAX_POWER_RETRY, P_TUYA_DIMMER_ID, P_MDNS_DELAYED_START, P_BOOT_LOOP_OFFSET, P_RGB_REMAP, P_IR_UNKNOW_THRESHOLD, // SetOption32 .. SetOption38
P_CSE7766_INVALID_POWER, P_HOLD_IGNORE, P_TUYA_RELAYS, P_OVER_TEMP, P_TUYA_DIMMER_MAX, // SetOption39 .. SetOption43
P_CSE7766_INVALID_POWER, P_HOLD_IGNORE, P_TUYA_RELAYS, P_OVER_TEMP, P_TUYA_DIMMER_MAX, P_TUYA_VOLTAGE_ID, P_TUYA_CURRENT_ID, P_TUYA_POWER_ID, // SetOption39 .. SetOption46
P_MAX_PARAM8}; // Max is PARAM8_SIZE (18) - SetOption32 until SetOption49
enum DomoticzSensors {DZ_TEMP, DZ_TEMP_HUM, DZ_TEMP_HUM_BARO, DZ_POWER_ENERGY, DZ_ILLUMINANCE, DZ_COUNT, DZ_VOLTAGE, DZ_CURRENT, DZ_AIRQUALITY, DZ_P1_SMART_METER, DZ_MAX_SENSORS};

View File

@ -654,6 +654,9 @@ void CmndSetoption(void)
#endif
#ifdef USE_TUYA_DIMMER
case P_TUYA_RELAYS:
case P_TUYA_POWER_ID:
case P_TUYA_CURRENT_ID:
case P_TUYA_VOLTAGE_ID:
case P_TUYA_DIMMER_MAX:
restart_flag = 2; // Need a restart to update GUI
break;

View File

@ -21,13 +21,12 @@
#ifdef USE_TUYA_DIMMER
#define XDRV_16 16
#define XNRG_08 8
#ifndef TUYA_DIMMER_ID
#define TUYA_DIMMER_ID 0
#endif
#define TUYA_POWER_ID 1
#define TUYA_CMD_HEARTBEAT 0x00
#define TUYA_CMD_QUERY_PRODUCT 0x01
#define TUYA_CMD_MCU_CONF 0x02
@ -55,6 +54,7 @@ struct TUYA {
uint8_t data_len = 0; // Data lenght of command
int8_t wifi_state = -2; // Keep MCU wifi-status in sync with WifiState()
uint8_t heartbeat_timer = 0; // 10 second heartbeat timer for tuya module
uint32_t lastPowerCheckTime = 0; // Time when last power was checked
char *buffer = nullptr; // Serial receive buffer
int byte_counter = 0; // Index in serial receive buffer
@ -228,6 +228,25 @@ void TuyaPacketProcess(void)
}
}
}
if (Settings.param[P_TUYA_VOLTAGE_ID] == Tuya.buffer[6]) {
Energy.voltage = (float)(Tuya.buffer[12] << 8 | Tuya.buffer[13]) / 10;
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Voltage=%d"), Settings.param[P_TUYA_VOLTAGE_ID], (Tuya.buffer[12] << 8 | Tuya.buffer[13]));
} else if (Settings.param[P_TUYA_CURRENT_ID] == Tuya.buffer[6]) {
Energy.current = (float)(Tuya.buffer[12] << 8 | Tuya.buffer[13]) / 1000;
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Current=%d"), Settings.param[P_TUYA_CURRENT_ID], (Tuya.buffer[12] << 8 | Tuya.buffer[13]));
} else if (Settings.param[P_TUYA_POWER_ID] == Tuya.buffer[6]) {
Energy.active_power = (float)(Tuya.buffer[12] << 8 | Tuya.buffer[13]) / 10;
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Active_Power=%d"), Settings.param[P_TUYA_POWER_ID], (Tuya.buffer[12] << 8 | Tuya.buffer[13]));
if (Tuya.lastPowerCheckTime != 0 && Energy.active_power > 0) {
Energy.kWhtoday += (float)Energy.active_power * (Rtc.utc_time - Tuya.lastPowerCheckTime) / 36;
EnergyUpdateToday();
}
Tuya.lastPowerCheckTime = Rtc.utc_time;
} else if (Settings.param[P_TUYA_DIMMER_ID] != Tuya.buffer[6]){
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Unknown ID=%d"), Tuya.buffer[6]);
}
}
break;
@ -440,5 +459,26 @@ bool Xdrv16(uint8_t function)
return result;
}
/*********************************************************************************************\
* Energy Interface
\*********************************************************************************************/
int Xnrg08(uint8_t function)
{
int result = 0;
if (FUNC_PRE_INIT == function) {
if (Settings.param[P_TUYA_POWER_ID] != 0) {
energy_flg = XNRG_08;
}
if (Settings.param[P_TUYA_CURRENT_ID] == 0) {
Energy.current_available = false;
}
if (Settings.param[P_TUYA_VOLTAGE_ID] == 0) {
Energy.voltage_available = false;
}
}
return result;
}
#endif // USE_TUYA_DIMMER
#endif // USE_LIGHT