spejsiot/spejsiot/SpejsNode.cpp

181 lines
4.6 KiB
C++
Raw Normal View History

2016-06-29 15:00:22 +00:00
#include <SpejsNode.h>
void SpejsNode::init() {
deviceID = WifiStation.getMAC().substring(6, 12);
2016-08-30 19:24:34 +00:00
currentSlot = 0;
if(!rboot_get_last_boot_rom(&currentSlot)) {
currentSlot = rboot_get_current_rom();
}
2016-06-29 15:00:22 +00:00
Serial.begin(115200);
Serial.systemDebugOutput(false); // Debug output to serial
2016-08-30 19:24:34 +00:00
Serial.print("*** SpejsNode init, running on:");
Serial.print(deviceID);
Serial.printf(", current rom: %d\r\n", currentSlot);
2016-06-29 15:00:22 +00:00
WifiStation.config(WIFI_SSID, WIFI_PWD);
WifiStation.enable(true);
WifiAccessPoint.enable(false);
WifiStation.waitConnection(
ConnectionDelegate(&SpejsNode::onConnected, this),
20, *[] {
Serial.println("Connection failed");
});
2016-08-30 19:24:34 +00:00
inputs["control"] = MqttStringSubscriptionCallback(&SpejsNode::controlHandler, this);
2016-06-29 15:00:22 +00:00
}
void SpejsNode::keepAliveHandler() {
if(mqtt.getConnectionState() != eTCS_Connected) {
Serial.println("Reconnecting");
onConnected();
2016-08-30 19:24:34 +00:00
} else {
uint8_t mode;
if(rboot_get_last_boot_mode(&mode)) {
if(mode == MODE_TEMP_ROM) {
rboot_set_current_rom(currentSlot);
Serial.println("Successfuly connected, accepting temp rom");
} else {
Serial.printf("Not a TEMP ROM boot: %d\r\n", mode);
}
} else {
Serial.println("No boot mode info");
}
2016-06-29 15:00:22 +00:00
}
}
void SpejsNode::onConnected() {
Serial.println("Connection successful");
2016-09-10 23:46:42 +00:00
2016-06-29 15:00:22 +00:00
mqtt.setWill(TOPIC_PREFIX + deviceID + "/state", "offline", 1, true);
2016-09-10 23:46:42 +00:00
#ifdef ENABLE_SSL
const uint8_t sha1Fingerprint[] = SSL_FINGERPRINT;
mqtt.connect("iot-" + deviceID, "", "", true);
mqtt.addSslOptions(SSL_SERVER_VERIFY_LATER);
mqtt.setSslFingerprint(sha1Fingerprint, 20);
#else
2016-06-29 15:00:22 +00:00
mqtt.connect("iot-" + deviceID);
2016-09-10 23:46:42 +00:00
#endif
2016-06-29 15:00:22 +00:00
mqtt.subscribe(TOPIC_PREFIX + deviceID + "/control");
for(unsigned int i = 0 ; i < inputs.count() ; i++) {
2016-09-10 23:46:42 +00:00
mqtt.subscribe(TOPIC_PREFIX + deviceID + "/" + inputs.keyAt(i));
2016-06-29 15:00:22 +00:00
}
mqtt.publish(TOPIC_PREFIX + deviceID + "/state", "online");
mqtt.publish(TOPIC_PREFIX + deviceID + "/type", deviceType);
keepaliveTimer.initializeMs(10000, TimerDelegate(&SpejsNode::keepAliveHandler, this)).start();
}
bool SpejsNode::notify(String key, String value) {
if(mqtt.getConnectionState() == eTCS_Connected) {
mqtt.publish("iot/" + deviceID + "/" + key, value);
return true;
}
return false;
}
2016-08-30 19:24:34 +00:00
void SpejsNode::registerInput(String key, MqttStringSubscriptionCallback callback) {
2016-06-29 15:00:22 +00:00
inputs[key] = callback;
}
2016-08-30 19:24:34 +00:00
void SpejsNode::mqttCallback(String origtopic, String value) {
2016-06-29 15:00:22 +00:00
String devicePrefix = TOPIC_PREFIX + deviceID;
2016-09-10 23:46:42 +00:00
2016-08-30 19:24:34 +00:00
if(!origtopic.startsWith(devicePrefix)) {
2016-09-10 23:46:42 +00:00
Serial.println("ignoring");
return;
2016-06-29 15:00:22 +00:00
}
2016-08-30 19:24:34 +00:00
String topic = origtopic.substring(devicePrefix.length() + 1);
2016-06-29 15:00:22 +00:00
Serial.println(topic);
Serial.println(value);
if(inputs.contains(topic)) {
2016-09-10 23:46:42 +00:00
inputs[topic](origtopic, value);
2016-08-30 19:24:34 +00:00
} else {
2016-09-10 23:46:42 +00:00
Serial.println("unknown topic?");
2016-08-30 19:24:34 +00:00
}
}
void SpejsNode::controlHandler(String key, String value) {
Serial.println("Control command: " + value);
if(value == "ota") {
2016-09-10 23:46:42 +00:00
startOTA();
2016-08-30 19:24:34 +00:00
} else if(value == "restart") {
2016-09-10 23:46:42 +00:00
System.restart();
2016-08-30 19:24:34 +00:00
} else {
2016-09-10 23:46:42 +00:00
Serial.println("Invalid command");
2016-08-30 19:24:34 +00:00
}
}
void SpejsNode::startOTA() {
uint8_t slot;
rboot_config bootconf;
String romURL = OTA_URL + deviceID + "/rom0.bin";
String spiffsURL = OTA_URL + deviceID + "/spiff_rom.bin";
Serial.println("Updating...");
// need a clean object, otherwise if run before and failed will not run again
if (otaUpdater) delete otaUpdater;
otaUpdater = new rBootHttpUpdate();
bootconf = rboot_get_config();
if (currentSlot == 0)
2016-09-10 23:46:42 +00:00
slot = 1;
2016-08-30 19:24:34 +00:00
else
2016-09-10 23:46:42 +00:00
slot = 0;
2016-08-30 19:24:34 +00:00
Serial.printf("Updating to rom %d.\r\n", slot);
// flash rom to position indicated in the rBoot config rom table
otaUpdater->addItem(bootconf.roms[slot], romURL);
#ifndef DISABLE_SPIFFS
// use user supplied values (defaults for 4mb flash in makefile)
if (slot == 0) {
otaUpdater->addItem(RBOOT_SPIFFS_0, spiffsURL);
} else {
otaUpdater->addItem(RBOOT_SPIFFS_1, spiffsURL);
}
#endif
otaUpdater->setCallback(otaUpdateDelegate(&SpejsNode::otaUpdateCallback, this));
otaUpdater->start();
2016-09-10 23:46:42 +00:00
2016-08-30 19:24:34 +00:00
notify("ota", "started");
}
2016-09-10 23:46:42 +00:00
void SpejsNode::otaUpdateCallback(rBootHttpUpdate& updater, bool result) {
2016-08-30 19:24:34 +00:00
if(result == true) {
// success
notify("ota", "finished");
uint8 slot;
if (currentSlot == 0)
2016-09-10 23:46:42 +00:00
slot = 1;
2016-08-30 19:24:34 +00:00
else
2016-09-10 23:46:42 +00:00
slot = 0;
2016-08-30 19:24:34 +00:00
// set to boot new rom and then reboot
Serial.printf("Firmware updated, rebooting to rom %d...\r\n", slot);
rboot_set_temp_rom(slot);
System.restart();
2016-06-29 15:00:22 +00:00
} else {
2016-08-30 19:24:34 +00:00
notify("ota", "failed");
2016-06-29 15:00:22 +00:00
}
}