mirror of
https://github.com/arendst/Tasmota.git
synced 2025-08-03 07:57:43 +00:00
Merge pull request #4887 from dh-harald/development
Add support for Mi Desk Lamp
This commit is contained in:
commit
6b7becb30a
@ -11,7 +11,9 @@
|
|||||||
* Add support for Luminea ZX2820 Smart Socket with Energy monitoring (#4921)
|
* Add support for Luminea ZX2820 Smart Socket with Energy monitoring (#4921)
|
||||||
* Add define MDNS_ENABLE to control initial mDNS state (#4923)
|
* Add define MDNS_ENABLE to control initial mDNS state (#4923)
|
||||||
* Add split interlock part 1 (#4910)
|
* Add split interlock part 1 (#4910)
|
||||||
*
|
* Add support for rotary switch
|
||||||
|
* Add support for Mi Desk Lamp
|
||||||
|
*
|
||||||
* 6.4.1.7 20190106
|
* 6.4.1.7 20190106
|
||||||
* Fix HLW8012, HJL01 and BL0937 based energy sensors low Power (below 10W) measurement regression from 6.4.1.6
|
* Fix HLW8012, HJL01 and BL0937 based energy sensors low Power (below 10W) measurement regression from 6.4.1.6
|
||||||
* Add Power status functionality to LED2 when configured leaving LED1 for Link status indication
|
* Add Power status functionality to LED2 when configured leaving LED1 for Link status indication
|
||||||
|
@ -260,5 +260,7 @@ const uint8_t kIFan02Speed[MAX_FAN_SPEED][3] = {{6,6,6}, {7,6,6}, {7,7,6}, {7,6,
|
|||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
extern uint8_t light_device; // Light device number
|
extern uint8_t light_device; // Light device number
|
||||||
|
extern uint8_t light_power; // Light power
|
||||||
|
extern uint8_t rotary_changed; // Rotary switch changed
|
||||||
|
|
||||||
#endif // _SONOFF_H_
|
#endif // _SONOFF_H_
|
||||||
|
@ -2362,6 +2362,7 @@ void GpioInit(void)
|
|||||||
|
|
||||||
ButtonInit();
|
ButtonInit();
|
||||||
SwitchInit();
|
SwitchInit();
|
||||||
|
RotaryInit();
|
||||||
|
|
||||||
#ifdef USE_WS2812
|
#ifdef USE_WS2812
|
||||||
if (!light_type && (pin[GPIO_WS2812] < 99)) { // RGB led
|
if (!light_type && (pin[GPIO_WS2812] < 99)) { // RGB led
|
||||||
@ -2548,6 +2549,7 @@ void loop(void)
|
|||||||
|
|
||||||
ButtonLoop();
|
ButtonLoop();
|
||||||
SwitchLoop();
|
SwitchLoop();
|
||||||
|
RotaryLoop();
|
||||||
|
|
||||||
if (TimeReached(state_50msecond)) {
|
if (TimeReached(state_50msecond)) {
|
||||||
SetNextTimeInterval(state_50msecond, 50);
|
SetNextTimeInterval(state_50msecond, 50);
|
||||||
|
@ -163,6 +163,8 @@ enum ProgramSelectablePins {
|
|||||||
GPIO_DI, // my92x1 PWM input
|
GPIO_DI, // my92x1 PWM input
|
||||||
GPIO_DCKI, // my92x1 CLK input
|
GPIO_DCKI, // my92x1 CLK input
|
||||||
GPIO_ARIRFRCV, // AliLux RF Receive input
|
GPIO_ARIRFRCV, // AliLux RF Receive input
|
||||||
|
GPIO_ROT_A, // Rotary switch A Pin
|
||||||
|
GPIO_ROT_B, // Rotary switch B Pin
|
||||||
GPIO_USER, // User configurable
|
GPIO_USER, // User configurable
|
||||||
GPIO_MAX };
|
GPIO_MAX };
|
||||||
|
|
||||||
@ -278,6 +280,7 @@ enum SupportedModules {
|
|||||||
DIGOO,
|
DIGOO,
|
||||||
KA10,
|
KA10,
|
||||||
ZX2820,
|
ZX2820,
|
||||||
|
MI_DESK_LAMP,
|
||||||
MAXMODULE };
|
MAXMODULE };
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
@ -565,6 +568,7 @@ const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = {
|
|||||||
ARILUX_LC11,
|
ARILUX_LC11,
|
||||||
ZENGGE_ZF_WF017,
|
ZENGGE_ZF_WF017,
|
||||||
HUAFAN_SS,
|
HUAFAN_SS,
|
||||||
|
MI_DESK_LAMP,
|
||||||
KMC_70011,
|
KMC_70011,
|
||||||
AILIGHT, // Light Bulbs
|
AILIGHT, // Light Bulbs
|
||||||
PHILIPS,
|
PHILIPS,
|
||||||
@ -1754,6 +1758,23 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
|
|||||||
GPIO_LED1_INV, // GPIO13 Green Led - Link and Power status
|
GPIO_LED1_INV, // GPIO13 Green Led - Link and Power status
|
||||||
GPIO_REL1, // GPIO14 Relay
|
GPIO_REL1, // GPIO14 Relay
|
||||||
0, 0, 0
|
0, 0, 0
|
||||||
|
},
|
||||||
|
{ "Mi Desk Lamp", // Mi LED Desk Lamp
|
||||||
|
// https://www.mi.com/global/smartlamp/
|
||||||
|
0, 0,
|
||||||
|
GPIO_KEY1, // GPIO02 Button
|
||||||
|
0,
|
||||||
|
GPIO_PWM1, // GPIO04 Cold White
|
||||||
|
GPIO_PWM2, // GPIO05 Warm White
|
||||||
|
// GPIO06 (SD_CLK Flash)
|
||||||
|
// GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
|
||||||
|
// GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
// GPIO11 (SD_CMD Flash)
|
||||||
|
GPIO_ROT_A, // GPIO12 Rotary switch A pin
|
||||||
|
GPIO_ROT_B, // GPIO13 Rotary switch B pin
|
||||||
|
0, 0, 0, 0
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -203,19 +203,23 @@ void ButtonHandler(void)
|
|||||||
multipress[button_index] = 1;
|
multipress[button_index] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((MI_DESK_LAMP == Settings.module) && (button_index == 0) && (rotary_changed) && (light_power)) {
|
||||||
|
rotary_changed = 0; // Color temp changed, no need to turn of the light
|
||||||
|
} else {
|
||||||
if (single_press && SendKey(0, button_index + multipress[button_index], POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set
|
if (single_press && SendKey(0, button_index + multipress[button_index], POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set
|
||||||
// Success
|
// Success
|
||||||
} else {
|
} else {
|
||||||
if (multipress[button_index] < 3) { // Single or Double press
|
if (multipress[button_index] < 3) { // Single or Double press
|
||||||
if (WifiState() > WIFI_RESTART) { // WPSconfig, Smartconfig or Wifimanager active
|
if (WifiState() > WIFI_RESTART) { // WPSconfig, Smartconfig or Wifimanager active
|
||||||
restart_flag = 1;
|
restart_flag = 1;
|
||||||
} else {
|
} else {
|
||||||
ExecuteCommandPower(button_index + multipress[button_index], POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally
|
ExecuteCommandPower(button_index + multipress[button_index], POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally
|
||||||
}
|
}
|
||||||
} else { // 3 - 7 press
|
} else { // 3 - 7 press
|
||||||
if (!Settings.flag.button_restrict) {
|
if (!Settings.flag.button_restrict) {
|
||||||
snprintf_P(scmnd, sizeof(scmnd), kCommands[multipress[button_index] -3]);
|
snprintf_P(scmnd, sizeof(scmnd), kCommands[multipress[button_index] -3]);
|
||||||
ExecuteCommand(scmnd, SRC_BUTTON);
|
ExecuteCommand(scmnd, SRC_BUTTON);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
151
sonoff/support_rotary.ino
Normal file
151
sonoff/support_rotary.ino
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
support_rotary.ino - rotary switch support for Sonoff-Tasmota
|
||||||
|
|
||||||
|
Copyright (C) 2019 Theo Arends
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ROTARY_V1
|
||||||
|
#ifdef ROTARY_V1
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Rotary support
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
unsigned long rotary_debounce = 0; // Rotary debounce timer
|
||||||
|
uint8_t rotaries_found = 0;
|
||||||
|
uint8_t rotary_state = 0;
|
||||||
|
uint8_t rotary_position = 128;
|
||||||
|
uint8_t rotary_last_position = 128;
|
||||||
|
uint8_t interrupts_in_use = 0;
|
||||||
|
uint8_t rotary_changed = 0;
|
||||||
|
|
||||||
|
/********************************************************************************************/
|
||||||
|
|
||||||
|
void update_position(void) {
|
||||||
|
uint8_t s;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
s = rotary_state & 3;
|
||||||
|
if (digitalRead(pin[GPIO_ROT_A])) s |= 4;
|
||||||
|
if (digitalRead(pin[GPIO_ROT_B])) s |= 8;
|
||||||
|
switch (s) {
|
||||||
|
case 0: case 5: case 10: case 15:
|
||||||
|
break;
|
||||||
|
case 1: case 7: case 8: case 14:
|
||||||
|
rotary_position++; break;
|
||||||
|
case 2: case 4: case 11: case 13:
|
||||||
|
rotary_position--; break;
|
||||||
|
case 3: case 12:
|
||||||
|
rotary_position = rotary_position + 2; break;
|
||||||
|
default:
|
||||||
|
rotary_position = rotary_position - 2; break;
|
||||||
|
}
|
||||||
|
rotary_state = (s >> 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_rotary(void) {
|
||||||
|
if (MI_DESK_LAMP == Settings.module){
|
||||||
|
if (light_power) {
|
||||||
|
update_position();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RotaryInit(void)
|
||||||
|
{
|
||||||
|
rotaries_found = 0;
|
||||||
|
if ((pin[GPIO_ROT_A] < 99) && (pin[GPIO_ROT_B] < 99)) {
|
||||||
|
rotaries_found++;
|
||||||
|
pinMode(pin[GPIO_ROT_A], INPUT_PULLUP);
|
||||||
|
pinMode(pin[GPIO_ROT_B], INPUT_PULLUP);
|
||||||
|
|
||||||
|
// GPIO6-GPIO11 are typically used to interface with the flash memory IC on
|
||||||
|
// most esp8266 modules, so we should avoid adding interrupts to these pins.
|
||||||
|
|
||||||
|
if ((pin[GPIO_ROT_A] < 6) || (pin[GPIO_ROT_A] > 11)) {
|
||||||
|
attachInterrupt(digitalPinToInterrupt(pin[GPIO_ROT_A]), update_rotary, CHANGE);
|
||||||
|
interrupts_in_use++;
|
||||||
|
}
|
||||||
|
if ((pin[GPIO_ROT_B] < 6) || (pin[GPIO_ROT_B] > 11)) {
|
||||||
|
attachInterrupt(digitalPinToInterrupt(pin[GPIO_ROT_B]), update_rotary, CHANGE);
|
||||||
|
interrupts_in_use++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Rotary handler
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
void RotaryHandler(void)
|
||||||
|
{
|
||||||
|
if (interrupts_in_use < 2) {
|
||||||
|
noInterrupts();
|
||||||
|
update_rotary();
|
||||||
|
} else {
|
||||||
|
noInterrupts();
|
||||||
|
}
|
||||||
|
if (rotary_last_position != rotary_position) {
|
||||||
|
if (MI_DESK_LAMP == Settings.module) { // Mi Desk lamp
|
||||||
|
if (holdbutton[0]) {
|
||||||
|
rotary_changed = 1;
|
||||||
|
// button1 is pressed: set color temperature
|
||||||
|
int16_t t = LightGetColorTemp();
|
||||||
|
t = t + (rotary_position - rotary_last_position);
|
||||||
|
if (t < 153) {
|
||||||
|
t = 153;
|
||||||
|
}
|
||||||
|
if (t > 500) {
|
||||||
|
t = 500;
|
||||||
|
}
|
||||||
|
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_CMND_COLORTEMPERATURE " %d"), rotary_position - rotary_last_position);
|
||||||
|
AddLog(LOG_LEVEL_DEBUG);
|
||||||
|
LightSetColorTemp((uint16_t)t);
|
||||||
|
} else {
|
||||||
|
int8_t d = Settings.light_dimmer;
|
||||||
|
d = d + (rotary_position - rotary_last_position);
|
||||||
|
if (d < 1) {
|
||||||
|
d = 1;
|
||||||
|
}
|
||||||
|
if (d > 100) {
|
||||||
|
d = 100;
|
||||||
|
}
|
||||||
|
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_CMND_DIMMER " %d"), rotary_position - rotary_last_position);
|
||||||
|
AddLog(LOG_LEVEL_DEBUG);
|
||||||
|
|
||||||
|
LightSetDimmer((uint8_t)d);
|
||||||
|
Settings.light_dimmer = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rotary_last_position = 128;
|
||||||
|
rotary_position = 128;
|
||||||
|
}
|
||||||
|
interrupts();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RotaryLoop(void)
|
||||||
|
{
|
||||||
|
if (rotaries_found) {
|
||||||
|
if (TimeReached(rotary_debounce)) {
|
||||||
|
SetNextTimeInterval(rotary_debounce, Settings.button_debounce); // Using button_debounce setting for this as well
|
||||||
|
RotaryHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ROTARY_V1
|
Loading…
x
Reference in New Issue
Block a user