OMOTE/Platformio/src/commandHandler.cpp
2024-01-29 10:31:45 +01:00

167 lines
5.8 KiB
C++

#include <string>
#include <sstream>
#include "hardware/infrared_sender.h"
#include "hardware/mqtt.h"
#include "device_samsungTV/device_samsungTV.h"
#include "device_yamahaAmp/device_yamahaAmp.h"
#include "device_keyboard_mqtt/device_keyboard_mqtt.h"
#include "device_keyboard_ble/device_keyboard_ble.h"
#include "commandHandler.h"
#include "scenes/sceneHandler.h"
std::map<std::string, commandData> commands;
commandData makeCommandData(commandHandlers a, std::list<std::string> b) {
commandData c = {a, b};
return c;
}
void register_specialCommands() {
// put SPECIAL commands here if you want
commands[MY_SPECIAL_COMMAND] = makeCommandData(SPECIAL, {""});
}
void executeCommandWithData(std::string command, commandData commandData, std::string additionalPayload = "") {
switch (commandData.commandHandler) {
case IR_GC: {
auto current = commandData.commandPayloads.begin();
std::string arrayStr = *current;
// first create array of needed size
std::string::difference_type size = std::count(arrayStr.begin(), arrayStr.end(), ',');
size += 1;
uint16_t *buf = new uint16_t[size];
// now get comma separated values and fill array
int pos = 0;
std::stringstream ss(arrayStr);
while(ss.good()) {
std::string dataStr;
std::getline(ss, dataStr, ',');
// https://cplusplus.com/reference/string/stoull/
std::string::size_type sz = 0; // alias of size_t
const uint64_t data = std::stoull(dataStr, &sz, 0);
// Serial.printf(" next string value %s (%" PRIu64 ")\r\n", dataStr.c_str(), data);
buf[pos] = data;
pos += 1;
}
Serial.printf("execute: will send IR GC, array size %d\r\n", size);
IrSender.sendGC(buf, size);
delete [] buf;
break;
}
case IR_NEC: {
auto current = commandData.commandPayloads.begin();
std::string dataStr = *current;
// https://cplusplus.com/reference/string/stoull/
std::string::size_type sz = 0; // alias of size_t
const uint64_t data = std::stoull(dataStr, &sz, 0);
Serial.printf("execute: will send IR NEC, data %s (%" PRIu64 ")\r\n", dataStr.c_str(), data);
IrSender.sendNEC(data);
break;
}
case IR_SAMSUNG: {
auto current = commandData.commandPayloads.begin();
std::string dataStr = *current;
// https://cplusplus.com/reference/string/stoull/
std::string::size_type sz = 0; // alias of size_t
const uint64_t data = std::stoull(dataStr, &sz, 0);
Serial.printf("execute: will send IR SAMSUNG, data %s (%" PRIu64 ")\r\n", dataStr.c_str(), data);
IrSender.sendSAMSUNG(data);
break;
}
case IR_SONY: {
std::string::size_type sz = 0; // alias of size_t
uint64_t data;
if (commandData.commandPayloads.empty() && (additionalPayload == "")) {
Serial.printf("execute: cannot send IR SONY, because both data and payload are empty\r\n");
} else {
if (additionalPayload != "") {
data = std::stoull(additionalPayload, &sz, 0);
} else {
auto current = commandData.commandPayloads.begin();
data = std::stoull(*current, &sz, 0);
}
Serial.printf("execute: will send IR SONY, data (%" PRIu64 ")\r\n", data);
IrSender.sendSony(data, 15);
}
break;
}
case IR_RC5: {
std::string::size_type sz = 0; // alias of size_t
uint64_t data;
if (commandData.commandPayloads.empty() && (additionalPayload == "")) {
Serial.printf("execute: cannot send IR RC5, because both data and payload are empty\r\n");
} else {
if (additionalPayload != "") {
data = std::stoull(additionalPayload, &sz, 0);
} else {
auto current = commandData.commandPayloads.begin();
data = std::stoull(*current, &sz, 0);
}
Serial.printf("execute: will send IR RC5, data (%" PRIu64 ")\r\n", data);
IrSender.sendRC5(IrSender.encodeRC5X(0x00, data));
}
break;
}
#ifdef ENABLE_WIFI_AND_MQTT
case MQTT: {
auto current = commandData.commandPayloads.begin();
std::string topic = *current;
std::string payload;
if (additionalPayload == "") {
current = std::next(current, 1);
payload = *current;
} else {
payload = additionalPayload;
}
Serial.printf("execute: will send MQTT, topic '%s', payload '%s'\r\n", topic.c_str(), payload.c_str());
publishMQTTMessage(topic.c_str(), payload.c_str());
break;
}
#endif
#ifdef ENABLE_KEYBOARD_BLE
case BLE_KEYBOARD: {
auto current = commandData.commandPayloads.begin();
std::string command = *current;
std::string payload = "";
if (additionalPayload != "") {
payload = additionalPayload;
}
Serial.printf("execute: will send BLE keyboard command, command '%s', payload '%s'\r\n", command.c_str(), payload.c_str());
keyboard_ble_executeCommand(command, payload);
break;
}
#endif
case SCENE: {
// let the sceneHandler do the scene stuff
Serial.printf("execute: will send scene command to the sceneHandler\r\n");
handleScene(command, commandData, additionalPayload);
break;
}
case SPECIAL: {
if (command == MY_SPECIAL_COMMAND) {
// do your special command here
Serial.printf("execute: could execute a special command here, if you define one\r\n");
}
break;
}
}
}
void executeCommand(std::string command, std::string additionalPayload) {
if (commands.count(command) > 0) {
Serial.printf("command: will execute command '%s'\r\n", command.c_str());
executeCommandWithData(command, commands[command], additionalPayload);
} else {
Serial.printf("command: command '%s' not found\r\n", command.c_str());
}
}