mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-03-24 01:40:20 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c74e719327 | ||
|
|
8c8e14f60c | ||
|
|
3b93897a8e | ||
|
|
e080c7d535 | ||
|
|
64ea8c4888 | ||
|
|
e7ae24b26f |
@@ -295,7 +295,7 @@ public:
|
|||||||
|
|
||||||
bool getGpioConfig(GpioConfig&);
|
bool getGpioConfig(GpioConfig&);
|
||||||
bool setGpioConfig(GpioConfig&);
|
bool setGpioConfig(GpioConfig&);
|
||||||
void clearGpio(GpioConfig&);
|
void clearGpio(GpioConfig& config, bool all=true);
|
||||||
|
|
||||||
void print(Print* debugger);
|
void print(Print* debugger);
|
||||||
|
|
||||||
|
|||||||
@@ -518,7 +518,7 @@ bool AmsConfiguration::setGpioConfig(GpioConfig& config) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AmsConfiguration::clearGpio(GpioConfig& config) {
|
void AmsConfiguration::clearGpio(GpioConfig& config, bool all) {
|
||||||
config.apPin = 0xFF;
|
config.apPin = 0xFF;
|
||||||
config.ledPin = 0xFF;
|
config.ledPin = 0xFF;
|
||||||
config.ledInverted = true;
|
config.ledInverted = true;
|
||||||
@@ -529,13 +529,16 @@ void AmsConfiguration::clearGpio(GpioConfig& config) {
|
|||||||
config.tempSensorPin = 0xFF;
|
config.tempSensorPin = 0xFF;
|
||||||
config.tempAnalogSensorPin = 0xFF;
|
config.tempAnalogSensorPin = 0xFF;
|
||||||
config.vccPin = 0xFF;
|
config.vccPin = 0xFF;
|
||||||
config.vccOffset = 0;
|
|
||||||
config.vccMultiplier = 1000;
|
|
||||||
config.vccBootLimit = 0;
|
|
||||||
config.vccResistorGnd = 0;
|
|
||||||
config.vccResistorVcc = 0;
|
|
||||||
config.ledDisablePin = 0xFF;
|
config.ledDisablePin = 0xFF;
|
||||||
config.ledBehaviour = LED_BEHAVIOUR_DEFAULT;
|
|
||||||
|
if(all) {
|
||||||
|
config.vccOffset = 0;
|
||||||
|
config.vccMultiplier = 1000;
|
||||||
|
config.vccBootLimit = 0;
|
||||||
|
config.vccResistorGnd = 0;
|
||||||
|
config.vccResistorVcc = 0;
|
||||||
|
config.ledBehaviour = LED_BEHAVIOUR_DEFAULT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AmsConfiguration::getNtpConfig(NtpConfig& config) {
|
bool AmsConfiguration::getNtpConfig(NtpConfig& config) {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ static const char CC_JSON_POWER_LIST3[] PROGMEM = ",\"%s\":{\"P\":%lu,\"Q\":%lu,
|
|||||||
static const char CC_JSON_PHASE[] PROGMEM = "%s\"%d\":{\"u\":%.2f,\"i\":%s}";
|
static const char CC_JSON_PHASE[] PROGMEM = "%s\"%d\":{\"u\":%.2f,\"i\":%s}";
|
||||||
static const char CC_JSON_PHASE_LIST4[] PROGMEM = "%s\"%d\":{\"u\":%.2f,\"i\":%s,\"Pim\":%lu,\"Pex\":%lu,\"pf\":%.2f}";
|
static const char CC_JSON_PHASE_LIST4[] PROGMEM = "%s\"%d\":{\"u\":%.2f,\"i\":%s,\"Pim\":%lu,\"Pex\":%lu,\"pf\":%.2f}";
|
||||||
static const char CC_JSON_STATUS[] PROGMEM = ",\"status\":{\"esp\":{\"state\":%d,\"error\":%d},\"han\":{\"state\":%d,\"error\":%d},\"wifi\":{\"state\":%d,\"error\":%d},\"mqtt\":{\"state\":%d,\"error\":%d}}";
|
static const char CC_JSON_STATUS[] PROGMEM = ",\"status\":{\"esp\":{\"state\":%d,\"error\":%d},\"han\":{\"state\":%d,\"error\":%d},\"wifi\":{\"state\":%d,\"error\":%d},\"mqtt\":{\"state\":%d,\"error\":%d}}";
|
||||||
static const char CC_JSON_INIT[] PROGMEM = ",\"init\":{\"mac\":\"%s\",\"apmac\":\"%s\",\"version\":\"%s\",\"boardType\":%d,\"bootReason\":%d,\"bootCause\":%d,\"utcOffset\":%d},\"meter\":{\"manufacturerId\":%d,\"manufacturer\":\"%s\",\"model\":\"%s\",\"id\":\"%s\",\"system\":\"%s\",\"fuse\":%d,\"import\":%d,\"export\":%d},\"network\":{\"ip\":\"%s\",\"mask\":\"%s\",\"gw\":\"%s\",\"dns1\":\"%s\",\"dns2\":\"%s\"}";
|
static const char CC_JSON_INIT[] PROGMEM = ",\"init\":{\"mac\":\"%s\",\"apmac\":\"%s\",\"version\":\"%s\",\"boardType\":%d,\"bootReason\":%d,\"bootCause\":%d,\"tz\":\"%s\"},\"meter\":{\"manufacturerId\":%d,\"manufacturer\":\"%s\",\"model\":\"%s\",\"id\":\"%s\",\"system\":\"%s\",\"fuse\":%d,\"import\":%d,\"export\":%d},\"network\":{\"ip\":\"%s\",\"mask\":\"%s\",\"gw\":\"%s\",\"dns1\":\"%s\",\"dns2\":\"%s\"}";
|
||||||
|
|
||||||
struct CloudData {
|
struct CloudData {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
@@ -52,11 +52,12 @@ struct CloudData {
|
|||||||
class CloudConnector {
|
class CloudConnector {
|
||||||
public:
|
public:
|
||||||
CloudConnector(RemoteDebug*);
|
CloudConnector(RemoteDebug*);
|
||||||
bool setup(CloudConfig& config, MeterConfig& meter, SystemConfig& system, HwTools* hw, ResetDataContainer* rdc);
|
bool setup(CloudConfig& config, MeterConfig& meter, SystemConfig& system, NtpConfig& ntp, HwTools* hw, ResetDataContainer* rdc);
|
||||||
void setMqttHandler(AmsMqttHandler* mqttHandler);
|
void setMqttHandler(AmsMqttHandler* mqttHandler);
|
||||||
void update(AmsData& data, EnergyAccounting& ea);
|
void update(AmsData& data, EnergyAccounting& ea);
|
||||||
|
void setPriceConfig(PriceServiceConfig&);
|
||||||
|
void setEnergyAccountingConfig(EnergyAccountingConfig&);
|
||||||
void forceUpdate();
|
void forceUpdate();
|
||||||
void setTimezone(Timezone* tz);
|
|
||||||
void setConnectionHandler(ConnectionHandler* ch);
|
void setConnectionHandler(ConnectionHandler* ch);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -64,13 +65,17 @@ private:
|
|||||||
HwTools* hw = NULL;
|
HwTools* hw = NULL;
|
||||||
ConnectionHandler* ch = NULL;
|
ConnectionHandler* ch = NULL;
|
||||||
ResetDataContainer* rdc = NULL;
|
ResetDataContainer* rdc = NULL;
|
||||||
Timezone* tz = NULL;
|
|
||||||
AmsMqttHandler* mqttHandler = NULL;
|
AmsMqttHandler* mqttHandler = NULL;
|
||||||
CloudConfig config;
|
CloudConfig config;
|
||||||
|
PriceServiceConfig priceConfig;
|
||||||
|
unsigned long lastPriceConfig = 0;
|
||||||
|
EnergyAccountingConfig eac;
|
||||||
|
unsigned long lastEac = 0;
|
||||||
HTTPClient http;
|
HTTPClient http;
|
||||||
WiFiUDP udp;
|
WiFiUDP udp;
|
||||||
int maxPwr = 0;
|
int maxPwr = 0;
|
||||||
uint8_t boardType = 0;
|
uint8_t boardType = 0;
|
||||||
|
char timezone[32];
|
||||||
uint8_t distributionSystem = 0;
|
uint8_t distributionSystem = 0;
|
||||||
uint16_t mainFuse = 0, productionCapacity = 0;
|
uint16_t mainFuse = 0, productionCapacity = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ CloudConnector::CloudConnector(RemoteDebug* debugger) {
|
|||||||
sprintf_P(this->apmac, PSTR("%02X:%02X:%02X:%02X:%02X:%02X"), apmac[0], apmac[1], apmac[2], apmac[3], apmac[4], apmac[5]);
|
sprintf_P(this->apmac, PSTR("%02X:%02X:%02X:%02X:%02X:%02X"), apmac[0], apmac[1], apmac[2], apmac[3], apmac[4], apmac[5]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CloudConnector::setup(CloudConfig& config, MeterConfig& meter, SystemConfig& system, HwTools* hw, ResetDataContainer* rdc) {
|
bool CloudConnector::setup(CloudConfig& config, MeterConfig& meter, SystemConfig& system, NtpConfig& ntp, HwTools* hw, ResetDataContainer* rdc) {
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
#if defined(ESP32)
|
#if defined(ESP32)
|
||||||
if(!ESPRandom::isValidV4Uuid(config.clientId)) {
|
if(!ESPRandom::isValidV4Uuid(config.clientId)) {
|
||||||
@@ -61,6 +61,7 @@ bool CloudConnector::setup(CloudConfig& config, MeterConfig& meter, SystemConfig
|
|||||||
this->rdc = rdc;
|
this->rdc = rdc;
|
||||||
|
|
||||||
this->boardType = system.boardType;
|
this->boardType = system.boardType;
|
||||||
|
strcpy(this->timezone, ntp.timezone);
|
||||||
|
|
||||||
this->maxPwr = 0;
|
this->maxPwr = 0;
|
||||||
this->distributionSystem = meter.distributionSystem;
|
this->distributionSystem = meter.distributionSystem;
|
||||||
@@ -204,7 +205,7 @@ void CloudConnector::update(AmsData& data, EnergyAccounting& ea) {
|
|||||||
boardType,
|
boardType,
|
||||||
rtc_get_reset_reason(0),
|
rtc_get_reset_reason(0),
|
||||||
rdc == NULL ? 0 : rdc->last_cause,
|
rdc == NULL ? 0 : rdc->last_cause,
|
||||||
tz == NULL ? 0 : (tz->toLocal(now)-now)/3600,
|
timezone,
|
||||||
data.getMeterType(),
|
data.getMeterType(),
|
||||||
meterManufacturer(data.getMeterType()).c_str(),
|
meterManufacturer(data.getMeterType()).c_str(),
|
||||||
data.getMeterModel().c_str(),
|
data.getMeterModel().c_str(),
|
||||||
@@ -219,6 +220,23 @@ void CloudConnector::update(AmsData& data, EnergyAccounting& ea) {
|
|||||||
dns1.toString().c_str(),
|
dns1.toString().c_str(),
|
||||||
dns2.toString().c_str()
|
dns2.toString().c_str()
|
||||||
);
|
);
|
||||||
|
} else if(lastPriceConfig == 0) {
|
||||||
|
pos += snprintf_P(clearBuffer+pos, CC_BUF_SIZE-pos, PSTR(",\"price\":{\"area\":\"%s\",\"currency\":\"%s\"}"), priceConfig.area, priceConfig.currency);
|
||||||
|
lastPriceConfig = now;
|
||||||
|
} else if(lastEac == 0) {
|
||||||
|
pos += snprintf_P(clearBuffer+pos, CC_BUF_SIZE-pos, PSTR(",\"accounting\":{\"hours\":%d,\"thresholds\":[%d,%d,%d,%d,%d,%d,%d,%d,%d]}"),
|
||||||
|
eac.hours,
|
||||||
|
eac.thresholds[0],
|
||||||
|
eac.thresholds[1],
|
||||||
|
eac.thresholds[2],
|
||||||
|
eac.thresholds[3],
|
||||||
|
eac.thresholds[4],
|
||||||
|
eac.thresholds[5],
|
||||||
|
eac.thresholds[6],
|
||||||
|
eac.thresholds[7],
|
||||||
|
eac.thresholds[8]
|
||||||
|
);
|
||||||
|
lastEac = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
float vcc = 0.0;
|
float vcc = 0.0;
|
||||||
@@ -382,16 +400,24 @@ void CloudConnector::update(AmsData& data, EnergyAccounting& ea) {
|
|||||||
|
|
||||||
void CloudConnector::forceUpdate() {
|
void CloudConnector::forceUpdate() {
|
||||||
lastUpdate = 0;
|
lastUpdate = 0;
|
||||||
}
|
lastPriceConfig = 0;
|
||||||
|
lastEac = 0;
|
||||||
void CloudConnector::setTimezone(Timezone* tz) {
|
|
||||||
this->tz = tz;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloudConnector::setConnectionHandler(ConnectionHandler* ch) {
|
void CloudConnector::setConnectionHandler(ConnectionHandler* ch) {
|
||||||
this->ch = ch;
|
this->ch = ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CloudConnector::setPriceConfig(PriceServiceConfig& priceConfig) {
|
||||||
|
this->priceConfig = priceConfig;
|
||||||
|
this->lastPriceConfig = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CloudConnector::setEnergyAccountingConfig(EnergyAccountingConfig& eac) {
|
||||||
|
this->eac = eac;
|
||||||
|
this->lastEac = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void CloudConnector::debugPrint(byte *buffer, int start, int length) {
|
void CloudConnector::debugPrint(byte *buffer, int start, int length) {
|
||||||
for (int i = start; i < start + length; i++) {
|
for (int i = start; i < start + length; i++) {
|
||||||
if (buffer[i] < 0x10)
|
if (buffer[i] < 0x10)
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ bool WiFiClientConnectionHandler::connect(NetworkConfig config, SystemConfig sys
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
WiFi.setAutoReconnect(true);
|
WiFi.setAutoReconnect(true);
|
||||||
|
this->config = config;
|
||||||
#if defined(ESP32)
|
#if defined(ESP32)
|
||||||
if(begin(config.ssid, config.psk)) {
|
if(begin(config.ssid, config.psk)) {
|
||||||
#else
|
#else
|
||||||
@@ -112,7 +113,6 @@ bool WiFiClientConnectionHandler::connect(NetworkConfig config, SystemConfig sys
|
|||||||
} else {
|
} else {
|
||||||
if (debugger->isActive(RemoteDebug::ERROR)) debugger->printf_P(PSTR("Unable to start WiFi\n"));
|
if (debugger->isActive(RemoteDebug::ERROR)) debugger->printf_P(PSTR("Unable to start WiFi\n"));
|
||||||
}
|
}
|
||||||
this->config = config;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -164,7 +164,7 @@ wl_status_t WiFiClientConnectionHandler::begin(const char* ssid, const char* pas
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(strlen(config.ip) > 0){
|
if(strlen(config.ip) == 0){
|
||||||
if(set_esp_interface_ip(ESP_IF_WIFI_STA) != ESP_OK) {
|
if(set_esp_interface_ip(ESP_IF_WIFI_STA) != ESP_OK) {
|
||||||
return WL_CONNECT_FAILED;
|
return WL_CONNECT_FAILED;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,6 +142,8 @@ private:
|
|||||||
void redirectToMain();
|
void redirectToMain();
|
||||||
void robotstxt();
|
void robotstxt();
|
||||||
void ssdpSchema();
|
void ssdpSchema();
|
||||||
|
|
||||||
|
void updaterRequestCallback(HTTPClient*);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1652,7 +1652,11 @@ void AmsWebServer::upgradeFromUrl(String url, String nextVersion) {
|
|||||||
|
|
||||||
httpUpdate.rebootOnUpdate(false);
|
httpUpdate.rebootOnUpdate(false);
|
||||||
httpUpdate.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
|
httpUpdate.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
|
||||||
|
#if defined(ESP32)
|
||||||
|
HTTPUpdateResult ret = httpUpdate.update(client, url, currentVersion, std::bind(&AmsWebServer::updaterRequestCallback, this, std::placeholders::_1));
|
||||||
|
#else
|
||||||
HTTPUpdateResult ret = httpUpdate.update(client, url, currentVersion);
|
HTTPUpdateResult ret = httpUpdate.update(client, url, currentVersion);
|
||||||
|
#endif
|
||||||
int lastError = httpUpdate.getLastError();
|
int lastError = httpUpdate.getLastError();
|
||||||
|
|
||||||
config->setUpgradeInformation(ret, ret == HTTP_UPDATE_OK ? 0 : lastError, FirmwareVersion::VersionString, nextVersion.c_str());
|
config->setUpgradeInformation(ret, ret == HTTP_UPDATE_OK ? 0 : lastError, FirmwareVersion::VersionString, nextVersion.c_str());
|
||||||
@@ -1672,6 +1676,19 @@ void AmsWebServer::upgradeFromUrl(String url, String nextVersion) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AmsWebServer::updaterRequestCallback(HTTPClient* http) {
|
||||||
|
SystemConfig sys;
|
||||||
|
if(config->getSystemConfig(sys)) {
|
||||||
|
http->addHeader(F("x-AMS-board-type"), String(sys.boardType, 10));
|
||||||
|
if(meterState->getMeterType() != AmsTypeAutodetect) {
|
||||||
|
http->addHeader(F("x-AMS-meter-mfg"), String(meterState->getMeterType(), 10));
|
||||||
|
}
|
||||||
|
if(!meterState->getMeterModel().isEmpty()) {
|
||||||
|
http->addHeader(F("x-AMS-meter-model"), meterState->getMeterModel());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AmsWebServer::firmwareHtml() {
|
void AmsWebServer::firmwareHtml() {
|
||||||
if(!checkSecurity(1))
|
if(!checkSecurity(1))
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ void setup() {
|
|||||||
if(config.getSystemConfig(sysConfig)) {
|
if(config.getSystemConfig(sysConfig)) {
|
||||||
config.getMeterConfig(meterConfig);
|
config.getMeterConfig(meterConfig);
|
||||||
if(sysConfig.boardType < 20) {
|
if(sysConfig.boardType < 20) {
|
||||||
config.clearGpio(gpioConfig);
|
config.clearGpio(gpioConfig, false);
|
||||||
hw.applyBoardConfig(sysConfig.boardType, gpioConfig, meterConfig, meterConfig.rxPin);
|
hw.applyBoardConfig(sysConfig.boardType, gpioConfig, meterConfig, meterConfig.rxPin);
|
||||||
config.setMeterConfig(meterConfig);
|
config.setMeterConfig(meterConfig);
|
||||||
config.setGpioConfig(gpioConfig);
|
config.setGpioConfig(gpioConfig);
|
||||||
@@ -674,11 +674,19 @@ void loop() {
|
|||||||
if(cloud == NULL) {
|
if(cloud == NULL) {
|
||||||
cloud = new CloudConnector(&Debug);
|
cloud = new CloudConnector(&Debug);
|
||||||
}
|
}
|
||||||
if(cloud->setup(cc, meterConfig, sysConfig, &hw, &rdc)) {
|
NtpConfig ntp;
|
||||||
|
config.getNtpConfig(ntp);
|
||||||
|
if(cloud->setup(cc, meterConfig, sysConfig, ntp, &hw, &rdc)) {
|
||||||
config.setCloudConfig(cc);
|
config.setCloudConfig(cc);
|
||||||
}
|
}
|
||||||
cloud->setTimezone(tz);
|
|
||||||
cloud->setConnectionHandler(ch);
|
cloud->setConnectionHandler(ch);
|
||||||
|
|
||||||
|
PriceServiceConfig price;
|
||||||
|
config.getPriceServiceConfig(price);
|
||||||
|
cloud->setPriceConfig(price);
|
||||||
|
|
||||||
|
EnergyAccountingConfig *eac = ea.getConfig();
|
||||||
|
cloud->setEnergyAccountingConfig(*eac);
|
||||||
}
|
}
|
||||||
config.ackCloudConfig();
|
config.ackCloudConfig();
|
||||||
}
|
}
|
||||||
@@ -908,6 +916,11 @@ void handleEnergyAccountingChanged() {
|
|||||||
config.getEnergyAccountingConfig(*eac);
|
config.getEnergyAccountingConfig(*eac);
|
||||||
ea.setup(&ds, eac);
|
ea.setup(&ds, eac);
|
||||||
config.ackEnergyAccountingChange();
|
config.ackEnergyAccountingChange();
|
||||||
|
#if defined(ESP32)
|
||||||
|
if(cloud != NULL) {
|
||||||
|
cloud->setEnergyAccountingConfig(*eac);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
char ntpServerName[64] = "";
|
char ntpServerName[64] = "";
|
||||||
@@ -931,11 +944,6 @@ void handleNtpChange() {
|
|||||||
ws.setTimezone(tz);
|
ws.setTimezone(tz);
|
||||||
ds.setTimezone(tz);
|
ds.setTimezone(tz);
|
||||||
ea.setTimezone(tz);
|
ea.setTimezone(tz);
|
||||||
#if defined(ESP32)
|
|
||||||
if(cloud != NULL) {
|
|
||||||
cloud->setTimezone(tz);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config.ackNtpChange();
|
config.ackNtpChange();
|
||||||
@@ -1049,6 +1057,11 @@ void handlePriceService(unsigned long now) {
|
|||||||
ps = new PriceService(&Debug);
|
ps = new PriceService(&Debug);
|
||||||
ea.setPriceService(ps);
|
ea.setPriceService(ps);
|
||||||
ws.setPriceService(ps);
|
ws.setPriceService(ps);
|
||||||
|
#if defined(ESP32)
|
||||||
|
if(cloud != NULL) {
|
||||||
|
cloud->setPriceConfig(price);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
ps->setup(price);
|
ps->setup(price);
|
||||||
} else if(ps != NULL) {
|
} else if(ps != NULL) {
|
||||||
|
|||||||
Reference in New Issue
Block a user