mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-03-26 10:32:10 +00:00
Compare commits
2 Commits
feat/confi
...
feat/uniq_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60d9e1fd22 | ||
|
|
4698442101 |
82
.github/workflows/pr-build-env.yml
vendored
82
.github/workflows/pr-build-env.yml
vendored
@@ -1,82 +0,0 @@
|
||||
name: PR build with env
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
env:
|
||||
description: 'The environment to build for'
|
||||
required: true
|
||||
type: string
|
||||
is_esp32:
|
||||
description: 'Whether the build is for ESP32 based firmware'
|
||||
required: false
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code from repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Cache Python dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('platformio.ini') }}
|
||||
|
||||
- name: Cache PlatformIO dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.pio/libdeps
|
||||
key: ${{ runner.os }}-pio-${{ hashFiles('platformio.ini') }}
|
||||
|
||||
- name: Set up Python 3.9
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.9
|
||||
|
||||
- name: Inject secrets into ini file
|
||||
run: |
|
||||
sed -i 's/NO_AMS2MQTT_PRICE_KEY/AMS2MQTT_PRICE_KEY="${{secrets.AMS2MQTT_PRICE_KEY}}"/g' platformio.ini
|
||||
sed -i 's/NO_AMS2MQTT_PRICE_AUTHENTICATION/AMS2MQTT_PRICE_AUTHENTICATION="${{secrets.AMS2MQTT_PRICE_AUTHENTICATION}}"/g' platformio.ini
|
||||
sed -i 's/NO_AMS2MQTT_SC_KEY/AMS2MQTT_SC_KEY=\\"${{secrets.AMS2MQTT_SC_KEY}}\\"/g' platformio.ini
|
||||
sed -i 's/NO_ENERGY_SPEEDOMETER_USER/ENERGY_SPEEDOMETER_USER=\\"${{secrets.ENERGY_SPEEDOMETER_USER}}\\"/g' platformio.ini
|
||||
sed -i 's/NO_ENERGY_SPEEDOMETER_PASS/ENERGY_SPEEDOMETER_PASS=\\"${{secrets.ENERGY_SPEEDOMETER_PASS}}\\"/g' platformio.ini
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U platformio css_html_js_minify
|
||||
|
||||
- name: Set up node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '19.x'
|
||||
|
||||
- name: Build with node
|
||||
run: |
|
||||
cd lib/SvelteUi/app
|
||||
npm ci
|
||||
npm run build
|
||||
cd -
|
||||
env:
|
||||
CI: false
|
||||
|
||||
- name: PlatformIO lib install
|
||||
run: pio lib install
|
||||
|
||||
- name: Build firmware
|
||||
run: pio run -e ${{ inputs.env }}
|
||||
|
||||
- name: Create zip file
|
||||
run: /bin/sh scripts/${{ inputs.env }}/mkzip.sh
|
||||
|
||||
- name: Upload zip as artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ inputs.env }}.zip
|
||||
path: ${{ inputs.env }}.zip
|
||||
archive: false
|
||||
retention-days: 7
|
||||
110
.github/workflows/pull-request.yml
vendored
110
.github/workflows/pull-request.yml
vendored
@@ -1,110 +0,0 @@
|
||||
name: Pull Request build
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
jobs:
|
||||
build-esp32s2:
|
||||
uses: ./.github/workflows/pr-build-env.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
env: esp32s2
|
||||
is_esp32: true
|
||||
|
||||
build-esp32s3:
|
||||
uses: ./.github/workflows/pr-build-env.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
env: esp32s3
|
||||
is_esp32: true
|
||||
|
||||
build-esp32c3:
|
||||
uses: ./.github/workflows/pr-build-env.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
env: esp32c3
|
||||
is_esp32: true
|
||||
|
||||
build-esp32:
|
||||
uses: ./.github/workflows/pr-build-env.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
env: esp32
|
||||
is_esp32: true
|
||||
|
||||
build-esp32solo:
|
||||
uses: ./.github/workflows/pr-build-env.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
env: esp32solo
|
||||
is_esp32: true
|
||||
|
||||
build-esp8266:
|
||||
uses: ./.github/workflows/pr-build-env.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
env: esp8266
|
||||
is_esp32: false
|
||||
|
||||
comment:
|
||||
needs:
|
||||
- build-esp32s2
|
||||
- build-esp32s3
|
||||
- build-esp32c3
|
||||
- build-esp32
|
||||
- build-esp32solo
|
||||
- build-esp8266
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Post PR comment with download links
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const { owner, repo } = context.repo;
|
||||
const prNumber = context.payload.pull_request.number;
|
||||
const runId = context.runId;
|
||||
const runUrl = `https://github.com/${owner}/${repo}/actions/runs/${runId}`;
|
||||
|
||||
// Get the commit SHA (short version)
|
||||
const sha = context.payload.pull_request.head.sha;
|
||||
const shortSha = sha.substring(0, 7);
|
||||
|
||||
// Fetch the list of artifacts for this run via the API
|
||||
const artifactsResp = await github.rest.actions.listWorkflowRunArtifacts({ owner, repo, run_id: runId });
|
||||
const artifacts = artifactsResp.data.artifacts;
|
||||
|
||||
const envs = ['esp32s2', 'esp32s3', 'esp32c3', 'esp32', 'esp32solo', 'esp8266'];
|
||||
const lines = envs.map(env => {
|
||||
const artifact = artifacts.find(a => a.name === `${env}.zip`);
|
||||
if (artifact) {
|
||||
// The artifact download page URL - directly navigable in the browser
|
||||
const artifactUrl = `${runUrl}#artifacts-${env}`;
|
||||
return `- **${env}**: [Download ${env}.zip](https://github.com/${owner}/${repo}/actions/runs/${runId}/artifacts/${artifact.id})`;
|
||||
}
|
||||
return `- **${env}**: ⚠️ artifact not found`;
|
||||
});
|
||||
|
||||
const body = [
|
||||
'## 🔧 PR Build Artifacts',
|
||||
'',
|
||||
`**Version**: \`${shortSha}\``,
|
||||
'',
|
||||
'All environments built successfully. Download the zip files:',
|
||||
'',
|
||||
...lines,
|
||||
'',
|
||||
`> Artifacts expire after 7 days. [View workflow run](${runUrl})`,
|
||||
].join('\n');
|
||||
|
||||
// Find and delete any previous bot comment to keep the PR clean
|
||||
const comments = await github.rest.issues.listComments({ owner, repo, issue_number: prNumber });
|
||||
for (const comment of comments.data) {
|
||||
if (comment.user.type === 'Bot' && comment.body.includes('PR Build Artifacts')) {
|
||||
await github.rest.issues.deleteComment({ owner, repo, comment_id: comment.id });
|
||||
}
|
||||
}
|
||||
|
||||
await github.rest.issues.createComment({ owner, repo, issue_number: prNumber, body });
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "Arduino.h"
|
||||
|
||||
#define EEPROM_SIZE 1024*3
|
||||
#define EEPROM_EXPECTED_VERSION 104 // Used to check if config is stored. Change if structure changes
|
||||
#define EEPROM_CHECK_SUM 104 // Used to check if config is stored. Change if structure changes
|
||||
#define EEPROM_CLEARED_INDICATOR 0xFC
|
||||
#define EEPROM_CONFIG_ADDRESS 0
|
||||
|
||||
@@ -283,12 +283,11 @@ struct ZmartChargeConfig {
|
||||
|
||||
class AmsConfiguration {
|
||||
public:
|
||||
bool load();
|
||||
bool save();
|
||||
|
||||
bool hasConfig();
|
||||
int getConfigVersion();
|
||||
|
||||
bool save();
|
||||
|
||||
bool getSystemConfig(SystemConfig&);
|
||||
bool setSystemConfig(SystemConfig&);
|
||||
bool isSystemConfigChanged();
|
||||
@@ -382,6 +381,8 @@ public:
|
||||
bool isZmartChargeConfigChanged();
|
||||
void ackZmartChargeConfig();
|
||||
|
||||
uint32_t getChipId();
|
||||
void getUniqueName(char* buffer, size_t length);
|
||||
|
||||
void clear();
|
||||
|
||||
|
||||
@@ -11,14 +11,16 @@
|
||||
#endif
|
||||
|
||||
bool AmsConfiguration::getSystemConfig(SystemConfig& config) {
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
uint8_t configVersion = EEPROM.read(EEPROM_CONFIG_ADDRESS);
|
||||
EEPROM.get(CONFIG_SYSTEM_START, config);
|
||||
EEPROM.end();
|
||||
|
||||
if(config.firmwareChannel > 3) {
|
||||
config.firmwareChannel = 0;
|
||||
}
|
||||
|
||||
if(configVersion == EEPROM_EXPECTED_VERSION) {
|
||||
if(configVersion == EEPROM_CHECK_SUM) {
|
||||
return true;
|
||||
} else {
|
||||
if(configVersion == EEPROM_CLEARED_INDICATOR && config.boardType > 0 && config.boardType < 250) {
|
||||
@@ -50,9 +52,12 @@ bool AmsConfiguration::setSystemConfig(SystemConfig& config) {
|
||||
} else {
|
||||
sysChanged = true;
|
||||
}
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
stripNonAscii((uint8_t*) config.country, 2);
|
||||
EEPROM.put(CONFIG_SYSTEM_START, config);
|
||||
return sysChanged;
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AmsConfiguration::isSystemConfigChanged() {
|
||||
@@ -65,8 +70,10 @@ void AmsConfiguration::ackSystemConfigChanged() {
|
||||
|
||||
bool AmsConfiguration::getNetworkConfig(NetworkConfig& config) {
|
||||
if(hasConfig()) {
|
||||
EEPROM.get(CONFIG_NETWORK_START, config);
|
||||
if(config.sleep > 2) config.sleep = 1;
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.get(CONFIG_NETWORK_START, config);
|
||||
EEPROM.end();
|
||||
if(config.sleep > 2) config.sleep = 1;
|
||||
return true;
|
||||
} else {
|
||||
clearNetworkConfig(config);
|
||||
@@ -106,24 +113,23 @@ bool AmsConfiguration::setNetworkConfig(NetworkConfig& config) {
|
||||
stripNonAscii((uint8_t*) config.dns2, 16);
|
||||
stripNonAscii((uint8_t*) config.hostname, 32);
|
||||
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(CONFIG_NETWORK_START, config);
|
||||
return networkChanged;
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearNetworkConfig(NetworkConfig& config) {
|
||||
memset(config.ssid, 0, 32);
|
||||
memset(config.psk, 0, 64);
|
||||
clearNetworkConfigIp(config);
|
||||
|
||||
uint16_t chipId;
|
||||
getUniqueName(config.hostname, 32);
|
||||
#if defined(ESP32)
|
||||
chipId = ( ESP.getEfuseMac() >> 32 ) % 0xFFFFFFFF;
|
||||
config.power = 195;
|
||||
#else
|
||||
chipId = ESP.getChipId();
|
||||
config.power = 205;
|
||||
#endif
|
||||
strcpy(config.hostname, (String("ams-") + String(chipId, HEX)).c_str());
|
||||
config.mdns = true;
|
||||
config.sleep = 0xFF;
|
||||
config.use11b = 1;
|
||||
@@ -148,8 +154,10 @@ void AmsConfiguration::ackNetworkConfigChange() {
|
||||
|
||||
bool AmsConfiguration::getMqttConfig(MqttConfig& config) {
|
||||
if(hasConfig()) {
|
||||
EEPROM.get(CONFIG_MQTT_START, config);
|
||||
if(config.magic != 0xA5) { // New magic for 2.4.11
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.get(CONFIG_MQTT_START, config);
|
||||
EEPROM.end();
|
||||
if(config.magic != 0xA5) { // New magic for 2.4.11
|
||||
if(config.magic != 0x9C) {
|
||||
if(config.magic != 0x7B) {
|
||||
config.stateUpdate = false;
|
||||
@@ -201,8 +209,11 @@ bool AmsConfiguration::setMqttConfig(MqttConfig& config) {
|
||||
if(config.keepalive > 240) config.keepalive = 60;
|
||||
if(config.rebootMinutes > 240) config.rebootMinutes = 0;
|
||||
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(CONFIG_MQTT_START, config);
|
||||
return mqttChanged;
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearMqtt(MqttConfig& config) {
|
||||
@@ -238,8 +249,10 @@ void AmsConfiguration::ackMqttChange() {
|
||||
|
||||
bool AmsConfiguration::getWebConfig(WebConfig& config) {
|
||||
if(hasConfig()) {
|
||||
EEPROM.get(CONFIG_WEB_START, config);
|
||||
return true;
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.get(CONFIG_WEB_START, config);
|
||||
EEPROM.end();
|
||||
return true;
|
||||
} else {
|
||||
clearWebConfig(config);
|
||||
return false;
|
||||
@@ -260,8 +273,11 @@ bool AmsConfiguration::setWebConfig(WebConfig& config) {
|
||||
stripNonAscii((uint8_t*) config.password, 37, false, false);
|
||||
stripNonAscii((uint8_t*) config.context, 37);
|
||||
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(CONFIG_WEB_START, config);
|
||||
return webChanged;
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearWebConfig(WebConfig& config) {
|
||||
@@ -280,10 +296,12 @@ void AmsConfiguration::ackWebChange() {
|
||||
}
|
||||
|
||||
bool AmsConfiguration::getMeterConfig(MeterConfig& config) {
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
uint8_t configVersion = EEPROM.read(EEPROM_CONFIG_ADDRESS);
|
||||
if(configVersion == EEPROM_EXPECTED_VERSION || configVersion == EEPROM_CLEARED_INDICATOR) {
|
||||
if(configVersion == EEPROM_CHECK_SUM || configVersion == EEPROM_CLEARED_INDICATOR) {
|
||||
EEPROM.get(CONFIG_METER_START, config);
|
||||
if(config.bufferSize < 1 || config.bufferSize > 64) {
|
||||
EEPROM.end();
|
||||
if(config.bufferSize < 1 || config.bufferSize > 64) {
|
||||
#if defined(ESP32)
|
||||
config.bufferSize = 2;
|
||||
#else
|
||||
@@ -324,8 +342,11 @@ bool AmsConfiguration::setMeterConfig(MeterConfig& config) {
|
||||
} else {
|
||||
meterChanged = true;
|
||||
}
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(CONFIG_METER_START, config);
|
||||
return meterChanged;
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearMeter(MeterConfig& config) {
|
||||
@@ -363,8 +384,10 @@ void AmsConfiguration::setMeterChanged() {
|
||||
|
||||
bool AmsConfiguration::getDebugConfig(DebugConfig& config) {
|
||||
if(hasConfig()) {
|
||||
EEPROM.get(CONFIG_DEBUG_START, config);
|
||||
return true;
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.get(CONFIG_DEBUG_START, config);
|
||||
EEPROM.end();
|
||||
return true;
|
||||
} else {
|
||||
clearDebug(config);
|
||||
return false;
|
||||
@@ -374,8 +397,11 @@ bool AmsConfiguration::getDebugConfig(DebugConfig& config) {
|
||||
bool AmsConfiguration::setDebugConfig(DebugConfig& config) {
|
||||
if(!config.serial && !config.telnet)
|
||||
config.level = 4; // Force warning level when debug is disabled
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(CONFIG_DEBUG_START, config);
|
||||
return true;
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearDebug(DebugConfig& config) {
|
||||
@@ -386,8 +412,10 @@ void AmsConfiguration::clearDebug(DebugConfig& config) {
|
||||
|
||||
bool AmsConfiguration::getDomoticzConfig(DomoticzConfig& config) {
|
||||
if(hasConfig()) {
|
||||
EEPROM.get(CONFIG_DOMOTICZ_START, config);
|
||||
return true;
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.get(CONFIG_DOMOTICZ_START, config);
|
||||
EEPROM.end();
|
||||
return true;
|
||||
} else {
|
||||
clearDomo(config);
|
||||
return false;
|
||||
@@ -405,8 +433,11 @@ bool AmsConfiguration::setDomoticzConfig(DomoticzConfig& config) {
|
||||
} else {
|
||||
mqttChanged = true;
|
||||
}
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(CONFIG_DOMOTICZ_START, config);
|
||||
return mqttChanged;
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearDomo(DomoticzConfig& config) {
|
||||
@@ -419,8 +450,10 @@ void AmsConfiguration::clearDomo(DomoticzConfig& config) {
|
||||
|
||||
bool AmsConfiguration::getHomeAssistantConfig(HomeAssistantConfig& config) {
|
||||
if(hasConfig()) {
|
||||
EEPROM.get(CONFIG_HA_START, config);
|
||||
if(stripNonAscii((uint8_t*) config.discoveryPrefix, 64) || stripNonAscii((uint8_t*) config.discoveryHostname, 64) || stripNonAscii((uint8_t*) config.discoveryNameTag, 16)) {
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.get(CONFIG_HA_START, config);
|
||||
EEPROM.end();
|
||||
if(stripNonAscii((uint8_t*) config.discoveryPrefix, 64) || stripNonAscii((uint8_t*) config.discoveryHostname, 64) || stripNonAscii((uint8_t*) config.discoveryNameTag, 16)) {
|
||||
clearHomeAssistantConfig(config);
|
||||
return false;
|
||||
}
|
||||
@@ -445,8 +478,11 @@ bool AmsConfiguration::setHomeAssistantConfig(HomeAssistantConfig& config) {
|
||||
stripNonAscii((uint8_t*) config.discoveryHostname, 64);
|
||||
stripNonAscii((uint8_t*) config.discoveryNameTag, 16);
|
||||
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(CONFIG_HA_START, config);
|
||||
return mqttChanged;
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearHomeAssistantConfig(HomeAssistantConfig& config) {
|
||||
@@ -472,10 +508,12 @@ bool AmsConfiguration::pinUsed(uint8_t pin, GpioConfig& config) {
|
||||
}
|
||||
|
||||
bool AmsConfiguration::getGpioConfig(GpioConfig& config) {
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
uint8_t configVersion = EEPROM.read(EEPROM_CONFIG_ADDRESS);
|
||||
if(configVersion == EEPROM_EXPECTED_VERSION || configVersion == EEPROM_CLEARED_INDICATOR) {
|
||||
if(configVersion == EEPROM_CHECK_SUM || configVersion == EEPROM_CLEARED_INDICATOR) {
|
||||
EEPROM.get(CONFIG_GPIO_START, config);
|
||||
if(config.powersaving > 4) config.powersaving = 0;
|
||||
EEPROM.end();
|
||||
if(config.powersaving > 4) config.powersaving = 0;
|
||||
return true;
|
||||
} else {
|
||||
clearGpio(config);
|
||||
@@ -530,8 +568,11 @@ bool AmsConfiguration::setGpioConfig(GpioConfig& config) {
|
||||
if(config.apPin >= 0)
|
||||
pinMode(config.apPin, INPUT_PULLUP);
|
||||
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(CONFIG_GPIO_START, config);
|
||||
return true;
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearGpio(GpioConfig& config, bool all) {
|
||||
@@ -560,8 +601,10 @@ void AmsConfiguration::clearGpio(GpioConfig& config, bool all) {
|
||||
|
||||
bool AmsConfiguration::getNtpConfig(NtpConfig& config) {
|
||||
if(hasConfig()) {
|
||||
EEPROM.get(CONFIG_NTP_START, config);
|
||||
return true;
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.get(CONFIG_NTP_START, config);
|
||||
EEPROM.end();
|
||||
return true;
|
||||
} else {
|
||||
clearNtp(config);
|
||||
return false;
|
||||
@@ -588,8 +631,11 @@ bool AmsConfiguration::setNtpConfig(NtpConfig& config) {
|
||||
stripNonAscii((uint8_t*) config.server, 64);
|
||||
stripNonAscii((uint8_t*) config.timezone, 32);
|
||||
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(CONFIG_NTP_START, config);
|
||||
return ntpChanged;
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AmsConfiguration::isNtpChanged() {
|
||||
@@ -609,8 +655,10 @@ void AmsConfiguration::clearNtp(NtpConfig& config) {
|
||||
|
||||
bool AmsConfiguration::getPriceServiceConfig(PriceServiceConfig& config) {
|
||||
if(hasConfig()) {
|
||||
EEPROM.get(CONFIG_PRICE_START, config);
|
||||
if(strlen(config.entsoeToken) != 0 && strlen(config.entsoeToken) != 36) {
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.get(CONFIG_PRICE_START, config);
|
||||
EEPROM.end();
|
||||
if(strlen(config.entsoeToken) != 0 && strlen(config.entsoeToken) != 36) {
|
||||
clearPriceServiceConfig(config);
|
||||
return false;
|
||||
}
|
||||
@@ -640,8 +688,11 @@ bool AmsConfiguration::setPriceServiceConfig(PriceServiceConfig& config) {
|
||||
stripNonAscii((uint8_t*) config.area, 17);
|
||||
stripNonAscii((uint8_t*) config.currency, 4);
|
||||
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(CONFIG_PRICE_START, config);
|
||||
return priceChanged;
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearPriceServiceConfig(PriceServiceConfig& config) {
|
||||
@@ -663,8 +714,10 @@ void AmsConfiguration::ackPriceServiceChange() {
|
||||
|
||||
bool AmsConfiguration::getEnergyAccountingConfig(EnergyAccountingConfig& config) {
|
||||
if(hasConfig()) {
|
||||
EEPROM.get(CONFIG_ENERGYACCOUNTING_START, config);
|
||||
if(config.thresholds[9] != 0xFFFF) {
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.get(CONFIG_ENERGYACCOUNTING_START, config);
|
||||
EEPROM.end();
|
||||
if(config.thresholds[9] != 0xFFFF) {
|
||||
clearEnergyAccountingConfig(config);
|
||||
return false;
|
||||
}
|
||||
@@ -690,8 +743,11 @@ bool AmsConfiguration::setEnergyAccountingConfig(EnergyAccountingConfig& config)
|
||||
} else {
|
||||
energyAccountingChanged = true;
|
||||
}
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(CONFIG_ENERGYACCOUNTING_START, config);
|
||||
return energyAccountingChanged;
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearEnergyAccountingConfig(EnergyAccountingConfig& config) {
|
||||
@@ -718,9 +774,11 @@ void AmsConfiguration::ackEnergyAccountingChange() {
|
||||
|
||||
bool AmsConfiguration::getUiConfig(UiConfig& config) {
|
||||
if(hasConfig()) {
|
||||
EEPROM.get(CONFIG_UI_START, config);
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.get(CONFIG_UI_START, config);
|
||||
if(config.showImport > 2) clearUiConfig(config); // Must be wrong
|
||||
return true;
|
||||
EEPROM.end();
|
||||
return true;
|
||||
} else {
|
||||
clearUiConfig(config);
|
||||
return false;
|
||||
@@ -734,8 +792,11 @@ bool AmsConfiguration::setUiConfig(UiConfig& config) {
|
||||
} else {
|
||||
uiLanguageChanged = true;
|
||||
}
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(CONFIG_UI_START, config);
|
||||
return uiLanguageChanged;
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearUiConfig(UiConfig& config) {
|
||||
@@ -770,14 +831,19 @@ bool AmsConfiguration::setUpgradeInformation(UpgradeInformation& upinfo) {
|
||||
stripNonAscii((uint8_t*) upinfo.fromVersion, 16);
|
||||
stripNonAscii((uint8_t*) upinfo.toVersion, 16);
|
||||
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(CONFIG_UPGRADE_INFO_START, upinfo);
|
||||
return true;
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AmsConfiguration::getUpgradeInformation(UpgradeInformation& upinfo) {
|
||||
if(hasConfig()) {
|
||||
EEPROM.get(CONFIG_UPGRADE_INFO_START, upinfo);
|
||||
if(stripNonAscii((uint8_t*) upinfo.fromVersion, 16) || stripNonAscii((uint8_t*) upinfo.toVersion, 16)) {
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.get(CONFIG_UPGRADE_INFO_START, upinfo);
|
||||
EEPROM.end();
|
||||
if(stripNonAscii((uint8_t*) upinfo.fromVersion, 16) || stripNonAscii((uint8_t*) upinfo.toVersion, 16)) {
|
||||
clearUpgradeInformation(upinfo);
|
||||
return false;
|
||||
}
|
||||
@@ -800,8 +866,10 @@ void AmsConfiguration::clearUpgradeInformation(UpgradeInformation& upinfo) {
|
||||
|
||||
bool AmsConfiguration::getCloudConfig(CloudConfig& config) {
|
||||
if(hasConfig()) {
|
||||
EEPROM.get(CONFIG_CLOUD_START, config);
|
||||
if(config.proto > 2) config.proto = 0;
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.get(CONFIG_CLOUD_START, config);
|
||||
EEPROM.end();
|
||||
if(config.proto > 2) config.proto = 0;
|
||||
return true;
|
||||
} else {
|
||||
clearCloudConfig(config);
|
||||
@@ -824,8 +892,11 @@ bool AmsConfiguration::setCloudConfig(CloudConfig& config) {
|
||||
|
||||
stripNonAscii((uint8_t*) config.hostname, 64);
|
||||
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(CONFIG_CLOUD_START, config);
|
||||
return cloudChanged;
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearCloudConfig(CloudConfig& config) {
|
||||
@@ -847,9 +918,11 @@ void AmsConfiguration::ackCloudConfig() {
|
||||
|
||||
bool AmsConfiguration::getZmartChargeConfig(ZmartChargeConfig& config) {
|
||||
if(hasConfig()) {
|
||||
EEPROM.get(CONFIG_ZC_START, config);
|
||||
stripNonAscii((uint8_t*) config.token, 21);
|
||||
stripNonAscii((uint8_t*) config.baseUrl, 64);
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.get(CONFIG_ZC_START, config);
|
||||
EEPROM.end();
|
||||
stripNonAscii((uint8_t*) config.token, 21);
|
||||
stripNonAscii((uint8_t*) config.baseUrl, 64);
|
||||
if(strlen(config.token) != 20 || !config.enabled) {
|
||||
config.enabled = false;
|
||||
memset(config.token, 0, 64);
|
||||
@@ -882,8 +955,11 @@ bool AmsConfiguration::setZmartChargeConfig(ZmartChargeConfig& config) {
|
||||
memset(config.baseUrl, 0, 64);
|
||||
}
|
||||
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
EEPROM.put(CONFIG_ZC_START, config);
|
||||
return zcChanged;
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearZmartChargeConfig(ZmartChargeConfig& config) {
|
||||
@@ -903,7 +979,26 @@ void AmsConfiguration::setUiLanguageChanged() {
|
||||
uiLanguageChanged = true;
|
||||
}
|
||||
|
||||
uint32_t AmsConfiguration::getChipId() {
|
||||
uint32_t chipId;
|
||||
#if defined(ESP32)
|
||||
for(int i=0; i<17; i=i+8) {
|
||||
chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
|
||||
}
|
||||
#else
|
||||
chipId = ESP.getChipId();
|
||||
#endif
|
||||
return chipId;
|
||||
}
|
||||
|
||||
void AmsConfiguration::getUniqueName(char* buffer, size_t length) {
|
||||
uint32_t chipId = getChipId();
|
||||
snprintf(buffer, length, "ams-%06x", chipId);
|
||||
}
|
||||
|
||||
void AmsConfiguration::clear() {
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
|
||||
SystemConfig sys;
|
||||
EEPROM.get(CONFIG_SYSTEM_START, sys);
|
||||
sys.userConfigured = false;
|
||||
@@ -971,16 +1066,18 @@ void AmsConfiguration::clear() {
|
||||
|
||||
EEPROM.put(EEPROM_CONFIG_ADDRESS, EEPROM_CLEARED_INDICATOR);
|
||||
EEPROM.commit();
|
||||
EEPROM.end();
|
||||
}
|
||||
|
||||
bool AmsConfiguration::load() {
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
bool AmsConfiguration::hasConfig() {
|
||||
if(configVersion == 0) {
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
configVersion = EEPROM.read(EEPROM_CONFIG_ADDRESS);
|
||||
EEPROM.end();
|
||||
}
|
||||
if(configVersion > EEPROM_EXPECTED_VERSION) {
|
||||
if(loadFromFs(EEPROM_EXPECTED_VERSION)) {
|
||||
configVersion = EEPROM_EXPECTED_VERSION;
|
||||
if(configVersion > EEPROM_CHECK_SUM) {
|
||||
if(loadFromFs(EEPROM_CHECK_SUM)) {
|
||||
configVersion = EEPROM_CHECK_SUM;
|
||||
} else {
|
||||
configVersion = 0;
|
||||
}
|
||||
@@ -994,18 +1091,14 @@ bool AmsConfiguration::load() {
|
||||
configVersion = 0;
|
||||
return false;
|
||||
}
|
||||
case EEPROM_EXPECTED_VERSION:
|
||||
case EEPROM_CHECK_SUM:
|
||||
return true;
|
||||
default:
|
||||
configVersion = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return configVersion == EEPROM_EXPECTED_VERSION;
|
||||
}
|
||||
|
||||
bool AmsConfiguration::hasConfig() {
|
||||
return configVersion == EEPROM_EXPECTED_VERSION;
|
||||
return configVersion == EEPROM_CHECK_SUM;
|
||||
}
|
||||
|
||||
int AmsConfiguration::getConfigVersion() {
|
||||
@@ -1013,6 +1106,8 @@ int AmsConfiguration::getConfigVersion() {
|
||||
}
|
||||
|
||||
bool AmsConfiguration::relocateConfig103() {
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
|
||||
MeterConfig meter;
|
||||
UpgradeInformation upinfo;
|
||||
UiConfig ui;
|
||||
@@ -1109,14 +1204,19 @@ bool AmsConfiguration::relocateConfig103() {
|
||||
EEPROM.put(CONFIG_ZC_START, zcc);
|
||||
|
||||
EEPROM.put(EEPROM_CONFIG_ADDRESS, 104);
|
||||
return EEPROM.commit();
|
||||
bool ret = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AmsConfiguration::save() {
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
uint8_t configVersion = EEPROM.read(EEPROM_CONFIG_ADDRESS);
|
||||
EEPROM.put(EEPROM_CONFIG_ADDRESS, EEPROM_EXPECTED_VERSION);
|
||||
EEPROM.put(EEPROM_CONFIG_ADDRESS, EEPROM_CHECK_SUM);
|
||||
bool success = EEPROM.commit();
|
||||
configVersion = EEPROM_EXPECTED_VERSION;
|
||||
EEPROM.end();
|
||||
|
||||
configVersion = EEPROM_CHECK_SUM;
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "AmsDataStorage.h"
|
||||
#include "AmsConfiguration.h"
|
||||
|
||||
class AmsJsonGenerator {
|
||||
public:
|
||||
static void generateDayPlotJson(AmsDataStorage* ds, char* buf, size_t bufSize);
|
||||
static void generateMonthPlotJson(AmsDataStorage* ds, char* buf, size_t bufSize);
|
||||
static void generateConfigurationJson(AmsConfiguration* config, char* buf, size_t bufSize);
|
||||
};
|
||||
@@ -1,8 +1,4 @@
|
||||
#include "AmsJsonGenerator.h"
|
||||
#include "hexutils.h"
|
||||
#include "AmsStorage.h"
|
||||
#include "LittleFS.h"
|
||||
#include "FirmwareVersion.h"
|
||||
|
||||
void AmsJsonGenerator::generateDayPlotJson(AmsDataStorage* ds, char* buf, size_t bufSize) {
|
||||
uint16_t pos = snprintf_P(buf, bufSize, PSTR("{\"unit\":\"kwh\""));
|
||||
@@ -19,266 +15,3 @@ void AmsJsonGenerator::generateMonthPlotJson(AmsDataStorage* ds, char* buf, size
|
||||
}
|
||||
snprintf_P(buf+pos, bufSize-pos, PSTR("}"));
|
||||
}
|
||||
|
||||
void AmsJsonGenerator::generateConfigurationJson(AmsConfiguration* config, char* buf, size_t bufSize) {
|
||||
uint16_t pos = snprintf_P(buf, bufSize, PSTR("{\"version\":\"%s\""), FirmwareVersion::VersionString);
|
||||
|
||||
SystemConfig sysConfig;
|
||||
config->getSystemConfig(sysConfig);
|
||||
|
||||
WebConfig webConfig;
|
||||
config->getWebConfig(webConfig);
|
||||
|
||||
MeterConfig meterConfig;
|
||||
config->getMeterConfig(meterConfig);
|
||||
|
||||
NetworkConfig networkConfig;
|
||||
config->getNetworkConfig(networkConfig);
|
||||
|
||||
NtpConfig ntpConfig;
|
||||
config->getNtpConfig(ntpConfig);
|
||||
|
||||
EnergyAccountingConfig eac;
|
||||
config->getEnergyAccountingConfig(eac);
|
||||
|
||||
MqttConfig mqttConfig;
|
||||
config->getMqttConfig(mqttConfig);
|
||||
|
||||
PriceServiceConfig price;
|
||||
config->getPriceServiceConfig(price);
|
||||
|
||||
DebugConfig debugConfig;
|
||||
config->getDebugConfig(debugConfig);
|
||||
|
||||
GpioConfig gpioConfig;
|
||||
config->getGpioConfig(gpioConfig);
|
||||
|
||||
UiConfig ui;
|
||||
config->getUiConfig(ui);
|
||||
|
||||
DomoticzConfig domo;
|
||||
config->getDomoticzConfig(domo);
|
||||
|
||||
HomeAssistantConfig haconf;
|
||||
config->getHomeAssistantConfig(haconf);
|
||||
|
||||
CloudConfig cloud;
|
||||
config->getCloudConfig(cloud);
|
||||
|
||||
ZmartChargeConfig zcc;
|
||||
config->getZmartChargeConfig(zcc);
|
||||
|
||||
// General
|
||||
pos += snprintf_P(buf+pos, bufSize-pos, PSTR(",\"g\":{\"t\":\"%s\",\"h\":\"%s\",\"s\":%d,\"u\":\"%s\",\"p\":\"%s\",\"c\":\"%s\"}"),
|
||||
ntpConfig.timezone,
|
||||
networkConfig.hostname,
|
||||
webConfig.security,
|
||||
webConfig.username,
|
||||
strlen(webConfig.password) > 0 ? "***" : "",
|
||||
webConfig.context
|
||||
);
|
||||
|
||||
// Meter
|
||||
pos += snprintf_P(buf+pos, bufSize-pos, PSTR(",\"m\":{\"o\":%d,\"a\":%d,\"b\":%d,\"p\":%d,\"i\":%s,\"s\":%d,\"d\":%d,\"f\":%d,\"r\":%d"),
|
||||
meterConfig.source,
|
||||
meterConfig.parser,
|
||||
meterConfig.baud,
|
||||
meterConfig.parity,
|
||||
meterConfig.invert ? "true" : "false",
|
||||
meterConfig.bufferSize * 64,
|
||||
meterConfig.distributionSystem,
|
||||
meterConfig.mainFuse,
|
||||
meterConfig.productionCapacity
|
||||
);
|
||||
|
||||
bool encen = false;
|
||||
for(uint8_t i = 0; i < 16; i++) {
|
||||
if(meterConfig.encryptionKey[i] > 0) {
|
||||
encen = true;
|
||||
}
|
||||
}
|
||||
pos += snprintf_P(buf+pos, bufSize-pos, PSTR(",\"e\":{\"e\":%s,\"k\":\"%s\",\"a\":\"%s\"}"),
|
||||
encen ? "true" : "false",
|
||||
toHex(meterConfig.encryptionKey, 16).c_str(),
|
||||
toHex(meterConfig.authenticationKey, 16).c_str()
|
||||
);
|
||||
|
||||
bool multEnable = false;
|
||||
if(meterConfig.wattageMultiplier != 1.0 && meterConfig.wattageMultiplier != 0.0)
|
||||
multEnable = true;
|
||||
if(meterConfig.voltageMultiplier != 1.0 && meterConfig.voltageMultiplier != 0.0)
|
||||
multEnable = true;
|
||||
if(meterConfig.amperageMultiplier != 1.0 && meterConfig.amperageMultiplier != 0.0)
|
||||
multEnable = true;
|
||||
if(meterConfig.accumulatedMultiplier != 1.0 && meterConfig.accumulatedMultiplier != 0.0)
|
||||
multEnable = true;
|
||||
pos += snprintf_P(buf+pos, bufSize-pos, PSTR(",\"m\":{\"e\":%s,\"w\":%.3f,\"v\":%.3f,\"a\":%.3f,\"c\":%.3f}"),
|
||||
multEnable ? "true" : "false",
|
||||
meterConfig.wattageMultiplier == 0.0 ? 1.0 : meterConfig.wattageMultiplier / 1000.0,
|
||||
meterConfig.voltageMultiplier == 0.0 ? 1.0 : meterConfig.voltageMultiplier / 1000.0,
|
||||
meterConfig.amperageMultiplier == 0.0 ? 1.0 : meterConfig.amperageMultiplier / 1000.0,
|
||||
meterConfig.accumulatedMultiplier == 0.0 ? 1.0 : meterConfig.accumulatedMultiplier / 1000.0
|
||||
);
|
||||
|
||||
pos += snprintf_P(buf+pos, bufSize-pos, PSTR("}")); // End of meter
|
||||
|
||||
// Thresholds
|
||||
pos += snprintf_P(buf+pos, bufSize-pos, PSTR(",\"t\":{\"t\":[%d,%d,%d,%d,%d,%d,%d,%d,%d,%d],\"h\":%d}"),
|
||||
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],
|
||||
eac.thresholds[9],
|
||||
eac.hours
|
||||
);
|
||||
|
||||
// WiFi
|
||||
pos += snprintf_P(buf+pos, bufSize-pos, PSTR(",\"w\":{\"s\":\"%s\",\"p\":\"%s\",\"w\":%.1f,\"z\":%d,\"b\":%s}"),
|
||||
networkConfig.ssid,
|
||||
strlen(networkConfig.psk) > 0 ? "***" : "",
|
||||
networkConfig.power / 10.0,
|
||||
networkConfig.sleep,
|
||||
networkConfig.use11b ? "true" : "false"
|
||||
);
|
||||
|
||||
// Network
|
||||
pos += snprintf_P(buf+pos, bufSize-pos, PSTR(",\"n\":{\"c\":%d,\"m\":\"%s\",\"i\":\"%s\",\"s\":\"%s\",\"g\":\"%s\",\"d1\":\"%s\",\"d2\":\"%s\",\"d\":%s,\"n1\":\"%s\",\"h\":%s,\"x\":%s}"),
|
||||
networkConfig.mode,
|
||||
strlen(networkConfig.ip) > 0 ? "static" : "dhcp",
|
||||
networkConfig.ip,
|
||||
networkConfig.subnet,
|
||||
networkConfig.gateway,
|
||||
networkConfig.dns1,
|
||||
networkConfig.dns2,
|
||||
networkConfig.mdns ? "true" : "false",
|
||||
ntpConfig.server,
|
||||
ntpConfig.dhcp ? "true" : "false",
|
||||
networkConfig.ipv6 ? "true" : "false"
|
||||
);
|
||||
|
||||
// MQTT
|
||||
bool qsc = false;
|
||||
bool qsr = false;
|
||||
bool qsk = false;
|
||||
if(LittleFS.begin()) {
|
||||
qsc = LittleFS.exists(FILE_MQTT_CA);
|
||||
qsr = LittleFS.exists(FILE_MQTT_CERT);
|
||||
qsk = LittleFS.exists(FILE_MQTT_KEY);
|
||||
}
|
||||
pos += snprintf_P(buf+pos, bufSize-pos, PSTR(",\"q\":{\"h\":\"%s\",\"p\":%d,\"u\":\"%s\",\"a\":\"%s\",\"c\":\"%s\",\"b\":\"%s\",\"r\":\"%s\",\"m\":%d,\"s\":{\"e\":%s,\"c\":%s,\"r\":%s,\"k\":%s},\"t\":%d,\"d\":%d,\"i\":%d,\"k\":%d,\"e\":%d}"),
|
||||
mqttConfig.host,
|
||||
mqttConfig.port,
|
||||
mqttConfig.username,
|
||||
strlen(mqttConfig.password) > 0 ? "***" : "",
|
||||
mqttConfig.clientId,
|
||||
mqttConfig.publishTopic,
|
||||
mqttConfig.subscribeTopic,
|
||||
mqttConfig.payloadFormat,
|
||||
mqttConfig.ssl ? "true" : "false",
|
||||
qsc ? "true" : "false",
|
||||
qsr ? "true" : "false",
|
||||
qsk ? "true" : "false",
|
||||
mqttConfig.stateUpdate,
|
||||
mqttConfig.stateUpdateInterval,
|
||||
mqttConfig.timeout,
|
||||
mqttConfig.keepalive,
|
||||
mqttConfig.rebootMinutes == 0 ? "null" : String(mqttConfig.rebootMinutes, 10).c_str()
|
||||
);
|
||||
|
||||
// Price
|
||||
pos += snprintf_P(buf+pos, bufSize-pos, PSTR(",\"p\":{\"e\":%s,\"t\":\"%s\",\"r\":\"%s\",\"c\":\"%s\",\"m\":%d}"),
|
||||
price.enabled ? "true" : "false",
|
||||
price.entsoeToken,
|
||||
price.area,
|
||||
price.currency,
|
||||
price.resolutionInMinutes
|
||||
);
|
||||
|
||||
// Debug
|
||||
pos += snprintf_P(buf+pos, bufSize-pos, PSTR(",\"d\":{\"s\":%s,\"t\":%s,\"l\":%d}"),
|
||||
debugConfig.serial ? "true" : "false",
|
||||
debugConfig.telnet ? "true" : "false",
|
||||
debugConfig.level
|
||||
);
|
||||
|
||||
// GPIO
|
||||
pos += snprintf_P(buf+pos, bufSize-pos, PSTR(",\"i\":{\"h\":{\"p\":%s,\"u\":%s,\"t\":%s},\"a\":%s,\"l\":{\"p\":%s,\"i\":%s},\"r\":{\"r\":%s,\"g\":%s,\"b\":%s,\"i\":%s},\"d\":{\"d\":%s,\"b\":%d},\"t\":{\"d\":%s,\"a\":%s},\"v\":{\"p\":%s,\"o\":%.2f,\"m\":%.3f,\"d\":{\"v\":%d,\"g\":%d},\"b\":%.1f},\"p\":%d}"),
|
||||
meterConfig.rxPin == 0xff ? "null" : String(meterConfig.rxPin, 10).c_str(),
|
||||
meterConfig.rxPinPullup ? "true" : "false",
|
||||
meterConfig.txPin == 0xff ? "null" : String(meterConfig.txPin, 10).c_str(),
|
||||
gpioConfig.apPin == 0xff ? "null" : String(gpioConfig.apPin, 10).c_str(),
|
||||
gpioConfig.ledPin == 0xff ? "null" : String(gpioConfig.ledPin, 10).c_str(),
|
||||
gpioConfig.ledInverted ? "true" : "false",
|
||||
gpioConfig.ledPinRed == 0xff ? "null" : String(gpioConfig.ledPinRed, 10).c_str(),
|
||||
gpioConfig.ledPinGreen == 0xff ? "null" : String(gpioConfig.ledPinGreen, 10).c_str(),
|
||||
gpioConfig.ledPinBlue == 0xff ? "null" : String(gpioConfig.ledPinBlue, 10).c_str(),
|
||||
gpioConfig.ledRgbInverted ? "true" : "false",
|
||||
gpioConfig.ledDisablePin == 0xff ? "null" : String(gpioConfig.ledDisablePin, 10).c_str(),
|
||||
gpioConfig.ledBehaviour,
|
||||
gpioConfig.tempSensorPin == 0xff ? "null" : String(gpioConfig.tempSensorPin, 10).c_str(),
|
||||
gpioConfig.tempAnalogSensorPin == 0xff ? "null" : String(gpioConfig.tempAnalogSensorPin, 10).c_str(),
|
||||
gpioConfig.vccPin == 0xff ? "null" : String(gpioConfig.vccPin, 10).c_str(),
|
||||
gpioConfig.vccOffset / 100.0,
|
||||
gpioConfig.vccMultiplier / 1000.0,
|
||||
gpioConfig.vccResistorVcc,
|
||||
gpioConfig.vccResistorGnd,
|
||||
gpioConfig.vccBootLimit / 10.0,
|
||||
gpioConfig.powersaving
|
||||
);
|
||||
|
||||
// UI
|
||||
pos += snprintf_P(buf+pos, bufSize-pos, PSTR(",\"u\":{\"i\":%d,\"e\":%d,\"v\":%d,\"a\":%d,\"r\":%d,\"c\":%d,\"t\":%d,\"p\":%d,\"d\":%d,\"m\":%d,\"s\":%d,\"l\":%d,\"h\":%d,\"f\":%d,\"k\":%d,\"lang\":\"%s\"}"),
|
||||
ui.showImport,
|
||||
ui.showExport,
|
||||
ui.showVoltage,
|
||||
ui.showAmperage,
|
||||
ui.showReactive,
|
||||
ui.showRealtime,
|
||||
ui.showPeaks,
|
||||
ui.showPricePlot,
|
||||
ui.showDayPlot,
|
||||
ui.showMonthPlot,
|
||||
ui.showTemperaturePlot,
|
||||
ui.showRealtimePlot,
|
||||
ui.showPerPhasePower,
|
||||
ui.showPowerFactor,
|
||||
ui.darkMode,
|
||||
ui.language
|
||||
);
|
||||
|
||||
// Domoticz
|
||||
pos += snprintf_P(buf+pos, bufSize-pos, PSTR(",\"o\":{\"e\":%d,\"c\":%d,\"u1\":%d,\"u2\":%d,\"u3\":%d}"),
|
||||
domo.elidx,
|
||||
domo.cl1idx,
|
||||
domo.vl1idx,
|
||||
domo.vl2idx,
|
||||
domo.vl3idx
|
||||
);
|
||||
|
||||
// Home-Assistant
|
||||
pos += snprintf_P(buf+pos, bufSize-pos, PSTR(",\"h\":{\"t\":\"%s\",\"h\":\"%s\",\"n\":\"%s\"}"),
|
||||
haconf.discoveryPrefix,
|
||||
haconf.discoveryHostname,
|
||||
haconf.discoveryNameTag
|
||||
);
|
||||
|
||||
// Cloud
|
||||
pos += snprintf_P(buf+pos, bufSize-pos, PSTR(",\"c\":{\"e\":%s,\"p\":%d,\"es\":%s,\"ze\":%s,\"zt\":\"%s\"}"),
|
||||
cloud.enabled ? "true" : "false",
|
||||
cloud.proto,
|
||||
#if defined(ESP32) && defined(ENERGY_SPEEDOMETER_PASS)
|
||||
sysConfig.energyspeedometer == 7 ? "true" : "false",
|
||||
#else
|
||||
"null",
|
||||
#endif
|
||||
zcc.enabled ? "true" : "false",
|
||||
zcc.token
|
||||
);
|
||||
|
||||
pos += snprintf_P(buf+pos, bufSize-pos, PSTR("}")); // End of config
|
||||
}
|
||||
@@ -23,19 +23,12 @@
|
||||
class AmsMqttHandler {
|
||||
public:
|
||||
#if defined(AMS_REMOTE_DEBUG)
|
||||
AmsMqttHandler(AmsConfiguration* config, RemoteDebug* debugger, char* buf, AmsFirmwareUpdater* updater) {
|
||||
AmsMqttHandler(MqttConfig& mqttConfig, RemoteDebug* debugger, char* buf, AmsFirmwareUpdater* updater) {
|
||||
#else
|
||||
AmsMqttHandler(AmsConfiguration* config, Stream* debugger, char* buf, AmsFirmwareUpdater* updater) {
|
||||
#endif
|
||||
this->config = config;
|
||||
config->getMqttConfig(mqttConfig);
|
||||
AmsMqttHandler(mqttConfig, debugger, buf, updater);
|
||||
};
|
||||
#if defined(AMS_REMOTE_DEBUG)
|
||||
AmsMqttHandler(MqttConfig& MqttConfig, RemoteDebug* debugger, char* buf, AmsFirmwareUpdater* updater) {
|
||||
#else
|
||||
AmsMqttHandler(MqttConfig& MqttConfig, Stream* debugger, char* buf, AmsFirmwareUpdater* updater) {
|
||||
AmsMqttHandler(MqttConfig& mqttConfig, Stream* debugger, char* buf, AmsFirmwareUpdater* updater) {
|
||||
#endif
|
||||
this->mqttConfig = mqttConfig;
|
||||
this->mqttConfigChanged = true;
|
||||
this->debugger = debugger;
|
||||
this->json = buf;
|
||||
this->updater = updater;
|
||||
@@ -44,7 +37,7 @@ public:
|
||||
pubTopic = String(mqttConfig.publishTopic);
|
||||
subTopic = String(mqttConfig.subscribeTopic);
|
||||
if(subTopic.isEmpty()) subTopic = pubTopic+"/command";
|
||||
}
|
||||
};
|
||||
|
||||
void setCaVerification(bool);
|
||||
void setConfig(MqttConfig& mqttConfig);
|
||||
@@ -86,10 +79,8 @@ protected:
|
||||
#else
|
||||
Stream* debugger;
|
||||
#endif
|
||||
AmsConfiguration* config;
|
||||
MqttConfig mqttConfig;
|
||||
bool mqttConfigChanged = false;
|
||||
|
||||
bool mqttConfigChanged = true;
|
||||
MQTTClient mqtt = MQTTClient(256);
|
||||
unsigned long lastMqttRetry = -10000;
|
||||
bool caVerification = true;
|
||||
|
||||
@@ -8,18 +8,9 @@
|
||||
#define _JSONMQTTHANDLER_H
|
||||
|
||||
#include "AmsMqttHandler.h"
|
||||
#include "ArduinoJson.h"
|
||||
|
||||
class JsonMqttHandler : public AmsMqttHandler {
|
||||
public:
|
||||
#if defined(AMS_REMOTE_DEBUG)
|
||||
JsonMqttHandler(AmsConfiguration* config, RemoteDebug* debugger, char* buf, HwTools* hw, AmsDataStorage* ds, AmsFirmwareUpdater* updater) : AmsMqttHandler(config, debugger, buf, updater) {
|
||||
#else
|
||||
JsonMqttHandler(AmsConfiguration* config, Stream* debugger, char* buf, HwTools* hw, AmsDataStorage* ds, AmsFirmwareUpdater* updater) : AmsMqttHandler(config, debugger, buf, updater) {
|
||||
#endif
|
||||
this->hw = hw;
|
||||
this->ds = ds;
|
||||
};
|
||||
#if defined(AMS_REMOTE_DEBUG)
|
||||
JsonMqttHandler(MqttConfig& mqttConfig, RemoteDebug* debugger, char* buf, HwTools* hw, AmsDataStorage* ds, AmsFirmwareUpdater* updater) : AmsMqttHandler(mqttConfig, debugger, buf, updater) {
|
||||
#else
|
||||
@@ -52,6 +43,5 @@ private:
|
||||
bool publishList4(AmsData* data, EnergyAccounting* ea);
|
||||
String getMeterModel(AmsData* data);
|
||||
void toJsonIsoTimestamp(time_t t, char* buf, size_t buflen);
|
||||
void handleConfigMessage(JsonObject& configObj);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -525,53 +525,17 @@ void JsonMqttHandler::onMessage(String &topic, String &payload) {
|
||||
if (debugger->isActive(RemoteDebug::DEBUG))
|
||||
#endif
|
||||
debugger->printf_P(PSTR(" - this is our subscribed topic\n"));
|
||||
|
||||
if(payload.startsWith("{")) {
|
||||
DynamicJsonDocument doc(512);
|
||||
DeserializationError error = deserializeJson(doc, payload);
|
||||
if(error) {
|
||||
#if defined(AMS_REMOTE_DEBUG)
|
||||
if (debugger->isActive(RemoteDebug::ERROR))
|
||||
#endif
|
||||
debugger->printf_P(PSTR(" - failed to parse JSON: %s\n"), error.c_str());
|
||||
return;
|
||||
} else {
|
||||
JsonObject obj = doc.as<JsonObject>();
|
||||
if(obj.containsKey(F("action"))) {
|
||||
const char* action = obj[F("action")];
|
||||
if(strcmp_P(action, PSTR("fwupgrade")) == 0) {
|
||||
if(strcmp(updater->getNextVersion(), FirmwareVersion::VersionString) != 0) {
|
||||
updater->setTargetVersion(updater->getNextVersion());
|
||||
}
|
||||
} else if(strcmp_P(action, PSTR("dayplot")) == 0) {
|
||||
char pubTopic[192];
|
||||
snprintf_P(pubTopic, 192, PSTR("%s/dayplot"), mqttConfig.publishTopic);
|
||||
AmsJsonGenerator::generateDayPlotJson(ds, json, BufferSize);
|
||||
bool ret = mqtt.publish(pubTopic, json);
|
||||
loop();
|
||||
} else if(strcmp_P(action, PSTR("monthplot")) == 0) {
|
||||
char pubTopic[192];
|
||||
snprintf_P(pubTopic, 192, PSTR("%s/monthplot"), mqttConfig.publishTopic);
|
||||
AmsJsonGenerator::generateMonthPlotJson(ds, json, BufferSize);
|
||||
bool ret = mqtt.publish(pubTopic, json);
|
||||
loop();
|
||||
} else if(strcmp_P(action, PSTR("config")) == 0 && obj.containsKey(F("config"))) {
|
||||
JsonObject configObj = obj[F("config")];
|
||||
handleConfigMessage(configObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(payload.equals(F("fwupgrade"))) {
|
||||
if(payload.equals("fwupgrade")) {
|
||||
if(strcmp(updater->getNextVersion(), FirmwareVersion::VersionString) != 0) {
|
||||
updater->setTargetVersion(updater->getNextVersion());
|
||||
}
|
||||
} else if(payload.equals(F("dayplot"))) {
|
||||
} else if(payload.equals("dayplot")) {
|
||||
char pubTopic[192];
|
||||
snprintf_P(pubTopic, 192, PSTR("%s/dayplot"), mqttConfig.publishTopic);
|
||||
AmsJsonGenerator::generateDayPlotJson(ds, json, BufferSize);
|
||||
bool ret = mqtt.publish(pubTopic, json);
|
||||
loop();
|
||||
} else if(payload.equals(F("monthplot"))) {
|
||||
} else if(payload.equals("monthplot")) {
|
||||
char pubTopic[192];
|
||||
snprintf_P(pubTopic, 192, PSTR("%s/monthplot"), mqttConfig.publishTopic);
|
||||
AmsJsonGenerator::generateMonthPlotJson(ds, json, BufferSize);
|
||||
@@ -581,469 +545,6 @@ void JsonMqttHandler::onMessage(String &topic, String &payload) {
|
||||
}
|
||||
}
|
||||
|
||||
void JsonMqttHandler::handleConfigMessage(JsonObject& configObj) {
|
||||
// General
|
||||
if(configObj.containsKey(F("g"))) {
|
||||
JsonObject generalObj = configObj[F("g")];
|
||||
if(generalObj.containsKey(F("t"))) {
|
||||
NtpConfig ntpConfig;
|
||||
config->getNtpConfig(ntpConfig);
|
||||
strlcpy(ntpConfig.timezone, generalObj[F("t")], sizeof(ntpConfig.timezone));
|
||||
config->setNtpConfig(ntpConfig);
|
||||
}
|
||||
if(generalObj.containsKey(F("h"))) {
|
||||
NetworkConfig networkConfig;
|
||||
config->getNetworkConfig(networkConfig);
|
||||
strlcpy(networkConfig.hostname, generalObj[F("h")], sizeof(networkConfig.hostname));
|
||||
config->setNetworkConfig(networkConfig);
|
||||
}
|
||||
|
||||
WebConfig webConfig;
|
||||
config->getWebConfig(webConfig);
|
||||
if(generalObj.containsKey(F("s"))) {
|
||||
webConfig.security = generalObj[F("s")];
|
||||
}
|
||||
if(webConfig.security > 0) {
|
||||
if(generalObj.containsKey(F("u"))) {
|
||||
strlcpy(webConfig.username, generalObj[F("u")], sizeof(webConfig.username));
|
||||
}
|
||||
if(generalObj.containsKey(F("p"))) {
|
||||
strlcpy(webConfig.password, generalObj[F("p")], sizeof(webConfig.password));
|
||||
}
|
||||
}
|
||||
if(generalObj.containsKey(F("c"))) {
|
||||
strlcpy(webConfig.context, generalObj[F("c")], sizeof(webConfig.context));
|
||||
}
|
||||
config->setWebConfig(webConfig);
|
||||
}
|
||||
|
||||
// Meter
|
||||
if(configObj.containsKey(F("m"))) {
|
||||
JsonObject meterObj = configObj[F("m")];
|
||||
MeterConfig newConfig;
|
||||
config->getMeterConfig(newConfig);
|
||||
|
||||
if(meterObj.containsKey(F("o"))) {
|
||||
newConfig.source = meterObj[F("o")];
|
||||
}
|
||||
if(meterObj.containsKey(F("a"))) {
|
||||
newConfig.parser = meterObj[F("a")];
|
||||
}
|
||||
if(meterObj.containsKey(F("b"))) {
|
||||
newConfig.baud = meterObj[F("b")];
|
||||
}
|
||||
if(meterObj.containsKey(F("p"))) {
|
||||
// TODO, string to enum
|
||||
newConfig.parity = meterObj[F("p")];
|
||||
}
|
||||
if(meterObj.containsKey(F("i"))) {
|
||||
newConfig.invert = meterObj[F("i")];
|
||||
}
|
||||
if(meterObj.containsKey(F("s"))) {
|
||||
newConfig.bufferSize = meterObj[F("s")] / 64; // convert from bytes to 64 byte blocks
|
||||
}
|
||||
if(meterObj.containsKey(F("d"))) {
|
||||
newConfig.distributionSystem = meterObj[F("d")];
|
||||
}
|
||||
if(meterObj.containsKey(F("f"))) {
|
||||
newConfig.mainFuse = meterObj[F("f")];
|
||||
}
|
||||
if(meterObj.containsKey(F("r"))) {
|
||||
newConfig.productionCapacity = meterObj[F("r")];
|
||||
}
|
||||
if(meterObj.containsKey(F("e"))) {
|
||||
JsonObject encryptionObj = meterObj[F("e")];
|
||||
if(encryptionObj.containsKey(F("e"))) {
|
||||
bool enabled = encryptionObj[F("e")];
|
||||
if(enabled) {
|
||||
if(encryptionObj.containsKey(F("k"))) {
|
||||
// TODO
|
||||
}
|
||||
if(encryptionObj.containsKey(F("a"))) {
|
||||
// TODO
|
||||
}
|
||||
} else {
|
||||
memset(newConfig.encryptionKey, 0, sizeof(newConfig.encryptionKey));
|
||||
memset(newConfig.authenticationKey, 0, sizeof(newConfig.authenticationKey));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
config->setMeterConfig(newConfig);
|
||||
}
|
||||
|
||||
if(configObj.containsKey(F("system"))) {
|
||||
SystemConfig newConfig;
|
||||
config->getSystemConfig(newConfig);
|
||||
|
||||
JsonObject systemObj = configObj[F("system")];
|
||||
if(systemObj.containsKey(F("country"))) {
|
||||
strlcpy(newConfig.country, systemObj[F("country")], sizeof(newConfig.country));
|
||||
}
|
||||
if(systemObj.containsKey(F("firmwareChannel"))) {
|
||||
newConfig.firmwareChannel = systemObj[F("firmwareChannel")];
|
||||
}
|
||||
config->setSystemConfig(newConfig);
|
||||
}
|
||||
|
||||
if(configObj.containsKey(F("network"))) {
|
||||
NetworkConfig newConfig;
|
||||
config->getNetworkConfig(newConfig);
|
||||
|
||||
JsonObject networkObj = configObj[F("network")];
|
||||
if(networkObj.containsKey(F("mode"))) {
|
||||
newConfig.mode = networkObj[F("mode")];
|
||||
}
|
||||
if(newConfig.mode == 1 || newConfig.mode == 2) {
|
||||
if(networkObj.containsKey(F("ssid"))) {
|
||||
strlcpy(newConfig.ssid, networkObj[F("ssid")], sizeof(newConfig.ssid));
|
||||
}
|
||||
if(networkObj.containsKey(F("psk"))) {
|
||||
strlcpy(newConfig.psk, networkObj[F("psk")], sizeof(newConfig.psk));
|
||||
}
|
||||
if(networkObj.containsKey(F("power"))) {
|
||||
newConfig.power = networkObj[F("power")];
|
||||
}
|
||||
if(networkObj.containsKey(F("sleep"))) {
|
||||
newConfig.sleep = networkObj[F("sleep")];
|
||||
}
|
||||
if(networkObj.containsKey(F("use11b"))) {
|
||||
newConfig.use11b = networkObj[F("use11b")];
|
||||
}
|
||||
}
|
||||
if(networkObj.containsKey(F("ip"))) {
|
||||
strlcpy(newConfig.ip, networkObj[F("ip")], sizeof(newConfig.ip));
|
||||
}
|
||||
if(networkObj.containsKey(F("gateway"))) {
|
||||
strlcpy(newConfig.gateway, networkObj[F("gateway")], sizeof(newConfig.gateway));
|
||||
}
|
||||
if(networkObj.containsKey(F("subnet"))) {
|
||||
strlcpy(newConfig.subnet, networkObj[F("subnet")], sizeof(newConfig.subnet));
|
||||
}
|
||||
if(networkObj.containsKey(F("dns1"))) {
|
||||
strlcpy(newConfig.dns1, networkObj[F("dns1")], sizeof(newConfig.dns1));
|
||||
}
|
||||
if(networkObj.containsKey(F("dns2"))) {
|
||||
strlcpy(newConfig.dns2, networkObj[F("dns2")], sizeof(newConfig.dns2));
|
||||
}
|
||||
if(networkObj.containsKey(F("mdns"))) {
|
||||
newConfig.mdns = networkObj[F("mdns")];
|
||||
}
|
||||
if(networkObj.containsKey(F("ipv6"))) {
|
||||
newConfig.ipv6 = networkObj[F("ipv6")];
|
||||
}
|
||||
config->setNetworkConfig(newConfig);
|
||||
}
|
||||
|
||||
if(configObj.containsKey(F("meter"))) {
|
||||
MeterConfig newConfig;
|
||||
config->getMeterConfig(newConfig);
|
||||
|
||||
JsonObject meterObj = configObj[F("meter")];
|
||||
if(meterObj.containsKey(F("baud"))) {
|
||||
newConfig.baud = meterObj[F("baud")];
|
||||
}
|
||||
if(meterObj.containsKey(F("parity"))) {
|
||||
newConfig.parity = meterObj[F("parity")];
|
||||
}
|
||||
if(meterObj.containsKey(F("invert"))) {
|
||||
newConfig.invert = meterObj[F("invert")];
|
||||
}
|
||||
if(meterObj.containsKey(F("distributionSystem"))) {
|
||||
newConfig.distributionSystem = meterObj[F("distributionSystem")];
|
||||
}
|
||||
if(meterObj.containsKey(F("mainFuse"))) {
|
||||
newConfig.mainFuse = meterObj[F("mainFuse")];
|
||||
}
|
||||
if(meterObj.containsKey(F("productionCapacity"))) {
|
||||
newConfig.productionCapacity = meterObj[F("productionCapacity")];
|
||||
}
|
||||
if(meterObj.containsKey(F("wattageMultiplier"))) {
|
||||
newConfig.wattageMultiplier = meterObj[F("wattageMultiplier")];
|
||||
}
|
||||
if(meterObj.containsKey(F("voltageMultiplier"))) {
|
||||
newConfig.voltageMultiplier = meterObj[F("voltageMultiplier")];
|
||||
}
|
||||
if(meterObj.containsKey(F("amperageMultiplier"))) {
|
||||
newConfig.amperageMultiplier = meterObj[F("amperageMultiplier")];
|
||||
}
|
||||
if(meterObj.containsKey(F("accumulatedMultiplier"))) {
|
||||
newConfig.accumulatedMultiplier = meterObj[F("accumulatedMultiplier")];
|
||||
}
|
||||
if(meterObj.containsKey(F("parser"))) {
|
||||
newConfig.parser = meterObj[F("parser")];
|
||||
}
|
||||
if(meterObj.containsKey(F("bufferSize"))) {
|
||||
newConfig.bufferSize = meterObj[F("bufferSize")];
|
||||
}
|
||||
if(meterObj.containsKey(F("rxPin"))) {
|
||||
newConfig.rxPin = meterObj[F("rxPin")];
|
||||
}
|
||||
if(meterObj.containsKey(F("rxPinPullup"))) {
|
||||
newConfig.rxPinPullup = meterObj[F("rxPinPullup")];
|
||||
}
|
||||
if(meterObj.containsKey(F("txPin"))) {
|
||||
newConfig.txPin = meterObj[F("txPin")];
|
||||
}
|
||||
}
|
||||
|
||||
if(configObj.containsKey(F("mqtt"))) {
|
||||
MqttConfig newConfig;
|
||||
config->getMqttConfig(newConfig);
|
||||
|
||||
JsonObject mqttObj = configObj[F("mqtt")];
|
||||
if(mqttObj.containsKey(F("host"))) {
|
||||
strlcpy(newConfig.host, mqttObj[F("host")], sizeof(newConfig.host));
|
||||
}
|
||||
if(mqttObj.containsKey(F("port"))) {
|
||||
newConfig.port = mqttObj[F("port")];
|
||||
}
|
||||
if(mqttObj.containsKey(F("clientId"))) {
|
||||
strlcpy(newConfig.clientId, mqttObj[F("clientId")], sizeof(newConfig.clientId));
|
||||
}
|
||||
if(mqttObj.containsKey(F("publishTopic"))) {
|
||||
strlcpy(newConfig.publishTopic, mqttObj[F("publishTopic")], sizeof(newConfig.publishTopic));
|
||||
}
|
||||
if(mqttObj.containsKey(F("subscribeTopic"))) {
|
||||
strlcpy(newConfig.subscribeTopic, mqttObj[F("subscribeTopic")], sizeof(newConfig.subscribeTopic));
|
||||
}
|
||||
if(mqttObj.containsKey(F("username"))) {
|
||||
strlcpy(newConfig.username, mqttObj[F("username")], sizeof(newConfig.username));
|
||||
}
|
||||
if(mqttObj.containsKey(F("password"))) {
|
||||
strlcpy(newConfig.password, mqttObj[F("password")], sizeof(newConfig.password));
|
||||
}
|
||||
if(mqttObj.containsKey(F("payloadFormat"))) {
|
||||
newConfig.payloadFormat = mqttObj[F("payloadFormat")];
|
||||
}
|
||||
if(mqttObj.containsKey(F("ssl"))) {
|
||||
newConfig.ssl = mqttObj[F("ssl")];
|
||||
}
|
||||
if(mqttObj.containsKey(F("stateUpdate"))) {
|
||||
newConfig.stateUpdate = mqttObj[F("stateUpdate")];
|
||||
}
|
||||
if(mqttObj.containsKey(F("stateUpdateInterval"))) {
|
||||
newConfig.stateUpdateInterval = mqttObj[F("stateUpdateInterval")];
|
||||
}
|
||||
if(mqttObj.containsKey(F("timeout"))) {
|
||||
newConfig.timeout = mqttObj[F("timeout")];
|
||||
}
|
||||
if(mqttObj.containsKey(F("keepalive"))) {
|
||||
newConfig.keepalive = mqttObj[F("keepalive")];
|
||||
}
|
||||
if(mqttObj.containsKey(F("rebootMinutes"))) {
|
||||
newConfig.rebootMinutes = mqttObj[F("rebootMinutes")];
|
||||
}
|
||||
config->setMqttConfig(newConfig);
|
||||
|
||||
if(mqttObj.containsKey(F("domoticz"))) {
|
||||
DomoticzConfig newConfig;
|
||||
config->getDomoticzConfig(newConfig);
|
||||
JsonObject domoticzObj = mqttObj[F("domoticz")];
|
||||
if(domoticzObj.containsKey(F("elidx"))) {
|
||||
newConfig.elidx = domoticzObj[F("elidx")];
|
||||
}
|
||||
if(domoticzObj.containsKey(F("vl1idx"))) {
|
||||
newConfig.vl1idx = domoticzObj[F("vl1idx")];
|
||||
}
|
||||
if(domoticzObj.containsKey(F("vl2idx"))) {
|
||||
newConfig.vl2idx = domoticzObj[F("vl2idx")];
|
||||
}
|
||||
if(domoticzObj.containsKey(F("vl3idx"))) {
|
||||
newConfig.vl3idx = domoticzObj[F("vl3idx")];
|
||||
}
|
||||
if(domoticzObj.containsKey(F("cl1idx"))) {
|
||||
newConfig.cl1idx = domoticzObj[F("cl1idx")];
|
||||
}
|
||||
config->setDomoticzConfig(newConfig);
|
||||
}
|
||||
|
||||
if(mqttObj.containsKey(F("homeAssistant"))) {
|
||||
HomeAssistantConfig newConfig;
|
||||
config->getHomeAssistantConfig(newConfig);
|
||||
JsonObject haObj = mqttObj[F("homeAssistant")];
|
||||
if(haObj.containsKey(F("discoveryPrefix"))) {
|
||||
strlcpy(newConfig.discoveryPrefix, haObj[F("discoveryPrefix")], sizeof(newConfig.discoveryPrefix));
|
||||
}
|
||||
if(haObj.containsKey(F("discoveryHostname"))) {
|
||||
strlcpy(newConfig.discoveryHostname, haObj[F("discoveryHostname")], sizeof(newConfig.discoveryHostname));
|
||||
}
|
||||
if(haObj.containsKey(F("discoveryNameTag"))) {
|
||||
strlcpy(newConfig.discoveryNameTag, haObj[F("discoveryNameTag")], sizeof(newConfig.discoveryNameTag));
|
||||
}
|
||||
config->setHomeAssistantConfig(newConfig);
|
||||
}
|
||||
}
|
||||
|
||||
if(configObj.containsKey(F("debug"))) {
|
||||
DebugConfig newConfig;
|
||||
config->getDebugConfig(newConfig);
|
||||
|
||||
JsonObject debugObj = configObj[F("debug")];
|
||||
if(debugObj.containsKey(F("telnet"))) {
|
||||
newConfig.telnet = debugObj[F("telnet")];
|
||||
}
|
||||
if(debugObj.containsKey(F("serial"))) {
|
||||
newConfig.serial = debugObj[F("serial")];
|
||||
}
|
||||
if(debugObj.containsKey(F("level"))) {
|
||||
newConfig.level = debugObj[F("level")];
|
||||
}
|
||||
config->setDebugConfig(newConfig);
|
||||
}
|
||||
|
||||
if(configObj.containsKey(F("gpio"))) {
|
||||
GpioConfig newConfig;
|
||||
config->getGpioConfig(newConfig);
|
||||
|
||||
JsonObject gpioObj = configObj[F("gpio")];
|
||||
if(gpioObj.containsKey(F("apPin"))) {
|
||||
newConfig.apPin = gpioObj[F("apPin")];
|
||||
}
|
||||
if(gpioObj.containsKey(F("ledPin"))) {
|
||||
newConfig.ledPin = gpioObj[F("ledPin")];
|
||||
}
|
||||
if(gpioObj.containsKey(F("ledInverted"))) {
|
||||
newConfig.ledInverted = gpioObj[F("ledInverted")];
|
||||
}
|
||||
if(gpioObj.containsKey(F("ledPinRed"))) {
|
||||
newConfig.ledPinRed = gpioObj[F("ledPinRed")];
|
||||
}
|
||||
if(gpioObj.containsKey(F("ledPinGreen"))) {
|
||||
newConfig.ledPinGreen = gpioObj[F("ledPinGreen")];
|
||||
}
|
||||
if(gpioObj.containsKey(F("ledPinBlue"))) {
|
||||
newConfig.ledPinBlue = gpioObj[F("ledPinBlue")];
|
||||
}
|
||||
if(gpioObj.containsKey(F("ledRgbInverted"))) {
|
||||
newConfig.ledRgbInverted = gpioObj[F("ledRgbInverted")];
|
||||
}
|
||||
if(gpioObj.containsKey(F("tempSensorPin"))) {
|
||||
newConfig.tempSensorPin = gpioObj[F("tempSensorPin")];
|
||||
}
|
||||
if(gpioObj.containsKey(F("tempAnalogSensorPin"))) {
|
||||
newConfig.tempAnalogSensorPin = gpioObj[F("tempAnalogSensorPin")];
|
||||
}
|
||||
if(gpioObj.containsKey(F("vccPin"))) {
|
||||
newConfig.vccPin = gpioObj[F("vccPin")];
|
||||
}
|
||||
if(gpioObj.containsKey(F("vccOffset"))) {
|
||||
newConfig.vccOffset = gpioObj[F("vccOffset")];
|
||||
}
|
||||
if(gpioObj.containsKey(F("vccMultiplier"))) {
|
||||
newConfig.vccMultiplier = gpioObj[F("vccMultiplier")];
|
||||
}
|
||||
if(gpioObj.containsKey(F("vccBootLimit"))) {
|
||||
newConfig.vccBootLimit = gpioObj[F("vccBootLimit")];
|
||||
}
|
||||
if(gpioObj.containsKey(F("vccResistorGnd"))) {
|
||||
newConfig.vccResistorGnd = gpioObj[F("vccResistorGnd")];
|
||||
}
|
||||
if(gpioObj.containsKey(F("vccResistorVcc"))) {
|
||||
newConfig.vccResistorVcc = gpioObj[F("vccResistorVcc")];
|
||||
}
|
||||
if(gpioObj.containsKey(F("ledDisablePin"))) {
|
||||
newConfig.ledDisablePin = gpioObj[F("ledDisablePin")];
|
||||
}
|
||||
if(gpioObj.containsKey(F("ledBehaviour"))) {
|
||||
newConfig.ledBehaviour = gpioObj[F("ledBehaviour")];
|
||||
}
|
||||
config->setGpioConfig(newConfig);
|
||||
}
|
||||
|
||||
if(configObj.containsKey(F("ntp"))) {
|
||||
NtpConfig newConfig;
|
||||
config->getNtpConfig(newConfig);
|
||||
|
||||
JsonObject ntpObj = configObj[F("ntp")];
|
||||
if(ntpObj.containsKey(F("enable"))) {
|
||||
newConfig.enable = ntpObj[F("enable")];
|
||||
}
|
||||
if(ntpObj.containsKey(F("dhcp"))) {
|
||||
newConfig.dhcp = ntpObj[F("dhcp")];
|
||||
}
|
||||
if(ntpObj.containsKey(F("server"))) {
|
||||
strlcpy(newConfig.server, ntpObj[F("server")], sizeof(newConfig.server));
|
||||
}
|
||||
config->setNtpConfig(newConfig);
|
||||
}
|
||||
|
||||
if(configObj.containsKey(F("priceService"))) {
|
||||
PriceServiceConfig newConfig;
|
||||
config->getPriceServiceConfig(newConfig);
|
||||
JsonObject priceServiceObj = configObj[F("priceService")];
|
||||
if(priceServiceObj.containsKey(F("area"))) {
|
||||
strlcpy(newConfig.area, priceServiceObj[F("area")], sizeof(newConfig.area));
|
||||
}
|
||||
if(priceServiceObj.containsKey(F("currency"))) {
|
||||
strlcpy(newConfig.currency, priceServiceObj[F("currency")], sizeof(newConfig.currency));
|
||||
}
|
||||
if(priceServiceObj.containsKey(F("resolutionInMinutes"))) {
|
||||
newConfig.resolutionInMinutes = priceServiceObj[F("resolutionInMinutes")];
|
||||
}
|
||||
if(priceServiceObj.containsKey(F("enabled"))) {
|
||||
newConfig.enabled = priceServiceObj[F("enabled")];
|
||||
}
|
||||
config->setPriceServiceConfig(newConfig);
|
||||
}
|
||||
|
||||
if(configObj.containsKey(F("cloud"))) {
|
||||
JsonObject cloudObj = configObj[F("cloud")];
|
||||
|
||||
if(cloudObj.containsKey(F("amsleser"))) {
|
||||
CloudConfig newConfig;
|
||||
config->getCloudConfig(newConfig);
|
||||
|
||||
JsonObject amsCloudObj = cloudObj[F("amsleser")];
|
||||
if(amsCloudObj.containsKey(F("enabled"))) {
|
||||
newConfig.enabled = amsCloudObj[F("enabled")];
|
||||
}
|
||||
if(amsCloudObj.containsKey(F("interval"))) {
|
||||
newConfig.interval = amsCloudObj[F("interval")];
|
||||
}
|
||||
if(amsCloudObj.containsKey(F("hostname"))) {
|
||||
strlcpy(newConfig.hostname, amsCloudObj[F("hostname")], sizeof(newConfig.hostname));
|
||||
}
|
||||
if(amsCloudObj.containsKey(F("port"))) {
|
||||
newConfig.port = amsCloudObj[F("port")];
|
||||
}
|
||||
if(amsCloudObj.containsKey(F("clientId"))) {
|
||||
strlcpy((char*)newConfig.clientId, amsCloudObj[F("clientId")], sizeof(newConfig.clientId));
|
||||
}
|
||||
if(amsCloudObj.containsKey(F("proto"))) {
|
||||
newConfig.proto = amsCloudObj[F("proto")];
|
||||
}
|
||||
config->setCloudConfig(newConfig);
|
||||
}
|
||||
|
||||
if(cloudObj.containsKey(F("zmartcharge"))) {
|
||||
ZmartChargeConfig newConfig;
|
||||
config->getZmartChargeConfig(newConfig);
|
||||
JsonObject zmartChargeObj = cloudObj[F("zmartcharge")];
|
||||
if(zmartChargeObj.containsKey(F("enabled"))) {
|
||||
newConfig.enabled = zmartChargeObj[F("enabled")];
|
||||
}
|
||||
if(zmartChargeObj.containsKey(F("token"))) {
|
||||
strlcpy(newConfig.token, zmartChargeObj[F("token")], sizeof(newConfig.token));
|
||||
}
|
||||
if(zmartChargeObj.containsKey(F("baseUrl"))) {
|
||||
strlcpy(newConfig.baseUrl, zmartChargeObj[F("baseUrl")], sizeof(newConfig.baseUrl));
|
||||
}
|
||||
config->setZmartChargeConfig(newConfig);
|
||||
}
|
||||
|
||||
if(cloudObj.containsKey(F("energyspeedometer"))) {
|
||||
SystemConfig newConfig;
|
||||
config->getSystemConfig(newConfig);
|
||||
JsonObject speedometerObj = cloudObj[F("energyspeedometer")];
|
||||
if(speedometerObj.containsKey(F("enabled"))) {
|
||||
newConfig.energyspeedometer = speedometerObj[F("enabled")];
|
||||
}
|
||||
config->setSystemConfig(newConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JsonMqttHandler::toJsonIsoTimestamp(time_t t, char* buf, size_t buflen) {
|
||||
memset(buf, 0, buflen);
|
||||
if(t > 0) {
|
||||
|
||||
56
lib/SvelteUi/app/package-lock.json
generated
56
lib/SvelteUi/app/package-lock.json
generated
@@ -613,6 +613,14 @@
|
||||
"tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@trysound/sax": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
|
||||
"integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
|
||||
@@ -1812,11 +1820,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
@@ -2711,11 +2718,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "3.30.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.30.0.tgz",
|
||||
"integrity": "sha512-kQvGasUgN+AlWGliFn2POSajRQEsULVYFGTvOZmK06d7vCD+YhZztt70kGk3qaeAXeWYL5eO7zx+rAubBc55eA==",
|
||||
"version": "3.29.5",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz",
|
||||
"integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
},
|
||||
@@ -2762,15 +2768,6 @@
|
||||
"rimraf": "^2.5.2"
|
||||
}
|
||||
},
|
||||
"node_modules/sax": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz",
|
||||
"integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"engines": {
|
||||
"node": ">=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
@@ -2987,11 +2984,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/sucrase/node_modules/brace-expansion": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
@@ -3026,13 +3022,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/sucrase/node_modules/minimatch": {
|
||||
"version": "9.0.9",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
|
||||
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.2"
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
@@ -3189,17 +3184,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/svgo": {
|
||||
"version": "2.8.2",
|
||||
"resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.2.tgz",
|
||||
"integrity": "sha512-TyzE4NVGLUFy+H/Uy4N6c3G0HEeprsVfge6Lmq+0FdQQ/zqoVYB62IsBZORsiL+o96s6ff/V6/3UQo/C0cgCAA==",
|
||||
"license": "MIT",
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz",
|
||||
"integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==",
|
||||
"dependencies": {
|
||||
"@trysound/sax": "0.2.0",
|
||||
"commander": "^7.2.0",
|
||||
"css-select": "^4.1.3",
|
||||
"css-tree": "^1.1.3",
|
||||
"csso": "^4.2.0",
|
||||
"picocolors": "^1.0.0",
|
||||
"sax": "^1.5.0",
|
||||
"stable": "^0.1.8"
|
||||
},
|
||||
"bin": {
|
||||
|
||||
7
lib/SvelteUi/json/conf_cloud.json
Normal file
7
lib/SvelteUi/json/conf_cloud.json
Normal file
@@ -0,0 +1,7 @@
|
||||
"c": {
|
||||
"e" : %s,
|
||||
"p" : %d,
|
||||
"es": %s,
|
||||
"ze": %s,
|
||||
"zt" : "%s"
|
||||
}
|
||||
5
lib/SvelteUi/json/conf_debug.json
Normal file
5
lib/SvelteUi/json/conf_debug.json
Normal file
@@ -0,0 +1,5 @@
|
||||
"d": {
|
||||
"s": %s,
|
||||
"t": %s,
|
||||
"l": %d
|
||||
},
|
||||
7
lib/SvelteUi/json/conf_domoticz.json
Normal file
7
lib/SvelteUi/json/conf_domoticz.json
Normal file
@@ -0,0 +1,7 @@
|
||||
"o": {
|
||||
"e" : %d,
|
||||
"c" : %d,
|
||||
"u1" : %d,
|
||||
"u2" : %d,
|
||||
"u3" : %d
|
||||
},
|
||||
8
lib/SvelteUi/json/conf_general.json
Normal file
8
lib/SvelteUi/json/conf_general.json
Normal file
@@ -0,0 +1,8 @@
|
||||
"g": {
|
||||
"t": "%s",
|
||||
"h": "%s",
|
||||
"s": %d,
|
||||
"u": "%s",
|
||||
"p": "%s",
|
||||
"c": "%s"
|
||||
},
|
||||
37
lib/SvelteUi/json/conf_gpio.json
Normal file
37
lib/SvelteUi/json/conf_gpio.json
Normal file
@@ -0,0 +1,37 @@
|
||||
"i": {
|
||||
"h": {
|
||||
"p": %s,
|
||||
"u": %s,
|
||||
"t": %s
|
||||
},
|
||||
"a": %s,
|
||||
"l": {
|
||||
"p": %s,
|
||||
"i": %s
|
||||
},
|
||||
"r": {
|
||||
"r": %s,
|
||||
"g": %s,
|
||||
"b": %s,
|
||||
"i": %s
|
||||
},
|
||||
"d": {
|
||||
"d": %s,
|
||||
"b": %d
|
||||
},
|
||||
"t": {
|
||||
"d": %s,
|
||||
"a": %s
|
||||
},
|
||||
"v": {
|
||||
"p": %s,
|
||||
"o": %.2f,
|
||||
"m": %.3f,
|
||||
"d": {
|
||||
"v": %d,
|
||||
"g": %d
|
||||
},
|
||||
"b": %.1f
|
||||
},
|
||||
"p": %d
|
||||
},
|
||||
5
lib/SvelteUi/json/conf_ha.json
Normal file
5
lib/SvelteUi/json/conf_ha.json
Normal file
@@ -0,0 +1,5 @@
|
||||
"h": {
|
||||
"t" : "%s",
|
||||
"h" : "%s",
|
||||
"n" : "%s"
|
||||
},
|
||||
23
lib/SvelteUi/json/conf_meter.json
Normal file
23
lib/SvelteUi/json/conf_meter.json
Normal file
@@ -0,0 +1,23 @@
|
||||
"m": {
|
||||
"o": %d,
|
||||
"a": %d,
|
||||
"b": %d,
|
||||
"p": %d,
|
||||
"i": %s,
|
||||
"s": %d,
|
||||
"d": %d,
|
||||
"f": %d,
|
||||
"r": %d,
|
||||
"e": {
|
||||
"e": %s,
|
||||
"k": "%s",
|
||||
"a": "%s"
|
||||
},
|
||||
"m": {
|
||||
"e": %s,
|
||||
"w": %.3f,
|
||||
"v": %.3f,
|
||||
"a": %.3f,
|
||||
"c": %.3f
|
||||
}
|
||||
},
|
||||
21
lib/SvelteUi/json/conf_mqtt.json
Normal file
21
lib/SvelteUi/json/conf_mqtt.json
Normal file
@@ -0,0 +1,21 @@
|
||||
"q": {
|
||||
"h": "%s",
|
||||
"p": %d,
|
||||
"u": "%s",
|
||||
"a": "%s",
|
||||
"c": "%s",
|
||||
"b": "%s",
|
||||
"r": "%s",
|
||||
"m": %d,
|
||||
"s": {
|
||||
"e": %s,
|
||||
"c": %s,
|
||||
"r": %s,
|
||||
"k": %s
|
||||
},
|
||||
"t": %d,
|
||||
"d": %d,
|
||||
"i": %d,
|
||||
"k": %d,
|
||||
"e": %s
|
||||
},
|
||||
13
lib/SvelteUi/json/conf_net.json
Normal file
13
lib/SvelteUi/json/conf_net.json
Normal file
@@ -0,0 +1,13 @@
|
||||
"n": {
|
||||
"c": %d,
|
||||
"m": "%s",
|
||||
"i": "%s",
|
||||
"s": "%s",
|
||||
"g": "%s",
|
||||
"d1": "%s",
|
||||
"d2": "%s",
|
||||
"d": %s,
|
||||
"n1": "%s",
|
||||
"h": %s,
|
||||
"x": %s
|
||||
},
|
||||
7
lib/SvelteUi/json/conf_price.json
Normal file
7
lib/SvelteUi/json/conf_price.json
Normal file
@@ -0,0 +1,7 @@
|
||||
"p": {
|
||||
"e": %s,
|
||||
"t": "%s",
|
||||
"r": "%s",
|
||||
"c": "%s",
|
||||
"m": %d
|
||||
},
|
||||
10
lib/SvelteUi/json/conf_price_row.json
Normal file
10
lib/SvelteUi/json/conf_price_row.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"t" : %d,
|
||||
"n" : "%s",
|
||||
"d" : %d,
|
||||
"a" : [%s],
|
||||
"h" : [%s],
|
||||
"v" : %.4f,
|
||||
"s" : { "m":%d,"d":%d},
|
||||
"e" : { "m":%d,"d":%d}
|
||||
}%s
|
||||
15
lib/SvelteUi/json/conf_thresholds.json
Normal file
15
lib/SvelteUi/json/conf_thresholds.json
Normal file
@@ -0,0 +1,15 @@
|
||||
"t": {
|
||||
"t": [
|
||||
%d,
|
||||
%d,
|
||||
%d,
|
||||
%d,
|
||||
%d,
|
||||
%d,
|
||||
%d,
|
||||
%d,
|
||||
%d,
|
||||
%d
|
||||
],
|
||||
"h": %d
|
||||
},
|
||||
18
lib/SvelteUi/json/conf_ui.json
Normal file
18
lib/SvelteUi/json/conf_ui.json
Normal file
@@ -0,0 +1,18 @@
|
||||
"u": {
|
||||
"i": %d,
|
||||
"e": %d,
|
||||
"v": %d,
|
||||
"a": %d,
|
||||
"r": %d,
|
||||
"c": %d,
|
||||
"t": %d,
|
||||
"p": %d,
|
||||
"d": %d,
|
||||
"m": %d,
|
||||
"s": %d,
|
||||
"l": %d,
|
||||
"h": %d,
|
||||
"f": %d,
|
||||
"k": %d,
|
||||
"lang" : "%s"
|
||||
},
|
||||
7
lib/SvelteUi/json/conf_wifi.json
Normal file
7
lib/SvelteUi/json/conf_wifi.json
Normal file
@@ -0,0 +1,7 @@
|
||||
"w": {
|
||||
"s": "%s",
|
||||
"p": "%s",
|
||||
"w": %.1f,
|
||||
"z": %d,
|
||||
"b": %s
|
||||
},
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": "%s",
|
||||
"chip": "%s",
|
||||
"chipId": "%s",
|
||||
"chipId": "%06x",
|
||||
"cpu": %d,
|
||||
"mac": "%s",
|
||||
"apmac": "%s",
|
||||
|
||||
@@ -19,6 +19,20 @@
|
||||
#include "html/response_json.h"
|
||||
#include "html/sysinfo_json.h"
|
||||
#include "html/tariff_json.h"
|
||||
#include "html/conf_general_json.h"
|
||||
#include "html/conf_meter_json.h"
|
||||
#include "html/conf_wifi_json.h"
|
||||
#include "html/conf_net_json.h"
|
||||
#include "html/conf_mqtt_json.h"
|
||||
#include "html/conf_price_json.h"
|
||||
#include "html/conf_price_row_json.h"
|
||||
#include "html/conf_thresholds_json.h"
|
||||
#include "html/conf_debug_json.h"
|
||||
#include "html/conf_gpio_json.h"
|
||||
#include "html/conf_domoticz_json.h"
|
||||
#include "html/conf_ha_json.h"
|
||||
#include "html/conf_ui_json.h"
|
||||
#include "html/conf_cloud_json.h"
|
||||
#include "html/firmware_html.h"
|
||||
|
||||
#if defined(ESP32)
|
||||
@@ -292,22 +306,14 @@ void AmsWebServer::sysinfoJson() {
|
||||
|
||||
SystemConfig sys;
|
||||
config->getSystemConfig(sys);
|
||||
|
||||
uint32_t chipId;
|
||||
#if defined(ESP32)
|
||||
chipId = ( ESP.getEfuseMac() >> 32 ) % 0xFFFFFFFF;
|
||||
#else
|
||||
chipId = ESP.getChipId();
|
||||
#endif
|
||||
String chipIdStr = String(chipId, HEX);
|
||||
|
||||
String hostname;
|
||||
|
||||
char hostname[32];
|
||||
if(sys.userConfigured) {
|
||||
NetworkConfig networkConfig;
|
||||
config->getNetworkConfig(networkConfig);
|
||||
hostname = String(networkConfig.hostname);
|
||||
strncpy(hostname, networkConfig.hostname, 32);
|
||||
} else {
|
||||
hostname = "ams-"+chipIdStr;
|
||||
config->getUniqueName(hostname, 32);
|
||||
}
|
||||
|
||||
IPAddress localIp;
|
||||
@@ -407,7 +413,7 @@ void AmsWebServer::sysinfoJson() {
|
||||
#elif defined(ESP8266)
|
||||
"esp8266",
|
||||
#endif
|
||||
chipIdStr.c_str(),
|
||||
config->getChipId(),
|
||||
cpu_freq,
|
||||
macStr,
|
||||
apMacStr,
|
||||
@@ -415,7 +421,7 @@ void AmsWebServer::sysinfoJson() {
|
||||
sys.vendorConfigured ? "true" : "false",
|
||||
sys.userConfigured ? "true" : "false",
|
||||
sys.dataCollectionConsent,
|
||||
hostname.c_str(),
|
||||
hostname,
|
||||
performRestart ? "true" : "false",
|
||||
updater->getProgress() > 0.0 && upinfo.errorCode == 0 ? "true" : "false",
|
||||
#if defined(ESP8266)
|
||||
@@ -878,14 +884,244 @@ void AmsWebServer::configurationJson() {
|
||||
if(!checkSecurity(1))
|
||||
return;
|
||||
|
||||
|
||||
MeterConfig meterConfig;
|
||||
config->getMeterConfig(meterConfig);
|
||||
|
||||
bool multEnable = false;
|
||||
if(meterConfig.wattageMultiplier != 1.0 && meterConfig.wattageMultiplier != 0.0)
|
||||
multEnable = true;
|
||||
if(meterConfig.voltageMultiplier != 1.0 && meterConfig.voltageMultiplier != 0.0)
|
||||
multEnable = true;
|
||||
if(meterConfig.amperageMultiplier != 1.0 && meterConfig.amperageMultiplier != 0.0)
|
||||
multEnable = true;
|
||||
if(meterConfig.accumulatedMultiplier != 1.0 && meterConfig.accumulatedMultiplier != 0.0)
|
||||
multEnable = true;
|
||||
|
||||
SystemConfig sysConfig;
|
||||
config->getSystemConfig(sysConfig);
|
||||
NtpConfig ntpConfig;
|
||||
config->getNtpConfig(ntpConfig);
|
||||
NetworkConfig networkConfig;
|
||||
config->getNetworkConfig(networkConfig);
|
||||
|
||||
bool encen = false;
|
||||
for(uint8_t i = 0; i < 16; i++) {
|
||||
if(meterConfig.encryptionKey[i] > 0) {
|
||||
encen = true;
|
||||
}
|
||||
}
|
||||
|
||||
EnergyAccountingConfig* eac = ea->getConfig();
|
||||
MqttConfig mqttConfig;
|
||||
config->getMqttConfig(mqttConfig);
|
||||
|
||||
PriceServiceConfig price;
|
||||
config->getPriceServiceConfig(price);
|
||||
DebugConfig debugConfig;
|
||||
config->getDebugConfig(debugConfig);
|
||||
DomoticzConfig domo;
|
||||
config->getDomoticzConfig(domo);
|
||||
UiConfig ui;
|
||||
config->getUiConfig(ui);
|
||||
HomeAssistantConfig haconf;
|
||||
config->getHomeAssistantConfig(haconf);
|
||||
CloudConfig cloud;
|
||||
config->getCloudConfig(cloud);
|
||||
ZmartChargeConfig zcc;
|
||||
config->getZmartChargeConfig(zcc);
|
||||
stripNonAscii((uint8_t*) zcc.token, 21);
|
||||
|
||||
bool qsc = false;
|
||||
bool qsr = false;
|
||||
bool qsk = false;
|
||||
|
||||
if(LittleFS.begin()) {
|
||||
qsc = LittleFS.exists(FILE_MQTT_CA);
|
||||
qsr = LittleFS.exists(FILE_MQTT_CERT);
|
||||
qsk = LittleFS.exists(FILE_MQTT_KEY);
|
||||
}
|
||||
|
||||
addConditionalCloudHeaders();
|
||||
server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE);
|
||||
server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE);
|
||||
server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF);
|
||||
|
||||
server.setContentLength(CONTENT_LENGTH_UNKNOWN);
|
||||
AmsJsonGenerator::generateConfigurationJson(config, buf, BufferSize);
|
||||
server.send(200, MIME_JSON, buf);
|
||||
server.send_P(200, MIME_JSON, PSTR("{\"version\":\""));
|
||||
server.sendContent_P(FirmwareVersion::VersionString);
|
||||
server.sendContent_P(PSTR("\","));
|
||||
snprintf_P(buf, BufferSize, CONF_GENERAL_JSON,
|
||||
ntpConfig.timezone,
|
||||
networkConfig.hostname,
|
||||
webConfig.security,
|
||||
webConfig.username,
|
||||
strlen(webConfig.password) > 0 ? "***" : "",
|
||||
webConfig.context
|
||||
);
|
||||
server.sendContent(buf);
|
||||
snprintf_P(buf, BufferSize, CONF_METER_JSON,
|
||||
meterConfig.source,
|
||||
meterConfig.parser,
|
||||
meterConfig.baud,
|
||||
meterConfig.parity,
|
||||
meterConfig.invert ? "true" : "false",
|
||||
meterConfig.bufferSize * 64,
|
||||
meterConfig.distributionSystem,
|
||||
meterConfig.mainFuse,
|
||||
meterConfig.productionCapacity,
|
||||
encen ? "true" : "false",
|
||||
toHex(meterConfig.encryptionKey, 16).c_str(),
|
||||
toHex(meterConfig.authenticationKey, 16).c_str(),
|
||||
multEnable ? "true" : "false",
|
||||
meterConfig.wattageMultiplier == 0.0 ? 1.0 : meterConfig.wattageMultiplier / 1000.0,
|
||||
meterConfig.voltageMultiplier == 0.0 ? 1.0 : meterConfig.voltageMultiplier / 1000.0,
|
||||
meterConfig.amperageMultiplier == 0.0 ? 1.0 : meterConfig.amperageMultiplier / 1000.0,
|
||||
meterConfig.accumulatedMultiplier == 0.0 ? 1.0 : meterConfig.accumulatedMultiplier / 1000.0
|
||||
);
|
||||
server.sendContent(buf);
|
||||
|
||||
snprintf_P(buf, BufferSize, CONF_THRESHOLDS_JSON,
|
||||
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],
|
||||
eac->thresholds[9],
|
||||
eac->hours
|
||||
);
|
||||
server.sendContent(buf);
|
||||
snprintf_P(buf, BufferSize, CONF_WIFI_JSON,
|
||||
networkConfig.ssid,
|
||||
strlen(networkConfig.psk) > 0 ? "***" : "",
|
||||
networkConfig.power / 10.0,
|
||||
networkConfig.sleep,
|
||||
networkConfig.use11b ? "true" : "false"
|
||||
);
|
||||
server.sendContent(buf);
|
||||
snprintf_P(buf, BufferSize, CONF_NET_JSON,
|
||||
networkConfig.mode,
|
||||
strlen(networkConfig.ip) > 0 ? "static" : "dhcp",
|
||||
networkConfig.ip,
|
||||
networkConfig.subnet,
|
||||
networkConfig.gateway,
|
||||
networkConfig.dns1,
|
||||
networkConfig.dns2,
|
||||
networkConfig.mdns ? "true" : "false",
|
||||
ntpConfig.server,
|
||||
ntpConfig.dhcp ? "true" : "false",
|
||||
networkConfig.ipv6 ? "true" : "false"
|
||||
);
|
||||
server.sendContent(buf);
|
||||
snprintf_P(buf, BufferSize, CONF_MQTT_JSON,
|
||||
mqttConfig.host,
|
||||
mqttConfig.port,
|
||||
mqttConfig.username,
|
||||
strlen(mqttConfig.password) > 0 ? "***" : "",
|
||||
mqttConfig.clientId,
|
||||
mqttConfig.publishTopic,
|
||||
mqttConfig.subscribeTopic,
|
||||
mqttConfig.payloadFormat,
|
||||
mqttConfig.ssl ? "true" : "false",
|
||||
qsc ? "true" : "false",
|
||||
qsr ? "true" : "false",
|
||||
qsk ? "true" : "false",
|
||||
mqttConfig.stateUpdate,
|
||||
mqttConfig.stateUpdateInterval,
|
||||
mqttConfig.timeout,
|
||||
mqttConfig.keepalive,
|
||||
mqttConfig.rebootMinutes == 0 ? "null" : String(mqttConfig.rebootMinutes, 10).c_str()
|
||||
);
|
||||
server.sendContent(buf);
|
||||
|
||||
snprintf_P(buf, BufferSize, CONF_PRICE_JSON,
|
||||
price.enabled ? "true" : "false",
|
||||
price.entsoeToken,
|
||||
price.area,
|
||||
price.currency,
|
||||
price.resolutionInMinutes
|
||||
);
|
||||
server.sendContent(buf);
|
||||
snprintf_P(buf, BufferSize, CONF_DEBUG_JSON,
|
||||
debugConfig.serial ? "true" : "false",
|
||||
debugConfig.telnet ? "true" : "false",
|
||||
debugConfig.level
|
||||
);
|
||||
server.sendContent(buf);
|
||||
snprintf_P(buf, BufferSize, CONF_GPIO_JSON,
|
||||
meterConfig.rxPin == 0xff ? "null" : String(meterConfig.rxPin, 10).c_str(),
|
||||
meterConfig.rxPinPullup ? "true" : "false",
|
||||
meterConfig.txPin == 0xff ? "null" : String(meterConfig.txPin, 10).c_str(),
|
||||
gpioConfig->apPin == 0xff ? "null" : String(gpioConfig->apPin, 10).c_str(),
|
||||
gpioConfig->ledPin == 0xff ? "null" : String(gpioConfig->ledPin, 10).c_str(),
|
||||
gpioConfig->ledInverted ? "true" : "false",
|
||||
gpioConfig->ledPinRed == 0xff ? "null" : String(gpioConfig->ledPinRed, 10).c_str(),
|
||||
gpioConfig->ledPinGreen == 0xff ? "null" : String(gpioConfig->ledPinGreen, 10).c_str(),
|
||||
gpioConfig->ledPinBlue == 0xff ? "null" : String(gpioConfig->ledPinBlue, 10).c_str(),
|
||||
gpioConfig->ledRgbInverted ? "true" : "false",
|
||||
gpioConfig->ledDisablePin == 0xff ? "null" : String(gpioConfig->ledDisablePin, 10).c_str(),
|
||||
gpioConfig->ledBehaviour,
|
||||
gpioConfig->tempSensorPin == 0xff ? "null" : String(gpioConfig->tempSensorPin, 10).c_str(),
|
||||
gpioConfig->tempAnalogSensorPin == 0xff ? "null" : String(gpioConfig->tempAnalogSensorPin, 10).c_str(),
|
||||
gpioConfig->vccPin == 0xff ? "null" : String(gpioConfig->vccPin, 10).c_str(),
|
||||
gpioConfig->vccOffset / 100.0,
|
||||
gpioConfig->vccMultiplier / 1000.0,
|
||||
gpioConfig->vccResistorVcc,
|
||||
gpioConfig->vccResistorGnd,
|
||||
gpioConfig->vccBootLimit / 10.0,
|
||||
gpioConfig->powersaving
|
||||
);
|
||||
server.sendContent(buf);
|
||||
snprintf_P(buf, BufferSize, CONF_UI_JSON,
|
||||
ui.showImport,
|
||||
ui.showExport,
|
||||
ui.showVoltage,
|
||||
ui.showAmperage,
|
||||
ui.showReactive,
|
||||
ui.showRealtime,
|
||||
ui.showPeaks,
|
||||
ui.showPricePlot,
|
||||
ui.showDayPlot,
|
||||
ui.showMonthPlot,
|
||||
ui.showTemperaturePlot,
|
||||
ui.showRealtimePlot,
|
||||
ui.showPerPhasePower,
|
||||
ui.showPowerFactor,
|
||||
ui.darkMode,
|
||||
ui.language
|
||||
);
|
||||
server.sendContent(buf);
|
||||
snprintf_P(buf, BufferSize, CONF_DOMOTICZ_JSON,
|
||||
domo.elidx,
|
||||
domo.cl1idx,
|
||||
domo.vl1idx,
|
||||
domo.vl2idx,
|
||||
domo.vl3idx
|
||||
);
|
||||
server.sendContent(buf);
|
||||
snprintf_P(buf, BufferSize, CONF_HA_JSON,
|
||||
haconf.discoveryPrefix,
|
||||
haconf.discoveryHostname,
|
||||
haconf.discoveryNameTag
|
||||
);
|
||||
server.sendContent(buf);
|
||||
snprintf_P(buf, BufferSize, CONF_CLOUD_JSON,
|
||||
cloud.enabled ? "true" : "false",
|
||||
cloud.proto,
|
||||
#if defined(ESP32) && defined(ENERGY_SPEEDOMETER_PASS)
|
||||
sysConfig.energyspeedometer == 7 ? "true" : "false",
|
||||
#else
|
||||
"null",
|
||||
#endif
|
||||
zcc.enabled ? "true" : "false",
|
||||
zcc.token
|
||||
);
|
||||
server.sendContent(buf);
|
||||
server.sendContent_P(PSTR("}"));
|
||||
}
|
||||
|
||||
void AmsWebServer::priceConfigJson() {
|
||||
@@ -921,7 +1157,7 @@ void AmsWebServer::priceConfigJson() {
|
||||
}
|
||||
hours = hours.substring(0, hours.length()-1);
|
||||
|
||||
snprintf_P(buf, BufferSize, PSTR("{\"t\":%d,\"n\":\"%s\",\"d\":%d,\"a\":[%s],\"h\":[%s],\"v\":%.4f,\"s\":{\"m\":%d,\"d\":%d},\"e\":{\"m\":%d,\"d\":%d}}%s"),
|
||||
snprintf_P(buf, BufferSize, CONF_PRICE_ROW_JSON,
|
||||
p.type,
|
||||
p.name,
|
||||
p.direction,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
extra_configs = platformio-user.ini
|
||||
|
||||
[common]
|
||||
lib_deps = EEPROM, LittleFS, DNSServer, 256dpi/MQTT@2.5.2, OneWireNg@0.13.3, DallasTemperature@4.0.4, https://github.com/gskjold/RemoteDebug.git, PaulStoffregen/Time@1.6.1, JChristensen/Timezone@1.2.4, FirmwareVersion, AmsConfiguration, AmsData, AmsDataStorage, HwTools, Uptime, AmsDecoder, PriceService, EnergyAccounting, AmsFirmwareUpdater, AmsJsonGenerator, bblanchon/ArduinoJson@7.0.4, AmsMqttHandler, RawMqttHandler, JsonMqttHandler, DomoticzMqttHandler, HomeAssistantMqttHandler, PassthroughMqttHandler, RealtimePlot, ConnectionHandler, MeterCommunicators
|
||||
lib_deps = EEPROM, LittleFS, DNSServer, 256dpi/MQTT@2.5.2, OneWireNg@0.13.3, DallasTemperature@4.0.4, https://github.com/gskjold/RemoteDebug.git, PaulStoffregen/Time@1.6.1, JChristensen/Timezone@1.2.4, FirmwareVersion, AmsConfiguration, AmsData, AmsDataStorage, HwTools, Uptime, AmsDecoder, PriceService, EnergyAccounting, AmsFirmwareUpdater, AmsJsonGenerator, AmsMqttHandler, RawMqttHandler, JsonMqttHandler, DomoticzMqttHandler, HomeAssistantMqttHandler, PassthroughMqttHandler, RealtimePlot, ConnectionHandler, MeterCommunicators
|
||||
lib_ignore = OneWire
|
||||
extra_scripts =
|
||||
pre:scripts/addversion.py
|
||||
@@ -19,7 +19,7 @@ build_flags =
|
||||
-fexceptions
|
||||
|
||||
[esp32]
|
||||
lib_deps = WiFi, Ethernet, ESPmDNS, WiFiClientSecure, HTTPClient, FS, WebServer, ESP32 Async UDP, ESP32SSDP, mulmer89/ESPRandom@1.5.0, ${common.lib_deps}, CloudConnector, ZmartCharge, SvelteUi
|
||||
lib_deps = WiFi, Ethernet, ESPmDNS, WiFiClientSecure, HTTPClient, FS, WebServer, ESP32 Async UDP, ESP32SSDP, mulmer89/ESPRandom@1.5.0, ${common.lib_deps}, bblanchon/ArduinoJson@7.0.4, CloudConnector, ZmartCharge, SvelteUi
|
||||
|
||||
[env:esp8266]
|
||||
platform = espressif8266@4.2.1
|
||||
|
||||
@@ -360,7 +360,7 @@ void resetBootCycleCounter(bool deepSleep) {
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
config.load(); // Need to run this to make sure all configuration have been migrated before we load GPIO config
|
||||
config.hasConfig(); // Need to run this to make sure all configuration have been migrated before we load GPIO config
|
||||
|
||||
if(!config.getGpioConfig(gpioConfig)) {
|
||||
config.clearGpio(gpioConfig);
|
||||
@@ -378,10 +378,6 @@ void setup() {
|
||||
|
||||
delay(1);
|
||||
hw.setup(&sysConfig, &gpioConfig);
|
||||
hw.ledOff(LED_INTERNAL);
|
||||
hw.ledOff(LED_RED);
|
||||
hw.ledOff(LED_GREEN);
|
||||
hw.ledOff(LED_BLUE);
|
||||
|
||||
if(gpioConfig.apPin >= 0) {
|
||||
pinMode(gpioConfig.apPin, INPUT_PULLUP);
|
||||
@@ -905,13 +901,7 @@ void handleEnergySpeedometer() {
|
||||
if(sysConfig.energyspeedometer == 7) {
|
||||
if(!meterState.getMeterId().isEmpty()) {
|
||||
if(energySpeedometer == NULL) {
|
||||
uint16_t chipId;
|
||||
#if defined(ESP32)
|
||||
chipId = ( ESP.getEfuseMac() >> 32 ) % 0xFFFFFFFF;
|
||||
#else
|
||||
chipId = ESP.getChipId();
|
||||
#endif
|
||||
strcpy(energySpeedometerConfig.clientId, (String("ams") + String(chipId, HEX)).c_str());
|
||||
config.getUniqueName(energySpeedometerConfig.clientId, 32);
|
||||
energySpeedometer = new JsonMqttHandler(energySpeedometerConfig, &Debug, (char*) commonBuffer, &hw, &ds, &updater);
|
||||
energySpeedometer->setCaVerification(false);
|
||||
}
|
||||
@@ -1464,17 +1454,29 @@ void toggleSetupMode() {
|
||||
#else
|
||||
WiFi.beginSmartConfig();
|
||||
#endif
|
||||
WiFi.softAP(PSTR("AMS2MQTT"));
|
||||
|
||||
char ssid[32];
|
||||
if(sysConfig.vendorConfigured) {
|
||||
// Use the standard SSID if the vendor has configured the device
|
||||
strcpy_P(ssid, PSTR("AMS2MQTT"));
|
||||
} else {
|
||||
// If not vendor configured, use a unique SSID to avoid conflicts if multiple devices are in setup mode at the same time
|
||||
config.getUniqueName(ssid, 32);
|
||||
}
|
||||
uint8_t debugLevel = RemoteDebug::INFO;
|
||||
#if defined(DEBUG_MODE)
|
||||
debugLevel = RemoteDebug::VERBOSE;
|
||||
#endif
|
||||
WiFi.softAP(ssid);
|
||||
Debug.setSerialEnabled(true);
|
||||
Debug.begin(F("192.168.4.1"), 23, debugLevel);
|
||||
debugI_P(PSTR("SSID: %s"), ssid);
|
||||
|
||||
if(dnsServer == NULL) {
|
||||
dnsServer = new DNSServer();
|
||||
}
|
||||
dnsServer->setErrorReplyCode(DNSReplyCode::NoError);
|
||||
dnsServer->start(53, PSTR("*"), WiFi.softAPIP());
|
||||
#if defined(DEBUG_MODE)
|
||||
Debug.setSerialEnabled(true);
|
||||
Debug.begin(F("192.168.4.1"), 23, RemoteDebug::VERBOSE);
|
||||
#endif
|
||||
setupMode = true;
|
||||
|
||||
hw.setBootSuccessful(false);
|
||||
@@ -1751,7 +1753,7 @@ void MQTT_connect() {
|
||||
case 0:
|
||||
case 5:
|
||||
case 6:
|
||||
mqttHandler = new JsonMqttHandler(&config, &Debug, (char*) commonBuffer, &hw, &ds, &updater);
|
||||
mqttHandler = new JsonMqttHandler(mqttConfig, &Debug, (char*) commonBuffer, &hw, &ds, &updater);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
|
||||
Reference in New Issue
Block a user