Merge branch 'main' into feature/mqtt_plot_request

This commit is contained in:
Gunnar Skjold 2025-10-01 12:33:26 +02:00
commit 4d6b5884b0
36 changed files with 2502 additions and 53 deletions

41
.github/workflows/localazy.yml vendored Normal file
View File

@ -0,0 +1,41 @@
name: Deploy language files from localazy
on:
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Check out code from repo
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22.x'
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-north-1
- name: Generate localazy-keys.json
run: |
echo '{"writeKey": "", "readKey": "${{secrets.LOCALAZY_READ_KEY}}"}' > localazy/localazy-keys.json
- name: Create localazy language folder
run: mkdir -p localazy/language
- name: Install Localazy CLI
run: npm install -g @localazy/cli
- name: Download translations
working-directory: localazy
run: localazy download -k localazy-keys.json
- name: Upload translations to S3
run: aws s3 sync ./localazy/language/ s3://amscloud-private/language/

2
.gitignore vendored
View File

@ -19,3 +19,5 @@ platformio-user.ini
node_modules
/gui/dist
/scripts/*dev
localazy-keys.json
localazy/language

Binary file not shown.

View File

@ -0,0 +1 @@

File diff suppressed because it is too large Load Diff

682
frames/L&G-E350_Norway.raw Normal file
View File

@ -0,0 +1,682 @@
*** Remote debug - over telnet - for ESP32 - version 3.0.5
* Host name: ams-e603 IP:10.10.10.62 Mac address:D8:3B:DA:C4:03:E6
* Free Heap RAM: 87952
* ESP SDK version: 4.4.5.230722
******************************************************
* Commands:
? or help -> display these help of commands
q -> quit (close this connection)
m -> display memory available
v -> set debug level to verbose
d -> set debug level to debug
i -> set debug level to info
w -> set debug level to warning
e -> set debug level to errors
s -> set debug silence on/off
l -> show debug level
t -> show time (millis)
profiler:
p -> show time between actual and last message (in millis)
p min -> show only if time is this minimal
P time -> set debug level to profiler
c -> show colors
filter:
filter <string> -> show only debugs with this
nofilter -> disable the filter
* Please type the command and press enter to execute.(? or h for this help)
***
(V) HDLC frame:
(V) 7E A1 1E 41 08 83 13 EE EE E6 E7 00 0F 40 00 00
(V) 00 00 01 0D 02 02 09 06 01 01 00 02 81 FF 0A 0B
(V) 45 4D 42 52 49 51 5F 56 31 5F 31 02 02 09 06 00
(V) 00 60 01 00 FF 0A 10 31 33 39 34 33 35 39 37 00
(V) 00 00 00 00 00 00 00 02 02 09 06 00 00 60 01 07
(V) FF 0A 04 5A 46 46 31 02 03 09 06 01 00 01 07 00
(V) FF 06 00 00 24 F4 02 02 0F 00 16 1B 02 03 09 06
(V) 01 00 02 07 00 FF 06 00 00 00 00 02 02 0F 00 16
(V) 1B 02 03 09 06 01 00 03 07 00 FF 06 00 00 00 31
(V) 02 02 0F 00 16 1D 02 03 09 06 01 00 04 07 00 FF
(V) 06 00 00 00 00 02 02 0F 00 16 1D 02 03 09 06 01
(V) 00 1F 07 00 FF 10 0C 6C 02 02 0F FE 16 21 02 03
(V) 09 06 01 00 33 07 00 FF 10 00 00 02 02 0F FE 16
(V) 21 02 03 09 06 01 00 47 07 00 FF 10 0D 68 02 02
(V) 0F FE 16 21 02 03 09 06 01 00 20 07 00 FF 12 09
(V) 2E 02 02 0F FF 16 23 02 03 09 06 01 00 34 07 00
(V) FF 12 00 00 02 02 0F FF 16 23 02 03 09 06 01 00
(V) 48 07 00 FF 12 09 10 02 02 0F FF 16 23 2F AF 7E
(V)
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 0D 02 02 09 06 01
(V) 01 00 02 81 FF 0A 0B 45 4D 42 52 49 51 5F 56 31
(V) 5F 31 02 02 09 06 00 00 60 01 00 FF 0A 10 31 33
(V) 39 34 33 35 39 37 00 00 00 00 00 00 00 00 02 02
(V) 09 06 00 00 60 01 07 FF 0A 04 5A 46 46 31 02 03
(V) 09 06 01 00 01 07 00 FF 06 00 00 24 F4 02 02 0F
(V) 00 16 1B 02 03 09 06 01 00 02 07 00 FF 06 00 00
(V) 00 00 02 02 0F 00 16 1B 02 03 09 06 01 00 03 07
(V) 00 FF 06 00 00 00 31 02 02 0F 00 16 1D 02 03 09
(V) 06 01 00 04 07 00 FF 06 00 00 00 00 02 02 0F 00
(V) 16 1D 02 03 09 06 01 00 1F 07 00 FF 10 0C 6C 02
(V) 02 0F FE 16 21 02 03 09 06 01 00 33 07 00 FF 10
(V) 00 00 02 02 0F FE 16 21 02 03 09 06 01 00 47 07
(V) 00 FF 10 0D 68 02 02 0F FE 16 21 02 03 09 06 01
(V) 00 20 07 00 FF 12 09 2E 02 02 0F FF 16 23 02 03
(V) 09 06 01 00 34 07 00 FF 12 00 00 02 02 0F FF 16
(V) 23 02 03 09 06 01 00 48 07 00 FF 12 09 10 02 02
(V) 0F FF 16 23
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 0D 02 02 09 06 01 01 00 02
(V) 81 FF 0A 0B 45 4D 42 52 49 51 5F 56 31 5F 31 02
(V) 02 09 06 00 00 60 01 00 FF 0A 10 31 33 39 34 33
(V) 35 39 37 00 00 00 00 00 00 00 00 02 02 09 06 00
(V) 00 60 01 07 FF 0A 04 5A 46 46 31 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 F4 02 02 0F 00 16 1B
(V) 02 03 09 06 01 00 02 07 00 FF 06 00 00 00 00 02
(V) 02 0F 00 16 1B 02 03 09 06 01 00 03 07 00 FF 06
(V) 00 00 00 31 02 02 0F 00 16 1D 02 03 09 06 01 00
(V) 04 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1D 02
(V) 03 09 06 01 00 1F 07 00 FF 10 0C 6C 02 02 0F FE
(V) 16 21 02 03 09 06 01 00 33 07 00 FF 10 00 00 02
(V) 02 0F FE 16 21 02 03 09 06 01 00 47 07 00 FF 10
(V) 0D 68 02 02 0F FE 16 21 02 03 09 06 01 00 20 07
(V) 00 FF 12 09 2E 02 02 0F FF 16 23 02 03 09 06 01
(V) 00 34 07 00 FF 12 00 00 02 02 0F FF 16 23 02 03
(V) 09 06 01 00 48 07 00 FF 12 09 10 02 02 0F FF 16
(V) 23
(D) Received valid DLMS at 18 +267
(V) Using application data:
(V) 01 0D 02 02 09 06 01 01 00 02 81 FF 0A 0B 45 4D
(V) 42 52 49 51 5F 56 31 5F 31 02 02 09 06 00 00 60
(V) 01 00 FF 0A 10 31 33 39 34 33 35 39 37 00 00 00
(V) 00 00 00 00 00 02 02 09 06 00 00 60 01 07 FF 0A
(V) 04 5A 46 46 31 02 03 09 06 01 00 01 07 00 FF 06
(V) 00 00 24 F4 02 02 0F 00 16 1B 02 03 09 06 01 00
(V) 02 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1B 02
(V) 03 09 06 01 00 03 07 00 FF 06 00 00 00 31 02 02
(V) 0F 00 16 1D 02 03 09 06 01 00 04 07 00 FF 06 00
(V) 00 00 00 02 02 0F 00 16 1D 02 03 09 06 01 00 1F
(V) 07 00 FF 10 0C 6C 02 02 0F FE 16 21 02 03 09 06
(V) 01 00 33 07 00 FF 10 00 00 02 02 0F FE 16 21 02
(V) 03 09 06 01 00 47 07 00 FF 10 0D 68 02 02 0F FE
(V) 16 21 02 03 09 06 01 00 20 07 00 FF 12 09 2E 02
(V) 02 0F FF 16 23 02 03 09 06 01 00 34 07 00 FF 12
(V) 00 00 02 02 0F FF 16 23 02 03 09 06 01 00 48 07
(V) 00 FF 12 09 10 02 02 0F FF 16 23
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:06 UTC, meter clock: 00:00:00, list type 2, est: 1)
(V) HDLC frame:
(V) 7E A0 2A 41 08 83 13 04 13 E6 E7 00 0F 40 00 00
(V) 00 00 01 01 02 03 09 06 01 00 01 07 00 FF 06 00
(V) 00 24 F4 02 02 0F 00 16 1B A7 7F 7E
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 01 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 F4 02 02 0F 00 16 1B
(V)
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 01 02 03 09 06 01 00 01 07
(V) 00 FF 06 00 00 24 F4 02 02 0F 00 16 1B
(D) Received valid DLMS at 18 +23
(V) Using application data:
(V) 01 01 02 03 09 06 01 00 01 07 00 FF 06 00 00 24
(V) F4 02 02 0F 00 16 1B
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:07 UTC, meter clock: 00:00:00, list type 1, est: 1)
(V) HDLC frame:
(V) 7E A0 2A 41 08 83 13 04 13 E6 E7 00 0F 40 00 00
(V) 00 00 01 01 02 03 09 06 01 00 01 07 00 FF 06 00
(V) 00 24 F4 02 02 0F 00 16 1B A7 7F 7E
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 01 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 F4 02 02 0F 00 16 1B
(V)
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 01 02 03 09 06 01 00 01 07
(V) 00 FF 06 00 00 24 F4 02 02 0F 00 16 1B
(D) Received valid DLMS at 18 +23
(V) Using application data:
(V) 01 01 02 03 09 06 01 00 01 07 00 FF 06 00 00 24
(V) F4 02 02 0F 00 16 1B
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:10 UTC, meter clock: 00:00:00, list type 1, est: 1)
(V) HDLC frame:
(V) 7E A0 2A 41 08 83 13 04 13 E6 E7 00 0F 40 00 00
(V) 00 00 01 01 02 03 09 06 01 00 01 07 00 FF 06 00
(V) 00 24 E0 02 02 0F 00 16 1B 18 A5 7E
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 01 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 E0 02 02 0F 00 16 1B
(V)
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 01 02 03 09 06 01 00 01 07
(V) 00 FF 06 00 00 24 E0 02 02 0F 00 16 1B
(D) Received valid DLMS at 18 +23
(V) Using application data:
(V) 01 01 02 03 09 06 01 00 01 07 00 FF 06 00 00 24
(V) E0 02 02 0F 00 16 1B
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:12 UTC, meter clock: 00:00:00, list type 1, est: 1)
(V) HDLC frame:
(V) 7E A1 1E 41 08 83 13 EE EE E6 E7 00 0F 40 00 00
(V) 00 00 01 0D 02 02 09 06 01 01 00 02 81 FF 0A 0B
(V) 45 4D 42 52 49 51 5F 56 31 5F 31 02 02 09 06 00
(V) 00 60 01 00 FF 0A 10 31 33 39 34 33 35 39 37 00
(V) 00 00 00 00 00 00 00 02 02 09 06 00 00 60 01 07
(V) FF 0A 04 00 00 00 00 02 03 09 06 01 00 01 07 00
(V) FF 06 00 00 24 E0 02 02 0F 00 16 1B 02 03 09 06
(V) 01 00 02 07 00 FF 06 00 00 00 00 02 02 0F 00 16
(V) 1B 02 03 09 06 01 00 03 07 00 FF 06 00 00 00 28
(V) 02 02 0F 00 16 1D 02 03 09 06 01 00 04 07 00 FF
(V) 06 00 00 00 00 02 02 0F 00 16 1D 02 03 09 06 01
(V) 00 1F 07 00 FF 10 0C 68 02 02 0F FE 16 21 02 03
(V) 09 06 01 00 33 07 00 FF 10 00 00 02 02 0F FE 16
(V) 21 02 03 09 06 01 00 47 07 00 FF 10 0D 5D 02 02
(V) 0F FE 16 21 02 03 09 06 01 00 20 07 00 FF 12 09
(V) 2E 02 02 0F FF 16 23 02 03 09 06 01 00 34 07 00
(V) FF 12 00 00 02 02 0F FF 16 23 02 03 09 06 01 00
(V) 48 07 00 FF 12 09 10 02 02 0F FF 16 23 AE 9D 7E
(V)
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 0D 02 02 09 06 01
(V) 01 00 02 81 FF 0A 0B 45 4D 42 52 49 51 5F 56 31
(V) 5F 31 02 02 09 06 00 00 60 01 00 FF 0A 10 31 33
(V) 39 34 33 35 39 37 00 00 00 00 00 00 00 00 02 02
(V) 09 06 00 00 60 01 07 FF 0A 04 00 00 00 00 02 03
(V) 09 06 01 00 01 07 00 FF 06 00 00 24 E0 02 02 0F
(V) 00 16 1B 02 03 09 06 01 00 02 07 00 FF 06 00 00
(V) 00 00 02 02 0F 00 16 1B 02 03 09 06 01 00 03 07
(V) 00 FF 06 00 00 00 28 02 02 0F 00 16 1D 02 03 09
(V) 06 01 00 04 07 00 FF 06 00 00 00 00 02 02 0F 00
(V) 16 1D 02 03 09 06 01 00 1F 07 00 FF 10 0C 68 02
(V) 02 0F FE 16 21 02 03 09 06 01 00 33 07 00 FF 10
(V) 00 00 02 02 0F FE 16 21 02 03 09 06 01 00 47 07
(V) 00 FF 10 0D 5D 02 02 0F FE 16 21 02 03 09 06 01
(V) 00 20 07 00 FF 12 09 2E 02 02 0F FF 16 23 02 03
(V) 09 06 01 00 34 07 00 FF 12 00 00 02 02 0F FF 16
(V) 23 02 03 09 06 01 00 48 07 00 FF 12 09 10 02 02
(V) 0F FF 16 23
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 0D 02 02 09 06 01 01 00 02
(V) 81 FF 0A 0B 45 4D 42 52 49 51 5F 56 31 5F 31 02
(V) 02 09 06 00 00 60 01 00 FF 0A 10 31 33 39 34 33
(V) 35 39 37 00 00 00 00 00 00 00 00 02 02 09 06 00
(V) 00 60 01 07 FF 0A 04 00 00 00 00 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 E0 02 02 0F 00 16 1B
(V) 02 03 09 06 01 00 02 07 00 FF 06 00 00 00 00 02
(V) 02 0F 00 16 1B 02 03 09 06 01 00 03 07 00 FF 06
(V) 00 00 00 28 02 02 0F 00 16 1D 02 03 09 06 01 00
(V) 04 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1D 02
(V) 03 09 06 01 00 1F 07 00 FF 10 0C 68 02 02 0F FE
(V) 16 21 02 03 09 06 01 00 33 07 00 FF 10 00 00 02
(V) 02 0F FE 16 21 02 03 09 06 01 00 47 07 00 FF 10
(V) 0D 5D 02 02 0F FE 16 21 02 03 09 06 01 00 20 07
(V) 00 FF 12 09 2E 02 02 0F FF 16 23 02 03 09 06 01
(V) 00 34 07 00 FF 12 00 00 02 02 0F FF 16 23 02 03
(V) 09 06 01 00 48 07 00 FF 12 09 10 02 02 0F FF 16
(V) 23
(D) Received valid DLMS at 18 +267
(V) Using application data:
(V) 01 0D 02 02 09 06 01 01 00 02 81 FF 0A 0B 45 4D
(V) 42 52 49 51 5F 56 31 5F 31 02 02 09 06 00 00 60
(V) 01 00 FF 0A 10 31 33 39 34 33 35 39 37 00 00 00
(V) 00 00 00 00 00 02 02 09 06 00 00 60 01 07 FF 0A
(V) 04 00 00 00 00 02 03 09 06 01 00 01 07 00 FF 06
(V) 00 00 24 E0 02 02 0F 00 16 1B 02 03 09 06 01 00
(V) 02 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1B 02
(V) 03 09 06 01 00 03 07 00 FF 06 00 00 00 28 02 02
(V) 0F 00 16 1D 02 03 09 06 01 00 04 07 00 FF 06 00
(V) 00 00 00 02 02 0F 00 16 1D 02 03 09 06 01 00 1F
(V) 07 00 FF 10 0C 68 02 02 0F FE 16 21 02 03 09 06
(V) 01 00 33 07 00 FF 10 00 00 02 02 0F FE 16 21 02
(V) 03 09 06 01 00 47 07 00 FF 10 0D 5D 02 02 0F FE
(V) 16 21 02 03 09 06 01 00 20 07 00 FF 12 09 2E 02
(V) 02 0F FF 16 23 02 03 09 06 01 00 34 07 00 FF 12
(V) 00 00 02 02 0F FF 16 23 02 03 09 06 01 00 48 07
(V) 00 FF 12 09 10 02 02 0F FF 16 23
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:16 UTC, meter clock: 00:00:00, list type 2, est: 1)
(V) HDLC frame:
(V) 7E A0 2A 41 08 83 13 04 13 E6 E7 00 0F 40 00 00
(V) 00 00 01 01 02 03 09 06 01 00 01 07 00 FF 06 00
(V) 00 24 E0 02 02 0F 00 16 1B 18 A5 7E
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 01 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 E0 02 02 0F 00 16 1B
(V)
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 01 02 03 09 06 01 00 01 07
(V) 00 FF 06 00 00 24 E0 02 02 0F 00 16 1B
(D) Received valid DLMS at 18 +23
(V) Using application data:
(V) 01 01 02 03 09 06 01 00 01 07 00 FF 06 00 00 24
(V) E0 02 02 0F 00 16 1B
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:17 UTC, meter clock: 00:00:00, list type 1, est: 1)
(V) HDLC frame:
(V) 7E A0 2A 41 08 83 13 04 13 E6 E7 00 0F 40 00 00
(V) 00 00 01 01 02 03 09 06 01 00 01 07 00 FF 06 00
(V) 00 24 A4 02 02 0F 00 16 1B 68 0D 7E
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 01 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 A4 02 02 0F 00 16 1B
(V)
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 01 02 03 09 06 01 00 01 07
(V) 00 FF 06 00 00 24 A4 02 02 0F 00 16 1B
(D) Received valid DLMS at 18 +23
(V) Using application data:
(V) 01 01 02 03 09 06 01 00 01 07 00 FF 06 00 00 24
(V) A4 02 02 0F 00 16 1B
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:20 UTC, meter clock: 00:00:00, list type 1, est: 1)
(V) HDLC frame:
(V) 7E A0 2A 41 08 83 13 04 13 E6 E7 00 0F 40 00 00
(V) 00 00 01 01 02 03 09 06 01 00 01 07 00 FF 06 00
(V) 00 24 A4 02 02 0F 00 16 1B 68 0D 7E
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 01 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 A4 02 02 0F 00 16 1B
(V)
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 01 02 03 09 06 01 00 01 07
(V) 00 FF 06 00 00 24 A4 02 02 0F 00 16 1B
(D) Received valid DLMS at 18 +23
(V) Using application data:
(V) 01 01 02 03 09 06 01 00 01 07 00 FF 06 00 00 24
(V) A4 02 02 0F 00 16 1B
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:22 UTC, meter clock: 00:00:00, list type 1, est: 1)
(V) HDLC frame:
(V) 7E A1 1E 41 08 83 13 EE EE E6 E7 00 0F 40 00 00
(V) 00 00 01 0D 02 02 09 06 01 01 00 02 81 FF 0A 0B
(V) 45 4D 42 52 49 51 5F 56 31 5F 31 02 02 09 06 00
(V) 00 60 01 00 FF 0A 10 31 33 39 34 33 35 39 37 00
(V) 00 00 00 00 00 00 00 02 02 09 06 00 00 60 01 07
(V) FF 0A 04 5A 46 46 31 02 03 09 06 01 00 01 07 00
(V) FF 06 00 00 24 A4 02 02 0F 00 16 1B 02 03 09 06
(V) 01 00 02 07 00 FF 06 00 00 00 00 02 02 0F 00 16
(V) 1B 02 03 09 06 01 00 03 07 00 FF 06 00 00 00 31
(V) 02 02 0F 00 16 1D 02 03 09 06 01 00 04 07 00 FF
(V) 06 00 00 00 00 02 02 0F 00 16 1D 02 03 09 06 01
(V) 00 1F 07 00 FF 10 0C 6E 02 02 0F FE 16 21 02 03
(V) 09 06 01 00 33 07 00 FF 10 00 00 02 02 0F FE 16
(V) 21 02 03 09 06 01 00 47 07 00 FF 10 0D 5C 02 02
(V) 0F FE 16 21 02 03 09 06 01 00 20 07 00 FF 12 09
(V) 38 02 02 0F FF 16 23 02 03 09 06 01 00 34 07 00
(V) FF 12 00 00 02 02 0F FF 16 23 02 03 09 06 01 00
(V) 48 07 00 FF 12 09 10 02 02 0F FF 16 23 4A DF 7E
(V)
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 0D 02 02 09 06 01
(V) 01 00 02 81 FF 0A 0B 45 4D 42 52 49 51 5F 56 31
(V) 5F 31 02 02 09 06 00 00 60 01 00 FF 0A 10 31 33
(V) 39 34 33 35 39 37 00 00 00 00 00 00 00 00 02 02
(V) 09 06 00 00 60 01 07 FF 0A 04 5A 46 46 31 02 03
(V) 09 06 01 00 01 07 00 FF 06 00 00 24 A4 02 02 0F
(V) 00 16 1B 02 03 09 06 01 00 02 07 00 FF 06 00 00
(V) 00 00 02 02 0F 00 16 1B 02 03 09 06 01 00 03 07
(V) 00 FF 06 00 00 00 31 02 02 0F 00 16 1D 02 03 09
(V) 06 01 00 04 07 00 FF 06 00 00 00 00 02 02 0F 00
(V) 16 1D 02 03 09 06 01 00 1F 07 00 FF 10 0C 6E 02
(V) 02 0F FE 16 21 02 03 09 06 01 00 33 07 00 FF 10
(V) 00 00 02 02 0F FE 16 21 02 03 09 06 01 00 47 07
(V) 00 FF 10 0D 5C 02 02 0F FE 16 21 02 03 09 06 01
(V) 00 20 07 00 FF 12 09 38 02 02 0F FF 16 23 02 03
(V) 09 06 01 00 34 07 00 FF 12 00 00 02 02 0F FF 16
(V) 23 02 03 09 06 01 00 48 07 00 FF 12 09 10 02 02
(V) 0F FF 16 23
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 0D 02 02 09 06 01 01 00 02
(V) 81 FF 0A 0B 45 4D 42 52 49 51 5F 56 31 5F 31 02
(V) 02 09 06 00 00 60 01 00 FF 0A 10 31 33 39 34 33
(V) 35 39 37 00 00 00 00 00 00 00 00 02 02 09 06 00
(V) 00 60 01 07 FF 0A 04 5A 46 46 31 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 A4 02 02 0F 00 16 1B
(V) 02 03 09 06 01 00 02 07 00 FF 06 00 00 00 00 02
(V) 02 0F 00 16 1B 02 03 09 06 01 00 03 07 00 FF 06
(V) 00 00 00 31 02 02 0F 00 16 1D 02 03 09 06 01 00
(V) 04 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1D 02
(V) 03 09 06 01 00 1F 07 00 FF 10 0C 6E 02 02 0F FE
(V) 16 21 02 03 09 06 01 00 33 07 00 FF 10 00 00 02
(V) 02 0F FE 16 21 02 03 09 06 01 00 47 07 00 FF 10
(V) 0D 5C 02 02 0F FE 16 21 02 03 09 06 01 00 20 07
(V) 00 FF 12 09 38 02 02 0F FF 16 23 02 03 09 06 01
(V) 00 34 07 00 FF 12 00 00 02 02 0F FF 16 23 02 03
(V) 09 06 01 00 48 07 00 FF 12 09 10 02 02 0F FF 16
(V) 23
(D) Received valid DLMS at 18 +267
(V) Using application data:
(V) 01 0D 02 02 09 06 01 01 00 02 81 FF 0A 0B 45 4D
(V) 42 52 49 51 5F 56 31 5F 31 02 02 09 06 00 00 60
(V) 01 00 FF 0A 10 31 33 39 34 33 35 39 37 00 00 00
(V) 00 00 00 00 00 02 02 09 06 00 00 60 01 07 FF 0A
(V) 04 5A 46 46 31 02 03 09 06 01 00 01 07 00 FF 06
(V) 00 00 24 A4 02 02 0F 00 16 1B 02 03 09 06 01 00
(V) 02 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1B 02
(V) 03 09 06 01 00 03 07 00 FF 06 00 00 00 31 02 02
(V) 0F 00 16 1D 02 03 09 06 01 00 04 07 00 FF 06 00
(V) 00 00 00 02 02 0F 00 16 1D 02 03 09 06 01 00 1F
(V) 07 00 FF 10 0C 6E 02 02 0F FE 16 21 02 03 09 06
(V) 01 00 33 07 00 FF 10 00 00 02 02 0F FE 16 21 02
(V) 03 09 06 01 00 47 07 00 FF 10 0D 5C 02 02 0F FE
(V) 16 21 02 03 09 06 01 00 20 07 00 FF 12 09 38 02
(V) 02 0F FF 16 23 02 03 09 06 01 00 34 07 00 FF 12
(V) 00 00 02 02 0F FF 16 23 02 03 09 06 01 00 48 07
(V) 00 FF 12 09 10 02 02 0F FF 16 23
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:26 UTC, meter clock: 00:00:00, list type 2, est: 1)
(V) HDLC frame:
(V) 7E A0 2A 41 08 83 13 04 13 E6 E7 00 0F 40 00 00
(V) 00 00 01 01 02 03 09 06 01 00 01 07 00 FF 06 00
(V) 00 24 B8 02 02 0F 00 16 1B 3B 09 7E
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 01 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 B8 02 02 0F 00 16 1B
(V)
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 01 02 03 09 06 01 00 01 07
(V) 00 FF 06 00 00 24 B8 02 02 0F 00 16 1B
(D) Received valid DLMS at 18 +23
(V) Using application data:
(V) 01 01 02 03 09 06 01 00 01 07 00 FF 06 00 00 24
(V) B8 02 02 0F 00 16 1B
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:27 UTC, meter clock: 00:00:00, list type 1, est: 1)
(V) HDLC frame:
(V) 7E A0 2A 41 08 83 13 04 13 E6 E7 00 0F 40 00 00
(V) 00 00 01 01 02 03 09 06 01 00 01 07 00 FF 06 00
(V) 00 24 B8 02 02 0F 00 16 1B 3B 09 7E
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 01 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 B8 02 02 0F 00 16 1B
(V)
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 01 02 03 09 06 01 00 01 07
(V) 00 FF 06 00 00 24 B8 02 02 0F 00 16 1B
(D) Received valid DLMS at 18 +23
(V) Using application data:
(V) 01 01 02 03 09 06 01 00 01 07 00 FF 06 00 00 24
(V) B8 02 02 0F 00 16 1B
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:29 UTC, meter clock: 00:00:00, list type 1, est: 1)
(V) HDLC frame:
(V) 7E A0 2A 41 08 83 13 04 13 E6 E7 00 0F 40 00 00
(V) 00 00 01 01 02 03 09 06 01 00 01 07 00 FF 06 00
(V) 00 24 B8 02 02 0F 00 16 1B 3B 09 7E
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 01 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 B8 02 02 0F 00 16 1B
(V)
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 01 02 03 09 06 01 00 01 07
(V) 00 FF 06 00 00 24 B8 02 02 0F 00 16 1B
(D) Received valid DLMS at 18 +23
(V) Using application data:
(V) 01 01 02 03 09 06 01 00 01 07 00 FF 06 00 00 24
(V) B8 02 02 0F 00 16 1B
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:32 UTC, meter clock: 00:00:00, list type 1, est: 1)
q(V) HDLC frame:
(V) 7E A1 1E 41 08 83 13 EE EE E6 E7 00 0F 40 00 00
(V) 00 00 01 0D 02 02 09 06 01 01 00 02 81 FF 0A 0B
(V) 45 4D 42 52 49 51 5F 56 31 5F 31 02 02 09 06 00
(V) 00 60 01 00 FF 0A 10 31 33 39 34 33 35 39 37 00
(V) 00 00 00 00 00 00 00 02 02 09 06 00 00 60 01 07
(V) FF 0A 04 5A 46 46 31 02 03 09 06 01 00 01 07 00
(V) FF 06 00 00 24 A4 02 02 0F 00 16 1B 02 03 09 06
(V) 01 00 02 07 00 FF 06 00 00 00 00 02 02 0F 00 16
(V) 1B 02 03 09 06 01 00 03 07 00 FF 06 00 00 00 46
(V) 02 02 0F 00 16 1D 02 03 09 06 01 00 04 07 00 FF
(V) 06 00 00 00 00 02 02 0F 00 16 1D 02 03 09 06 01
(V) 00 1F 07 00 FF 10 0C 67 02 02 0F FE 16 21 02 03
(V) 09 06 01 00 33 07 00 FF 10 00 00 02 02 0F FE 16
(V) 21 02 03 09 06 01 00 47 07 00 FF 10 0D 5D 02 02
(V) 0F FE 16 21 02 03 09 06 01 00 20 07 00 FF 12 09
(V) 2E 02 02 0F FF 16 23 02 03 09 06 01 00 34 07 00
(V) FF 12 00 00 02 02 0F FF 16 23 02 03 09 06 01 00
(V) 48 07 00 FF 12 09 06 02 02 0F FF 16 23 3A 49 7E
(V)
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 0D 02 02 09 06 01
(V) 01 00 02 81 FF 0A 0B 45 4D 42 52 49 51 5F 56 31
(V) 5F 31 02 02 09 06 00 00 60 01 00 FF 0A 10 31 33
(V) 39 34 33 35 39 37 00 00 00 00 00 00 00 00 02 02
(V) 09 06 00 00 60 01 07 FF 0A 04 5A 46 46 31 02 03
(V) 09 06 01 00 01 07 00 FF 06 00 00 24 A4 02 02 0F
(V) 00 16 1B 02 03 09 06 01 00 02 07 00 FF 06 00 00
(V) 00 00 02 02 0F 00 16 1B 02 03 09 06 01 00 03 07
(V) 00 FF 06 00 00 00 46 02 02 0F 00 16 1D 02 03 09
(V) 06 01 00 04 07 00 FF 06 00 00 00 00 02 02 0F 00
(V) 16 1D 02 03 09 06 01 00 1F 07 00 FF 10 0C 67 02
(V) 02 0F FE 16 21 02 03 09 06 01 00 33 07 00 FF 10
(V) 00 00 02 02 0F FE 16 21 02 03 09 06 01 00 47 07
(V) 00 FF 10 0D 5D 02 02 0F FE 16 21 02 03 09 06 01
(V) 00 20 07 00 FF 12 09 2E 02 02 0F FF 16 23 02 03
(V) 09 06 01 00 34 07 00 FF 12 00 00 02 02 0F FF 16
(V) 23 02 03 09 06 01 00 48 07 00 FF 12 09 06 02 02
(V) 0F FF 16 23
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 0D 02 02 09 06 01 01 00 02
(V) 81 FF 0A 0B 45 4D 42 52 49 51 5F 56 31 5F 31 02
(V) 02 09 06 00 00 60 01 00 FF 0A 10 31 33 39 34 33
(V) 35 39 37 00 00 00 00 00 00 00 00 02 02 09 06 00
(V) 00 60 01 07 FF 0A 04 5A 46 46 31 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 A4 02 02 0F 00 16 1B
(V) 02 03 09 06 01 00 02 07 00 FF 06 00 00 00 00 02
(V) 02 0F 00 16 1B 02 03 09 06 01 00 03 07 00 FF 06
(V) 00 00 00 46 02 02 0F 00 16 1D 02 03 09 06 01 00
(V) 04 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1D 02
(V) 03 09 06 01 00 1F 07 00 FF 10 0C 67 02 02 0F FE
(V) 16 21 02 03 09 06 01 00 33 07 00 FF 10 00 00 02
(V) 02 0F FE 16 21 02 03 09 06 01 00 47 07 00 FF 10
(V) 0D 5D 02 02 0F FE 16 21 02 03 09 06 01 00 20 07
(V) 00 FF 12 09 2E 02 02 0F FF 16 23 02 03 09 06 01
(V) 00 34 07 00 FF 12 00 00 02 02 0F FF 16 23 02 03
(V) 09 06 01 00 48 07 00 FF 12 09 06 02 02 0F FF 16
(V) 23
(D) Received valid DLMS at 18 +267
(V) Using application data:
(V) 01 0D 02 02 09 06 01 01 00 02 81 FF 0A 0B 45 4D
(V) 42 52 49 51 5F 56 31 5F 31 02 02 09 06 00 00 60
(V) 01 00 FF 0A 10 31 33 39 34 33 35 39 37 00 00 00
(V) 00 00 00 00 00 02 02 09 06 00 00 60 01 07 FF 0A
(V) 04 5A 46 46 31 02 03 09 06 01 00 01 07 00 FF 06
(V) 00 00 24 A4 02 02 0F 00 16 1B 02 03 09 06 01 00
(V) 02 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1B 02
(V) 03 09 06 01 00 03 07 00 FF 06 00 00 00 46 02 02
(V) 0F 00 16 1D 02 03 09 06 01 00 04 07 00 FF 06 00
(V) 00 00 00 02 02 0F 00 16 1D 02 03 09 06 01 00 1F
(V) 07 00 FF 10 0C 67 02 02 0F FE 16 21 02 03 09 06
(V) 01 00 33 07 00 FF 10 00 00 02 02 0F FE 16 21 02
(V) 03 09 06 01 00 47 07 00 FF 10 0D 5D 02 02 0F FE
(V) 16 21 02 03 09 06 01 00 20 07 00 FF 12 09 2E 02
(V) 02 0F FF 16 23 02 03 09 06 01 00 34 07 00 FF 12
(V) 00 00 02 02 0F FF 16 23 02 03 09 06 01 00 48 07
(V) 00 FF 12 09 06 02 02 0F FF 16 23
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:36 UTC, meter clock: 00:00:00, list type 2, est: 1)
(V) HDLC frame:
(V) 7E A0 2A 41 08 83 13 04 13 E6 E7 00 0F 40 00 00
(V) 00 00 01 01 02 03 09 06 01 00 01 07 00 FF 06 00
(V) 00 24 A4 02 02 0F 00 16 1B 68 0D 7E
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 01 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 A4 02 02 0F 00 16 1B
(V)
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 01 02 03 09 06 01 00 01 07
(V) 00 FF 06 00 00 24 A4 02 02 0F 00 16 1B
(D) Received valid DLMS at 18 +23
(V) Using application data:
(V) 01 01 02 03 09 06 01 00 01 07 00 FF 06 00 00 24
(V) A4 02 02 0F 00 16 1B
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:37 UTC, meter clock: 00:00:00, list type 1, est: 1)
(V) HDLC frame:
(V) 7E A0 2A 41 08 83 13 04 13 E6 E7 00 0F 40 00 00
(V) 00 00 01 01 02 03 09 06 01 00 01 07 00 FF 06 00
(V) 00 24 A4 02 02 0F 00 16 1B 68 0D 7E
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 01 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 A4 02 02 0F 00 16 1B
(V)
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 01 02 03 09 06 01 00 01 07
(V) 00 FF 06 00 00 24 A4 02 02 0F 00 16 1B
(D) Received valid DLMS at 18 +23
(V) Using application data:
(V) 01 01 02 03 09 06 01 00 01 07 00 FF 06 00 00 24
(V) A4 02 02 0F 00 16 1B
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:39 UTC, meter clock: 00:00:00, list type 1, est: 1)
(V) HDLC frame:
(V) 7E A0 2A 41 08 83 13 04 13 E6 E7 00 0F 40 00 00
(V) 00 00 01 01 02 03 09 06 01 00 01 07 00 FF 06 00
(V) 00 24 D5 02 02 0F 00 16 1B F1 83 7E
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 01 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 D5 02 02 0F 00 16 1B
(V)
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 01 02 03 09 06 01 00 01 07
(V) 00 FF 06 00 00 24 D5 02 02 0F 00 16 1B
(D) Received valid DLMS at 18 +23
(V) Using application data:
(V) 01 01 02 03 09 06 01 00 01 07 00 FF 06 00 00 24
(V) D5 02 02 0F 00 16 1B
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:42 UTC, meter clock: 00:00:00, list type 1, est: 1)
(V) HDLC frame:
(V) 7E A1 1E 41 08 83 13 EE EE E6 E7 00 0F 40 00 00
(V) 00 00 01 0D 02 02 09 06 01 01 00 02 81 FF 0A 0B
(V) 45 4D 42 52 49 51 5F 56 31 5F 31 02 02 09 06 00
(V) 00 60 01 00 FF 0A 10 31 33 39 34 33 35 39 37 00
(V) 00 00 00 00 00 00 00 02 02 09 06 00 00 60 01 07
(V) FF 0A 04 5A 46 46 31 02 03 09 06 01 00 01 07 00
(V) FF 06 00 00 24 D5 02 02 0F 00 16 1B 02 03 09 06
(V) 01 00 02 07 00 FF 06 00 00 00 00 02 02 0F 00 16
(V) 1B 02 03 09 06 01 00 03 07 00 FF 06 00 00 00 3C
(V) 02 02 0F 00 16 1D 02 03 09 06 01 00 04 07 00 FF
(V) 06 00 00 00 00 02 02 0F 00 16 1D 02 03 09 06 01
(V) 00 1F 07 00 FF 10 0C 77 02 02 0F FE 16 21 02 03
(V) 09 06 01 00 33 07 00 FF 10 00 00 02 02 0F FE 16
(V) 21 02 03 09 06 01 00 47 07 00 FF 10 0D 5F 02 02
(V) 0F FE 16 21 02 03 09 06 01 00 20 07 00 FF 12 09
(V) 2E 02 02 0F FF 16 23 02 03 09 06 01 00 34 07 00
(V) FF 12 00 00 02 02 0F FF 16 23 02 03 09 06 01 00
(V) 48 07 00 FF 12 09 06 02 02 0F FF 16 23 4A 9D 7E
(V)
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 0D 02 02 09 06 01
(V) 01 00 02 81 FF 0A 0B 45 4D 42 52 49 51 5F 56 31
(V) 5F 31 02 02 09 06 00 00 60 01 00 FF 0A 10 31 33
(V) 39 34 33 35 39 37 00 00 00 00 00 00 00 00 02 02
(V) 09 06 00 00 60 01 07 FF 0A 04 5A 46 46 31 02 03
(V) 09 06 01 00 01 07 00 FF 06 00 00 24 D5 02 02 0F
(V) 00 16 1B 02 03 09 06 01 00 02 07 00 FF 06 00 00
(V) 00 00 02 02 0F 00 16 1B 02 03 09 06 01 00 03 07
(V) 00 FF 06 00 00 00 3C 02 02 0F 00 16 1D 02 03 09
(V) 06 01 00 04 07 00 FF 06 00 00 00 00 02 02 0F 00
(V) 16 1D 02 03 09 06 01 00 1F 07 00 FF 10 0C 77 02
(V) 02 0F FE 16 21 02 03 09 06 01 00 33 07 00 FF 10
(V) 00 00 02 02 0F FE 16 21 02 03 09 06 01 00 47 07
(V) 00 FF 10 0D 5F 02 02 0F FE 16 21 02 03 09 06 01
(V) 00 20 07 00 FF 12 09 2E 02 02 0F FF 16 23 02 03
(V) 09 06 01 00 34 07 00 FF 12 00 00 02 02 0F FF 16
(V) 23 02 03 09 06 01 00 48 07 00 FF 12 09 06 02 02
(V) 0F FF 16 23
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 0D 02 02 09 06 01 01 00 02
(V) 81 FF 0A 0B 45 4D 42 52 49 51 5F 56 31 5F 31 02
(V) 02 09 06 00 00 60 01 00 FF 0A 10 31 33 39 34 33
(V) 35 39 37 00 00 00 00 00 00 00 00 02 02 09 06 00
(V) 00 60 01 07 FF 0A 04 5A 46 46 31 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 D5 02 02 0F 00 16 1B
(V) 02 03 09 06 01 00 02 07 00 FF 06 00 00 00 00 02
(V) 02 0F 00 16 1B 02 03 09 06 01 00 03 07 00 FF 06
(V) 00 00 00 3C 02 02 0F 00 16 1D 02 03 09 06 01 00
(V) 04 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1D 02
(V) 03 09 06 01 00 1F 07 00 FF 10 0C 77 02 02 0F FE
(V) 16 21 02 03 09 06 01 00 33 07 00 FF 10 00 00 02
(V) 02 0F FE 16 21 02 03 09 06 01 00 47 07 00 FF 10
(V) 0D 5F 02 02 0F FE 16 21 02 03 09 06 01 00 20 07
(V) 00 FF 12 09 2E 02 02 0F FF 16 23 02 03 09 06 01
(V) 00 34 07 00 FF 12 00 00 02 02 0F FF 16 23 02 03
(V) 09 06 01 00 48 07 00 FF 12 09 06 02 02 0F FF 16
(V) 23
(D) Received valid DLMS at 18 +267
(V) Using application data:
(V) 01 0D 02 02 09 06 01 01 00 02 81 FF 0A 0B 45 4D
(V) 42 52 49 51 5F 56 31 5F 31 02 02 09 06 00 00 60
(V) 01 00 FF 0A 10 31 33 39 34 33 35 39 37 00 00 00
(V) 00 00 00 00 00 02 02 09 06 00 00 60 01 07 FF 0A
(V) 04 5A 46 46 31 02 03 09 06 01 00 01 07 00 FF 06
(V) 00 00 24 D5 02 02 0F 00 16 1B 02 03 09 06 01 00
(V) 02 07 00 FF 06 00 00 00 00 02 02 0F 00 16 1B 02
(V) 03 09 06 01 00 03 07 00 FF 06 00 00 00 3C 02 02
(V) 0F 00 16 1D 02 03 09 06 01 00 04 07 00 FF 06 00
(V) 00 00 00 02 02 0F 00 16 1D 02 03 09 06 01 00 1F
(V) 07 00 FF 10 0C 77 02 02 0F FE 16 21 02 03 09 06
(V) 01 00 33 07 00 FF 10 00 00 02 02 0F FE 16 21 02
(V) 03 09 06 01 00 47 07 00 FF 10 0D 5F 02 02 0F FE
(V) 16 21 02 03 09 06 01 00 20 07 00 FF 12 09 2E 02
(V) 02 0F FF 16 23 02 03 09 06 01 00 34 07 00 FF 12
(V) 00 00 02 02 0F FF 16 23 02 03 09 06 01 00 48 07
(V) 00 FF 12 09 06 02 02 0F FF 16 23
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:46 UTC, meter clock: 00:00:00, list type 2, est: 1)
qq(V) HDLC frame:
(V) 7E A0 2A 41 08 83 13 04 13 E6 E7 00 0F 40 00 00
(V) 00 00 01 01 02 03 09 06 01 00 01 07 00 FF 06 00
(V) 00 24 D5 02 02 0F 00 16 1B F1 83 7E
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 01 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 D5 02 02 0F 00 16 1B
(V)
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 01 02 03 09 06 01 00 01 07
(V) 00 FF 06 00 00 24 D5 02 02 0F 00 16 1B
(D) Received valid DLMS at 18 +23
(V) Using application data:
(V) 01 01 02 03 09 06 01 00 01 07 00 FF 06 00 00 24
(V) D5 02 02 0F 00 16 1B
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:47 UTC, meter clock: 00:00:00, list type 1, est: 1)
q
* Debug: Command received: qqqqq
(V) HDLC frame:
(V) 7E A0 2A 41 08 83 13 04 13 E6 E7 00 0F 40 00 00
(V) 00 00 01 01 02 03 09 06 01 00 01 07 00 FF 06 00
(V) 00 24 B8 02 02 0F 00 16 1B 3B 09 7E
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 01 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 B8 02 02 0F 00 16 1B
(V)
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 01 02 03 09 06 01 00 01 07
(V) 00 FF 06 00 00 24 B8 02 02 0F 00 16 1B
(D) Received valid DLMS at 18 +23
(V) Using application data:
(V) 01 01 02 03 09 06 01 00 01 07 00 FF 06 00 00 24
(V) B8 02 02 0F 00 16 1B
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:49 UTC, meter clock: 00:00:00, list type 1, est: 1)
(V) HDLC frame:
(V) 7E A0 2A 41 08 83 13 04 13 E6 E7 00 0F 40 00 00
(V) 00 00 01 01 02 03 09 06 01 00 01 07 00 FF 06 00
(V) 00 24 B8 02 02 0F 00 16 1B 3B 09 7E
(V) LLC frame:
(V) E6 E7 00 0F 40 00 00 00 00 01 01 02 03 09 06 01
(V) 00 01 07 00 FF 06 00 00 24 B8 02 02 0F 00 16 1B
(V)
(V) DLMS frame:
(V) 0F 40 00 00 00 00 01 01 02 03 09 06 01 00 01 07
(V) 00 FF 06 00 00 24 B8 02 02 0F 00 16 1B
(D) Received valid DLMS at 18 +23
(V) Using application data:
(V) 01 01 02 03 09 06 01 00 01 07 00 FF 06 00 00 24
(V) B8 02 02 0F 00 16 1B
(V) DLMS
(D) NOT Ready to update (internal clock 12:32:51 UTC, meter clock: 00:00:00, list type 1, est: 1)
q
* Debug: Command received: q
* Closing client connection ...

View File

@ -13,7 +13,6 @@
#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
#define EEPROM_TEMP_CONFIG_ADDRESS 2048
#define CONFIG_SYSTEM_START 8
#define CONFIG_NETWORK_START 40
@ -30,6 +29,7 @@
#define CONFIG_UI_START 1720
#define CONFIG_CLOUD_START 1742
#define CONFIG_UPGRADE_INFO_START 1934
#define CONFIG_ZC_START 2000
#define CONFIG_METER_START_103 32
#define CONFIG_UPGRADE_INFO_START_103 216
@ -254,6 +254,12 @@ struct CloudConfig {
uint8_t proto;
}; // 88
struct ZmartChargeConfig {
bool enabled;
char token[21];
char baseUrl[64];
}; // 86
class AmsConfiguration {
public:
bool hasConfig();
@ -347,6 +353,13 @@ public:
void clearCloudConfig(CloudConfig&);
bool isCloudChanged();
void ackCloudConfig();
bool getZmartChargeConfig(ZmartChargeConfig&);
bool setZmartChargeConfig(ZmartChargeConfig&);
void clearZmartChargeConfig(ZmartChargeConfig&);
bool isZmartChargeConfigChanged();
void ackZmartChargeConfig();
void clear();
@ -355,7 +368,7 @@ protected:
private:
uint8_t configVersion = 0;
bool sysChanged = false, networkChanged = false, mqttChanged = false, webChanged = false, meterChanged = true, ntpChanged = true, priceChanged = false, energyAccountingChanged = true, cloudChanged = true, uiLanguageChanged = false;
bool sysChanged = false, networkChanged = false, mqttChanged = false, webChanged = false, meterChanged = true, ntpChanged = true, priceChanged = false, energyAccountingChanged = true, cloudChanged = true, uiLanguageChanged = false, zcChanged = true;
bool relocateConfig103(); // 2.2.12, until, but not including 2.3

View File

@ -13,7 +13,7 @@
String toHex(uint8_t* in);
String toHex(uint8_t* in, uint16_t size);
void fromHex(uint8_t *out, String in, uint16_t size);
bool stripNonAscii(uint8_t* in, uint16_t size, bool extended = false);
bool stripNonAscii(uint8_t* in, uint16_t size, bool extended = false, bool trim = true);
void debugPrint(uint8_t *buffer, uint16_t start, uint16_t length, Print* debugger);
#endif

View File

@ -13,13 +13,17 @@
bool AmsConfiguration::getSystemConfig(SystemConfig& config) {
EEPROM.begin(EEPROM_SIZE);
uint8_t configVersion = EEPROM.read(EEPROM_CONFIG_ADDRESS);
if(configVersion == EEPROM_CHECK_SUM || configVersion == EEPROM_CLEARED_INDICATOR) {
if(configVersion == EEPROM_CHECK_SUM) {
EEPROM.get(CONFIG_SYSTEM_START, config);
EEPROM.end();
return true;
} else {
config.boardType = 0xFF;
config.vendorConfigured = false;
if(configVersion == EEPROM_CLEARED_INDICATOR) {
config.vendorConfigured = true;
} else {
config.vendorConfigured = false;
config.boardType = 0xFF;
}
config.userConfigured = false;
config.dataCollectionConsent = 0;
config.energyspeedometer = 0;
@ -91,7 +95,7 @@ bool AmsConfiguration::setNetworkConfig(NetworkConfig& config) {
}
stripNonAscii((uint8_t*) config.ssid, 32, true);
stripNonAscii((uint8_t*) config.psk, 64, true);
stripNonAscii((uint8_t*) config.psk, 64, true, false);
stripNonAscii((uint8_t*) config.ip, 16);
stripNonAscii((uint8_t*) config.gateway, 16);
stripNonAscii((uint8_t*) config.subnet, 16);
@ -186,7 +190,7 @@ bool AmsConfiguration::setMqttConfig(MqttConfig& config) {
stripNonAscii((uint8_t*) config.publishTopic, 64);
stripNonAscii((uint8_t*) config.subscribeTopic, 64);
stripNonAscii((uint8_t*) config.username, 128, true);
stripNonAscii((uint8_t*) config.password, 256, true);
stripNonAscii((uint8_t*) config.password, 256, true, false);
if(config.timeout < 500) config.timeout = 1000;
if(config.timeout > 10000) config.timeout = 1000;
if(config.keepalive < 5) config.keepalive = 60;
@ -252,7 +256,7 @@ bool AmsConfiguration::setWebConfig(WebConfig& config) {
}
stripNonAscii((uint8_t*) config.username, 37);
stripNonAscii((uint8_t*) config.password, 37);
stripNonAscii((uint8_t*) config.password, 37, false, false);
stripNonAscii((uint8_t*) config.context, 37);
EEPROM.begin(EEPROM_SIZE);
@ -892,6 +896,65 @@ void AmsConfiguration::ackCloudConfig() {
cloudChanged = false;
}
bool AmsConfiguration::getZmartChargeConfig(ZmartChargeConfig& config) {
if(hasConfig()) {
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 = false;
memset(config.token, 0, 64);
memset(config.baseUrl, 0, 64);
}
if(strncmp_P(config.baseUrl, PSTR("https"), 5) != 0) {
memset(config.baseUrl, 0, 64);
snprintf_P(config.baseUrl, 64, PSTR("https://main.zmartcharge.com/api"));
}
return true;
} else {
clearZmartChargeConfig(config);
return false;
}
}
bool AmsConfiguration::setZmartChargeConfig(ZmartChargeConfig& config) {
ZmartChargeConfig existing;
if(getZmartChargeConfig(existing)) {
zcChanged |= config.enabled != existing.enabled;
zcChanged |= memcmp(config.token, existing.token, 21) != 0;
zcChanged |= memcmp(config.token, existing.baseUrl, 64) != 0;
} else {
zcChanged = true;
}
stripNonAscii((uint8_t*) config.token, 21);
stripNonAscii((uint8_t*) config.baseUrl, 64);
if(strncmp_P(config.baseUrl, PSTR("https"), 5) != 0) {
memset(config.baseUrl, 0, 64);
}
EEPROM.begin(EEPROM_SIZE);
EEPROM.put(CONFIG_ZC_START, config);
bool ret = EEPROM.commit();
EEPROM.end();
return ret;
}
void AmsConfiguration::clearZmartChargeConfig(ZmartChargeConfig& config) {
config.enabled = false;
memset(config.token, 0, 21);
}
bool AmsConfiguration::isZmartChargeConfigChanged() {
return zcChanged;
}
void AmsConfiguration::ackZmartChargeConfig() {
zcChanged = false;
}
void AmsConfiguration::setUiLanguageChanged() {
uiLanguageChanged = true;
}
@ -1093,6 +1156,10 @@ bool AmsConfiguration::relocateConfig103() {
clearCloudConfig(cloud);
EEPROM.put(CONFIG_CLOUD_START, cloud);
ZmartChargeConfig zcc;
clearZmartChargeConfig(zcc);
EEPROM.put(CONFIG_ZC_START, zcc);
EEPROM.put(EEPROM_CONFIG_ADDRESS, 104);
bool ret = EEPROM.commit();
EEPROM.end();
@ -1101,6 +1168,7 @@ bool AmsConfiguration::relocateConfig103() {
bool AmsConfiguration::save() {
EEPROM.begin(EEPROM_SIZE);
uint8_t configVersion = EEPROM.read(EEPROM_CONFIG_ADDRESS);
EEPROM.put(EEPROM_CONFIG_ADDRESS, EEPROM_CHECK_SUM);
bool success = EEPROM.commit();
EEPROM.end();

View File

@ -28,7 +28,7 @@ void fromHex(uint8_t *out, String in, uint16_t size) {
}
}
bool stripNonAscii(uint8_t* in, uint16_t size, bool extended) {
bool stripNonAscii(uint8_t* in, uint16_t size, bool extended, bool trim) {
bool ret = false;
for(uint16_t i = 0; i < size; i++) {
if(in[i] == 0) { // Clear the rest with null-terminator
@ -43,6 +43,22 @@ bool stripNonAscii(uint8_t* in, uint16_t size, bool extended) {
ret = true;
}
}
if(trim) {
// Strip leading spaces
while(in[0] == ' ') {
for(uint16_t i = 0; i < size; i++) {
in[i] = in[i+1];
}
}
// Strip trailing spaces
for(int i = size-1; i > 0; i--) {
if(in[i] == ' ' || in[i] == 0) {
memset(in+i, 0, 1);
} else {
break;
}
}
}
memset(in+size-1, 0, 1); // Make sure the last character is null-terminator
return ret;
}

View File

@ -24,7 +24,7 @@
#define DATA_PARSE_OK 0
#define DATA_PARSE_FAIL -1
#define DATA_PARSE_INCOMPLETE -2
#define DATA_PARSE_BOUNDRY_FLAG_MISSING -3
#define DATA_PARSE_BOUNDARY_FLAG_MISSING -3
#define DATA_PARSE_HEADER_CHECKSUM_ERROR -4
#define DATA_PARSE_FOOTER_CHECKSUM_ERROR -5
#define DATA_PARSE_INTERMEDIATE_SEGMENT -6

View File

@ -19,8 +19,6 @@ time_t decodeCosemDateTime(CosemDateTime timestamp) {
tm.Minute = timestamp.minute;
tm.Second = timestamp.second;
//Serial.printf("\nY: %d, M: %d, D: %d, h: %d, m: %d, s: %d, deviation: 0x%2X, status: 0x%1X\n", tm.Year, tm.Month, tm.Day, tm.Hour, tm.Minute, tm.Second, timestamp.deviation, timestamp.status);
time_t time = makeTime(tm);
int16_t deviation = ntohs(timestamp.deviation);
if(deviation >= -720 && deviation <= 720) {

View File

@ -17,7 +17,7 @@ int8_t DSMRParser::parse(uint8_t *buf, DataParserContext &ctx, bool verified, Pr
uint8_t lastByte = 0x00;
for(uint16_t pos = 0; pos < ctx.length; pos++) {
uint8_t b = *(buf+pos);
if(pos == 0 && b != '/') return DATA_PARSE_BOUNDRY_FLAG_MISSING;
if(pos == 0 && b != '/') return DATA_PARSE_BOUNDARY_FLAG_MISSING;
if(pos > 0 && b == '!') crcPos = pos+1;
if(crcPos > 0 && b == 0x0A && lastByte == 0x0D) {
reachedEnd = true;

View File

@ -11,7 +11,7 @@ int8_t GBTParser::parse(uint8_t *d, DataParserContext &ctx) {
GBTHeader* h = (GBTHeader*) (d);
uint16_t sequence = ntohs(h->sequence);
if(h->flag != GBT_TAG) return DATA_PARSE_BOUNDRY_FLAG_MISSING;
if(h->flag != GBT_TAG) return DATA_PARSE_BOUNDARY_FLAG_MISSING;
if(sequence == 1) {
if(buf == NULL) buf = (uint8_t *)malloc((size_t)1024); // TODO find out from first package ?

View File

@ -23,7 +23,7 @@ int8_t GCMParser::parse(uint8_t *d, DataParserContext &ctx, bool hastag) {
uint32_t headersize = 0;
uint8_t* ptr = (uint8_t*) d;
if(hastag) {
if(*ptr != GCM_TAG) return DATA_PARSE_BOUNDRY_FLAG_MISSING;
if(*ptr != GCM_TAG) return DATA_PARSE_BOUNDARY_FLAG_MISSING;
ptr++;
headersize++;
}

View File

@ -29,7 +29,7 @@ int8_t HDLCParser::parse(uint8_t *d, DataParserContext &ctx) {
// First and last byte should be HDLC_FLAG
if(h->flag != HDLC_FLAG || f->flag != HDLC_FLAG)
return DATA_PARSE_BOUNDRY_FLAG_MISSING;
return DATA_PARSE_BOUNDARY_FLAG_MISSING;
// Verify FCS
if(ntohs(f->fcs) != crc16_x25(d + 1, len - sizeof *f - 1))

View File

@ -19,7 +19,7 @@ int8_t MBUSParser::parse(uint8_t *d, DataParserContext &ctx) {
MbusHeader* mh = (MbusHeader*) d;
if(mh->flag1 != MBUS_START || mh->flag2 != MBUS_START)
return DATA_PARSE_BOUNDRY_FLAG_MISSING;
return DATA_PARSE_BOUNDARY_FLAG_MISSING;
// First two bytes is 1-byte length value repeated. Only used for last segment
if(mh->len1 != mh->len2)
@ -40,7 +40,7 @@ int8_t MBUSParser::parse(uint8_t *d, DataParserContext &ctx) {
MbusFooter* mf = (MbusFooter*) (d + len + headersize);
if(mf->flag != MBUS_END)
return DATA_PARSE_BOUNDRY_FLAG_MISSING;
return DATA_PARSE_BOUNDARY_FLAG_MISSING;
if(checksum(d + headersize, len) != mf->fcs)
return DATA_PARSE_FOOTER_CHECKSUM_ERROR;

View File

@ -11,6 +11,9 @@
#include "AmsConfiguration.h"
#include "DataParser.h"
#include "Cosem.h"
#if defined(AMS_REMOTE_DEBUG)
#include "RemoteDebug.h"
#endif
#define NOVALUE 0xFFFFFFFF
@ -21,7 +24,11 @@ struct AmsOctetTimestamp {
class IEC6205675 : public AmsData {
public:
IEC6205675(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, AmsData &state);
#if defined(AMS_REMOTE_DEBUG)
IEC6205675(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, AmsData &state, RemoteDebug* debugger);
#else
IEC6205675(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, AmsData &state, Stream* debugger);
#endif
private:
CosemData* getCosemDataAt(uint8_t index, const char* ptr);

View File

@ -11,7 +11,11 @@
#include "Uptime.h"
#include "hexutils.h"
IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, AmsData &state) {
#if defined(AMS_REMOTE_DEBUG)
IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, AmsData &state, RemoteDebug* debugger) {
#else
IEC6205675::IEC6205675(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, AmsData &state, Stream* debugger) {
#endif
float val;
char str[64];
@ -635,12 +639,6 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterCo
}
}
if(this->packageTimestamp > 0) {
if(meterType == AmsTypeKamstrup) {
this->packageTimestamp = this->packageTimestamp - 3600;
}
}
uint8_t str_len = 0;
str_len = getString(AMS_OBIS_VERSION, sizeof(AMS_OBIS_VERSION), ((char *) (d)), str);
if(str_len > 0) {
@ -741,8 +739,12 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterCo
if(meterTs != NULL) {
AmsOctetTimestamp* amst = (AmsOctetTimestamp*) meterTs;
time_t ts = decodeCosemDateTime(amst->dt);
if(amst->dt.deviation == 0x8000) { // Deviation not specified, adjust from localtime to UTC
int16_t deviation = ntohs(amst->dt.deviation);
if(deviation < -720 || deviation > 720) { // Deviation not specified, adjust from localtime to UTC
meterTimestamp = tz.toUTC(ts);
if(ctx.timestamp > 0) {
this->packageTimestamp = tz.toUTC(ctx.timestamp);
}
} else if(meterType == AmsTypeAidon) {
meterTimestamp = ts - 3600; // 21.09.24, the clock is now correct
} else {

View File

@ -278,7 +278,7 @@ AmsData* PassiveMeterCommunicator::getData(AmsData& meterState) {
#endif
debugger->printf_P(PSTR("DLMS\n"));
// TODO: Split IEC6205675 into DataParserKaifa and DataParserObis. This way we can add other means of parsing, for those other proprietary formats
data = new IEC6205675(payload, meterState.getMeterType(), &meterConfig, ctx, meterState);
data = new IEC6205675(payload, meterState.getMeterType(), &meterConfig, ctx, meterState, debugger);
}
} else if(ctx.type == DATA_TAG_DSMR) {
data = new IEC6205621(payload, tz, &meterConfig);
@ -509,11 +509,11 @@ void PassiveMeterCommunicator::printHanReadError(int pos) {
#endif
{
switch(pos) {
case DATA_PARSE_BOUNDRY_FLAG_MISSING:
case DATA_PARSE_BOUNDARY_FLAG_MISSING:
#if defined(AMS_REMOTE_DEBUG)
if (debugger->isActive(RemoteDebug::WARNING))
#endif
debugger->printf_P(PSTR("Boundry flag missing\n"));
debugger->printf_P(PSTR("Boundary flag missing\n"));
break;
case DATA_PARSE_HEADER_CHECKSUM_ERROR:
#if defined(AMS_REMOTE_DEBUG)

File diff suppressed because one or more lines are too long

View File

@ -225,6 +225,10 @@
}
}
async function enablePriceFetch() {
configuration.p.e = true;
}
let gpioMax = 44;
$: {
gpioMax = sysinfo.chip == 'esp8266' ? 16 : sysinfo.chip == 'esp32s2' ? 44 : 39;
@ -272,7 +276,7 @@
<div class="flex">
<div class="w-full">
{translations.conf?.price?.region ?? "Price region"}<br/>
<select name="pr" bind:value={configuration.p.r} class="in-f w-full">
<select name="pr" bind:value={configuration.p.r} on:change={enablePriceFetch} class="in-f w-full">
<optgroup label="Norway">
{#if !configuration.p.t}
<option value="NO1S">NO1 with support</option>
@ -753,6 +757,16 @@
{/if}
{/if}
</div>
{#if sysinfo?.features?.includes('zc')}
<div class="my-1">
<label><input type="checkbox" name="cze" value="true" bind:checked={configuration.c.ze} class="rounded mb-1"/> ZmartCharge</label>
</div>
{#if configuration.c.ze}
<div class="my-1">
<input name="czt" bind:value={configuration.c.zt} type="text" class="in-s" placeholder="ZmartCharge token"/>
</div>
{/if}
{/if}
</div>
{/if}
{#if configuration?.p?.r?.startsWith("NO") || configuration?.p?.r?.startsWith("10YNO") || configuration?.p?.r?.startsWith('10Y1001A1001A4')}

View File

@ -7,7 +7,7 @@
case 'esp8266': gpioMax = 16; break;
case 'esp32s2': gpioMax = 44; break;
case 'esp32s3': gpioMax = 46; break;
case 'esp32c3': gpioMax = 19; break;
case 'esp32c3': gpioMax = 21; break;
}
}
</script>
@ -23,4 +23,3 @@
<option value={i}>GPIO{i}</option>
{/if}
{/each}

View File

@ -32,10 +32,10 @@
return s;
});
navigate(basepath + (sysinfo.usrcfg ? "/" : "/setup"));
navigate(basepath + (sysinfo.usrcfg ? "" : "setup"));
}
let cc = false;
let cc = true;
sysinfoStore.subscribe(update => {
sysinfo = update;
if(update.fwconsent === 1) {

View File

@ -316,7 +316,7 @@
"han" : {
"-1" : "Parse error",
"-2" : "Incomplete data received",
"-3" : "Payload boundry flag missing",
"-3" : "Payload boundary flag missing",
"-4" : "Header checksum error",
"-5" : "Footer checksum error",
"-9" : "Unknown data received, check meter config",
@ -324,6 +324,7 @@
"-51" : "Authentication failed",
"-52" : "Decryption failed",
"-53" : "Encryption key invalid",
"89" : "Unrecognized data received from meter",
"90" : "No HAN data received for at least 30s",
"91" : "Serial break",
"92" : "Serial buffer full",

View File

@ -1,5 +1,7 @@
"c": {
"e" : %s,
"p" : %d,
"es": %s
"es": %s,
"ze": %s,
"zt" : "%s"
}

View File

@ -398,6 +398,10 @@ void AmsWebServer::sysinfoJson() {
if(!features.isEmpty()) features += ",";
features += "\"cloud\"";
#endif
#if defined(ZMART_CHARGE)
if(!features.isEmpty()) features += ",";
features += "\"zc\"";
#endif
int size = snprintf_P(buf, BufferSize, SYSINFO_JSON,
FirmwareVersion::VersionString,
@ -870,6 +874,9 @@ void AmsWebServer::configurationJson() {
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;
@ -1049,10 +1056,12 @@ void AmsWebServer::configurationJson() {
cloud.enabled ? "true" : "false",
cloud.proto,
#if defined(ESP32) && defined(ENERGY_SPEEDOMETER_PASS)
sysConfig.energyspeedometer == 7 ? "true" : "false"
sysConfig.energyspeedometer == 7 ? "true" : "false",
#else
"null"
"null",
#endif
zcc.enabled ? "true" : "false",
zcc.token
);
server.sendContent(buf);
server.sendContent_P(PSTR("}"));
@ -1181,9 +1190,6 @@ void AmsWebServer::handleSave() {
if(server.hasArg(F("v")) && server.arg(F("v")) == F("true")) {
int boardType = server.arg(F("vb")).toInt();
int hanPin = server.arg(F("vh")).toInt();
if(server.hasArg(F("vr")) && server.arg(F("vr")) == F("true")) {
config->clear();
}
MeterConfig meterConfig;
config->getMeterConfig(meterConfig);
@ -1572,6 +1578,16 @@ void AmsWebServer::handleSave() {
cloud.enabled = server.hasArg(F("ce")) && server.arg(F("ce")) == F("true");
cloud.proto = server.arg(F("cp")).toInt();
config->setCloudConfig(cloud);
ZmartChargeConfig zcc;
config->getZmartChargeConfig(zcc);
zcc.enabled = server.hasArg(F("cze")) && server.arg(F("cze")) == F("true");
String token = server.arg(F("czt"));
strcpy(zcc.token, token.c_str());
if(server.hasArg(F("czu")) && server.arg(F("czu")).startsWith(F("https"))) {
strcpy(zcc.baseUrl, server.arg(F("czu")).c_str());
}
config->setZmartChargeConfig(zcc);
}
if(server.hasArg(F("r")) && server.arg(F("r")) == F("true")) {
@ -1647,7 +1663,10 @@ void AmsWebServer::handleSave() {
#endif
debugger->printf_P(PSTR("Saving configuration now...\n"));
if (config->save()) {
// If vendor page and clear all config is selected
if(server.hasArg(F("v")) && server.arg(F("v")) == F("true") && server.hasArg(F("vr")) && server.arg(F("vr")) == F("true")) {
config->clear();
} else if(config->save()) {
#if defined(AMS_REMOTE_DEBUG)
if (debugger->isActive(RemoteDebug::INFO))
#endif

View File

@ -0,0 +1,52 @@
#pragma once
#include "RemoteDebug.h"
#include "AmsData.h"
#include "FirmwareVersion.h"
#if defined(ESP8266)
#include <ESP8266HTTPClient.h>
#elif defined(ESP32) // ARDUINO_ARCH_ESP32
#include <HTTPClient.h>
#else
#warning "Unsupported board type"
#endif
static const char ZC_LB_JSON[] PROGMEM = "{\"LBToken\":\"%s\",\"L1A\":\"%.1f\",\"L2A\":\"%.1f\",\"L3A\":\"%.1f\",\"HighConsumption\":\"%d\",\"CurrentPower\":\"%d\"}";
class ZmartChargeCloudConnector {
public:
ZmartChargeCloudConnector(RemoteDebug* debugger, char* buf) {
this->debugger = debugger;
this->json = buf;
http = new HTTPClient();
http->setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
http->setReuse(false);
http->setTimeout(10000);
http->setUserAgent("ams2mqtt/" + String(FirmwareVersion::VersionString));
};
void setup(const char* baseUrl, const char* token);
void update(AmsData& data);
bool isConfigChanged();
void ackConfigChanged();
const char* getBaseUrl();
private:
RemoteDebug* debugger;
char baseUrl[64];
char token[21];
uint16_t BufferSize = 2048;
char* json;
bool configChanged = false;
bool lastFailed = false;
uint64_t lastUpdate = 0;
HTTPClient* http = NULL;
uint16_t heartbeat = 30;
uint16_t heartbeatFast = 10;
uint16_t heartbeatFastThreshold = 32;
};

View File

@ -0,0 +1,100 @@
#include "ZmartChargeCloudConnector.h"
#include "Uptime.h"
#include "ArduinoJson.h"
void ZmartChargeCloudConnector::setup(const char* baseUrl, const char* token) {
memset(this->baseUrl, 0, 64);
memset(this->token, 0, 21);
strcpy(this->baseUrl, baseUrl);
strcpy(this->token, token);
}
bool ZmartChargeCloudConnector::isConfigChanged() {
return configChanged;
}
void ZmartChargeCloudConnector::ackConfigChanged() {
configChanged = false;
}
const char* ZmartChargeCloudConnector::getBaseUrl() {
return baseUrl;
}
void ZmartChargeCloudConnector::update(AmsData& data) {
if(strlen(token) == 0) return;
uint64_t now = millis64();
float maximum = max(max(data.getL1Current(), data.getL1Current()), data.getL3Current());
bool fast = maximum > heartbeatFastThreshold;
if(now - lastUpdate < (fast ? heartbeatFast : heartbeat) * 1000) return;
if(strlen(token) != 20) {
lastUpdate = now;
if(debugger->isActive(RemoteDebug::WARNING)) debugger->printf_P(PSTR("(ZmartCharge) Token defined, but is incorrect length (%s, %d)\n"), token, strlen(token));
return;
}
if(((now - lastUpdate) / 1000) > (fast || lastFailed ? heartbeatFast : heartbeat)) {
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf_P(PSTR("(ZmartCharge) Preparing to update cloud\n"));
memset(json, 0, BufferSize);
snprintf_P(json, BufferSize, ZC_LB_JSON,
token,
data.getL1Current(),
data.getL2Current(),
data.getL3Current(),
fast ? 1 : 0,
data.getActiveImportPower()
);
lastFailed = true;
char url[128];
memset(url, 0, 128);
snprintf_P(url, 128, PSTR("%s/loadbalancer"), baseUrl);
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf_P(PSTR("(ZmartCharge) Connecting to: %s\n"), baseUrl);
if(http->begin(url)) {
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf_P(PSTR("(ZmartCharge) Sending data: %s\n"), json);
int status = http->POST(json);
if(status == 200) {
lastFailed = false;
JsonDocument doc;
String body = http->getString();
if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf_P(PSTR("(ZmartCharge) Received data: %s\n"), body.c_str());
deserializeJson(doc, body);
if(doc.containsKey("Settings")) {
if(doc["Settings"].containsKey("HeartBeatTime")) {
heartbeat = doc["Settings"]["HeartBeatTime"].as<long>();
}
if(doc["Settings"].containsKey("HearBeatTimeFast")) {
heartbeatFast = doc["Settings"]["HearBeatTimeFast"].as<long>();
}
if(doc["Settings"].containsKey("HeartBeatTimeFastThreshold")) {
heartbeatFastThreshold = doc["Settings"]["HeartBeatTimeFastThreshold"].as<long>();
}
if(doc["Settings"].containsKey("ZmartChargeUrl")) {
String newBaseUrl = doc["Settings"]["ZmartChargeUrl"].as<String>();
if(newBaseUrl.startsWith("https:") && strncmp(newBaseUrl.c_str(), baseUrl, strlen(baseUrl)) != 0) {
newBaseUrl.replace("\\/", "/");
if(debugger->isActive(RemoteDebug::INFO)) debugger->printf_P(PSTR("(ZmartCharge) Received new URL: %s\n"), newBaseUrl.c_str());
memset(baseUrl, 0, 64);
memcpy(baseUrl, newBaseUrl.c_str(), strlen(newBaseUrl.c_str()));
configChanged = true;
}
}
}
http->end();
} else {
if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf_P(PSTR("(ZmartCharge) Communication error, returned status: %d\n"), status);
if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf(http->errorToString(status).c_str());
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(http->getString().c_str());
http->end();
}
} else {
if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf_P(PSTR("(ZmartCharge) Unable to establish connection with cloud\n"));
}
lastUpdate = now;
}
}

9
localazy/localazy.json Normal file
View File

@ -0,0 +1,9 @@
{
"upload": {},
"download": {
"includeSourceLang": true,
"folder": "./language/",
"files": "${lang}.json"
},
"transformations": []
}

View File

@ -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, 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, bblanchon/ArduinoJson@7.0.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, SvelteUi
lib_deps = WiFi, Ethernet, ESPmDNS, WiFiClientSecure, HTTPClient, FS, WebServer, ESP32 Async UDP, ESP32SSDP, mulmer89/ESPRandom@1.5.0, ${common.lib_deps}, CloudConnector, ZmartCharge, SvelteUi
[env:esp8266]
platform = espressif8266@4.2.1
@ -44,6 +44,7 @@ build_flags =
-D AMS_REMOTE_DEBUG=1
-D AMS_CLOUD=1
-D AMS_KMP=1
-D ZMART_CHARGE=1
-L precompiled/esp32
-lKmpTalker
lib_ldf_mode = off
@ -70,6 +71,7 @@ build_flags =
-D AMS_REMOTE_DEBUG=1
-D AMS_CLOUD=1
-D AMS_KMP=1
-D ZMART_CHARGE=1
-L precompiled/esp32s2
-lKmpTalker
lib_ldf_mode = off
@ -90,6 +92,7 @@ build_flags =
-D AMS_REMOTE_DEBUG=1
-D AMS_CLOUD=1
-D AMS_KMP=1
-D ZMART_CHARGE=1
-L precompiled/esp32
-lKmpTalker
lib_ldf_mode = off
@ -109,6 +112,7 @@ build_flags =
-D AMS_REMOTE_DEBUG=1
-D AMS_CLOUD=1
-D AMS_KMP=1
-D ZMART_CHARGE=1
-L precompiled/esp32c3
-lKmpTalker
lib_ldf_mode = off
@ -127,6 +131,7 @@ build_flags =
-D AMS_REMOTE_DEBUG=1
-D AMS_CLOUD=1
-D AMS_KMP=1
-D ZMART_CHARGE=1
-L precompiled/esp32s3
-lKmpTalker
lib_ldf_mode = off

View File

@ -26,6 +26,9 @@ ADC_MODE(ADC_VCC);
#if defined(AMS_CLOUD)
#include "CloudConnector.h"
#endif
#if defined(ZMART_CHARGE)
#include "ZmartChargeCloudConnector.h"
#endif
#define WDT_TIMEOUT 120
#if defined(SLOW_PROC_TRIGGER_MS)
@ -43,6 +46,7 @@ ADC_MODE(ADC_VCC);
#define METER_PARSER_PULSE 2
#define METER_PARSER_KAMSTRUP 9
#define METER_ERROR_UNKNOWN_DATA 89
#define METER_ERROR_NO_DATA 90
#define METER_ERROR_BREAK 91
#define METER_ERROR_BUFFER 92
@ -182,6 +186,11 @@ AmsFirmwareUpdater updater(&Debug, &hw, &meterState);
AmsDataStorage ds(&Debug);
#if defined(_CLOUDCONNECTOR_H)
CloudConnector *cloud = NULL;
#endif
#if defined(ZMART_CHARGE)
ZmartChargeCloudConnector *zcloud = NULL;
#endif
#if defined(ESP32)
__NOINIT_ATTR EnergyAccountingRealtimeData rtd;
#else
EnergyAccountingRealtimeData rtd;
@ -694,6 +703,36 @@ void loop() {
cloud->update(meterState, ea);
}
#endif
#if defined(ZMART_CHARGE)
if(config.isZmartChargeConfigChanged()) {
ZmartChargeConfig zcc;
if(config.getZmartChargeConfig(zcc) && zcc.enabled) {
if(zcloud == NULL) {
zcloud = new ZmartChargeCloudConnector(&Debug, (char*) commonBuffer);
}
zcloud->setup(zcc.baseUrl, zcc.token);
} else if(zcloud != NULL) {
delete zcloud;
zcloud = NULL;
}
config.ackZmartChargeConfig();
}
if(zcloud != NULL) {
zcloud->update(meterState);
if(zcloud->isConfigChanged()) {
ZmartChargeConfig zcc;
if(config.getZmartChargeConfig(zcc)) {
const char* newBaseUrl = zcloud->getBaseUrl();
memset(zcc.baseUrl, 0, 64);
memcpy(zcc.baseUrl, newBaseUrl, strlen(newBaseUrl));
config.setZmartChargeConfig(zcc);
config.ackZmartChargeConfig();
}
zcloud->ackConfigChanged();
}
}
#endif
start = millis();
handleUiLanguage();
end = millis();
@ -1307,6 +1346,8 @@ bool readHanPort() {
if(data != NULL) {
if(data->getListType() > 0) {
handleDataSuccess(data);
} else {
meterState.setLastError(METER_ERROR_UNKNOWN_DATA);
}
delete data;
}
@ -1620,7 +1661,9 @@ void configFileParse() {
}
if(strncmp_P(buf, PSTR("boardType "), 10) == 0) {
if(!lSys) { config.getSystemConfig(sys); lSys = true; };
sys.boardType = String(buf+10).toInt();
if(sys.boardType == 0xFF) {
sys.boardType = String(buf+10).toInt();
}
} else if(strncmp_P(buf, PSTR("netmode "), 8) == 0) {
if(!lNetwork) { config.getNetworkConfig(network); lNetwork = true; };
network.mode = String(buf+8).toInt();