Browse Source

btn: terminal command action

allow to use api helpers to execute something when button event happens
dev
Maxim Prokhorov 6 months ago
parent
commit
eb17675c2a
5 changed files with 101 additions and 30 deletions
  1. +54
    -1
      code/espurna/button.cpp
  2. +1
    -0
      code/espurna/button.h
  3. +18
    -17
      code/espurna/config/types.h
  4. +6
    -12
      code/espurna/ir.cpp
  5. +22
    -0
      code/espurna/libs/EphemeralPrint.h

+ 54
- 1
code/espurna/button.cpp View File

@ -25,6 +25,9 @@ Copyright (C) 2019-2021 by Maxim Prokhorov <prokhorov dot max at outlook dot com
#include "ws.h"
#endif
#include "libs/EphemeralPrint.h"
#include "libs/PrintString.h"
#include "mcp23s08_pin.h"
#include <bitset>
@ -112,6 +115,8 @@ PROGMEM_STRING(MqttRetain, "btnMqttRetain");
[[gnu::unused]] PROGMEM_STRING(AnalogLevel, "btnLevel");
[[gnu::unused]] PROGMEM_STRING(TerminalCommand, "btnTermCmd");
} // namespace
} // namespace keys
@ -181,6 +186,8 @@ PROGMEM_STRING(Custom, "custom");
[[gnu::unused]] PROGMEM_STRING(FanMedium, "fan-medium");
[[gnu::unused]] PROGMEM_STRING(FanHigh, "fan-high");
PROGMEM_STRING(TerminalCommand, "term-cmd");
static constexpr Enumeration<ButtonAction> ButtonActionOptions[] PROGMEM {
{ButtonAction::None, None},
#if RELAY_SUPPORT
@ -204,6 +211,9 @@ static constexpr Enumeration<ButtonAction> ButtonActionOptions[] PROGMEM {
{ButtonAction::FanMedium, FanMedium},
{ButtonAction::FanHigh, FanHigh},
#endif
#if TERMINAL_SUPPORT
{ButtonAction::TerminalCommand, TerminalCommand},
#endif
};
} // namespace
@ -733,6 +743,12 @@ int analogLevel(size_t index) {
}
#endif
#if TERMINAL_SUPPORT
String terminalCommand(size_t index) {
return getSetting({keys::TerminalCommand, index});
}
#endif
} // namespace
namespace query {
@ -801,6 +817,9 @@ static constexpr espurna::settings::query::IndexedSetting IndexedSettings[] PROG
{keys::MqttSendAll, internal::mqttSendAllEvents},
{keys::MqttRetain, internal::mqttRetain},
#endif
#if TERMINAL_SUPPORT
{keys::TerminalCommand, settings::terminalCommand},
#endif
};
bool checkSamePrefix(StringView key) {
@ -824,6 +843,31 @@ void setup() {
} // namespace settings
namespace terminal {
namespace internal {
void inject(String command) {
if (!command.endsWith("\r\n") && !command.endsWith("\n")) {
command.concat('\n');
}
static EphemeralPrint output;
PrintString error(64);
if (!espurna::terminal::api_find_and_call(command, output, error)) {
DEBUG_MSG_P(PSTR("[BUTTON] \"%s\"\n"), error.c_str());
}
}
} // namespace internal
void process(size_t id) {
auto cmd = settings::terminalCommand(id);
if (!cmd.length()) {
return;
}
internal::inject(std::move(cmd));
}
void button(::terminal::CommandContext&& ctx) {
if (ctx.argv.size() == 2) {
@ -854,6 +898,10 @@ static constexpr ::terminal::Command Commands[] PROGMEM {
{Button, button},
};
void setup() {
espurna::terminal::add(Commands);
}
} // namespace terminal
} // namespace button
} // namespace espurna
@ -1181,6 +1229,11 @@ void buttonEvent(size_t id, ButtonEvent event) {
#endif
break;
case ButtonAction::TerminalCommand:
#if TERMINAL_SUPPORT
espurna::button::terminal::process(id);
#endif
case ButtonAction::None:
break;
@ -1495,7 +1548,7 @@ void buttonSetup() {
DEBUG_MSG_P(PSTR("[BUTTON] Number of buttons: %u\n"), count);
#if TERMINAL_SUPPORT
espurna::terminal::add(espurna::button::terminal::Commands);
espurna::button::terminal::setup();
#endif
if (count) {


+ 1
- 0
code/espurna/button.h View File

@ -48,6 +48,7 @@ enum class ButtonAction {
FanLow,
FanMedium,
FanHigh,
TerminalCommand,
};
using ButtonEventHandler = void(*)(size_t id, ButtonEvent event);


+ 18
- 17
code/espurna/config/types.h View File

@ -17,23 +17,24 @@
// BUTTONS
//------------------------------------------------------------------------------
#define BUTTON_ACTION_NONE ButtonAction::None
#define BUTTON_ACTION_TOGGLE ButtonAction::Toggle
#define BUTTON_ACTION_ON ButtonAction::On
#define BUTTON_ACTION_OFF ButtonAction::Off
#define BUTTON_ACTION_AP ButtonAction::AccessPoint
#define BUTTON_ACTION_RESET ButtonAction::Reset
#define BUTTON_ACTION_PULSE ButtonAction::Pulse
#define BUTTON_ACTION_FACTORY ButtonAction::FactoryReset
#define BUTTON_ACTION_WPS ButtonAction::Wps
#define BUTTON_ACTION_SMART_CONFIG ButtonAction::SmartConfig
#define BUTTON_ACTION_DIM_UP ButtonAction::BrightnessIncrease
#define BUTTON_ACTION_DIM_DOWN ButtonAction::BrightnessDecrease
#define BUTTON_ACTION_DISPLAY_ON ButtonAction::DisplayOn
#define BUTTON_ACTION_CUSTOM ButtonAction::Custom
#define BUTTON_ACTION_FAN_LOW ButtonAction::FanLow
#define BUTTON_ACTION_FAN_MEDIUM ButtonAction::FanMedium
#define BUTTON_ACTION_FAN_HIGH ButtonAction::FanHigh
#define BUTTON_ACTION_NONE ButtonAction::None
#define BUTTON_ACTION_TOGGLE ButtonAction::Toggle
#define BUTTON_ACTION_ON ButtonAction::On
#define BUTTON_ACTION_OFF ButtonAction::Off
#define BUTTON_ACTION_AP ButtonAction::AccessPoint
#define BUTTON_ACTION_RESET ButtonAction::Reset
#define BUTTON_ACTION_PULSE ButtonAction::Pulse
#define BUTTON_ACTION_FACTORY ButtonAction::FactoryReset
#define BUTTON_ACTION_WPS ButtonAction::Wps
#define BUTTON_ACTION_SMART_CONFIG ButtonAction::SmartConfig
#define BUTTON_ACTION_DIM_UP ButtonAction::BrightnessIncrease
#define BUTTON_ACTION_DIM_DOWN ButtonAction::BrightnessDecrease
#define BUTTON_ACTION_DISPLAY_ON ButtonAction::DisplayOn
#define BUTTON_ACTION_CUSTOM ButtonAction::Custom
#define BUTTON_ACTION_FAN_LOW ButtonAction::FanLow
#define BUTTON_ACTION_FAN_MEDIUM ButtonAction::FanMedium
#define BUTTON_ACTION_FAN_HIGH ButtonAction::FanHigh
#define BUTTON_ACTION_TERMINAL_COMMAND ButtonAction::TerminalCommand
// Deprecated: legacy mapping, changed to action from above
#define BUTTON_MODE_NONE BUTTON_ACTION_NONE


+ 6
- 12
code/espurna/ir.cpp View File

@ -29,6 +29,9 @@ $ pio run -e ... \
#include "relay.h"
#include "terminal.h"
#include "libs/EphemeralPrint.h"
#include "libs/PrintString.h"
#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <IRsend.h>
@ -1518,24 +1521,15 @@ Preset preset() {
namespace internal {
struct EphemeralPrint : public Print {
size_t write(uint8_t) override {
return 0;
}
size_t write(const uint8_t*, size_t) override {
return 0;
}
};
void inject(String command) {
if (!command.endsWith("\r\n") && !command.endsWith("\n")) {
command.concat('\n');
}
static EphemeralPrint output;
if (!espurna::terminal::api_find_and_call(command, output)) {
DEBUG_MSG_P(PSTR("[IR] Failed to execute command: \"%s\"\n"), command.c_str());
PrintString error(64);
if (!espurna::terminal::api_find_and_call(command, output, error)) {
DEBUG_MSG_P(PSTR("[IR] \"%s\"\n"), error.c_str());
}
}


+ 22
- 0
code/espurna/libs/EphemeralPrint.h View File

@ -0,0 +1,22 @@
/*
Arduino Print without any buffer.
*/
#pragma once
#include <Arduino.h>
#include <cstdint>
#include <cstddef>
struct EphemeralPrint : public Print {
size_t write(uint8_t) override {
return 0;
}
size_t write(const uint8_t*, size_t) override {
return 0;
}
};

Loading…
Cancel
Save