Merge branch 'development' of github.com:arendst/Tasmota into pr_max7219

This commit is contained in:
Ajith Vasudevan 2021-03-19 19:20:18 +05:30
commit 4c9182f680
6 changed files with 257 additions and 134 deletions

5
eMyloEAI90.txt Normal file
View File

@ -0,0 +1,5 @@
Template TuyaMCU(54)
Console:
Backlog SetOption66 1; TuyaMCU 11,16; TuyaMCU 36,6; TuyaMCU 37,1; SetOption59 1; SetOption72 1
Rule1 on System#Boot do RuleTimer1 10 endon on Rules#Timer=1 do backlog TuyaSend8; RuleTimer1 10 endon

View File

@ -80,7 +80,7 @@ build_flags = ${core.build_flags}
board_build.f_cpu = 80000000L board_build.f_cpu = 80000000L
board_build.f_flash = 40000000L board_build.f_flash = 40000000L
monitor_speed = 74880 monitor_speed = 115200
monitor_port = COM5 monitor_port = COM5
upload_speed = 115200 upload_speed = 115200
; *** Upload Serial reset method for Wemos and NodeMCU ; *** Upload Serial reset method for Wemos and NodeMCU

View File

@ -424,7 +424,7 @@ enum TuyaSupportedFunctions { TUYA_MCU_FUNC_NONE,
TUYA_MCU_FUNC_REL6, TUYA_MCU_FUNC_REL7, TUYA_MCU_FUNC_REL8, TUYA_MCU_FUNC_REL6, TUYA_MCU_FUNC_REL7, TUYA_MCU_FUNC_REL8,
TUYA_MCU_FUNC_DIMMER = 21, TUYA_MCU_FUNC_DIMMER2, TUYA_MCU_FUNC_CT, TUYA_MCU_FUNC_RGB, TUYA_MCU_FUNC_WHITE, TUYA_MCU_FUNC_DIMMER = 21, TUYA_MCU_FUNC_DIMMER2, TUYA_MCU_FUNC_CT, TUYA_MCU_FUNC_RGB, TUYA_MCU_FUNC_WHITE,
TUYA_MCU_FUNC_MODESET, TUYA_MCU_FUNC_REPORT1, TUYA_MCU_FUNC_REPORT2, TUYA_MCU_FUNC_MODESET, TUYA_MCU_FUNC_REPORT1, TUYA_MCU_FUNC_REPORT2,
TUYA_MCU_FUNC_POWER = 31, TUYA_MCU_FUNC_CURRENT, TUYA_MCU_FUNC_VOLTAGE, TUYA_MCU_FUNC_BATTERY_STATE, TUYA_MCU_FUNC_BATTERY_PERCENTAGE, TUYA_MCU_FUNC_POWER = 31, TUYA_MCU_FUNC_CURRENT, TUYA_MCU_FUNC_VOLTAGE, TUYA_MCU_FUNC_BATTERY_STATE, TUYA_MCU_FUNC_BATTERY_PERCENTAGE, TUYA_MCU_FUNC_POWER_COMBINED, TUYA_MCU_FUNC_POWER_TOTAL,
TUYA_MCU_FUNC_REL1_INV = 41, TUYA_MCU_FUNC_REL2_INV, TUYA_MCU_FUNC_REL3_INV, TUYA_MCU_FUNC_REL4_INV, TUYA_MCU_FUNC_REL5_INV, TUYA_MCU_FUNC_REL1_INV = 41, TUYA_MCU_FUNC_REL2_INV, TUYA_MCU_FUNC_REL3_INV, TUYA_MCU_FUNC_REL4_INV, TUYA_MCU_FUNC_REL5_INV,
TUYA_MCU_FUNC_REL6_INV, TUYA_MCU_FUNC_REL7_INV, TUYA_MCU_FUNC_REL8_INV, TUYA_MCU_FUNC_REL6_INV, TUYA_MCU_FUNC_REL7_INV, TUYA_MCU_FUNC_REL8_INV,
TUYA_MCU_FUNC_LOWPOWER_MODE = 51, TUYA_MCU_FUNC_LOWPOWER_MODE = 51,

View File

@ -89,12 +89,12 @@ enum XdspFunctions { FUNC_DISPLAY_INIT_DRIVER, FUNC_DISPLAY_INIT, FUNC_DISPLAY_E
FUNC_DISPLAY_DRAW_CIRCLE, FUNC_DISPLAY_FILL_CIRCLE, FUNC_DISPLAY_DRAW_CIRCLE, FUNC_DISPLAY_FILL_CIRCLE,
FUNC_DISPLAY_DRAW_RECTANGLE, FUNC_DISPLAY_FILL_RECTANGLE, FUNC_DISPLAY_DRAW_RECTANGLE, FUNC_DISPLAY_FILL_RECTANGLE,
FUNC_DISPLAY_TEXT_SIZE, FUNC_DISPLAY_FONT_SIZE, FUNC_DISPLAY_ROTATION, FUNC_DISPLAY_DRAW_STRING, FUNC_DISPLAY_TEXT_SIZE, FUNC_DISPLAY_FONT_SIZE, FUNC_DISPLAY_ROTATION, FUNC_DISPLAY_DRAW_STRING,
FUNC_DISPLAY_DIM, FUNC_DISPLAY_BLINKRATE FUNC_DISPLAY_DIM, FUNC_DISPLAY_BLINKRATE,
#ifdef USE_UFILESYS #ifdef USE_UFILESYS
,FUNC_DISPLAY_BATCH FUNC_DISPLAY_BATCH,
#endif #endif
, FUNC_DISPLAY_NUMBER, FUNC_DISPLAY_FLOAT, FUNC_DISPLAY_NUMBERNC, FUNC_DISPLAY_FLOATNC, FUNC_DISPLAY_NUMBER, FUNC_DISPLAY_FLOAT, FUNC_DISPLAY_NUMBERNC, FUNC_DISPLAY_FLOATNC,
FUNC_DISPLAY_BRIGHTNESS, FUNC_DISPLAY_RAW, FUNC_DISPLAY_LEVEL, FUNC_DISPLAY_SEVENSEG_TEXT, FUNC_DISPLAY_SEVENSEG_TEXTNC, FUNC_DISPLAY_RAW, FUNC_DISPLAY_LEVEL, FUNC_DISPLAY_SEVENSEG_TEXT, FUNC_DISPLAY_SEVENSEG_TEXTNC,
FUNC_DISPLAY_SCROLLDELAY, FUNC_DISPLAY_CLOCK, FUNC_DISPLAY_SCROLLTEXT FUNC_DISPLAY_SCROLLDELAY, FUNC_DISPLAY_CLOCK, FUNC_DISPLAY_SCROLLTEXT
}; };
@ -103,25 +103,25 @@ enum DisplayInitModes { DISPLAY_INIT_MODE, DISPLAY_INIT_PARTIAL, DISPLAY_INIT_FU
const char kDisplayCommands[] PROGMEM = D_PRFX_DISPLAY "|" // Prefix const char kDisplayCommands[] PROGMEM = D_PRFX_DISPLAY "|" // Prefix
"|" D_CMND_DISP_MODEL "|" D_CMND_DISP_WIDTH "|" D_CMND_DISP_HEIGHT "|" D_CMND_DISP_MODE "|" D_CMND_DISP_REFRESH "|" "|" D_CMND_DISP_MODEL "|" D_CMND_DISP_WIDTH "|" D_CMND_DISP_HEIGHT "|" D_CMND_DISP_MODE "|" D_CMND_DISP_REFRESH "|"
D_CMND_DISP_DIMMER "|" D_CMND_DISP_COLS "|" D_CMND_DISP_ROWS "|" D_CMND_DISP_SIZE "|" D_CMND_DISP_FONT "|" D_CMND_DISP_DIMMER "|" D_CMND_DISP_COLS "|" D_CMND_DISP_ROWS "|" D_CMND_DISP_SIZE "|" D_CMND_DISP_FONT "|"
D_CMND_DISP_ROTATE "|" D_CMND_DISP_TEXT "|" D_CMND_DISP_ADDRESS "|" D_CMND_DISP_BLINKRATE D_CMND_DISP_ROTATE "|" D_CMND_DISP_TEXT "|" D_CMND_DISP_ADDRESS "|" D_CMND_DISP_BLINKRATE "|"
#ifdef USE_UFILESYS #ifdef USE_UFILESYS
"|" D_CMND_DISP_BATCH D_CMND_DISP_BATCH "|"
#endif #endif
"|" D_CMND_DISP_CLEAR "|" D_CMND_DISP_NUMBER "|" D_CMND_DISP_FLOAT "|" D_CMND_DISP_NUMBERNC "|" D_CMND_DISP_FLOATNC "|" D_CMND_DISP_CLEAR "|" D_CMND_DISP_NUMBER "|" D_CMND_DISP_FLOAT "|" D_CMND_DISP_NUMBERNC "|" D_CMND_DISP_FLOATNC "|"
D_CMND_DISP_BRIGHTNESS "|" D_CMND_DISP_RAW "|" D_CMND_DISP_LEVEL "|" D_CMND_DISP_SEVENSEG_TEXT "|" D_CMND_DISP_SEVENSEG_TEXTNC "|" D_CMND_DISP_RAW "|" D_CMND_DISP_LEVEL "|" D_CMND_DISP_SEVENSEG_TEXT "|" D_CMND_DISP_SEVENSEG_TEXTNC "|"
D_CMND_DISP_SCROLLDELAY "|" D_CMND_DISP_CLOCK "|" D_CMND_DISP_TEXTNC "|" D_CMND_DISP_SCROLLDELAY "|" D_CMND_DISP_CLOCK "|" D_CMND_DISP_TEXTNC "|"
D_CMND_DISP_SCROLLTEXT "|" D_CMND_DISP_ILIMODE "|" D_CMND_DISP_ILIINVERT D_CMND_DISP_SCROLLTEXT "|" D_CMND_DISP_ILIMODE "|" D_CMND_DISP_ILIINVERT
; ;
void (* const DisplayCommand[])(void) PROGMEM = { void (* const DisplayCommand[])(void) PROGMEM = {
&CmndDisplay, &CmndDisplayModel, &CmndDisplayWidth, &CmndDisplayHeight, &CmndDisplayMode, &CmndDisplayRefresh, &CmndDisplay, &CmndDisplayModel, &CmndDisplayWidth, &CmndDisplayHeight, &CmndDisplayMode, &CmndDisplayRefresh,
&CmndDisplayDimmer, &CmndDisplayColumns, &CmndDisplayRows, &CmndDisplaySize, &CmndDisplayFont, &CmndDisplayDimmer, &CmndDisplayColumns, &CmndDisplayRows, &CmndDisplaySize, &CmndDisplayFont,
&CmndDisplayRotate, &CmndDisplayText, &CmndDisplayAddress, &CmndDisplayBlinkrate &CmndDisplayRotate, &CmndDisplayText, &CmndDisplayAddress, &CmndDisplayBlinkrate,
#ifdef USE_UFILESYS #ifdef USE_UFILESYS
,&CmndDisplayBatch &CmndDisplayBatch,
#endif #endif
, &CmndDisplayClear, &CmndDisplayNumber, &CmndDisplayFloat, &CmndDisplayNumberNC, &CmndDisplayFloatNC, &CmndDisplayClear, &CmndDisplayNumber, &CmndDisplayFloat, &CmndDisplayNumberNC, &CmndDisplayFloatNC,
&CmndDisplayBrightness, &CmndDisplayRaw, &CmndDisplayLevel, &CmndDisplaySevensegText, &CmndDisplaySevensegTextNC, &CmndDisplayRaw, &CmndDisplayLevel, &CmndDisplaySevensegText, &CmndDisplaySevensegTextNC,
&CmndDisplayScrollDelay, &CmndDisplayClock, &CmndDisplayTextNC, &CmndDisplayScrollDelay, &CmndDisplayClock, &CmndDisplayTextNC,
&CmndDisplayScrollText, &CmndDisplayILIMOde , &CmndDisplayILIInvert &CmndDisplayScrollText, &CmndDisplayILIMOde , &CmndDisplayILIInvert
}; };
@ -1643,7 +1643,7 @@ void CmndDisplay(void)
D_CMND_DISP_MODE "\":%d,\"" D_CMND_DISP_DIMMER "\":%d,\"" D_CMND_DISP_SIZE "\":%d,\"" D_CMND_DISP_FONT "\":%d,\"" D_CMND_DISP_MODE "\":%d,\"" D_CMND_DISP_DIMMER "\":%d,\"" D_CMND_DISP_SIZE "\":%d,\"" D_CMND_DISP_FONT "\":%d,\""
D_CMND_DISP_ROTATE "\":%d,\"" D_CMND_DISP_REFRESH "\":%d,\"" D_CMND_DISP_COLS "\":[%d,%d],\"" D_CMND_DISP_ROWS "\":%d}}"), D_CMND_DISP_ROTATE "\":%d,\"" D_CMND_DISP_REFRESH "\":%d,\"" D_CMND_DISP_COLS "\":[%d,%d],\"" D_CMND_DISP_ROWS "\":%d}}"),
Settings.display_model, Settings.display_width, Settings.display_height, Settings.display_model, Settings.display_width, Settings.display_height,
Settings.display_mode, Settings.display_dimmer, Settings.display_size, Settings.display_font, Settings.display_mode, ((Settings.display_dimmer * 666) / 100) +1, Settings.display_size, Settings.display_font,
Settings.display_rotate, Settings.display_refresh, Settings.display_cols[0], Settings.display_cols[1], Settings.display_rows); Settings.display_rotate, Settings.display_refresh, Settings.display_cols[0], Settings.display_cols[1], Settings.display_rows);
} }
@ -1686,7 +1686,7 @@ void CmndDisplayHeight(void)
void CmndDisplayMode(void) void CmndDisplayMode(void)
{ {
#ifdef USE_DISPLAY_MODES1TO5 #ifdef USE_DISPLAY_MODES1TO5
/* Matrix LCD / Oled TFT /* Matrix / 7-segment LCD / Oled TFT
* 1 = Text up and time Time * 1 = Text up and time Time
* 2 = Date Local sensors Local sensors * 2 = Date Local sensors Local sensors
* 3 = Day Local sensors and time Local sensors and time * 3 = Day Local sensors and time Local sensors and time
@ -1714,8 +1714,7 @@ void CmndDisplayMode(void)
ResponseCmndNumber(Settings.display_mode); ResponseCmndNumber(Settings.display_mode);
} }
void CmndDisplayDimmer(void) void CmndDisplayDimmer(void) {
{
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) {
Settings.display_dimmer = ((XdrvMailbox.payload +1) * 100) / 666; // Correction for Domoticz (0 - 15) Settings.display_dimmer = ((XdrvMailbox.payload +1) * 100) / 666; // Correction for Domoticz (0 - 15)
if (Settings.display_dimmer && !(disp_power)) { if (Settings.display_dimmer && !(disp_power)) {
@ -1724,12 +1723,13 @@ void CmndDisplayDimmer(void)
else if (!Settings.display_dimmer && disp_power) { else if (!Settings.display_dimmer && disp_power) {
ExecuteCommandPower(disp_device, POWER_OFF, SRC_DISPLAY); ExecuteCommandPower(disp_device, POWER_OFF, SRC_DISPLAY);
} }
if (renderer) if (renderer) {
renderer->dim(Settings.display_dimmer); renderer->dim(Settings.display_dimmer);
else } else {
XdspCall(FUNC_DISPLAY_DIM); XdspCall(FUNC_DISPLAY_DIM);
}
} }
ResponseCmndNumber(Settings.display_dimmer); ResponseCmndNumber(((Settings.display_dimmer * 666) / 100) +1);
} }
void CmndDisplayBlinkrate(void) void CmndDisplayBlinkrate(void)
@ -1794,15 +1794,6 @@ void CmndDisplayFloatNC(void)
ResponseCmndChar(XdrvMailbox.data); ResponseCmndChar(XdrvMailbox.data);
} }
void CmndDisplayBrightness(void)
{
bool result = false;
if (!renderer) {
result = XdspCall(FUNC_DISPLAY_BRIGHTNESS);
}
if(result) ResponseCmndNumber(XdrvMailbox.payload);
}
void CmndDisplayRaw(void) void CmndDisplayRaw(void)
{ {
if (!renderer) { if (!renderer) {

View File

@ -386,7 +386,7 @@ inline bool TuyaFuncIdValid(uint8_t fnId) {
return (fnId >= TUYA_MCU_FUNC_SWT1 && fnId <= TUYA_MCU_FUNC_SWT4) || return (fnId >= TUYA_MCU_FUNC_SWT1 && fnId <= TUYA_MCU_FUNC_SWT4) ||
(fnId >= TUYA_MCU_FUNC_REL1 && fnId <= TUYA_MCU_FUNC_REL8) || (fnId >= TUYA_MCU_FUNC_REL1 && fnId <= TUYA_MCU_FUNC_REL8) ||
(fnId >= TUYA_MCU_FUNC_DIMMER && fnId <= TUYA_MCU_FUNC_REPORT2) || (fnId >= TUYA_MCU_FUNC_DIMMER && fnId <= TUYA_MCU_FUNC_REPORT2) ||
(fnId >= TUYA_MCU_FUNC_POWER && fnId <= TUYA_MCU_FUNC_BATTERY_PERCENTAGE) || (fnId >= TUYA_MCU_FUNC_POWER && fnId <= TUYA_MCU_FUNC_POWER_TOTAL) ||
(fnId >= TUYA_MCU_FUNC_REL1_INV && fnId <= TUYA_MCU_FUNC_REL8_INV) || (fnId >= TUYA_MCU_FUNC_REL1_INV && fnId <= TUYA_MCU_FUNC_REL8_INV) ||
(fnId >= TUYA_MCU_FUNC_ENUM1 && fnId <= TUYA_MCU_FUNC_ENUM4) || (fnId >= TUYA_MCU_FUNC_ENUM1 && fnId <= TUYA_MCU_FUNC_ENUM4) ||
(fnId >= TUYA_MCU_FUNC_MOTOR_DIR && fnId <= TUYA_MCU_FUNC_DUMMY) || (fnId >= TUYA_MCU_FUNC_MOTOR_DIR && fnId <= TUYA_MCU_FUNC_DUMMY) ||
@ -697,13 +697,41 @@ void TuyaProcessStatePacket(void) {
uint8_t fnId; uint8_t fnId;
uint16_t dpDataLen; uint16_t dpDataLen;
bool PowerOff = false; bool PowerOff = false;
bool tuya_energy_enabled = (XNRG_32 == TasmotaGlobal.energy_driver);
while (dpidStart + 4 < Tuya.byte_counter) { while (dpidStart + 4 < Tuya.byte_counter) {
dpDataLen = Tuya.buffer[dpidStart + 2] << 8 | Tuya.buffer[dpidStart + 3]; dpDataLen = Tuya.buffer[dpidStart + 2] << 8 | Tuya.buffer[dpidStart + 3];
fnId = TuyaGetFuncId(Tuya.buffer[dpidStart]); fnId = TuyaGetFuncId(Tuya.buffer[dpidStart]);
AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: fnId=%d is set for dpId=%d"), fnId, Tuya.buffer[dpidStart]); AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: fnId=%d is set for dpId=%d"), fnId, Tuya.buffer[dpidStart]);
if (Tuya.buffer[dpidStart + 1] == 1) { // Data Type 1 if (Tuya.buffer[dpidStart + 1] == 0) {
#ifdef USE_ENERGY_SENSOR
if (tuya_energy_enabled && fnId == TUYA_MCU_FUNC_POWER_COMBINED) {
if (dpDataLen == 8) {
uint16_t tmpVol = Tuya.buffer[dpidStart + 4] << 8 | Tuya.buffer[dpidStart + 5];
uint16_t tmpCur = Tuya.buffer[dpidStart + 7] << 8 | Tuya.buffer[dpidStart + 8];
uint16_t tmpPow = Tuya.buffer[dpidStart + 10] << 8 | Tuya.buffer[dpidStart + 11];
Energy.voltage[0] = (float)tmpVol / 10;
Energy.current[0] = (float)tmpCur / 1000;
Energy.active_power[0] = (float)tmpPow;
AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Voltage=%d"), Tuya.buffer[dpidStart], tmpVol);
AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Current=%d"), Tuya.buffer[dpidStart], tmpCur);
AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Active_Power=%d"), Tuya.buffer[dpidStart], tmpPow);
if (RtcTime.valid) {
if (Tuya.lastPowerCheckTime != 0 && Energy.active_power[0] > 0) {
Energy.kWhtoday += (float)Energy.active_power[0] * (Rtc.utc_time - Tuya.lastPowerCheckTime) / 36;
EnergyUpdateToday();
}
Tuya.lastPowerCheckTime = Rtc.utc_time;
}
} else {
AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d INV_LEN=%d"), Tuya.buffer[dpidStart], dpDataLen);
}
}
#endif // USE_ENERGY_SENSOR
}
else if (Tuya.buffer[dpidStart + 1] == 1) { // Data Type 1
if (fnId >= TUYA_MCU_FUNC_REL1 && fnId <= TUYA_MCU_FUNC_REL8) { if (fnId >= TUYA_MCU_FUNC_REL1 && fnId <= TUYA_MCU_FUNC_REL8) {
AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: RX Relay-%d --> MCU State: %s Current State:%s"), fnId - TUYA_MCU_FUNC_REL1 + 1, Tuya.buffer[dpidStart + 4]?"On":"Off",bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1)?"On":"Off"); AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: RX Relay-%d --> MCU State: %s Current State:%s"), fnId - TUYA_MCU_FUNC_REL1 + 1, Tuya.buffer[dpidStart + 4]?"On":"Off",bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1)?"On":"Off");
@ -728,7 +756,6 @@ void TuyaProcessStatePacket(void) {
if (PowerOff) { Tuya.ignore_dimmer_cmd_timeout = millis() + 250; } if (PowerOff) { Tuya.ignore_dimmer_cmd_timeout = millis() + 250; }
} }
else if (Tuya.buffer[dpidStart + 1] == 2) { // Data Type 2 else if (Tuya.buffer[dpidStart + 1] == 2) { // Data Type 2
bool tuya_energy_enabled = (XNRG_32 == TasmotaGlobal.energy_driver);
uint16_t packetValue = Tuya.buffer[dpidStart + 6] << 8 | Tuya.buffer[dpidStart + 7]; uint16_t packetValue = Tuya.buffer[dpidStart + 6] << 8 | Tuya.buffer[dpidStart + 7];
uint8_t dimIndex; uint8_t dimIndex;
bool SnsUpdate = false; bool SnsUpdate = false;
@ -824,6 +851,9 @@ void TuyaProcessStatePacket(void) {
} }
Tuya.lastPowerCheckTime = Rtc.utc_time; Tuya.lastPowerCheckTime = Rtc.utc_time;
} }
} else if (tuya_energy_enabled && fnId == TUYA_MCU_FUNC_POWER_TOTAL) {
EnergyUpdateTotal((float)packetValue / 100,true);
AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Total_Power=%d"), Tuya.buffer[dpidStart], packetValue);
} }
#endif // USE_ENERGY_SENSOR #endif // USE_ENERGY_SENSOR
} }
@ -862,6 +892,7 @@ void TuyaProcessStatePacket(void) {
ExecuteCommand(scmnd, SRC_SWITCH); ExecuteCommand(scmnd, SRC_SWITCH);
} }
} }
} }
else if (Tuya.buffer[dpidStart + 1] == 4) { // Data Type 4 else if (Tuya.buffer[dpidStart + 1] == 4) { // Data Type 4
const unsigned char *dpData = (unsigned char*)&Tuya.buffer[dpidStart + 4]; const unsigned char *dpData = (unsigned char*)&Tuya.buffer[dpidStart + 4];
@ -1273,11 +1304,11 @@ bool Xnrg32(uint8_t function)
if (TUYA_DIMMER == TasmotaGlobal.module_type) { if (TUYA_DIMMER == TasmotaGlobal.module_type) {
if (FUNC_PRE_INIT == function) { if (FUNC_PRE_INIT == function) {
if (TuyaGetDpId(TUYA_MCU_FUNC_POWER) != 0) { if (TuyaGetDpId(TUYA_MCU_FUNC_POWER) != 0 || TuyaGetDpId(TUYA_MCU_FUNC_POWER_COMBINED) != 0) {
if (TuyaGetDpId(TUYA_MCU_FUNC_CURRENT) == 0) { if (TuyaGetDpId(TUYA_MCU_FUNC_CURRENT) == 0 && TuyaGetDpId(TUYA_MCU_FUNC_POWER_COMBINED) == 0) {
Energy.current_available = false; Energy.current_available = false;
} }
if (TuyaGetDpId(TUYA_MCU_FUNC_VOLTAGE) == 0) { if (TuyaGetDpId(TUYA_MCU_FUNC_VOLTAGE) == 0 && TuyaGetDpId(TUYA_MCU_FUNC_POWER_COMBINED) == 0) {
Energy.voltage_available = false; Energy.voltage_available = false;
} }
TasmotaGlobal.energy_driver = XNRG_32; TasmotaGlobal.energy_driver = XNRG_32;

View File

@ -60,57 +60,51 @@
Clears the display, command: "DisplayClear" Clears the display, command: "DisplayClear"
DisplayNumber num [,position {0-(TM1637Data.num_digits-1))} [,leading_zeros {0|1} [,length {1 to TM1637Data.num_digits}]]] DisplayNumber num [,position {0-(Settings.display_width-1))} [,leading_zeros {0|1} [,length {1 to Settings.display_width}]]]
Clears and then displays number without decimal. command e.g., "DisplayNumber 1234" Clears and then displays number without decimal. command e.g., "DisplayNumber 1234"
Control 'leading zeros', 'length' and 'position' with "DisplayNumber 1234, <position>, <leadingZeros>, <length>" Control 'leading zeros', 'length' and 'position' with "DisplayNumber 1234, <position>, <leadingZeros>, <length>"
'leading zeros' can be 1 or 0 (default), 'length' can be 1 to TM1637Data.num_digits, 'position' can be 0 (left-most) to TM1637Data.num_digits (right-most). 'leading zeros' can be 1 or 0 (default), 'length' can be 1 to Settings.display_width, 'position' can be 0 (left-most) to Settings.display_width (right-most).
See function description below for more details. See function description below for more details.
DisplayNumberNC num [,position {0-(TM1637Data.num_digits-1))} [,leading_zeros {0|1} [,length {1 to TM1637Data.num_digits}]]] DisplayNumberNC num [,position {0-(Settings.display_width-1))} [,leading_zeros {0|1} [,length {1 to Settings.display_width}]]]
Display integer number as above, but without clearing first. e.g., "DisplayNumberNC 1234". Usage is same as above. Display integer number as above, but without clearing first. e.g., "DisplayNumberNC 1234". Usage is same as above.
DisplayFloat num [,position {0-(TM1637Data.num_digits-1)} [,precision {0-TM1637Data.num_digits} [,length {1 to TM1637Data.num_digits}]]] DisplayFloat num [,position {0-(Settings.display_width-1)} [,precision {0-Settings.display_width} [,length {1 to Settings.display_width}]]]
Clears and then displays float (with decimal point) command e.g., "DisplayFloat 12.34" Clears and then displays float (with decimal point) command e.g., "DisplayFloat 12.34"
See function description below for more details. See function description below for more details.
DisplayFloatNC num [,position {0-(TM1637Data.num_digits-1)} [,precision {0-TM1637Data.num_digits} [,length {1 to TM1637Data.num_digits}]]] DisplayFloatNC num [,position {0-(Settings.display_width-1)} [,precision {0-Settings.display_width} [,length {1 to Settings.display_width}]]]
Displays float (with decimal point) as above, but without clearing first. command e.g., "DisplayFloatNC 12.34" Displays float (with decimal point) as above, but without clearing first. command e.g., "DisplayFloatNC 12.34"
See function description below for more details. See function description below for more details.
DisplayBrightness num {1-8} DisplayRaw position {0-(Settings.display_width-1)},length {1 to Settings.display_width}, num1 [, num2[, num3[, num4[, ...upto Settings.display_width numbers]]]]]
Set brightness (1 to 8) command e.g., "DisplayBrightness 2" Takes upto Settings.display_width comma-separated integers (0-255) and displays raw segments. Each number represents a
DisplayRaw position {0-(TM1637Data.num_digits-1)},length {1 to TM1637Data.num_digits}, num1 [, num2[, num3[, num4[, ...upto TM1637Data.num_digits numbers]]]]]
Takes upto TM1637Data.num_digits comma-separated integers (0-255) and displays raw segments. Each number represents a
7-segment digit. Each 8-bit number represents individual segments of a digit. 7-segment digit. Each 8-bit number represents individual segments of a digit.
For example, the command "DisplayRaw 0, 4, 255, 255, 255, 255" would display "[8.8.8.8.]" For example, the command "DisplayRaw 0, 4, 255, 255, 255, 255" would display "[8.8.8.8.]"
DisplayText text [, position {0-(TM1637Data.num_digits-1)} [,length {1 to TM1637Data.num_digits}]] DisplayText text [, position {0-(Settings.display_width-1)} [,length {1 to Settings.display_width}]]
Clears and then displays basic text. command e.g., "DisplayText ajith vasudevan" Clears and then displays basic text. command e.g., "DisplayText ajith vasudevan"
Control 'length' and 'position' with "DisplayText <text>, <position>, <length>" Control 'length' and 'position' with "DisplayText <text>, <position>, <length>"
'length' can be 1 to TM1637Data.num_digits, 'position' can be 0 (left-most) to TM1637Data.num_digits-1 (right-most) 'length' can be 1 to Settings.display_width, 'position' can be 0 (left-most) to Settings.display_width-1 (right-most)
A caret(^) symbol in the text input is dispayed as the degrees(°) symbol. This is useful for displaying Temperature! A caret(^) symbol in the text input is dispayed as the degrees(°) symbol. This is useful for displaying Temperature!
For example, the command "DisplayText 22.5^" will display "22.5°". For example, the command "DisplayText 22.5^" will display "22.5°".
DisplayTextNC text [, position {0-TM1637Data.num_digits-1} [,length {1 to TM1637Data.num_digits}]] DisplayTextNC text [, position {0-Settings.display_width-1} [,length {1 to Settings.display_width}]]
Clears first, then displays text. Usage is same as above. Clears first, then displays text. Usage is same as above.
@ -148,8 +142,6 @@
#define XDSP_15 15 #define XDSP_15 15
#define BRIGHTNESS_MIN 1
#define BRIGHTNESS_MAX 8
#define CMD_MAX_LEN 55 #define CMD_MAX_LEN 55
#define LEVEL_MIN 0 #define LEVEL_MIN 0
#define LEVEL_MAX 100 #define LEVEL_MAX 100
@ -171,11 +163,9 @@ struct {
char scroll_text[CMD_MAX_LEN]; char scroll_text[CMD_MAX_LEN];
char msg[60]; char msg[60];
char model_name[8]; char model_name[8];
uint8_t num_digits = 4;
uint8_t scroll_delay = 4; uint8_t scroll_delay = 4;
uint8_t scroll_index = 0; uint8_t scroll_index = 0;
uint8_t iteration = 0; uint8_t iteration = 0;
uint8_t brightness = 5;
uint8_t buttons; uint8_t buttons;
uint8_t display_type = TM1637; uint8_t display_type = TM1637;
uint8_t prev_buttons; uint8_t prev_buttons;
@ -194,14 +184,12 @@ struct {
void TM1637Init(void) { void TM1637Init(void) {
if (PinUsed(GPIO_TM1638CLK) && PinUsed(GPIO_TM1638DIO) && PinUsed(GPIO_TM1638STB)) { if (PinUsed(GPIO_TM1638CLK) && PinUsed(GPIO_TM1638DIO) && PinUsed(GPIO_TM1638STB)) {
TM1637Data.display_type = TM1638; TM1637Data.display_type = TM1638;
TM1637Data.num_digits = 8; Settings.display_width = 8;
} }
else if (PinUsed(GPIO_TM1637CLK) && PinUsed(GPIO_TM1637DIO)) { else if (PinUsed(GPIO_TM1637CLK) && PinUsed(GPIO_TM1637DIO)) {
TM1637Data.display_type = TM1637; TM1637Data.display_type = TM1637;
if (Settings.display_cols[0] <= 6) { if ((!Settings.display_width || Settings.display_width > 6)) {
TM1637Data.num_digits = Settings.display_cols[0]; Settings.display_width = 4;
} else {
TM1637Data.num_digits = 4;
} }
} }
else { else {
@ -209,30 +197,31 @@ void TM1637Init(void) {
} }
Settings.display_model = XDSP_15; Settings.display_model = XDSP_15;
Settings.display_cols[0] = Settings.display_width;
Settings.display_height = 1;
Settings.display_rows = Settings.display_height;
if (TM1637 == TM1637Data.display_type) { if (TM1637 == TM1637Data.display_type) {
strcpy_P(TM1637Data.model_name, PSTR("TM1637")); strcpy_P(TM1637Data.model_name, PSTR("TM1637"));
tm1637display = new SevenSegmentTM1637(Pin(GPIO_TM1637CLK), Pin(GPIO_TM1637DIO)); tm1637display = new SevenSegmentTM1637(Pin(GPIO_TM1637CLK), Pin(GPIO_TM1637DIO));
tm1637display->begin(TM1637Data.num_digits, 1); tm1637display->begin(Settings.display_width, 1);
} }
else if (TM1638 == TM1637Data.display_type) { else if (TM1638 == TM1637Data.display_type) {
strcpy_P(TM1637Data.model_name, PSTR("TM1638")); strcpy_P(TM1637Data.model_name, PSTR("TM1638"));
tm1638display = new TM1638plus(Pin(GPIO_TM1638STB), Pin(GPIO_TM1638CLK), Pin(GPIO_TM1638DIO), true ); tm1638display = new TM1638plus(Pin(GPIO_TM1638STB), Pin(GPIO_TM1638CLK), Pin(GPIO_TM1638DIO), true );
TM1637Data.num_digits = 8;
tm1638display->displayBegin(); tm1638display->displayBegin();
} }
TM1637ClearDisplay(); TM1637ClearDisplay();
TM1637Data.brightness = (Settings.display_dimmer ? Settings.display_dimmer : TM1637Data.brightness); TM1637Dim();
TM1637SetBrightness(TM1637Data.brightness);
TM1637Data.init_done = true; TM1637Data.init_done = true;
AddLog(LOG_LEVEL_INFO, PSTR("DSP: %s with %d digits"), TM1637Data.model_name, TM1637Data.num_digits); AddLog(LOG_LEVEL_INFO, PSTR("DSP: %s with %d digits"), TM1637Data.model_name, Settings.display_width);
} }
/*********************************************************************************************\ /*********************************************************************************************\
* Displays number without decimal, with/without leading zeros, specifying start-position * Displays number without decimal, with/without leading zeros, specifying start-position
* and length, optionally skipping clearing display before displaying the number. * and length, optionally skipping clearing display before displaying the number.
* commands: DisplayNumber num [,position {0-(TM1637Data.num_digits-1)} [,leading_zeros {0|1} [,length {1 to TM1637Data.num_digits}]]] * commands: DisplayNumber num [,position {0-(Settings.display_width-1)} [,leading_zeros {0|1} [,length {1 to Settings.display_width}]]]
* DisplayNumberNC num [,position {0-(TM1637Data.num_digits-1)} [,leading_zeros {0|1} [,length {1 to TM1637Data.num_digits}]]] // "NC" --> "No Clear" * DisplayNumberNC num [,position {0-(Settings.display_width-1)} [,leading_zeros {0|1} [,length {1 to Settings.display_width}]]] // "NC" --> "No Clear"
\*********************************************************************************************/ \*********************************************************************************************/
bool CmndTM1637Number(bool clear) { bool CmndTM1637Number(bool clear) {
char sNum[CMD_MAX_LEN]; char sNum[CMD_MAX_LEN];
@ -262,7 +251,7 @@ bool CmndTM1637Number(bool clear) {
} }
if((position < 0) || (position > (TM1637Data.num_digits-1))) position = 0; if((position < 0) || (position > (Settings.display_width-1))) position = 0;
AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: num %d, pos %d, lead %d, len %d"), num, position, leadingzeros, length); AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: num %d, pos %d, lead %d, len %d"), num, position, leadingzeros, length);
@ -271,20 +260,20 @@ bool CmndTM1637Number(bool clear) {
char txt[30]; char txt[30];
snprintf_P(txt, sizeof(txt), PSTR("%d"), num); snprintf_P(txt, sizeof(txt), PSTR("%d"), num);
if(!length) length = strlen(txt); if(!length) length = strlen(txt);
if((length < 0) || (length > TM1637Data.num_digits)) length = TM1637Data.num_digits; if((length < 0) || (length > Settings.display_width)) length = Settings.display_width;
char pad = (leadingzeros ? '0': ' '); char pad = (leadingzeros ? '0': ' ');
uint32_t i = position; uint32_t i = position;
uint8_t rawBytes[1]; uint8_t rawBytes[1];
for(; i<position + (length - strlen(txt)); i++) { for(; i<position + (length - strlen(txt)); i++) {
if(i>TM1637Data.num_digits) break; if(i>Settings.display_width) break;
if(TM1637Data.display_type == TM1637) { rawBytes[0] = tm1637display->encode(pad); tm1637display->printRaw(rawBytes, 1, i); } if(TM1637Data.display_type == TM1637) { rawBytes[0] = tm1637display->encode(pad); tm1637display->printRaw(rawBytes, 1, i); }
else if(TM1637Data.display_type == TM1638) tm1638display->displayASCII(i, pad); else if(TM1637Data.display_type == TM1638) tm1638display->displayASCII(i, pad);
} }
for(uint32_t j = 0; i< position + length; i++, j++) { for(uint32_t j = 0; i< position + length; i++, j++) {
if(i>TM1637Data.num_digits) break; if(i>Settings.display_width) break;
if(txt[j] == 0) break; if(txt[j] == 0) break;
if(TM1637Data.display_type == TM1637) { rawBytes[0] = tm1637display->encode(txt[j]); tm1637display->printRaw(rawBytes, 1, i); } if(TM1637Data.display_type == TM1637) { rawBytes[0] = tm1637display->encode(txt[j]); tm1637display->printRaw(rawBytes, 1, i); }
else if(TM1637Data.display_type == TM1638) tm1638display->displayASCII(i, txt[j]); else if(TM1637Data.display_type == TM1638) tm1638display->displayASCII(i, txt[j]);
@ -296,8 +285,8 @@ bool CmndTM1637Number(bool clear) {
/*********************************************************************************************\ /*********************************************************************************************\
* Displays number with decimal, specifying position, precision and length, * Displays number with decimal, specifying position, precision and length,
* optionally skipping clearing display before displaying the number. * optionally skipping clearing display before displaying the number.
* commands: DisplayFloat num [,position {0-(TM1637Data.num_digits-1)} [,precision {0-TM1637Data.num_digits} [,length {1 to TM1637Data.num_digits}]]] * commands: DisplayFloat num [,position {0-(Settings.display_width-1)} [,precision {0-Settings.display_width} [,length {1 to Settings.display_width}]]]
* DisplayFloatNC num [,position {0-(TM1637Data.num_digits-1)} [,precision {0-TM1637Data.num_digits} [,length {1 to TM1637Data.num_digits}]]] // "NC" --> "No Clear" * DisplayFloatNC num [,position {0-(Settings.display_width-1)} [,precision {0-Settings.display_width} [,length {1 to Settings.display_width}]]] // "NC" --> "No Clear"
\*********************************************************************************************/ \*********************************************************************************************/
bool CmndTM1637Float(bool clear) { bool CmndTM1637Float(bool clear) {
@ -306,7 +295,7 @@ bool CmndTM1637Float(bool clear) {
char sPosition[CMD_MAX_LEN]; char sPosition[CMD_MAX_LEN];
char sLength[CMD_MAX_LEN]; char sLength[CMD_MAX_LEN];
uint8_t length = 0; uint8_t length = 0;
uint8_t precision = TM1637Data.num_digits; uint8_t precision = Settings.display_width;
uint8_t position = 0; uint8_t position = 0;
float fnum = 0.0f; float fnum = 0.0f;
@ -328,8 +317,8 @@ bool CmndTM1637Float(bool clear) {
} }
if((position < 0) || (position > (TM1637Data.num_digits-1))) position = 0; if((position < 0) || (position > (Settings.display_width-1))) position = 0;
if((precision < 0) || (precision > TM1637Data.num_digits)) precision = TM1637Data.num_digits; if((precision < 0) || (precision > Settings.display_width)) precision = Settings.display_width;
if(clear) TM1637ClearDisplay(); if(clear) TM1637ClearDisplay();
@ -337,7 +326,7 @@ bool CmndTM1637Float(bool clear) {
ext_snprintf_P(txt, sizeof(txt), PSTR("%*_f"), precision, &fnum); ext_snprintf_P(txt, sizeof(txt), PSTR("%*_f"), precision, &fnum);
if(!length) length = strlen(txt); if(!length) length = strlen(txt);
if((length <= 0) || (length > TM1637Data.num_digits)) length = TM1637Data.num_digits; if((length <= 0) || (length > Settings.display_width)) length = Settings.display_width;
AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: num %4_f, prec %d, len %d"), &fnum, precision, length); AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: num %4_f, prec %d, len %d"), &fnum, precision, length);
@ -351,7 +340,7 @@ bool CmndTM1637Float(bool clear) {
i++; i++;
length++; length++;
} }
if((j+position) > TM1637Data.num_digits) break; if((j+position) > Settings.display_width) break;
tm1637display->printRaw(rawBytes, 1, j+position); tm1637display->printRaw(rawBytes, 1, j+position);
} }
} else if(TM1637Data.display_type == TM1638) { } else if(TM1637Data.display_type == TM1638) {
@ -389,9 +378,9 @@ bool CmndTM1637Clear(void) {
void TM1637ClearDisplay (void) { void TM1637ClearDisplay (void) {
if(TM1637Data.display_type == TM1637) { if(TM1637Data.display_type == TM1637) {
unsigned char arr[] = {0}; unsigned char arr[] = {0};
for(int i=0; i<TM1637Data.num_digits; i++) tm1637display->printRaw(arr, 1, i); for(int i=0; i<Settings.display_width; i++) tm1637display->printRaw(arr, 1, i);
} else if(TM1637Data.display_type == TM1638) { } else if(TM1637Data.display_type == TM1638) {
for(int i=0; i<TM1637Data.num_digits; i++) tm1638display->display7Seg(i, 0); for(int i=0; i<Settings.display_width; i++) tm1638display->display7Seg(i, 0);
} }
} }
@ -453,7 +442,7 @@ void TM1637ScrollText(void) {
} }
uint8_t rawBytes[1]; uint8_t rawBytes[1];
for(uint32_t i=0, j=TM1637Data.scroll_index; i< 1 + strlen(TM1637Data.scroll_text); i++, j++) { for(uint32_t i=0, j=TM1637Data.scroll_index; i< 1 + strlen(TM1637Data.scroll_text); i++, j++) {
if(i > (TM1637Data.num_digits-1)) { break; } if(i > (Settings.display_width-1)) { break; }
rawBytes[0] = tm1637display->encode(TM1637Data.scroll_text[j]); rawBytes[0] = tm1637display->encode(TM1637Data.scroll_text[j]);
bool dotSkipped = false; bool dotSkipped = false;
if(TM1637Data.scroll_text[j+1] == '.') { if(TM1637Data.scroll_text[j+1] == '.') {
@ -490,7 +479,7 @@ bool CmndTM1637Level(void) {
return false; return false;
} }
uint8_t totalBars = 2*TM1637Data.num_digits; uint8_t totalBars = 2*Settings.display_width;
AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: TM1637Data.model_name %s CmndTM1637Level totalBars=%d"), TM1637Data.model_name, totalBars); AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: TM1637Data.model_name %s CmndTM1637Level totalBars=%d"), TM1637Data.model_name, totalBars);
float barsToDisplay = totalBars * val / 100.0f; float barsToDisplay = totalBars * val / 100.0f;
char txt[5]; char txt[5];
@ -519,8 +508,8 @@ bool CmndTM1637Level(void) {
/*********************************************************************************************\ /*********************************************************************************************\
* Display arbitrary data on the display module * Display arbitrary data on the display module
* Command: DisplayRaw position {0-(TM1637Data.num_digits-1)},length {1 to TM1637Data.num_digits}, a [, b[, c[, d[...upto TM1637Data.num_digits]]]] * Command: DisplayRaw position {0-(Settings.display_width-1)},length {1 to Settings.display_width}, a [, b[, c[, d[...upto Settings.display_width]]]]
* where a,b,c,d... are upto TM1637Data.num_digits numbers in the range 0-255, each number (byte) * where a,b,c,d... are upto Settings.display_width numbers in the range 0-255, each number (byte)
* corresponding to a single 7-segment digit. Within each byte, bit 0 is segment A, * corresponding to a single 7-segment digit. Within each byte, bit 0 is segment A,
* bit 1 is segment B etc. The function may either set the entire display * bit 1 is segment B etc. The function may either set the entire display
* or any desired part using the length and position parameters. * or any desired part using the length and position parameters.
@ -571,8 +560,8 @@ bool CmndTM1637Raw(void) {
} }
if(!length) length = ArgC() - 2; if(!length) length = ArgC() - 2;
if(length < 0 || length > TM1637Data.num_digits) length = TM1637Data.num_digits; if(length < 0 || length > Settings.display_width) length = Settings.display_width;
if(position < 0 || position > (TM1637Data.num_digits-1)) position = 0; if(position < 0 || position > (Settings.display_width-1)) position = 0;
AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: a %d, b %d, c %d, d %d, e %d, f %d, len %d, pos %d"), AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: a %d, b %d, c %d, d %d, e %d, f %d, len %d, pos %d"),
DATA[0], DATA[1], DATA[2], DATA[3], DATA[4], DATA[5], length, position); DATA[0], DATA[1], DATA[2], DATA[3], DATA[4], DATA[5], length, position);
@ -580,7 +569,7 @@ bool CmndTM1637Raw(void) {
if(TM1637Data.display_type == TM1637) { if(TM1637Data.display_type == TM1637) {
uint8_t rawBytes[1]; uint8_t rawBytes[1];
for(uint32_t i=position; i<position+length; i++ ) { for(uint32_t i=position; i<position+length; i++ ) {
if(i>(TM1637Data.num_digits-1)) break; if(i>(Settings.display_width-1)) break;
rawBytes[0] = DATA[i-position]; rawBytes[0] = DATA[i-position];
tm1637display->printRaw(rawBytes, 1, i); tm1637display->printRaw(rawBytes, 1, i);
} }
@ -599,7 +588,7 @@ bool CmndTM1637Raw(void) {
* Display a given string. * Display a given string.
* Text can be placed at arbitrary location on the display using the length and * Text can be placed at arbitrary location on the display using the length and
* position parameters without affecting the rest of the display. * position parameters without affecting the rest of the display.
* Command: DisplayText text [, position {0-(TM1637Data.num_digits-1)} [,length {1 to TM1637Data.num_digits}]] * Command: DisplayText text [, position {0-(Settings.display_width-1)} [,length {1 to Settings.display_width}]]
\*********************************************************************************************/ \*********************************************************************************************/
bool CmndTM1637Text(bool clear) { bool CmndTM1637Text(bool clear) {
char sString[CMD_MAX_LEN + 1]; char sString[CMD_MAX_LEN + 1];
@ -621,20 +610,20 @@ bool CmndTM1637Text(bool clear) {
} }
if((position < 0) || (position > (TM1637Data.num_digits-1))) position = 0; if((position < 0) || (position > (Settings.display_width-1))) position = 0;
AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: sString %s, pos %d, len %d"), sString, position, length); AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: sString %s, pos %d, len %d"), sString, position, length);
if(clear) TM1637ClearDisplay(); if(clear) TM1637ClearDisplay();
if(!length) length = strlen(sString); if(!length) length = strlen(sString);
if((length < 0) || (length > TM1637Data.num_digits)) length = TM1637Data.num_digits; if((length < 0) || (length > Settings.display_width)) length = Settings.display_width;
uint32_t i = position; uint32_t i = position;
if(TM1637Data.display_type == TM1637) { if(TM1637Data.display_type == TM1637) {
uint8_t rawBytes[1]; uint8_t rawBytes[1];
for(uint32_t j = 0; i< position + length; i++, j++) { for(uint32_t j = 0; i< position + length; i++, j++) {
if(i > (TM1637Data.num_digits-1)) break; if(i > (Settings.display_width-1)) break;
if(sString[j] == 0) break; if(sString[j] == 0) break;
rawBytes[0] = tm1637display->encode(sString[j]); rawBytes[0] = tm1637display->encode(sString[j]);
bool dotSkipped = false; bool dotSkipped = false;
@ -665,40 +654,6 @@ bool CmndTM1637Text(bool clear) {
} }
/*********************************************************************************************\
* Sets brightness of the display.
* Command: DisplayBrightness {1-8}
\*********************************************************************************************/
bool CmndTM1637Brightness(void) {
uint16_t val = XdrvMailbox.payload;
if(ArgC() == 0) {
XdrvMailbox.payload = TM1637Data.brightness;
return true;
}
if((val < BRIGHTNESS_MIN) || (val > BRIGHTNESS_MAX)) {
Response_P(PSTR("{\"Error\":\"Brightness should be a number in the range [%d, %d]\"}"), BRIGHTNESS_MIN, BRIGHTNESS_MAX);
return false;
}
TM1637Data.brightness = val;
TM1637SetBrightness(TM1637Data.brightness);
return true;
}
void TM1637SetBrightness(uint8_t val) {
if((val < BRIGHTNESS_MIN) || (val > BRIGHTNESS_MAX)) val = 5;
Settings.display_dimmer = val;
if(TM1637Data.display_type == TM1637) tm1637display->setBacklight(val*10);
else if(TM1637Data.display_type == TM1638) tm1638display->brightness(val-1);
}
/*********************************************************************************************\ /*********************************************************************************************\
* Displays a clock. * Displays a clock.
* Command: DisplayClock 1 // 12-hour format * Command: DisplayClock 1 // 12-hour format
@ -788,9 +743,6 @@ bool TM1637MainFunc(uint8_t fn) {
case FUNC_DISPLAY_FLOATNC : case FUNC_DISPLAY_FLOATNC :
result = CmndTM1637Float(false); result = CmndTM1637Float(false);
break; break;
case FUNC_DISPLAY_BRIGHTNESS:
result = CmndTM1637Brightness();
break;
case FUNC_DISPLAY_RAW: case FUNC_DISPLAY_RAW:
result = CmndTM1637Raw(); result = CmndTM1637Raw();
break; break;
@ -817,10 +769,147 @@ bool TM1637MainFunc(uint8_t fn) {
return result; return result;
} }
void TM1637Dim(void) {
// Settings.display_dimmer = 0 - 15
uint8_t brightness = Settings.display_dimmer >> 1; // 0 - 7
if (TM1637 == TM1637Data.display_type) {
tm1637display->setBacklight(brightness * 12); // 0 - 84
}
else if (TM1637Data.display_type == TM1638) {
tm1638display->brightness(brightness); // 0 - 7
}
}
/*********************************************************************************************/
#ifdef USE_DISPLAY_MODES1TO5
void TM1637Print(char* txt) {
for (uint32_t i = 0; i < Settings.display_cols[0]; i++) {
if (TM1637 == TM1637Data.display_type) {
uint8_t rawBytes[1];
rawBytes[0] = tm1637display->encode(txt[i]);
// if ((millis() % 1000) > 500 && (i == 1)) { rawBytes[0] = rawBytes[0] | 128; }
tm1637display->printRaw(rawBytes, 1, i);
}
else if (TM1638 == TM1637Data.display_type) {
// if ((millis() % 1000) > 500 && (i == 1)) { tm1638display->displayASCIIwDot(i, txt[i]); }
tm1638display->displayASCII(i, txt[i]);
}
}
}
void TM1637Center(char* txt) {
char line[Settings.display_cols[0] +2];
int len = strlen(txt);
int offset = 0;
if (len >= Settings.display_cols[0]) {
len = Settings.display_cols[0];
} else {
offset = (Settings.display_cols[0] - len) / 2;
}
memset(line, 0x20, Settings.display_cols[0]);
line[Settings.display_cols[0]] = 0;
for (uint32_t i = 0; i < len; i++) {
line[offset +i] = txt[i];
}
TM1637Print(line);
}
/*
bool TM1637PrintLog(void) {
bool result = false;
disp_refresh--;
if (!disp_refresh) {
disp_refresh = Settings.display_refresh;
if (!disp_screen_buffer_cols) { DisplayAllocScreenBuffer(); }
char* txt = DisplayLogBuffer('\337');
if (txt != nullptr) {
uint8_t last_row = Settings.display_rows -1;
strlcpy(disp_screen_buffer[last_row], txt, disp_screen_buffer_cols);
DisplayFillScreen(last_row);
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "[%s]"), disp_screen_buffer[last_row]);
TM1637Print(disp_screen_buffer[last_row]);
result = true;
}
}
return result;
}
*/
void TM1637Time(void) {
char line[Settings.display_cols[0] +1];
if (Settings.display_cols[0] >= 8) {
snprintf_P(line, sizeof(line), PSTR("%02d %02d %02d"), RtcTime.hour, RtcTime.minute, RtcTime.second);
}
else if (Settings.display_cols[0] >= 6) {
snprintf_P(line, sizeof(line), PSTR("%02d%02d%02d"), RtcTime.hour, RtcTime.minute, RtcTime.second);
}
else {
snprintf_P(line, sizeof(line), PSTR("%02d%02d"), RtcTime.hour, RtcTime.minute);
}
TM1637Center(line);
}
void TM1637Date(void) {
char line[Settings.display_cols[0] +1];
if (Settings.display_cols[0] >= 8) {
snprintf_P(line, sizeof(line), PSTR("%02d-%02d-%02d"), RtcTime.day_of_month, RtcTime.month, RtcTime.year -2000);
}
else if (Settings.display_cols[0] >= 6) {
snprintf_P(line, sizeof(line), PSTR("%02d%02d%02d"), RtcTime.day_of_month, RtcTime.month, RtcTime.year -2000);
}
else {
snprintf_P(line, sizeof(line), PSTR("%02d%02d"), RtcTime.day_of_month, RtcTime.month);
}
TM1637Center(line);
}
void TM1637Refresh(void) { // Every second
if (!disp_power || !Settings.display_mode) { return; } // Mode 0 is User text
switch (Settings.display_mode) {
case 1: // Time
TM1637Time();
break;
case 2: // Date
TM1637Date();
break;
case 3: // Time
if (TasmotaGlobal.uptime % Settings.display_refresh) {
TM1637Time();
} else {
TM1637Date();
}
break;
/*
case 4: // Mqtt
TM1637PrintLog();
break;
case 5: { // Mqtt
if (!TM1637PrintLog()) { TM1637Time(); }
break;
}
*/
}
}
#endif // USE_DISPLAY_MODES1TO5
/*********************************************************************************************\ /*********************************************************************************************\
* Interface * Interface
\*********************************************************************************************/ \*********************************************************************************************/
bool Xdsp15(uint8_t function) { bool Xdsp15(uint8_t function) {
bool result = false; bool result = false;
@ -830,11 +919,16 @@ bool Xdsp15(uint8_t function) {
else if (TM1637Data.init_done && (XDSP_15 == Settings.display_model)) { else if (TM1637Data.init_done && (XDSP_15 == Settings.display_model)) {
switch (function) { switch (function) {
case FUNC_DISPLAY_EVERY_50_MSECOND: case FUNC_DISPLAY_EVERY_50_MSECOND:
if (disp_power) { if (disp_power && !Settings.display_mode) {
if (TM1637Data.scroll) { TM1637ScrollText(); } if (TM1637Data.scroll) { TM1637ScrollText(); }
if (TM1637Data.show_clock) { TM1637ShowTime(); } if (TM1637Data.show_clock) { TM1637ShowTime(); }
} }
break; break;
#ifdef USE_DISPLAY_MODES1TO5
case FUNC_DISPLAY_EVERY_SECOND:
TM1637Refresh();
break;
#endif // USE_DISPLAY_MODES1TO5
case FUNC_DISPLAY_MODEL: case FUNC_DISPLAY_MODEL:
result = true; result = true;
break; break;
@ -850,12 +944,14 @@ bool Xdsp15(uint8_t function) {
case FUNC_DISPLAY_SCROLLTEXT: case FUNC_DISPLAY_SCROLLTEXT:
case FUNC_DISPLAY_SCROLLDELAY: case FUNC_DISPLAY_SCROLLDELAY:
case FUNC_DISPLAY_CLOCK: case FUNC_DISPLAY_CLOCK:
TM1637Data.show_clock = false; if (disp_power && !Settings.display_mode) {
case FUNC_DISPLAY_BRIGHTNESS: TM1637Data.show_clock = false;
if (disp_power) {
result = TM1637MainFunc(function); result = TM1637MainFunc(function);
} }
break; break;
case FUNC_DISPLAY_DIM:
TM1637Dim();
break;
case FUNC_DISPLAY_POWER: case FUNC_DISPLAY_POWER:
if (!disp_power) { TM1637ClearDisplay(); } if (!disp_power) { TM1637ClearDisplay(); }
break; break;