Stream all responses. Fix missing ETH IP address #310

This commit is contained in:
Robert Strouse 2024-04-09 13:46:51 -07:00
parent 6ba354c7ff
commit 026f9315b1
19 changed files with 1361 additions and 456 deletions

View file

@ -85,6 +85,20 @@ bool appver_t::toJSON(JsonObject &obj) {
obj["suffix"] = this->suffix; obj["suffix"] = this->suffix;
return true; return true;
} }
void appver_t::toJSON(JsonResponse &json) {
json.addElem("name", this->name);
json.addElem("major", this->major);
json.addElem("minor", this->minor);
json.addElem("build", this->build);
json.addElem("suffix", this->suffix);
}
void appver_t::toJSON(JsonSockEvent *json) {
json->addElem("name", this->name);
json->addElem("major", this->major);
json->addElem("minor", this->minor);
json->addElem("build", this->build);
json->addElem("suffix", this->suffix);
}
bool BaseSettings::load() { return true; } bool BaseSettings::load() { return true; }
bool BaseSettings::loadFile(const char *filename) { bool BaseSettings::loadFile(const char *filename) {
@ -235,6 +249,14 @@ bool ConfigSettings::toJSON(JsonObject &obj) {
obj["checkForUpdate"] = this->checkForUpdate; obj["checkForUpdate"] = this->checkForUpdate;
return true; return true;
} }
void ConfigSettings::toJSON(JsonResponse &json) {
json.addElem("ssdpBroadcast", this->ssdpBroadcast);
json.addElem("hostname", this->hostname);
json.addElem("connType", static_cast<uint8_t>(this->connType));
json.addElem("chipModel", this->chipModel);
json.addElem("checkForUpdate", this->checkForUpdate);
}
bool ConfigSettings::requiresAuth() { return this->Security.type != security_types::None; } bool ConfigSettings::requiresAuth() { return this->Security.type != security_types::None; }
bool ConfigSettings::fromJSON(JsonObject &obj) { bool ConfigSettings::fromJSON(JsonObject &obj) {
if(obj.containsKey("ssdpBroadcast")) this->ssdpBroadcast = obj["ssdpBroadcast"]; if(obj.containsKey("ssdpBroadcast")) this->ssdpBroadcast = obj["ssdpBroadcast"];
@ -286,6 +308,18 @@ bool MQTTSettings::begin() {
this->load(); this->load();
return true; return true;
} }
void MQTTSettings::toJSON(JsonResponse &json) {
json.addElem("enabled", this->enabled);
json.addElem("pubDisco", this->pubDisco);
json.addElem("protocol", this->protocol);
json.addElem("hostname", this->hostname);
json.addElem("port", this->port);
json.addElem("username", this->username);
json.addElem("password", this->password);
json.addElem("rootTopic", this->rootTopic);
json.addElem("discoTopic", this->discoTopic);
}
bool MQTTSettings::toJSON(JsonObject &obj) { bool MQTTSettings::toJSON(JsonObject &obj) {
obj["enabled"] = this->enabled; obj["enabled"] = this->enabled;
obj["pubDisco"] = this->pubDisco; obj["pubDisco"] = this->pubDisco;
@ -384,6 +418,11 @@ bool NTPSettings::fromJSON(JsonObject &obj) {
this->parseValueString(obj, "posixZone", this->posixZone, sizeof(this->posixZone)); this->parseValueString(obj, "posixZone", this->posixZone, sizeof(this->posixZone));
return true; return true;
} }
void NTPSettings::toJSON(JsonResponse &json) {
json.addElem("ntpServer", this->ntpServer);
json.addElem("posixZone", this->posixZone);
}
bool NTPSettings::toJSON(JsonObject &obj) { bool NTPSettings::toJSON(JsonObject &obj) {
obj["ntpServer"] = this->ntpServer; obj["ntpServer"] = this->ntpServer;
obj["posixZone"] = this->posixZone; obj["posixZone"] = this->posixZone;
@ -420,6 +459,16 @@ bool IPSettings::toJSON(JsonObject &obj) {
obj["dns2"] = this->dns2 == ipEmpty ? "" : this->dns2.toString(); obj["dns2"] = this->dns2 == ipEmpty ? "" : this->dns2.toString();
return true; return true;
} }
void IPSettings::toJSON(JsonResponse &json) {
IPAddress ipEmpty(0,0,0,0);
json.addElem("dhcp", this->dhcp);
json.addElem("ip", this->ip.toString().c_str());
json.addElem("gateway", this->gateway.toString().c_str());
json.addElem("subnet", this->subnet.toString().c_str());
json.addElem("dns1", this->dns1.toString().c_str());
json.addElem("dns2", this->dns2.toString().c_str());
}
bool IPSettings::save() { bool IPSettings::save() {
pref.begin("IP"); pref.begin("IP");
pref.clear(); pref.clear();
@ -480,6 +529,14 @@ bool SecuritySettings::toJSON(JsonObject &obj) {
obj["permissions"] = this->permissions; obj["permissions"] = this->permissions;
return true; return true;
} }
void SecuritySettings::toJSON(JsonResponse &json) {
json.addElem("type", static_cast<uint8_t>(this->type));
json.addElem("username", this->username);
json.addElem("password", this->password);
json.addElem("pin", this->pin);
json.addElem("permissions", this->permissions);
}
bool SecuritySettings::save() { bool SecuritySettings::save() {
pref.begin("SEC"); pref.begin("SEC");
pref.clear(); pref.clear();
@ -531,6 +588,12 @@ bool WifiSettings::toJSON(JsonObject &obj) {
obj["roaming"] = this->roaming; obj["roaming"] = this->roaming;
return true; return true;
} }
void WifiSettings::toJSON(JsonResponse &json) {
json.addElem("ssid", this->ssid);
json.addElem("passphrase", this->passphrase);
json.addElem("roaming", this->roaming);
}
bool WifiSettings::save() { bool WifiSettings::save() {
pref.begin("WIFI"); pref.begin("WIFI");
pref.clear(); pref.clear();
@ -628,6 +691,16 @@ bool EthernetSettings::toJSON(JsonObject &obj) {
obj["MDIOPin"] = this->MDIOPin; obj["MDIOPin"] = this->MDIOPin;
return true; return true;
} }
void EthernetSettings::toJSON(JsonResponse &json) {
json.addElem("boardType", this->boardType);
json.addElem("phyAddress", this->phyAddress);
json.addElem("CLKMode", static_cast<uint8_t>(this->CLKMode));
json.addElem("phyType", static_cast<uint8_t>(this->phyType));
json.addElem("PWRPin", this->PWRPin);
json.addElem("MDCPin", this->MDCPin);
json.addElem("MDIOPin", this->MDIOPin);
}
bool EthernetSettings::usesPin(uint8_t pin) { bool EthernetSettings::usesPin(uint8_t pin) {
if((this->CLKMode == 0 || this->CLKMode == 1) && pin == 0) return true; if((this->CLKMode == 0 || this->CLKMode == 1) && pin == 0) return true;
else if(this->CLKMode == 2 && pin == 16) return true; else if(this->CLKMode == 2 && pin == 16) return true;

View file

@ -2,7 +2,7 @@
#include <ETH.h> #include <ETH.h>
#ifndef configsettings_h #ifndef configsettings_h
#define configsettings_h #define configsettings_h
#include "WResp.h"
#define FW_VERSION "v2.4.2" #define FW_VERSION "v2.4.2"
enum DeviceStatus { enum DeviceStatus {
DS_OK = 0, DS_OK = 0,
@ -26,6 +26,8 @@ struct appver_t {
char suffix[4] = ""; char suffix[4] = "";
void parse(const char *ver); void parse(const char *ver);
bool toJSON(JsonObject &obj); bool toJSON(JsonObject &obj);
void toJSON(JsonResponse &json);
void toJSON(JsonSockEvent *json);
int8_t compare(appver_t &ver); int8_t compare(appver_t &ver);
void copy(appver_t &ver); void copy(appver_t &ver);
}; };
@ -36,6 +38,7 @@ class BaseSettings {
bool loadFile(const char* filename); bool loadFile(const char* filename);
bool fromJSON(JsonObject &obj); bool fromJSON(JsonObject &obj);
bool toJSON(JsonObject &obj); bool toJSON(JsonObject &obj);
void toJSON(JsonResponse &json);
bool parseIPAddress(JsonObject &obj, const char *prop, IPAddress *); bool parseIPAddress(JsonObject &obj, const char *prop, IPAddress *);
bool parseValueString(JsonObject &obj, const char *prop, char *dest, size_t size); bool parseValueString(JsonObject &obj, const char *prop, char *dest, size_t size);
int parseValueInt(JsonObject &obj, const char *prop, int defVal); int parseValueInt(JsonObject &obj, const char *prop, int defVal);
@ -50,6 +53,7 @@ class NTPSettings: BaseSettings {
char posixZone[64] = ""; char posixZone[64] = "";
bool fromJSON(JsonObject &obj); bool fromJSON(JsonObject &obj);
bool toJSON(JsonObject &obj); bool toJSON(JsonObject &obj);
void toJSON(JsonResponse &json);
bool apply(); bool apply();
bool begin(); bool begin();
bool save(); bool save();
@ -66,6 +70,7 @@ class WifiSettings: BaseSettings {
bool begin(); bool begin();
bool fromJSON(JsonObject &obj); bool fromJSON(JsonObject &obj);
bool toJSON(JsonObject &obj); bool toJSON(JsonObject &obj);
void toJSON(JsonResponse &json);
String mapEncryptionType(int type); String mapEncryptionType(int type);
bool ssidExists(const char *ssid); bool ssidExists(const char *ssid);
void printNetworks(); void printNetworks();
@ -88,6 +93,7 @@ class EthernetSettings: BaseSettings {
bool begin(); bool begin();
bool fromJSON(JsonObject &obj); bool fromJSON(JsonObject &obj);
bool toJSON(JsonObject &obj); bool toJSON(JsonObject &obj);
void toJSON(JsonResponse &json);
bool load(); bool load();
bool save(); bool save();
void print(); void print();
@ -105,6 +111,7 @@ class IPSettings: BaseSettings {
bool begin(); bool begin();
bool fromJSON(JsonObject &obj); bool fromJSON(JsonObject &obj);
bool toJSON(JsonObject &obj); bool toJSON(JsonObject &obj);
void toJSON(JsonResponse &json);
bool load(); bool load();
bool save(); bool save();
void print(); void print();
@ -129,6 +136,7 @@ class SecuritySettings: BaseSettings {
bool load(); bool load();
void print(); void print();
bool toJSON(JsonObject &obj); bool toJSON(JsonObject &obj);
void toJSON(JsonResponse &json);
bool fromJSON(JsonObject &obj); bool fromJSON(JsonObject &obj);
}; };
class MQTTSettings: BaseSettings { class MQTTSettings: BaseSettings {
@ -146,6 +154,7 @@ class MQTTSettings: BaseSettings {
bool save(); bool save();
bool load(); bool load();
bool toJSON(JsonObject &obj); bool toJSON(JsonObject &obj);
void toJSON(JsonResponse &json);
bool fromJSON(JsonObject &obj); bool fromJSON(JsonObject &obj);
}; };
enum class conn_types : byte { enum class conn_types : byte {
@ -175,6 +184,7 @@ class ConfigSettings: BaseSettings {
bool requiresAuth(); bool requiresAuth();
bool fromJSON(JsonObject &obj); bool fromJSON(JsonObject &obj);
bool toJSON(JsonObject &obj); bool toJSON(JsonObject &obj);
void toJSON(JsonResponse &json);
bool begin(); bool begin();
bool save(); bool save();
bool load(); bool load();

View file

@ -8,6 +8,8 @@
#include "Sockets.h" #include "Sockets.h"
#include "Somfy.h" #include "Somfy.h"
#include "Web.h" #include "Web.h"
#include "WResp.h"
extern ConfigSettings settings; extern ConfigSettings settings;
@ -79,6 +81,20 @@ bool GitRelease::toJSON(JsonObject &obj) {
this->version.toJSON(ver); this->version.toJSON(ver);
return true; return true;
} }
void GitRelease::toJSON(JsonResponse &json) {
Timestamp ts;
json.addElem("id", this->id);
json.addElem("name", this->name);
json.addElem("date", ts.getISOTime(this->releaseDate));
json.addElem("draft", this->draft);
json.addElem("preRelease", this->preRelease);
json.addElem("main", this->main);
json.addElem("hasFS", this->hasFS);
json.addElem("hwVersions", this->hwVersions);
json.beginObject("version");
this->version.toJSON(json);
json.endObject();
}
#define ERR_CLIENT_OFFSET -50 #define ERR_CLIENT_OFFSET -50
int16_t GitRepo::getReleases(uint8_t num) { int16_t GitRepo::getReleases(uint8_t num) {
@ -221,6 +237,22 @@ int16_t GitRepo::getReleases(uint8_t num) {
settings.printAvailHeap(); settings.printAvailHeap();
return 0; return 0;
} }
void GitRepo::toJSON(JsonResponse &json) {
json.beginObject("fwVersion");
settings.fwVersion.toJSON(json);
json.endObject();
json.beginObject("appVersion");
settings.appVersion.toJSON(json);
json.endObject();
json.beginArray("releases");
for(uint8_t i = 0; i < GIT_MAX_RELEASES + 1; i++) {
if(this->releases[i].id == 0) continue;
json.beginObject();
this->releases[i].toJSON(json);
json.endObject();
}
json.endArray();
}
bool GitRepo::toJSON(JsonObject &obj) { bool GitRepo::toJSON(JsonObject &obj) {
JsonObject fw = obj.createNestedObject("fwVersion"); JsonObject fw = obj.createNestedObject("fwVersion");
settings.fwVersion.toJSON(fw); settings.fwVersion.toJSON(fw);
@ -299,6 +331,24 @@ void GitUpdater::setCurrentRelease(GitRepo &repo) {
} }
this->emitUpdateCheck(); this->emitUpdateCheck();
} }
void GitUpdater::toJSON(JsonResponse &json) {
json.addElem("available", this->updateAvailable);
json.addElem("status", this->status);
json.addElem("error", this->error);
json.addElem("cancelled", this->cancelled);
json.addElem("checkForUpdate", settings.checkForUpdate);
json.addElem("inetAvailable", this->inetAvailable);
json.beginObject("fwVersion");
settings.fwVersion.toJSON(json);
json.endObject();
json.beginObject("appVersion");
settings.appVersion.toJSON(json);
json.endObject();
json.beginObject("latest");
this->latest.toJSON(json);
json.endObject();
}
void GitUpdater::toJSON(JsonObject &obj) { void GitUpdater::toJSON(JsonObject &obj) {
obj["available"] = this->updateAvailable; obj["available"] = this->updateAvailable;
obj["status"] = this->status; obj["status"] = this->status;
@ -314,6 +364,26 @@ void GitUpdater::toJSON(JsonObject &obj) {
this->latest.toJSON(latest); this->latest.toJSON(latest);
} }
void GitUpdater::emitUpdateCheck(uint8_t num) { void GitUpdater::emitUpdateCheck(uint8_t num) {
JsonSockEvent *json = sockEmit.beginEmit("fwStatus");
json->beginObject();
json->addElem("available", this->updateAvailable);
json->addElem("status", this->status);
json->addElem("error", this->error);
json->addElem("cancelled", this->cancelled);
json->addElem("checkForUpdate", settings.checkForUpdate);
json->addElem("inetAvailable", this->inetAvailable);
json->beginObject("fwVersion");
settings.fwVersion.toJSON(json);
json->endObject();
json->beginObject("appVersion");
settings.appVersion.toJSON(json);
json->endObject();
json->beginObject("latest");
this->latest.toJSON(json);
json->endObject();
json->endObject();
sockEmit.endEmit(num);
/*
ClientSocketEvent evt("fwStatus"); ClientSocketEvent evt("fwStatus");
DynamicJsonDocument doc(512); DynamicJsonDocument doc(512);
JsonObject obj = doc.to<JsonObject>(); JsonObject obj = doc.to<JsonObject>();
@ -322,6 +392,7 @@ void GitUpdater::emitUpdateCheck(uint8_t num) {
sockEmit.sendToClients("fwStatus", doc); sockEmit.sendToClients("fwStatus", doc);
else else
sockEmit.sendToClient(num, "fwStatus", doc); sockEmit.sendToClient(num, "fwStatus", doc);
*/
} }
int GitUpdater::checkInternet() { int GitUpdater::checkInternet() {
int err = 500; int err = 500;
@ -353,10 +424,22 @@ int GitUpdater::checkInternet() {
} }
void GitUpdater::emitDownloadProgress(size_t total, size_t loaded, const char *evt) { this->emitDownloadProgress(255, total, loaded, evt); } void GitUpdater::emitDownloadProgress(size_t total, size_t loaded, const char *evt) { this->emitDownloadProgress(255, total, loaded, evt); }
void GitUpdater::emitDownloadProgress(uint8_t num, size_t total, size_t loaded, const char *evt) { void GitUpdater::emitDownloadProgress(uint8_t num, size_t total, size_t loaded, const char *evt) {
JsonSockEvent *json = sockEmit.beginEmit(evt);
json->beginObject();
json->addElem("ver", this->targetRelease);
json->addElem("part", this->partition);
json->addElem("file", this->currentFile);
json->addElem("total", total);
json->addElem("loaded", loaded);
json->addElem("error", this->error);
json->endObject();
sockEmit.endEmit(num);
/*
char buf[420]; char buf[420];
snprintf(buf, sizeof(buf), "{\"ver\":\"%s\",\"part\":%d,\"file\":\"%s\",\"total\":%d,\"loaded\":%d, \"error\":%d}", this->targetRelease, this->partition, this->currentFile, total, loaded, this->error); snprintf(buf, sizeof(buf), "{\"ver\":\"%s\",\"part\":%d,\"file\":\"%s\",\"total\":%d,\"loaded\":%d, \"error\":%d}", this->targetRelease, this->partition, this->currentFile, total, loaded, this->error);
if(num >= 255) sockEmit.sendToClients(evt, buf); if(num >= 255) sockEmit.sendToClients(evt, buf);
else sockEmit.sendToClient(num, evt, buf); else sockEmit.sendToClient(num, evt, buf);
*/
sockEmit.loop(); sockEmit.loop();
webServer.loop(); webServer.loop();
} }

View file

@ -4,6 +4,7 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <time.h> #include <time.h>
#include "ConfigSettings.h" #include "ConfigSettings.h"
#include "WResp.h"
#define GIT_MAX_RELEASES 5 #define GIT_MAX_RELEASES 5
#define GIT_STATUS_READY 0 #define GIT_STATUS_READY 0
@ -28,13 +29,14 @@ class GitRelease {
void setReleaseProperty(const char *key, const char *val); void setReleaseProperty(const char *key, const char *val);
void setAssetProperty(const char *key, const char *val); void setAssetProperty(const char *key, const char *val);
bool toJSON(JsonObject &obj); bool toJSON(JsonObject &obj);
void toJSON(JsonResponse &json);
}; };
class GitRepo { class GitRepo {
public: public:
int16_t getReleases(uint8_t num = GIT_MAX_RELEASES); int16_t getReleases(uint8_t num = GIT_MAX_RELEASES);
GitRelease releases[GIT_MAX_RELEASES + 1]; GitRelease releases[GIT_MAX_RELEASES + 1];
bool toJSON(JsonObject &obj); bool toJSON(JsonObject &obj);
void toJSON(JsonResponse &json);
}; };
class GitUpdater { class GitUpdater {
public: public:
@ -59,6 +61,7 @@ class GitUpdater {
void setCurrentRelease(GitRepo &repo); void setCurrentRelease(GitRepo &repo);
void loop(); void loop();
void toJSON(JsonObject &obj); void toJSON(JsonObject &obj);
void toJSON(JsonResponse &json);
bool recoverFilesystem(); bool recoverFilesystem();
int checkInternet(); int checkInternet();
void emitUpdateCheck(uint8_t num=255); void emitUpdateCheck(uint8_t num=255);

View file

@ -155,23 +155,58 @@ void Network::emitSockets() {
void Network::emitSockets(uint8_t num) { void Network::emitSockets(uint8_t num) {
char buf[128]; char buf[128];
if(this->connType == conn_types::ethernet) { if(this->connType == conn_types::ethernet) {
JsonSockEvent *json = sockEmit.beginEmit("ethernet");
json->beginObject();
json->addElem("connected", this->connected());
json->addElem("speed", ETH.linkSpeed());
json->addElem("fullduplex", ETH.fullDuplex());
json->endObject();
sockEmit.endEmit(num);
/*
snprintf(buf, sizeof(buf), "{\"connected\":%s,\"speed\":%d,\"fullduplex\":%s}", this->connected() ? "true" : "false", ETH.linkSpeed(), ETH.fullDuplex() ? "true" : "false"); snprintf(buf, sizeof(buf), "{\"connected\":%s,\"speed\":%d,\"fullduplex\":%s}", this->connected() ? "true" : "false", ETH.linkSpeed(), ETH.fullDuplex() ? "true" : "false");
if(num == 255) if(num == 255)
sockEmit.sendToClients("ethernet", buf); sockEmit.sendToClients("ethernet", buf);
else else
sockEmit.sendToClient(num, "ethernet", buf); sockEmit.sendToClient(num, "ethernet", buf);
*/
} }
else { else {
if(WiFi.status() == WL_CONNECTED) { if(WiFi.status() == WL_CONNECTED) {
JsonSockEvent *json = sockEmit.beginEmit("wifiStrength");
json->beginObject();
json->addElem("ssid", WiFi.SSID().c_str());
json->addElem("strength", WiFi.RSSI());
json->addElem("channel", this->channel);
json->endObject();
sockEmit.endEmit(num);
/*
snprintf(buf, sizeof(buf), "{\"ssid\":\"%s\",\"strength\":%d,\"channel\":%d}", WiFi.SSID().c_str(), WiFi.RSSI(), this->channel); snprintf(buf, sizeof(buf), "{\"ssid\":\"%s\",\"strength\":%d,\"channel\":%d}", WiFi.SSID().c_str(), WiFi.RSSI(), this->channel);
if(num == 255) if(num == 255)
sockEmit.sendToClients("wifiStrength", buf); sockEmit.sendToClients("wifiStrength", buf);
else else
sockEmit.sendToClient(num, "wifiStrength", buf); sockEmit.sendToClient(num, "wifiStrength", buf);
*/
this->lastRSSI = WiFi.RSSI(); this->lastRSSI = WiFi.RSSI();
this->lastChannel = WiFi.channel(); this->lastChannel = WiFi.channel();
} }
else { else {
JsonSockEvent *json = sockEmit.beginEmit("wifiStrength");
json->beginObject();
json->addElem("ssid", "");
json->addElem("strength", -100);
json->addElem("channel", -1);
json->endObject();
sockEmit.endEmit(num);
json = sockEmit.beginEmit("ethernet");
json->beginObject();
json->addElem("connected", false);
json->addElem("speed", 0);
json->addElem("fullduplex", false);
json->endObject();
sockEmit.endEmit(num);
/*
if(num == 255) { if(num == 255) {
sockEmit.sendToClients("wifiStrength", "{\"ssid\":\"\", \"strength\":-100,\"channel\":-1}"); sockEmit.sendToClients("wifiStrength", "{\"ssid\":\"\", \"strength\":-100,\"channel\":-1}");
sockEmit.sendToClients("ethernet", "{\"connected\":false,\"speed\":0,\"fullduplex\":false}"); sockEmit.sendToClients("ethernet", "{\"connected\":false,\"speed\":0,\"fullduplex\":false}");
@ -180,6 +215,7 @@ void Network::emitSockets(uint8_t num) {
sockEmit.sendToClient(num, "wifiStrength", "{\"ssid\":\"\", \"strength\":-100,\"channel\":-1}"); sockEmit.sendToClient(num, "wifiStrength", "{\"ssid\":\"\", \"strength\":-100,\"channel\":-1}");
sockEmit.sendToClient(num, "ethernet", "{\"connected\":false,\"speed\":0,\"fullduplex\":false}"); sockEmit.sendToClient(num, "ethernet", "{\"connected\":false,\"speed\":0,\"fullduplex\":false}");
} }
*/
this->lastRSSI = -100; this->lastRSSI = -100;
this->lastChannel = -1; this->lastChannel = -1;
} }
@ -239,9 +275,18 @@ void Network::setConnected(conn_types connType) {
settings.IP.dns1 = ETH.dnsIP(0); settings.IP.dns1 = ETH.dnsIP(0);
settings.IP.dns2 = ETH.dnsIP(1); settings.IP.dns2 = ETH.dnsIP(1);
} }
JsonSockEvent *json = sockEmit.beginEmit("ethernet");
json->beginObject();
json->addElem("connected", this->connected());
json->addElem("speed", ETH.linkSpeed());
json->addElem("fullduplex", ETH.fullDuplex());
json->endObject();
sockEmit.endEmit();
/*
char buf[128]; char buf[128];
snprintf(buf, sizeof(buf), "{\"connected\":true,\"speed\":%d,\"fullduplex\":%s}", ETH.linkSpeed(), ETH.fullDuplex() ? "true" : "false"); snprintf(buf, sizeof(buf), "{\"connected\":true,\"speed\":%d,\"fullduplex\":%s}", ETH.linkSpeed(), ETH.fullDuplex() ? "true" : "false");
sockEmit.sendToClients("ethernet", buf); sockEmit.sendToClients("ethernet", buf);
*/
} }
} }
else { else {
@ -364,7 +409,7 @@ bool Network::connectWired() {
uint32_t wait = millis(); uint32_t wait = millis();
while(millis() - wait < 14000) { while(millis() - wait < 14000) {
if(ETH.linkUp()) { if(ETH.linkUp() && ETH.localIP() != INADDR_NONE) {
net.mac = ETH.macAddress(); net.mac = ETH.macAddress();
net.setConnected(conn_types::ethernet); net.setConnected(conn_types::ethernet);
return true; return true;
@ -660,7 +705,18 @@ void Network::networkEvent(WiFiEvent_t event) {
break; break;
case ARDUINO_EVENT_ETH_DISCONNECTED: case ARDUINO_EVENT_ETH_DISCONNECTED:
Serial.println("Ethernet Disconnected"); Serial.println("Ethernet Disconnected");
{
JsonSockEvent *json = sockEmit.beginEmit("ethernet");
json->beginObject();
json->addElem("connected", false);
json->addElem("speed", 0);
json->addElem("fullduplex", false);
json->endObject();
sockEmit.endEmit();
}
/*
sockEmit.sendToClients("ethernet", "{\"connected\":false,\"speed\":0,\"fullduplex\":false}"); sockEmit.sendToClients("ethernet", "{\"connected\":false,\"speed\":0,\"fullduplex\":false}");
*/
net.connType = conn_types::unset; net.connType = conn_types::unset;
break; break;
case ARDUINO_EVENT_ETH_STOP: case ARDUINO_EVENT_ETH_STOP:

View file

@ -16,6 +16,9 @@ extern GitUpdater git;
WebSocketsServer sockServer = WebSocketsServer(8080); WebSocketsServer sockServer = WebSocketsServer(8080);
#define MAX_SOCK_RESPONSE 2048
static char g_response[MAX_SOCK_RESPONSE];
bool room_t::isJoined(uint8_t num) { bool room_t::isJoined(uint8_t num) {
for(uint8_t i = 0; i < sizeof(this->clients); i++) { for(uint8_t i = 0; i < sizeof(this->clients); i++) {
if(this->clients[i] == num) return true; if(this->clients[i] == num) return true;
@ -49,7 +52,9 @@ uint8_t room_t::activeClients() {
/********************************************************************* /*********************************************************************
* ClientSocketEvent class members * ClientSocketEvent class members
********************************************************************/ ********************************************************************/
/*
void ClientSocketEvent::prepareMessage(const char *evt, const char *payload) { void ClientSocketEvent::prepareMessage(const char *evt, const char *payload) {
if(strlen(payload) + 5 >= sizeof(this->msg)) Serial.printf("Socket buffer overflow %d > 2048\n", strlen(payload) + 5 + strlen(evt));
snprintf(this->msg, sizeof(this->msg), "42[%s,%s]", evt, payload); snprintf(this->msg, sizeof(this->msg), "42[%s,%s]", evt, payload);
} }
void ClientSocketEvent::prepareMessage(const char *evt, JsonDocument &doc) { void ClientSocketEvent::prepareMessage(const char *evt, JsonDocument &doc) {
@ -58,6 +63,7 @@ void ClientSocketEvent::prepareMessage(const char *evt, JsonDocument &doc) {
serializeJson(doc, &this->msg[strlen(this->msg)], sizeof(this->msg) - strlen(this->msg) - 2); serializeJson(doc, &this->msg[strlen(this->msg)], sizeof(this->msg) - strlen(this->msg) - 2);
strcat(this->msg, "]"); strcat(this->msg, "]");
} }
*/
/********************************************************************* /*********************************************************************
* SocketEmitter class members * SocketEmitter class members
@ -76,56 +82,113 @@ void SocketEmitter::loop() {
sockServer.loop(); sockServer.loop();
} }
/* /*
bool SocketEmitter::sendToClients(const char *evt, JsonObject &obj) { ClientSocketEvent::ClientSocketEvent() { this->msg[0] = 0x00; }
serializeJson(obj, g_buffer, sizeof(g_buffer));
return this->sendToClients(evt, g_buffer);
}
bool SocketEmitter::sendToClient(uint8_t num, const char *evt, JsonObject &obj) {
serializeJson(obj, g_buffer, sizeof(g_buffer));
return this->sendToClient(num, evt, g_buffer);
}
*/
ClientSocketEvent::ClientSocketEvent() {}
ClientSocketEvent::ClientSocketEvent(const char *evt) { snprintf(this->msg, sizeof(this->msg), "42[%s,]", evt); } ClientSocketEvent::ClientSocketEvent(const char *evt) { snprintf(this->msg, sizeof(this->msg), "42[%s,]", evt); }
ClientSocketEvent::ClientSocketEvent(const char *evt, const char *payload) { snprintf(this->msg, sizeof(this->msg), "42[%s,%s]", evt, payload); } //ClientSocketEvent::ClientSocketEvent(const char *evt, const char *payload) { snprintf(this->msg, sizeof(this->msg), "42[%s,%s]", evt, payload); }
void ClientSocketEvent::beginEmit(const char *evt) { snprintf(this->msg, sizeof(this->msg), "42[%s,", evt); }
void ClientSocketEvent::endEmit() { this->_safecat("]"); }
void ClientSocketEvent::appendMessage(const char *text) { void ClientSocketEvent::appendMessage(const char *text) {
uint16_t len = strlen(this->msg); uint16_t len = strlen(this->msg);
this->msg[len - 1] = '\0'; this->msg[len - 1] = '\0';
strcat(this->msg, text); strcat(this->msg, text);
strcat(this->msg, "]"); strcat(this->msg, "]");
} }
/* void ClientSocketEvent::beginObject(const char *name) {
void ClientSocketEvent::appendJSONElem(const char *elem) { if(name && strlen(name) > 0) this->appendElem(name);
this->msg[strlen(this->msg) - 1] = '\0'; // Trim off the ending bracket. else if(!this->_nocomma) this->_safecat(",");
uint16_t len = strlen(this->msg); this->_safecat("{");
if(len > 0) { this->_objects++;
if(this->msg[strlen(this->msg) - 1] == '{') strcat(this->msg, ','); this->_nocomma = true;
}
void ClientSocketEvent::endObject() {
//if(strlen(this->buff) + 1 > this->buffSize - 1) this->send();
this->_safecat("}");
this->_objects--;
this->_nocomma = false;
}
void ClientSocketEvent::beginArray(const char *name) {
if(name && strlen(name) > 0) this->appendElem(name);
else if(!this->_nocomma) this->_safecat(",");
this->_safecat("[");
this->_arrays++;
this->_nocomma = true;
}
void ClientSocketEvent::endArray() {
//if(strlen(this->buff) + 1 > this->buffSize - 1) this->send();
this->_safecat("]");
this->_arrays--;
this->_nocomma = false;
}
void ClientSocketEvent::appendElem(const char *name) {
if(!this->_nocomma) this->_safecat(",");
if(name && strlen(name) > 0) {
this->_safecat(name, true);
this->_safecat(":");
} }
strcat(this->msg, "\""); this->_nocomma = false;
strcat(this->msg, elem);
strcat(this->msg, "\":");
strcat(this->msg, "]");
} }
void ClientSocketEvent::appendJSON(const char *elem, const char *text, bool quoted) {
this->appendJSONElem(elem); void ClientSocketEvent::addElem(const char *name, const char *val) {
this->msg[strlen(this->msg) - 1] = '\0'; // Trim off the ending bracket. if(!val) return;
if(quoted) strcat(this->msg, "\""); this->appendElem(name);
strcat(this->msg, text); this->_safecat(val, true);
if(quoted) strcat(this->msg, "\"");
strcat(this->msg, "]");
} }
void ClientSocketEvent::appendJSON(const char *elem, const bool b) { this->appendJSON(elem, b ? "true" : "false", false); } void ClientSocketEvent::addElem(const char *val) { this->addElem(nullptr, val); }
void ClientSocketEvent::appendJSON(const char *elem, const uint8_t val) { void ClientSocketEvent::addElem(float fval) { sprintf(this->_numbuff, "%.4f", fval); this->_appendNumber(nullptr); }
char buff[5]; void ClientSocketEvent::addElem(int8_t nval) { sprintf(this->_numbuff, "%d", nval); this->_appendNumber(nullptr); }
sprintf(buff, "%d", val); void ClientSocketEvent::addElem(uint8_t nval) { sprintf(this->_numbuff, "%u", nval); this->_appendNumber(nullptr); }
this->appendJSON(elem, buff, false); void ClientSocketEvent::addElem(int16_t nval) { sprintf(this->_numbuff, "%d", nval); this->_appendNumber(nullptr); }
void ClientSocketEvent::addElem(uint16_t nval) { sprintf(this->_numbuff, "%u", nval); this->_appendNumber(nullptr); }
void ClientSocketEvent::addElem(int32_t nval) { sprintf(this->_numbuff, "%ld", (long)nval); this->_appendNumber(nullptr); }
void ClientSocketEvent::addElem(uint32_t nval) { sprintf(this->_numbuff, "%lu", (unsigned long)nval); this->_appendNumber(nullptr); }
void ClientSocketEvent::addElem(int64_t lval) { sprintf(this->_numbuff, "%lld", (long long)lval); this->_appendNumber(nullptr); }
void ClientSocketEvent::addElem(uint64_t lval) { sprintf(this->_numbuff, "%llu", (unsigned long long)lval); this->_appendNumber(nullptr); }
void ClientSocketEvent::addElem(bool bval) { strcpy(this->_numbuff, bval ? "true" : "false"); this->_appendNumber(nullptr); }
void ClientSocketEvent::addElem(const char *name, float fval) { sprintf(this->_numbuff, "%.4f", fval); this->_appendNumber(name); }
void ClientSocketEvent::addElem(const char *name, int8_t nval) { sprintf(this->_numbuff, "%d", nval); this->_appendNumber(name); }
void ClientSocketEvent::addElem(const char *name, uint8_t nval) { sprintf(this->_numbuff, "%u", nval); this->_appendNumber(name); }
void ClientSocketEvent::addElem(const char *name, int16_t nval) { sprintf(this->_numbuff, "%d", nval); this->_appendNumber(name); }
void ClientSocketEvent::addElem(const char *name, uint16_t nval) { sprintf(this->_numbuff, "%u", nval); this->_appendNumber(name); }
void ClientSocketEvent::addElem(const char *name, int32_t nval) { sprintf(this->_numbuff, "%ld", (long)nval); this->_appendNumber(name); }
void ClientSocketEvent::addElem(const char *name, uint32_t nval) { sprintf(this->_numbuff, "%lu", (unsigned long)nval); this->_appendNumber(name); }
void ClientSocketEvent::addElem(const char *name, int64_t lval) { sprintf(this->_numbuff, "%lld", (long long)lval); this->_appendNumber(name); }
void ClientSocketEvent::addElem(const char *name, uint64_t lval) { sprintf(this->_numbuff, "%llu", (unsigned long long)lval); this->_appendNumber(name); }
void ClientSocketEvent::addElem(const char *name, bool bval) { strcpy(this->_numbuff, bval ? "true" : "false"); this->_appendNumber(name); }
void ClientSocketEvent::_safecat(const char *val, bool escape) {
size_t len = strlen(val) + strlen(this->msg);
if(escape) len += 2;
if(len >= sizeof(this->msg)) {
//this->send();
}
if(escape) strcat(this->msg, "\"");
strcat(this->msg, val);
if(escape) strcat(this->msg, "\"");
} }
void ClientSocketEvent::_appendNumber(const char *name) { this->appendElem(name); this->_safecat(this->_numbuff); }
*/ */
JsonSockEvent *SocketEmitter::beginEmit(const char *evt) {
this->json.beginEvent(&sockServer, evt, g_response, sizeof(g_response));
return &this->json;
}
void SocketEmitter::endEmit(uint8_t num) { this->json.endEvent(num); }
void SocketEmitter::endEmitRoom(uint8_t room) {
if(room < SOCK_MAX_ROOMS) {
room_t *r = &this->rooms[room];
for(uint8_t i = 0; i < sizeof(r->clients); i++) {
if(r->clients[i] != 255) this->json.endEvent(r->clients[i]);
}
}
}
uint8_t SocketEmitter::activeClients(uint8_t room) { uint8_t SocketEmitter::activeClients(uint8_t room) {
if(room < SOCK_MAX_ROOMS) return this->rooms[room].activeClients(); if(room < SOCK_MAX_ROOMS) return this->rooms[room].activeClients();
return 0; return 0;
} }
/*
bool SocketEmitter::sendToRoom(uint8_t room, ClientSocketEvent *evt) { bool SocketEmitter::sendToRoom(uint8_t room, ClientSocketEvent *evt) {
if(room < SOCK_MAX_ROOMS) { if(room < SOCK_MAX_ROOMS) {
room_t *r = &this->rooms[room]; room_t *r = &this->rooms[room];
@ -164,7 +227,7 @@ bool SocketEmitter::sendToClients(const char *evt, JsonDocument &doc) {
this->evt.prepareMessage(evt, doc); this->evt.prepareMessage(evt, doc);
return sockServer.broadcastTXT(this->evt.msg); return sockServer.broadcastTXT(this->evt.msg);
} }
*/
void SocketEmitter::end() { sockServer.close(); } void SocketEmitter::end() { sockServer.close(); }
void SocketEmitter::disconnect() { sockServer.disconnect(); } void SocketEmitter::disconnect() { sockServer.disconnect(); }
void SocketEmitter::wsEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length) { void SocketEmitter::wsEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length) {

View file

@ -1,4 +1,5 @@
#include <WebSocketsServer.h> #include <WebSocketsServer.h>
#include "WResp.h"
#ifndef sockets_h #ifndef sockets_h
#define sockets_h #define sockets_h
@ -6,31 +7,70 @@
#define ROOM_EMIT_FRAME 0 #define ROOM_EMIT_FRAME 0
struct room_t { struct room_t {
uint8_t clients[5] = {255, 255, 255, 255}; uint8_t clients[5] = {255, 255, 255, 255, 255};
uint8_t activeClients(); uint8_t activeClients();
bool isJoined(uint8_t num); bool isJoined(uint8_t num);
bool join(uint8_t num); bool join(uint8_t num);
bool leave(uint8_t num); bool leave(uint8_t num);
}; };
/*
class ClientSocketEvent { class ClientSocketEvent {
private:
uint8_t _objects = 0;
uint8_t _arrays = 0;
bool _nocomma = true;
char _numbuff[25] = {0};
protected:
void _safecat(const char *val, bool escape = false);
void _appendNumber(const char *name);
public: public:
ClientSocketEvent(); ClientSocketEvent();
ClientSocketEvent(const char *evt); ClientSocketEvent(const char *evt);
ClientSocketEvent(const char *evt, const char *data); //ClientSocketEvent(const char *evt, const char *data);
char msg[2048]; char msg[2048] = "";
void beginEmit(const char *evt);
void endEmit();
void prepareMessage(const char *evt, const char *data); void prepareMessage(const char *evt, const char *data);
void prepareMessage(const char *evt, JsonDocument &doc); void prepareMessage(const char *evt, JsonDocument &doc);
void appendMessage(const char *text); void appendMessage(const char *text);
void appendElement(const char *elem, const char *val); void appendElement(const char *elem, const char *val);
void beginObject(const char *name = nullptr);
void endObject();
void beginArray(const char *name = nullptr);
void endArray();
void appendElem(const char *name = nullptr);
void addElem(const char* val);
void addElem(float fval);
void addElem(int8_t nval);
void addElem(uint8_t nval);
void addElem(int16_t nval);
void addElem(uint16_t nval);
void addElem(int32_t nval);
void addElem(uint32_t nval);
void addElem(int64_t lval);
void addElem(uint64_t lval);
void addElem(bool bval);
void addElem(const char* name, float fval);
void addElem(const char* name, int8_t nval);
void addElem(const char* name, uint8_t nval);
void addElem(const char* name, int16_t nval);
void addElem(const char* name, uint16_t nval);
void addElem(const char* name, int32_t nval);
void addElem(const char* name, uint32_t nval);
void addElem(const char* name, int64_t lval);
void addElem(const char* name, uint64_t lval);
void addElem(const char* name, bool bval);
void addElem(const char *name, const char *val);
}; };
*/
class SocketEmitter { class SocketEmitter {
ClientSocketEvent evt;
public: public:
JsonSockEvent json;
//ClientSocketEvent evt;
room_t rooms[SOCK_MAX_ROOMS]; room_t rooms[SOCK_MAX_ROOMS];
uint8_t activeClients(uint8_t room); uint8_t activeClients(uint8_t room);
void startup(); void startup();
@ -38,6 +78,10 @@ class SocketEmitter {
void loop(); void loop();
void end(); void end();
void disconnect(); void disconnect();
JsonSockEvent * beginEmit(const char *evt);
void endEmit(uint8_t num = 255);
void endEmitRoom(uint8_t num);
/*
bool sendToRoom(uint8_t room, ClientSocketEvent *evt); bool sendToRoom(uint8_t room, ClientSocketEvent *evt);
bool sendToClients(ClientSocketEvent *evt); bool sendToClients(ClientSocketEvent *evt);
bool sendToClient(uint8_t num, ClientSocketEvent *evt); bool sendToClient(uint8_t num, ClientSocketEvent *evt);
@ -45,6 +89,7 @@ class SocketEmitter {
bool sendToClient(uint8_t num, const char *evt, const char *data); bool sendToClient(uint8_t num, const char *evt, const char *data);
bool sendToClients(const char *evt, JsonDocument &doc); bool sendToClients(const char *evt, JsonDocument &doc);
bool sendToClient(uint8_t num, const char *evt, JsonDocument &doc); bool sendToClient(uint8_t num, const char *evt, JsonDocument &doc);
*/
static void wsEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length); static void wsEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length);
}; };
#endif #endif

303
Somfy.cpp
View file

@ -1,6 +1,7 @@
#include <Preferences.h> #include <Preferences.h>
#include <ELECHOUSE_CC1101_SRC_DRV.h> #include <ELECHOUSE_CC1101_SRC_DRV.h>
#include <SPI.h> #include <SPI.h>
#include <WebServer.h>
#include "Utils.h" #include "Utils.h"
#include "ConfigSettings.h" #include "ConfigSettings.h"
#include "Somfy.h" #include "Somfy.h"
@ -1820,6 +1821,32 @@ float SomfyShade::p_myTiltPos(float pos) {
void SomfyShade::emitState(const char *evt) { this->emitState(255, evt); } void SomfyShade::emitState(const char *evt) { this->emitState(255, evt); }
void SomfyShade::emitState(uint8_t num, const char *evt) { void SomfyShade::emitState(uint8_t num, const char *evt) {
JsonSockEvent *json = sockEmit.beginEmit(evt);
json->beginObject();
json->addElem("shadeId", this->shadeId);
json->addElem("type", static_cast<uint8_t>(this->shadeType));
json->addElem("remoteAddress", this->getRemoteAddress());
json->addElem("name", this->name);
json->addElem("direction", this->direction);
json->addElem("position", this->transformPosition(this->currentPos));
json->addElem("target", this->transformPosition(this->target));
json->addElem("myPos", this->transformPosition(this->myPos));
json->addElem("tiltType", static_cast<uint8_t>(this->tiltType));
json->addElem("flipCommands", this->flipCommands);
json->addElem("flipPosition", this->flipPosition);
json->addElem("flags", this->flags);
json->addElem("sunSensor", this->hasSunSensor());
json->addElem("light", this->hasLight());
json->addElem("sortOrder", this->sortOrder);
if(this->tiltType != tilt_types::none) {
json->addElem("tiltDirection", this->tiltDirection);
json->addElem("tiltTarget", this->transformPosition(this->tiltTarget));
json->addElem("tiltPosition", this->transformPosition(this->currentTiltPos));
json->addElem("myTiltPos", this->transformPosition(this->myTiltPos));
}
json->endObject();
sockEmit.endEmit(num);
/*
char buf[420]; char buf[420];
if(this->tiltType != tilt_types::none) if(this->tiltType != tilt_types::none)
snprintf(buf, sizeof(buf), "{\"shadeId\":%d,\"type\":%u,\"remoteAddress\":%d,\"name\":\"%s\",\"direction\":%d,\"position\":%d,\"target\":%d,\"myPos\":%d,\"myTiltPos\":%d,\"tiltType\":%u,\"tiltDirection\":%d,\"tiltTarget\":%d,\"tiltPosition\":%d,\"flipCommands\":%s,\"flipPosition\":%s,\"flags\":%d,\"sunSensor\":%s,\"light\":%s,\"sortOrder\":%d}", snprintf(buf, sizeof(buf), "{\"shadeId\":%d,\"type\":%u,\"remoteAddress\":%d,\"name\":\"%s\",\"direction\":%d,\"position\":%d,\"target\":%d,\"myPos\":%d,\"myTiltPos\":%d,\"tiltType\":%u,\"tiltDirection\":%d,\"tiltTarget\":%d,\"tiltPosition\":%d,\"flipCommands\":%s,\"flipPosition\":%s,\"flags\":%d,\"sunSensor\":%s,\"light\":%s,\"sortOrder\":%d}",
@ -1834,9 +1861,21 @@ void SomfyShade::emitState(uint8_t num, const char *evt) {
static_cast<uint8_t>(this->tiltType), this->flipCommands ? "true" : "false", this->flipPosition ? "true": "false", this->flags, this->hasSunSensor() ? "true" : "false", this->hasLight() ? "true" : "false", this->sortOrder); static_cast<uint8_t>(this->tiltType), this->flipCommands ? "true" : "false", this->flipPosition ? "true": "false", this->flags, this->hasSunSensor() ? "true" : "false", this->hasLight() ? "true" : "false", this->sortOrder);
if(num >= 255) sockEmit.sendToClients(evt, buf); if(num >= 255) sockEmit.sendToClients(evt, buf);
else sockEmit.sendToClient(num, evt, buf); else sockEmit.sendToClient(num, evt, buf);
*/
} }
void SomfyShade::emitCommand(somfy_commands cmd, const char *source, uint32_t sourceAddress, const char *evt) { this->emitCommand(255, cmd, source, sourceAddress, evt); } void SomfyShade::emitCommand(somfy_commands cmd, const char *source, uint32_t sourceAddress, const char *evt) { this->emitCommand(255, cmd, source, sourceAddress, evt); }
void SomfyShade::emitCommand(uint8_t num, somfy_commands cmd, const char *source, uint32_t sourceAddress, const char *evt) { void SomfyShade::emitCommand(uint8_t num, somfy_commands cmd, const char *source, uint32_t sourceAddress, const char *evt) {
JsonSockEvent *json = sockEmit.beginEmit(evt);
json->beginObject();
json->addElem("shadeId", this->shadeId);
json->addElem("remoteAddress", this->getRemoteAddress());
json->addElem("cmd", translateSomfyCommand(cmd).c_str());
json->addElem("source", source);
json->addElem("rcode", this->lastRollingCode);
json->addElem("sourceAddress", sourceAddress);
json->endObject();
sockEmit.endEmit(num);
/*
ClientSocketEvent e(evt); ClientSocketEvent e(evt);
char buf[30]; char buf[30];
snprintf(buf, sizeof(buf), "{\"shadeId\":%d", this->shadeId); snprintf(buf, sizeof(buf), "{\"shadeId\":%d", this->shadeId);
@ -1853,6 +1892,7 @@ void SomfyShade::emitCommand(uint8_t num, somfy_commands cmd, const char *source
e.appendMessage(buf); e.appendMessage(buf);
if(num >= 255) sockEmit.sendToClients(&e); if(num >= 255) sockEmit.sendToClients(&e);
else sockEmit.sendToClient(num, &e); else sockEmit.sendToClient(num, &e);
*/
if(mqtt.connected()) { if(mqtt.connected()) {
this->publish("cmdSource", source); this->publish("cmdSource", source);
this->publish("cmdAddress", sourceAddress); this->publish("cmdAddress", sourceAddress);
@ -1861,6 +1901,14 @@ void SomfyShade::emitCommand(uint8_t num, somfy_commands cmd, const char *source
} }
void SomfyRoom::emitState(const char *evt) { this->emitState(255, evt); } void SomfyRoom::emitState(const char *evt) { this->emitState(255, evt); }
void SomfyRoom::emitState(uint8_t num, const char *evt) { void SomfyRoom::emitState(uint8_t num, const char *evt) {
JsonSockEvent *json = sockEmit.beginEmit(evt);
json->beginObject();
json->addElem("roomId", this->roomId);
json->addElem("name", this->name);
json->addElem("sortOrder", this->sortOrder);
json->endObject();
sockEmit.endEmit(num);
/*
ClientSocketEvent e(evt); ClientSocketEvent e(evt);
char buf[55]; char buf[55];
uint8_t flags = 0; uint8_t flags = 0;
@ -1872,10 +1920,28 @@ void SomfyRoom::emitState(uint8_t num, const char *evt) {
e.appendMessage(buf); e.appendMessage(buf);
if(num >= 255) sockEmit.sendToClients(&e); if(num >= 255) sockEmit.sendToClients(&e);
else sockEmit.sendToClient(num, &e); else sockEmit.sendToClient(num, &e);
*/
this->publish(); this->publish();
} }
void SomfyGroup::emitState(const char *evt) { this->emitState(255, evt); } void SomfyGroup::emitState(const char *evt) { this->emitState(255, evt); }
void SomfyGroup::emitState(uint8_t num, const char *evt) { void SomfyGroup::emitState(uint8_t num, const char *evt) {
JsonSockEvent *json = sockEmit.beginEmit(evt);
json->beginObject();
json->addElem("groupId", this->groupId);
json->addElem("remoteAddress", this->getRemoteAddress());
json->addElem("name", this->name);
json->addElem("sunSensor", this->hasSunSensor());
json->beginArray("shades");
for(uint8_t i = 0; i < SOMFY_MAX_GROUPED_SHADES; i++) {
if(this->linkedShades[i] != 255 && this->linkedShades[i] != 0) {
SomfyShade *shade = somfy.getShadeById(this->linkedShades[i]);
if(shade) json->addElem(this->linkedShades[i]);
}
}
json->endArray();
json->endObject();
sockEmit.endEmit(num);
/*
ClientSocketEvent e(evt); ClientSocketEvent e(evt);
char buf[55]; char buf[55];
uint8_t flags = 0; uint8_t flags = 0;
@ -1906,6 +1972,7 @@ void SomfyGroup::emitState(uint8_t num, const char *evt) {
if(num >= 255) sockEmit.sendToClients(&e); if(num >= 255) sockEmit.sendToClients(&e);
else sockEmit.sendToClient(num, &e); else sockEmit.sendToClient(num, &e);
*/
this->publish(); this->publish();
} }
int8_t SomfyShade::transformPosition(float fpos) { int8_t SomfyShade::transformPosition(float fpos) {
@ -3110,6 +3177,7 @@ int8_t SomfyShade::fromJSON(JsonObject &obj) {
} }
return err; return err;
} }
/*
bool SomfyShade::toJSONRef(JsonObject &obj) { bool SomfyShade::toJSONRef(JsonObject &obj) {
obj["shadeId"] = this->getShadeId(); obj["shadeId"] = this->getShadeId();
obj["roomId"] = this->roomId; obj["roomId"] = this->roomId;
@ -3126,6 +3194,70 @@ bool SomfyShade::toJSONRef(JsonObject &obj) {
SomfyRemote::toJSON(obj); SomfyRemote::toJSON(obj);
return true; return true;
} }
*/
void SomfyShade::toJSONRef(JsonResponse &json) {
json.addElem("shadeId", this->getShadeId());
json.addElem("roomId", this->roomId);
json.addElem("name", this->name);
json.addElem("remoteAddress", this->m_remoteAddress);
json.addElem("paired", this->paired);
json.addElem("shadeType", static_cast<uint8_t>(this->shadeType));
json.addElem("bitLength", this->bitLength);
json.addElem("proto", static_cast<uint8_t>(this->proto));
json.addElem("flags", this->flags);
json.addElem("sunSensor", this->hasSunSensor());
json.addElem("hasLight", this->hasLight());
json.addElem("repeats", this->repeats);
//SomfyRemote::toJSON(json);
}
void SomfyShade::toJSON(JsonResponse &json) {
json.addElem("shadeId", this->getShadeId());
json.addElem("roomId", this->roomId);
json.addElem("name", this->name);
json.addElem("remoteAddress", this->m_remoteAddress);
json.addElem("upTime", this->upTime);
json.addElem("downTime", this->downTime);
json.addElem("paired", this->paired);
json.addElem("lastRollingCode", this->lastRollingCode);
json.addElem("position", this->transformPosition(this->currentPos));
json.addElem("tiltType", static_cast<uint8_t>(this->tiltType));
json.addElem("tiltPosition", this->transformPosition(this->currentTiltPos));
json.addElem("tiltDirection", this->tiltDirection);
json.addElem("tiltTime", this->tiltTime);
json.addElem("stepSize", this->stepSize);
json.addElem("tiltTarget", this->transformPosition(this->tiltTarget));
json.addElem("target", this->transformPosition(this->target));
json.addElem("myPos", this->transformPosition(this->myPos));
json.addElem("myTiltPos", this->transformPosition(this->myTiltPos));
json.addElem("direction", this->direction);
json.addElem("shadeType", static_cast<uint8_t>(this->shadeType));
json.addElem("bitLength", this->bitLength);
json.addElem("proto", static_cast<uint8_t>(this->proto));
json.addElem("flags", this->flags);
json.addElem("flipCommands", this->flipCommands);
json.addElem("flipPosition", this->flipPosition);
json.addElem("inGroup", this->isInGroup());
json.addElem("sunSensor", this->hasSunSensor());
json.addElem("light", this->hasLight());
json.addElem("repeats", this->repeats);
json.addElem("sortOrder", this->sortOrder);
json.addElem("gpioUp", this->gpioUp);
json.addElem("gpioDown", this->gpioDown);
json.addElem("gpioMy", this->gpioMy);
json.addElem("gpioLLTrigger", ((this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger) == 0) ? false : true);
json.beginArray("linkedRemotes");
for(uint8_t i = 0; i < SOMFY_MAX_LINKED_REMOTES; i++) {
SomfyLinkedRemote &lremote = this->linkedRemotes[i];
if(lremote.getRemoteAddress() != 0) {
json.beginObject();
lremote.toJSON(json);
json.endObject();
}
}
json.endArray();
}
bool SomfyShade::toJSON(JsonObject &obj) { bool SomfyShade::toJSON(JsonObject &obj) {
//Serial.print("Serializing Shade:"); //Serial.print("Serializing Shade:");
//Serial.print(this->getShadeId()); //Serial.print(this->getShadeId());
@ -3189,6 +3321,11 @@ bool SomfyRoom::toJSON(JsonObject &obj) {
obj["sortOrder"] = this->sortOrder; obj["sortOrder"] = this->sortOrder;
return true; return true;
} }
void SomfyRoom::toJSON(JsonResponse &json) {
json.addElem("roomId", this->roomId);
json.addElem("name", this->name);
json.addElem("sortOrder", this->sortOrder);
}
bool SomfyGroup::fromJSON(JsonObject &obj) { bool SomfyGroup::fromJSON(JsonObject &obj) {
if(obj.containsKey("name")) strlcpy(this->name, obj["name"], sizeof(this->name)); if(obj.containsKey("name")) strlcpy(this->name, obj["name"], sizeof(this->name));
@ -3211,6 +3348,51 @@ bool SomfyGroup::fromJSON(JsonObject &obj) {
} }
return true; return true;
} }
void SomfyGroup::toJSON(JsonResponse &json) {
this->updateFlags();
json.addElem("groupId", this->getGroupId());
json.addElem("roomId", this->roomId);
json.addElem("name", this->name);
json.addElem("remoteAddress", this->m_remoteAddress);
json.addElem("lastRollingCode", this->lastRollingCode);
json.addElem("bitLength", this->bitLength);
json.addElem("proto", static_cast<uint8_t>(this->proto));
json.addElem("sunSensor", this->hasSunSensor());
json.addElem("flipCommands", this->flipCommands);
json.addElem("flags", this->flags);
json.addElem("repeats", this->repeats);
json.addElem("sortOrder", this->sortOrder);
json.beginArray("linkedShades");
for(uint8_t i = 0; i < SOMFY_MAX_GROUPED_SHADES; i++) {
uint8_t shadeId = this->linkedShades[i];
if(shadeId > 0 && shadeId < 255) {
SomfyShade *shade = somfy.getShadeById(shadeId);
if(shade) {
json.beginObject();
shade->toJSONRef(json);
json.endObject();
}
}
}
json.endArray();
}
void SomfyGroup::toJSONRef(JsonResponse &json) {
this->updateFlags();
json.addElem("groupId", this->getGroupId());
json.addElem("roomId", this->roomId);
json.addElem("name", this->name);
json.addElem("remoteAddress", this->m_remoteAddress);
json.addElem("lastRollingCode", this->lastRollingCode);
json.addElem("bitLength", this->bitLength);
json.addElem("proto", static_cast<uint8_t>(this->proto));
json.addElem("sunSensor", this->hasSunSensor());
json.addElem("flipCommands", this->flipCommands);
json.addElem("flags", this->flags);
json.addElem("repeats", this->repeats);
json.addElem("sortOrder", this->sortOrder);
}
/*
bool SomfyGroup::toJSON(JsonObject &obj) { bool SomfyGroup::toJSON(JsonObject &obj) {
this->updateFlags(); this->updateFlags();
obj["groupId"] = this->getGroupId(); obj["groupId"] = this->getGroupId();
@ -3239,6 +3421,11 @@ bool SomfyGroup::toJSON(JsonObject &obj) {
} }
return true; return true;
} }
*/
void SomfyRemote::toJSON(JsonResponse &json) {
json.addElem("remoteAddress", this->getRemoteAddress());
json.addElem("lastRollingCode", this->lastRollingCode);
}
bool SomfyRemote::toJSON(JsonObject &obj) { bool SomfyRemote::toJSON(JsonObject &obj) {
//obj["remotePrefId"] = this->getRemotePrefId(); //obj["remotePrefId"] = this->getRemotePrefId();
obj["remoteAddress"] = this->getRemoteAddress(); obj["remoteAddress"] = this->getRemoteAddress();
@ -3807,6 +3994,28 @@ uint16_t SomfyRemote::setRollingCode(uint16_t code) {
} }
return code; return code;
} }
void SomfyShadeController::toJSONRooms(JsonResponse &json) {
for(uint8_t i = 0; i < SOMFY_MAX_ROOMS; i++) {
SomfyRoom *room = &this->rooms[i];
if(room->roomId != 0) {
json.beginObject();
room->toJSON(json);
json.endObject();
}
}
}
void SomfyShadeController::toJSONShades(JsonResponse &json) {
for(uint8_t i = 0; i < SOMFY_MAX_SHADES; i++) {
SomfyShade &shade = this->shades[i];
if(shade.getShadeId() != 255) {
json.beginObject();
shade.toJSON(json);
json.endObject();
}
}
}
/*
bool SomfyShadeController::toJSON(DynamicJsonDocument &doc) { bool SomfyShadeController::toJSON(DynamicJsonDocument &doc) {
doc["maxRooms"] = SOMFY_MAX_ROOMS; doc["maxRooms"] = SOMFY_MAX_ROOMS;
doc["maxShades"] = SOMFY_MAX_SHADES; doc["maxShades"] = SOMFY_MAX_SHADES;
@ -3836,23 +4045,7 @@ bool SomfyShadeController::toJSON(JsonObject &obj) {
this->toJSONGroups(arrGroups); this->toJSONGroups(arrGroups);
return true; return true;
} }
bool SomfyShadeController::toJSONRepeaters(JsonArray &arr) {
for(uint8_t i = 0; i < SOMFY_MAX_REPEATERS; i++) {
if(somfy.repeaters[i] != 0) arr.add(somfy.repeaters[i]);
}
return true;
}
bool SomfyShadeController::toJSONRooms(JsonArray &arr) {
for(uint8_t i = 0; i < SOMFY_MAX_ROOMS; i++) {
SomfyRoom &room = this->rooms[i];
if(room.roomId != 0) {
JsonObject oroom = arr.createNestedObject();
room.toJSON(oroom);
}
}
return true;
}
bool SomfyShadeController::toJSONShades(JsonArray &arr) { bool SomfyShadeController::toJSONShades(JsonArray &arr) {
for(uint8_t i = 0; i < SOMFY_MAX_SHADES; i++) { for(uint8_t i = 0; i < SOMFY_MAX_SHADES; i++) {
@ -3874,6 +4067,29 @@ bool SomfyShadeController::toJSONGroups(JsonArray &arr) {
} }
return true; return true;
} }
*/
void SomfyShadeController::toJSONGroups(JsonResponse &json) {
for(uint8_t i = 0; i < SOMFY_MAX_GROUPS; i++) {
SomfyGroup &group = this->groups[i];
if(group.getGroupId() != 255) {
json.beginObject();
group.toJSON(json);
json.endObject();
}
}
}
void SomfyShadeController::toJSONRepeaters(JsonResponse &json) {
for(uint8_t i = 0; i < SOMFY_MAX_REPEATERS; i++) {
if(somfy.repeaters[i] != 0) json.addElem(somfy.repeaters[i]);
}
}
bool SomfyShadeController::toJSONRepeaters(JsonArray &arr) {
for(uint8_t i = 0; i < SOMFY_MAX_REPEATERS; i++) {
if(somfy.repeaters[i] != 0) arr.add(somfy.repeaters[i]);
}
return true;
}
void SomfyShadeController::loop() { void SomfyShadeController::loop() {
this->transceiver.loop(); this->transceiver.loop();
for(uint8_t i = 0; i < SOMFY_MAX_SHADES; i++) { for(uint8_t i = 0; i < SOMFY_MAX_SHADES; i++) {
@ -4244,10 +4460,21 @@ void Transceiver::endFrequencyScan() {
} }
} }
void Transceiver::emitFrequencyScan(uint8_t num) { void Transceiver::emitFrequencyScan(uint8_t num) {
JsonSockEvent *json = sockEmit.beginEmit("frequencyScan");
json->beginObject();
json->addElem("scanning", rxmode == 3);
json->addElem("testFreq", currFreq);
json->addElem("testRSSI", currRSSI);
json->addElem("frequency", markFreq);
json->addElem("RSSI", markRSSI);
json->endObject();
sockEmit.endEmit(num);
/*
char buf[420]; char buf[420];
snprintf(buf, sizeof(buf), "{\"scanning\":%s,\"testFreq\":%f,\"testRSSI\":%d,\"frequency\":%f,\"RSSI\":%d}", rxmode == 3 ? "true" : "false", currFreq, currRSSI, markFreq, markRSSI); snprintf(buf, sizeof(buf), "{\"scanning\":%s,\"testFreq\":%f,\"testRSSI\":%d,\"frequency\":%f,\"RSSI\":%d}", rxmode == 3 ? "true" : "false", currFreq, currRSSI, markFreq, markRSSI);
if(num >= 255) sockEmit.sendToClients("frequencyScan", buf); if(num >= 255) sockEmit.sendToClients("frequencyScan", buf);
else sockEmit.sendToClient(num, "frequencyScan", buf); else sockEmit.sendToClient(num, "frequencyScan", buf);
*/
} }
bool Transceiver::receive(somfy_rx_t *rx) { bool Transceiver::receive(somfy_rx_t *rx) {
// Check to see if there is anything in the buffer // Check to see if there is anything in the buffer
@ -4262,6 +4489,27 @@ bool Transceiver::receive(somfy_rx_t *rx) {
} }
void Transceiver::emitFrame(somfy_frame_t *frame, somfy_rx_t *rx) { void Transceiver::emitFrame(somfy_frame_t *frame, somfy_rx_t *rx) {
if(sockEmit.activeClients(ROOM_EMIT_FRAME) > 0) { if(sockEmit.activeClients(ROOM_EMIT_FRAME) > 0) {
JsonSockEvent *json = sockEmit.beginEmit("remoteFrame");
json->beginObject();
json->addElem("encKey", frame->encKey);
json->addElem("address", frame->remoteAddress);
json->addElem("rcode", frame->rollingCode);
json->addElem("command", translateSomfyCommand(frame->cmd).c_str());
json->addElem("rssi", frame->rssi);
json->addElem("bits", rx->bit_length);
json->addElem("proto", static_cast<uint8_t>(frame->proto));
json->addElem("valid", frame->valid);
json->addElem("sync", frame->hwsync);
json->beginArray("pulses");
if(rx) {
for(uint16_t i = 0; i < rx->pulseCount; i++) {
json->addElem(rx->pulses[i]);
}
}
json->endArray();
json->endObject();
sockEmit.endEmitRoom(ROOM_EMIT_FRAME);
/*
ClientSocketEvent evt("remoteFrame"); ClientSocketEvent evt("remoteFrame");
char buf[30]; char buf[30];
snprintf(buf, sizeof(buf), "{\"encKey\":%d,", frame->encKey); snprintf(buf, sizeof(buf), "{\"encKey\":%d,", frame->encKey);
@ -4291,6 +4539,7 @@ void Transceiver::emitFrame(somfy_frame_t *frame, somfy_rx_t *rx) {
} }
evt.appendMessage("]}"); evt.appendMessage("]}");
sockEmit.sendToRoom(ROOM_EMIT_FRAME, &evt); sockEmit.sendToRoom(ROOM_EMIT_FRAME, &evt);
*/
} }
} }
void Transceiver::clearReceived(void) { void Transceiver::clearReceived(void) {
@ -4317,6 +4566,12 @@ void Transceiver::disableReceive(void) {
interruptPin = 0; interruptPin = 0;
} }
void Transceiver::toJSON(JsonResponse& json) {
json.beginObject("config");
this->config.toJSON(json);
json.endObject();
}
bool Transceiver::toJSON(JsonObject& obj) { bool Transceiver::toJSON(JsonObject& obj) {
//Serial.println("Setting Transceiver Json"); //Serial.println("Setting Transceiver Json");
JsonObject objConfig = obj.createNestedObject("config"); JsonObject objConfig = obj.createNestedObject("config");
@ -4393,6 +4648,22 @@ void transceiver_config_t::fromJSON(JsonObject& obj) {
*/ */
Serial.printf("SCK:%u MISO:%u MOSI:%u CSN:%u RX:%u TX:%u\n", this->SCKPin, this->MISOPin, this->MOSIPin, this->CSNPin, this->RXPin, this->TXPin); Serial.printf("SCK:%u MISO:%u MOSI:%u CSN:%u RX:%u TX:%u\n", this->SCKPin, this->MISOPin, this->MOSIPin, this->CSNPin, this->RXPin, this->TXPin);
} }
void transceiver_config_t::toJSON(JsonResponse &json) {
json.addElem("type", this->type);
json.addElem("TXPin", this->TXPin);
json.addElem("RXPin", this->RXPin);
json.addElem("SCKPin", this->SCKPin);
json.addElem("MOSIPin", this->MOSIPin);
json.addElem("MISOPin", this->MISOPin);
json.addElem("CSNPin", this->CSNPin);
json.addElem("rxBandwidth", this->rxBandwidth); // float
json.addElem("frequency", this->frequency); // float
json.addElem("deviation", this->deviation); // float
json.addElem("txPower", this->txPower);
json.addElem("proto", static_cast<uint8_t>(this->proto));
json.addElem("enabled", this->enabled);
json.addElem("radioInit", this->radioInit);
}
void transceiver_config_t::toJSON(JsonObject& obj) { void transceiver_config_t::toJSON(JsonObject& obj) {
obj["type"] = this->type; obj["type"] = this->type;
obj["TXPin"] = this->TXPin; obj["TXPin"] = this->TXPin;

29
Somfy.h
View file

@ -1,6 +1,7 @@
#ifndef SOMFY_H #ifndef SOMFY_H
#define SOMFY_H #define SOMFY_H
#include "ConfigSettings.h" #include "ConfigSettings.h"
#include "WResp.h"
#define SOMFY_MAX_SHADES 32 #define SOMFY_MAX_SHADES 32
#define SOMFY_MAX_GROUPS 16 #define SOMFY_MAX_GROUPS 16
@ -197,6 +198,7 @@ class SomfyRoom {
bool save(); bool save();
bool fromJSON(JsonObject &obj); bool fromJSON(JsonObject &obj);
bool toJSON(JsonObject &obj); bool toJSON(JsonObject &obj);
void toJSON(JsonResponse &json);
void emitState(const char *evt = "roomState"); void emitState(const char *evt = "roomState");
void emitState(uint8_t num, const char *evt = "roomState"); void emitState(uint8_t num, const char *evt = "roomState");
void publish(); void publish();
@ -227,6 +229,7 @@ class SomfyRemote {
virtual bool isLastCommand(somfy_commands cmd); virtual bool isLastCommand(somfy_commands cmd);
char *getRemotePrefId() {return m_remotePrefId;} char *getRemotePrefId() {return m_remotePrefId;}
virtual bool toJSON(JsonObject &obj); virtual bool toJSON(JsonObject &obj);
virtual void toJSON(JsonResponse &json);
virtual void setRemoteAddress(uint32_t address); virtual void setRemoteAddress(uint32_t address);
virtual uint32_t getRemoteAddress(); virtual uint32_t getRemoteAddress();
virtual uint16_t getNextRollingCode(); virtual uint16_t getNextRollingCode();
@ -291,9 +294,12 @@ class SomfyShade : public SomfyRemote {
SomfyLinkedRemote linkedRemotes[SOMFY_MAX_LINKED_REMOTES]; SomfyLinkedRemote linkedRemotes[SOMFY_MAX_LINKED_REMOTES];
bool paired = false; bool paired = false;
int8_t validateJSON(JsonObject &obj); int8_t validateJSON(JsonObject &obj);
bool toJSONRef(JsonObject &obj); //bool toJSONRef(JsonObject &obj);
void toJSONRef(JsonResponse &json);
int8_t fromJSON(JsonObject &obj); int8_t fromJSON(JsonObject &obj);
bool toJSON(JsonObject &obj) override; bool toJSON(JsonObject &obj) override;
void toJSON(JsonResponse &json) override;
char name[21] = ""; char name[21] = "";
void setShadeId(uint8_t id) { shadeId = id; } void setShadeId(uint8_t id) { shadeId = id; }
uint8_t getShadeId() { return shadeId; } uint8_t getShadeId() { return shadeId; }
@ -377,7 +383,10 @@ class SomfyGroup : public SomfyRemote {
bool save(); bool save();
void clear(); void clear();
bool fromJSON(JsonObject &obj); bool fromJSON(JsonObject &obj);
bool toJSON(JsonObject &obj); //bool toJSON(JsonObject &obj);
void toJSON(JsonResponse &json);
void toJSONRef(JsonResponse &json);
bool linkShade(uint8_t shadeId); bool linkShade(uint8_t shadeId);
bool unlinkShade(uint8_t shadeId); bool unlinkShade(uint8_t shadeId);
bool hasShadeId(uint8_t shadeId); bool hasShadeId(uint8_t shadeId);
@ -467,6 +476,7 @@ struct transceiver_config_t {
*/ */
void fromJSON(JsonObject& obj); void fromJSON(JsonObject& obj);
void toJSON(JsonObject& obj); void toJSON(JsonObject& obj);
void toJSON(JsonResponse& json);
void save(); void save();
void load(); void load();
void apply(); void apply();
@ -481,6 +491,7 @@ class Transceiver {
transceiver_config_t config; transceiver_config_t config;
bool printBuffer = false; bool printBuffer = false;
bool toJSON(JsonObject& obj); bool toJSON(JsonObject& obj);
void toJSON(JsonResponse& json);
bool fromJSON(JsonObject& obj); bool fromJSON(JsonObject& obj);
bool save(); bool save();
bool begin(); bool begin();
@ -537,11 +548,15 @@ class SomfyShadeController {
SomfyGroup groups[SOMFY_MAX_GROUPS]; SomfyGroup groups[SOMFY_MAX_GROUPS];
bool linkRepeater(uint32_t address); bool linkRepeater(uint32_t address);
bool unlinkRepeater(uint32_t address); bool unlinkRepeater(uint32_t address);
bool toJSON(DynamicJsonDocument &doc); //bool toJSON(DynamicJsonDocument &doc);
bool toJSON(JsonObject &obj); //bool toJSON(JsonObject &obj);
bool toJSONRooms(JsonArray &arr); //bool toJSONRooms(JsonArray &arr);
bool toJSONShades(JsonArray &arr); //bool toJSONShades(JsonArray &arr);
bool toJSONGroups(JsonArray &arr); //bool toJSONGroups(JsonArray &arr);
void toJSONShades(JsonResponse &json);
void toJSONRooms(JsonResponse &json);
void toJSONGroups(JsonResponse &json);
void toJSONRepeaters(JsonResponse &json);
bool toJSONRepeaters(JsonArray &arr); bool toJSONRepeaters(JsonArray &arr);
uint8_t repeaterCount(); uint8_t repeaterCount();
uint8_t roomCount(); uint8_t roomCount();

Binary file not shown.

Binary file not shown.

Binary file not shown.

139
WResp.cpp Normal file
View file

@ -0,0 +1,139 @@
#include "WResp.h"
void JsonSockEvent::beginEvent(WebSocketsServer *server, const char *evt, char *buff, size_t buffSize) {
this->server = server;
this->buff = buff;
this->buffSize = buffSize;
this->_nocomma = true;
this->_closed = false;
snprintf(this->buff, buffSize, "42[%s,", evt);
}
void JsonSockEvent::closeEvent() {
if(!this->_closed) {
if(strlen(this->buff) < buffSize) strcat(this->buff, "]");
else this->buff[buffSize - 1] = ']';
}
this->_nocomma = true;
this->_closed = true;
}
void JsonSockEvent::endEvent(uint8_t num) {
this->closeEvent();
if(num == 255) this->server->broadcastTXT(this->buff);
else this->server->sendTXT(num, this->buff);
}
void JsonSockEvent::_safecat(const char *val, bool escape) {
size_t len = strlen(val) + strlen(this->buff);
if(escape) len += 2;
if(len >= this->buffSize) {
Serial.printf("Socket exceeded buffer size %d - %d\n", this->buffSize, len);
Serial.println(this->buff);
return;
}
if(escape) strcat(this->buff, "\"");
strcat(this->buff, val);
if(escape) strcat(this->buff, "\"");
}
void JsonResponse::beginResponse(WebServer *server, char *buff, size_t buffSize) {
this->server = server;
this->buff = buff;
this->buffSize = buffSize;
this->buff[0] = 0x00;
this->_nocomma = true;
server->setContentLength(CONTENT_LENGTH_UNKNOWN);
}
void JsonResponse::endResponse() {
if(strlen(buff)) this->send();
server->sendContent("", 0);
}
void JsonResponse::send() {
if(!this->_headersSent) server->send_P(200, "application/json", this->buff);
else server->sendContent(this->buff);
//Serial.printf("Sent %d bytes %d\n", strlen(this->buff), this->buffSize);
this->buff[0] = 0x00;
this->_headersSent = true;
}
void JsonResponse::_safecat(const char *val, bool escape) {
size_t len = strlen(val) + strlen(this->buff);
if(escape) len += 2;
if(len >= this->buffSize) {
this->send();
}
if(escape) strcat(this->buff, "\"");
strcat(this->buff, val);
if(escape) strcat(this->buff, "\"");
}
void JsonFormatter::beginObject(const char *name) {
if(name && strlen(name) > 0) this->appendElem(name);
else if(!this->_nocomma) this->_safecat(",");
this->_safecat("{");
this->_objects++;
this->_nocomma = true;
}
void JsonFormatter::endObject() {
//if(strlen(this->buff) + 1 > this->buffSize - 1) this->send();
this->_safecat("}");
this->_objects--;
this->_nocomma = false;
}
void JsonFormatter::beginArray(const char *name) {
if(name && strlen(name) > 0) this->appendElem(name);
else if(!this->_nocomma) this->_safecat(",");
this->_safecat("[");
this->_arrays++;
this->_nocomma = true;
}
void JsonFormatter::endArray() {
//if(strlen(this->buff) + 1 > this->buffSize - 1) this->send();
this->_safecat("]");
this->_arrays--;
this->_nocomma = false;
}
void JsonFormatter::appendElem(const char *name) {
if(!this->_nocomma) this->_safecat(",");
if(name && strlen(name) > 0) {
this->_safecat(name, true);
this->_safecat(":");
}
this->_nocomma = false;
}
void JsonFormatter::addElem(const char *name, const char *val) {
if(!val) return;
this->appendElem(name);
this->_safecat(val, true);
}
void JsonFormatter::addElem(const char *val) { this->addElem(nullptr, val); }
void JsonFormatter::addElem(float fval) { sprintf(this->_numbuff, "%.4f", fval); this->_appendNumber(nullptr); }
void JsonFormatter::addElem(int8_t nval) { sprintf(this->_numbuff, "%d", nval); this->_appendNumber(nullptr); }
void JsonFormatter::addElem(uint8_t nval) { sprintf(this->_numbuff, "%u", nval); this->_appendNumber(nullptr); }
void JsonFormatter::addElem(int16_t nval) { sprintf(this->_numbuff, "%d", nval); this->_appendNumber(nullptr); }
void JsonFormatter::addElem(uint16_t nval) { sprintf(this->_numbuff, "%u", nval); this->_appendNumber(nullptr); }
void JsonFormatter::addElem(int32_t nval) { sprintf(this->_numbuff, "%ld", (long)nval); this->_appendNumber(nullptr); }
void JsonFormatter::addElem(uint32_t nval) { sprintf(this->_numbuff, "%lu", (unsigned long)nval); this->_appendNumber(nullptr); }
void JsonFormatter::addElem(int64_t lval) { sprintf(this->_numbuff, "%lld", (long long)lval); this->_appendNumber(nullptr); }
void JsonFormatter::addElem(uint64_t lval) { sprintf(this->_numbuff, "%llu", (unsigned long long)lval); this->_appendNumber(nullptr); }
void JsonFormatter::addElem(bool bval) { strcpy(this->_numbuff, bval ? "true" : "false"); this->_appendNumber(nullptr); }
void JsonFormatter::addElem(const char *name, float fval) { sprintf(this->_numbuff, "%.4f", fval); this->_appendNumber(name); }
void JsonFormatter::addElem(const char *name, int8_t nval) { sprintf(this->_numbuff, "%d", nval); this->_appendNumber(name); }
void JsonFormatter::addElem(const char *name, uint8_t nval) { sprintf(this->_numbuff, "%u", nval); this->_appendNumber(name); }
void JsonFormatter::addElem(const char *name, int16_t nval) { sprintf(this->_numbuff, "%d", nval); this->_appendNumber(name); }
void JsonFormatter::addElem(const char *name, uint16_t nval) { sprintf(this->_numbuff, "%u", nval); this->_appendNumber(name); }
void JsonFormatter::addElem(const char *name, int32_t nval) { sprintf(this->_numbuff, "%ld", (long)nval); this->_appendNumber(name); }
void JsonFormatter::addElem(const char *name, uint32_t nval) { sprintf(this->_numbuff, "%lu", (unsigned long)nval); this->_appendNumber(name); }
void JsonFormatter::addElem(const char *name, int64_t lval) { sprintf(this->_numbuff, "%lld", (long long)lval); this->_appendNumber(name); }
void JsonFormatter::addElem(const char *name, uint64_t lval) { sprintf(this->_numbuff, "%llu", (unsigned long long)lval); this->_appendNumber(name); }
void JsonFormatter::addElem(const char *name, bool bval) { strcpy(this->_numbuff, bval ? "true" : "false"); this->_appendNumber(name); }
void JsonFormatter::_safecat(const char *val, bool escape) {
size_t len = strlen(val) + strlen(this->buff);
if(escape) len += 2;
if(len >= this->buffSize) {
return;
}
if(escape) strcat(this->buff, "\"");
strcat(this->buff, val);
if(escape) strcat(this->buff, "\"");
}
void JsonFormatter::_appendNumber(const char *name) { this->appendElem(name); this->_safecat(this->_numbuff); }

68
WResp.h Normal file
View file

@ -0,0 +1,68 @@
#include <WebServer.h>
#include <WebSocketsServer.h>
#include "Somfy.h"
#ifndef wresp_h
#define wresp_h
class JsonFormatter {
protected:
char *buff;
size_t buffSize;
bool _headersSent = false;
uint8_t _objects = 0;
uint8_t _arrays = 0;
bool _nocomma = true;
char _numbuff[25] = {0};
virtual void _safecat(const char *val, bool escape = false);
void _appendNumber(const char *name);
public:
void beginObject(const char *name = nullptr);
void endObject();
void beginArray(const char *name = nullptr);
void endArray();
void appendElem(const char *name = nullptr);
void addElem(const char* val);
void addElem(float fval);
void addElem(int8_t nval);
void addElem(uint8_t nval);
void addElem(int16_t nval);
void addElem(uint16_t nval);
void addElem(int32_t nval);
void addElem(uint32_t nval);
void addElem(int64_t lval);
void addElem(uint64_t lval);
void addElem(bool bval);
void addElem(const char* name, float fval);
void addElem(const char* name, int8_t nval);
void addElem(const char* name, uint8_t nval);
void addElem(const char* name, int16_t nval);
void addElem(const char* name, uint16_t nval);
void addElem(const char* name, int32_t nval);
void addElem(const char* name, uint32_t nval);
void addElem(const char* name, int64_t lval);
void addElem(const char* name, uint64_t lval);
void addElem(const char* name, bool bval);
void addElem(const char *name, const char *val);
};
class JsonResponse : public JsonFormatter {
protected:
void _safecat(const char *val, bool escape = false) override;
public:
WebServer *server;
void beginResponse(WebServer *server, char *buff, size_t buffSize);
void endResponse();
void send();
};
class JsonSockEvent : public JsonFormatter {
protected:
bool _closed = false;
void _safecat(const char *val, bool escape = false) override;
public:
WebSocketsServer *server = nullptr;
void beginEvent(WebSocketsServer *server, const char *evt, char *buff, size_t buffSize);
void endEvent(uint8_t clientNum = 255);
void closeEvent();
};
#endif

823
Web.cpp

File diff suppressed because it is too large Load diff

9
Web.h
View file

@ -42,10 +42,9 @@ class Web {
bool createAPIPasswordToken(const IPAddress ipAddress, const char *username, const char *password, char *token); bool createAPIPasswordToken(const IPAddress ipAddress, const char *username, const char *password, char *token);
bool isAuthenticated(WebServer &server, bool cfg = false); bool isAuthenticated(WebServer &server, bool cfg = false);
void chunkRoomsResponse(WebServer &server, const char *elem = nullptr); //void chunkRoomsResponse(WebServer &server, const char *elem = nullptr);
void chunkShadesResponse(WebServer &server, const char *elem = nullptr); //void chunkShadesResponse(WebServer &server, const char *elem = nullptr);
void chunkGroupsResponse(WebServer &server, const char *elem = nullptr); //void chunkGroupsResponse(WebServer &server, const char *elem = nullptr);
void chunkGroupResponse(WebServer &server, SomfyGroup *, const char *prefix = nullptr); //void chunkGroupResponse(WebServer &server, SomfyGroup *, const char *prefix = nullptr);
}; };
#endif #endif

View file

@ -3,11 +3,11 @@
<head> <head>
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="stylesheet" href="main.css?v=2.4.1r" type="text/css" /> <link rel="stylesheet" href="main.css?v=2.4.2b" type="text/css" />
<link rel="stylesheet" href="widgets.css?v=2.4.1r" type="text/css" /> <link rel="stylesheet" href="widgets.css?v=2.4.2b" type="text/css" />
<link rel="stylesheet" href="icons.css?v=2.4.1r" type="text/css" /> <link rel="stylesheet" href="icons.css?v=2.4.2b" type="text/css" />
<link rel="icon" type="image/png" href="favicon.png" /> <link rel="icon" type="image/png" href="favicon.png" />
<script type="text/javascript" src="index.js?v=2.4.1r"></script> <script type="text/javascript" src="index.js?v=2.4.2b"></script>
</head> </head>
<body> <body>
<div id="divContainer" class="container main" data-auth="false"> <div id="divContainer" class="container main" data-auth="false">

View file

@ -1,5 +1,6 @@
//var hst = '192.168.1.208'; //var hst = '192.168.1.208';
var hst = '192.168.1.152'; //var hst = '192.168.1.152';
var hst = '192.168.1.159';
var _rooms = [{ roomId: 0, name: 'Home' }]; var _rooms = [{ roomId: 0, name: 'Home' }];
var errors = [ var errors = [
@ -562,6 +563,8 @@ async function initSockets() {
await wifi.loadNetwork(); await wifi.loadNetwork();
await somfy.loadSomfy(); await somfy.loadSomfy();
await mqtt.loadMQTT(); await mqtt.loadMQTT();
if (ui.isConfigOpen()) socket.send('join:0');
//await general.init(); //await general.init();
//await somfy.init(); //await somfy.init();
//await mqtt.init(); //await mqtt.init();
@ -1264,7 +1267,7 @@ var security = new Security();
class General { class General {
initialized = false; initialized = false;
appVersion = 'v2.4.1'; appVersion = 'v2.4.2';
reloadApp = false; reloadApp = false;
init() { init() {
if (this.initialized) return; if (this.initialized) return;
@ -2582,12 +2585,15 @@ class Somfy {
divCtl += `<span class="groupctl-name">${group.name}</span>`; divCtl += `<span class="groupctl-name">${group.name}</span>`;
divCtl += `<div class="groupctl-shades">`; divCtl += `<div class="groupctl-shades">`;
if (typeof group.linkedShades !== 'undefined') { if (typeof group.linkedShades !== 'undefined') {
divCtl += `<label>Members:</label><span>${group.linkedShades.length}`;
/*
for (let j = 0; j < group.linkedShades.length; j++) { for (let j = 0; j < group.linkedShades.length; j++) {
divCtl += '<span>'; divCtl += '<span>';
if (j !== 0) divCtl += ', '; if (j !== 0) divCtl += ', ';
divCtl += group.linkedShades[j].name; divCtl += group.linkedShades[j].name;
divCtl += '</span>'; divCtl += '</span>';
} }
*/
} }
divCtl += '</div></div>'; divCtl += '</div></div>';
divCtl += `<div class="groupctl-buttons">`; divCtl += `<div class="groupctl-buttons">`;

View file

@ -651,7 +651,10 @@ div.wait-overlay > .lds-roller {
} }
.somfyGroupCtl .groupctl-shades { .somfyGroupCtl .groupctl-shades {
font-size:12px; font-size:12px;
margin-top:-3px; margin-top:0px;
}
.somfyGroupCtl .groupctl-shades > label {
margin-right:3px;
} }
.somfyGroupCtl .groupctl-name, .somfyGroupCtl .groupctl-name,
.somfyShadeCtl .shadectl-name { .somfyShadeCtl .shadectl-name {