mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-27 20:56:35 +00:00
Add virtual Buttons & Switches in Digtian driver (#18223)
* add support for virtual buttons or switches * remove DINGTIAN key from SENSOR when using buttons-switches
This commit is contained in:
parent
115105bf7c
commit
948a82d75e
@ -978,6 +978,11 @@
|
|||||||
//#define USE_HX711 // Add support for HX711 load cell (+1k5 code)
|
//#define USE_HX711 // Add support for HX711 load cell (+1k5 code)
|
||||||
// #define USE_HX711_GUI // Add optional web GUI to HX711 as scale (+1k8 code)
|
// #define USE_HX711_GUI // Add optional web GUI to HX711 as scale (+1k8 code)
|
||||||
|
|
||||||
|
//#define USE_DINGTIAN_RELAY // Add support for the Dingian board using 74'595 et 74'165 shift registers
|
||||||
|
// #define DINGTIAN_INPUTS_INVERTED // Invert input states (Hi => OFF, Low => ON)
|
||||||
|
// #define DINGTIAN_USE_AS_BUTTON // Inputs as Tasmota's virtual Buttons
|
||||||
|
// #define DINGTIAN_USE_AS_SWITCH // Inputs as Tasmota's virtual Switches
|
||||||
|
|
||||||
// Select none or only one of the below defines
|
// Select none or only one of the below defines
|
||||||
//#define USE_TX20_WIND_SENSOR // Add support for La Crosse TX20 anemometer (+2k6/0k8 code)
|
//#define USE_TX20_WIND_SENSOR // Add support for La Crosse TX20 anemometer (+2k6/0k8 code)
|
||||||
//#define USE_TX23_WIND_SENSOR // Add support for La Crosse TX23 anemometer (+2k7/1k code)
|
//#define USE_TX23_WIND_SENSOR // Add support for La Crosse TX23 anemometer (+2k7/1k code)
|
||||||
|
@ -22,6 +22,14 @@
|
|||||||
|
|
||||||
#define XDRV_90 90
|
#define XDRV_90 90
|
||||||
|
|
||||||
|
/********************************************************************************************************
|
||||||
|
* Check defines
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(DINGTIAN_USE_AS_BUTTON) && defined(DINGTIAN_USE_AS_SWITCH)
|
||||||
|
#error DINGTIAN - Only one of DINGTIAN_USE_AS_BUTTON or DINGTIAN_USE_AS_SWITCH should be defined
|
||||||
|
#endif
|
||||||
|
|
||||||
/********************************************************************************************************
|
/********************************************************************************************************
|
||||||
* Global private data
|
* Global private data
|
||||||
*/
|
*/
|
||||||
@ -31,6 +39,7 @@ struct DINGTIAN_DATA {
|
|||||||
uint32_t last_inputs; // previous inputs state
|
uint32_t last_inputs; // previous inputs state
|
||||||
uint8_t count; // number of relay and input (8 * numver of shift registers)
|
uint8_t count; // number of relay and input (8 * numver of shift registers)
|
||||||
uint8_t first; // index of 1st Tasmota relay assigned to 1st Dingtian relays
|
uint8_t first; // index of 1st Tasmota relay assigned to 1st Dingtian relays
|
||||||
|
int8_t key_offset; // index of virtual key
|
||||||
// pins
|
// pins
|
||||||
uint8_t pin_clk, pin_sdi, pin_q7, pin_pl, pin_rck;
|
uint8_t pin_clk, pin_sdi, pin_q7, pin_pl, pin_rck;
|
||||||
} *Dingtian = nullptr;
|
} *Dingtian = nullptr;
|
||||||
@ -63,7 +72,11 @@ uint32_t DingtianReadWrite(uint32_t outputs)
|
|||||||
digitalWrite(Dingtian->pin_rck, 1); // rclk pulse to load '595 into output registers
|
digitalWrite(Dingtian->pin_rck, 1); // rclk pulse to load '595 into output registers
|
||||||
digitalWrite(Dingtian->pin_pl, 0); // re-enable '595 ouputs
|
digitalWrite(Dingtian->pin_pl, 0); // re-enable '595 ouputs
|
||||||
|
|
||||||
|
#ifdef DINGTIAN_INPUTS_INVERTED
|
||||||
|
return ~inputs;
|
||||||
|
#else
|
||||||
return inputs;
|
return inputs;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************************************************
|
/********************************************************************************************************
|
||||||
@ -98,16 +111,51 @@ void DingtianInit(void) {
|
|||||||
DINGTIAN_SET_OUTPUT(Dingtian->pin_rck, 0);
|
DINGTIAN_SET_OUTPUT(Dingtian->pin_rck, 0);
|
||||||
|
|
||||||
Dingtian->first = TasmotaGlobal.devices_present;
|
Dingtian->first = TasmotaGlobal.devices_present;
|
||||||
|
Dingtian->key_offset = -1;
|
||||||
UpdateDevicesPresent(Dingtian->count);
|
UpdateDevicesPresent(Dingtian->count);
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("DNGT: Dingtian relays: POWER%d to POWER%d"), Dingtian->first + 1, TasmotaGlobal.devices_present);
|
AddLog(LOG_LEVEL_DEBUG, PSTR("DNGT: Dingtian relays: POWER%d to POWER%d"), Dingtian->first + 1, TasmotaGlobal.devices_present);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(DINGTIAN_USE_AS_BUTTON) || defined(DINGTIAN_USE_AS_SWITCH)
|
||||||
|
bool DingtianAddKey(void) {
|
||||||
|
if (Dingtian->key_offset < 0) {
|
||||||
|
Dingtian->key_offset = XdrvMailbox.index;
|
||||||
|
#ifdef DINGTIAN_USE_AS_BUTTON
|
||||||
|
AddLog(LOG_LEVEL_DEBUG, PSTR("DNGT: Dingtian inputs: Button%d to Button%d"), Dingtian->key_offset + 1, Dingtian->key_offset + Dingtian->count);
|
||||||
|
#else
|
||||||
|
AddLog(LOG_LEVEL_DEBUG, PSTR("DNGT: Dingtian inputs: Switch%d to Switch%d"), Dingtian->key_offset + 1, Dingtian->key_offset + Dingtian->count);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
uint32_t index = XdrvMailbox.index - Dingtian->key_offset;
|
||||||
|
if (index >= Dingtian->count) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
XdrvMailbox.index = 0; // Default is 0 - Button will also set invert
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/********************************************************************************************************
|
/********************************************************************************************************
|
||||||
* Driver operations
|
* Driver operations
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if defined(DINGTIAN_USE_AS_BUTTON) || defined(DINGTIAN_USE_AS_SWITCH)
|
||||||
|
void DingtianLoop()
|
||||||
|
{
|
||||||
|
uint32_t inputs = DingtianReadWrite(Dingtian->outputs);
|
||||||
|
Dingtian->last_inputs = inputs;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < Dingtian->count ; i++, inputs>>=1) {
|
||||||
|
#ifdef DINGTIAN_USE_AS_BUTTON
|
||||||
|
ButtonSetVirtualPinState(Dingtian->key_offset +i, inputs &1);
|
||||||
|
#else
|
||||||
|
SwitchSetVirtualPinState(Dingtian->key_offset +i, inputs &1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
void DingtianLoop()
|
void DingtianLoop()
|
||||||
{
|
{
|
||||||
uint32_t inputs = DingtianReadWrite(Dingtian->outputs);
|
uint32_t inputs = DingtianReadWrite(Dingtian->outputs);
|
||||||
@ -131,6 +179,7 @@ void DingtianLoop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void DingtianSetPower(void)
|
void DingtianSetPower(void)
|
||||||
{
|
{
|
||||||
@ -146,30 +195,32 @@ void DingtianSetPower(void)
|
|||||||
|
|
||||||
const char HTTP_DINGTIAN_INPUTS[] PROGMEM = "{s}DINGTIAN " D_SENSOR_INPUT "%d.." D_SENSOR_INPUT "%d{m}%s{e}";
|
const char HTTP_DINGTIAN_INPUTS[] PROGMEM = "{s}DINGTIAN " D_SENSOR_INPUT "%d.." D_SENSOR_INPUT "%d{m}%s{e}";
|
||||||
|
|
||||||
void DingtianShow(bool json)
|
#if !defined(DINGTIAN_USE_AS_BUTTON) && !defined(DINGTIAN_USE_AS_SWITCH)
|
||||||
|
void DingtianJsonAppend(void)
|
||||||
{
|
{
|
||||||
if (json) {
|
bool first_done = false;
|
||||||
bool first_done = false;
|
ResponseAppend_P(PSTR(",\"DINGTIAN\":{"));
|
||||||
ResponseAppend_P(PSTR(",\"DINGTIAN\":{"));
|
for (int i = 0 ; i < Dingtian->count ; i++) {
|
||||||
for (int i = 0 ; i < Dingtian->count ; i++) {
|
if (first_done) ResponseAppend_P(PSTR(","));
|
||||||
if (first_done) ResponseAppend_P(PSTR(","));
|
ResponseAppend_P(PSTR("\"IN%d\":%d"), i +1, bitRead(Dingtian->last_inputs, i));
|
||||||
ResponseAppend_P(PSTR("\"IN%d\":%d"), i +1, bitRead(Dingtian->last_inputs, i));
|
first_done = true;
|
||||||
first_done = true;
|
|
||||||
}
|
|
||||||
ResponseAppend_P(PSTR("}"));
|
|
||||||
}
|
}
|
||||||
#ifdef USE_WEBSERVER
|
ResponseAppend_P(PSTR("}"));
|
||||||
else {
|
|
||||||
char input_str[9];
|
|
||||||
for (int block_input = 0 ; block_input < Dingtian->count ; block_input += 8 ) {
|
|
||||||
for (int i = 0 ; i < 8 ; i++ )
|
|
||||||
input_str[i] = '0' + bitRead(Dingtian->last_inputs, block_input +i);
|
|
||||||
input_str[8] = '\0';
|
|
||||||
WSContentSend_P(HTTP_DINGTIAN_INPUTS, block_input, block_input +7, input_str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_WEBSERVER
|
||||||
|
void DingtianWebSensor(void)
|
||||||
|
{
|
||||||
|
char input_str[9];
|
||||||
|
for (int block_input = 0 ; block_input < Dingtian->count ; block_input += 8 ) {
|
||||||
|
for (int i = 0 ; i < 8 ; i++ )
|
||||||
|
input_str[i] = '0' + bitRead(Dingtian->last_inputs, block_input +i);
|
||||||
|
input_str[8] = '\0';
|
||||||
|
WSContentSend_P(HTTP_DINGTIAN_INPUTS, block_input, block_input +7, input_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
@ -179,7 +230,7 @@ void DingtianShow(bool json)
|
|||||||
bool Xdrv90(uint32_t function) {
|
bool Xdrv90(uint32_t function) {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
if (FUNC_PRE_INIT == function) {
|
if (FUNC_SETUP_RING2 == function) {
|
||||||
DingtianInit();
|
DingtianInit();
|
||||||
} else if (Dingtian) {
|
} else if (Dingtian) {
|
||||||
switch (function) {
|
switch (function) {
|
||||||
@ -190,14 +241,26 @@ bool Xdrv90(uint32_t function) {
|
|||||||
//case FUNC_EVERY_250_MSECOND:
|
//case FUNC_EVERY_250_MSECOND:
|
||||||
DingtianLoop();
|
DingtianLoop();
|
||||||
break;
|
break;
|
||||||
|
#if !defined(DINGTIAN_USE_AS_BUTTON) && !defined(DINGTIAN_USE_AS_SWITCH)
|
||||||
case FUNC_JSON_APPEND:
|
case FUNC_JSON_APPEND:
|
||||||
DingtianShow(1);
|
DingtianJsonAppend();
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
#ifdef USE_WEBSERVER
|
#ifdef USE_WEBSERVER
|
||||||
case FUNC_WEB_SENSOR:
|
case FUNC_WEB_SENSOR:
|
||||||
DingtianShow(0);
|
DingtianWebSensor();
|
||||||
break;
|
break;
|
||||||
#endif // USE_WEBSERVER
|
#endif // USE_WEBSERVER
|
||||||
|
#ifdef DINGTIAN_USE_AS_BUTTON
|
||||||
|
case FUNC_ADD_BUTTON:
|
||||||
|
result = DingtianAddKey();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef DINGTIAN_USE_AS_SWITCH
|
||||||
|
case FUNC_ADD_SWITCH:
|
||||||
|
result = DingtianAddKey();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user