Compare commits

...

11 Commits

Author SHA1 Message Date
Gunnar Skjold
4634050700 Ability to clear fixed price 2023-10-15 15:47:31 +02:00
Gunnar Skjold
60fff4533a 11b mode for 8266 2023-10-15 15:47:05 +02:00
Gunnar Skjold
6a0921a445 Added option to disable 802.11b for ESP8266 2023-10-14 08:44:55 +02:00
Gunnar Skjold
2a44f89a7b Disabling voltage check for wifi 2023-10-14 08:20:11 +02:00
Gunnar Skjold
f9b4680b9c Improved MQTT SSL 2023-10-12 18:44:40 +02:00
Gunnar Skjold
2a10096306 Merge pull request #652 from UtilitechAS/dependabot/npm_and_yarn/lib/SvelteUi/app/postcss-8.4.31
Bump postcss from 8.4.24 to 8.4.31 in /lib/SvelteUi/app
2023-10-11 20:24:25 +02:00
Gunnar Skjold
17d8d325c0 Added support for MQTTs without CA validation and public/private key 2023-10-11 20:23:53 +02:00
Gunnar Skjold
88ddc6ea15 Fixed runaway price update 2023-10-10 21:08:37 +02:00
Gunnar Skjold
3af19c9b15 Minor adjustment to autodisable of 802.11b 2023-10-10 20:54:13 +02:00
dependabot[bot]
2d6b523e37 Bump postcss from 8.4.24 to 8.4.31 in /lib/SvelteUi/app
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.24 to 8.4.31.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.4.24...8.4.31)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-07 20:36:22 +00:00
Gunnar Skjold
28a6a62907 Fixed issue where price graph disappears 2023-10-04 07:01:13 +02:00
12 changed files with 209 additions and 82 deletions

View File

@@ -1200,6 +1200,7 @@ void AmsConfiguration::print(Print* debugger)
}
debugger->printf_P(PSTR("Hostname: '%s'\r\n"), wifi.hostname);
debugger->printf_P(PSTR("mDNS: '%s'\r\n"), wifi.mdns ? "Yes" : "No");
debugger->printf_P(PSTR("802.11b: '%s'\r\n"), wifi.use11b ? "Yes" : "No");
debugger->println(F(""));
delay(10);
debugger->flush();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -15,7 +15,7 @@
"@tailwindcss/forms": "^0.5.2",
"autoprefixer": "^10.4.7",
"http-proxy-middleware": "^2.0.1",
"postcss": "^8.4.14",
"postcss": "^8.4.31",
"postcss-load-config": "^4.0.1",
"svelte": "^3.49.0",
"svelte-navigator": "^3.2.2",
@@ -1682,9 +1682,9 @@
}
},
"node_modules/postcss": {
"version": "8.4.24",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz",
"integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==",
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
"integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
"funding": [
{
"type": "opencollective",
@@ -3936,9 +3936,9 @@
"dev": true
},
"postcss": {
"version": "8.4.24",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz",
"integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==",
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
"integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
"requires": {
"nanoid": "^3.3.6",
"picocolors": "^1.0.0",

View File

@@ -13,7 +13,7 @@
"@tailwindcss/forms": "^0.5.2",
"autoprefixer": "^10.4.7",
"http-proxy-middleware": "^2.0.1",
"postcss": "^8.4.14",
"postcss": "^8.4.31",
"postcss-load-config": "^4.0.1",
"svelte": "^3.49.0",
"svelte-navigator": "^3.2.2",

View File

@@ -9,6 +9,7 @@
import CountrySelectOptions from './CountrySelectOptions.svelte';
import { Link, navigate } from 'svelte-navigator';
import SubnetOptions from './SubnetOptions.svelte';
import TrashIcon from './TrashIcon.svelte';
export let sysinfo = {}
@@ -166,6 +167,45 @@
}
}
async function askDeleteCa() {
if(confirm('Are you sure you want to delete CA?')) {
const response = await fetch('/mqtt-ca', {
method: 'POST'
});
let res = (await response.text())
configurationStore.update(c => {
c.q.s.c = false;
return c;
});
}
}
async function askDeleteCert() {
if(confirm('Are you sure you want to delete cert?')) {
const response = await fetch('/mqtt-cert', {
method: 'POST'
});
let res = (await response.text())
configurationStore.update(c => {
c.q.s.r = false;
return c;
});
}
}
async function askDeleteKey() {
if(confirm('Are you sure you want to delete key?')) {
const response = await fetch('/mqtt-key', {
method: 'POST'
});
let res = (await response.text())
configurationStore.update(c => {
c.q.s.k = false;
return c;
});
}
}
const updateMqttPort = function() {
if(configuration.q.s.e) {
if(configuration.q.p == 1883) configuration.q.p = 8883;
@@ -404,11 +444,9 @@
<div class="my-3">
<label><input type="checkbox" name="wa" value="true" bind:checked={configuration.w.a} class="rounded mb-1"/> Auto reboot on connection problem</label>
</div>
{#if sysinfo.chip != 'esp8266'}
<div class="my-3">
<label><input type="checkbox" name="wb" value="true" bind:checked={configuration.w.b} class="rounded mb-1"/> Allow 802.11b legacy rates</label>
</div>
{/if}
</div>
<div class="cnt">
<strong class="text-sm">Network</strong>
@@ -466,32 +504,33 @@
</div>
</div>
{#if configuration.q.s.e}
<div class="my-1">
<div>
<Link to="/mqtt-ca">
{#if configuration.q.s.c}
<Badge color="green" text="CA OK" title="Click here to replace CA"/>
{:else}
<Badge color="blue" text="Upload CA" title="Click here to upload CA"/>
{/if}
</Link>
<div class="my-1 flex">
<span class="flex pr-2">
{#if configuration.q.s.c}
<span class="rounded-l-md bg-green-500 text-green-100 text-xs font-semibold px-2.5 py-1"><Link to="/mqtt-ca">CA OK</Link></span>
<span class="rounded-r-md bg-red-500 text-red-100 text-xs px-2.5 py-1" on:click={askDeleteCa} on:keypress={askDeleteCa}><TrashIcon/></span>
{:else}
<Link to="/mqtt-ca"><Badge color="blue" text="Upload CA" title="Click here to upload CA"/></Link>
{/if}
</span>
<Link to="/mqtt-cert">
{#if configuration.q.s.r}
<Badge color="green" text="Cert OK" title="Click here to replace certificate"/>
{:else}
<Badge color="blue" text="Upload cert" title="Click here to upload certificate"/>
{/if}
</Link>
<span class="flex pr-2">
{#if configuration.q.s.r}
<span class="rounded-l-md bg-green-500 text-green-100 text-xs font-semibold px-2.5 py-1"><Link to="/mqtt-cert">Cert OK</Link></span>
<span class="rounded-r-md bg-red-500 text-red-100 text-xs px-2.5 py-1" on:click={askDeleteCert} on:keypress={askDeleteCert}><TrashIcon/></span>
{:else}
<Link to="/mqtt-cert"><Badge color="blue" text="Upload cert" title="Click here to upload certificate"/></Link>
{/if}
</span>
<Link to="/mqtt-key">
{#if configuration.q.s.k}
<Badge color="green" text="Key OK" title="Click here to replace key"/>
{:else}
<Badge color="blue" text="Upload key" title="Click here to upload key"/>
{/if}
</Link>
</div>
<span class="flex pr-2">
{#if configuration.q.s.k}
<span class="rounded-l-md bg-green-500 text-green-100 text-xs font-semibold px-2.5 py-1"><Link to="/mqtt-key">Key OK</Link></span>
<span class="rounded-r-md bg-red-500 text-red-100 text-xs px-2.5 py-1" on:click={askDeleteKey} on:keypress={askDeleteKey}><TrashIcon/></span>
{:else}
<Link to="/mqtt-key"><Badge color="blue" text="Upload key" title="Click here to upload key"/></Link>
{/if}
</span>
</div>
{/if}
<div class="my-1">

View File

@@ -57,7 +57,7 @@ export const dataStore = readable(data, (set) => {
lastTemp = data.t;
setTimeout(getTemperatures, 2000);
}
if(lastPrice == null && data.pe && data.p) {
if(lastPrice == null && data.pe && data.p != null) {
lastPrice = data.p;
getPrices();
}
@@ -121,13 +121,17 @@ export async function shiftPrices() {
});
if(fetchUpdate) {
getPrices();
} else {
let date = new Date();
priceShiftTimeout = setTimeout(shiftPrices, ((60-date.getMinutes())*60000))
}
let date = new Date();
priceShiftTimeout = setTimeout(shiftPrices, ((60-date.getMinutes())*60000))
}
export async function getPrices() {
if(priceShiftTimeout) {
clearTimeout(priceShiftTimeout);
priceShiftTimeout = 0;
}
const response = await fetchWithTimeout("/energyprice.json");
prices = (await response.json())
pricesStore.set(prices);

View File

@@ -0,0 +1,5 @@
<script></script>
<!-- Heroicons -->
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
<path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
</svg>

View File

@@ -17,18 +17,21 @@ export default defineConfig({
plugins: [svelte()],
server: {
proxy: {
"/data.json": "http://192.168.233.235",
"/energyprice.json": "http://192.168.233.235",
"/dayplot.json": "http://192.168.233.235",
"/monthplot.json": "http://192.168.233.235",
"/temperature.json": "http://192.168.233.235",
"/sysinfo.json": "http://192.168.233.235",
"/configuration.json": "http://192.168.233.235",
"/tariff.json": "http://192.168.233.235",
"/save": "http://192.168.233.235",
"/reboot": "http://192.168.233.235",
"/configfile": "http://192.168.233.235",
"/upgrade": "http://192.168.233.235"
"/data.json": "http://192.168.233.244",
"/energyprice.json": "http://192.168.233.244",
"/dayplot.json": "http://192.168.233.244",
"/monthplot.json": "http://192.168.233.244",
"/temperature.json": "http://192.168.233.244",
"/sysinfo.json": "http://192.168.233.244",
"/configuration.json": "http://192.168.233.244",
"/tariff.json": "http://192.168.233.244",
"/save": "http://192.168.233.244",
"/reboot": "http://192.168.233.244",
"/configfile": "http://192.168.233.244",
"/upgrade": "http://192.168.233.244",
"/mqtt-ca": "http://192.168.233.244",
"/mqtt-cert": "http://192.168.233.244",
"/mqtt-key": "http://192.168.233.244",
}
}
})

View File

@@ -104,9 +104,13 @@ private:
void isAliveCheck();
void mqttCaUpload();
void mqttCaDelete();
void mqttCertUpload();
void mqttCertDelete();
void mqttKeyUpload();
void mqttKeyDelete();
HTTPUpload& uploadFile(const char* path);
void deleteFile(const char* path);
void configFileDownload();
void configFileUpload();

View File

@@ -100,9 +100,9 @@ void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, Meter
server.on(F("/robots.txt"), HTTP_GET, std::bind(&AmsWebServer::robotstxt, this));
server.on(F("/mqtt-ca"), HTTP_POST, std::bind(&AmsWebServer::firmwarePost, this), std::bind(&AmsWebServer::mqttCaUpload, this));
server.on(F("/mqtt-cert"), HTTP_POST, std::bind(&AmsWebServer::firmwarePost, this), std::bind(&AmsWebServer::mqttCertUpload, this));
server.on(F("/mqtt-key"), HTTP_POST, std::bind(&AmsWebServer::firmwarePost, this), std::bind(&AmsWebServer::mqttKeyUpload, this));
server.on(F("/mqtt-ca"), HTTP_POST, std::bind(&AmsWebServer::mqttCaDelete, this), std::bind(&AmsWebServer::mqttCaUpload, this));
server.on(F("/mqtt-cert"), HTTP_POST, std::bind(&AmsWebServer::mqttCertDelete, this), std::bind(&AmsWebServer::mqttCertUpload, this));
server.on(F("/mqtt-key"), HTTP_POST, std::bind(&AmsWebServer::mqttKeyDelete, this), std::bind(&AmsWebServer::mqttKeyUpload, this));
server.on(F("/configfile"), HTTP_POST, std::bind(&AmsWebServer::firmwarePost, this), std::bind(&AmsWebServer::configFileUpload, this));
server.on(F("/configfile.cfg"), HTTP_GET, std::bind(&AmsWebServer::configFileDownload, this));
@@ -240,11 +240,11 @@ void AmsWebServer::sysinfoJson() {
#if defined(ESP8266)
wifi_get_macaddr(STATION_IF, mac);
wifi_get_macaddr(SOFTAP_IF, apmac);
uint32_t cpu_freq = 80;
uint8_t cpu_freq = system_get_cpu_freq();
#elif defined(ESP32)
esp_wifi_get_mac((wifi_interface_t)ESP_IF_WIFI_STA, mac);
esp_wifi_get_mac((wifi_interface_t)ESP_IF_WIFI_AP, apmac);
uint32_t cpu_freq = esp_clk_cpu_freq();
uint32_t cpu_freq = esp_clk_cpu_freq() / 1000000;
#endif
sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
@@ -280,7 +280,7 @@ void AmsWebServer::sysinfoJson() {
"esp8266",
#endif
chipIdStr.c_str(),
cpu_freq / 1000000,
cpu_freq,
macStr,
apMacStr,
sys.boardType,
@@ -1450,7 +1450,7 @@ void AmsWebServer::handleSave() {
strcpy(entsoe.area, priceRegion.c_str());
strcpy(entsoe.currency, server.arg(F("pc")).c_str());
entsoe.multiplier = server.arg(F("pm")).toFloat() * 1000;
entsoe.fixedPrice = server.arg(F("pf")).toFloat() * 1000;
entsoe.fixedPrice = server.hasArg(F("pf")) ? server.arg(F("pf")).toFloat() * 1000 : 0;
config->setEntsoeConfig(entsoe);
}
@@ -1807,6 +1807,23 @@ void AmsWebServer::mqttCaUpload() {
}
}
void AmsWebServer::mqttCaDelete() {
if(!checkSecurity(1))
return;
if(!uploading) { // Not an upload
deleteFile(FILE_MQTT_CA);
server.send(200);
MqttConfig mqttConfig;
if(config->getMqttConfig(mqttConfig) && mqttConfig.ssl) {
config->setMqttChanged();
}
} else {
uploading = false;
server.send(200);
}
}
void AmsWebServer::mqttCertUpload() {
if(!checkSecurity(1))
return;
@@ -1823,6 +1840,23 @@ void AmsWebServer::mqttCertUpload() {
}
}
void AmsWebServer::mqttCertDelete() {
if(!checkSecurity(1))
return;
if(!uploading) { // Not an upload
deleteFile(FILE_MQTT_CERT);
server.send(200);
MqttConfig mqttConfig;
if(config->getMqttConfig(mqttConfig) && mqttConfig.ssl) {
config->setMqttChanged();
}
} else {
uploading = false;
server.send(200);
}
}
void AmsWebServer::mqttKeyUpload() {
if(!checkSecurity(1))
return;
@@ -1839,6 +1873,30 @@ void AmsWebServer::mqttKeyUpload() {
}
}
void AmsWebServer::mqttKeyDelete() {
if(!checkSecurity(1))
return;
if(!uploading) { // Not an upload
deleteFile(FILE_MQTT_KEY);
server.send(200);
MqttConfig mqttConfig;
if(config->getMqttConfig(mqttConfig) && mqttConfig.ssl) {
config->setMqttChanged();
}
} else {
uploading = false;
server.send(200);
}
}
void AmsWebServer::deleteFile(const char* path) {
if(LittleFS.begin()) {
LittleFS.remove(path);
LittleFS.end();
}
}
void AmsWebServer::tariffJson() {
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf_P(PSTR("Serving /tariff.json over http...\n"));

View File

@@ -577,11 +577,12 @@ void loop() {
debugW_P(PSTR("Used %dms to handle mqtt"), millis()-start);
}
}
/*
if(now - lastVoltageCheck > 500) {
handleVoltageCheck();
lastVoltageCheck = now;
}
*/
} else {
if(dnsServer != NULL) {
dnsServer->processNextRequest();
@@ -852,8 +853,8 @@ bool handleVoltageCheck() {
debugD_P(PSTR("Setting new max Vcc to %.2f"), vcc);
maxVcc = vcc;
} else if(WiFi.getMode() != WIFI_OFF) {
float diff = maxVcc-vcc;
if(diff > 0.3) {
float diff = min(maxVcc, (float) 3.3)-vcc;
if(diff > 0.4) {
debugW_P(PSTR("Vcc dropped to %.2f, disconnecting WiFi for 5 seconds to preserve power"), vcc);
WiFi_disconnect(2000);
return false;
@@ -1457,10 +1458,12 @@ void WiFi_connect() {
}
lastWifiRetry = millis();
/*
if(!handleVoltageCheck()) {
debugW_P(PSTR("Voltage is not high enough to reconnect"));
return;
}
*/
if (WiFi.status() != WL_CONNECTED) {
WiFiConfig wifi;
@@ -1510,16 +1513,18 @@ void WiFi_connect() {
if(!WiFi.config(ip, gw, sn, dns1, dns2)) {
debugE_P(PSTR("Static IP configuration is invalid, not using"));
}
} else {
#if defined(ESP32)
// This trick does not work anymore...
// WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE); // Workaround to make DHCP hostname work for ESP32. See: https://github.com/espressif/arduino-esp32/issues/2537
#endif
}
#if defined(ESP8266)
if(strlen(wifi.hostname) > 0) {
WiFi.hostname(wifi.hostname);
}
}
//wifi_set_phy_mode(PHY_MODE_11N);
if(!wifi.use11b) {
wifi_set_user_sup_rate(RATE_11G6M, RATE_11G54M);
wifi_set_user_rate_limit(RC_LIMIT_11G, 0x00, RATE_11G_G54M, RATE_11G_G6M);
wifi_set_user_rate_limit(RC_LIMIT_11N, 0x00, RATE_11N_MCS7S, RATE_11N_MCS0);
wifi_set_user_limit_rate_mask(LIMIT_RATE_MASK_ALL);
}
#endif
#if defined(ESP32)
WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN);
@@ -1569,9 +1574,6 @@ void WiFi_post_connect() {
debugI_P(PSTR("WiFi supports better rates than 802.11b, disabling"))
wifi.use11b = false;
config.setWiFiConfig(wifi);
config.ackWifiChange();
// Reconnect to enforce new setting
WiFi_disconnect(0);
return;
}
}
@@ -1866,7 +1868,14 @@ void MQTT_connect() {
BearSSL::X509List *serverTrustedCA = new BearSSL::X509List(file);
mqttSecureClient->setTrustAnchors(serverTrustedCA);
#elif defined(ESP32)
mqttSecureClient->loadCACert(file, file.size());
if(mqttSecureClient->loadCACert(file, file.size())) {
debugI_P(PSTR("CA accepted"));
} else {
debugW_P(PSTR("CA was rejected"));
delete mqttSecureClient;
mqttSecureClient = NULL;
return;
}
#endif
file.close();
@@ -1895,9 +1904,12 @@ void MQTT_connect() {
mqttSecureClient->loadPrivateKey(file, file.size());
file.close();
#endif
mqttClient = mqttSecureClient;
}
} else {
debugI_P(PSTR("No CA, disabling certificate validation"));
mqttSecureClient->setInsecure();
}
mqttClient = mqttSecureClient;
LittleFS.end();
debugD_P(PSTR("MQTT SSL setup complete (%dkb free heap)"), ESP.getFreeHeap());
@@ -1906,6 +1918,7 @@ void MQTT_connect() {
}
if(mqttClient == NULL) {
debugI_P(PSTR("No SSL, using client without SSL support"));
mqttClient = new WiFiClient();
}