From 2af356cde854f401070d389c5504d420e87fae84 Mon Sep 17 00:00:00 2001
From: Stephan van Rooij <1292510+svrooij@users.noreply.github.com>
Date: Fri, 26 Feb 2021 19:48:24 +0100
Subject: [PATCH] feat: Support for meters with encrypted DSMR (#23)
* wip: Luxemburg meter parsing
* fix: Timeout on socket connection
Fixed #22
* feat: Basic support for reading encrypted meters
Fixed #21
* fix: Final changes to support decrypting
* docs: Started documentation
* docs: Another docs update
* chore: Remove duplicate screenshot
* chore: Lint errors
---
.gitignore | 2 -
.vscode/launch.json | 37 +++
README.md | 38 ++-
docs/.gitignore | 3 +
docs/404.html | 24 ++
docs/Gemfile | 28 ++
docs/Gemfile.lock | 272 ++++++++++++++++++
docs/_config.yml | 71 +++++
docs/_data/readers.json | 38 +++
docs/_includes/network.html | 18 ++
docs/_includes/usb.html | 16 ++
docs/advanced/decryption.md | 50 ++++
docs/advanced/index.md | 9 +
docs/advanced/solar-input.md | 55 ++++
.../images/screenshot_web-with-solar.png | Bin 0 -> 2022327 bytes
.../assets/images}/screenshot_web.png | Bin
.../images/undraw_data_processing_yrrv.svg | 1 +
docs/configuration.md | 72 +++++
docs/connect.md | 28 ++
docs/development.md | 67 +++++
docs/docker-compose.yml | 15 +
docs/index.md | 123 ++++++++
docs/outputs/mqtt.md | 78 +++++
docs/outputs/outputs.md | 12 +
docs/outputs/post-to-url.md | 13 +
docs/outputs/socket.md | 105 +++++++
docs/outputs/webserver.md | 13 +
example/decode-from-socket.js | 45 +++
example/decrypt-message.js | 12 +
example/encrypt-message.js | 63 ++++
example/socket-reader.js | 101 +++++++
src/config.ts | 84 +++++-
src/dsmr-message.ts | 28 ++
src/index.ts | 5 +-
src/output/http-output.ts | 10 +-
src/output/mqtt-output.ts | 78 +++--
src/output/tcp-output.ts | 2 +-
src/output/wwwroot/index.html | 4 +-
src/output/wwwroot/loader.js | 16 +-
src/p1-crypt.ts | 119 ++++++++
src/p1-map.ts | 11 +-
src/p1-parser.ts | 5 +-
src/p1-reader.ts | 39 ++-
tests/output-tests.ts | 2 +-
44 files changed, 1747 insertions(+), 65 deletions(-)
create mode 100644 .vscode/launch.json
create mode 100644 docs/.gitignore
create mode 100644 docs/404.html
create mode 100644 docs/Gemfile
create mode 100644 docs/Gemfile.lock
create mode 100644 docs/_config.yml
create mode 100644 docs/_data/readers.json
create mode 100644 docs/_includes/network.html
create mode 100644 docs/_includes/usb.html
create mode 100644 docs/advanced/decryption.md
create mode 100644 docs/advanced/index.md
create mode 100644 docs/advanced/solar-input.md
create mode 100644 docs/assets/images/screenshot_web-with-solar.png
rename {screenshots => docs/assets/images}/screenshot_web.png (100%)
create mode 100644 docs/assets/images/undraw_data_processing_yrrv.svg
create mode 100644 docs/configuration.md
create mode 100644 docs/connect.md
create mode 100644 docs/development.md
create mode 100644 docs/docker-compose.yml
create mode 100644 docs/index.md
create mode 100644 docs/outputs/mqtt.md
create mode 100644 docs/outputs/outputs.md
create mode 100644 docs/outputs/post-to-url.md
create mode 100644 docs/outputs/socket.md
create mode 100644 docs/outputs/webserver.md
create mode 100644 example/decode-from-socket.js
create mode 100644 example/decrypt-message.js
create mode 100644 example/encrypt-message.js
create mode 100644 example/socket-reader.js
create mode 100644 src/p1-crypt.ts
diff --git a/.gitignore b/.gitignore
index 5b97b72..9c1caa6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -60,6 +60,4 @@ typings/
# next.js build output
.next
-.vscode
-
dist
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..72be5a9
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,37 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "Launch Program",
+ "program": "${workspaceFolder}/src/index.ts",
+ "preLaunchTask": "tsc: build - tsconfig.json",
+ "outFiles": ["${workspaceFolder}/dist/**/*.js"],
+ "env": {
+ // "SMARTMETER_PORT": "/dev/ttyUSB0",
+ // "SMARTMETER_SOCKET": "192.168.94.12:3020",
+ "SMARTMETER_DEBUG": "true",
+ "SMARTMETER_web-server": "3000",
+ "SMARTMETER_tcp-server": "3010",
+ "SMARTMETER_raw-tcp-server": "3020",
+ "SMARTMETER_mqtt-url": "mqtt://localhost:1883",
+ // "SMARTMETER_enc-key": "AAAA57A9FC71698E193D7CF6103CAAAA"
+ // "SMARTMETER_sunspec-modbus": "192.168.1.30"
+
+ }
+ },
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "Run current file",
+ "program": "${file}",
+ "preLaunchTask": "tsc: build - tsconfig.json",
+ "outFiles": ["${workspaceFolder}/dist/**/*.js"],
+ // "args": ["192.168.1.14", "23"]
+ },
+ ]
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 3bd4283..284d69b 100644
--- a/README.md
+++ b/README.md
@@ -158,7 +158,7 @@ You can enable the webserver. This will enable you to see a simple webpage with
This webpage uses WebSockets for automatic server side data refresh. So the browser will show the latest data as it comes in. If your browser doesn't support websockets it should fallback on ajax loading.
-![Screenshot of web interface](./screenshots/screenshot_web.png "Web interface demo")
+![Screenshot of web interface](./docs/assets/images/screenshot_web.png "Web interface demo")
### Output -> JSON tcp socket
@@ -288,6 +288,42 @@ If you're running home assistant, be sure to enable mqtt discovery `--mqtt-disco
This section is for the curious ones.
+### Debugging
+
+You can easily debug this app in vscode if you add the following to the `.vscode/launch.json` file:
+
+```jsonc
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "Launch Program",
+ "program": "${workspaceFolder}/src/index.ts",
+ "preLaunchTask": "tsc: build - tsconfig.json",
+ "outFiles": ["${workspaceFolder}/dist/**/*.js"],
+ "env": {
+ // "SMARTMETER_SOCKET": "192.168.94.12:3020",
+ "SMARTMETER_DEBUG": "true",
+ "SMARTMETER_web-server": "3000",
+ "SMARTMETER_tcp-server": "3010",
+ "SMARTMETER_raw-tcp-server": "3020",
+ "SMARTMETER_mqtt-url": "mqtt://localhost:1883",
+ //"SMARTMETER_enc-key": "AAAA57A9FC71698E193D7CF6103CAAAA"
+ //"SMARTMETER_sunspec-modbus": "192.168.1.30"
+
+ }
+ }
+ ]
+}
+```
+
+I have one instance running, that outputs a raw tcp socket that I use for debugging on my computer.
+
### Support for output X
This package comes with several outputs, they all extend [Output](https://github.com/svrooij/smartmeter2mqtt/blob/master/src/output/output.ts).
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 0000000..45c1505
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1,3 @@
+_site
+.sass-cache
+.jekyll-metadata
diff --git a/docs/404.html b/docs/404.html
new file mode 100644
index 0000000..c472b4e
--- /dev/null
+++ b/docs/404.html
@@ -0,0 +1,24 @@
+---
+layout: default
+---
+
+
+
+
+
404
+
+
Page not found :(
+
The requested page could not be found.
+
diff --git a/docs/Gemfile b/docs/Gemfile
new file mode 100644
index 0000000..e4f4650
--- /dev/null
+++ b/docs/Gemfile
@@ -0,0 +1,28 @@
+source "https://rubygems.org"
+
+# Hello! This is where you manage which Jekyll version is used to run.
+# When you want to use a different version, change it below, save the
+# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
+#
+# bundle exec jekyll serve
+#
+# This will help ensure the proper Jekyll version is running.
+# Happy Jekylling!
+# gem "jekyll", "~> 3.8.5"
+
+# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
+# uncomment the line below. To upgrade, run `bundle update github-pages`.
+gem "github-pages", group: :jekyll_plugins
+
+# If you have any plugins, put them here!
+group :jekyll_plugins do
+ gem "jekyll-feed", "~> 0.6"
+end
+
+# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
+gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]
+
+# Performance-booster for watching directories on Windows
+gem "wdm", "~> 0.1.0" if Gem.win_platform?
+
+gem "just-the-docs", "0.3.3"
diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock
new file mode 100644
index 0000000..044d837
--- /dev/null
+++ b/docs/Gemfile.lock
@@ -0,0 +1,272 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ activesupport (6.0.3.4)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ i18n (>= 0.7, < 2)
+ minitest (~> 5.1)
+ tzinfo (~> 1.1)
+ zeitwerk (~> 2.2, >= 2.2.2)
+ addressable (2.7.0)
+ public_suffix (>= 2.0.2, < 5.0)
+ coffee-script (2.4.1)
+ coffee-script-source
+ execjs
+ coffee-script-source (1.11.1)
+ colorator (1.1.0)
+ commonmarker (0.17.13)
+ ruby-enum (~> 0.5)
+ concurrent-ruby (1.1.8)
+ dnsruby (1.61.5)
+ simpleidn (~> 0.1)
+ em-websocket (0.5.2)
+ eventmachine (>= 0.12.9)
+ http_parser.rb (~> 0.6.0)
+ ethon (0.12.0)
+ ffi (>= 1.3.0)
+ eventmachine (1.2.7)
+ execjs (2.7.0)
+ faraday (1.3.0)
+ faraday-net_http (~> 1.0)
+ multipart-post (>= 1.2, < 3)
+ ruby2_keywords
+ faraday-net_http (1.0.1)
+ ffi (1.14.2)
+ forwardable-extended (2.6.0)
+ gemoji (3.0.1)
+ github-pages (211)
+ github-pages-health-check (= 1.16.1)
+ jekyll (= 3.9.0)
+ jekyll-avatar (= 0.7.0)
+ jekyll-coffeescript (= 1.1.1)
+ jekyll-commonmark-ghpages (= 0.1.6)
+ jekyll-default-layout (= 0.1.4)
+ jekyll-feed (= 0.15.1)
+ jekyll-gist (= 1.5.0)
+ jekyll-github-metadata (= 2.13.0)
+ jekyll-mentions (= 1.6.0)
+ jekyll-optional-front-matter (= 0.3.2)
+ jekyll-paginate (= 1.1.0)
+ jekyll-readme-index (= 0.3.0)
+ jekyll-redirect-from (= 0.16.0)
+ jekyll-relative-links (= 0.6.1)
+ jekyll-remote-theme (= 0.4.2)
+ jekyll-sass-converter (= 1.5.2)
+ jekyll-seo-tag (= 2.7.1)
+ jekyll-sitemap (= 1.4.0)
+ jekyll-swiss (= 1.0.0)
+ jekyll-theme-architect (= 0.1.1)
+ jekyll-theme-cayman (= 0.1.1)
+ jekyll-theme-dinky (= 0.1.1)
+ jekyll-theme-hacker (= 0.1.2)
+ jekyll-theme-leap-day (= 0.1.1)
+ jekyll-theme-merlot (= 0.1.1)
+ jekyll-theme-midnight (= 0.1.1)
+ jekyll-theme-minimal (= 0.1.1)
+ jekyll-theme-modernist (= 0.1.1)
+ jekyll-theme-primer (= 0.5.4)
+ jekyll-theme-slate (= 0.1.1)
+ jekyll-theme-tactile (= 0.1.1)
+ jekyll-theme-time-machine (= 0.1.1)
+ jekyll-titles-from-headings (= 0.5.3)
+ jemoji (= 0.12.0)
+ kramdown (= 2.3.0)
+ kramdown-parser-gfm (= 1.1.0)
+ liquid (= 4.0.3)
+ mercenary (~> 0.3)
+ minima (= 2.5.1)
+ nokogiri (>= 1.10.4, < 2.0)
+ rouge (= 3.26.0)
+ terminal-table (~> 1.4)
+ github-pages-health-check (1.16.1)
+ addressable (~> 2.3)
+ dnsruby (~> 1.60)
+ octokit (~> 4.0)
+ public_suffix (~> 3.0)
+ typhoeus (~> 1.3)
+ html-pipeline (2.14.0)
+ activesupport (>= 2)
+ nokogiri (>= 1.4)
+ http_parser.rb (0.6.0)
+ i18n (0.9.5)
+ concurrent-ruby (~> 1.0)
+ jekyll (3.9.0)
+ addressable (~> 2.4)
+ colorator (~> 1.0)
+ em-websocket (~> 0.5)
+ i18n (~> 0.7)
+ jekyll-sass-converter (~> 1.0)
+ jekyll-watch (~> 2.0)
+ kramdown (>= 1.17, < 3)
+ liquid (~> 4.0)
+ mercenary (~> 0.3.3)
+ pathutil (~> 0.9)
+ rouge (>= 1.7, < 4)
+ safe_yaml (~> 1.0)
+ jekyll-avatar (0.7.0)
+ jekyll (>= 3.0, < 5.0)
+ jekyll-coffeescript (1.1.1)
+ coffee-script (~> 2.2)
+ coffee-script-source (~> 1.11.1)
+ jekyll-commonmark (1.3.1)
+ commonmarker (~> 0.14)
+ jekyll (>= 3.7, < 5.0)
+ jekyll-commonmark-ghpages (0.1.6)
+ commonmarker (~> 0.17.6)
+ jekyll-commonmark (~> 1.2)
+ rouge (>= 2.0, < 4.0)
+ jekyll-default-layout (0.1.4)
+ jekyll (~> 3.0)
+ jekyll-feed (0.15.1)
+ jekyll (>= 3.7, < 5.0)
+ jekyll-gist (1.5.0)
+ octokit (~> 4.2)
+ jekyll-github-metadata (2.13.0)
+ jekyll (>= 3.4, < 5.0)
+ octokit (~> 4.0, != 4.4.0)
+ jekyll-mentions (1.6.0)
+ html-pipeline (~> 2.3)
+ jekyll (>= 3.7, < 5.0)
+ jekyll-optional-front-matter (0.3.2)
+ jekyll (>= 3.0, < 5.0)
+ jekyll-paginate (1.1.0)
+ jekyll-readme-index (0.3.0)
+ jekyll (>= 3.0, < 5.0)
+ jekyll-redirect-from (0.16.0)
+ jekyll (>= 3.3, < 5.0)
+ jekyll-relative-links (0.6.1)
+ jekyll (>= 3.3, < 5.0)
+ jekyll-remote-theme (0.4.2)
+ addressable (~> 2.0)
+ jekyll (>= 3.5, < 5.0)
+ jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0)
+ rubyzip (>= 1.3.0, < 3.0)
+ jekyll-sass-converter (1.5.2)
+ sass (~> 3.4)
+ jekyll-seo-tag (2.7.1)
+ jekyll (>= 3.8, < 5.0)
+ jekyll-sitemap (1.4.0)
+ jekyll (>= 3.7, < 5.0)
+ jekyll-swiss (1.0.0)
+ jekyll-theme-architect (0.1.1)
+ jekyll (~> 3.5)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-cayman (0.1.1)
+ jekyll (~> 3.5)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-dinky (0.1.1)
+ jekyll (~> 3.5)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-hacker (0.1.2)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-leap-day (0.1.1)
+ jekyll (~> 3.5)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-merlot (0.1.1)
+ jekyll (~> 3.5)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-midnight (0.1.1)
+ jekyll (~> 3.5)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-minimal (0.1.1)
+ jekyll (~> 3.5)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-modernist (0.1.1)
+ jekyll (~> 3.5)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-primer (0.5.4)
+ jekyll (> 3.5, < 5.0)
+ jekyll-github-metadata (~> 2.9)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-slate (0.1.1)
+ jekyll (~> 3.5)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-tactile (0.1.1)
+ jekyll (~> 3.5)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-time-machine (0.1.1)
+ jekyll (~> 3.5)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-titles-from-headings (0.5.3)
+ jekyll (>= 3.3, < 5.0)
+ jekyll-watch (2.2.1)
+ listen (~> 3.0)
+ jemoji (0.12.0)
+ gemoji (~> 3.0)
+ html-pipeline (~> 2.2)
+ jekyll (>= 3.0, < 5.0)
+ just-the-docs (0.3.3)
+ jekyll (>= 3.8.5)
+ jekyll-seo-tag (~> 2.0)
+ rake (>= 12.3.1, < 13.1.0)
+ kramdown (2.3.0)
+ rexml
+ kramdown-parser-gfm (1.1.0)
+ kramdown (~> 2.0)
+ liquid (4.0.3)
+ listen (3.4.1)
+ rb-fsevent (~> 0.10, >= 0.10.3)
+ rb-inotify (~> 0.9, >= 0.9.10)
+ mercenary (0.3.6)
+ minima (2.5.1)
+ jekyll (>= 3.5, < 5.0)
+ jekyll-feed (~> 0.9)
+ jekyll-seo-tag (~> 2.1)
+ minitest (5.14.3)
+ multipart-post (2.1.1)
+ nokogiri (1.11.1-x86_64-linux)
+ racc (~> 1.4)
+ octokit (4.20.0)
+ faraday (>= 0.9)
+ sawyer (~> 0.8.0, >= 0.5.3)
+ pathutil (0.16.2)
+ forwardable-extended (~> 2.6)
+ public_suffix (3.1.1)
+ racc (1.5.2)
+ rake (13.0.3)
+ rb-fsevent (0.10.4)
+ rb-inotify (0.10.1)
+ ffi (~> 1.0)
+ rexml (3.2.4)
+ rouge (3.26.0)
+ ruby-enum (0.8.0)
+ i18n
+ ruby2_keywords (0.0.4)
+ rubyzip (2.3.0)
+ safe_yaml (1.0.5)
+ sass (3.7.4)
+ sass-listen (~> 4.0.0)
+ sass-listen (4.0.0)
+ rb-fsevent (~> 0.9, >= 0.9.4)
+ rb-inotify (~> 0.9, >= 0.9.7)
+ sawyer (0.8.2)
+ addressable (>= 2.3.5)
+ faraday (> 0.8, < 2.0)
+ simpleidn (0.2.1)
+ unf (~> 0.1.4)
+ terminal-table (1.8.0)
+ unicode-display_width (~> 1.1, >= 1.1.1)
+ thread_safe (0.3.6)
+ typhoeus (1.4.0)
+ ethon (>= 0.9.0)
+ tzinfo (1.2.9)
+ thread_safe (~> 0.1)
+ unf (0.1.4)
+ unf_ext
+ unf_ext (0.0.7.7)
+ unicode-display_width (1.7.0)
+ zeitwerk (2.4.2)
+
+PLATFORMS
+ ruby
+ x86_64-linux-musl
+
+DEPENDENCIES
+ github-pages
+ jekyll-feed (~> 0.6)
+ just-the-docs (= 0.3.3)
+ tzinfo-data
+
+BUNDLED WITH
+ 2.2.2
diff --git a/docs/_config.yml b/docs/_config.yml
new file mode 100644
index 0000000..a8b0aa2
--- /dev/null
+++ b/docs/_config.yml
@@ -0,0 +1,71 @@
+# Welcome to Jekyll!
+#
+# This config file is meant for settings that affect your whole blog, values
+# which you are expected to set up once and rarely edit after that. If you find
+# yourself editing this file very often, consider using Jekyll's data files
+# feature for the data you need to update frequently.
+#
+# For technical reasons, this file is *NOT* reloaded automatically when you use
+# 'bundle exec jekyll serve'. If you change this file, please restart the server process.
+
+# Site settings
+# These are used to personalize your new site. If you look in the HTML files,
+# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
+# You can create any custom variable you would like, and they will be accessible
+# in the templates via {{ site.myvariable }}.
+title: Smartmeter2mqtt
+email: 1292510+svrooij@users.noreply.github.com
+# description: >- # this means to ignore newlines until "baseurl:"
+# Write an awesome description for your new site here. You can edit this
+# line in _config.yml. It will appear in your document head meta (for
+# Google search results) and in your feed.xml site description.
+baseurl: "/smartmeter2mqtt" # the subpath of your site, e.g. /blog
+url: "https://svrooij.io" # the base hostname & protocol for your site, e.g. http://example.com
+twitter_username: svrooij
+github_username: svrooij
+repository: svrooij/smartmeter2mqtt
+
+# Build settings
+markdown: kramdown
+remote_theme: svrooij/just-the-docs@relative-everything
+plugins:
+ - jekyll-feed
+ - jemoji
+
+# Exclude from processing.
+# The following items will not be processed, by default. Create a custom list
+# to override the default setting.
+# exclude:
+# - Gemfile
+# - Gemfile.lock
+# - node_modules
+# - vendor/bundle/
+# - vendor/cache/
+# - vendor/gems/
+# - vendor/ruby/
+
+# Enable or disable heading anchors
+heading_anchors: true
+
+# Aux links for the upper right navigation
+aux_links:
+ "Github repository":
+ - "//github.com/svrooij/smartmeter2mqtt"
+ "Become sponsor":
+ - "//github.com/sponsors/svrooij/"
+
+# Footer content appears at the bottom of every page's main content
+footer_content: "Copyright © 2021 Stephan van Rooij. Distributed by an MIT license."
+
+toc:
+ max_levels: 2
+
+# Footer "Edit this page on GitHub" link text
+gh_edit_link: true # show or hide edit this page link
+gh_edit_link_text: "Source on Github"
+gh_edit_repository: "https://github.com/svrooij/smartmeter2mqtt" # the github URL for your repo
+gh_edit_branch: "master/docs" # the branch that your docs is served from
+gh_edit_view_mode: "tree" # "tree" or "edit" if you want the user to jump into the editor immediately
+
+ga_tracking: UA-172036806-1
+ga_tracking_anonymize_ip: true
\ No newline at end of file
diff --git a/docs/_data/readers.json b/docs/_data/readers.json
new file mode 100644
index 0000000..bdaa956
--- /dev/null
+++ b/docs/_data/readers.json
@@ -0,0 +1,38 @@
+{
+ "socket":[
+ {
+ "name": "P1 reader ethernet v3.2",
+ "connection": "Ethernet",
+ "meterPowered": true,
+ "usbPowered": true,
+ "link": "https://www.zuidwijk.com/p1-reader-ethernet-version/",
+ "buy": "https://www.zuidwijk.com/product/p1-reader-ethernet/",
+ "creator": {
+ "name": "Marcel Zuidwijk",
+ "link": "https://www.zuidwijk.com/"
+ }
+ },
+ {
+ "name": "Slimme lezer",
+ "connection": "Wifi",
+ "meterPowered": true,
+ "usbPowered": true,
+ "link": "https://www.zuidwijk.com/slimme-lezer-smart-reader/",
+ "buy": "https://www.zuidwijk.com/product/slimme-lezer-smart-reader/",
+ "creator": {
+ "name": "Marcel Zuidwijk",
+ "link": "https://www.zuidwijk.com/"
+ }
+ }
+ ],
+ "usb": [
+ {
+ "name": "Slimme meter kabel 1m",
+ "buy": "https://www.sossolutions.nl/slimme-meter-kabel",
+ "creator": {
+ "name": "SOS-Solutions",
+ "link": "https://www.sossolutions.nl/"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/docs/_includes/network.html b/docs/_includes/network.html
new file mode 100644
index 0000000..ac9bd6d
--- /dev/null
+++ b/docs/_includes/network.html
@@ -0,0 +1,18 @@
+
+{% assign network_readers = site.data.readers.socket | sort: 'name' %}
+
\ No newline at end of file
diff --git a/docs/_includes/usb.html b/docs/_includes/usb.html
new file mode 100644
index 0000000..1116e53
--- /dev/null
+++ b/docs/_includes/usb.html
@@ -0,0 +1,16 @@
+
+{% assign usb_readers = site.data.readers.usb | sort: 'name' %}
+
\ No newline at end of file
diff --git a/docs/advanced/decryption.md b/docs/advanced/decryption.md
new file mode 100644
index 0000000..59ec0af
--- /dev/null
+++ b/docs/advanced/decryption.md
@@ -0,0 +1,50 @@
+---
+layout: default
+title: Decryption
+parent: Advanced
+---
+
+# Read encrypted DSMR messages
+
+Smartmeters in Luxemborg are encrypting DSMR messages on the P1 port. You can request the key from your energy supplier, the key will look like `056F9B0CFEDF150E889BEAD52FA7A174` (hexadecimal 16 bytes).
+
+## Decrypt messages
+
+If you want to enable decrypting you only have to set the key, as argument `--enc-key` or as environment variable `SMARTMETER_ENC-KEY` and once you restart it will automatically decrypt and validate the messages.
+
+If you enable the [raw tcp socket](../outputs/socket.html#raw-socket) you can just this application just for decrypting the messages and forwarding them to some other application.
+
+### Encryption specs
+
+For those interested the encryption works as follows. They use `aes-128-gcm` encryption, as found in the [specification](https://smarty.creos.net/wp-content/uploads/P1PortSpecification.pdf) (page 9). And the decryption is done by the [p1-crypt](https://github.com/svrooij/smartmeter2mqtt/blob/beta/src/p1-crypt.ts) file.
+
+Needed data:
+
+| What | Docs | Value |
+|:-------|:-----|:----|
+| **AAD** | Additional data (17 bytes) for validation | `3000112233445566778899AABBCCDDEEFF` hex, default |
+| **IV** | 96 bits total `system-title (64 bits)` + `frame counter (32 bits)` | |
+| **KEY** | (request from energy company) 16 bytes / 128 bits | `056F9B0CFEDF150E889BEAD52FA7A174` hex, fictive key |
+
+Each encrypted message has a sequential number that is specified in the message (the frame counter), this value is then written in the message so you can use it to parse the data.
+
+Each message (converted to hexadecimal representation) looks like this:
+
+```text
+db08abcdefabcdef1234000236300000000a632a0d6906545bb83d844c4f917647c2d03130211b9119b98f49e9b7cda67499445997301e0a0b570951f9f8ebef12dfddc71b1f405f502a86fe85fbafb8fab7b6d0f59b1626527c21d63f60ae1bbd91c20bab4d8c48f5c7eb3443032a02b591874eb75a96ad00e7b2fa815938fbf3842ca8964f1a22acf7312e90020e730591c6a1b85d709ecbd6eacef828c44f07b5f34e219cd09d6047d23c74181303cf8d04ab3790aab2d264a60d971bce3382eb6e3bc4ac0e0b1ebf630244433d5507c9d2674256878e5d0506f1a6c7029bc89d43eefdfd2a765b87e80808a5004e1714750f47b6f2b507ea295503bb6394f1a8fa46c5309fef84258bf1b20f450097ed1aab393c5a68cbe60aa51e1606cb711ddd9e3afb1b23177efa0b4bcc00f6e105ba759c69c3abc598ddaa806fb8e78a5d68bd74ba51520ee8c6054eeb2a0c25a17992b5b043740a8d7d521b316f156ef7202b6b520eb81fb96617079673cef3e955a5791fcc356d38a08514d9ec8cccd46be9de106c882f66bbb53e8291cf99f74122b6caccde878f79cc7bb9b5219d9e2131879bea23d3a616ad82f3fb1be6c9a112039a0a991e2f66d7a8c54e4a2f5d015a79df3fe24623df0b934d234a2a6dbbe0797e00ca69cdd2dd4c36cc7077e64dd88c3a58a46bbea4a6be97b0420569315e783505a573e7071112af1ba30e2c79d06a8773e395a27c3452b7d16f674221be6273a9afe7475fccc282e950098e09552c0762ead82e085d5459f6b737c5dec34f49c49313c500c1751a5055f02d9d
+```
+
+And contains the following data:
+
+| What | Value (sample) | bytes | specs |
+|:-- |:-- |:-- |:-- |
+| Start | `db` | `1` | hex, static |
+| Length of system title | `08` | `1` | hex, static |
+| System title (needed for IV) | `abcdefabcdef1234` | `8` | 8 bytes / 64 bits (or other if length changes) |
+| Number of bytes that follow | `000236` | ? (use delimeter) | 17 + length of data |
+| Delimiter | `30` | `1` | hex, static |
+| Unknown value | `82` | `1` | hex |
+| Frame counter (needed for IV) | `00000a` | `3` | 3 bytes / 24 bits |
+| Data :tada: | `...` | `(see length above)` | computed number of bytes |
+| GCM tag | `9313c500c1751a5055f02d9d` (max) | `12` | 12 bytes / 96 bits |
+
diff --git a/docs/advanced/index.md b/docs/advanced/index.md
new file mode 100644
index 0000000..0c1e196
--- /dev/null
+++ b/docs/advanced/index.md
@@ -0,0 +1,9 @@
+---
+layout: default
+title: Advanced
+nav_order: 8
+has_children: true
+permalink: /advanced
+---
+
+# Advanced stuff
\ No newline at end of file
diff --git a/docs/advanced/solar-input.md b/docs/advanced/solar-input.md
new file mode 100644
index 0000000..5b969f2
--- /dev/null
+++ b/docs/advanced/solar-input.md
@@ -0,0 +1,55 @@
+---
+layout: default
+title: Solar input
+parent: Advanced
+---
+
+# Solar input
+
+To make this app even more accurate, you can als have it load data from your solar panel invertor.
+
+This library can also read current solar production from an inverter supporting **SunSpec**. We use [@svrooij/sunspec](https://github.com/svrooij/sunspec) for this, see other package for more info.
+
+By reading data from the solar panel as well, the properties `houseUsage` and `solarProduction` will become available. The first one is computed as follows `solarProduction + calculatedUsage` if you're producing 1000 watt and the calculatedUsage is -400 (delivering 400 watt), the houseUsage must be 600 watt.
+
+![Screenshot of smartmeter2mqtt web page](../assets/images/screenshot_web-with-solar.png)
+
+## SolarEdge
+
+SolarEdge invertors support the [SunSpec](https://www.solaredge.com/sites/default/files/sunspec-implementation-technical-note.pdf). That means you can turn on modbus over tcp on the inverter. You need to turn it on **and connect within 120 seconds**. After that modbus over tcp will stay on until you manually turn it off.
+
+Turn on reading data from this modbus port by starting this app with the argument `--sunspec-modbus` for the IP and optional `--sunspec-modbus-port` to specify the port (defaults to `502`).
+
+## Webserver
+
+After you enable solar input the webserver page will also show the **Solar Production** and the **House Usage**. And there will be an extra endpoint available `http(s)://ip:port/api/solar` with the following output:
+
+```json
+{
+ "manufacturer": "SolarEdge",
+ "model": "SE3680",
+ "version": "0003.2186",
+ "serial": "xxx",
+ "did": 101,
+ "lifetimeProduction": 11366553,
+ "temperature": 45.26,
+ "status": 4,
+ "acTotalCurrent": 10.8,
+ "acPower": 2523,
+ "acFrequency": 50.03,
+ "apparentPower": 2530.9,
+ "reactivePower": 199.85,
+ "powerFactor": 99.68,
+ "dcCurrent": 6.854,
+ "dcVoltage": 373.7,
+ "dcPower": 2561.4
+}
+```
+
+## Mqtt
+
+The solar data will also be available in the [mqtt](../outputs/mqtt.html) output.
+
+## Developer notes
+
+The [modbus-solar-input](https://github.com/svrooij/smartmeter2mqtt/blob/master/src/modbus-solar-input.ts) is responsible for loading the data from this invertor. Creating an additional solar input should be easy.
diff --git a/docs/assets/images/screenshot_web-with-solar.png b/docs/assets/images/screenshot_web-with-solar.png
new file mode 100644
index 0000000000000000000000000000000000000000..3caf1804603a157a90297b27e4dd2243126b59a9
GIT binary patch
literal 2022327
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