mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 02:36:35 +00:00
Add commands DspLine and DspSpeed
Add commands DspLine and DspSpeed (#15856)
This commit is contained in:
parent
c3d95bfddc
commit
04160106c2
@ -12,6 +12,8 @@ All notable changes to this project will be documented in this file.
|
||||
- Zigbee prepare for Green Power support (#16407)
|
||||
- Command ``SetOption146 1`` to enable display of ESP32 internal temperature
|
||||
- Support for DFRobot SEN0390 V30B ambient light sensor (#16105)
|
||||
- Command ``DspSpeed 2..127`` to control message rotation speed on display of POWR3xxD and THR3xxD
|
||||
- Command ``DspLine<1|2> <index>,<unit>,<index>,<unit>,...`` to select message(s) on display of POWR3xxD and THR3xxD
|
||||
|
||||
### Changed
|
||||
- TasmotaModbus library from v3.5.0 to v3.6.0 (#16351)
|
||||
|
@ -111,6 +111,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
|
||||
### Added
|
||||
- Command ``SetOption146 1`` to enable display of ESP32 internal temperature
|
||||
- Command ``StatusRetain`` [#11109](https://github.com/arendst/Tasmota/issues/11109)
|
||||
- Command ``DspSpeed 2..127`` to control message rotation speed on display of POWR3xxD and THR3xxD
|
||||
- Command ``DspLine<1|2> <index>,<unit>,<index>,<unit>,...`` to select message(s) on display of POWR3xxD and THR3xxD
|
||||
- Support for SGP40 gas and air quality sensor [#16341](https://github.com/arendst/Tasmota/issues/16341)
|
||||
- Support for Modbus writing using ModbusBridge by JeroenSt [#16351](https://github.com/arendst/Tasmota/issues/16351)
|
||||
- Support for DFRobot SEN0390 V30B ambient light sensor [#16105](https://github.com/arendst/Tasmota/issues/16105)
|
||||
|
@ -819,7 +819,7 @@ void ResponseAppendFeatures(void)
|
||||
feature8 |= 0x40000000; // xlgt_09_sm2335.ino
|
||||
#endif
|
||||
#ifdef USE_DISPLAY_TM1621_SONOFF
|
||||
feature8 |= 0x80000000; // xdrv_87_tm1621_sonoff.ino
|
||||
feature8 |= 0x80000000; // xdrv_87_esp32_sonoff_tm1621.ino
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
/*
|
||||
xdrv_87_tm1621_sonoff.ino - Sonoff POWR3xxD and THR3xxD display support for Tasmota
|
||||
xdrv_87_esp32_sonoff_tm1621.ino - Sonoff POWR3xxD and THR3xxD display support for Tasmota
|
||||
|
||||
SPDX-FileCopyrightText: 2022 Theo Arends
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
|
||||
#ifdef ESP32
|
||||
#ifdef USE_DISPLAY_TM1621_SONOFF
|
||||
/*********************************************************************************************\
|
||||
* Sonoff POWR3xxD and THR3xxD LCD support
|
||||
@ -13,11 +14,29 @@
|
||||
* {"NAME":"Sonoff POWR316D","GPIO":[32,0,0,0,0,576,0,0,0,224,9280,0,3104,0,320,0,0,0,0,0,0,9184,9248,9216,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
||||
* {"NAME":"Sonoff POWR320D","GPIO":[32,0,9313,0,9312,576,0,0,0,0,9280,0,3104,0,320,0,0,0,0,0,0,9184,9248,9216,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
||||
* {"NAME":"Sonoff THR316D","GPIO":[32,0,0,0,225,9280,0,0,0,321,0,576,320,9184,9216,0,0,224,0,9248,0,1,0,3840,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
||||
* {"NAME":"Sonoff THR316D GPIO26","GPIO":[32,0,0,0,225,9280,0,0,0,321,0,576,320,9184,9216,0,0,224,0,9248,0,1,1,3840,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
||||
* {"NAME":"Sonoff THR320D","GPIO":[32,0,0,0,226,9280,0,0,0,321,0,576,320,9184,9216,9312,0,0,9313,9248,0,1,0,3840,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
||||
* {"NAME":"Sonoff THR320D GPIO26","GPIO":[32,0,0,0,226,9280,0,0,0,321,0,576,320,9184,9216,9312,0,0,9313,9248,0,1,1,3840,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
||||
*
|
||||
* DspSpeed 2..127 = Display rotation speed in seconds if more than one value is requested
|
||||
* DspLine<1|2> <index>,<unit>,<index>,<unit>,... = Display specific JSON value and rotate between them
|
||||
* unit 0 = None
|
||||
* 1 = Temperature (Line 1 only)
|
||||
* 2 = %RH (Line 2 only)
|
||||
* 3 = Both V (Line 1 only) / A (Line 2 only)
|
||||
* 4 = Both kWh (Line 1 only) / W (Line 2 only)
|
||||
* DspLine1 0 and DspLine2 0 = Default of temperature/humidity
|
||||
*
|
||||
* Example: "SCD30":{"CarbonDioxide":746,"eCO2":727,"Temperature":30.6,"Humidity":43.6,"DewPoint":16.8}
|
||||
* DspLine1 4,1,3,0 = Temperature and eCO2
|
||||
* DspLine2 2,0,5,2 = CarbonDioxide and humidity
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XDRV_87 87
|
||||
|
||||
#define TM1621_ROTATE 5 // Seconds display rotation speed
|
||||
#define TM1621_MAX_VALUES 8 // Default 8 x two different lines
|
||||
|
||||
#define TM1621_PULSE_WIDTH 10 // microseconds (Sonoff = 100)
|
||||
|
||||
#define TM1621_SYS_EN 0x01 // 0b00000001
|
||||
@ -29,6 +48,7 @@
|
||||
#define TM1621_IRQ_DIS 0x80 // 0b100x0xxx
|
||||
|
||||
enum Tm1621Device { TM1621_USER, TM1621_POWR316D, TM1621_THR316D };
|
||||
enum Tm1621Units { TM1621_NONE, TM1621_TEMPERATURE, TM1621_HUMIDITY, TM1621_VOLTAGE_CURRENT, TM1621_ENERGY_POWER };
|
||||
|
||||
const uint8_t tm1621_commands[] = { TM1621_SYS_EN, TM1621_LCD_ON, TM1621_BIAS, TM1621_TIMER_DIS, TM1621_WDT_DIS, TM1621_TONE_OFF, TM1621_IRQ_DIS };
|
||||
|
||||
@ -46,6 +66,7 @@ struct Tm1621 {
|
||||
uint8_t pin_wr;
|
||||
uint8_t state;
|
||||
uint8_t device;
|
||||
uint8_t display_rotate;
|
||||
uint8_t temp_sensors;
|
||||
uint8_t temp_sensors_rotate;
|
||||
bool celsius;
|
||||
@ -56,6 +77,96 @@ struct Tm1621 {
|
||||
bool present;
|
||||
} Tm1621;
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Driver Settings load and save using filesystem
|
||||
\*********************************************************************************************/
|
||||
|
||||
const uint32_t XDRV_87_VERSION = 0x0100; // Latest driver version (See settings deltas below)
|
||||
|
||||
typedef struct {
|
||||
uint32_t crc32; // To detect file changes
|
||||
uint16_t version; // To detect driver function changes
|
||||
uint8_t rotate;
|
||||
uint8_t spare;
|
||||
uint8_t line[2][TM1621_MAX_VALUES];
|
||||
uint8_t unit[2][TM1621_MAX_VALUES];
|
||||
} tXdrv87Settings;
|
||||
tXdrv87Settings Xdrv87Settings;
|
||||
|
||||
uint32_t Xdrv87SettingsCrc32(void) {
|
||||
// Use Tasmota CRC calculation function
|
||||
return GetCfgCrc32((uint8_t*)&Xdrv87Settings +4, sizeof(tXdrv87Settings) -4); // Skip crc32
|
||||
}
|
||||
|
||||
void Xdrv87SettingsDefault(void) {
|
||||
// Init default values in case file is not found
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: XDRV87 " D_USE_DEFAULTS));
|
||||
|
||||
memset(&Xdrv87Settings, 0x00, sizeof(tXdrv87Settings));
|
||||
Xdrv87Settings.version = XDRV_87_VERSION;
|
||||
// Init any other parameter in struct Xdrv87Settings
|
||||
Xdrv87Settings.rotate = TM1621_ROTATE;
|
||||
}
|
||||
|
||||
void Xdrv87SettingsDelta(void) {
|
||||
// Fix possible setting deltas
|
||||
if (Xdrv87Settings.version != SSPM_VERSION) { // Fix version dependent changes
|
||||
|
||||
// Set current version and save settings
|
||||
Xdrv87Settings.version = SSPM_VERSION;
|
||||
Xdrv87SettingsSave();
|
||||
}
|
||||
}
|
||||
|
||||
void Xdrv87SettingsLoad(void) {
|
||||
// Init default values in case file is not found
|
||||
Xdrv87SettingsDefault();
|
||||
|
||||
// Try to load file /.drvset087
|
||||
char filename[20];
|
||||
// Use for drivers:
|
||||
snprintf_P(filename, sizeof(filename), PSTR(TASM_FILE_DRIVER), XDRV_87);
|
||||
|
||||
#ifdef USE_UFILESYS
|
||||
if (TfsLoadFile(filename, (uint8_t*)&Xdrv87Settings, sizeof(tXdrv87Settings))) {
|
||||
// Fix possible setting deltas
|
||||
Xdrv87SettingsDelta();
|
||||
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("CFG: XDRV87 loaded from file"));
|
||||
} else {
|
||||
// File system not ready: No flash space reserved for file system
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: XDRV87 ERROR File system not ready or file not found"));
|
||||
}
|
||||
#else
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: XDRV87 ERROR File system not enabled"));
|
||||
#endif // USE_UFILESYS
|
||||
}
|
||||
|
||||
void Xdrv87SettingsSave(void) {
|
||||
// Called from FUNC_SAVE_SETTINGS every SaveData second and at restart
|
||||
if (Xdrv87SettingsCrc32() != Xdrv87Settings.crc32) {
|
||||
// Try to save file /.drvset087
|
||||
Xdrv87Settings.crc32 = Xdrv87SettingsCrc32();
|
||||
|
||||
char filename[20];
|
||||
// Use for drivers:
|
||||
snprintf_P(filename, sizeof(filename), PSTR(TASM_FILE_DRIVER), XDRV_87);
|
||||
|
||||
#ifdef USE_UFILESYS
|
||||
if (TfsSaveFile(filename, (const uint8_t*)&Xdrv87Settings, sizeof(tXdrv87Settings))) {
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: XDRV87 saved to file"));
|
||||
} else {
|
||||
// File system not ready: No flash space reserved for file system
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: XDRV87 ERROR File system not ready or unable to save file"));
|
||||
}
|
||||
#else
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: XDRV87 ERROR File system not enabled"));
|
||||
#endif // USE_UFILESYS
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
void TM1621StopSequence(void) {
|
||||
digitalWrite(Tm1621.pin_cs, 1); // Stop command sequence
|
||||
delayMicroseconds(TM1621_PULSE_WIDTH / 2);
|
||||
@ -194,7 +305,9 @@ void TM1621PreInit(void) {
|
||||
pinMode(Tm1621.pin_wr, OUTPUT);
|
||||
digitalWrite(Tm1621.pin_wr, 1);
|
||||
|
||||
Tm1621.state = 100;
|
||||
Xdrv87SettingsLoad();
|
||||
|
||||
Tm1621.state = 200;
|
||||
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("DSP: TM1621"));
|
||||
}
|
||||
@ -225,18 +338,48 @@ void TM1621Init(void) {
|
||||
TM1621SendRows();
|
||||
}
|
||||
|
||||
float TM1621GetTemperatureValues(uint32_t index) {
|
||||
char *start = ResponseData();
|
||||
int data_start = ResponseLength();
|
||||
float TM1621GetValues(uint32_t index, bool refresh) {
|
||||
if (refresh) {
|
||||
ResponseClear();
|
||||
XsnsCall(FUNC_JSON_APPEND);
|
||||
XdrvCall(FUNC_JSON_APPEND);
|
||||
}
|
||||
if (!ResponseLength()) { return NAN; }
|
||||
char *start = ResponseData() +1; // Starts with ",..." so skip comma
|
||||
|
||||
XsnsCall(FUNC_JSON_APPEND);
|
||||
XdrvCall(FUNC_JSON_APPEND);
|
||||
|
||||
if (data_start == ResponseLength()) { return NAN; }
|
||||
if (refresh) {
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("TM1: Sensors '%s'"), start);
|
||||
}
|
||||
|
||||
float value = NAN;
|
||||
uint32_t idx = 0;
|
||||
char *data = start; // Invalid JSON ,"HTU21":{"Temperature":30.7,"Humidity":39.0,"DewPoint":15.2},"BME680":{"Temperature":30.0,"Humidity":50.4,"DewPoint":18.5,"Pressure":1009.6,"Gas":1660.52},"ESP32":{"Temperature":53.3}
|
||||
char *data = start; // "HTU21":{"Temperature":30.7,"Humidity":39.0,"DewPoint":15.2},"BME680":{"Temperature":30.0,"Humidity":50.4,"DewPoint":18.5,"Pressure":1009.6,"Gas":1660.52},"ESP32":{"Temperature":53.3}
|
||||
while (data) {
|
||||
data = strstr_P(data, PSTR("\":"));
|
||||
if (data) {
|
||||
idx++;
|
||||
data += 2;
|
||||
if (idx == index) {
|
||||
value = CharToFloat(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
float TM1621GetTemperatureValues(uint32_t index) {
|
||||
ResponseClear();
|
||||
XsnsCall(FUNC_JSON_APPEND);
|
||||
XdrvCall(FUNC_JSON_APPEND);
|
||||
if (!ResponseLength()) { return NAN; }
|
||||
|
||||
char *start = ResponseData() +1; // Starts with ",..." so skip comma
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("TM1: Sensors '%s'"), start);
|
||||
|
||||
float value = NAN;
|
||||
uint32_t idx = 0;
|
||||
char *data = start; // "HTU21":{"Temperature":30.7,"Humidity":39.0,"DewPoint":15.2},"BME680":{"Temperature":30.0,"Humidity":50.4,"DewPoint":18.5,"Pressure":1009.6,"Gas":1660.52},"ESP32":{"Temperature":53.3}
|
||||
while (data) {
|
||||
data = strstr_P(data, PSTR(D_JSON_TEMPERATURE));
|
||||
if (data) {
|
||||
@ -257,30 +400,64 @@ float TM1621GetTemperatureValues(uint32_t index) {
|
||||
}
|
||||
|
||||
void TM1621Show(void) {
|
||||
Tm1621.celsius = false;
|
||||
Tm1621.fahrenheit = false;
|
||||
Tm1621.humidity = false;
|
||||
Tm1621.voltage = false;
|
||||
Tm1621.kwh = false;
|
||||
snprintf_P(Tm1621.row[0], sizeof(Tm1621.row[0]), PSTR(" "));
|
||||
snprintf_P(Tm1621.row[1], sizeof(Tm1621.row[1]), PSTR(" "));
|
||||
|
||||
if ((Xdrv87Settings.line[0][0] > 0) || (Xdrv87Settings.line[1][0] > 0)) {
|
||||
float value = TM1621GetValues(Xdrv87Settings.line[0][Tm1621.display_rotate], 1);
|
||||
if (!isnan(value)) {
|
||||
ext_snprintf_P(Tm1621.row[0], sizeof(Tm1621.row[0]), PSTR("%1_f"), &value);
|
||||
if (TM1621_TEMPERATURE == Xdrv87Settings.unit[0][Tm1621.display_rotate]) {
|
||||
if (Settings->flag.temperature_conversion) { // SetOption8 - Switch between Celsius or Fahrenheit
|
||||
Tm1621.fahrenheit = true;
|
||||
} else {
|
||||
Tm1621.celsius = true;
|
||||
}
|
||||
}
|
||||
Tm1621.voltage = (TM1621_VOLTAGE_CURRENT == Xdrv87Settings.unit[0][Tm1621.display_rotate]);
|
||||
Tm1621.kwh = (4 == Xdrv87Settings.unit[0][Tm1621.display_rotate]);
|
||||
}
|
||||
value = TM1621GetValues(Xdrv87Settings.line[1][Tm1621.display_rotate], 0);
|
||||
if (!isnan(value)) {
|
||||
ext_snprintf_P(Tm1621.row[1], sizeof(Tm1621.row[1]), PSTR("%1_f"), &value);
|
||||
Tm1621.humidity = (TM1621_HUMIDITY == Xdrv87Settings.unit[1][Tm1621.display_rotate]);
|
||||
Tm1621.voltage = (TM1621_VOLTAGE_CURRENT == Xdrv87Settings.unit[1][Tm1621.display_rotate]);
|
||||
Tm1621.kwh = (TM1621_ENERGY_POWER == Xdrv87Settings.unit[1][Tm1621.display_rotate]);
|
||||
}
|
||||
uint32_t max = 0;
|
||||
while ((max < TM1621_MAX_VALUES) && ((Xdrv87Settings.line[0][max] > 0) || (Xdrv87Settings.line[1][max] > 0))) { max++; }
|
||||
Tm1621.display_rotate++;
|
||||
if (Tm1621.display_rotate >= max) {
|
||||
Tm1621.display_rotate = 0;
|
||||
}
|
||||
TM1621SendRows();
|
||||
return;
|
||||
}
|
||||
|
||||
if (TM1621_POWR316D == Tm1621.device) {
|
||||
static uint32_t display = 0;
|
||||
if (0 == display) {
|
||||
Tm1621.kwh = false;
|
||||
if (0 == Tm1621.display_rotate) {
|
||||
// Tm1621.kwh = false;
|
||||
ext_snprintf_P(Tm1621.row[0], sizeof(Tm1621.row[0]), PSTR("%1_f"), &Energy.voltage[0]);
|
||||
ext_snprintf_P(Tm1621.row[1], sizeof(Tm1621.row[1]), PSTR("%1_f"), &Energy.current[0]);
|
||||
Tm1621.voltage = true;
|
||||
display = 1;
|
||||
Tm1621.display_rotate = 1;
|
||||
} else {
|
||||
Tm1621.voltage = false;
|
||||
// Tm1621.voltage = false;
|
||||
ext_snprintf_P(Tm1621.row[0], sizeof(Tm1621.row[0]), PSTR("%1_f"), &Energy.total[0]);
|
||||
ext_snprintf_P(Tm1621.row[1], sizeof(Tm1621.row[1]), PSTR("%1_f"), &Energy.active_power[0]);
|
||||
Tm1621.kwh = true;
|
||||
display = 0;
|
||||
Tm1621.display_rotate = 0;
|
||||
}
|
||||
TM1621SendRows();
|
||||
return;
|
||||
}
|
||||
|
||||
if (TM1621_THR316D == Tm1621.device) {
|
||||
Tm1621.celsius = false;
|
||||
Tm1621.fahrenheit = false;
|
||||
Tm1621.humidity = false;
|
||||
snprintf_P(Tm1621.row[0], sizeof(Tm1621.row[0]), PSTR(" "));
|
||||
snprintf_P(Tm1621.row[1], sizeof(Tm1621.row[1]), PSTR(" "));
|
||||
if (!isnan(TasmotaGlobal.temperature_celsius)) {
|
||||
float temperature = ConvertTempToFahrenheit(TasmotaGlobal.temperature_celsius);
|
||||
if (TasmotaGlobal.humidity == 0.0f) { // No humidity so check for more temperature sensors
|
||||
@ -312,22 +489,77 @@ void TM1621Show(void) {
|
||||
Tm1621.humidity = true;
|
||||
ext_snprintf_P(Tm1621.row[1], sizeof(Tm1621.row[1]), PSTR("%1_f"), &TasmotaGlobal.humidity);
|
||||
}
|
||||
TM1621SendRows();
|
||||
}
|
||||
TM1621SendRows();
|
||||
}
|
||||
|
||||
void TM1621EverySecond(void) {
|
||||
Tm1621.state++;
|
||||
if (5 == Tm1621.state) {
|
||||
TM1621Show();
|
||||
Tm1621.state = 0;
|
||||
if (Tm1621.state > 127) {
|
||||
if (202 == Tm1621.state) {
|
||||
TM1621Init();
|
||||
Tm1621.state = 0;
|
||||
}
|
||||
} else {
|
||||
if (Tm1621.state >= Xdrv87Settings.rotate) {
|
||||
TM1621Show();
|
||||
Tm1621.state = 0;
|
||||
}
|
||||
}
|
||||
if (102 == Tm1621.state) {
|
||||
TM1621Init();
|
||||
Tm1621.state = 0;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Command
|
||||
\*********************************************************************************************/
|
||||
|
||||
const char kTm1621Commands[] PROGMEM = "Dsp|" // No prefix
|
||||
"Line|Speed";
|
||||
void (*const kTm1621Command[])(void) PROGMEM = {
|
||||
&CmndDspLine, &CmndDspSpeed };
|
||||
|
||||
void CmndDspLine(void) {
|
||||
// DspLine1 <index>,<unit>,<index>,<unit>,... = Rotate between indexes
|
||||
// DspLine1 0 and DspLine2 0 = Default of temperature/humidity
|
||||
// Teleperiod: "SCD30":{"CarbonDioxide":746,"eCO2":727,"Temperature":30.6,"Humidity":43.6,"DewPoint":16.8}
|
||||
// DspLine1 4,1,3,0 = Temperature and eCO2
|
||||
// DspLine2 2,0,5,2 = CarbonDioxide and humidity
|
||||
// Unit 0 = None
|
||||
// 1 = temperature (Line 1 only)
|
||||
// 2 = %RH (Line 2 only)
|
||||
// 3 = Both V (Line 1 only) / A (Line 2 only)
|
||||
// 4 = Both kWh (Line 1 only) / W (Line 2 only)
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 2)) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
uint32_t parm[2 * TM1621_MAX_VALUES] = { 0 };
|
||||
ParseParameters(2 * TM1621_MAX_VALUES, parm);
|
||||
for (uint32_t i = 0; i < TM1621_MAX_VALUES; i++) {
|
||||
uint32_t j = i << 1;
|
||||
Xdrv87Settings.line[XdrvMailbox.index -1][i] = parm[j];
|
||||
Xdrv87Settings.unit[XdrvMailbox.index -1][i] = parm[j +1];
|
||||
}
|
||||
}
|
||||
char values[8 * TM1621_MAX_VALUES];
|
||||
values[0] = '\0';
|
||||
uint32_t i = 0;
|
||||
do {
|
||||
snprintf_P(values, sizeof(values), PSTR("%s%s%d,%d"),
|
||||
values, (i > 0) ? "," : "", Xdrv87Settings.line[XdrvMailbox.index -1][i], Xdrv87Settings.unit[XdrvMailbox.index -1][i]);
|
||||
i++;
|
||||
} while ((i < TM1621_MAX_VALUES) && (Xdrv87Settings.line[XdrvMailbox.index -1][i] > 0));
|
||||
ResponseCmndIdxChar(values);
|
||||
}
|
||||
}
|
||||
|
||||
void CmndDspSpeed(void) {
|
||||
// DspSpeed 2..127 = Rotation speed
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
if (XdrvMailbox.payload > 1) { // We need at least 2 seconds to poll all sensors
|
||||
Xdrv87Settings.rotate = XdrvMailbox.payload &0x7F; // Max 127 seconds
|
||||
}
|
||||
}
|
||||
ResponseCmndNumber(Xdrv87Settings.rotate);
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
@ -343,9 +575,16 @@ bool Xdrv87(uint8_t function) {
|
||||
case FUNC_EVERY_SECOND:
|
||||
TM1621EverySecond();
|
||||
break;
|
||||
case FUNC_SAVE_SETTINGS:
|
||||
Xdrv87SettingsSave();
|
||||
break;
|
||||
case FUNC_COMMAND:
|
||||
result = DecodeCommand(kTm1621Commands, kTm1621Command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_DISPLAY_TM1621_SONOFF
|
||||
#endif // ESP32
|
Loading…
x
Reference in New Issue
Block a user