62 lines
2.0 KiB
C++
62 lines
2.0 KiB
C++
#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, "stopped", -1, -1};
|
|
for (size_t i = 0; i < shadeConfiguredCallbacks.size(); i++) {
|
|
shadeConfiguredCallbacks[i](shade);
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
} |