mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-24 11:16:34 +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_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
|
||||
//#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)
|
||||
|
@ -22,6 +22,14 @@
|
||||
|
||||
#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
|
||||
*/
|
||||
@ -31,6 +39,7 @@ struct DINGTIAN_DATA {
|
||||
uint32_t last_inputs; // previous inputs state
|
||||
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
|
||||
int8_t key_offset; // index of virtual key
|
||||
// pins
|
||||
uint8_t pin_clk, pin_sdi, pin_q7, pin_pl, pin_rck;
|
||||
} *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_pl, 0); // re-enable '595 ouputs
|
||||
|
||||
#ifdef DINGTIAN_INPUTS_INVERTED
|
||||
return ~inputs;
|
||||
#else
|
||||
return inputs;
|
||||
#endif
|
||||
}
|
||||
|
||||
/********************************************************************************************************
|
||||
@ -98,16 +111,51 @@ void DingtianInit(void) {
|
||||
DINGTIAN_SET_OUTPUT(Dingtian->pin_rck, 0);
|
||||
|
||||
Dingtian->first = TasmotaGlobal.devices_present;
|
||||
Dingtian->key_offset = -1;
|
||||
UpdateDevicesPresent(Dingtian->count);
|
||||
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
|
||||
*/
|
||||
|
||||
#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()
|
||||
{
|
||||
uint32_t inputs = DingtianReadWrite(Dingtian->outputs);
|
||||
@ -131,6 +179,7 @@ void DingtianLoop()
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
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}";
|
||||
|
||||
void DingtianShow(bool json)
|
||||
#if !defined(DINGTIAN_USE_AS_BUTTON) && !defined(DINGTIAN_USE_AS_SWITCH)
|
||||
void DingtianJsonAppend(void)
|
||||
{
|
||||
if (json) {
|
||||
bool first_done = false;
|
||||
ResponseAppend_P(PSTR(",\"DINGTIAN\":{"));
|
||||
for (int i = 0 ; i < Dingtian->count ; i++) {
|
||||
if (first_done) ResponseAppend_P(PSTR(","));
|
||||
ResponseAppend_P(PSTR("\"IN%d\":%d"), i +1, bitRead(Dingtian->last_inputs, i));
|
||||
first_done = true;
|
||||
}
|
||||
ResponseAppend_P(PSTR("}"));
|
||||
bool first_done = false;
|
||||
ResponseAppend_P(PSTR(",\"DINGTIAN\":{"));
|
||||
for (int i = 0 ; i < Dingtian->count ; i++) {
|
||||
if (first_done) ResponseAppend_P(PSTR(","));
|
||||
ResponseAppend_P(PSTR("\"IN%d\":%d"), i +1, bitRead(Dingtian->last_inputs, i));
|
||||
first_done = true;
|
||||
}
|
||||
#ifdef USE_WEBSERVER
|
||||
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
|
||||
ResponseAppend_P(PSTR("}"));
|
||||
}
|
||||
#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 result = false;
|
||||
|
||||
if (FUNC_PRE_INIT == function) {
|
||||
if (FUNC_SETUP_RING2 == function) {
|
||||
DingtianInit();
|
||||
} else if (Dingtian) {
|
||||
switch (function) {
|
||||
@ -190,14 +241,26 @@ bool Xdrv90(uint32_t function) {
|
||||
//case FUNC_EVERY_250_MSECOND:
|
||||
DingtianLoop();
|
||||
break;
|
||||
#if !defined(DINGTIAN_USE_AS_BUTTON) && !defined(DINGTIAN_USE_AS_SWITCH)
|
||||
case FUNC_JSON_APPEND:
|
||||
DingtianShow(1);
|
||||
DingtianJsonAppend();
|
||||
break;
|
||||
#endif
|
||||
#ifdef USE_WEBSERVER
|
||||
case FUNC_WEB_SENSOR:
|
||||
DingtianShow(0);
|
||||
DingtianWebSensor();
|
||||
break;
|
||||
#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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user