/* extern WiFiClient wifi_client; extern PubSubClient mqtt_client; */ namespace diller { namespace core { using diller::utils::tty_status; using diller::utils::property; class esp_wifi { public: static auto macAddress() -> decltype(WiFi.macAddress()) { return WiFi.macAddress(); } static auto status() -> decltype(WiFi.status()) { return WiFi.status(); } }; // core::core template core::core(const String &mqtt_host, int mqtt_port) : mqtt_host(mqtt_host), mqtt_port(mqtt_port), property_action_listener_(nullptr) { mac = esp_wifi::macAddress(); mac.toLowerCase(); client_id = "diller-" + mac; } template void core::callback(char* topic_, byte* payload, unsigned int length) { Serial.print("got message on "); Serial.println(topic_); Serial.println("payload"); Serial.write(payload, length); Serial.println(); String prefix = "/diller/" + mac + "/property/"; String topic(topic_); if (!topic.startsWith(prefix)) { Serial.print("debug bad-prefix: "); Serial.println(topic); return; } topic.remove(0, prefix.length()); property *p = nullptr; for (auto i = 0; i < properties.size(); i++) { auto *x = properties[i]; if (topic.startsWith(x->id())) { p = x; break; } } if (p) { topic.remove(0, p->id().length() + 1); Serial.print("debug property="); Serial.print(p->id()); Serial.print(", topic="); Serial.println(topic); property_action a; if (topic == "value") { Serial.println("debug action=value"); a = property_action::VALUE; } else if (topic == "name") { Serial.println("debug action=name"); a = property_action::NAME; } else if (topic == "description") { Serial.println("debug action=description"); a = property_action::DESCRIPTION; } else { return; } if (property_action_listener_) { property_action_listener_->on_property_action(p, a); } } else { Serial.print("debug unknown-property"); } } template bool core::connected() const { return mqtt_client.connected(); } template void core::setup() { mqtt_client.setServer(mqtt_host.c_str(), mqtt_port); mqtt_client.setCallback([this](char* topic_, byte* payload, unsigned int length) { callback(topic_, payload, length); }); } template void core::loop() { auto wl_status = esp_wifi::status(); if (wl_status == WL_CONNECTED) { if (!mqtt_client.loop()) { Serial.println("status mqtt=connecting"); if (mqtt_client.connect(client_id.c_str())) { Serial.println("status mqtt=connected"); } else { Serial.println("status mqtt=disconnected"); } } } } template diller_error core::cmd_property(const char *id, const char *value, const char *name) { if (!id) { return diller_error::INVAL; } auto p = properties.find(id); if (!p) { return diller_error::NOMEM; } if (value) { String topic = "/diller/" + mac + "/property/" + id + "/value"; mqtt_client.publish(topic.c_str(), value); } if (name) { String topic = "/diller/" + mac + "/property/" + id + "/name"; mqtt_client.publish(topic.c_str(), name); } if (p->is_new()) { String topic = "/diller/" + mac + "/property/" + id + "/#"; mqtt_client.subscribe(topic.c_str()); Serial.print("debug subscribing="); Serial.println(topic); p->set_old(); } return diller_error::OK; } template void core::set_property_action_listener(property_action_listener *l) { this->property_action_listener_ = l; } } // namespace core } // namespace diller