AMS reader ${version}
+AMS reader ${version}
-
@@ -64,9 +64,9 @@
MQTT
Web
NTP
- ENTSO-E API
+ Price API
- Documentation
+ Documentation
-
-
+
-
-
+
-
-
+
diff --git a/web/meteradvanced.html b/lib/ClassicUi/html/meteradvanced.html
similarity index 100%
rename from web/meteradvanced.html
rename to lib/ClassicUi/html/meteradvanced.html
diff --git a/web/monthplot.json b/lib/ClassicUi/html/monthplot.json
similarity index 100%
rename from web/monthplot.json
rename to lib/ClassicUi/html/monthplot.json
diff --git a/web/mqtt.html b/lib/ClassicUi/html/mqtt.html
similarity index 100%
rename from web/mqtt.html
rename to lib/ClassicUi/html/mqtt.html
diff --git a/web/notfound.html b/lib/ClassicUi/html/notfound.html
similarity index 100%
rename from web/notfound.html
rename to lib/ClassicUi/html/notfound.html
diff --git a/web/ntp.html b/lib/ClassicUi/html/ntp.html
similarity index 100%
rename from web/ntp.html
rename to lib/ClassicUi/html/ntp.html
diff --git a/web/entsoe.html b/lib/ClassicUi/html/priceapi.html
similarity index 70%
rename from web/entsoe.html
rename to lib/ClassicUi/html/priceapi.html
index 44b4847e..60dc4e6f 100644
--- a/web/entsoe.html
+++ b/lib/ClassicUi/html/priceapi.html
@@ -1,38 +1,31 @@
+
+
+
+
+ ENTSO-E token
+
+
+ diff --git a/web/reset.html b/lib/ClassicUi/html/reset.html similarity index 100% rename from web/reset.html rename to lib/ClassicUi/html/reset.html diff --git a/web/restart.html b/lib/ClassicUi/html/restart.html similarity index 100% rename from web/restart.html rename to lib/ClassicUi/html/restart.html diff --git a/web/restartwait.html b/lib/ClassicUi/html/restartwait.html similarity index 96% rename from web/restartwait.html rename to lib/ClassicUi/html/restartwait.html index 4ef22ae8..3d0071fd 100644 --- a/web/restartwait.html +++ b/lib/ClassicUi/html/restartwait.html @@ -12,7 +12,7 @@
AMS reader ${version}
AMS reader ${version}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {#if sysinfo.upgrading}
+
+ {:else if sysinfo.booting}
+
+ {/if}
+
diff --git a/lib/SvelteUi/app/src/app.postcss b/lib/SvelteUi/app/src/app.postcss
new file mode 100644
index 00000000..dace2220
--- /dev/null
+++ b/lib/SvelteUi/app/src/app.postcss
@@ -0,0 +1,152 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+.gh-logo {
+ width: 2rem;
+ height: 2rem;
+}
+
+.cnt {
+ @apply bg-white m-2 p-2 rounded shadow-lg
+}
+
+.in-pre {
+ @apply flex items-center bg-gray-100 rounded-l-md border border-r-0 border-gray-300 px-3 whitespace-nowrap text-sm
+}
+
+.in-post {
+ @apply flex items-center bg-gray-100 rounded-r-md border border-l-0 border-gray-300 px-3 whitespace-nowrap text-sm
+}
+
+.in-txt {
+ @apply h-10 shadow-sm border-gray-300 disabled:bg-gray-200
+}
+.in-f {
+ @apply in-txt rounded-l-md
+}
+.in-m {
+ @apply in-txt border-l-0
+}
+.in-l {
+ @apply in-txt border-l-0 rounded-r-md
+}
+.in-s {
+ @apply in-txt rounded-md w-full
+}
+.tr {
+ @apply text-right
+}
+
+.bd-grn {
+ @apply my-auto bg-green-500 text-green-100 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded
+}
+.bd-ylo {
+ @apply my-auto bg-yellow-500 text-yellow-100 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded
+}
+.bd-red {
+ @apply my-auto bg-red-500 text-red-100 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded
+}
+.bd-blu {
+ @apply my-auto bg-blue-500 text-blue-100 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded
+}
+.bd-gry {
+ @apply my-auto bg-gray-500 text-gray-100 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded
+}
+
+.btn-pri {
+ @apply py-2 px-4 rounded bg-blue-500 text-white mr-3
+}
+
+.pl-root {
+ position: relative;
+}
+.pl-ov {
+ position: absolute;
+ top: 27%;
+ left: 25%;
+ width: 50%;
+ text-align: center;
+}
+.pl-val {
+ font-size: 1.7rem;
+}
+.pl-unt {
+ font-size: 1.0rem;
+ color: grey;
+}
+.pl-sub {
+ padding-top: 10px;
+ font-size: 1.0rem;
+}
+.pl-snt {
+ font-size: 0.7rem;
+ color: grey;
+}
+.pl-lab {
+ font-size: 1.0rem;
+}
+
+.chart {
+ width: 100%;
+ height: 100%;
+ margin: 0 auto;
+}
+
+svg {
+ position: relative;
+ width: 100%;
+}
+
+.tick {
+ font-family: Helvetica, Arial;
+ font-size: 0.85em;
+ font-weight: 200;
+}
+
+.tick line {
+ stroke: #e2e2e2;
+ stroke-dasharray: 2;
+}
+
+.tick text {
+ fill: #999;
+ text-anchor: start;
+}
+
+.tick.tick-0 line {
+ stroke-dasharray: 0;
+}
+
+.tick.tick-green line {
+ stroke: #32d900 !important;
+}
+
+.tick.tick-green text {
+ fill: #32d900 !important;
+}
+
+.tick.tick-orange line {
+ stroke: #d95600 !important;
+}
+
+.tick.tick-orange text {
+ fill: #d95600 !important;
+}
+
+.x-axis .tick text {
+ text-anchor: middle;
+}
+
+.bars rect {
+ stroke: rgb(0,0,0);
+ stroke-opacity: 0.25;
+ opacity: 0.9;
+}
+
+.bars text {
+ font-family: Helvetica, Arial;
+ font-size: 0.85em;
+ display: block;
+ text-align: center;
+}
diff --git a/lib/SvelteUi/app/src/assets/favicon.svg b/lib/SvelteUi/app/src/assets/favicon.svg
new file mode 100644
index 00000000..b00c064f
--- /dev/null
+++ b/lib/SvelteUi/app/src/assets/favicon.svg
@@ -0,0 +1,19 @@
+
+
+
diff --git a/lib/SvelteUi/app/src/assets/github.svg b/lib/SvelteUi/app/src/assets/github.svg
new file mode 100644
index 00000000..f25b68d5
--- /dev/null
+++ b/lib/SvelteUi/app/src/assets/github.svg
@@ -0,0 +1,6 @@
+
+
+
diff --git a/lib/SvelteUi/app/src/lib/AccountingData.svelte b/lib/SvelteUi/app/src/lib/AccountingData.svelte
new file mode 100644
index 00000000..c21dafbb
--- /dev/null
+++ b/lib/SvelteUi/app/src/lib/AccountingData.svelte
@@ -0,0 +1,54 @@
+
+
+
+ Real time calculation
+
+ {#if data && data.h !== undefined}
+
\ No newline at end of file
diff --git a/lib/SvelteUi/app/src/lib/AmpPlot.svelte b/lib/SvelteUi/app/src/lib/AmpPlot.svelte
new file mode 100644
index 00000000..3e5c9a75
--- /dev/null
+++ b/lib/SvelteUi/app/src/lib/AmpPlot.svelte
@@ -0,0 +1,62 @@
+
+
+
+ Hour
+ {data.h.u ? data.h.u.toFixed(2) : '-'} kWh {#if currency && (hasExport)}/ {data.h.c ? data.h.c.toFixed(2) : '-'} {currency}{/if}
+
+
+ Day
+ {data.d.u ? data.d.u.toFixed(1) : '-'} kWh {#if currency && (hasExport)}/ {data.d.c ? data.d.c.toFixed(2) : '-'} {currency}{/if}
+
+
+ Month
+ {data.m.u ? data.m.u.toFixed(0) : '-'} kWh {#if currency && (hasExport)}/ {data.m.c ? data.m.c.toFixed(2) : '-'} {currency}{/if}
+
+ {#if hasExport}
+
+ {/if}
+
+
+ Hour
+ {data.h.p ? data.h.p.toFixed(2) : '-'} kWh {#if currency}/ {data.h.i ? data.h.i.toFixed(2) : '-'} {currency}{/if}
+
+
+ Day
+ {data.d.p ? data.d.p.toFixed(1) : '-'} kWh {#if currency}/ {data.d.i ? data.d.i.toFixed(2) : '-'} {currency}{/if}
+
+
+ {:else}
+ Month
+ {data.m.p ? data.m.p.toFixed(0) : '-'} kWh {#if currency}/ {data.m.i ? data.m.i.toFixed(2) : '-'} {currency}{/if}
+
+
+ Hour
+ {data.h.c ? data.h.c.toFixed(2) : '-'} {currency}
+
+
+ Day
+ {data.d.c ? data.d.c.toFixed(2) : '-'} {currency}
+
+
+ {/if}
+ Month
+ {data.m.c ? data.m.c.toFixed(2) : '-'} {currency}
+
+ {#if config.title}
+ {config.title}
+ {/if}
+
+
diff --git a/lib/SvelteUi/app/src/lib/BoardTypeSelectOptions.svelte b/lib/SvelteUi/app/src/lib/BoardTypeSelectOptions.svelte
new file mode 100644
index 00000000..d0d51c39
--- /dev/null
+++ b/lib/SvelteUi/app/src/lib/BoardTypeSelectOptions.svelte
@@ -0,0 +1,48 @@
+
+
+
+{#if chip == 'esp8266'}
+
+
+
+{/if}
+{#if chip == 'esp32'}
+
+{/if}
+{#if chip == 'esp32s2'}
+
+
+{/if}
+{#if chip == 'esp32solo'}
+
+{/if}
diff --git a/lib/SvelteUi/app/src/lib/Clock.svelte b/lib/SvelteUi/app/src/lib/Clock.svelte
new file mode 100644
index 00000000..e0f5dc57
--- /dev/null
+++ b/lib/SvelteUi/app/src/lib/Clock.svelte
@@ -0,0 +1,11 @@
+
+
+{#if Math.abs(new Date().getTime()-timestamp.getTime()) < 300000 }
+{`${zeropad(timestamp.getDate())}. ${monthnames[timestamp.getMonth()]} ${zeropad(timestamp.getHours())}:${zeropad(timestamp.getMinutes())}`}
+{:else}
+{`${zeropad(timestamp.getDate())}.${zeropad(timestamp.getMonth())}.${timestamp.getFullYear()} ${zeropad(timestamp.getHours())}:${zeropad(timestamp.getMinutes())}`}
+{/if}
diff --git a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte
new file mode 100644
index 00000000..29bc503d
--- /dev/null
+++ b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte
@@ -0,0 +1,768 @@
+
+
+
+
+
+
+
+
+
+
+
+ {#if uiVisibility(sysinfo.ui.i, data.i)}
+
\ No newline at end of file
diff --git a/lib/SvelteUi/app/src/lib/DataStores.js b/lib/SvelteUi/app/src/lib/DataStores.js
new file mode 100644
index 00000000..d664fc25
--- /dev/null
+++ b/lib/SvelteUi/app/src/lib/DataStores.js
@@ -0,0 +1,183 @@
+import { readable, writable } from 'svelte/store';
+import { isBusPowered } from './Helpers';
+
+async function fetchWithTimeout(resource, options = {}) {
+ const { timeout = 8000 } = options;
+
+ const controller = new AbortController();
+ const id = setTimeout(() => controller.abort(), timeout);
+ const response = await fetch(resource, {
+ ...options,
+ signal: controller.signal
+ });
+ clearTimeout(id);
+ return response;
+ }
+
+let sysinfo = {
+ version: '',
+ chip: '',
+ mac: null,
+ apmac: null,
+ vndcfg: null,
+ usrcfg: null,
+ fwconsent: null,
+ booting: false,
+ upgrading: false,
+ ui: {},
+ security: 0
+};
+export const sysinfoStore = writable(sysinfo);
+export async function getSysinfo() {
+ const response = await fetchWithTimeout("/sysinfo.json?t=" + Math.floor(Date.now() / 1000));
+ sysinfo = (await response.json())
+ sysinfoStore.set(sysinfo);
+};
+
+let tries = 0;
+let lastTemp = -127;
+let lastPrice = null;
+let data = {};
+export const dataStore = readable(data, (set) => {
+ let timeout;
+ async function getData() {
+ fetchWithTimeout("/data.json")
+ .then((res) => res.json())
+ .then((data) => {
+ set(data);
+ if(lastTemp != data.t) {
+ lastTemp = data.t;
+ setTimeout(getTemperatures, 2000);
+ }
+ if(lastPrice != data.p) {
+ lastPrice = data.p;
+ setTimeout(getPrices, 4000);
+ }
+ if(sysinfo.upgrading) {
+ window.location.reload();
+ } else if(!sysinfo || !sysinfo.chip || sysinfo.booting || (tries > 1 && !isBusPowered(sysinfo.board))) {
+ getSysinfo();
+ if(dayPlotTimeout) clearTimeout(dayPlotTimeout);
+ dayPlotTimeout = setTimeout(getDayPlot, 2000);
+ if(monthPlotTimeout) clearTimeout(monthPlotTimeout);
+ monthPlotTimeout = setTimeout(getMonthPlot, 3000);
+ }
+ let to = 5000;
+ if(isBusPowered(sysinfo.board) && data.v > 2.5) {
+ let diff = (3.3 - Math.min(3.3, data.v));
+ if(diff > 0) {
+ to = Math.max(diff, 0.1) * 10 * 5000;
+ }
+ }
+ if(to > 5000) console.log("Scheduling next data fetch in " + to + "ms");
+ if(timeout) clearTimeout(timeout);
+ timeout = setTimeout(getData, to);
+ tries = 0;
+ })
+ .catch((err) => {
+ tries++;
+ if(tries > 3) {
+ set({
+ em: 3,
+ hm: 0,
+ wm: 0,
+ mm: 0
+ });
+ timeout = setTimeout(getData, 15000);
+ } else {
+ timeout = setTimeout(getData, isBusPowered(sysinfo.board) ? 10000 : 5000);
+ }
+ });
+ }
+ getData();
+ return function stop() {
+ clearTimeout(timeout);
+ }
+});
+
+let prices = {};
+export const pricesStore = writable(prices);
+export async function getPrices() {
+ const response = await fetchWithTimeout("/energyprice.json");
+ prices = (await response.json())
+ pricesStore.set(prices);
+}
+
+let dayPlot = {};
+let dayPlotTimeout;
+export async function getDayPlot() {
+ if(dayPlotTimeout) {
+ clearTimeout(dayPlotTimeout);
+ dayPlotTimeout = 0;
+ }
+ const response = await fetchWithTimeout("/dayplot.json");
+ dayPlot = (await response.json())
+ dayPlotStore.set(dayPlot);
+
+ let date = new Date();
+ dayPlotTimeout = setTimeout(getDayPlot, ((60-date.getMinutes())*60000)+20)
+}
+
+export const dayPlotStore = writable(dayPlot, (set) => {
+ getDayPlot();
+ return function stop() {}
+});
+
+let monthPlot = {};
+let monthPlotTimeout;
+export async function getMonthPlot() {
+ if(monthPlotTimeout) {
+ clearTimeout(monthPlotTimeout);
+ monthPlotTimeout = 0;
+ }
+ const response = await fetchWithTimeout("/monthplot.json");
+ monthPlot = (await response.json())
+ monthPlotStore.set(monthPlot);
+
+ let date = new Date();
+ monthPlotTimeout = setTimeout(getMonthPlot, ((24-date.getHours())*3600000)+40)
+}
+
+export const monthPlotStore = writable(monthPlot, (set) => {
+ getMonthPlot();
+ return function stop() {}
+});
+
+let temperatures = {};
+export async function getTemperatures() {
+ const response = await fetchWithTimeout("/temperature.json");
+ temperatures = (await response.json())
+ temperaturesStore.set(temperatures);
+}
+
+export const temperaturesStore = writable(temperatures, (set) => {
+ getTemperatures();
+ return function stop() {}
+});
+
+let tariff = {};
+let tariffTimeout;
+export async function getTariff() {
+ if(tariffTimeout) {
+ clearTimeout(tariffTimeout);
+ tariffTimeout = 0;
+ }
+ const response = await fetchWithTimeout("/tariff.json");
+ tariff = (await response.json())
+ tariffStore.set(tariff);
+ let date = new Date();
+ tariffTimeout = setTimeout(getTariff, ((60-date.getMinutes())*60000)+30)
+}
+
+export const tariffStore = writable(tariff, (set) => {
+ return function stop() {}
+});
+
+let releases = [];
+export const gitHubReleaseStore = writable(releases);
+
+export async function getGitHubReleases() {
+ const response = await fetchWithTimeout("https://api.github.com/repos/UtilitechAS/amsreader-firmware/releases");
+ releases = (await response.json())
+ gitHubReleaseStore.set(releases);
+};
diff --git a/lib/SvelteUi/app/src/lib/DayPlot.svelte b/lib/SvelteUi/app/src/lib/DayPlot.svelte
new file mode 100644
index 00000000..7ee09bdc
--- /dev/null
+++ b/lib/SvelteUi/app/src/lib/DayPlot.svelte
@@ -0,0 +1,101 @@
+
+
+
+
+ {/if}
+ {#if uiVisibility(sysinfo.ui.e, data.om || data.e > 0)}
+
+
+
+
+
+ {data.mt ? metertype(data.mt) : '-'}
+ {data.ic ? data.ic.toFixed(1) : '-'} kWh
+
+
+ {/if}
+ {#if uiVisibility(sysinfo.ui.v, data.u1 > 100 || data.u2 > 100 || data.u3 > 100)}
+
+
+
+
+
+
+ {data.ec ? data.ec.toFixed(1) : '-'} kWh
+
+
+
+ {/if}
+ {#if uiVisibility(sysinfo.ui.a, data.i1 > 0.01 || data.i2 > 0.01 || data.i3 > 0.01)}
+
+
+
+ {/if}
+ {#if uiVisibility(sysinfo.ui.r, data.ri > 0 || data.re > 0 || data.ric > 0 || data.rec > 0)}
+
+
+
+ {/if}
+ {#if uiVisibility(sysinfo.ui.c, data.ea)}
+
+
+
+ {/if}
+ {#if data && data.pr && (data.pr.startsWith("10YNO") || data.pr == '10Y1001A1001A48H')}
+
+
+
+ {/if}
+ {#if uiVisibility(sysinfo.ui.p, (typeof data.p == "number") && !Number.isNaN(data.p))}
+
+
+
+ {/if}
+ {#if uiVisibility(sysinfo.ui.d, dayPlot)}
+
+
+
+ {/if}
+ {#if uiVisibility(sysinfo.ui.m, monthPlot)}
+
+
+
+ {/if}
+ {#if uiVisibility(sysinfo.ui.s, data.t && data.t != -127 && temperatures.c > 1)}
+
+
+
+ {/if}
+
+
+
+ Upload {title}
+
+Select a suitable file and click upload
+ +
+
+{/if}
diff --git a/lib/SvelteUi/app/src/lib/MonthPlot.svelte b/lib/SvelteUi/app/src/lib/MonthPlot.svelte
new file mode 100644
index 00000000..15991410
--- /dev/null
+++ b/lib/SvelteUi/app/src/lib/MonthPlot.svelte
@@ -0,0 +1,103 @@
+
+
+
+ {#if message}
+
+{message}
+ {/if}
+
+
+
+ {label}
+
+ {val} + {unit} + {#if sub} +
+ {sub} + {subunit}/kWh + {/if} + +
diff --git a/lib/SvelteUi/app/src/lib/PowerGaugeSvg.svelte b/lib/SvelteUi/app/src/lib/PowerGaugeSvg.svelte
new file mode 100644
index 00000000..eef9456a
--- /dev/null
+++ b/lib/SvelteUi/app/src/lib/PowerGaugeSvg.svelte
@@ -0,0 +1,31 @@
+
+
+
diff --git a/lib/SvelteUi/app/src/lib/PricePlot.svelte b/lib/SvelteUi/app/src/lib/PricePlot.svelte
new file mode 100644
index 00000000..c7d5d78a
--- /dev/null
+++ b/lib/SvelteUi/app/src/lib/PricePlot.svelte
@@ -0,0 +1,97 @@
+
+
+Provided by ENTSO-E
++ {val} + {unit} + {#if sub} +
+ {sub} + {subunit}/kWh + {/if} + +
+ Reactive
+
+
\ No newline at end of file
diff --git a/lib/SvelteUi/app/src/lib/SetupPanel.svelte b/lib/SvelteUi/app/src/lib/SetupPanel.svelte
new file mode 100644
index 00000000..d1ef3c36
--- /dev/null
+++ b/lib/SvelteUi/app/src/lib/SetupPanel.svelte
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+ Instant in
+ {typeof importInstant !== 'undefined' ? importInstant.toFixed(0) : '-'} VAr
+ Instant out
+ {typeof exportInstant !== 'undefined' ? exportInstant.toFixed(0) : '-'} VAr
+
+
+Total in
+ {typeof importTotal !== 'undefined' ? importTotal.toFixed(1) : '-'} kVArh
+ Total out
+ {typeof exportTotal !== 'undefined' ? exportTotal.toFixed(1) : '-'} kVArh
+
+
+
+
+
+
+
+
+
+ Device information
+
+ {#if sysinfo.meter}
+
+ Chip: {sysinfo.chip}
+
+
+ Device: {boardtype(sysinfo.chip, sysinfo.board)}
+
+
+ MAC: {sysinfo.mac}
+
+ {#if sysinfo.apmac && sysinfo.apmac != sysinfo.mac}
+
+ AP MAC: {sysinfo.apmac}
+
+ {/if}
+
+
+ Update consents
+
+
+
+
+ Meter
+
+ {/if}
+ {#if sysinfo.net}
+
+ Manufacturer: {metertype(sysinfo.meter.mfg)}
+
+
+ Model: {sysinfo.meter.model}
+
+
+ ID: {sysinfo.meter.id}
+
+
+ Network
+
+ {/if}
+
+ IP: {sysinfo.net.ip}
+
+
+ Mask: {sysinfo.net.mask}
+
+
+ Gateway: {sysinfo.net.gw}
+
+
+ DNS: {sysinfo.net.dns1} {#if sysinfo.net.dns2 && sysinfo.net.dns2 != '0.0.0.0'}/ {sysinfo.net.dns2}{/if}
+
+
+ Firmware
+
+ {#if sysinfo.security == 0 || data.a}
+
+ Installed version: {sysinfo.version}
+
+ {#if nextVersion}
+
+ Latest version:
+ {nextVersion.tag_name}
+ {#if (sysinfo.security == 0 || data.a) && sysinfo.fwconsent === 1 && nextVersion && nextVersion.tag_name}
+
+ {#if sysinfo.fwconsent === 2}
+
+
+
+ {/if}
+
+
+ {/if}
+ {/if}
+ {#if (sysinfo.security == 0 || data.a) && isBusPowered(sysinfo.board) }
+ You have disabled one-click firmware upgrade, link to self-upgrade is disabled
+
+ {boardtype(sysinfo.chip, sysinfo.board)} must be connected to an external power supply during firmware upgrade. Failure to do so may cause power-down during upload resulting in non-functioning unit.
+
+ {/if}
+ {#if sysinfo.security == 0 || data.a}
+
+
+
+ {/if}
+
+ Configuration
+
+
+
+ {/if}
+
+
+
+
+
+
+
-Go to the [WiKi](https://github.com/gskjold/AmsToMqttBridge/wiki) for information on how to get your own device! And find the latest prebuilt firmware file at the [release section](https://github.com/gskjold/AmsToMqttBridge/releases).
+Go to the [WiKi](https://github.com/UtilitechAS/amsreader-firmware/wiki) for information on how to get your own device! And find the latest prebuilt firmware file at the [release section](https://github.com/UtilitechAS/amsreader-firmware/releases).
## Building this project with PlatformIO
To build this project, you need [PlatformIO](https://platformio.org/) installed.
diff --git a/hardware/README.md b/hardware/README.md
index 422bcb43..fd2bf581 100644
--- a/hardware/README.md
+++ b/hardware/README.md
@@ -1 +1 @@
-[See Hardware page in Wiki](https://github.com/gskjold/AmsToMqttBridge/wiki)
+[See Hardware page in Wiki](https://github.com/UtilitechAS/amsreader-firmware/wiki)
diff --git a/hardware/v1/kicad/HAN_ESP_TSS721-backups/HAN_ESP_TSS721-2022-06-25_174436.zip b/hardware/v1/kicad/HAN_ESP_TSS721-backups/HAN_ESP_TSS721-2022-06-25_174436.zip
new file mode 100644
index 00000000..cebef764
Binary files /dev/null and b/hardware/v1/kicad/HAN_ESP_TSS721-backups/HAN_ESP_TSS721-2022-06-25_174436.zip differ
diff --git a/hardware/v1/kicad/HAN_ESP_TSS721-backups/HAN_ESP_TSS721-2022-06-25_190751.zip b/hardware/v1/kicad/HAN_ESP_TSS721-backups/HAN_ESP_TSS721-2022-06-25_190751.zip
new file mode 100644
index 00000000..9fd0b14f
Binary files /dev/null and b/hardware/v1/kicad/HAN_ESP_TSS721-backups/HAN_ESP_TSS721-2022-06-25_190751.zip differ
diff --git a/hardware/v1/kicad/HAN_ESP_TSS721.kicad_prl b/hardware/v1/kicad/HAN_ESP_TSS721.kicad_prl
new file mode 100644
index 00000000..4c89d5ae
--- /dev/null
+++ b/hardware/v1/kicad/HAN_ESP_TSS721.kicad_prl
@@ -0,0 +1,76 @@
+{
+ "board": {
+ "active_layer": 0,
+ "active_layer_preset": "",
+ "auto_track_width": true,
+ "hidden_nets": [],
+ "high_contrast_mode": 0,
+ "net_color_mode": 1,
+ "opacity": {
+ "pads": 1.0,
+ "tracks": 1.0,
+ "vias": 1.0,
+ "zones": 0.6
+ },
+ "ratsnest_display_mode": 0,
+ "selection_filter": {
+ "dimensions": true,
+ "footprints": true,
+ "graphics": true,
+ "keepouts": true,
+ "lockedItems": true,
+ "otherItems": true,
+ "pads": true,
+ "text": true,
+ "tracks": true,
+ "vias": true,
+ "zones": true
+ },
+ "visible_items": [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16,
+ 17,
+ 18,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 32,
+ 33,
+ 34,
+ 35,
+ 36
+ ],
+ "visible_layers": "fffffff_ffffffff",
+ "zone_display_mode": 0
+ },
+ "meta": {
+ "filename": "HAN_ESP_TSS721.kicad_prl",
+ "version": 3
+ },
+ "project": {
+ "files": []
+ }
+}
diff --git a/hardware/v1/kicad/HAN_ESP_TSS721.kicad_pro b/hardware/v1/kicad/HAN_ESP_TSS721.kicad_pro
new file mode 100644
index 00000000..1fbda6af
--- /dev/null
+++ b/hardware/v1/kicad/HAN_ESP_TSS721.kicad_pro
@@ -0,0 +1,440 @@
+{
+ "board": {
+ "design_settings": {
+ "defaults": {
+ "board_outline_line_width": 0.15,
+ "copper_line_width": 0.19999999999999998,
+ "copper_text_italic": false,
+ "copper_text_size_h": 1.5,
+ "copper_text_size_v": 1.5,
+ "copper_text_thickness": 0.3,
+ "copper_text_upright": false,
+ "courtyard_line_width": 0.049999999999999996,
+ "dimension_precision": 4,
+ "dimension_units": 3,
+ "dimensions": {
+ "arrow_length": 1270000,
+ "extension_offset": 500000,
+ "keep_text_aligned": true,
+ "suppress_zeroes": false,
+ "text_position": 0,
+ "units_format": 1
+ },
+ "fab_line_width": 0.09999999999999999,
+ "fab_text_italic": false,
+ "fab_text_size_h": 1.0,
+ "fab_text_size_v": 1.0,
+ "fab_text_thickness": 0.15,
+ "fab_text_upright": false,
+ "other_line_width": 0.09999999999999999,
+ "other_text_italic": false,
+ "other_text_size_h": 1.0,
+ "other_text_size_v": 1.0,
+ "other_text_thickness": 0.15,
+ "other_text_upright": false,
+ "pads": {
+ "drill": 0.762,
+ "height": 1.524,
+ "width": 1.524
+ },
+ "silk_line_width": 0.15,
+ "silk_text_italic": false,
+ "silk_text_size_h": 1.0,
+ "silk_text_size_v": 1.0,
+ "silk_text_thickness": 0.15,
+ "silk_text_upright": false,
+ "zones": {
+ "45_degree_only": true,
+ "min_clearance": 0.508
+ }
+ },
+ "diff_pair_dimensions": [],
+ "drc_exclusions": [],
+ "meta": {
+ "filename": "board_design_settings.json",
+ "version": 2
+ },
+ "rule_severities": {
+ "annular_width": "error",
+ "clearance": "error",
+ "copper_edge_clearance": "error",
+ "courtyards_overlap": "error",
+ "diff_pair_gap_out_of_range": "error",
+ "diff_pair_uncoupled_length_too_long": "error",
+ "drill_out_of_range": "error",
+ "duplicate_footprints": "warning",
+ "extra_footprint": "warning",
+ "footprint_type_mismatch": "error",
+ "hole_clearance": "error",
+ "hole_near_hole": "error",
+ "invalid_outline": "error",
+ "item_on_disabled_layer": "error",
+ "items_not_allowed": "error",
+ "length_out_of_range": "error",
+ "malformed_courtyard": "error",
+ "microvia_drill_out_of_range": "error",
+ "missing_courtyard": "ignore",
+ "missing_footprint": "warning",
+ "net_conflict": "warning",
+ "npth_inside_courtyard": "ignore",
+ "padstack": "error",
+ "pth_inside_courtyard": "ignore",
+ "shorting_items": "error",
+ "silk_over_copper": "warning",
+ "silk_overlap": "warning",
+ "skew_out_of_range": "error",
+ "through_hole_pad_without_hole": "error",
+ "too_many_vias": "error",
+ "track_dangling": "warning",
+ "track_width": "error",
+ "tracks_crossing": "error",
+ "unconnected_items": "error",
+ "unresolved_variable": "error",
+ "via_dangling": "warning",
+ "zone_has_empty_net": "error",
+ "zones_intersect": "error"
+ },
+ "rules": {
+ "allow_blind_buried_vias": false,
+ "allow_microvias": false,
+ "max_error": 0.005,
+ "min_clearance": 0.0,
+ "min_copper_edge_clearance": 0.075,
+ "min_hole_clearance": 0.25,
+ "min_hole_to_hole": 0.25,
+ "min_microvia_diameter": 0.19999999999999998,
+ "min_microvia_drill": 0.09999999999999999,
+ "min_silk_clearance": 0.0,
+ "min_through_hole_diameter": 0.3,
+ "min_track_width": 0.19999999999999998,
+ "min_via_annular_width": 0.049999999999999996,
+ "min_via_diameter": 0.39999999999999997,
+ "use_height_for_length_calcs": true
+ },
+ "track_widths": [
+ 0.0,
+ 0.2,
+ 0.4,
+ 0.6,
+ 1.0
+ ],
+ "via_dimensions": [],
+ "zones_allow_external_fillets": false,
+ "zones_use_no_outline": true
+ },
+ "layer_presets": []
+ },
+ "boards": [],
+ "cvpcb": {
+ "equivalence_files": []
+ },
+ "erc": {
+ "erc_exclusions": [],
+ "meta": {
+ "version": 0
+ },
+ "pin_map": [
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 0,
+ 2,
+ 0,
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 2,
+ 2,
+ 2
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 2
+ ],
+ [
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 1,
+ 2,
+ 1,
+ 1,
+ 2
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 2
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 0,
+ 2,
+ 1,
+ 2,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 2,
+ 2,
+ 2
+ ],
+ [
+ 0,
+ 2,
+ 0,
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 0,
+ 2,
+ 1,
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2
+ ]
+ ],
+ "rule_severities": {
+ "bus_definition_conflict": "error",
+ "bus_entry_needed": "error",
+ "bus_label_syntax": "error",
+ "bus_to_bus_conflict": "error",
+ "bus_to_net_conflict": "error",
+ "different_unit_footprint": "error",
+ "different_unit_net": "error",
+ "duplicate_reference": "error",
+ "duplicate_sheet_names": "error",
+ "extra_units": "error",
+ "global_label_dangling": "warning",
+ "hier_label_mismatch": "error",
+ "label_dangling": "error",
+ "lib_symbol_issues": "warning",
+ "multiple_net_names": "warning",
+ "net_not_bus_member": "warning",
+ "no_connect_connected": "warning",
+ "no_connect_dangling": "warning",
+ "pin_not_connected": "error",
+ "pin_not_driven": "error",
+ "pin_to_pin": "warning",
+ "power_pin_not_driven": "error",
+ "similar_labels": "warning",
+ "unannotated": "error",
+ "unit_value_mismatch": "error",
+ "unresolved_variable": "error",
+ "wire_dangling": "error"
+ }
+ },
+ "libraries": {
+ "pinned_footprint_libs": [],
+ "pinned_symbol_libs": []
+ },
+ "meta": {
+ "filename": "HAN_ESP_TSS721.kicad_pro",
+ "version": 1
+ },
+ "net_settings": {
+ "classes": [
+ {
+ "bus_width": 12.0,
+ "clearance": 0.2,
+ "diff_pair_gap": 0.25,
+ "diff_pair_via_gap": 0.25,
+ "diff_pair_width": 0.2,
+ "line_style": 0,
+ "microvia_diameter": 0.3,
+ "microvia_drill": 0.1,
+ "name": "Default",
+ "pcb_color": "rgba(0, 0, 0, 0.000)",
+ "schematic_color": "rgba(0, 0, 0, 0.000)",
+ "track_width": 0.25,
+ "via_diameter": 0.6,
+ "via_drill": 0.4,
+ "wire_width": 6.0
+ },
+ {
+ "bus_width": 12.0,
+ "clearance": 0.5,
+ "diff_pair_gap": 0.25,
+ "diff_pair_via_gap": 0.25,
+ "diff_pair_width": 0.2,
+ "line_style": 0,
+ "microvia_diameter": 0.5,
+ "microvia_drill": 0.2,
+ "name": "PWR",
+ "nets": [
+ "+3V3"
+ ],
+ "pcb_color": "rgba(0, 0, 0, 0.000)",
+ "schematic_color": "rgba(0, 0, 0, 0.000)",
+ "track_width": 0.5,
+ "via_diameter": 0.8,
+ "via_drill": 0.6,
+ "wire_width": 6.0
+ }
+ ],
+ "meta": {
+ "version": 2
+ },
+ "net_colors": null
+ },
+ "pcbnew": {
+ "last_paths": {
+ "gencad": "",
+ "idf": "",
+ "netlist": "",
+ "specctra_dsn": "",
+ "step": "",
+ "vrml": ""
+ },
+ "page_layout_descr_file": ""
+ },
+ "schematic": {
+ "annotate_start_num": 0,
+ "drawing": {
+ "default_line_thickness": 6.0,
+ "default_text_size": 50.0,
+ "field_names": [],
+ "intersheets_ref_own_page": false,
+ "intersheets_ref_prefix": "",
+ "intersheets_ref_short": false,
+ "intersheets_ref_show": false,
+ "intersheets_ref_suffix": "",
+ "junction_size_choice": 3,
+ "label_size_ratio": 0.25,
+ "pin_symbol_size": 0.0,
+ "text_offset_ratio": 0.08
+ },
+ "legacy_lib_dir": "",
+ "legacy_lib_list": [],
+ "meta": {
+ "version": 1
+ },
+ "net_format_name": "",
+ "ngspice": {
+ "fix_include_paths": true,
+ "fix_passive_vals": false,
+ "meta": {
+ "version": 0
+ },
+ "model_mode": 0,
+ "workbook_filename": ""
+ },
+ "page_layout_descr_file": "",
+ "plot_directory": "",
+ "spice_adjust_passive_values": false,
+ "spice_external_command": "spice \"%I\"",
+ "subpart_first_id": 65,
+ "subpart_id_separator": 0
+ },
+ "sheets": [],
+ "text_variables": {}
+}
diff --git a/hardware/v1/kicad/fp-info-cache b/hardware/v1/kicad/fp-info-cache
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/hardware/v1/kicad/fp-info-cache
@@ -0,0 +1 @@
+0
diff --git a/hardware/wemos_mbus_shield/kicad/d1_mini_shield-backups/d1_mini_shield-2023-01-06_143235.zip b/hardware/wemos_mbus_shield/kicad/d1_mini_shield-backups/d1_mini_shield-2023-01-06_143235.zip
new file mode 100644
index 00000000..6281d2a3
Binary files /dev/null and b/hardware/wemos_mbus_shield/kicad/d1_mini_shield-backups/d1_mini_shield-2023-01-06_143235.zip differ
diff --git a/hardware/wemos_mbus_shield/kicad/d1_mini_shield-rescue.dcm b/hardware/wemos_mbus_shield/kicad/d1_mini_shield-rescue.dcm
new file mode 100644
index 00000000..5f3ed79b
--- /dev/null
+++ b/hardware/wemos_mbus_shield/kicad/d1_mini_shield-rescue.dcm
@@ -0,0 +1,3 @@
+EESchema-DOCLIB Version 2.0
+#
+#End Doc Library
diff --git a/hardware/wemos_mbus_shield/kicad/d1_mini_shield-rescue.lib b/hardware/wemos_mbus_shield/kicad/d1_mini_shield-rescue.lib
index e33391c9..53ec0cf4 100644
--- a/hardware/wemos_mbus_shield/kicad/d1_mini_shield-rescue.lib
+++ b/hardware/wemos_mbus_shield/kicad/d1_mini_shield-rescue.lib
@@ -1,6 +1,21 @@
EESchema-LIBRARY Version 2.4
#encoding utf-8
#
+# +3.3V-power
+#
+DEF +3.3V-power #PWR 0 0 Y Y 1 F P
+F0 "#PWR" 0 -150 50 H I C CNN
+F1 "+3.3V-power" 0 140 50 H V C CNN
+F2 "" 0 0 50 H I C CNN
+F3 "" 0 0 50 H I C CNN
+DRAW
+P 2 0 1 0 -30 50 0 100 N
+P 2 0 1 0 0 0 0 100 N
+P 2 0 1 0 0 100 30 50 N
+X +3V3 1 0 0 0 U 50 50 1 1 W N
+ENDDRAW
+ENDDEF
+#
# CONN_01X08
#
DEF CONN_01X08 P 0 40 Y N 1 F N
@@ -35,4 +50,23 @@ X P8 8 -200 -350 150 R 50 50 1 1 P
ENDDRAW
ENDDEF
#
+# Jumper-Device
+#
+DEF Jumper-Device JP 0 30 Y N 1 F N
+F0 "JP" 0 150 50 H V C CNN
+F1 "Jumper-Device" 0 -80 50 H V C CNN
+F2 "" 0 0 50 H I C CNN
+F3 "" 0 0 50 H I C CNN
+$FPLIST
+ SolderJumper*
+$ENDFPLIST
+DRAW
+C -100 0 35 0 1 0 N
+A 0 -26 125 375 1422 0 1 0 N 99 50 -98 50
+C 100 0 35 0 1 0 N
+X 1 1 -300 0 165 R 50 50 0 1 P
+X 2 2 300 0 165 L 50 50 0 1 P
+ENDDRAW
+ENDDEF
+#
#End Library
diff --git a/hardware/wemos_mbus_shield/kicad/d1_mini_shield.kicad_prl b/hardware/wemos_mbus_shield/kicad/d1_mini_shield.kicad_prl
new file mode 100644
index 00000000..2528e579
--- /dev/null
+++ b/hardware/wemos_mbus_shield/kicad/d1_mini_shield.kicad_prl
@@ -0,0 +1,75 @@
+{
+ "board": {
+ "active_layer": 0,
+ "active_layer_preset": "",
+ "auto_track_width": true,
+ "hidden_nets": [],
+ "high_contrast_mode": 0,
+ "net_color_mode": 1,
+ "opacity": {
+ "pads": 1.0,
+ "tracks": 1.0,
+ "vias": 1.0,
+ "zones": 0.6
+ },
+ "ratsnest_display_mode": 0,
+ "selection_filter": {
+ "dimensions": true,
+ "footprints": true,
+ "graphics": true,
+ "keepouts": true,
+ "lockedItems": true,
+ "otherItems": true,
+ "pads": true,
+ "text": true,
+ "tracks": true,
+ "vias": true,
+ "zones": true
+ },
+ "visible_items": [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16,
+ 17,
+ 18,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 32,
+ 33,
+ 34,
+ 35,
+ 36
+ ],
+ "visible_layers": "fffffff_ffffffff",
+ "zone_display_mode": 0
+ },
+ "meta": {
+ "filename": "d1_mini_shield.kicad_prl",
+ "version": 3
+ },
+ "project": {
+ "files": []
+ }
+}
diff --git a/hardware/wemos_mbus_shield/kicad/d1_mini_shield.kicad_pro b/hardware/wemos_mbus_shield/kicad/d1_mini_shield.kicad_pro
new file mode 100644
index 00000000..7ff505c9
--- /dev/null
+++ b/hardware/wemos_mbus_shield/kicad/d1_mini_shield.kicad_pro
@@ -0,0 +1,356 @@
+{
+ "board": {
+ "design_settings": {
+ "defaults": {
+ "board_outline_line_width": 0.15,
+ "copper_line_width": 0.2,
+ "copper_text_italic": false,
+ "copper_text_size_h": 1.5,
+ "copper_text_size_v": 1.5,
+ "copper_text_thickness": 0.3,
+ "copper_text_upright": true,
+ "courtyard_line_width": 0.05,
+ "other_line_width": 0.15,
+ "other_text_italic": false,
+ "other_text_size_h": 1.0,
+ "other_text_size_v": 1.0,
+ "other_text_thickness": 0.15,
+ "other_text_upright": true,
+ "silk_line_width": 0.15,
+ "silk_text_italic": false,
+ "silk_text_size_h": 1.0,
+ "silk_text_size_v": 1.0,
+ "silk_text_thickness": 0.15,
+ "silk_text_upright": true
+ },
+ "diff_pair_dimensions": [
+ {
+ "gap": 0.25,
+ "via_gap": 0.25,
+ "width": 0.2
+ }
+ ],
+ "drc_exclusions": [],
+ "rule_severitieslegacy_courtyards_overlap": true,
+ "rule_severitieslegacy_no_courtyard_defined": false,
+ "rules": {
+ "allow_blind_buried_vias": false,
+ "allow_microvias": false,
+ "min_hole_to_hole": 0.25,
+ "min_microvia_diameter": 0.2,
+ "min_microvia_drill": 0.09999999999999999,
+ "min_through_hole_diameter": 0.3,
+ "min_track_width": 0.2,
+ "min_via_diameter": 0.4,
+ "solder_mask_clearance": 0.2,
+ "solder_mask_min_width": 0.0,
+ "solder_paste_clearance": 0.0,
+ "solder_paste_margin_ratio": -0.0
+ },
+ "track_widths": [
+ 0.25,
+ 0.5
+ ],
+ "via_dimensions": [
+ {
+ "diameter": 0.6,
+ "drill": 0.4
+ }
+ ]
+ },
+ "layer_presets": []
+ },
+ "boards": [],
+ "cvpcb": {
+ "equivalence_files": []
+ },
+ "erc": {
+ "erc_exclusions": [],
+ "meta": {
+ "version": 0
+ },
+ "pin_map": [
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 0,
+ 2,
+ 0,
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 2,
+ 2,
+ 2
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 2
+ ],
+ [
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 1,
+ 2,
+ 1,
+ 1,
+ 2
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 2
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 0,
+ 2,
+ 1,
+ 2,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 2,
+ 2,
+ 2
+ ],
+ [
+ 0,
+ 2,
+ 0,
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 0,
+ 2,
+ 1,
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2
+ ]
+ ],
+ "rule_severities": {
+ "bus_definition_conflict": "error",
+ "bus_entry_needed": "error",
+ "bus_label_syntax": "error",
+ "bus_to_bus_conflict": "error",
+ "bus_to_net_conflict": "error",
+ "different_unit_footprint": "error",
+ "different_unit_net": "error",
+ "duplicate_reference": "error",
+ "duplicate_sheet_names": "error",
+ "extra_units": "error",
+ "global_label_dangling": "warning",
+ "hier_label_mismatch": "error",
+ "label_dangling": "error",
+ "lib_symbol_issues": "warning",
+ "multiple_net_names": "warning",
+ "net_not_bus_member": "warning",
+ "no_connect_connected": "warning",
+ "no_connect_dangling": "warning",
+ "pin_not_connected": "error",
+ "pin_not_driven": "error",
+ "pin_to_pin": "warning",
+ "power_pin_not_driven": "error",
+ "similar_labels": "warning",
+ "unannotated": "error",
+ "unit_value_mismatch": "error",
+ "unresolved_variable": "error",
+ "wire_dangling": "error"
+ }
+ },
+ "libraries": {
+ "pinned_footprint_libs": [],
+ "pinned_symbol_libs": []
+ },
+ "meta": {
+ "filename": "d1_mini_shield.kicad_pro",
+ "version": 1
+ },
+ "net_settings": {
+ "classes": [
+ {
+ "bus_width": 12.0,
+ "clearance": 0.2,
+ "diff_pair_gap": 0.25,
+ "diff_pair_via_gap": 0.25,
+ "diff_pair_width": 0.2,
+ "line_style": 0,
+ "microvia_diameter": 0.3,
+ "microvia_drill": 0.1,
+ "name": "Default",
+ "pcb_color": "rgba(0, 0, 0, 0.000)",
+ "schematic_color": "rgba(0, 0, 0, 0.000)",
+ "track_width": 0.25,
+ "via_diameter": 0.8,
+ "via_drill": 0.4,
+ "wire_width": 6.0
+ }
+ ],
+ "meta": {
+ "version": 2
+ },
+ "net_colors": null
+ },
+ "pcbnew": {
+ "last_paths": {
+ "gencad": "",
+ "idf": "",
+ "netlist": "d1_mini_shield.net",
+ "specctra_dsn": "",
+ "step": "",
+ "vrml": ""
+ },
+ "page_layout_descr_file": ""
+ },
+ "schematic": {
+ "annotate_start_num": 0,
+ "drawing": {
+ "default_line_thickness": 6.0,
+ "default_text_size": 50.0,
+ "field_names": [],
+ "intersheets_ref_own_page": false,
+ "intersheets_ref_prefix": "",
+ "intersheets_ref_short": false,
+ "intersheets_ref_show": false,
+ "intersheets_ref_suffix": "",
+ "junction_size_choice": 3,
+ "label_size_ratio": 0.25,
+ "pin_symbol_size": 0.0,
+ "text_offset_ratio": 0.08
+ },
+ "legacy_lib_dir": "",
+ "legacy_lib_list": [],
+ "meta": {
+ "version": 1
+ },
+ "net_format_name": "Pcbnew",
+ "ngspice": {
+ "fix_include_paths": true,
+ "fix_passive_vals": false,
+ "meta": {
+ "version": 0
+ },
+ "model_mode": 0,
+ "workbook_filename": ""
+ },
+ "page_layout_descr_file": "",
+ "plot_directory": "",
+ "spice_adjust_passive_values": false,
+ "spice_external_command": "spice \"%I\"",
+ "subpart_first_id": 65,
+ "subpart_id_separator": 0
+ },
+ "sheets": [],
+ "text_variables": {}
+}
diff --git a/images/dashboard.png b/images/dashboard.png
index 29eb7992..66083b87 100644
Binary files a/images/dashboard.png and b/images/dashboard.png differ
diff --git a/images/dayplot.png b/images/dayplot.png
index 6e3098e2..0e58b925 100644
Binary files a/images/dayplot.png and b/images/dayplot.png differ
diff --git a/images/future-energy-price.png b/images/future-energy-price.png
index 119ed1d6..fa956585 100644
Binary files a/images/future-energy-price.png and b/images/future-energy-price.png differ
diff --git a/images/main-header.png b/images/main-header.png
index 738442a3..80cb3fa9 100644
Binary files a/images/main-header.png and b/images/main-header.png differ
diff --git a/images/monthplot.png b/images/monthplot.png
index 9d6a7f4f..d1d89bca 100644
Binary files a/images/monthplot.png and b/images/monthplot.png differ
diff --git a/images/real-time-calculation.png b/images/real-time-calculation.png
index e5af9129..2b20e3d4 100644
Binary files a/images/real-time-calculation.png and b/images/real-time-calculation.png differ
diff --git a/images/sensor-displays.png b/images/sensor-displays.png
index e06bf053..0d78fd1d 100644
Binary files a/images/sensor-displays.png and b/images/sensor-displays.png differ
diff --git a/images/status-bar.png b/images/status-bar.png
deleted file mode 100644
index 37000f73..00000000
Binary files a/images/status-bar.png and /dev/null differ
diff --git a/images/tempsensors.png b/images/tempsensors.png
index 7484f170..47701be4 100644
Binary files a/images/tempsensors.png and b/images/tempsensors.png differ
diff --git a/src/AmsConfiguration.h b/lib/AmsConfiguration/include/AmsConfiguration.h
similarity index 81%
rename from src/AmsConfiguration.h
rename to lib/AmsConfiguration/include/AmsConfiguration.h
index 1413e45d..531118fe 100644
--- a/src/AmsConfiguration.h
+++ b/lib/AmsConfiguration/include/AmsConfiguration.h
@@ -4,12 +4,14 @@
#include "Arduino.h"
#define EEPROM_SIZE 1024*3
-#define EEPROM_CHECK_SUM 96 // Used to check if config is stored. Change if structure changes
+#define EEPROM_CHECK_SUM 101 // Used to check if config is stored. Change if structure changes
+#define EEPROM_CLEARED_INDICATOR 0xFC
#define EEPROM_CONFIG_ADDRESS 0
#define EEPROM_TEMP_CONFIG_ADDRESS 2048
#define CONFIG_SYSTEM_START 8
#define CONFIG_METER_START 32
+#define CONFIG_UI_START 248
#define CONFIG_GPIO_START 266
#define CONFIG_ENTSOE_START 290
#define CONFIG_WIFI_START 360
@@ -29,7 +31,11 @@
struct SystemConfig {
uint8_t boardType;
-}; // 1
+ bool vendorConfigured;
+ bool userConfigured;
+ uint8_t dataCollectionConsent; // 0 = unknown, 1 = accepted, 2 = declined
+ char country[3];
+}; // 7
struct WiFiConfig91 {
char ssid[32];
@@ -55,7 +61,9 @@ struct WiFiConfig {
bool mdns;
uint8_t power;
uint8_t sleep;
-}; // 211
+ uint8_t mode;
+ bool autoreboot;
+}; // 213
struct MqttConfig86 {
char host[128];
@@ -88,6 +96,23 @@ struct WebConfig {
}; // 129
struct MeterConfig {
+ uint32_t baud;
+ uint8_t parity;
+ bool invert;
+ uint8_t distributionSystem;
+ uint16_t mainFuse;
+ uint16_t productionCapacity;
+ uint8_t encryptionKey[16];
+ uint8_t authenticationKey[16];
+ uint32_t wattageMultiplier;
+ uint32_t voltageMultiplier;
+ uint32_t amperageMultiplier;
+ uint32_t accumulatedMultiplier;
+ uint8_t source;
+ uint8_t parser;
+}; // 52
+
+struct MeterConfig100 {
uint32_t baud;
uint8_t parity;
bool invert;
@@ -165,6 +190,13 @@ struct DomoticzConfig {
}; // 10
struct NtpConfig {
+ bool enable;
+ bool dhcp;
+ char server[64];
+ char timezone[32];
+}; // 98
+
+struct NtpConfig96 {
bool enable;
bool dhcp;
int16_t offset;
@@ -177,6 +209,7 @@ struct EntsoeConfig {
char area[17];
char currency[4];
uint32_t multiplier;
+ bool enabled;
}; // 62
struct EnergyAccountingConfig {
@@ -184,6 +217,20 @@ struct EnergyAccountingConfig {
uint8_t hours;
}; // 11
+struct UiConfig {
+ uint8_t showImport;
+ uint8_t showExport;
+ uint8_t showVoltage;
+ uint8_t showAmperage;
+ uint8_t showReactive;
+ uint8_t showRealtime;
+ uint8_t showPeaks;
+ uint8_t showPricePlot;
+ uint8_t showDayPlot;
+ uint8_t showMonthPlot;
+ uint8_t showTemperaturePlot;
+}; // 11
+
struct TempSensorConfig {
uint8_t address[8];
char name[16];
@@ -260,6 +307,10 @@ public:
bool isEnergyAccountingChanged();
void ackEnergyAccountingChange();
+ bool getUiConfig(UiConfig&);
+ bool setUiConfig(UiConfig&);
+ void clearUiConfig(UiConfig&);
+
void loadTempSensors();
void saveTempSensors();
uint8_t getTempSensorCount();
@@ -280,14 +331,14 @@ private:
uint8_t tempSensorCount = 0;
TempSensorConfig** tempSensors = NULL;
- bool relocateConfig86(); // 1.5.0
- bool relocateConfig87(); // 1.5.4
bool relocateConfig90(); // 2.0.0
bool relocateConfig91(); // 2.0.2
bool relocateConfig92(); // 2.0.3
bool relocateConfig93(); // 2.1.0
- bool relocateConfig94(); // 2.1.4
- bool relocateConfig95(); // 2.1.13
+ bool relocateConfig94(); // 2.1.0
+ bool relocateConfig95(); // 2.1.4
+ bool relocateConfig96(); // 2.1.14
+ bool relocateConfig100(); // 2.2-dev
void saveToFs();
bool loadFromFs(uint8_t version);
diff --git a/src/AmsStorage.h b/lib/AmsConfiguration/include/AmsStorage.h
similarity index 100%
rename from src/AmsStorage.h
rename to lib/AmsConfiguration/include/AmsStorage.h
diff --git a/lib/AmsConfiguration/include/Timezones.h b/lib/AmsConfiguration/include/Timezones.h
new file mode 100644
index 00000000..1e7be4f4
--- /dev/null
+++ b/lib/AmsConfiguration/include/Timezones.h
@@ -0,0 +1,86 @@
+#include