Configure shades via MQTT messages

This commit is contained in:
2024-05-04 23:08:21 +10:00
parent 0458c70b47
commit e8003772ef
4 changed files with 261 additions and 16 deletions

View File

@@ -0,0 +1,62 @@
#include "Configurator.h"
#include <cctype>
Configurator::Configurator() {
// TODO: Should be using MQTT directly here (and methods for handling methods should be private)
}
std::string Configurator::extractKey(std::string topic) {
int startIndex = topic.find("/") + 1;
int endIndex = topic.find("/", startIndex);
// TODO: need to verify that startIndex and endIndex are valid before substr()
return topic.substr(startIndex, endIndex - startIndex);
}
void Configurator::processIdMessage(std::string topic, std::string payload) {
auto key = extractKey(topic);
if (payload.length() != 4) {
// Ignore payloads that aren't exactly 4 characters
return;
}
uint16_t id = 0;
for (char c : payload) {
// Check if valid hex digit (0-9, A-F, a-f)
if (!std::isxdigit(c)) {
return; // Invalid character, not a hex digit
}
// Convert hex digit to numerical value (0-9, A-B=10-11, ...)
int digit = std::toupper(c) - (c <= '9' ? '0' : 'A' - 10);
id = (id << 4) | digit;
}
discoveredIds[key] = id;
tryBuild(key);
}
void Configurator::processFriendlyNameMessage(std::string topic, std::string friendlyName) {
auto key = extractKey(topic);
discoveredFriendlyNames[key] = friendlyName;
tryBuild(key);
}
void Configurator::addShadeConfiguredCallback(std::function<void (Shade)> callback) {
shadeConfiguredCallbacks.push_back(callback);
}
bool Configurator::tryBuild(std::string key) {
if (auto id = discoveredIds.find(key); id != discoveredIds.end()) {
if (auto friendlyName = discoveredFriendlyNames.find(key); friendlyName != discoveredFriendlyNames.end()) {
auto shade = Shade{id->second, key, friendlyName->second, -1, -1, 0, 0, nullptr};
for (size_t i = 0; i < shadeConfiguredCallbacks.size(); i++) {
shadeConfiguredCallbacks[i](shade);
}
return true;
}
}
return false;
}

View File

@@ -0,0 +1,30 @@
#ifndef CONFIGURATOR_H
#define CONFIGURATOR_H
#include <vector>
#include <map>
#include <functional>
#include "Shade.h"
// TODO: Allow shades to be removed
class Configurator
{
private:
std::vector<std::function<void (Shade)>> shadeConfiguredCallbacks;
std::map<std::string, uint16_t> discoveredIds;
std::map<std::string, std::string> discoveredFriendlyNames;
std::string extractKey(std::string topic);
bool tryBuild(std::string topic);
public:
Configurator();
void addShadeConfiguredCallback(std::function<void (Shade)> callback);
void processIdMessage(std::string topic, std::string id);
void processFriendlyNameMessage(std::string topic, std::string friendlyName);
};
#endif // CONFIGURATOR_H