#include "AlexaDevice.h" #include "AlexaLog.h" AlexaDevice::AlexaDevice(const String& name, const String& rootTopic, const String& endpointId, AlexaTransport* transport) : name(name), endpointId(endpointId), rootTopic(rootTopic), transport(transport) { // Initialize event arrays to nullptr for (int i = 0; i < MAX_EVENTS; ++i) { eventNames[i] = nullptr; // Set all event names to nullptr eventCallbacks[i] = nullptr; // Set all callbacks to nullptr } } // Setters and Getters void AlexaDevice::setName(const String& name) { this->name = name; } String AlexaDevice::getName() const { return name; } String AlexaDevice::getEndpointId() const { return endpointId; } bool AlexaDevice::hasEndpointId(const char* id, size_t length) const { return id != nullptr && endpointId.length() == length && memcmp(endpointId.c_str(), id, length) == 0; } DisplayCategory AlexaDevice::getDisplayCategory() const { return displayCategory; } void AlexaDevice::setDisplayCategory(DisplayCategory category) { displayCategory = category; } String AlexaDevice::getDescription() const { return description; } void AlexaDevice::setDescription(const String& description) { this->description = description; } String AlexaDevice::getManufacturerName() const { return manufacturerName; } void AlexaDevice::setManufacturerName(const String& manufacturerName) { this->manufacturerName = manufacturerName; } String AlexaDevice::getManufacturer() const { return manufacturer; } void AlexaDevice::setManufacturer(const String& manufacturer) { this->manufacturer = manufacturer; } String AlexaDevice::getModel() const { return model; } void AlexaDevice::setModel(const String& model) { this->model = model; } String AlexaDevice::getSoftwareVersion() const { return softwareVersion; } AlexaInterface* AlexaDevice::addCapability(AlexaInterfaceType type) { // Check if a interface with the given type already exists for (auto& iface : capabilities) { if (iface.getType() == type) { return &iface; // Return the existing interface } } // If the interface doesn't exist, create a new one capabilities.emplace_back(type); ALEX2ESP_LOGI("%s: capability %s added", endpointId.c_str(), capabilities.back().getTypeString().c_str()); // Return a pointer to the newly created device return &capabilities.back(); } JsonDocument AlexaDevice::getDeviceJSON() const { JsonDocument json; // Main device attributes json["endpointId"] = endpointId; json["friendlyName"] = name; json["description"] = description; json["manufacturerName"] = manufacturerName; JsonArray displayCategories = json["displayCategories"].to(); displayCategories.add(DisplayCategoryUtils::toString(displayCategory)); JsonObject additionalAttributes = json["additionalAttributes"].to(); additionalAttributes["manufacturer"] = manufacturer; additionalAttributes["model"] = model; additionalAttributes["serialNumber"] = "ESP2Alex"; additionalAttributes["firmwareVersion"] = "1.1.0"; additionalAttributes["softwareVersion"] = softwareVersion; additionalAttributes["customIdentifier"] = "ESP2Alex"; JsonArray capabilitiesArray = json["capabilities"].to(); for (const AlexaInterface& capability : capabilities) { capabilitiesArray.add(capability.getJSON().as()); } // capabilitiesArray.add(capability.getJSON().as()); return json; } // void AlexaDevice::registerEvent(const String& eventName, std::function callback) { // eventCallbacks[eventName] = callback; // } // void AlexaDevice::triggerEvent(const String& eventName, const JsonDocument& directive,const AlexaInterfaceType& type) const { // auto it = eventCallbacks.find(eventName); // if (it != eventCallbacks.end()) { // // Call the registered callback function // it->second(directive,type); // } else { // Serial.print("No event registered for: "); // Serial.println(eventName); // } // } // Register an event callback function void AlexaDevice::registerEvent(const char* eventName, void (*callback)(const JsonDocument&, const AlexaInterfaceType&)) { for (int i = 0; i < MAX_EVENTS; ++i) { // Find an empty slot for the new event if (eventNames[i] == nullptr) { eventNames[i] = eventName; // Store the event name eventCallbacks[i] = callback; // Store the callback function break; } } } // Trigger the event and invoke the corresponding callback void AlexaDevice::triggerEvent(const char* eventName, const JsonDocument& directive, const AlexaInterfaceType& type, bool warnIfMissing) const { for (int i = 0; i < MAX_EVENTS; ++i) { if (eventNames[i] != nullptr && strcmp(eventNames[i], eventName) == 0) { // Found the event name, call the corresponding callback function eventCallbacks[i](directive, type); return; } } // No handler: the directive goes unanswered, which Alexa reports as a device that does not respond if (warnIfMissing) { ALEX2ESP_LOGE("%s: no handler registered for %s, directive not handled", endpointId.c_str(), eventName); } }