diff --git a/.travis.yml b/.travis.yml index 785a46077..88f101f08 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,6 +44,10 @@ before_script: - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'drop database IF EXISTS dsmrreader;' -u root; fi" - sh -c "if [ '$DB' = 'mysql' ]; then mysqladmin create dsmrreader; fi" + # https://github.com/travis-ci/travis-ci/issues/8331 + - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e \"GRANT ALL PRIVILEGES ON dsmrreader.* TO 'travis'@'%';\" -u root; fi" + - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e \"GRANT ALL PRIVILEGES ON test_dsmrreader.* TO 'travis'@'%';\" -u root; fi" + script: - py.test --pylama --cov --cov-report=term diff --git a/docs/_static/faq/external_pvoutput_settings.png b/docs/_static/faq/external_pvoutput_settings.png new file mode 100644 index 000000000..da7af74ba Binary files /dev/null and b/docs/_static/faq/external_pvoutput_settings.png differ diff --git a/docs/_static/faq/pvoutput_add_status.png b/docs/_static/faq/pvoutput_add_status.png new file mode 100644 index 000000000..a956eaeec Binary files /dev/null and b/docs/_static/faq/pvoutput_add_status.png differ diff --git a/docs/_static/faq/pvoutput_api.png b/docs/_static/faq/pvoutput_api.png new file mode 100644 index 000000000..e7dda3cb8 Binary files /dev/null and b/docs/_static/faq/pvoutput_api.png differ diff --git a/docs/api.rst b/docs/api.rst index a7097fd44..a6055ba30 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -599,6 +599,56 @@ Using **requests** (Python):: ---- +``GET`` - ``consumption/today`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Returns the consumption of the current day so far. + + +URI +~~~ +Full path: ``/api/v2/consumption/today`` + + +Parameters +~~~~~~~~~~ +None. + + +Response +~~~~~~~~ +``HTTP 200`` on success. Body contains the result(s) in JSON format. Any other status code on failure. + + +Example +~~~~~~~ + +**Data structure returned**:: + + { + "day": "2017-09-28", + "electricity1": 0.716, + "electricity1_cost": 0.12, + "electricity1_returned": 0, + "electricity2": 3.403, + "electricity2_cost": 0.63, + "electricity2_returned": 0, + "gas": 0.253, + "gas_cost": 0.15, + "total_cost": 0.9, + } + + +---- + + +``GET`` - ``statistics/hour`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Retrieves any **aggregated hourly statistics**. Please note that these are generated a few hours **after midnight**. + + +---- + + ``GET`` - ``statistics/day`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Retrieves any **aggregated day statistics**. Please note that these are generated a few hours **after midnight**. diff --git a/docs/application.rst b/docs/application.rst index dfeb43dff..b1dccbb36 100644 --- a/docs/application.rst +++ b/docs/application.rst @@ -92,11 +92,18 @@ Public webinterface warning - You should also have Nginx restrict application access when exposing it to the Internet. Simply generate an htpasswd string `using one of the many generators found online `_. +- Paste the htpasswd string in ``/etc/nginx/htpasswd``. + .. warning:: - It's safe to a htpasswd generator, **just make sure to NEVER enter personal credentials** there **used for other applications or personal accounts**. + It's safe to a htpasswd generator, **just make sure to NEVER enter personal credentials** there **used for other applications or personal accounts**. + +.. seealso:: + + Alternatively you can generate a ``htpasswd`` file locally, by installing ``sudo apt-get install apache2-utils`` and running ``sudo htpasswd -c /etc/nginx/htpasswd USERNAME`` (where ``USERNAME`` is your desired username). + + The command will prompt you to enter a password for it. -- Paste the htpasswd string in ``/etc/nginx/htpasswd``. - Open the site's vhost in ``/etc/nginx/sites-enabled/dsmr-webinterface`` and **uncomment** the following lines (remove the ##):: diff --git a/docs/changelog.rst b/docs/changelog.rst index cfbf424c0..1db197440 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -18,6 +18,38 @@ Please make sure you have a fresh **database backup** before upgrading! Upgradin +v1.9.0 - 2017-10-08 +^^^^^^^^^^^^^^^^^^^ + +.. note:: + + This release contains an update for the API framework, which `has a fix for some timezone issues `_. + You may experience different output regarding to datetime formatting when using the API. + + +**Tickets resolved in this release:** + +- [`#9 `_] Data export: PVOutput +- [`#163 `_] Allow separate prices/costs for electricity returned +- [`#337 `_] API mogelijkheid voor ophalen 'dashboard' waarden +- [`#284 `_] Automatische backups geven alleen lege bestanden +- [`#279 `_] Weather report with temperature '-' eventually results in stopped dsmr_backend +- [`#245 `_] Grafiek gasverbruik doet wat vreemd na aantal uur geen nieuwe data +- [`#272 `_] Dashboard - weergave huidig verbruik bij smalle weergave +- [`#273 `_] Docker (by xirixiz) reference in docs +- [`#286 `_] Na gebruik admin-pagina's geen (eenvoudige) mogelijkheid voor terugkeren naar de site +- [`#332 `_] Launch full screen on iOS device when opening from homescreen +- [`#276 `_] Display error compare page on mobile +- [`#288 `_] Add info to FAQ +- [`#320 `_] auto refresh op statussen op statuspagina +- [`#314 `_] Add web-applicatie mogelijkheid ala pihole +- [`#358 `_] Requirements update (September 2017) +- [`#270 `_] Public Webinterface Warning (readthedocs.io) +- [`#231 `_] Contributors update +- [`#300 `_] Upgrade to Django 1.11 LTS + + + v1.8.2 - 2017-08-12 ^^^^^^^^^^^^^^^^^^^ diff --git a/docs/credits.rst b/docs/credits.rst index f692cb5b6..7e3351f95 100644 --- a/docs/credits.rst +++ b/docs/credits.rst @@ -8,23 +8,41 @@ Special thanks for supplying code contributions - `Jeroen Peters `_ -Also many thanks to the contributions of ----------------------------------------- +Also many thanks to the contributions (reporting) of +---------------------------------------------------- Listed in any order, sorted by name. - + +- `balk77 `_ - `Bert-Jan Vos `_ +- `dajappie `_ - `Daniel ter Horst `_ +- `emilkwaaitaal `_ +- `fpompert `_ - `Gert Schaafsma `_ +- `goegol `_ - `Hans-Paul Hemelaar `_ +- `helmo `_ - `Jelte Leijenaar `_ - `Jeroen Tielen `_ - Koen Volleberg +- `MarsWarrior `_ +- `mbnn `_ +- `michielvisser `_ +- `mkruiver `_ - `Paul Vinken `_ +- `perryodk `_ +- `pyrocumulus `_ - `Sander de Leeuw `_ - `Sevickson `_ -- "`WatskeBart `_" - - +- `ThinkPadNL `_ +- `thommy101 `_ +- `TopdRob `_ +- `trbs `_ +- `voipmeister `_ +- `WatskeBart `_ +- `xirixiz `_ + + Software used ------------- Please note and respect their licences as well, if any. Credits to the following software and projects: diff --git a/docs/faq.rst b/docs/faq.rst index 2a2400174..f06b4f415 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -18,6 +18,7 @@ Every once in a while there may be updates. Since ``v1.5`` you can also easily c You can update your application to the latest version by executing **deploy.sh**, located in the root of the project. Make sure to execute it while logged in as the ``dsmr`` user:: + sudo su - dsmr ./deploy.sh It will make sure to check, fetch and apply any changes released. Summary of deployment script steps: @@ -61,7 +62,7 @@ Mindergas.nl: Automated gas meter position export ------------------------------------------------- *How can I link my mindergas.nl account?* -Make sure you have a Mindergas.nl-account or `signup for one `_. +Make sure you have a Mindergas.nl account or `signup for one `_. Now go to "`Meterstand API `_" and click on the button located below **"Authenticatietoken"**. .. image:: _static/faq/mindergas_api.png @@ -77,6 +78,47 @@ Obviously the export only works when there are any gas readings at all and you h Therefor this is not supported by the application. You can however, enter them manually on their website. +PVOutput.org: Automated electricity consumption export +------------------------------------------------------ +*How can I link my PVOutput.org account?* + +Make sure you have a PVOutput.org account, or `signup for an account `_. +You will have to configure your account and PV system(s). For any support doing that, please `see this page `_ for more information. + +In order to link DSMR-reader to your account, please write down the "API Key" and "System ID" from your PVOutput account. You can find them near the bottom of the "Settings" page in PVOutput. + + +.. image:: _static/faq/external_pvoutput_settings.png + :target: _static/faq/external_pvoutput_settings.png + :alt: PVOutput account settings + + +Enter those values in DSMR-reader's admin pages, at "PVOutput: API configuration". Make sure to enter both: + + * API Key + * System ID + + +.. image:: _static/faq/pvoutput_api.png + :target: _static/faq/pvoutput_api.png + :alt: API settings + + +Now navigate to another settings page in DSMR-reader: "PVOutput: "Add Status" configuration". + + * Enable uploading the consumption. + * Choose an interval between the uploads. You can configure this as well on the PVOutput's end, in Device Settings. + * Optionally, choose an upload delay X (in minutes). If set, DSMR-reader will not use data of the past X minutes. + * Optionally, you can choose to enter a **processing delay in minutes** for PVOutput. Please note that PVOutput will only allow this when you have a **"Donation" account** on their website. If you do not have one, they will reject each API call you make, until you disable (clear) this option in DSMR-reader. + + +.. image:: _static/faq/pvoutput_add_status.png + :target: _static/faq/pvoutput_add_status.png + :alt: Add Status settings + +If you configured everything correctly, you should see some addional data in PVOutput listed under "Your Outputs" momentarily. + + Usage notification: Daily usage statistics on your smartphone ------------------------------------------------------------- *Which services for sending notifications are supported?* @@ -159,7 +201,7 @@ Recalculate prices retroactively Statistics for each day are generated once, the day after. However, you can flush your statistics by executing: -``./manage.py dsmr_stats_clear_statistics --ack-to-delete-my-data`` +``./manage.py dsmr_backend_delete_aggregated_data`` The application will delete all statistics and (slowly) regenerate them in the background. Just make sure the source data is still there. diff --git a/docs/installation.rst b/docs/installation.rst index f9c67a091..0d7ffa340 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -8,6 +8,20 @@ Installation .. contents:: :depth: 2 + + + +Docker (alternative) +-------------------- +.. seealso:: + + There is also a Docker version available for DSMR-reader. It's hosted and maintained by a third party. More information can be found here: + + Github: https://github.com/xirixiz/dsmr-reader-docker + + Docker hub: https://hub.docker.com/r/xirixiz/dsmr-reader-docker/ + +Not interested in Docker? Follow the instructions in the chapters below if you wish to install this project the regular way. 1. Database backend (PostgreSQL) diff --git a/docs/locale/nl/LC_MESSAGES/api.mo b/docs/locale/nl/LC_MESSAGES/api.mo index 6848ea07d..23ce3939e 100644 Binary files a/docs/locale/nl/LC_MESSAGES/api.mo and b/docs/locale/nl/LC_MESSAGES/api.mo differ diff --git a/docs/locale/nl/LC_MESSAGES/api.po b/docs/locale/nl/LC_MESSAGES/api.po index 291873b94..fdfa3407f 100644 --- a/docs/locale/nl/LC_MESSAGES/api.po +++ b/docs/locale/nl/LC_MESSAGES/api.po @@ -8,8 +8,6 @@ msgid "" msgstr "" "Project-Id-Version: DSMR Reader v1.x\n" "Report-Msgid-Bugs-To: Dennis Siemensma \n" -"POT-Creation-Date: 2017-06-13 21:18+0200\n" -"PO-Revision-Date: 2017-06-13 21:21+0200\n" "Last-Translator: Dennis Siemensma \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -47,8 +45,8 @@ msgstr "" "Standaard is de API in de applicatie uitgeschakeld. Je kunt deze inschakelen " "in het configuratiescherm of beheerderpaneel." -#: ../../api.rst:18 ../../api.rst:79 ../../api.rst:332 ../../api.rst:629 -#: ../../api.rst:689 +#: ../../api.rst:18 ../../api.rst:79 ../../api.rst:332 ../../api.rst:623 +#: ../../api.rst:679 ../../api.rst:739 msgid "Example" msgstr "Voorbeeld" @@ -113,7 +111,7 @@ msgstr "" "``HTTP 200``, wanneer succesvol." #: ../../api.rst:63 ../../api.rst:301 ../../api.rst:406 ../../api.rst:608 -#: ../../api.rst:668 +#: ../../api.rst:658 ../../api.rst:718 msgid "URI" msgstr "URI" @@ -122,7 +120,7 @@ msgid "Full path: ``/api/v1/datalogger/dsmrreading``" msgstr "Volledig pad: ``/api/v1/datalogger/dsmrreading``" #: ../../api.rst:68 ../../api.rst:306 ../../api.rst:411 ../../api.rst:613 -#: ../../api.rst:673 +#: ../../api.rst:663 ../../api.rst:723 msgid "Parameters" msgstr "Parameters" @@ -134,8 +132,8 @@ msgstr "" "``telegram`` (*string*) - De ruwe telegram tekenreeks inclusief alle " "regeleindes ``\\n`` en 'carriage returns' ``\\r``." -#: ../../api.rst:74 ../../api.rst:327 ../../api.rst:422 ../../api.rst:624 -#: ../../api.rst:684 +#: ../../api.rst:74 ../../api.rst:327 ../../api.rst:422 ../../api.rst:618 +#: ../../api.rst:674 ../../api.rst:734 msgid "Response" msgstr "Respons (van de server)" @@ -397,7 +395,7 @@ msgstr "" "Haalt opgeslagen metingen op. De metingen komen ofwel voort uit telegrammen of " "zijn handmatig aangemaakt via deze API." -#: ../../api.rst:412 ../../api.rst:614 ../../api.rst:674 +#: ../../api.rst:412 ../../api.rst:664 ../../api.rst:724 msgid "All parameters are optional." msgstr "Alle parameters zijn optioneel." @@ -426,7 +424,7 @@ msgstr "" "Laat de parameter weg of gebruik ``timestamp`` om **oplopend** te sorteren " "(standaard)." -#: ../../api.rst:417 ../../api.rst:619 ../../api.rst:679 +#: ../../api.rst:417 ../../api.rst:669 ../../api.rst:729 msgid "" "``offset`` (*integer*) - When iterating large resultsets, the offset " "determines the starting point." @@ -434,7 +432,7 @@ msgstr "" "``offset`` (*integer*) - Bij het doorlopen van vele resultaten kun je hiermee " "het startpunt bepalen." -#: ../../api.rst:418 ../../api.rst:620 ../../api.rst:680 +#: ../../api.rst:418 ../../api.rst:670 ../../api.rst:730 msgid "" "``limit`` (*integer*) - Limits the resultset size returned. Omit for " "maintaining the default limit (**25**)." @@ -442,7 +440,7 @@ msgstr "" "``limit`` (*integer*) - Beperkt het aantal resultaten dat teruggegeven wordt. " "Laat deze parameter weg voor de standaardwaarde (**25**)." -#: ../../api.rst:423 ../../api.rst:625 ../../api.rst:685 +#: ../../api.rst:423 ../../api.rst:619 ../../api.rst:675 ../../api.rst:735 msgid "" "``HTTP 200`` on success. Body contains the result(s) in JSON format. Any other " "status code on failure." @@ -499,10 +497,42 @@ msgstr "" "'Z' (Zulu tijdzone)." #: ../../api.rst:603 +msgid "``GET`` - ``consumption/today``" +msgstr "``GET`` - ``consumption/today``" + +#: ../../api.rst:604 +msgid "Returns the consumption of the current day so far." +msgstr "Geeft het verbruik (tot nu toe) van de huidige dag terug." + +#: ../../api.rst:609 +msgid "Full path: ``/api/v2/consumption/today``" +msgstr "Volledig pad:``/api/v2/consumption/today``" + +#: ../../api.rst:614 +msgid "None." +msgstr "Geen." + +#: ../../api.rst:625 ../../api.rst:682 ../../api.rst:742 +msgid "**Data structure returned**::" +msgstr "**Datastructuur**::" + +#: ../../api.rst:645 ../../api.rst:713 +msgid "``GET`` - ``statistics/hour``" +msgstr "``GET`` - ``statistics/hour``" + +#: ../../api.rst:646 ../../api.rst:714 +msgid "" +"Retrieves any **aggregated hourly statistics**. Please note that these are " +"generated a few hours **after midnight**." +msgstr "" +"Haalt **geaggregeerde uurstatistieken** op. Deze worden elke dag een paar uur " +"**ná middernacht** gegenereerd." + +#: ../../api.rst:653 msgid "``GET`` - ``statistics/day``" msgstr "``GET`` - ``statistics/day``" -#: ../../api.rst:604 +#: ../../api.rst:654 msgid "" "Retrieves any **aggregated day statistics**. Please note that these are " "generated a few hours **after midnight**." @@ -510,11 +540,11 @@ msgstr "" "Haalt **geaggregeerde dagstatistieken** op. Deze worden elke dag een paar uur " "**ná middernacht** gegenereerd." -#: ../../api.rst:609 +#: ../../api.rst:659 msgid "Full path: ``/api/v2/statistics/day``" msgstr "Volledig pad: ``/api/v2/statistics/day``" -#: ../../api.rst:616 +#: ../../api.rst:666 msgid "" "``day__gte`` (*date*) - Limits the result to any statistics having their date " "**higher or equal** to this parameter." @@ -522,7 +552,7 @@ msgstr "" "``day__gte`` (*date*) - Beperkt het resultaat tot alle datums die **hoger of " "gelijk zijn aan** deze parameter." -#: ../../api.rst:617 +#: ../../api.rst:667 msgid "" "``day__lte`` (*date*) - Limits the result to any statistics having their date " "**lower or equal** to this parameter." @@ -530,7 +560,7 @@ msgstr "" "``day__lte`` (*date*) - Beperkt het resultaat tot alle datums die **lager of " "gelijk zijn aan** deze parameter." -#: ../../api.rst:618 +#: ../../api.rst:668 msgid "" "``ordering`` (*string*) - Use ``-day`` to sort **descending**. Omit or use " "``day`` to sort **ascending** (default)." @@ -538,7 +568,7 @@ msgstr "" "``ordering`` (*string*) - Gebruik ``-day`` om **aflopend** te sorteren. Laat " "de parameter weg of gebruik ``day`` om **oplopend** te sorteren (standaard)." -#: ../../api.rst:630 ../../api.rst:690 +#: ../../api.rst:680 ../../api.rst:740 msgid "" "All the :ref:`generic DSMRREADING examples ` apply " "here as well, since only the ``timestamp`` field differs." @@ -546,27 +576,11 @@ msgstr "" "Alle :ref:`generieke DSMRREADING voorbeelden ` zijn " "hier tevens van toepassing, gezien alleen het ``timestamp`` field afwijkt." -#: ../../api.rst:632 ../../api.rst:692 -msgid "**Data structure returned**::" -msgstr "**Datastructuur**::" - -#: ../../api.rst:663 -msgid "``GET`` - ``statistics/hour``" -msgstr "``GET`` - ``statistics/hour``" - -#: ../../api.rst:664 -msgid "" -"Retrieves any **aggregated hourly statistics**. Please note that these are " -"generated a few hours **after midnight**." -msgstr "" -"Haalt **geaggregeerde uurstatistieken** op. Deze worden elke dag een paar uur " -"**ná middernacht** gegenereerd." - -#: ../../api.rst:669 +#: ../../api.rst:719 msgid "Full path: ``/api/v2/statistics/hour``" msgstr "Volledig pad: ``/api/v2/statistics/hour``" -#: ../../api.rst:676 +#: ../../api.rst:726 msgid "" "``hour_start__gte`` (*datetime*) - Limits the result to any statistics having " "their datetime (hour start) **higher or equal** to this parameter." @@ -574,7 +588,7 @@ msgstr "" "``hour_start__gte`` (*datetime*) - Beperkt het resultaat tot alle " "(datum)tijdstippen die **hoger of gelijk zijn aan** deze parameter." -#: ../../api.rst:677 +#: ../../api.rst:727 msgid "" "``hour_start__lte`` (*datetime*) - Limits the result to any statistics having " "their datetime (hour start) **lower or equal** to this parameter." @@ -582,7 +596,7 @@ msgstr "" "``hour_start__lte`` (*datetime*) - Beperkt het resultaat tot alle " "(datum)tijdstippen die **lager of gelijk zijn aan** deze parameter." -#: ../../api.rst:678 +#: ../../api.rst:728 msgid "" "``ordering`` (*string*) - Use ``-hour_start`` to sort **descending**. Omit or " "use ``hour_start`` to sort **ascending** (default)." diff --git a/docs/locale/nl/LC_MESSAGES/application.mo b/docs/locale/nl/LC_MESSAGES/application.mo index 9e68efb27..cd7134ea3 100644 Binary files a/docs/locale/nl/LC_MESSAGES/application.mo and b/docs/locale/nl/LC_MESSAGES/application.mo differ diff --git a/docs/locale/nl/LC_MESSAGES/application.po b/docs/locale/nl/LC_MESSAGES/application.po index 6bf85fb52..901ea0093 100644 --- a/docs/locale/nl/LC_MESSAGES/application.po +++ b/docs/locale/nl/LC_MESSAGES/application.po @@ -1,16 +1,15 @@ - msgid "" msgstr "" "Project-Id-Version: DSMR Reader v1.x\n" "Report-Msgid-Bugs-To: Dennis Siemensma \n" -"POT-Creation-Date: 2017-05-02 21:26+0200\n" -"PO-Revision-Date: 2017-01-03 20:41+0100\n" "Last-Translator: Dennis Siemensma \n" "Language-Team: Dennis Siemensma \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.3.4\n" +"Language: nl\n" +"X-Generator: Poedit 1.8.7.1\n" #: ../../application.rst:2 msgid "Using the application" @@ -22,20 +21,19 @@ msgstr "DSMR 2.x (oude meters)" #: ../../application.rst:14 msgid "" -"Note: The application's default DSMR version used is 4.x. This version is" -" also the **default** for any recent smart meters placed at your home." +"Note: The application's default DSMR version used is 4.x. This version is also " +"the **default** for any recent smart meters placed at your home." msgstr "" -"N.B.: De standaard DSMR-versie die de applicatie gebruikt is DSMR 4.x. " -"Dit is namelijk de **standaardversie** voor nieuwe/recent geplaatste " -"slimme meters." +"N.B.: De standaard DSMR-versie die de applicatie gebruikt is DSMR 4.x. Dit is " +"namelijk de **standaardversie** voor nieuwe/recent geplaatste slimme meters." #: ../../application.rst:18 msgid "" -"Make sure to alter this setting in the backend's configuration page to " -"DSMR 2.x when required!" +"Make sure to alter this setting in the backend's configuration page to DSMR 2.x " +"when required!" msgstr "" -"Wanneer je een meter met DSMR 2.x hebt, zul je deze in het " -"beheerderpaneel onder ``dataloggerconfiguratie`` moet instellen." +"Wanneer je een meter met DSMR 2.x hebt, zul je deze in het beheerderpaneel " +"onder ``dataloggerconfiguratie`` moet instellen." #: ../../application.rst:22 msgid "Viewing the application" @@ -43,34 +41,32 @@ msgstr "Bekijk applicatie" #: ../../application.rst:23 msgid "" -"Now it's time to view the application in your browser to check whether " -"the GUI works as well. Just enter the ip address or hostname of your " -"RaspberryPi in your browser." +"Now it's time to view the application in your browser to check whether the GUI " +"works as well. Just enter the ip address or hostname of your RaspberryPi in " +"your browser." msgstr "" -"Dit is het moment om de applicatie te bekijken in je browser om te zien " -"of alles naar behoren werkt. Vul het IP-adres van je RaspberryPi in je " -"browser." +"Dit is het moment om de applicatie te bekijken in je browser om te zien of " +"alles naar behoren werkt. Vul het IP-adres van je RaspberryPi in je browser." #: ../../application.rst:25 msgid "" -"Did you install using a monitor attached to the RaspberryPi and you don't" -" know what address your device has? Just type ``ifconfig | grep addr`` " -"and it should display an ip address, for example::" +"Did you install using a monitor attached to the RaspberryPi and you don't know " +"what address your device has? Just type ``ifconfig | grep addr`` and it should " +"display an ip address, for example::" msgstr "" -"Heb je de applicatie geinstalleerd met een monitor aan je RaspberryPi en " -"weet je het IP-adres niet? Typ in dat geval het volgende in en je krijgt " -"het IP-adres te zien: ``ifconfig | grep addr``" +"Heb je de applicatie geinstalleerd met een monitor aan je RaspberryPi en weet " +"je het IP-adres niet? Typ in dat geval het volgende in en je krijgt het IP-" +"adres te zien: ``ifconfig | grep addr``" #: ../../application.rst:31 msgid "" -"In this example the ip address is ``192.168.178.150``. If possible, you " -"should assign a static ip address to your device in your router. This " -"will make sure you will always be able to find the application at the " -"same location." +"In this example the ip address is ``192.168.178.150``. If possible, you should " +"assign a static ip address to your device in your router. This will make sure " +"you will always be able to find the application at the same location." msgstr "" -"In dit voorbeeld is het IP-adres ``192.168.178.150``. Het is aan te raden" -" om je apparaat een vast IP-adres te geven in je router. Dit zorgt ervoor" -" dat je de applicatie altijd op dezelfde locatie kan terugvinden." +"In dit voorbeeld is het IP-adres ``192.168.178.150``. Het is aan te raden om je " +"apparaat een vast IP-adres te geven in je router. Dit zorgt ervoor dat je de " +"applicatie altijd op dezelfde locatie kan terugvinden." #: ../../application.rst:35 msgid "Reboot test" @@ -78,14 +74,14 @@ msgstr "Herstart-test" #: ../../application.rst:36 msgid "" -"You surely want to ``reboot`` your device and check whether everything " -"comes up automatically again with ``sudo supervisorctl status``. This " -"will make sure your data logger 'survives' any power surges." +"You surely want to ``reboot`` your device and check whether everything comes up " +"automatically again with ``sudo supervisorctl status``. This will make sure " +"your data logger 'survives' any power surges." msgstr "" -"Herstart het apparaat met ``reboot`` om te testen of alles automatisch " -"opstart. Je zou na de herstart alles moeten zien draaien via ``sudo " -"supervisorctl status``. Dit zorgt ervoor dat je datalogger eventuele " -"stroomstoringen overleeft (of wanneer je zelf de stroom eraf haalt)." +"Herstart het apparaat met ``reboot`` om te testen of alles automatisch opstart. " +"Je zou na de herstart alles moeten zien draaien via ``sudo supervisorctl " +"status``. Dit zorgt ervoor dat je datalogger eventuele stroomstoringen " +"overleeft (of wanneer je zelf de stroom eraf haalt)." #: ../../application.rst:40 msgid "Data preservation & backups" @@ -93,23 +89,23 @@ msgstr "Databehoud & backups" #: ../../application.rst:44 msgid "" -"You **should (or must)** make sure to periodically BACKUP your data! It's" -" one of the most common mistakes to skip or ignore this. Actually, it " -"happened to myself quite soon after I started, as I somehow managed to " -"corrupt my SD storage card, losing all my data on it. It luckily happened" -" only a month after running my own readings, but imagine all the data " -"you'll lose when it will contain readings taken over several years." +"You **should (or must)** make sure to periodically BACKUP your data! It's one " +"of the most common mistakes to skip or ignore this. Actually, it happened to " +"myself quite soon after I started, as I somehow managed to corrupt my SD " +"storage card, losing all my data on it. It luckily happened only a month after " +"running my own readings, but imagine all the data you'll lose when it will " +"contain readings taken over several years." msgstr "" -"Zorg ervoor dat je regelmatig **back-ups maakt**! Het is een " -"veelvoorkomende fout om dat niet te doen en zelf liep ik er ook al vrij " -"snel tegenaan. Gelukkig gebeurde dat vrij vroeg in het traject en was ik " -"'slechts' een maand aan gegevens kwijt. Stel je voor dat je jaren met " -"historische data kwijtraakt, zou zonde zijn!" +"Zorg ervoor dat je regelmatig **back-ups maakt**! Het is een veelvoorkomende " +"fout om dat niet te doen en zelf liep ik er ook al vrij snel tegenaan. Gelukkig " +"gebeurde dat vrij vroeg in het traject en was ik 'slechts' een maand aan " +"gegevens kwijt. Stel je voor dat je jaren met historische data kwijtraakt, zou " +"zonde zijn!" #: ../../application.rst:48 msgid "" -"The SD card is by far **the weakest link** of this setup and **will** " -"fail you some day." +"The SD card is by far **the weakest link** of this setup and **will** fail you " +"some day." msgstr "" "De SD-kaart is verreweg **de zwakste schakel** in dit geheel and **gaat " "gegarandeerd kapot** op een dag." @@ -120,88 +116,86 @@ msgstr "De applicatie maakt standaard elke nacht een back-up." #: ../../application.rst:52 msgid "" -"You can find them in the ``backups`` folder of the application. They " -"either have a ``.sql`` or ``.gz`` extension, depending on whether " -"compression is enabled in the backup configuration." +"You can find them in the ``backups`` folder of the application. They either " +"have a ``.sql`` or ``.gz`` extension, depending on whether compression is " +"enabled in the backup configuration." msgstr "" -"Je kunt ze terugvinden in de ``backups`` map van de applicatie. Ze zijn " -"te herkennen aan een ``.sql`` of ``.gz`` extensie, afhankelijk de gekozen" -" compressie-instellingen in de back-upconfiguratie." +"Je kunt ze terugvinden in de ``backups`` map van de applicatie. Ze zijn te " +"herkennen aan een ``.sql`` of ``.gz`` extensie, afhankelijk de gekozen " +"compressie-instellingen in de back-upconfiguratie." #: ../../application.rst:53 msgid "" -"However, as the data is still stored **locally** on your 'vulnerable' SD " -"card, you must export it off your RaspberryPi as well." +"However, as the data is still stored **locally** on your 'vulnerable' SD card, " +"you must export it off your RaspberryPi as well." msgstr "" -"Echter, hiermee staan de gegevens nog steeds **lokaal** op je " -"'kwestsbare' SD-kaart. Je zult die data dus moeten kopieren naar een " -"locatie buiten je RaspberryPi om." +"Echter, hiermee staan de gegevens nog steeds **lokaal** op je 'kwestsbare' SD-" +"kaart. Je zult die data dus moeten kopieren naar een locatie buiten je " +"RaspberryPi om." #: ../../application.rst:55 msgid "" -"There is an builtin option to have backups synced to your **Dropbox**, " -"*without exposing your Dropbox account and your private files in it*." +"There is an builtin option to have backups synced to your **Dropbox**, *without " +"exposing your Dropbox account and your private files in it*." msgstr "" -"Er is ingebouwde ondersteuning om back-ups naar je **Dropbox**-account " -"te uploaden. *Zonder dat de applicatie toegang tot je (privé) bestanden " -"in je Dropbox-account heeft*." +"Er is ingebouwde ondersteuning om back-ups naar je **Dropbox**-account te " +"uploaden. *Zonder dat de applicatie toegang tot je (privé) bestanden in je " +"Dropbox-account heeft*." #: ../../application.rst:57 msgid "" -"Please either use this service or manage offloading backups on your own " -"(see below)." +"Please either use this service or manage offloading backups on your own (see " +"below)." msgstr "" -"Zorg ervoor dat je ofwel deze feature gebruikt ofwel zelf back-ups maakt " -"en ze regelmatig ergens heen kopieert (zie hieronder)." +"Zorg ervoor dat je ofwel deze feature gebruikt ofwel zelf back-ups maakt en ze " +"regelmatig ergens heen kopieert (zie hieronder)." #: ../../application.rst:59 msgid "You may also decide to run backups outside the application." msgstr "" -"Je kunt er tevens voor kiezen om zelf backups buiten de applicatie om te " -"maken." +"Je kunt er tevens voor kiezen om zelf backups buiten de applicatie om te maken." #: ../../application.rst:61 msgid "" -"There are example backup scripts available in " -"``dsmrreader/provisioning/postgresql/psql-backup.sh`` for **PostgreSQL**," -" which I dump to a separately USB stick mounted on my RaspberryPi." +"There are example backup scripts available in ``dsmrreader/provisioning/" +"postgresql/psql-backup.sh`` for **PostgreSQL**, which I dump to a separately " +"USB stick mounted on my RaspberryPi." msgstr "" -"Er zijn voorbeeldscripts voor back-ups beschikbaar in " -"``dsmrreader/provisioning/postgresql/psql-backup.sh`` voor " -"**PostgreSQL**. Deze gebruik ik zelf om handmatig een back-up te maken " -"naar een USB-stick die aan mijn RaspberryPi hangt." +"Er zijn voorbeeldscripts voor back-ups beschikbaar in ``dsmrreader/provisioning/" +"postgresql/psql-backup.sh`` voor **PostgreSQL**. Deze gebruik ik zelf om " +"handmatig een back-up te maken naar een USB-stick die aan mijn RaspberryPi " +"hangt." #: ../../application.rst:63 msgid "" -"For **MySQL/MariaDB** you can use ``dsmrreader/provisioning/mysql/mysql-" -"backup.sh``." +"For **MySQL/MariaDB** you can use ``dsmrreader/provisioning/mysql/mysql-backup." +"sh``." msgstr "" -"Voor **MySQL/MariaDB** kun je dit script gebruiken: " -"``dsmrreader/provisioning/mysql/mysql-backup.sh``." +"Voor **MySQL/MariaDB** kun je dit script gebruiken: ``dsmrreader/provisioning/" +"mysql/mysql-backup.sh``." #: ../../application.rst:65 msgid "" -"Make sure to schedule the backup scripts as cronjob and also verify that " -"it actually works, by running ``run-parts -v /etc/cron.daily``." +"Make sure to schedule the backup scripts as cronjob and also verify that it " +"actually works, by running ``run-parts -v /etc/cron.daily``." msgstr "" -"Zorg ervoor dat je de back-ups via een 'daily cronjob' hebt ingepland en " -"test dat door het volgende uit te voeren: ``run-parts -v " -"/etc/cron.daily``." +"Zorg ervoor dat je de back-ups via een 'daily cronjob' hebt ingepland en test " +"dat door het volgende uit te voeren: ``run-parts -v /etc/cron.daily``." #: ../../application.rst:67 msgid "" -"Also, check your free disk space once in a while. I will implement " -"automatic cleanup settings later, allowing you to choose your own " -"retention (for all the source readings)." +"Also, check your free disk space once in a while. I will implement automatic " +"cleanup settings later, allowing you to choose your own retention (for all the " +"source readings)." msgstr "" -"Kijk ook af en toe of je nog voldoende schijfruimte hebt. Later zal ik de" -" mogelijkheid toevoegen om oude metingen (niet de dagtotalen) te " -"verwijderen na een X-periode." +"Kijk ook af en toe of je nog voldoende schijfruimte hebt. Later zal ik de " +"mogelijkheid toevoegen om oude metingen (niet de dagtotalen) te verwijderen na " +"een X-periode." #: ../../application.rst:69 msgid "" -"Everything OK? Congratulations, this was the hardest part and now the fun" -" begins by monitoring your energy consumption." +"Everything OK? Congratulations, this was the hardest part and now the fun " +"begins by monitoring your energy consumption." msgstr "" "Alles gelukt? Gefeliciteerd! Dit was het lastigste gedeelte en nu kun je " "eindelijk gebruikmaken van de applicatie en je energieverbruik meten." @@ -220,90 +214,102 @@ msgstr "Waarschuwing voor publiekelijke toegang" #: ../../application.rst:85 msgid "" -"If you expose your application to the outside world or a public network, " -"you might want to take additional steps:" +"If you expose your application to the outside world or a public network, you " +"might want to take additional steps:" msgstr "" "Wanneer je de applicatie koppelt aan het Internet wil je sowieso extra " "maatregelen nemen:" #: ../../application.rst:87 msgid "" -"Please make sure to **alter** the ``SECRET_KEY`` setting in your " -"``dsmrreader/settings.py``." +"Please make sure to **alter** the ``SECRET_KEY`` setting in your ``dsmrreader/" +"settings.py``." msgstr "" "Zorg ervoor dat je de instelling ``SECRET_KEY`` wijzigt in het bestand " "``dsmrreader/settings.py``." #: ../../application.rst:89 msgid "" -"Don't forget to run ``./post-deploy.sh`` in the project's root, which " -"will force the application to gracefully reload itself and apply the new " -"settings instantly." +"Don't forget to run ``./post-deploy.sh`` in the project's root, which will " +"force the application to gracefully reload itself and apply the new settings " +"instantly." msgstr "" -"Vergeet vooral niet om daarna ``./post-deploy.sh`` uit te voeren (staat " -"in hoogste map van project), die ervoor zorgt dat de hele applicatie " -"zichzelf herlaadt en daarmee de nieuwe instellingen per direct gebruikt." +"Vergeet vooral niet om daarna ``./post-deploy.sh`` uit te voeren (staat in " +"hoogste map van project), die ervoor zorgt dat de hele applicatie zichzelf " +"herlaadt en daarmee de nieuwe instellingen per direct gebruikt." #: ../../application.rst:91 msgid "" -"Install a firewall, such as ``ufw`` `UncomplicatedFirewall " -"`_ and restrict traffic to" -" port ``22`` (only for yourself) and port ``80``." +"Install a firewall, such as ``ufw`` `UncomplicatedFirewall `_ and restrict traffic to port ``22`` (only for " +"yourself) and port ``80``." msgstr "" -"Installeer een firewall, zoals ``ufw`` (`UncomplicatedFirewall " -"`_) and beperk al het " -"toegestane verkeer tot poort ``22`` (puur voor jezelf) en poort ``80``." +"Installeer een firewall, zoals ``ufw`` (`UncomplicatedFirewall `_) and beperk al het toegestane verkeer tot " +"poort ``22`` (puur voor jezelf) en poort ``80``." #: ../../application.rst:93 msgid "" -"You should also have Nginx restrict application access when exposing it " -"to the Internet. Simply generate an htpasswd string `using one of the " -"many generators found online `_." +"You should also have Nginx restrict application access when exposing it to the " +"Internet. Simply generate an htpasswd string `using one of the many generators " +"found online `_." msgstr "" -"Je zou in Nginx de toegang moeten beperken door altijd inloggegevens te " -"vragen voor het bekijken van de applicatie. Genereer een zogenaamde " -"htpasswd-tekenreeks via `een van de vele websites die dit voor je kunnen " -"doen `_." +"Je zou in Nginx de toegang moeten beperken door altijd inloggegevens te vragen " +"voor het bekijken van de applicatie. Genereer een zogenaamde htpasswd-" +"tekenreeks via `een van de vele websites die dit voor je kunnen doen `_." -#: ../../application.rst:97 +#: ../../application.rst:95 +msgid "Paste the htpasswd string in ``/etc/nginx/htpasswd``." +msgstr "Plak de htpasswd-tekenreeks in het bestand ``/etc/nginx/htpasswd``." + +#: ../../application.rst:99 msgid "" -"It's safe to a htpasswd generator, **just make sure to NEVER enter " -"personal credentials** there **used for other applications or personal " -"accounts**." +"It's safe to a htpasswd generator, **just make sure to NEVER enter personal " +"credentials** there **used for other applications or personal accounts**." msgstr "" "Je kunt een htpassw-generator veilig gebruiken **zolang je maar NOOIT " -"persoonlijke informatie of gegevens invoert die je ook op andere websites" -" gebruikt**!" +"persoonlijke informatie of gegevens invoert die je ook op andere websites " +"gebruikt**!" -#: ../../application.rst:99 -msgid "Paste the htpasswd string in ``/etc/nginx/htpasswd``." -msgstr "Plak de htpasswd-tekenreeks in het bestand ``/etc/nginx/htpasswd``." +#: ../../application.rst:103 +msgid "" +"Alternatively you can generate a ``htpasswd`` file locally, by installing " +"``sudo apt-get install apache2-utils`` and running ``sudo htpasswd -c /etc/" +"nginx/htpasswd USERNAME`` (where ``USERNAME`` is your desired username)." +msgstr "" +"Als alternatief kun je ook lokaal een ``htpasswd`` bestand genereren, door " +"``sudo apt-get install apache2-utils`` te installeren en vervolgens het command " +"``sudo htpasswd -c /etc/nginx/htpasswd USERNAME`` uit te voeren (waarbij " +"``USERNAME`` je gewenste gebruikersnaam is)." + +#: ../../application.rst:105 +msgid "The command will prompt you to enter a password for it." +msgstr "Het command vraagt vervolgens om een wachtwoord voor het account." -#: ../../application.rst:101 +#: ../../application.rst:108 msgid "" -"Open the site's vhost in ``/etc/nginx/sites-enabled/dsmr-webinterface`` " -"and **uncomment** the following lines (remove the ##)::" +"Open the site's vhost in ``/etc/nginx/sites-enabled/dsmr-webinterface`` and " +"**uncomment** the following lines (remove the ##)::" msgstr "" -"Open de website's vhost in ``/etc/nginx/sites-enabled/dsmr-webinterface``" -" en schakel de volgende regels in (verwijder de ## tekens)::" +"Open de website's vhost in ``/etc/nginx/sites-enabled/dsmr-webinterface`` en " +"schakel de volgende regels in (verwijder de ## tekens)::" -#: ../../application.rst:106 +#: ../../application.rst:113 msgid "Now make sure you didn't insert any typo's by running::" msgstr "Zorg ervoor dat je geen typefouten hebt gemaakt door te controleren met::" -#: ../../application.rst:110 +#: ../../application.rst:117 msgid "And reload with::" msgstr "En herlaad met::" -#: ../../application.rst:114 +#: ../../application.rst:121 msgid "" "You should be prompted for login credentials the next time your browser " -"accesses the application. For more information regarding this topic, see " -"the `Nginx docs `_." +"accesses the application. For more information regarding this topic, see the " +"`Nginx docs `_." msgstr "" -"Als het goed is krijg je de volgende keer dat je de applicatie bekijkt " -"een pop-up te zien, waarin je gevraagd wordt om in te loggen. Voor meer " -"informatie over dit onderwerp `zie de Nginx documentatie " -"`_." - +"Als het goed is krijg je de volgende keer dat je de applicatie bekijkt een pop-" +"up te zien, waarin je gevraagd wordt om in te loggen. Voor meer informatie over " +"dit onderwerp `zie de Nginx documentatie `_." diff --git a/docs/locale/nl/LC_MESSAGES/changelog.mo b/docs/locale/nl/LC_MESSAGES/changelog.mo index 1a2a822fe..2cea6775f 100644 Binary files a/docs/locale/nl/LC_MESSAGES/changelog.mo and b/docs/locale/nl/LC_MESSAGES/changelog.mo differ diff --git a/docs/locale/nl/LC_MESSAGES/changelog.po b/docs/locale/nl/LC_MESSAGES/changelog.po index eda5b5a7f..3b70212f1 100644 --- a/docs/locale/nl/LC_MESSAGES/changelog.po +++ b/docs/locale/nl/LC_MESSAGES/changelog.po @@ -8,8 +8,6 @@ msgid "" msgstr "" "Project-Id-Version: DSMR Reader v1.x\n" "Report-Msgid-Bugs-To: Dennis Siemensma \n" -"POT-Creation-Date: 2017-06-13 21:18+0200\n" -"PO-Revision-Date: 2017-01-21 14:17+0100\n" "Last-Translator: Dennis Siemensma \n" "Language-Team: Dennis Siemensma \n" "MIME-Version: 1.0\n" @@ -55,21 +53,244 @@ msgstr "" "fixes-new-features>`_." #: ../../changelog.rst:22 -msgid "v1.8.0 - 2017-06-14" +msgid "v1.9.0 - 2017-10-29" msgstr "" -#: ../../changelog.rst:24 ../../changelog.rst:46 ../../changelog.rst:55 -#: ../../changelog.rst:65 ../../changelog.rst:87 ../../changelog.rst:105 -#: ../../changelog.rst:114 ../../changelog.rst:124 ../../changelog.rst:133 -#: ../../changelog.rst:143 ../../changelog.rst:152 ../../changelog.rst:170 -#: ../../changelog.rst:189 ../../changelog.rst:214 ../../changelog.rst:227 -#: ../../changelog.rst:242 ../../changelog.rst:250 ../../changelog.rst:261 -#: ../../changelog.rst:273 ../../changelog.rst:290 ../../changelog.rst:298 -#: ../../changelog.rst:306 ../../changelog.rst:320 +#: ../../changelog.rst:26 +msgid "" +"This release contains an update for the API framework, which `has a fix " +"for some timezone issues `_. You may experience different output regarding " +"to datetime formatting when using the API." +msgstr "" + +#: ../../changelog.rst:30 ../../changelog.rst:56 ../../changelog.rst:65 +#: ../../changelog.rst:74 ../../changelog.rst:97 ../../changelog.rst:106 +#: ../../changelog.rst:116 ../../changelog.rst:138 ../../changelog.rst:156 +#: ../../changelog.rst:165 ../../changelog.rst:175 ../../changelog.rst:184 +#: ../../changelog.rst:194 ../../changelog.rst:203 ../../changelog.rst:221 +#: ../../changelog.rst:240 ../../changelog.rst:265 ../../changelog.rst:278 +#: ../../changelog.rst:293 ../../changelog.rst:301 ../../changelog.rst:312 +#: ../../changelog.rst:324 ../../changelog.rst:341 ../../changelog.rst:349 +#: ../../changelog.rst:357 ../../changelog.rst:371 msgid "**Tickets resolved in this release:**" msgstr "**Tickets die opgelost zijn in deze release:**" -#: ../../changelog.rst:26 +#: ../../changelog.rst:32 +#, fuzzy +msgid "" +"[`#9 `_] Data " +"export: PVOutput" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:33 +#, fuzzy +msgid "" +"[`#163 `_] " +"Allow separate prices/costs for electricity returned" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:34 +#, fuzzy +msgid "" +"[`#337 `_] API" +" mogelijkheid voor ophalen 'dashboard' waarden" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:35 +#, fuzzy +msgid "" +"[`#284 `_] " +"Automatische backups geven alleen lege bestanden" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:36 +#, fuzzy +msgid "" +"[`#279 `_] " +"Weather report with temperature '-' eventually results in stopped " +"dsmr_backend" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:37 +#, fuzzy +msgid "" +"[`#245 `_] " +"Grafiek gasverbruik doet wat vreemd na aantal uur geen nieuwe data" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:38 +#, fuzzy +msgid "" +"[`#272 `_] " +"Dashboard - weergave huidig verbruik bij smalle weergave" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:39 +#, fuzzy +msgid "" +"[`#273 `_] " +"Docker (by xirixiz) reference in docs" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:40 +#, fuzzy +msgid "" +"[`#286 `_] Na " +"gebruik admin-pagina's geen (eenvoudige) mogelijkheid voor terugkeren " +"naar de site" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:41 +#, fuzzy +msgid "" +"[`#332 `_] " +"Launch full screen on iOS device when opening from homescreen" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:42 +#, fuzzy +msgid "" +"[`#276 `_] " +"Display error compare page on mobile" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:43 +#, fuzzy +msgid "" +"[`#288 `_] Add" +" info to FAQ" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:44 +#, fuzzy +msgid "" +"[`#320 `_] " +"auto refresh op statussen op statuspagina" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:45 +#, fuzzy +msgid "" +"[`#314 `_] Add" +" web-applicatie mogelijkheid ala pihole" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:46 +#, fuzzy +msgid "" +"[`#358 `_] " +"Requirements update (September 2017)" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:47 +#, fuzzy +msgid "" +"[`#270 `_] " +"Public Webinterface Warning (readthedocs.io)" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:48 +#, fuzzy +msgid "" +"[`#231 `_] " +"Contributors update" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:49 +#, fuzzy +msgid "" +"[`#300 `_] " +"Upgrade to Django 1.11 LTS" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:54 +msgid "v1.8.2 - 2017-08-12" +msgstr "" + +#: ../../changelog.rst:58 +#, fuzzy +msgid "" +"[`#346 `_] " +"Defer statistics page XHR" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:63 +msgid "v1.8.1 - 2017-07-04" +msgstr "" + +#: ../../changelog.rst:67 +#, fuzzy +msgid "" +"[`#339 `_] " +"Upgrade Dropbox-client to v8.x" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:72 +msgid "v1.8.0 - 2017-06-14" +msgstr "" + +#: ../../changelog.rst:76 #, fuzzy msgid "" "[`#141 `_] Add" @@ -79,7 +300,7 @@ msgstr "" "upgrade (`#103 `_)." -#: ../../changelog.rst:27 +#: ../../changelog.rst:77 #, fuzzy msgid "" "[`#331 `_] " @@ -89,31 +310,41 @@ msgstr "" "upgrade (`#103 `_)." -#: ../../changelog.rst:32 +#: ../../changelog.rst:78 +#, fuzzy +msgid "" +"[`#299 `_] " +"Support Python 3.6" +msgstr "" +"De ondersteuning voor ``Python 3.3`` is **vervallen** wegens de Django " +"upgrade (`#103 `_)." + +#: ../../changelog.rst:83 msgid "v1.7.0 - 2017-05-04" msgstr "" -#: ../../changelog.rst:36 +#: ../../changelog.rst:87 msgid "" "Please note that the ``dsmr_datalogger.0007_dsmrreading_timestamp_index``" " migration **will take quite some time**, as it adds an index on one of " "the largest database tables!" msgstr "" -#: ../../changelog.rst:38 +#: ../../changelog.rst:89 msgid "" "It takes **around two minutes** on a RaspberryPi 2 & 3 with ``> 4.3 " "million`` readings on PostgreSQL. Results may differ on **slower " "RaspberryPi's** or **with MySQL**." msgstr "" -#: ../../changelog.rst:43 +#: ../../changelog.rst:94 msgid "" "The API-docs for the new v2 API `can be found here `_." msgstr "" -#: ../../changelog.rst:48 +#: ../../changelog.rst:99 #, fuzzy msgid "" "[`#230 `_] " @@ -123,11 +354,11 @@ msgstr "" "upgrade (`#103 `_)." -#: ../../changelog.rst:53 +#: ../../changelog.rst:104 msgid "v1.6.2 - 2017-04-23" msgstr "" -#: ../../changelog.rst:57 +#: ../../changelog.rst:108 #, fuzzy msgid "" "[`#269 `_] " @@ -137,7 +368,7 @@ msgstr "" "upgrade (`#103 `_)." -#: ../../changelog.rst:58 +#: ../../changelog.rst:109 #, fuzzy msgid "" "[`#303 `_] " @@ -147,11 +378,11 @@ msgstr "" "upgrade (`#103 `_)." -#: ../../changelog.rst:63 +#: ../../changelog.rst:114 msgid "v1.6.1 - 2017-04-06" msgstr "" -#: ../../changelog.rst:67 +#: ../../changelog.rst:118 #, fuzzy msgid "" "[`#298 `_] " @@ -161,11 +392,11 @@ msgstr "" "upgrade (`#103 `_)." -#: ../../changelog.rst:72 +#: ../../changelog.rst:123 msgid "v1.6.0 - 2017-03-18" msgstr "" -#: ../../changelog.rst:76 +#: ../../changelog.rst:127 msgid "" "Support for ``MySQL`` has been **deprecated** since ``DSMR-reader v1.6`` " "and will be discontinued completely in a later release. Please use a " @@ -173,14 +404,14 @@ msgid "" "supported in easily migrating to PostgreSQL in the future." msgstr "" -#: ../../changelog.rst:81 +#: ../../changelog.rst:132 msgid "" "**Change in API:** The telegram creation API now returns an ``HTTP 201`` " "response when successful. An ``HTTP 200`` was returned in former " "versions. :doc:`View API docs`." msgstr "" -#: ../../changelog.rst:89 +#: ../../changelog.rst:140 #, fuzzy msgid "" "[`#221 `_] " @@ -190,7 +421,7 @@ msgstr "" "upgrade (`#103 `_)." -#: ../../changelog.rst:90 +#: ../../changelog.rst:141 #, fuzzy msgid "" "[`#237 `_] " @@ -200,7 +431,7 @@ msgstr "" "upgrade (`#103 `_)." -#: ../../changelog.rst:91 +#: ../../changelog.rst:142 #, fuzzy msgid "" "[`#249 `_] " @@ -210,7 +441,7 @@ msgstr "" "upgrade (`#103 `_)." -#: ../../changelog.rst:92 +#: ../../changelog.rst:143 #, fuzzy msgid "" "[`#232 `_] " @@ -220,19 +451,19 @@ msgstr "" "upgrade (`#103 `_)." -#: ../../changelog.rst:93 +#: ../../changelog.rst:144 msgid "" "[`#260 `_] Add" " link to readthedocs in Django for Dropbox instructions." msgstr "" -#: ../../changelog.rst:94 +#: ../../changelog.rst:145 msgid "" "[`#211 `_] API" " request should return HTTP 201 instead of HTTP 200." msgstr "" -#: ../../changelog.rst:95 +#: ../../changelog.rst:146 #, fuzzy msgid "" "[`#191 `_] " @@ -242,7 +473,7 @@ msgstr "" "upgrade (`#103 `_)." -#: ../../changelog.rst:96 +#: ../../changelog.rst:147 #, fuzzy msgid "" "[`#251 `_] " @@ -252,7 +483,7 @@ msgstr "" "upgrade (`#103 `_)." -#: ../../changelog.rst:97 +#: ../../changelog.rst:148 #, fuzzy msgid "" "[`#257 `_] " @@ -262,7 +493,7 @@ msgstr "" "upgrade (`#103 `_)." -#: ../../changelog.rst:98 +#: ../../changelog.rst:149 #, fuzzy msgid "" "[`#274 `_] " @@ -272,81 +503,81 @@ msgstr "" "upgrade (`#103 `_)." -#: ../../changelog.rst:103 ../../changelog.rst:122 +#: ../../changelog.rst:154 ../../changelog.rst:173 msgid "v1.5.5 - 2017-01-19" msgstr "" -#: ../../changelog.rst:107 ../../changelog.rst:126 +#: ../../changelog.rst:158 ../../changelog.rst:177 msgid "" "Remove readonly restriction for editing statistics in admin interface " "(`#242 `_)." msgstr "" -#: ../../changelog.rst:112 ../../changelog.rst:131 +#: ../../changelog.rst:163 ../../changelog.rst:182 msgid "v1.5.4 - 2017-01-12" msgstr "" -#: ../../changelog.rst:116 ../../changelog.rst:135 +#: ../../changelog.rst:167 ../../changelog.rst:186 msgid "" "Improve datalogger for DSMR v5.0 (`#212 " "`_)." msgstr "" -#: ../../changelog.rst:117 ../../changelog.rst:136 +#: ../../changelog.rst:168 ../../changelog.rst:187 msgid "" "Fixed another bug in MinderGas API client implementation (`#228 " "`_)." msgstr "" -#: ../../changelog.rst:141 +#: ../../changelog.rst:192 msgid "v1.5.3 - 2017-01-11" msgstr "" -#: ../../changelog.rst:145 +#: ../../changelog.rst:196 msgid "" "Improve MinderGas API client implementation (`#228 " "`_)." msgstr "" -#: ../../changelog.rst:150 +#: ../../changelog.rst:201 msgid "v1.5.2 - 2017-01-09" msgstr "" -#: ../../changelog.rst:154 +#: ../../changelog.rst:205 msgid "" "Automatic refresh of dashboard charts (`#210 " "`_)." msgstr "" -#: ../../changelog.rst:155 +#: ../../changelog.rst:206 msgid "" "Mindergas.nl API: Tijdstip van verzending willekeurig maken (`#204 " "`_)." msgstr "" -#: ../../changelog.rst:156 +#: ../../changelog.rst:207 msgid "" "Extend API docs with additional example (`#185 " "`_)." msgstr "" -#: ../../changelog.rst:157 +#: ../../changelog.rst:208 msgid "" "Docs: How to restore backup (`#190 `_)." msgstr "" -#: ../../changelog.rst:158 +#: ../../changelog.rst:209 msgid "" "Log errors occured to file (`#181 `_)." msgstr "" -#: ../../changelog.rst:163 +#: ../../changelog.rst:214 msgid "v1.5.1 - 2017-01-04" msgstr "" -#: ../../changelog.rst:167 +#: ../../changelog.rst:218 msgid "" "This patch contains no new features and **only solves upgrading issues** " "for some users." @@ -354,7 +585,7 @@ msgstr "" "Deze patch bevat geen nieuwe features en **lost alleen upgrade-problemen " "op** voor sommige gebruikers." -#: ../../changelog.rst:172 +#: ../../changelog.rst:223 msgid "" "Fix for issues `#200 `_ & `#217 `_)." -#: ../../changelog.rst:182 +#: ../../changelog.rst:233 msgid "" "There is **experimental support** for ``Python 3.6`` and ``Python 3.7 " "(nightly)`` as the unittests are `now built against those versions `_ (`#167 `_)." -#: ../../changelog.rst:184 +#: ../../changelog.rst:235 msgid "**Legacy warning**" msgstr "**Waarschuwing voor legacy**" -#: ../../changelog.rst:186 +#: ../../changelog.rst:237 msgid "" "The migrations that were squashed together in (`#31 " "`_) have been " @@ -416,7 +647,7 @@ msgstr "" "**verwijderd**. Hier heb je alleen maar te maken wanneer je nog gebruik " "maakt van een dsmrreader-versie **vóór** ``v0.13 (β)``." -#: ../../changelog.rst:187 +#: ../../changelog.rst:238 msgid "" "If you are indeed still running ``< v0.13 (β)``, please upgrade to " "``v1.4`` first (!), followed by an upgrade to ``v1.5``." @@ -424,409 +655,409 @@ msgstr "" "Wanneer je nog steeds een versie van vóór ``< v0.13 (β)`` draait, upgrade" " dan eerst naar ``v1.4`` (!), gevolgd door een upgrade naar ``v1.5``." -#: ../../changelog.rst:191 +#: ../../changelog.rst:242 msgid "" "Verify telegrams' CRC (`#188 `_)." msgstr "" -#: ../../changelog.rst:192 +#: ../../changelog.rst:243 msgid "" "Display last 24 hours on dashboard (`#164 " "`_)." msgstr "" -#: ../../changelog.rst:193 +#: ../../changelog.rst:244 msgid "" "Status page visualisation (`#172 `_)." msgstr "" -#: ../../changelog.rst:194 +#: ../../changelog.rst:245 msgid "" "Store and display phases consumption (`#161 " "`_)." msgstr "" -#: ../../changelog.rst:195 +#: ../../changelog.rst:246 msgid "" "Weather graph not showing when no gas data is available (`#170 " "`_)." msgstr "" -#: ../../changelog.rst:196 +#: ../../changelog.rst:247 msgid "" "Upgrade to ChartJs 2.0 (`#127 `_)." msgstr "" -#: ../../changelog.rst:197 +#: ../../changelog.rst:248 msgid "" "Improve Statistics page performance (`#173 " "`_)." msgstr "" -#: ../../changelog.rst:198 +#: ../../changelog.rst:249 msgid "" "Version checker at github (`#166 `_)." msgstr "" -#: ../../changelog.rst:199 +#: ../../changelog.rst:250 msgid "" "Remove required login for dismissal of in-app notifications (`#179 " "`_)." msgstr "" -#: ../../changelog.rst:200 +#: ../../changelog.rst:251 msgid "" "Round numbers displayed in GUI to 2 decimals (`#183 " "`_)." msgstr "" -#: ../../changelog.rst:201 +#: ../../changelog.rst:252 msgid "" "Switch Nosetests to Pytest (+ pytest-cov) (`#167 " "`_)." msgstr "" -#: ../../changelog.rst:202 +#: ../../changelog.rst:253 msgid "" "PyLama code audit (+ pytest-cov) (`#158 " "`_)." msgstr "" -#: ../../changelog.rst:203 +#: ../../changelog.rst:254 msgid "" "Double upgrade of Django framework ``Django 1.8`` -> ``Django 1.9`` -> " "``Django 1.10`` (`#103 `_)." msgstr "" -#: ../../changelog.rst:204 +#: ../../changelog.rst:255 msgid "" "Force ``PYTHONUNBUFFERED`` for supervisor commands (`#176 " "`_)." msgstr "" -#: ../../changelog.rst:205 +#: ../../changelog.rst:256 msgid "" "Documentation updates for v1.5 (`#171 `_)." msgstr "" -#: ../../changelog.rst:206 +#: ../../changelog.rst:257 msgid "" "Requirements update for v1.5 (december 2016) (`#182 " "`_)." msgstr "" -#: ../../changelog.rst:207 +#: ../../changelog.rst:258 msgid "" "Improved backend process logging (`#184 " "`_)." msgstr "" -#: ../../changelog.rst:212 +#: ../../changelog.rst:263 msgid "v1.4.1 - 2016-12-12" msgstr "" -#: ../../changelog.rst:216 +#: ../../changelog.rst:267 msgid "" "Consumption chart hangs due to unique_key violation (`#174 " "`_)." msgstr "" -#: ../../changelog.rst:217 +#: ../../changelog.rst:268 msgid "" "NoReverseMatch at / Reverse for 'docs' (`#175 " "`_)." msgstr "" -#: ../../changelog.rst:222 +#: ../../changelog.rst:273 msgid "v1.4.0 - 2016-11-28" msgstr "" -#: ../../changelog.rst:225 +#: ../../changelog.rst:276 msgid "" "Support for ``Python 3.5`` has been added officially (`#55 " "`_)." msgstr "" -#: ../../changelog.rst:229 +#: ../../changelog.rst:280 msgid "" "Push notifications for Notify My Android / Prowl (iOS), written by Jeroen" " Peters (`#152 `_)." msgstr "" -#: ../../changelog.rst:230 +#: ../../changelog.rst:281 msgid "" "Support for both single and high/low tariff (`#130 " "`_)." msgstr "" -#: ../../changelog.rst:231 +#: ../../changelog.rst:282 msgid "" "Add new note from Dashboard has wrong time format (`#159 " "`_)." msgstr "" -#: ../../changelog.rst:232 +#: ../../changelog.rst:283 msgid "" "Display estimated price for current usage in Dashboard (`#155 " "`_)." msgstr "" -#: ../../changelog.rst:233 +#: ../../changelog.rst:284 msgid "" "Dropbox API v1 deprecated in June 2017 (`#142 " "`_)." msgstr "" -#: ../../changelog.rst:234 +#: ../../changelog.rst:285 msgid "" "Improve code coverage (`#151 `_)." msgstr "" -#: ../../changelog.rst:235 +#: ../../changelog.rst:286 msgid "" "Restyle configuration overview (`#156 `_)." msgstr "" -#: ../../changelog.rst:236 +#: ../../changelog.rst:287 msgid "" "Capability based push notifications (`#165 " "`_)." msgstr "" -#: ../../changelog.rst:241 +#: ../../changelog.rst:292 msgid "v1.3.2 - 2016-11-08" msgstr "" -#: ../../changelog.rst:244 +#: ../../changelog.rst:295 msgid "" "Requirements update (november 2016) (`#150 " "`_)." msgstr "" -#: ../../changelog.rst:249 +#: ../../changelog.rst:300 msgid "v1.3.1 - 2016-08-16" msgstr "" -#: ../../changelog.rst:252 +#: ../../changelog.rst:303 msgid "" "CSS large margin-bottom (`#144 `_)." msgstr "" -#: ../../changelog.rst:253 +#: ../../changelog.rst:304 msgid "" "Django security releases issued: 1.8.14 (`#147 " "`_)." msgstr "" -#: ../../changelog.rst:254 +#: ../../changelog.rst:305 msgid "" "Requirements update (August 2016) (`#148 " "`_)." msgstr "" -#: ../../changelog.rst:255 +#: ../../changelog.rst:306 msgid "" "Query performance improvements (`#149 `_)." msgstr "" -#: ../../changelog.rst:260 +#: ../../changelog.rst:311 msgid "v1.3.0 - 2016-07-15" msgstr "" -#: ../../changelog.rst:263 +#: ../../changelog.rst:314 msgid "" "API endpoint for datalogger (`#140 `_)." msgstr "" -#: ../../changelog.rst:264 +#: ../../changelog.rst:315 msgid "" "Colors for charts (`#137 `_)." msgstr "" -#: ../../changelog.rst:265 +#: ../../changelog.rst:316 msgid "" "Data export: Mindergas.nl (`#10 `_)." msgstr "" -#: ../../changelog.rst:266 +#: ../../changelog.rst:317 msgid "" "Requirement upgrade (`#143 `_)." msgstr "" -#: ../../changelog.rst:267 +#: ../../changelog.rst:318 msgid "" "Installation wizard for first time use (`#139 " "`_)." msgstr "" -#: ../../changelog.rst:272 +#: ../../changelog.rst:323 msgid "v1.2.0 - 2016-05-18" msgstr "" -#: ../../changelog.rst:275 +#: ../../changelog.rst:326 msgid "" "Energy supplier prices does not indicate tariff type (Django admin) " "(`#126 `_)." msgstr "" -#: ../../changelog.rst:276 +#: ../../changelog.rst:327 msgid "" "Requirements update (`#128 `_)." msgstr "" -#: ../../changelog.rst:277 +#: ../../changelog.rst:328 msgid "" "Force backup (`#123 `_)." msgstr "" -#: ../../changelog.rst:278 +#: ../../changelog.rst:329 msgid "" "Update clean-install.md (`#131 `_)." msgstr "" -#: ../../changelog.rst:279 +#: ../../changelog.rst:330 msgid "" "Improve data export field names (`#132 " "`_)." msgstr "" -#: ../../changelog.rst:280 +#: ../../changelog.rst:331 msgid "" "Display average temperature in archive (`#122 " "`_)." msgstr "" -#: ../../changelog.rst:281 +#: ../../changelog.rst:332 msgid "" "Pie charts on trends page overlap their canvas (`#136 " "`_)." msgstr "" -#: ../../changelog.rst:282 +#: ../../changelog.rst:333 msgid "" "'Slumber' consumption (`#115 `_)." msgstr "" -#: ../../changelog.rst:283 +#: ../../changelog.rst:334 msgid "" "Show lowest & highest Watt peaks (`#138 " "`_)." msgstr "" -#: ../../changelog.rst:284 +#: ../../changelog.rst:335 msgid "" "Allow day & hour statistics reset due to changing energy prices (`#95 " "`_)." msgstr "" -#: ../../changelog.rst:289 +#: ../../changelog.rst:340 msgid "v1.1.2 - 2016-05-01" msgstr "" -#: ../../changelog.rst:292 +#: ../../changelog.rst:343 msgid "" "Trends page giving errors (when lacking data) (`#125 " "`_)." msgstr "" -#: ../../changelog.rst:297 +#: ../../changelog.rst:348 msgid "v1.1.1 - 2016-04-27" msgstr "" -#: ../../changelog.rst:300 +#: ../../changelog.rst:351 msgid "" "Improve readme (`#124 `_)." msgstr "" -#: ../../changelog.rst:305 +#: ../../changelog.rst:356 msgid "v1.1.0 - 2016-04-23" msgstr "" -#: ../../changelog.rst:308 +#: ../../changelog.rst:359 msgid "" "Autorefresh dashboard (`#117 `_)." msgstr "" -#: ../../changelog.rst:309 +#: ../../changelog.rst:360 msgid "" "Improve line graphs' visibility (`#111 " "`_)." msgstr "" -#: ../../changelog.rst:310 +#: ../../changelog.rst:361 msgid "" "Easily add notes (`#110 `_)." msgstr "" -#: ../../changelog.rst:311 +#: ../../changelog.rst:362 msgid "" "Export data points in CSV format (`#2 `_)." msgstr "" -#: ../../changelog.rst:312 +#: ../../changelog.rst:363 msgid "" "Allow day/month/year comparison (`#94 `_)." msgstr "" -#: ../../changelog.rst:313 +#: ../../changelog.rst:364 msgid "" "Docs: Add FAQ and generic application info (`#113 " "`_)." msgstr "" -#: ../../changelog.rst:314 +#: ../../changelog.rst:365 msgid "" "Support for Iskra meter (DSMR 2.x) (`#120 " "`_)." msgstr "" -#: ../../changelog.rst:319 +#: ../../changelog.rst:370 msgid "v1.0.1 - 2016-04-07" msgstr "" -#: ../../changelog.rst:322 +#: ../../changelog.rst:373 msgid "" "Update licence to OSI compatible one (`#119 " "`_)." msgstr "" -#: ../../changelog.rst:327 +#: ../../changelog.rst:378 msgid "v1.0.0 - 2016-04-07" msgstr "" -#: ../../changelog.rst:328 +#: ../../changelog.rst:379 msgid "First official stable release." msgstr "Eerste officiële stabiele release." -#: ../../changelog.rst:333 +#: ../../changelog.rst:384 msgid "[β] v0.1 (2015-10-29) to 0.16 (2016-04-06)" msgstr "" -#: ../../changelog.rst:336 +#: ../../changelog.rst:387 msgid "" "All previous beta releases/changes have been combined to a single list " "below." @@ -834,443 +1065,444 @@ msgstr "" "Alle vorige bèta releases/veranderingen zijn gecombineerd tot een enkele " "lijst hieronder." -#: ../../changelog.rst:338 +#: ../../changelog.rst:389 msgid "" "Move documentation to wiki or RTD (`#90 " "`_)." msgstr "" -#: ../../changelog.rst:339 +#: ../../changelog.rst:390 msgid "" "Translate README to Dutch (`#16 `_)." msgstr "" -#: ../../changelog.rst:340 +#: ../../changelog.rst:391 msgid "" "Delete (recent) history page (`#112 `_)." msgstr "" -#: ../../changelog.rst:341 +#: ../../changelog.rst:392 msgid "" "Display most recent temperature in dashboard (`#114 " "`_)." msgstr "" -#: ../../changelog.rst:342 +#: ../../changelog.rst:393 msgid "" "Upgrade Django to 1.8.12 (`#118 `_)." msgstr "" -#: ../../changelog.rst:344 +#: ../../changelog.rst:395 msgid "" "Redesign trends page (`#97 `_)." msgstr "" -#: ../../changelog.rst:345 +#: ../../changelog.rst:396 msgid "" "Support for summer time (`#105 `_)." msgstr "" -#: ../../changelog.rst:346 +#: ../../changelog.rst:397 msgid "" "Support for Daylight Saving Time (DST) transition (`#104 " "`_)." msgstr "" -#: ../../changelog.rst:347 +#: ../../changelog.rst:398 msgid "" "Add (error) hints to status page (`#106 " "`_)." msgstr "" -#: ../../changelog.rst:348 +#: ../../changelog.rst:399 msgid "" "Keep track of version (`#108 `_)." msgstr "" -#: ../../changelog.rst:350 +#: ../../changelog.rst:401 msgid "" "Django 1.8.11 released (`#82 `_)." msgstr "" -#: ../../changelog.rst:351 +#: ../../changelog.rst:402 msgid "" "Prevent tests from failing due to moment of execution (`#88 " "`_)." msgstr "" -#: ../../changelog.rst:352 +#: ../../changelog.rst:403 msgid "" "Statistics page meter positions are broken (`#93 " "`_)." msgstr "" -#: ../../changelog.rst:353 +#: ../../changelog.rst:404 msgid "" "Archive only shows graph untill 23:00 (11 pm) (`#77 " "`_)." msgstr "" -#: ../../changelog.rst:354 +#: ../../changelog.rst:405 msgid "" "Trends page crashes due to nullable fields average (`#100 " "`_)." msgstr "" -#: ../../changelog.rst:355 +#: ../../changelog.rst:406 msgid "" "Trends: Plot peak and off-peak relative to each other (`#99 " "`_)." msgstr "" -#: ../../changelog.rst:356 +#: ../../changelog.rst:407 msgid "" "Monitor requirements with requires.io (`#101 " "`_)." msgstr "" -#: ../../changelog.rst:357 +#: ../../changelog.rst:408 msgid "" "Terminology (`#41 `_)." msgstr "" -#: ../../changelog.rst:358 +#: ../../changelog.rst:409 msgid "" "Obsolete signals in dsmr_consumption (`#63 " "`_)." msgstr "" -#: ../../changelog.rst:359 +#: ../../changelog.rst:410 msgid "" "Individual app testing coverage (`#64 `_)." msgstr "" -#: ../../changelog.rst:360 +#: ../../changelog.rst:411 msgid "" "Support for extra devices on other M-bus (0-n:24.1) (`#92 " "`_)." msgstr "" -#: ../../changelog.rst:361 +#: ../../changelog.rst:412 msgid "" "Separate post-deployment commands (`#102 " "`_)." msgstr "" -#: ../../changelog.rst:363 +#: ../../changelog.rst:414 msgid "" "Show exceptions in production (webinterface) (`#87 " "`_)." msgstr "" -#: ../../changelog.rst:364 +#: ../../changelog.rst:415 msgid "" "Keep Supervisor processes running (`#79 " "`_)." msgstr "" -#: ../../changelog.rst:365 +#: ../../changelog.rst:416 msgid "" "Hourly stats of 22:00:00+00 every day lack gas (`#78 " "`_)." msgstr "" -#: ../../changelog.rst:366 +#: ../../changelog.rst:417 msgid "" "Test Travis-CI with MySQL + MariaDB + PostgreSQL (`#54 " "`_)." msgstr "" -#: ../../changelog.rst:367 +#: ../../changelog.rst:418 msgid "" "PostgreSQL tests + nosetests + coverage failure: unrecognized " "configuration parameter \"foreign_key_checks\" (`#62 " "`_)." msgstr "" -#: ../../changelog.rst:368 +#: ../../changelog.rst:419 msgid "" "Performance check (`#83 `_)." msgstr "" -#: ../../changelog.rst:369 +#: ../../changelog.rst:420 msgid "" "Allow month & year archive (`#66 `_)." msgstr "" -#: ../../changelog.rst:370 +#: ../../changelog.rst:421 msgid "" "Graphs keep increasing height on tablet (`#89 " "`_)." msgstr "" -#: ../../changelog.rst:372 +#: ../../changelog.rst:423 msgid "" "Delete StatsSettings(.track) settings model (`#71 " "`_)." msgstr "" -#: ../../changelog.rst:373 +#: ../../changelog.rst:424 msgid "" "Drop deprecated commands (`#22 `_)." msgstr "" -#: ../../changelog.rst:374 +#: ../../changelog.rst:425 msgid "" "Datalogger doesn't work properly with DSMR 4.2 (KAIFA-METER) (`#73 " "`_)." msgstr "" -#: ../../changelog.rst:375 +#: ../../changelog.rst:426 msgid "" "Dashboard month statistics costs does not add up (`#75 " "`_)." msgstr "" -#: ../../changelog.rst:376 +#: ../../changelog.rst:427 msgid "" "Log unhandled exceptions and errors (`#65 " "`_)." msgstr "" -#: ../../changelog.rst:377 +#: ../../changelog.rst:428 msgid "" "Datalogger crashes with IntegrityError because 'timestamp' is null (`#74 " "`_)." msgstr "" -#: ../../changelog.rst:378 +#: ../../changelog.rst:429 msgid "" "Trends are always shown in UTC (`#76 `_)." msgstr "" -#: ../../changelog.rst:379 +#: ../../changelog.rst:430 msgid "" "Squash migrations (`#31 `_)." msgstr "" -#: ../../changelog.rst:380 +#: ../../changelog.rst:431 msgid "" "Display 'electricity returned' graph in dashboard (`#81 " "`_)." msgstr "" -#: ../../changelog.rst:381 +#: ../../changelog.rst:432 msgid "" "Optional gas (and electricity returned) capabilities tracking (`#70 " "`_)." msgstr "" -#: ../../changelog.rst:382 +#: ../../changelog.rst:433 msgid "" "Add 'electricity returned' to trends page (`#84 " "`_)." msgstr "" -#: ../../changelog.rst:384 +#: ../../changelog.rst:435 msgid "" "Archive: View past days details (`#61 `_)." msgstr "" -#: ../../changelog.rst:385 +#: ../../changelog.rst:436 msgid "" "Dashboard: Consumption total for current month (`#60 " "`_)." msgstr "" -#: ../../changelog.rst:386 +#: ../../changelog.rst:437 msgid "" "Check whether gas readings are optional (`#34 " "`_)." msgstr "" -#: ../../changelog.rst:387 +#: ../../changelog.rst:438 msgid "" "Django security releases issued: 1.8.10 (`#68 " "`_)." msgstr "" -#: ../../changelog.rst:388 +#: ../../changelog.rst:439 msgid "" "Notes display in archive (`#69 `_)." msgstr "" -#: ../../changelog.rst:390 +#: ../../changelog.rst:441 msgid "" "Status page/alerts when features are disabled/unavailable (`#45 " "`_)." msgstr "" -#: ../../changelog.rst:391 +#: ../../changelog.rst:442 msgid "" "Integrate Travis CI (`#48 `_)." msgstr "" -#: ../../changelog.rst:392 +#: ../../changelog.rst:443 msgid "" "Testing coverage (`#38 `_)." msgstr "" -#: ../../changelog.rst:393 +#: ../../changelog.rst:444 msgid "" "Implement automatic backups & Dropbox cloud storage (`#44 " "`_)." msgstr "" -#: ../../changelog.rst:394 +#: ../../changelog.rst:445 msgid "" "Link code coverage service to repository (`#56 " "`_)." msgstr "" -#: ../../changelog.rst:395 +#: ../../changelog.rst:446 msgid "" "Explore timezone.localtime() as replacement for datetime.astimezone() " "(`#50 `_)." msgstr "" -#: ../../changelog.rst:396 +#: ../../changelog.rst:447 msgid "" "Align GasConsumption.read_at to represent the start of hour (`#40 " "`_)." msgstr "" -#: ../../changelog.rst:398 +#: ../../changelog.rst:449 msgid "" "Cleanup unused static files (`#47 `_)." msgstr "" -#: ../../changelog.rst:399 +#: ../../changelog.rst:450 msgid "" "Investigated mysql_tzinfo_to_sql — Load the Time Zone Tables (`#35 " "`_)." msgstr "" -#: ../../changelog.rst:400 +#: ../../changelog.rst:451 msgid "" "Make additional DSMR data optional (`#46 " "`_)." msgstr "" -#: ../../changelog.rst:401 +#: ../../changelog.rst:452 msgid "" "Localize graph x-axis (`#42 `_)." msgstr "" -#: ../../changelog.rst:402 +#: ../../changelog.rst:453 msgid "" "Added graph formatting string to gettext file (`#42 " "`_)." msgstr "" -#: ../../changelog.rst:403 +#: ../../changelog.rst:454 msgid "" "Different colors for peak & off-peak electricity (`#52 " "`_)." msgstr "" -#: ../../changelog.rst:404 +#: ../../changelog.rst:455 msgid "" "Admin: Note widget (`#51 `_)." msgstr "" -#: ../../changelog.rst:405 +#: ../../changelog.rst:456 msgid "" "Allow GUI to run without data (`#26 `_)." msgstr "" -#: ../../changelog.rst:407 +#: ../../changelog.rst:458 msgid "" "Moved project to GitHub (`#28 `_)." msgstr "" -#: ../../changelog.rst:408 +#: ../../changelog.rst:459 msgid "Added stdout to dsmr_backend to reflect progress." msgstr "" -#: ../../changelog.rst:409 +#: ../../changelog.rst:460 msgid "" "Restore note usage in GUI (`#39 `_)." msgstr "" -#: ../../changelog.rst:411 +#: ../../changelog.rst:462 msgid "" "Store daily, weekly, monthly and yearly statistics (`#3 " "`_)." msgstr "" -#: ../../changelog.rst:412 +#: ../../changelog.rst:463 msgid "" "Improved Recent History page performance a bit. (as result of `#3 " "`_)" msgstr "" -#: ../../changelog.rst:413 +#: ../../changelog.rst:464 msgid "" "Updates ChartJS library tot 1.1, disposing django-chartjs plugin. Labels " "finally work! (as result of `#3 `_)" msgstr "" -#: ../../changelog.rst:414 +#: ../../changelog.rst:465 msgid "" "Added trends page. (as result of `#3 `_)" msgstr "" -#: ../../changelog.rst:416 +#: ../../changelog.rst:467 msgid "" "Recent history setting: set range (`#29 " "`_)." msgstr "" -#: ../../changelog.rst:417 +#: ../../changelog.rst:468 msgid "" "Mock required for test: dsmr_weather.test_weather_tracking (`#32 " "`_)." msgstr "" -#: ../../changelog.rst:419 +#: ../../changelog.rst:470 msgid "" "Massive refactoring: Separating apps & using signals (`#19 " "`_)." msgstr "" -#: ../../changelog.rst:420 +#: ../../changelog.rst:471 msgid "" "README update: Exit character for cu (`#27 " "`_, by Jeroen " "Peters)." msgstr "" -#: ../../changelog.rst:421 +#: ../../changelog.rst:472 msgid "Fixed untranslated strings in admin interface." msgstr "" -#: ../../changelog.rst:422 +#: ../../changelog.rst:473 msgid "Upgraded Django to 1.8.9." msgstr "" + diff --git a/docs/locale/nl/LC_MESSAGES/contributing.mo b/docs/locale/nl/LC_MESSAGES/contributing.mo index a2a72b667..ea7342525 100644 Binary files a/docs/locale/nl/LC_MESSAGES/contributing.mo and b/docs/locale/nl/LC_MESSAGES/contributing.mo differ diff --git a/docs/locale/nl/LC_MESSAGES/contributing.po b/docs/locale/nl/LC_MESSAGES/contributing.po index 0796937d0..4309b6092 100644 --- a/docs/locale/nl/LC_MESSAGES/contributing.po +++ b/docs/locale/nl/LC_MESSAGES/contributing.po @@ -6,8 +6,6 @@ msgid "" msgstr "" "Project-Id-Version: DSMR Reader v1.x\n" "Report-Msgid-Bugs-To: Dennis Siemensma \n" -"POT-Creation-Date: 2017-02-18 00:28+0100\n" -"PO-Revision-Date: 2017-02-19 17:52+0100\n" "Last-Translator: Dennis Siemensma \n" "Language-Team: Dennis Siemensma \n" "MIME-Version: 1.0\n" diff --git a/docs/locale/nl/LC_MESSAGES/credits.mo b/docs/locale/nl/LC_MESSAGES/credits.mo index 960ac7218..f9b62c89e 100644 Binary files a/docs/locale/nl/LC_MESSAGES/credits.mo and b/docs/locale/nl/LC_MESSAGES/credits.mo differ diff --git a/docs/locale/nl/LC_MESSAGES/credits.po b/docs/locale/nl/LC_MESSAGES/credits.po index 71e4e8bb2..6632dc92e 100644 --- a/docs/locale/nl/LC_MESSAGES/credits.po +++ b/docs/locale/nl/LC_MESSAGES/credits.po @@ -8,8 +8,6 @@ msgid "" msgstr "" "Project-Id-Version: DSMR Reader v1.x\n" "Report-Msgid-Bugs-To: Dennis Siemensma \n" -"POT-Creation-Date: 2017-05-02 21:26+0200\n" -"PO-Revision-Date: 2017-01-01 00:00+0100\n" "Last-Translator: Dennis Siemensma \n" "Language-Team: Dennis Siemensma \n" "MIME-Version: 1.0\n" @@ -19,7 +17,7 @@ msgstr "" #: ../../credits.rst:2 msgid "Credits / Hall of Fame" -msgstr "" +msgstr "Credits / Hall of Fame" #: ../../credits.rst:6 msgid "Special thanks for supplying code contributions" @@ -30,184 +28,254 @@ msgid "`Jeroen Peters `_" msgstr "" #: ../../credits.rst:12 -msgid "Also many thanks to the contributions of" -msgstr "Dank voor de bijdrages van" +msgid "Also many thanks to the contributions (reporting) of" +msgstr "Dank voor de bijdrages (in de vorm van rapporteren) van" #: ../../credits.rst:13 msgid "Listed in any order, sorted by name." msgstr "Getoond in willekeurige belangrijkheid, gesorteerd op naam." #: ../../credits.rst:15 -msgid "`Bert-Jan Vos `_" +msgid "`balk77 `_" msgstr "" #: ../../credits.rst:16 -msgid "`Daniel ter Horst `_" +msgid "`Bert-Jan Vos `_" msgstr "" #: ../../credits.rst:17 -msgid "`Gert Schaafsma `_" +msgid "`dajappie `_" msgstr "" #: ../../credits.rst:18 -msgid "`Hans-Paul Hemelaar `_" +msgid "`Daniel ter Horst `_" msgstr "" #: ../../credits.rst:19 -msgid "`Jelte Leijenaar `_" +msgid "`emilkwaaitaal `_" msgstr "" #: ../../credits.rst:20 -msgid "`Jeroen Tielen `_" +msgid "`fpompert `_" msgstr "" #: ../../credits.rst:21 -msgid "Koen Volleberg" +msgid "`Gert Schaafsma `_" msgstr "" #: ../../credits.rst:22 -msgid "`Paul Vinken `_" +msgid "`goegol `_" msgstr "" #: ../../credits.rst:23 -msgid "`Sander de Leeuw `_" +msgid "`Hans-Paul Hemelaar `_" msgstr "" #: ../../credits.rst:24 -msgid "`Sevickson `_" +msgid "`helmo `_" msgstr "" #: ../../credits.rst:25 -msgid "\"`WatskeBart `_\"" +msgid "`Jelte Leijenaar `_" +msgstr "" + +#: ../../credits.rst:26 +msgid "`Jeroen Tielen `_" +msgstr "" + +#: ../../credits.rst:27 +msgid "Koen Volleberg" +msgstr "" + +#: ../../credits.rst:28 +msgid "`MarsWarrior `_" msgstr "" #: ../../credits.rst:29 -#, fuzzy -msgid "Software used" -msgstr "Software" +msgid "`mbnn `_" +msgstr "" #: ../../credits.rst:30 -#, fuzzy +msgid "`michielvisser `_" +msgstr "" + +#: ../../credits.rst:31 +msgid "`mkruiver `_" +msgstr "" + +#: ../../credits.rst:32 +msgid "`Paul Vinken `_" +msgstr "" + +#: ../../credits.rst:33 +msgid "`perryodk `_" +msgstr "" + +#: ../../credits.rst:34 +msgid "`pyrocumulus `_" +msgstr "" + +#: ../../credits.rst:35 +msgid "`Sander de Leeuw `_" +msgstr "" + +#: ../../credits.rst:36 +msgid "`Sevickson `_" +msgstr "" + +#: ../../credits.rst:37 +msgid "`ThinkPadNL `_" +msgstr "" + +#: ../../credits.rst:38 +msgid "`thommy101 `_" +msgstr "" + +#: ../../credits.rst:39 +msgid "`TopdRob `_" +msgstr "" + +#: ../../credits.rst:40 +msgid "`trbs `_" +msgstr "" + +#: ../../credits.rst:41 +msgid "`voipmeister `_" +msgstr "" + +#: ../../credits.rst:42 +msgid "`WatskeBart `_" +msgstr "" + +#: ../../credits.rst:43 +msgid "`xirixiz `_" +msgstr "" + +#: ../../credits.rst:47 +msgid "Software used" +msgstr "Gebruikte software" + +#: ../../credits.rst:48 msgid "" "Please note and respect their licences as well, if any. Credits to the " "following software and projects:" msgstr "" "Houd rekening met eventuele licenties/restricties van deze software, " -"wanneer van toepassing." +"wanneer van toepassing. Met dank aan de volgende software en projecten:" -#: ../../credits.rst:32 +#: ../../credits.rst:50 msgid "`Raspbian `_" msgstr "" -#: ../../credits.rst:33 +#: ../../credits.rst:51 msgid "`Django Project `_" msgstr "" -#: ../../credits.rst:34 +#: ../../credits.rst:52 msgid "`Django Solo `_" msgstr "" -#: ../../credits.rst:35 +#: ../../credits.rst:53 msgid "`Django Colorfield `_" msgstr "" -#: ../../credits.rst:36 +#: ../../credits.rst:54 msgid "`Supervisor `_" msgstr "" -#: ../../credits.rst:37 +#: ../../credits.rst:55 msgid "`MySQL `_" msgstr "" -#: ../../credits.rst:38 +#: ../../credits.rst:56 msgid "`MariaDB `_" msgstr "" -#: ../../credits.rst:39 +#: ../../credits.rst:57 msgid "`PostgreSQL `_" msgstr "" -#: ../../credits.rst:40 +#: ../../credits.rst:58 msgid "" "`Director Responsive Admin `_" msgstr "" -#: ../../credits.rst:41 +#: ../../credits.rst:59 msgid "" "Favicon made by `Freepik `_ from `flaticon.com " "`_" msgstr "" -#: ../../credits.rst:42 +#: ../../credits.rst:60 msgid "`Real Favicon Generator `_" msgstr "" -#: ../../credits.rst:43 +#: ../../credits.rst:61 msgid "`Bootstrap-datepicker `_" msgstr "" -#: ../../credits.rst:44 +#: ../../credits.rst:62 msgid "`Github `_" msgstr "" -#: ../../credits.rst:45 +#: ../../credits.rst:63 msgid "`TravisCI `_" msgstr "" -#: ../../credits.rst:46 +#: ../../credits.rst:64 msgid "`Codecov `_" msgstr "" -#: ../../credits.rst:47 +#: ../../credits.rst:65 msgid "`Read The Docs `_" msgstr "" -#: ../../credits.rst:48 +#: ../../credits.rst:66 msgid "`MW `_" msgstr "" -#: ../../credits.rst:49 +#: ../../credits.rst:67 msgid "" "`Full Page Screen Capture `_" msgstr "" -#: ../../credits.rst:50 +#: ../../credits.rst:68 msgid "`Buienradar `_" msgstr "" -#: ../../credits.rst:51 +#: ../../credits.rst:69 msgid "`Django REST Framework `_" msgstr "" -#: ../../credits.rst:52 +#: ../../credits.rst:70 msgid "`Swagger UI Themes `_" msgstr "" -#: ../../credits.rst:56 +#: ../../credits.rst:74 msgid "Misc" msgstr "Overig" -#: ../../credits.rst:58 +#: ../../credits.rst:76 msgid "Dutch Smart Meter reading specifications, data cables, examples and hints:" msgstr "Dutch Smart Meter reading specifications, data cables, examples and hints:" -#: ../../credits.rst:60 +#: ../../credits.rst:78 msgid "`Gé Janssen `_" msgstr "" -#: ../../credits.rst:62 +#: ../../credits.rst:80 msgid "" "`Joost van der Linde (smartmeterdashboard) " "`_" msgstr "" -#: ../../credits.rst:64 +#: ../../credits.rst:82 msgid "`SOS Solutions `_" msgstr "" -#: ../../credits.rst:66 +#: ../../credits.rst:84 msgid "`Nico Di Rocco `_" msgstr "" diff --git a/docs/locale/nl/LC_MESSAGES/faq.mo b/docs/locale/nl/LC_MESSAGES/faq.mo index 3ab7f0554..e9448f488 100644 Binary files a/docs/locale/nl/LC_MESSAGES/faq.mo and b/docs/locale/nl/LC_MESSAGES/faq.mo differ diff --git a/docs/locale/nl/LC_MESSAGES/faq.po b/docs/locale/nl/LC_MESSAGES/faq.po index 19180d0a7..0a5993e74 100644 --- a/docs/locale/nl/LC_MESSAGES/faq.po +++ b/docs/locale/nl/LC_MESSAGES/faq.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: DSMR Reader v1.x\n" "Report-Msgid-Bugs-To: Dennis Siemensma \n" -"POT-Creation-Date: 2017-02-16 15:58+0100\n" -"PO-Revision-Date: 2017-01-21 18:30+0100\n" "Last-Translator: Dennis Siemensma \n" "Language-Team: Dennis Siemensma \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.3.4\n" +"Language: nl\n" +"X-Generator: Poedit 1.8.7.1\n" #: ../../faq.rst:2 msgid "Frequently Asked Questions (FAQ)" @@ -27,15 +27,15 @@ msgstr "Hoe kan ik mijn applicatie bijwerken?" #: ../../faq.rst:11 msgid "" -"The version you are running is always based on the 'latest' version of " -"the application, called the `master` branch. Every once in a while there " -"may be updates. Since ``v1.5`` you can also easily check for updates by " -"using the application's Status page." +"The version you are running is always based on the 'latest' version of the " +"application, called the `master` branch. Every once in a while there may be " +"updates. Since ``v1.5`` you can also easily check for updates by using the " +"application's Status page." msgstr "" -"De versie die je draait is altijd gebaseerd op de 'laatste' versie van de" -" applicatie, ook wel de `master` branch genoemd. Met enige regelmaat zijn" -" er updates beschikbaar. Sinds ``v1.5`` kun je dit ook eenvoudig " -"controleren op de Status-pagina van de applicatie." +"De versie die je draait is altijd gebaseerd op de 'laatste' versie van de " +"applicatie, ook wel de `master` branch genoemd. Met enige regelmaat zijn er " +"updates beschikbaar. Sinds ``v1.5`` kun je dit ook eenvoudig controleren op de " +"Status-pagina van de applicatie." #: ../../faq.rst:16 msgid "" @@ -43,471 +43,555 @@ msgid "" "database**! :doc:`More information about backups can be found " "here`." msgstr "" -"Voordat je bijwerkt, **zorg ervoor dat je in ieder geval een recente " -"back-up van je database hebt**! :doc:`Meer informatie over back-ups kun " -"je hier vinden`." +"Voordat je bijwerkt, **zorg ervoor dat je in ieder geval een recente back-up " +"van je database hebt**! :doc:`Meer informatie over back-ups kun je hier " +"vinden`." #: ../../faq.rst:18 msgid "" -"You can update your application to the latest version by executing " -"**deploy.sh**, located in the root of the project. Make sure to execute " -"it while logged in as the ``dsmr`` user::" +"You can update your application to the latest version by executing **deploy." +"sh**, located in the root of the project. Make sure to execute it while logged " +"in as the ``dsmr`` user::" msgstr "" -"Je kun je applicatie bijwerken door het script **deploy.sh** uit te " -"voeren, die in zich in de hoofdmap van het project bevindt. Zorg er wel " -"voor dat je ingelogd bent als ``dsmr`` gebruiker op de terminal::" +"Je kun je applicatie bijwerken door het script **deploy.sh** uit te voeren, " +"die in zich in de hoofdmap van het project bevindt. Zorg er wel voor dat je " +"ingelogd bent als ``dsmr`` gebruiker op de terminal::" -#: ../../faq.rst:23 +#: ../../faq.rst:24 msgid "" -"It will make sure to check, fetch and apply any changes released. Summary" -" of deployment script steps:" +"It will make sure to check, fetch and apply any changes released. Summary of " +"deployment script steps:" msgstr "" "Dit zorgt ervoor dat alle wijzigingen op een juiste volgorde worden " -"binnengehaald en toegepast. Een overzicht van wat dit uitrol-script exact" -" doet:" +"binnengehaald en toegepast. Een overzicht van wat dit uitrol-script exact doet:" -#: ../../faq.rst:25 +#: ../../faq.rst:26 msgid "GIT pull (codebase update)." msgstr "GIT pull (codebase bijwerken)." -#: ../../faq.rst:26 +#: ../../faq.rst:27 msgid "PIP update requirements." msgstr "Update PIP afhankelijkheden." -#: ../../faq.rst:27 +#: ../../faq.rst:28 msgid "Apply any database migrations." msgstr "Past openstaande databasemigraties toe." -#: ../../faq.rst:28 +#: ../../faq.rst:29 msgid "Sync static files to Nginx folder." msgstr "Synchroniseert statische bestanden naar de Nginx map." -#: ../../faq.rst:29 +#: ../../faq.rst:30 msgid "" -"Reload Gunicorn application server (web interface) and backend processes " -"(such as the datalogger)." +"Reload Gunicorn application server (web interface) and backend processes (such " +"as the datalogger)." msgstr "" -"Herlaadt de Gunicorn-applicatieserver (webinterface) en " -"achtergrondprocessen (zoals de datalogger)." +"Herlaadt de Gunicorn-applicatieserver (webinterface) en achtergrondprocessen " +"(zoals de datalogger)." -#: ../../faq.rst:30 +#: ../../faq.rst:31 msgid "Clear any caches." msgstr "Gooit de cache leeg." -#: ../../faq.rst:34 +#: ../../faq.rst:35 msgid "Dropbox: Automated backup sync" msgstr "Dropbox: Automatisch backups uploaden" -#: ../../faq.rst:35 +#: ../../faq.rst:36 msgid "*How can I link my Dropbox account for backups?*" msgstr "*Hoe kan ik mijn Dropbox-account koppelen voor de backups?*" -#: ../../faq.rst:37 +#: ../../faq.rst:38 msgid "" -"Make sure you have a Dropbox-account or sign up for one. Now go to " -"`Dropbox Apps `_ and click " -"**\"Create app\"** in top right corner." +"Make sure you have a Dropbox-account or sign up for one. Now go to `Dropbox " +"Apps `_ and click **\"Create app\"** " +"in top right corner." msgstr "" -"Zorg allereerst dat je een Dropbox-account hebt. Ga vervolgens naar " -"`Dropbox Apps `_ en klik op " -"**\"Create app\"** rechtsbovenin." +"Zorg allereerst dat je een Dropbox-account hebt. Ga vervolgens naar `Dropbox " +"Apps `_ en klik op **\"Create app\"** " +"rechtsbovenin." -#: ../../faq.rst:44 +#: ../../faq.rst:45 msgid "" -"Choose the following options: (1) **Dropbox API** and (2) **App folder**." -" Then enter a name for your app (3), this will also be used as directory " -"name within the Apps-folder of your Dropbox." +"Choose the following options: (1) **Dropbox API** and (2) **App folder**. Then " +"enter a name for your app (3), this will also be used as directory name within " +"the Apps-folder of your Dropbox." msgstr "" -"Kies de volgende opties: (1) **Dropbox API** en (2) **App folder**. Voer" -" vervolgens een naam voor je app in (3), deze wordt ook gebruikt als naam" -" van de submap binnen je Apps-folder in Dropbox." +"Kies de volgende opties: (1) **Dropbox API** en (2) **App folder**. Voer " +"vervolgens een naam voor je app in (3), deze wordt ook gebruikt als naam van " +"de submap binnen je Apps-folder in Dropbox." -#: ../../faq.rst:51 +#: ../../faq.rst:52 msgid "" -"The app should be created in developer-mode. You can generate an access " -"token for yourself by clicking the **\"Generate\"** button somewhere " -"below." +"The app should be created in developer-mode. You can generate an access token " +"for yourself by clicking the **\"Generate\"** button somewhere below." msgstr "" -"The app is als het goed is nu aangemaakt in developer-modus. Je kunt nog " -"een toegangstoken genereren door op de knop **\"Generate\"** te klikken, " -"die verderop onderaan de pagina staat." +"The app is als het goed is nu aangemaakt in developer-modus. Je kunt nog een " +"toegangstoken genereren door op de knop **\"Generate\"** te klikken, die " +"verderop onderaan de pagina staat." -#: ../../faq.rst:57 +#: ../../faq.rst:58 msgid "" -"Copy the generated access token to the DSMR-reader settings for the " -"Dropbox-configuration. The DSMR-reader application should sync any " -"backups created shortly." +"Copy the generated access token to the DSMR-reader settings for the Dropbox-" +"configuration. The DSMR-reader application should sync any backups created " +"shortly." msgstr "" -"Kopieer de gegenereerde toegangstoken naar de DSMR-reader instellingen " -"onder Dropbox-configuratie. DSMR-reader zou vrij vlot gemaakte backups " -"moeten uploaden naar je Dropbox-account." +"Kopieer de gegenereerde toegangstoken naar de DSMR-reader instellingen onder " +"Dropbox-configuratie. DSMR-reader zou vrij vlot gemaakte backups moeten " +"uploaden naar je Dropbox-account." -#: ../../faq.rst:61 +#: ../../faq.rst:62 msgid "Mindergas.nl: Automated gas meter position export" msgstr "Mindergas.nl: Automatisch gasmeterstanden exporteren" -#: ../../faq.rst:62 +#: ../../faq.rst:63 msgid "*How can I link my mindergas.nl account?*" msgstr "*Hoe kan ik mijn mindergas.nl-account koppelen?*" -#: ../../faq.rst:64 +#: ../../faq.rst:65 msgid "" -"Make sure you have a Mindergas.nl-account or `signup for one " -"`_. Now go to \"`Meterstand API " -"`_\" and click on the button located" -" below **\"Authenticatietoken\"**." +"Make sure you have a Mindergas.nl account or `signup for one `_. Now go to \"`Meterstand API `_\" and click on the button located below **" +"\"Authenticatietoken\"**." msgstr "" -"Zorg ervoor dat je een mindergas.nl-account hebt of `registreer je op hun" -" website `_. Ga nu naar " -"\"`Meterstand API `_\" en klik op de" -" knop onder het kopje **\"Authenticatietoken\"**." +"Zorg ervoor dat je een mindergas.nl-account hebt of `registreer je op hun " +"website `_. Ga nu naar \"`Meterstand " +"API `_\" en klik op de knop onder het " +"kopje **\"Authenticatietoken\"**." -#: ../../faq.rst:71 +#: ../../faq.rst:72 msgid "" -"Copy the authentication token generated and paste in into the DSMR-reader" -" settings for the Mindergas.nl-configuration. Obviously the export only " -"works when there are any gas readings at all and you have ticked the " -"'export' checkbox in the Mindergas.nl-configuration as well." +"Copy the authentication token generated and paste in into the DSMR-reader " +"settings for the Mindergas.nl-configuration. Obviously the export only works " +"when there are any gas readings at all and you have ticked the 'export' " +"checkbox in the Mindergas.nl-configuration as well." msgstr "" -"Kopieer de gegenereerde authenticatietoken in de DSMR-reader instellingen" -" onder Mindergas.nl-configuratie. Vanzelfsprekend werkt deze feature " -"alleen wanneer er gas gemeten wordt, en wanneer je de optie 'Exporteer " -"gegevens naar MinderGas' aangevinkt hebt in dezelfde configuratie." +"Kopieer de gegenereerde authenticatietoken in de DSMR-reader instellingen " +"onder Mindergas.nl-configuratie. Vanzelfsprekend werkt deze feature alleen " +"wanneer er gas gemeten wordt, en wanneer je de optie 'Exporteer gegevens naar " +"MinderGas' aangevinkt hebt in dezelfde configuratie." -#: ../../faq.rst:76 +#: ../../faq.rst:77 msgid "" "Please note that due to policies of mindergas.nl it's not allowed to " "retroactively upload meter positions using the API. Therefor this is not " -"supported by the application. You can however, enter them manually on " -"their website." +"supported by the application. You can however, enter them manually on their " +"website." msgstr "" "N.B.: Wegens het beleid van mindergas.nl is het niet toegestaan om met " -"terugwerkende kracht meterstanden door te geven via de API. De applicatie" -" ondersteunt dat om die reden niet. Je kunt oude meterstanden echter wel " -"via hun website handmatig invoeren, indien gewenst." +"terugwerkende kracht meterstanden door te geven via de API. De applicatie " +"ondersteunt dat om die reden niet. Je kunt oude meterstanden echter wel via " +"hun website handmatig invoeren, indien gewenst." + +#: ../../faq.rst:82 +msgid "PVOutput.org: Automated electricity consumption export" +msgstr "PVOutput.org: Automatisch exporteren van verbruik" + +#: ../../faq.rst:83 +msgid "*How can I link my PVOutput.org account?*" +msgstr "*Hoe kan ik mijn PVOutput.org-account koppelen?*" + +#: ../../faq.rst:85 +msgid "" +"Make sure you have a PVOutput.org account, or `signup for an account `_. You will have to configure your account and PV system(s). " +"For any support doing that, please `see this page `_ for more information." +msgstr "" +"Zorg ervoor dat je een PVOutput.org-account hebt, of `registreer er een " +"`_. Vervolgens zul je je account en zonnesystemen " +"moeten configureren. Voor ondersteuning hoe dat moet, `zie de documentatie " +"`_ voor meer " +"informatie." + +#: ../../faq.rst:88 +msgid "" +"In order to link DSMR-reader to your account, please write down the \"API Key" +"\" and \"System ID\" from your PVOutput account. You can find them near the " +"bottom of the \"Settings\" page in PVOutput." +msgstr "" +"Om DSMR-reader te koppelen met je account, noteer de \"API Key\" en \"System ID" +"\" zoals je PVOutput-account aangeeft. Deze zijn terug te vinden onder " +"\"Settings\", binnen PVOutput." + +#: ../../faq.rst:96 +msgid "" +"Enter those values in DSMR-reader's admin pages, at \"PVOutput: API " +"configuration\". Make sure to enter both:" +msgstr "" +"Vul deze gegevens in de configuratiepagina's van DSMR-reader in, bij: " +"\"PVOutput: API-configuratie\". Zowel:" + +#: ../../faq.rst:98 +msgid "API Key" +msgstr "API Key" + +#: ../../faq.rst:99 +msgid "System ID" +msgstr "System ID" -#: ../../faq.rst:81 +#: ../../faq.rst:107 +msgid "" +"Now navigate to another settings page in DSMR-reader: \"PVOutput: \"Add Status" +"\" configuration\"." +msgstr "" +"Navigeer nu naar een andere pagina met instellingen binnen DSMR-reader, " +"genaamd \"PVOutput: Add Status configuratie\"." + +#: ../../faq.rst:109 +msgid "Enable uploading the consumption." +msgstr "Schakel het uploaden van je verbruik in." + +#: ../../faq.rst:110 +msgid "" +"Choose an interval between the uploads. You can configure this as well on the " +"PVOutput's end, in Device Settings." +msgstr "" +"Kies een interval tussen de uploads. Je kunt dit tevens instellen aan de kant " +"van PVOutput, onder Device Settings." + +#: ../../faq.rst:111 +msgid "" +"Optionally, choose an upload delay X (in minutes). If set, DSMR-reader will " +"not use data of the past X minutes." +msgstr "" +"Voer optioneel een uploadvertraging X in. Wanneer ingesteld, zal DSMR-reader " +"geen data gebruiken van de afgelopen X minuten." + +#: ../../faq.rst:112 +msgid "" +"Optionally, you can choose to enter a **processing delay in minutes** for " +"PVOutput. Please note that PVOutput will only allow this when you have a **" +"\"Donation\" account** on their website. If you do not have one, they will " +"reject each API call you make, until you disable (clear) this option in DSMR-" +"reader." +msgstr "" +"Optioneel kun je ervoor kiezen om PVOutput de gegevens **vertraagd te laten " +"verwerken**. Let op, dit is een feature van PVOutput die alleen beschikbaar is " +"wanneer je daar een **\"Donatie\" account** hebt. Indien dat niet het geval " +"is, zal PVOutput elke API-call weigeren, totdat je dit uitschakelt (veld " +"leegmaakt) in DSMR-reader." + +#: ../../faq.rst:119 +msgid "" +"If you configured everything correctly, you should see some addional data in " +"PVOutput listed under \"Your Outputs\" momentarily." +msgstr "" +"Indien je alles correct hebt ingesteld, zul je op korte termijn extra gegevens " +"moeten zien in PVOutput onder \"Your Outputs\"." + +#: ../../faq.rst:123 msgid "Usage notification: Daily usage statistics on your smartphone" msgstr "Verbruiksnotificaties: Dagelijkse verbruiksstatistieken op je smartphone" -#: ../../faq.rst:82 +#: ../../faq.rst:124 msgid "*Which services for sending notifications are supported?*" msgstr "*Welke services voor het sturen van notificaties worden ondersteund?*" -#: ../../faq.rst:84 +#: ../../faq.rst:126 msgid "" -"Currently, two mobile platforms are supported: Android and iOS. The " -"supported app for Android is `NotifyMyAndroid " -"`_. The supported app for iOS is `Prowl " -"`_." +"Currently, two mobile platforms are supported: Android and iOS. The supported " +"app for Android is `NotifyMyAndroid `_. The " +"supported app for iOS is `Prowl `_." msgstr "" "Op dit moment worden twee platforms ondersteund: Android en iOS. De " -"ondersteunde app voor Android is `NotifyMyAndroid " -"`_. De ondersteunde app voor iOS is " -"`Prowl `_." +"ondersteunde app voor Android is `NotifyMyAndroid `_. De ondersteunde app voor iOS is `Prowl `_." -#: ../../faq.rst:89 +#: ../../faq.rst:131 msgid "*How do I setup usage notifications?*" msgstr "*Hoe stel ik verbruiksnotificaties in?*" -#: ../../faq.rst:91 +#: ../../faq.rst:133 msgid "" "Make sure you either have NotifyMyAndroid or Prowl installed on your " -"smartphone. If you don't, visit your platforms app store to download the " -"app and sign up for an account. Then, make sure to get your API key from " -"the notificationservice that you prefer. For instruction on obtaining the" -" API key, please read below." +"smartphone. If you don't, visit your platforms app store to download the app " +"and sign up for an account. Then, make sure to get your API key from the " +"notificationservice that you prefer. For instruction on obtaining the API key, " +"please read below." msgstr "" "Zorg ervoor dat je NotifyMyAndroid of Prowl hebt geïnstalleerd op je " "smartphone. Als dat niet het geval is, bezoek dan de app store van je " -"platform, download de gewenste app en maak daarvoor een account. Daarna " -"haal je de API key voor de notificatieservice die je wilt gebruiken op. " -"Om te lezen hoe dat werkt, lees dan de instructies bij de volgende " -"kopjes." +"platform, download de gewenste app en maak daarvoor een account. Daarna haal " +"je de API key voor de notificatieservice die je wilt gebruiken op. Om te lezen " +"hoe dat werkt, lees dan de instructies bij de volgende kopjes." -#: ../../faq.rst:93 +#: ../../faq.rst:135 msgid "" "In the DSMR-reader settings for the Usagenotifications, tick the Send " -"Notifications checkbox and select the notification service you want to " -"use. Then copy the API key from the notification service and paste in " -"into the the textbox for the API key. When you save these settings, your " -"first notification should be sent after midnight. Don't worry, the " -"notification will be sent with low priority and will not wake you up." -msgstr "" -"In de DSMR-reader instellingen voor de Verbruiksnotificaties zet je een " -"vinkje bij Stuur Notificaties en selecteer daaronder welke " -"notificatieservice je wilt gebruiken. Kopieeër daarna de API key van de " -"notificatieservice en plak deze in het tekstveld voor de API key. Als je " -"deze instellingen opslaat zul je na middernacht je eerste notificatie " -"ontvangen. Geen nood, de notificatie wordt altijd verstuurd met lage " -"prioriteit, deze maakt je dus niet wakker." - -#: ../../faq.rst:96 +"Notifications checkbox and select the notification service you want to use. " +"Then copy the API key from the notification service and paste in into the the " +"textbox for the API key. When you save these settings, your first notification " +"should be sent after midnight. Don't worry, the notification will be sent with " +"low priority and will not wake you up." +msgstr "" +"In de DSMR-reader instellingen voor de Verbruiksnotificaties zet je een vinkje " +"bij Stuur Notificaties en selecteer daaronder welke notificatieservice je wilt " +"gebruiken. Kopieeër daarna de API key van de notificatieservice en plak deze " +"in het tekstveld voor de API key. Als je deze instellingen opslaat zul je na " +"middernacht je eerste notificatie ontvangen. Geen nood, de notificatie wordt " +"altijd verstuurd met lage prioriteit, deze maakt je dus niet wakker." + +#: ../../faq.rst:138 msgid "*How do I obtain my API key for NotifyMyAndroid?*" msgstr "*Hoe haal ik de API key op voor NotifyMyAndroid?*" -#: ../../faq.rst:98 +#: ../../faq.rst:140 msgid "" -"After you have downloaded NotifyMyAndroid and signed up for an account " -"you should be able to `login to your NotifyMyAndroid account " -"`_. Now go to \"`My Account " -"`_\", you should see an " -"overview of your current API keys if you have any. To create an API key " -"for the DSMR-reader, please click **\"Generate New Key\"**." +"After you have downloaded NotifyMyAndroid and signed up for an account you " +"should be able to `login to your NotifyMyAndroid account `_. Now go to \"`My Account `_\", you should see an overview of your " +"current API keys if you have any. To create an API key for the DSMR-reader, " +"please click **\"Generate New Key\"**." msgstr "" -"Nadat je NotifyMyAndroid hebt gedownload en een account hebt aangemaakt " -"zou je moeten kunnen `inloggen op je NotifyMyAndroid-account " -"`_. Ga nu naar \"`My Account " -"`_\" om een overzicht van je" -" account de API keys te krijgen als je deze al hebt. Om een API key voor " -"de DSMR-reader te genereren klik je op **\"Generate New Key\"**." +"Nadat je NotifyMyAndroid hebt gedownload en een account hebt aangemaakt zou je " +"moeten kunnen `inloggen op je NotifyMyAndroid-account `_. Ga nu naar \"`My Account `_\" om een overzicht van je account de API " +"keys te krijgen als je deze al hebt. Om een API key voor de DSMR-reader te " +"genereren klik je op **\"Generate New Key\"**." -#: ../../faq.rst:105 ../../faq.rst:121 +#: ../../faq.rst:147 ../../faq.rst:163 msgid "" -"When a new key is generated, you will see it immediatly. Your key is " -"listed like in the screenshot below (the red box marks your API key)." +"When a new key is generated, you will see it immediatly. Your key is listed " +"like in the screenshot below (the red box marks your API key)." msgstr "" -"Als er een nieuwe key is gegenereerd, zie je deze direct. De key is te " -"vinden zoals in onderstaande screenshot (er staat een rood kader om de " -"key)." +"Als er een nieuwe key is gegenereerd, zie je deze direct. De key is te vinden " +"zoals in onderstaande screenshot (er staat een rood kader om de key)." -#: ../../faq.rst:112 +#: ../../faq.rst:154 msgid "*How do I obtain my API key for Prowl?*" msgstr "*Hoe haal ik de API key op voor Prowl?*" -#: ../../faq.rst:114 +#: ../../faq.rst:156 msgid "" -"After you have downloaded Prowl and signed up for an account you should " -"be able to `login to your Prowl account " -"`_. Now go to \"`API Keys " -"`_\", you should see an " -"overview of your current API keys if you have any. To create an API key " -"for the DSMR-reader, input a name and click **\"Generate Key\"**." +"After you have downloaded Prowl and signed up for an account you should be " +"able to `login to your Prowl account `_. " +"Now go to \"`API Keys `_\", you " +"should see an overview of your current API keys if you have any. To create an " +"API key for the DSMR-reader, input a name and click **\"Generate Key\"**." msgstr "" -"Nadat je Prowl hebt gedownload en een account hebt aangemaakt zou je " -"moeten kunnen `inloggen op je Prowl-account " -"`_. Ga nu naar \"`API Keys " -"`_\" om een overzicht van je " -"API keys te krijgen als je deze al hebt. Om een API key voor de DSMR-" -"reader te genereren geef je een naam op en klik je op **\"Generate " -"Key\"**." +"Nadat je Prowl hebt gedownload en een account hebt aangemaakt zou je moeten " +"kunnen `inloggen op je Prowl-account `_. " +"Ga nu naar \"`API Keys `_\" om een " +"overzicht van je API keys te krijgen als je deze al hebt. Om een API key voor " +"de DSMR-reader te genereren geef je een naam op en klik je op **\"Generate Key" +"\"**." -#: ../../faq.rst:129 +#: ../../faq.rst:171 msgid "I only pay for a single electricity tariff but I see two!" msgstr "Ik betaal voor een enkel tarief maar ik zie er twee!" -#: ../../faq.rst:130 +#: ../../faq.rst:172 msgid "" -"DSMR (and your energy supplier) always read both high and low tariff from" -" your meter. It's possible however that you are only paying for a single " -"tariff. In that case your energy supplier will simply merge both high and" -" low tariffs to make it look like you have a single one." +"DSMR (and your energy supplier) always read both high and low tariff from your " +"meter. It's possible however that you are only paying for a single tariff. In " +"that case your energy supplier will simply merge both high and low tariffs to " +"make it look like you have a single one." msgstr "" -"DSMR (en je energieleverancier) lezen altijd zowel hoog als laag tarief " -"van je meter uit. Het is desondanks mogelijk dat je betaalt voor slechts " -"één tarief. In dat geval voegt jouw energieleverancier het hoge en lage " -"tarief samen zodat het lijkt alsof je een enkel tarief hebt." +"DSMR (en je energieleverancier) lezen altijd zowel hoog als laag tarief van je " +"meter uit. Het is desondanks mogelijk dat je betaalt voor slechts één tarief. " +"In dat geval voegt jouw energieleverancier het hoge en lage tarief samen zodat " +"het lijkt alsof je een enkel tarief hebt." -#: ../../faq.rst:134 +#: ../../faq.rst:176 msgid "" -"This application displays separate tariffs by default, but supports " -"merging them to a single one as well. Just make sure that you apply the " -"**same price to both electricity 1 and 2** and enable the option ``Merge " -"electricity tariffs`` in the frontend configuration." +"This application displays separate tariffs by default, but supports merging " +"them to a single one as well. Just make sure that you apply the **same price " +"to both electricity 1 and 2** and enable the option ``Merge electricity " +"tariffs`` in the frontend configuration." msgstr "" "Deze applicatie weergeeft standaard gescheiden tarieven, maar heeft wel " -"ondersteuning om ze samen te voegen (net zoals je energieleverancier " -"doet). Zorg er wel voor dat je **dezelfde prijs invult bij hoog en laag " -"tarief voor elektriciteit** en dat je de optie ``Voeg tarieven samen`` " -"aanzet in de interfaceconfiguratie." +"ondersteuning om ze samen te voegen (net zoals je energieleverancier doet). " +"Zorg er wel voor dat je **dezelfde prijs invult bij hoog en laag tarief voor " +"elektriciteit** en dat je de optie ``Voeg tarieven samen`` aanzet in de " +"interfaceconfiguratie." -#: ../../faq.rst:139 +#: ../../faq.rst:181 msgid "I want to see the load of each electricity phase as well" msgstr "Ik wil het elektriciteitsverbruik per fase ook kunnen zien" -#: ../../faq.rst:140 +#: ../../faq.rst:182 msgid "" -"Since ``DSMR-reader v1.5`` it's possible to track your ``P+`` " -"(consumption) phases as well. You will need to enable this in the " -"``Datalogger configuration``. There is a setting called ``Track " -"electricity phases``. When active, this will log the current usage of " -"those phases and plot these on the Dashboard page." +"Since ``DSMR-reader v1.5`` it's possible to track your ``P+`` (consumption) " +"phases as well. You will need to enable this in the ``Datalogger " +"configuration``. There is a setting called ``Track electricity phases``. When " +"active, this will log the current usage of those phases and plot these on the " +"Dashboard page." msgstr "" "Sinds ``DSMR-reader v1.5`` is het mogelijk om je ``P+`` (verbruik) " "elektriciteitsfasen in te zien. Dit is een aparte optie die je zelf moet " -"inschakelen in ``Dataloggerconfiguratie``. De instelling heet daar ``Houd" -" elektriciteitsfasen bij``. Zodra ingeschakeld, zal de applicatie het " -"verbruik per fase vastleggen in tonen in een grafiek in het Dashboard." +"inschakelen in ``Dataloggerconfiguratie``. De instelling heet daar ``Houd " +"elektriciteitsfasen bij``. Zodra ingeschakeld, zal de applicatie het verbruik " +"per fase vastleggen in tonen in een grafiek in het Dashboard." -#: ../../faq.rst:143 +#: ../../faq.rst:185 msgid "Please keep in mind:" msgstr "Houd in gedachten:" -#: ../../faq.rst:145 +#: ../../faq.rst:187 msgid "" -"This will **not work retroactively**. The datalogger always discards all " -"data not used." +"This will **not work retroactively**. The datalogger always discards all data " +"not used." msgstr "" -"Dit werkt **niet met terugwerkende kracht**. De datalogger gooit namelijk" -" alle gegevens weg die niet nodig zijn." +"Dit werkt **niet met terugwerkende kracht**. De datalogger gooit namelijk alle " +"gegevens weg die niet nodig zijn." -#: ../../faq.rst:146 +#: ../../faq.rst:188 msgid "" -"This feature will only work when your smart meter is connected to **three" -" phases**. Even when having the setting enabled." +"This feature will only work when your smart meter is connected to **three " +"phases**. Even when having the setting enabled." msgstr "" "Deze feature werkt alleen wanneer je slimme meter ook daadwerkelijk is " "aangesloten op **drie fasen**. Zelfs wanneer de optie is ingeschakeld." -#: ../../faq.rst:147 +#: ../../faq.rst:189 msgid "" -"When having tracking phases enabled, you should see a button in the " -"Dashboard called ``Display electricity phases``. Click on it to show the " -"graph." +"When having tracking phases enabled, you should see a button in the Dashboard " +"called ``Display electricity phases``. Click on it to show the graph." msgstr "" -"Wanneer het bijhouden van de fasen is ingeschakeld, zie je op het " -"Dashboard een knop genaamd ``Toon elektriciteitsfasen``. Klik die aan om " -"de grafiek te tonen." +"Wanneer het bijhouden van de fasen is ingeschakeld, zie je op het Dashboard " +"een knop genaamd ``Toon elektriciteitsfasen``. Klik die aan om de grafiek te " +"tonen." -#: ../../faq.rst:149 +#: ../../faq.rst:191 msgid "You should see something similar to:" msgstr "Je zult iets zien in de trend van:" -#: ../../faq.rst:157 +#: ../../faq.rst:199 msgid "Recalculate prices retroactively" msgstr "Prijzen opnieuw berekenen met terugwerkende kracht" -#: ../../faq.rst:158 +#: ../../faq.rst:200 msgid "" -"*I've adjusted my energy prices but there are no changes! How can I " -"regenerate them with my new prices?*" +"*I've adjusted my energy prices but there are no changes! How can I regenerate " +"them with my new prices?*" msgstr "" -"*Ik heb zojuist mijn energieprijzen aangepast, maar ik zie geen verschil!" -" Hoe kan ik de nieuwe prijzen doorvoeren?*" +"*Ik heb zojuist mijn energieprijzen aangepast, maar ik zie geen verschil! Hoe " +"kan ik de nieuwe prijzen doorvoeren?*" -#: ../../faq.rst:160 +#: ../../faq.rst:202 msgid "" -"Statistics for each day are generated once, the day after. However, you " -"can flush your statistics by executing:" +"Statistics for each day are generated once, the day after. However, you can " +"flush your statistics by executing:" msgstr "" "Dagstatistieken worden dagelijks eenmalig gegenereerd. Het is echter wel " "mogelijk om deze te resetten door het volgende te doen:" -#: ../../faq.rst:162 -msgid "``./manage.py dsmr_stats_clear_statistics --ack-to-delete-my-data``" -msgstr "``./manage.py dsmr_stats_clear_statistics --ack-to-delete-my-data``" +#: ../../faq.rst:204 +msgid "``./manage.py dsmr_backend_delete_aggregated_data``" +msgstr "``./manage.py dsmr_backend_delete_aggregated_data``" -#: ../../faq.rst:164 +#: ../../faq.rst:206 msgid "" -"The application will delete all statistics and (slowly) regenerate them " -"in the background. Just make sure the source data is still there." +"The application will delete all statistics and (slowly) regenerate them in the " +"background. Just make sure the source data is still there." msgstr "" -"De applicatie verwijdert alle statistieken en genereert ze (langzaam) " -"weer op de achtergrond. Zorg er wel voor dat alle brongegevens intact " -"zijn." +"De applicatie verwijdert alle statistieken en genereert ze (langzaam) weer op " +"de achtergrond. Zorg er wel voor dat alle brongegevens intact zijn." -#: ../../faq.rst:168 +#: ../../faq.rst:210 msgid "I'm not seeing any gas readings" msgstr "Ik zie geen gasverbruik" -#: ../../faq.rst:169 +#: ../../faq.rst:211 msgid "" -"Please make sure that your meter supports reading gas consumption and " -"that you've waited for a few hours for any graphs to render. The gas " -"meter positions are only be updated once per hour (for DSMR v4). The " -"Status page will give you insight in this as well." +"Please make sure that your meter supports reading gas consumption and that " +"you've waited for a few hours for any graphs to render. The gas meter " +"positions are only be updated once per hour (for DSMR v4). The Status page " +"will give you insight in this as well." msgstr "" "Wees er allereerst zeker van dat je slimme meter uberhaupt gasverbruik " -"registreert, en dat je een paar uur hebt gewacht. De gasmeterstanden " -"worden sowieso slechts een keer per uur bijgewerkt (voor DSMR v4). De " -"Status-pagina geeft je hier overigens ook inzicht in." +"registreert, en dat je een paar uur hebt gewacht. De gasmeterstanden worden " +"sowieso slechts een keer per uur bijgewerkt (voor DSMR v4). De Status-pagina " +"geeft je hier overigens ook inzicht in." -#: ../../faq.rst:175 +#: ../../faq.rst:217 msgid "How do I restore a database backup?" msgstr "Hoe zet ik een databaseback-up terug?" -#: ../../faq.rst:179 +#: ../../faq.rst:221 msgid "" -"Restoring a backup will replace any existing data stored in the database " -"and is irreversible!" +"Restoring a backup will replace any existing data stored in the database and " +"is irreversible!" msgstr "" -"Het herstellen van een back-up vervangt de bestaande data in de database " -"en is onomkeerbaar!" +"Het herstellen van een back-up vervangt de bestaande data in de database en is " +"onomkeerbaar!" -#: ../../faq.rst:183 +#: ../../faq.rst:225 msgid "" -"Do you need a complete reinstall of DSMR-reader as well? Then please " -":doc:`follow the install guide` and restore the database " -"backup **using the notes at the end of chapter 1**." +"Do you need a complete reinstall of DSMR-reader as well? Then please :doc:" +"`follow the install guide` and restore the database backup " +"**using the notes at the end of chapter 1**." msgstr "" -"Heb je tevens een complete herinstallatie van DSMR-reader nodig? " -":doc:`Volg dan de installatiehandleiding` en herstel de " -"databaseback-up volgens **de notities aan het einde van hoofdstuk 1**." +"Heb je tevens een complete herinstallatie van DSMR-reader nodig? :doc:`Volg " +"dan de installatiehandleiding` en herstel de databaseback-up " +"volgens **de notities aan het einde van hoofdstuk 1**." -#: ../../faq.rst:186 +#: ../../faq.rst:228 msgid "Only want to restore the database?" msgstr "Wil je alleen een databaseback-up terugzetten?" -#: ../../faq.rst:188 +#: ../../faq.rst:230 msgid "" -"This asumes you are still running the same application version as the " -"backup was created in." +"This asumes you are still running the same application version as the backup " +"was created in." msgstr "" -"Dit gaat er overigens wel van uit dat je dezelfde applicatie-versie " -"draait als waarmee de back-up is gemaakt." +"Dit gaat er overigens wel van uit dat je dezelfde applicatie-versie draait als " +"waarmee de back-up is gemaakt." -#: ../../faq.rst:190 +#: ../../faq.rst:232 msgid "" -"Stop the application first with ``sudo supervisorctl stop all``. This " -"will disconnect it from the database as well." +"Stop the application first with ``sudo supervisorctl stop all``. This will " +"disconnect it from the database as well." msgstr "" -"Stop als eerste de applicatie met ``sudo supervisorctl stop all``. Dit " -"zorgt er ook voor dat de databaseverbinding van de applicatie verdwijnt." +"Stop als eerste de applicatie met ``sudo supervisorctl stop all``. Dit zorgt " +"er ook voor dat de databaseverbinding van de applicatie verdwijnt." -#: ../../faq.rst:192 +#: ../../faq.rst:234 msgid "" -"Importing the data could take a long time. It took MySQL 15 minutes to " -"import nearly 3 million readings, from a compressed backup, on a " -"RaspberryPi 3." +"Importing the data could take a long time. It took MySQL 15 minutes to import " +"nearly 3 million readings, from a compressed backup, on a RaspberryPi 3." msgstr "" -"Het importeren van de gegevens kan enige tijd in beslag nemen. Op MySQL " -"duurt het ongeveer een kwartier om 3 miljoen metingen te importeren, " -"vanuit een gecomprimeerde back-up op een RaspberryPi 3." +"Het importeren van de gegevens kan enige tijd in beslag nemen. Op MySQL duurt " +"het ongeveer een kwartier om 3 miljoen metingen te importeren, vanuit een " +"gecomprimeerde back-up op een RaspberryPi 3." -#: ../../faq.rst:194 +#: ../../faq.rst:236 msgid "For **PostgreSQL** restores::" msgstr "Voor herstellen van **PostgreSQL**::" -#: ../../faq.rst:208 +#: ../../faq.rst:250 msgid "For **MySQL** restores::" msgstr "Voor herstellen van **MySQL**::" -#: ../../faq.rst:222 +#: ../../faq.rst:264 msgid "Start the application again with ``sudo supervisorctl start all``." msgstr "Start de applicatie weer met ``sudo supervisorctl start all``." -#: ../../faq.rst:226 +#: ../../faq.rst:268 msgid "" "In case the version differs, you can try forcing a deployment reload by: " "``sudo su - dsmr`` and then executing ``./post-deploy.sh``." msgstr "" -"Mocht de versie toch verschillen, dan kun je proberen om de applicatie te" -" herladen. Log in met: ``sudo su - dsmr`` en voer vervolgens ``./post-" -"deploy.sh`` uit." +"Mocht de versie toch verschillen, dan kun je proberen om de applicatie te " +"herladen. Log in met: ``sudo su - dsmr`` en voer vervolgens ``./post-deploy." +"sh`` uit." -#: ../../faq.rst:230 +#: ../../faq.rst:272 msgid "Feature/bug report" msgstr "Verzoek/fout melden" -#: ../../faq.rst:231 +#: ../../faq.rst:273 msgid "*How can I propose a feature or report a bug I've found?*" msgstr "*Hoe kan ik een verzoek indienen of een fout melden?*" -#: ../../faq.rst:235 +#: ../../faq.rst:277 msgid "" "`Just create a ticket at Github `_." msgstr "" -"`Maak een ticket aan op Github `_." - +"`Maak een ticket aan op Github `_." diff --git a/docs/locale/nl/LC_MESSAGES/index.mo b/docs/locale/nl/LC_MESSAGES/index.mo index 690fc93bc..1ddb4570d 100644 Binary files a/docs/locale/nl/LC_MESSAGES/index.mo and b/docs/locale/nl/LC_MESSAGES/index.mo differ diff --git a/docs/locale/nl/LC_MESSAGES/index.po b/docs/locale/nl/LC_MESSAGES/index.po index 9cda512b8..db9bcff29 100644 --- a/docs/locale/nl/LC_MESSAGES/index.po +++ b/docs/locale/nl/LC_MESSAGES/index.po @@ -6,8 +6,6 @@ msgid "" msgstr "" "Project-Id-Version: DSMR Reader v1.x\n" "Report-Msgid-Bugs-To: Dennis Siemensma \n" -"POT-Creation-Date: 2016-01-01 00:00+0100\n" -"PO-Revision-Date: 2017-01-01 00:00+0100\n" "Last-Translator: Dennis Siemensma \n" "Language-Team: Dennis Siemensma \n" "MIME-Version: 1.0\n" diff --git a/docs/locale/nl/LC_MESSAGES/installation.mo b/docs/locale/nl/LC_MESSAGES/installation.mo index 98097cbdf..3291a7160 100644 Binary files a/docs/locale/nl/LC_MESSAGES/installation.mo and b/docs/locale/nl/LC_MESSAGES/installation.mo differ diff --git a/docs/locale/nl/LC_MESSAGES/installation.po b/docs/locale/nl/LC_MESSAGES/installation.po index 05a7aa03d..0049b0eca 100644 --- a/docs/locale/nl/LC_MESSAGES/installation.po +++ b/docs/locale/nl/LC_MESSAGES/installation.po @@ -7,14 +7,14 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2017-06-13 21:36+0200\n" -"PO-Revision-Date: 2017-05-04 18:35+0200\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.3.4\n" +"Language: nl\n" +"X-Generator: Poedit 1.8.7.1\n" #: ../../installation.rst:2 msgid "Installation" @@ -22,678 +22,684 @@ msgstr "Installatie" #: ../../installation.rst:6 msgid "" -"The installation guide may take about *half an hour max* (for raspberryPi" -" 2/3), but it greatly depends on your Linux skills and whether you need " -"to understand every step described in this guide." +"The installation guide may take about *half an hour max* (for raspberryPi 2/3), " +"but it greatly depends on your Linux skills and whether you need to understand " +"every step described in this guide." msgstr "" -"Het installeren duurt naar verwachting zo'n *half uur* (op een " -"RaspberryPi 2/3), maar hangt natuurlijk ook af van je eigen vaardigheid " -"op de command line." +"Het installeren duurt naar verwachting zo'n *half uur* (op een RaspberryPi " +"2/3), maar hangt natuurlijk ook af van je eigen vaardigheid op de command line." -#: ../../installation.rst:14 +#: ../../installation.rst:15 +msgid "Docker (alternative)" +msgstr "Docker (alternatief)" + +#: ../../installation.rst:18 +msgid "" +"There is also a Docker version available for DSMR-reader. It's hosted and " +"maintained by a third party. More information can be found here:" +msgstr "" +"Er is tevens een Docker-versie beschikbaar voor DSMR-reader. Deze wordt " +"onderhouden door een derde partij. Meer informatie hierover is hier te vinden:" + +#: ../../installation.rst:20 +msgid "Github: https://github.com/xirixiz/dsmr-reader-docker" +msgstr "Github: https://github.com/xirixiz/dsmr-reader-docker" + +#: ../../installation.rst:22 +msgid "Docker hub: https://hub.docker.com/r/xirixiz/dsmr-reader-docker/" +msgstr "Docker hub: https://hub.docker.com/r/xirixiz/dsmr-reader-docker/" + +#: ../../installation.rst:24 +msgid "" +"Not interested in Docker? Follow the instructions in the chapters below if you " +"wish to install this project the regular way." +msgstr "" +"Geen interesse in Docker? Volg dan de instructies in de hoofdstukken hieronder " +"om dit project handmatig te installeren." + +#: ../../installation.rst:28 msgid "1. Database backend (PostgreSQL)" msgstr "1. Databaseopslag (PostgreSQL)" -#: ../../installation.rst:16 +#: ../../installation.rst:30 msgid "" -"The application stores by default all readings taken from the serial " -"cable. There is support for **PostgreSQL**, and there used to be support " -"for **MySQL/MariaDB** as well. The latter is currently deprecated by this" -" project and support will be discontinued in a future release." +"The application stores by default all readings taken from the serial cable. " +"There is support for **PostgreSQL**, and there used to be support for **MySQL/" +"MariaDB** as well. The latter is currently deprecated by this project and " +"support will be discontinued in a future release." msgstr "" -"De applicatie slaat de P1-metingen standaard op. Er is ondersteuning voor" -" **PostgreSQL**, en vroeger ook voor **MySQL/MariaDB**. Alleen wordt de " -"laatstgenoemde momenteel afgeraden om te gebruiken (ondersteuning vervalt" -" later)." +"De applicatie slaat de P1-metingen standaard op. Er is ondersteuning voor " +"**PostgreSQL**, en vroeger ook voor **MySQL/MariaDB**. Alleen wordt de " +"laatstgenoemde momenteel afgeraden om te gebruiken (ondersteuning vervalt " +"later)." -#: ../../installation.rst:20 +#: ../../installation.rst:34 msgid "" "Install PostgreSQL, ``postgresql-server-dev-all`` is required for the " "virtualenv installation later in this guide." msgstr "" -"Installeer PostgreSQL. Daarnaast is ``postgresql-server-dev-all`` nodig " -"voor het installeren van de VirtualEnv later." +"Installeer PostgreSQL. Daarnaast is ``postgresql-server-dev-all`` nodig voor " +"het installeren van de VirtualEnv later." -#: ../../installation.rst:22 ../../installation.rst:67 +#: ../../installation.rst:36 ../../installation.rst:81 msgid "Install database::" msgstr "Installeer database::" -#: ../../installation.rst:26 +#: ../../installation.rst:40 msgid "" -"Does Postgres not start due to locales? Try: ``dpkg-reconfigure " -"locales``. Still no luck? Try editing ``/etc/environment``, add " -"``LC_ALL=\"en_US.utf-8\"`` and reboot." +"Does Postgres not start due to locales? Try: ``dpkg-reconfigure locales``. " +"Still no luck? Try editing ``/etc/environment``, add ``LC_ALL=\"en_US.utf-8\"`` " +"and reboot." msgstr "" -"Start PostgreSQL niet wegens een fout in 'locales'? Probeer dan het " -"volgende: ``dpkg-reconfigure locales``. Werkt het nog steeds niet? Open " -"dan dit bestand ``/etc/environment``, voeg onderaan de regel " -"``LC_ALL=\"en_US.utf-8\"`` toe en herstart het systeem." +"Start PostgreSQL niet wegens een fout in 'locales'? Probeer dan het volgende: " +"``dpkg-reconfigure locales``. Werkt het nog steeds niet? Open dan dit bestand " +"``/etc/environment``, voeg onderaan de regel ``LC_ALL=\"en_US.utf-8\"`` toe en " +"herstart het systeem." -#: ../../installation.rst:29 +#: ../../installation.rst:43 msgid "" -"(!) Ignore any '*could not change directory to \"/root\": Permission " -"denied*' errors for the following three commands." +"(!) Ignore any '*could not change directory to \"/root\": Permission denied*' " +"errors for the following three commands." msgstr "" -"(!) Negeer voor de volgende drie commando's de foutmelding: '*could not " -"change directory to \"/root\": Permission denied*'." +"(!) Negeer voor de volgende drie commando's de foutmelding: '*could not change " +"directory to \"/root\": Permission denied*'." -#: ../../installation.rst:31 ../../installation.rst:75 +#: ../../installation.rst:45 ../../installation.rst:89 msgid "Create database user::" msgstr "Creëer databasegebruiker::" -#: ../../installation.rst:35 +#: ../../installation.rst:49 msgid "Create database, owned by the database user we just created::" msgstr "" "Creëer database, met als eigenaar de databasegebruiker die we net hebben " "aangemaakt::" -#: ../../installation.rst:39 +#: ../../installation.rst:53 msgid "Set password for database user::" msgstr "Stel wachtwoord in voor databasegebruiker::" -#: ../../installation.rst:45 +#: ../../installation.rst:59 msgid "" -"**Optional**: Do you need to restore a **PostgreSQL** database backup as " -"well?" +"**Optional**: Do you need to restore a **PostgreSQL** database backup as well?" msgstr "" -"**Optioneel**: Wil je ook nog een **PostgreSQL** database back-up " -"herstellen?" +"**Optioneel**: Wil je ook nog een **PostgreSQL** database back-up herstellen?" -#: ../../installation.rst:47 ../../installation.rst:91 +#: ../../installation.rst:61 ../../installation.rst:105 msgid "Restore an uncompressed (``.sql``) backup with::" msgstr "Herstel een ongecomprimeerde (``.sql``) back-up met::" -#: ../../installation.rst:51 ../../installation.rst:95 +#: ../../installation.rst:65 ../../installation.rst:109 msgid "Or restore a compressed (``.gz``) backup with::" msgstr "Of herstel een gecomprimeerde (``.gz``) back-up met::" -#: ../../installation.rst:55 +#: ../../installation.rst:69 msgid "Now continue at chapter 2 below (Dependencies)." msgstr "Ga door naar hoofdstuk 2 verderop (Dependencies)." -#: ../../installation.rst:58 ../../installation.rst:243 +#: ../../installation.rst:72 ../../installation.rst:257 msgid "(Legacy) MySQL/MariaDB" msgstr "(Legacy) MySQL/MariaDB" -#: ../../installation.rst:61 ../../installation.rst:246 +#: ../../installation.rst:75 ../../installation.rst:260 msgid "" -"Support for the MySQL database backend is deprecated and will be removed " -"in a later release. Please use a PostgreSQL database instead. Users " -"already running MySQL will be supported in migrating at a later moment." +"Support for the MySQL database backend is deprecated and will be removed in a " +"later release. Please use a PostgreSQL database instead. Users already running " +"MySQL will be supported in migrating at a later moment." msgstr "" -"Gebruik van MySQL-databases wordt afgeraden en de ondersteuning hiervoor" -" stopt in een latere release. Gebruik daarom PostgreSQL. Gebruikers die " -"dit project al op MySQL draaien krijgen in de toekomst ondersteuning om " -"te migreren." +"Gebruik van MySQL-databases wordt afgeraden en de ondersteuning hiervoor stopt " +"in een latere release. Gebruik daarom PostgreSQL. Gebruikers die dit project al " +"op MySQL draaien krijgen in de toekomst ondersteuning om te migreren." -#: ../../installation.rst:64 +#: ../../installation.rst:78 msgid "" -"Install MariaDB. You can also choose to install the closed source MySQL, " -"as they should be interchangeable anyway. ``libmysqlclient-dev`` is " -"required for the virtualenv installation later in this guide." +"Install MariaDB. You can also choose to install the closed source MySQL, as " +"they should be interchangeable anyway. ``libmysqlclient-dev`` is required for " +"the virtualenv installation later in this guide." msgstr "" -"Installeer MariaDB. Je kunt er ook voor kiezen om het closed-source MySQL" -" te installeren. Welke je ook kiest, ``libmysqlclient-dev`` is later " -"nodig voor de VirtualEnv." +"Installeer MariaDB. Je kunt er ook voor kiezen om het closed-source MySQL te " +"installeren. Welke je ook kiest, ``libmysqlclient-dev`` is later nodig voor de " +"VirtualEnv." -#: ../../installation.rst:71 +#: ../../installation.rst:85 msgid "Create database::" msgstr "Creëer database::" -#: ../../installation.rst:79 +#: ../../installation.rst:93 msgid "Set privileges for database user::" msgstr "Stel rechten in voor databasegebruiker::" -#: ../../installation.rst:83 +#: ../../installation.rst:97 msgid "Flush privileges to activate them::" msgstr "Pas de databaserechten toe::" -#: ../../installation.rst:89 +#: ../../installation.rst:103 msgid "**Optional**: Do you need to restore a **MySQL** database backup as well?" msgstr "**Optioneel**: Wil je ook nog een **MySQL** database back-up herstellen?" -#: ../../installation.rst:101 +#: ../../installation.rst:115 msgid "2. Dependencies" msgstr "2. Afhankelijkheden" -#: ../../installation.rst:102 +#: ../../installation.rst:116 msgid "" -"Now you'll have to install several utilities, required for the Nginx " -"webserver, Gunicorn application server and cloning the application code " -"from the Github repository::" +"Now you'll have to install several utilities, required for the Nginx webserver, " +"Gunicorn application server and cloning the application code from the Github " +"repository::" msgstr "" -"Tijd om diverse tools te installeren. Deze zijn nodig voor de Nginx " -"webserver, de Gunicorn applicatieserver en voor het binnenhalen van de " -"code van de applicatie vanaf Github::" +"Tijd om diverse tools te installeren. Deze zijn nodig voor de Nginx webserver, " +"de Gunicorn applicatieserver en voor het binnenhalen van de code van de " +"applicatie vanaf Github::" -#: ../../installation.rst:106 +#: ../../installation.rst:120 msgid "" "Install ``cu``. The CU program allows easy testing for your DSMR serial " -"connection. It's very basic but also very effective to simply test " -"whether your serial cable setup works properly::" +"connection. It's very basic but also very effective to simply test whether your " +"serial cable setup works properly::" msgstr "" -"Installeer ``cu``. Met dit programmaatje kunnen kun je vrij gemakkelijk " -"de DSMR-verbinding testen naar je slimme meter toe. Erg handig om te " -"kijken of dat überhaupt al lekker werkt::" +"Installeer ``cu``. Met dit programmaatje kunnen kun je vrij gemakkelijk de DSMR-" +"verbinding testen naar je slimme meter toe. Erg handig om te kijken of dat " +"überhaupt al lekker werkt::" -#: ../../installation.rst:113 +#: ../../installation.rst:127 msgid "3. Application user" msgstr "3. Applicatiegebruiker" -#: ../../installation.rst:114 +#: ../../installation.rst:128 msgid "" -"The application runs as ``dsmr`` user by default. This way we do not have" -" to run the application as ``root``, which is a bad practice anyway." +"The application runs as ``dsmr`` user by default. This way we do not have to " +"run the application as ``root``, which is a bad practice anyway." msgstr "" -"De applicatie draait standaard onder de gebruiker ``dsmr``. Hierdoor " -"heeft het geen ``root``-rechten (nodig), wat over het algemeen zeer " -"afgeraden wordt." +"De applicatie draait standaard onder de gebruiker ``dsmr``. Hierdoor heeft het " +"geen ``root``-rechten (nodig), wat over het algemeen zeer afgeraden wordt." -#: ../../installation.rst:116 +#: ../../installation.rst:130 msgid "" -"Create user with homedir. The application code and virtualenv will reside" -" in this directory as well::" +"Create user with homedir. The application code and virtualenv will reside in " +"this directory as well::" msgstr "" -"Maak een aparte gebruiker aan met eigen homedir. De code voor de " -"applicatie en VirtualEnv zetten we later hier in::" +"Maak een aparte gebruiker aan met eigen homedir. De code voor de applicatie en " +"VirtualEnv zetten we later hier in::" -#: ../../installation.rst:120 +#: ../../installation.rst:134 msgid "" -"Our user also requires dialout permissions. So allow the user to perform " -"a dialout by adding it to the ``dialout`` group::" +"Our user also requires dialout permissions. So allow the user to perform a " +"dialout by adding it to the ``dialout`` group::" msgstr "" -"De gebruiker heeft ook toegang nodig om de kabel te kunnen uitlezen. " -"Hiervoor voegen de we gebruiker toe aan de groep ``dialout``::" +"De gebruiker heeft ook toegang nodig om de kabel te kunnen uitlezen. Hiervoor " +"voegen de we gebruiker toe aan de groep ``dialout``::" -#: ../../installation.rst:124 +#: ../../installation.rst:138 msgid "" "Either proceed to the next heading **for a test reading** or continue at " "chapter 4." msgstr "" -"Ga ofwel door naar het volgende hoofdstuk **voor een testmeting** of ga " -"direct door naar stap 4." +"Ga ofwel door naar het volgende hoofdstuk **voor een testmeting** of ga direct " +"door naar stap 4." -#: ../../installation.rst:128 +#: ../../installation.rst:142 msgid "Your first reading (optional)" msgstr "Je allereerste (optionele) meting" -#: ../../installation.rst:132 +#: ../../installation.rst:146 msgid "" "**OPTIONAL**: You may skip this section as it's not required for the " "application to install. However, if you have never read your meter's P1 " -"telegram port before, I recommend to perform an initial reading to make " -"sure everything works as expected." +"telegram port before, I recommend to perform an initial reading to make sure " +"everything works as expected." msgstr "" "**OPTIONEEL**: Je kunt deze stap overslaan wanneer je al eerder een " -"(test)meting hebt gedaan met je slimme meter. Ik raad het dus vooral aan " -"als je nog nooit eerder je P1-poort hebt uitgelezen. Hiermee verzeker je " -"jezelf ook dat de applicatie straks dezelfde (werkende) toegang heeft " -"voor de metingen." +"(test)meting hebt gedaan met je slimme meter. Ik raad het dus vooral aan als je " +"nog nooit eerder je P1-poort hebt uitgelezen. Hiermee verzeker je jezelf ook " +"dat de applicatie straks dezelfde (werkende) toegang heeft voor de metingen." -#: ../../installation.rst:134 +#: ../../installation.rst:148 msgid "" "Now login as the user we have just created, to perform our very first " "reading! ::" msgstr "" -"Log nu in als de gebruiker die we zojuist hebben aangemaakt voor de " -"eerste testmeting! ::" +"Log nu in als de gebruiker die we zojuist hebben aangemaakt voor de eerste " +"testmeting! ::" -#: ../../installation.rst:138 +#: ../../installation.rst:152 msgid "Test with ``cu`` for **DSMR 4+**::" msgstr "Test met ``cu`` voor **DSMR 4+**::" -#: ../../installation.rst:142 +#: ../../installation.rst:156 msgid "Or test with ``cu`` for **DSMR 2.2** (untested)::" msgstr "Of test met ``cu`` voor **DSMR 2.2** (ongetest)::" -#: ../../installation.rst:146 +#: ../../installation.rst:160 msgid "" -"You now should see something similar to ``Connected.`` and a wall of text" -" and numbers *within 10 seconds*. Nothing? Try different BAUD rate, as " -"mentioned above. You might also check out a useful blog, `such as this " -"one (Dutch) `_." -msgstr "" -"Je zou nu iets moeten zien als ``Connected.``. Vervolgens krijg je, als " -"het goed is, binnen tien seconden een hele lap tekst te zijn met een hoop" -" cijfers. Werkt het niet? Probeer dan een andere BAUD-waarde, zoals " -"hierboven beschreven. Of `kijk op een nuttig weblog " +"You now should see something similar to ``Connected.`` and a wall of text and " +"numbers *within 10 seconds*. Nothing? Try different BAUD rate, as mentioned " +"above. You might also check out a useful blog, `such as this one (Dutch) " "`_." +msgstr "" +"Je zou nu iets moeten zien als ``Connected.``. Vervolgens krijg je, als het " +"goed is, binnen tien seconden een hele lap tekst te zijn met een hoop cijfers. " +"Werkt het niet? Probeer dan een andere BAUD-waarde, zoals hierboven beschreven. " +"Of `kijk op een nuttig weblog `_." -#: ../../installation.rst:148 +#: ../../installation.rst:162 msgid "" -"To exit cu, type \"``q.``\", hit Enter and wait for a few seconds. It " -"should exit with the message ``Disconnected.``." +"To exit cu, type \"``q.``\", hit Enter and wait for a few seconds. It should " +"exit with the message ``Disconnected.``." msgstr "" -"Om cu af te sluiten, typ \"``q.``\", druk op Enter en wacht voor een paar" -" seconden. Het programma sluit af met de melding ``Disconnected.``." +"Om cu af te sluiten, typ \"``q.``\", druk op Enter en wacht voor een paar " +"seconden. Het programma sluit af met de melding ``Disconnected.``." -#: ../../installation.rst:152 +#: ../../installation.rst:166 msgid "4. Webserver/Nginx (part 1)" msgstr "4. Webserver/Nginx (deel 1)" -#: ../../installation.rst:154 +#: ../../installation.rst:168 msgid "" -"*We will now prepare the webserver, Nginx. It will serve all " -"application's static files directly and proxy any application requests to" -" the backend, Gunicorn controlled by Supervisor, which we will configure " -"later on.*" +"*We will now prepare the webserver, Nginx. It will serve all application's " +"static files directly and proxy any application requests to the backend, " +"Gunicorn controlled by Supervisor, which we will configure later on.*" msgstr "" -"*We configureren vervolgens de webserver (Nginx). Deze serveert alle " -"statische bestanden en geeft de applicatie-verzoeken door naar de " -"backend, waar de applicatie in Gunicorn draait onder Supervisor. Deze " -"stellen we later in.*" +"*We configureren vervolgens de webserver (Nginx). Deze serveert alle statische " +"bestanden en geeft de applicatie-verzoeken door naar de backend, waar de " +"applicatie in Gunicorn draait onder Supervisor. Deze stellen we later in.*" -#: ../../installation.rst:156 ../../installation.rst:299 +#: ../../installation.rst:170 ../../installation.rst:313 msgid "" -"Make sure you are acting here as ``root`` or ``sudo`` user. If not, press" -" CTRL + D to log out of the ``dsmr`` user." +"Make sure you are acting here as ``root`` or ``sudo`` user. If not, press CTRL " +"+ D to log out of the ``dsmr`` user." msgstr "" -"Zorg ervoor dat je hier ``root``- of ``sudo``-gebruiker bent. Zo niet, " -"druk op CTRL + D om uit te loggen als ``dsmr`` gebruiker." +"Zorg ervoor dat je hier ``root``- of ``sudo``-gebruiker bent. Zo niet, druk op " +"CTRL + D om uit te loggen als ``dsmr`` gebruiker." -#: ../../installation.rst:158 +#: ../../installation.rst:172 msgid "" -"Django will later copy all static files to the directory below, used by " -"Nginx to serve statics. Therefor it requires (write) access to it::" +"Django will later copy all static files to the directory below, used by Nginx " +"to serve statics. Therefor it requires (write) access to it::" msgstr "" -"Django kopieert alle statische bestanden naar een aparte map, die weer " -"door Nginx gebruikt wordt. Daarom is er tevens (schrijf)toegang voor " -"nodig::" +"Django kopieert alle statische bestanden naar een aparte map, die weer door " +"Nginx gebruikt wordt. Daarom is er tevens (schrijf)toegang voor nodig::" -#: ../../installation.rst:166 +#: ../../installation.rst:180 msgid "5. Clone project code from Github" msgstr "5. Kloon project code vanaf Github" -#: ../../installation.rst:167 +#: ../../installation.rst:181 msgid "" -"Now is the time to clone the code from the repository into the homedir we" -" created." +"Now is the time to clone the code from the repository into the homedir we " +"created." msgstr "" -"Nu kunnen we de code van de applicatie van Github downloaden en in de " -"homedir zetten die we net aangemaakt hebben." +"Nu kunnen we de code van de applicatie van Github downloaden en in de homedir " +"zetten die we net aangemaakt hebben." -#: ../../installation.rst:169 +#: ../../installation.rst:183 msgid "" -"Make sure you are now acting as ``dsmr`` user (if not then enter: ``sudo " -"su - dsmr``)" +"Make sure you are now acting as ``dsmr`` user (if not then enter: ``sudo su - " +"dsmr``)" msgstr "" -"Zorg ervoor dat je ingelogd bent als ``dsmr``-gebruiker (zo niet, typ " -"dan: ``sudo su - dsmr``)" +"Zorg ervoor dat je ingelogd bent als ``dsmr``-gebruiker (zo niet, typ dan: " +"``sudo su - dsmr``)" -#: ../../installation.rst:171 +#: ../../installation.rst:185 msgid "Clone the repository::" msgstr "Kloon de repository::" -#: ../../installation.rst:175 +#: ../../installation.rst:189 msgid "" -"This may take a few seconds. When finished, you should see a new folder " -"called ``dsmr-reader``, containing a clone of the Github repository." +"This may take a few seconds. When finished, you should see a new folder called " +"``dsmr-reader``, containing a clone of the Github repository." msgstr "" -"Dit kan enkele seconden in beslag nemen. Als het goed is zie je hierna " -"een map genaamd ``dsmr-reader``, met daarin een kopie van de repository " -"zoals die op Github staat." +"Dit kan enkele seconden in beslag nemen. Als het goed is zie je hierna een map " +"genaamd ``dsmr-reader``, met daarin een kopie van de repository zoals die op " +"Github staat." -#: ../../installation.rst:179 +#: ../../installation.rst:193 msgid "6. Virtualenv" msgstr "6. VirtualEnv" -#: ../../installation.rst:181 +#: ../../installation.rst:195 msgid "" -"The dependencies our application uses are stored in a separate " -"environment, also called **VirtualEnv**." +"The dependencies our application uses are stored in a separate environment, " +"also called **VirtualEnv**." msgstr "" -"Alle (externe) afhankelijkheden worden opgeslagen in een aparte omgeving," -" ook wel **VirtualEnv** genoemd." +"Alle (externe) afhankelijkheden worden opgeslagen in een aparte omgeving, ook " +"wel **VirtualEnv** genoemd." -#: ../../installation.rst:183 +#: ../../installation.rst:197 msgid "" -"Although it's just a folder inside our user's homedir, it's very " -"effective as it allows us to keep dependencies isolated or to run " -"different versions of the same package on the same machine. `More " -"information about this subject can be found here `_." +"Although it's just a folder inside our user's homedir, it's very effective as " +"it allows us to keep dependencies isolated or to run different versions of the " +"same package on the same machine. `More information about this subject can be " +"found here `_." msgstr "" -"Dit is allemaal erg handig, ondanks dat het feitelijk niets meer " -"voorstelt dan een aparte map binnen de homedir van onze gebruiker. " -"Hierdoor kunnen we namelijk meerdere versie van software op hetzelfde " -"systeem installeren, zonder dat dat elkaar bijt. Meer informatie hierover" -" `kan hier gevonden worden `_." +"Dit is allemaal erg handig, ondanks dat het feitelijk niets meer voorstelt dan " +"een aparte map binnen de homedir van onze gebruiker. Hierdoor kunnen we " +"namelijk meerdere versie van software op hetzelfde systeem installeren, zonder " +"dat dat elkaar bijt. Meer informatie hierover `kan hier gevonden worden `_." -#: ../../installation.rst:186 +#: ../../installation.rst:200 msgid "" -"Make sure you are still acting as ``dsmr`` user (if not then enter: " -"``sudo su - dsmr``)" +"Make sure you are still acting as ``dsmr`` user (if not then enter: ``sudo su - " +"dsmr``)" msgstr "" -"Zorg ervoor dat je nog steeds ingelogd bent als ``dsmr``-gebruiker (zo " -"niet, typ dan: ``sudo su - dsmr``)" +"Zorg ervoor dat je nog steeds ingelogd bent als ``dsmr``-gebruiker (zo niet, " +"typ dan: ``sudo su - dsmr``)" -#: ../../installation.rst:188 +#: ../../installation.rst:202 msgid "Create folder for the virtualenv(s) of this user::" msgstr "Maak map aan voor de VirtualEnv van deze gebruiker::" -#: ../../installation.rst:192 +#: ../../installation.rst:206 msgid "" -"Create a new virtualenv, we usually use the same name for it as the " -"application or project::" +"Create a new virtualenv, we usually use the same name for it as the application " +"or project::" msgstr "" -"Maak een nieuwe VirtualEnv aan. Het is gebruikelijk om hiervoor dezelfde " -"naam te gebruiken als die van de applicatie of het project." +"Maak een nieuwe VirtualEnv aan. Het is gebruikelijk om hiervoor dezelfde naam " +"te gebruiken als die van de applicatie of het project." -#: ../../installation.rst:198 +#: ../../installation.rst:212 msgid "" -"Note that it's important to specify **Python 3** as the default " -"interpreter." +"Note that it's important to specify **Python 3** as the default interpreter." msgstr "" -"N.B.: het is belangrijk dat je voor deze VirtualEnv aangeeft dat **Python" -" 3** de gewenste standaardversie is::" +"N.B.: het is belangrijk dat je voor deze VirtualEnv aangeeft dat **Python 3** " +"de gewenste standaardversie is::" -#: ../../installation.rst:200 +#: ../../installation.rst:214 msgid "" -"Put both commands below in the ``dsmr`` user's ``~/.bashrc`` file with " -"your favorite text editor::" +"Put both commands below in the ``dsmr`` user's ``~/.bashrc`` file with your " +"favorite text editor::" msgstr "" -"Zet beide commands in het ``~/.bashrc`` bestand van de ``dsmr`` gebruiker" -" met je favoriete bestandseditor::" +"Zet beide commands in het ``~/.bashrc`` bestand van de ``dsmr`` gebruiker met " +"je favoriete bestandseditor::" -#: ../../installation.rst:206 +#: ../../installation.rst:220 msgid "" -"This will both **activate** the virtual environment and cd you into the " -"right directory on your **next login** as ``dsmr`` user." +"This will both **activate** the virtual environment and cd you into the right " +"directory on your **next login** as ``dsmr`` user." msgstr "" -"Hiermee wordt zowel de VirtualEnv geactiveerd en ga je direct naar de " -"juiste map. Dit werkt de **eerstvolgende keer** dat je inlogt als " -"``dsmr`` gebruiker." +"Hiermee wordt zowel de VirtualEnv geactiveerd en ga je direct naar de juiste " +"map. Dit werkt de **eerstvolgende keer** dat je inlogt als ``dsmr`` gebruiker." -#: ../../installation.rst:210 +#: ../../installation.rst:224 msgid "" -"You can easily test whether you've configured this correctly by logging " -"out the ``dsmr`` user (CTRL + D) and login again using ``sudo su - " -"dsmr``." +"You can easily test whether you've configured this correctly by logging out the " +"``dsmr`` user (CTRL + D) and login again using ``sudo su - dsmr``." msgstr "" -"Je kunt dit vrij gemakkelijk testen door uit te loggen als ``dsmr`` " -"gebruiker (met CTRL + D) en vervolgens weer in te loggen met ``sudo su - " -"dsmr``." +"Je kunt dit vrij gemakkelijk testen door uit te loggen als ``dsmr`` gebruiker " +"(met CTRL + D) en vervolgens weer in te loggen met ``sudo su - dsmr``." -#: ../../installation.rst:212 +#: ../../installation.rst:226 msgid "" -"You should see the terminal have a ``(dsmrreader)`` prefix now, for " -"example: ``(dsmrreader)dsmr@rasp:~/dsmr-reader $``" +"You should see the terminal have a ``(dsmrreader)`` prefix now, for example: " +"``(dsmrreader)dsmr@rasp:~/dsmr-reader $``" msgstr "" -"Als het goed is heeft je terminal nu een ``(dsmrreader)`` prefix, " -"bijvoorbeeld: ``(dsmrreader)dsmr@rasp:~/dsmr-reader $``" +"Als het goed is heeft je terminal nu een ``(dsmrreader)`` prefix, bijvoorbeeld: " +"``(dsmrreader)dsmr@rasp:~/dsmr-reader $``" -#: ../../installation.rst:214 +#: ../../installation.rst:228 msgid "" -"Make sure you've read and executed the note above, because you'll need it" -" for the next chapter." +"Make sure you've read and executed the note above, because you'll need it for " +"the next chapter." msgstr "" "Zorg ervoor dat je de bovenstaande notitie hebt gelezen en uitgevoerd, " "aangezien ze nodig zijn voor het volgende hoofdstuk." -#: ../../installation.rst:218 +#: ../../installation.rst:232 msgid "7. Application configuration & setup" msgstr "7. Applicatieconfiguratie" -#: ../../installation.rst:219 +#: ../../installation.rst:233 msgid "" -"The application will also need the appropriate database client, which is " -"not installed by default. For this I created two ready-to-use " -"requirements files, which will also install all other dependencies " -"required, such as the Django framework." +"The application will also need the appropriate database client, which is not " +"installed by default. For this I created two ready-to-use requirements files, " +"which will also install all other dependencies required, such as the Django " +"framework." msgstr "" "De applicatie heeft een databaseconnector nodig om de gegevens te kunnen " -"opslaan. Daarvoor heb ik een tweetal requirements-bestanden gemaakt, waar" -" alles al in staat wat nodig is. Zoals bijvoorbeeld Django en de " -"databaseverbinding." +"opslaan. Daarvoor heb ik een tweetal requirements-bestanden gemaakt, waar alles " +"al in staat wat nodig is. Zoals bijvoorbeeld Django en de databaseverbinding." -#: ../../installation.rst:222 +#: ../../installation.rst:236 msgid "" -"The ``base.txt`` contains requirements which the application needs " -"anyway, no matter which backend you've choosen." +"The ``base.txt`` contains requirements which the application needs anyway, no " +"matter which backend you've choosen." msgstr "" -"Het bestand ``base.txt`` bevat alle afhankelijkheden die de applicatie " -"sowieso nodig heeft, ongeacht de databasekeuze die je gemaakt hebt." +"Het bestand ``base.txt`` bevat alle afhankelijkheden die de applicatie sowieso " +"nodig heeft, ongeacht de databasekeuze die je gemaakt hebt." -#: ../../installation.rst:226 +#: ../../installation.rst:240 msgid "" -"**Installation of the requirements below might take a while**, depending " -"on your Internet connection, RaspberryPi speed and resources (generally " -"CPU) available. Nothing to worry about. :]" +"**Installation of the requirements below might take a while**, depending on " +"your Internet connection, RaspberryPi speed and resources (generally CPU) " +"available. Nothing to worry about. :]" msgstr "" -"**De installatie van de volgende afhankelijkheden kan enige tijd in " -"beslag nemen**. Dit varieert en is sterk afhankelijk van de snelheid van " -"je Internet-verbinding en je RaspberryPi. Je hoeft je dus niet zorgen te " -"maken wanneer dit lang lijkt te duren. :]" +"**De installatie van de volgende afhankelijkheden kan enige tijd in beslag " +"nemen**. Dit varieert en is sterk afhankelijk van de snelheid van je Internet-" +"verbinding en je RaspberryPi. Je hoeft je dus niet zorgen te maken wanneer dit " +"lang lijkt te duren. :]" -#: ../../installation.rst:229 +#: ../../installation.rst:243 msgid "PostgreSQL" msgstr "PostgreSQL" -#: ../../installation.rst:230 +#: ../../installation.rst:244 msgid "Did you choose PostgreSQL? Then execute these two lines::" msgstr "Heb je gekozen voor PostgreSQL? Voer dan deze twee regels uit::" -#: ../../installation.rst:237 +#: ../../installation.rst:251 msgid "" -"Did everything install without fatal errors? If the database client " -"refuses to install due to missing files/configs, make sure you've " -"installed ``postgresql-server-dev-all`` earlier in the process, when you " -"installed the database server itself." +"Did everything install without fatal errors? If the database client refuses to " +"install due to missing files/configs, make sure you've installed ``postgresql-" +"server-dev-all`` earlier in the process, when you installed the database server " +"itself." msgstr "" -"Zonder problemen alles kunnen installeren? Mocht de database client niet " -"willen installeren wegens missende bestanden, controleer dan of je eerder" -" tijdens de installatie het volgende hebt uitgevoerd: als het goed is heb" -" je ``postgresql-server-dev-all`` geïnstalleerd, tegelijkertijd met de " -"databaseserver." +"Zonder problemen alles kunnen installeren? Mocht de database client niet willen " +"installeren wegens missende bestanden, controleer dan of je eerder tijdens de " +"installatie het volgende hebt uitgevoerd: als het goed is heb je ``postgresql-" +"server-dev-all`` geïnstalleerd, tegelijkertijd met de databaseserver." -#: ../../installation.rst:240 +#: ../../installation.rst:254 msgid "Continue to chapter 8 (Bootstrapping)." msgstr "Ga door naar hoofdstuk 8 (Bootstrapping)." -#: ../../installation.rst:249 +#: ../../installation.rst:263 msgid "Or did you choose MySQL/MariaDB? Execute these two commands::" msgstr "Of heb je gekozen voor MySQL/MariaDB? Voer dan deze twee commando's uit::" -#: ../../installation.rst:255 +#: ../../installation.rst:269 msgid "" -"Did everything install without fatal errors? If the database client " -"refuses to install due to missing files/configs, make sure you've " -"installed ``libmysqlclient-dev`` earlier in the process, when you " -"installed the database server itself." +"Did everything install without fatal errors? If the database client refuses to " +"install due to missing files/configs, make sure you've installed " +"``libmysqlclient-dev`` earlier in the process, when you installed the database " +"server itself." msgstr "" -"Zonder problemen alles kunnen installeren? Mocht de database client niet " -"willen installeren wegens missende bestanden, controleer dan of je eerder" -" tijdens de installatie het volgende hebt uitgevoerd: als het goed is heb" -" je ``libmysqlclient-dev`` geïnstalleerd, tegelijkertijd met de " -"databaseserver." +"Zonder problemen alles kunnen installeren? Mocht de database client niet willen " +"installeren wegens missende bestanden, controleer dan of je eerder tijdens de " +"installatie het volgende hebt uitgevoerd: als het goed is heb je " +"``libmysqlclient-dev`` geïnstalleerd, tegelijkertijd met de databaseserver." -#: ../../installation.rst:260 +#: ../../installation.rst:274 msgid "8. Bootstrapping" msgstr "8. Initialisatie" -#: ../../installation.rst:261 +#: ../../installation.rst:275 msgid "" -"Now it's time to bootstrap the application and check whether all settings" -" are good and requirements are met." +"Now it's time to bootstrap the application and check whether all settings are " +"good and requirements are met." msgstr "" -"Tijd om te kijken of alles goed is ingesteld. We gaan de applicatie " -"proberen te initialiseren." +"Tijd om te kijken of alles goed is ingesteld. We gaan de applicatie proberen te " +"initialiseren." -#: ../../installation.rst:263 +#: ../../installation.rst:277 msgid "Execute this to initialize the database we've created earlier::" msgstr "Voer dit uit om de database te initialiseren::" -#: ../../installation.rst:267 +#: ../../installation.rst:281 msgid "" -"Prepare static files for webinterface. This will copy all static files to" -" the directory we created for Nginx earlier in the process. It allows us " -"to have Nginx serve static files outside our project/code root." +"Prepare static files for webinterface. This will copy all static files to the " +"directory we created for Nginx earlier in the process. It allows us to have " +"Nginx serve static files outside our project/code root." msgstr "" -"Ga nu bezit met de statische bestanden voor de webinterface. Dit kopieert" -" alle statische bestanden in de map die we eerder, vlak na de installatie" -" voor Nginx, hebben aangemaakt. Het zorgt ervoor dat Nginx deze bestanden" -" kan hosten buiten de code-bestanden." +"Ga nu bezit met de statische bestanden voor de webinterface. Dit kopieert alle " +"statische bestanden in de map die we eerder, vlak na de installatie voor Nginx, " +"hebben aangemaakt. Het zorgt ervoor dat Nginx deze bestanden kan hosten buiten " +"de code-bestanden." -#: ../../installation.rst:270 +#: ../../installation.rst:284 msgid "Sync static files::" msgstr "Synchroniseer statische bestanden::" -#: ../../installation.rst:274 +#: ../../installation.rst:288 msgid "" -"Create an application superuser. Django will prompt you for a password. " -"The credentials generated can be used to access the administration panel " -"inside the application. Alter username and email if you prefer other " -"credentials, but email is not used in the application anyway." +"Create an application superuser. Django will prompt you for a password. The " +"credentials generated can be used to access the administration panel inside the " +"application. Alter username and email if you prefer other credentials, but " +"email is not used in the application anyway." msgstr "" -"Maak een gebruiker aan voor binnen de applicatie. Django vraagt je om een" -" wachtwoord te kiezen. Met deze gegevens kun je het beheerderspaneel " -"binnen de applicatie gebruiken. Indien gewenst kun je een andere " -"gebruikersnaam kiezen. Het e-mailadres maakt niet uit, want de applicatie" -" ondersteunt toch geen e-mail." +"Maak een gebruiker aan voor binnen de applicatie. Django vraagt je om een " +"wachtwoord te kiezen. Met deze gegevens kun je het beheerderspaneel binnen de " +"applicatie gebruiken. Indien gewenst kun je een andere gebruikersnaam kiezen. " +"Het e-mailadres maakt niet uit, want de applicatie ondersteunt toch geen e-mail." -#: ../../installation.rst:277 +#: ../../installation.rst:291 msgid "Create your user::" msgstr "Creëer je eigen gebruiker::" -#: ../../installation.rst:283 +#: ../../installation.rst:297 msgid "" -"Because you have shell access you may reset your user's password at any " -"time (in case you forget it). Just enter this for a password reset::" +"Because you have shell access you may reset your user's password at any time " +"(in case you forget it). Just enter this for a password reset::" msgstr "" "Wachtwoord ooit vergeten? Via de command line kun je je wachtwoord (bij " "verlies) hiermee aanpassen::" -#: ../../installation.rst:287 +#: ../../installation.rst:301 msgid "You've almost completed the installation now." msgstr "Je bent op dit punt bijna klaar met de installatie." -#: ../../installation.rst:291 +#: ../../installation.rst:305 msgid "9. Webserver/Nginx (part 2)" msgstr "9. Webserver/Nginx (deel 2)" -#: ../../installation.rst:295 +#: ../../installation.rst:309 msgid "" -"This installation guide asumes you run the Nginx webserver for this " -"application only." +"This installation guide asumes you run the Nginx webserver for this application " +"only." msgstr "" -"Deze installatiehandleiding gaat er vanuit dat je de Nginx webserver " -"alleen gebruikt voor deze applicatie." +"Deze installatiehandleiding gaat er vanuit dat je de Nginx webserver alleen " +"gebruikt voor deze applicatie." -#: ../../installation.rst:297 +#: ../../installation.rst:311 msgid "" -"It's possible to have other applications use Nginx as well, but that " -"requires you to remove the wildcard in the ``dsmr-webinterface`` vhost, " -"which you will copy below." +"It's possible to have other applications use Nginx as well, but that requires " +"you to remove the wildcard in the ``dsmr-webinterface`` vhost, which you will " +"copy below." msgstr "" -"Het is uiteraard mogelijk dat andere applicaties ook Nginx gebruiken, " -"maar daarvoor zul je de wildcard moet weghalen in de ``dsmr-" -"webinterface`` vhost, die je hieronder kopieert." +"Het is uiteraard mogelijk dat andere applicaties ook Nginx gebruiken, maar " +"daarvoor zul je de wildcard moet weghalen in de ``dsmr-webinterface`` vhost, " +"die je hieronder kopieert." -#: ../../installation.rst:301 +#: ../../installation.rst:315 msgid "" -"Remove the default Nginx vhost (**only when you do not use it yourself, " -"see the note above**)::" +"Remove the default Nginx vhost (**only when you do not use it yourself, see the " +"note above**)::" msgstr "" -"Verwijder de standaard vhost van Nginx **wanneer je deze niet zelf " -"gebruikt** (zie de notitie hierboven)::" +"Verwijder de standaard vhost van Nginx **wanneer je deze niet zelf gebruikt** " +"(zie de notitie hierboven)::" -#: ../../installation.rst:305 +#: ../../installation.rst:319 msgid "" -"Copy application vhost, **it will listen to any hostname** (wildcard), " -"but you may change that if you feel like you need to. It won't affect the" -" application anyway::" +"Copy application vhost, **it will listen to any hostname** (wildcard), but you " +"may change that if you feel like you need to. It won't affect the application " +"anyway::" msgstr "" "Kopieer de vhost voor de applicatie. Deze luistert standaard naar **elke " -"hostname** (wildcard), maar dat is natuurlijk naar eigen wens aan te " -"passen::" +"hostname** (wildcard), maar dat is natuurlijk naar eigen wens aan te passen::" -#: ../../installation.rst:309 +#: ../../installation.rst:323 msgid "" -"Let Nginx verify vhost syntax and reload Nginx when ``configtest`` " -"passes::" +"Let Nginx verify vhost syntax and reload Nginx when ``configtest`` passes::" msgstr "" -"Laat Nginx controleren of je geen typefouten hebt gemaakt en herlaad " -"Nginx vervolgens wanneer de ``configtest`` lukt::" +"Laat Nginx controleren of je geen typefouten hebt gemaakt en herlaad Nginx " +"vervolgens wanneer de ``configtest`` lukt::" -#: ../../installation.rst:318 +#: ../../installation.rst:332 msgid "10. Supervisor" msgstr "10. Supervisor" -#: ../../installation.rst:319 +#: ../../installation.rst:333 msgid "" -"Now we configure `Supervisor `_, which is used " -"to run our application's web interface and background jobs used. It's " -"also configured to bring the entire application up again after a shutdown" -" or reboot." +"Now we configure `Supervisor `_, which is used to run " +"our application's web interface and background jobs used. It's also configured " +"to bring the entire application up again after a shutdown or reboot." msgstr "" -"We gaan nu `Supervisor `_ configureren, die " -"gebruikt wordt om de applicatie en achtergrondprocessen te draaien. " -"Tevens zorgt Supervisor ervoor dat deze processen bij het (opnieuw) " -"opstarten automatisch draaien." +"We gaan nu `Supervisor `_ configureren, die gebruikt " +"wordt om de applicatie en achtergrondprocessen te draaien. Tevens zorgt " +"Supervisor ervoor dat deze processen bij het (opnieuw) opstarten automatisch " +"draaien." -#: ../../installation.rst:322 +#: ../../installation.rst:336 msgid "Copy the configuration file for Supervisor::" msgstr "Kopieer het configuratie-bestand voor Supervisor::" -#: ../../installation.rst:326 +#: ../../installation.rst:340 msgid "Login to ``supervisorctl`` management console::" msgstr "Wissel naar de ``supervisorctl`` beheerconsole::" -#: ../../installation.rst:330 +#: ../../installation.rst:344 msgid "" -"Enter these commands (**listed after the** ``>``). It will ask Supervisor" -" to recheck its config directory and use/reload the files::" +"Enter these commands (**listed after the** ``>``). It will ask Supervisor to " +"recheck its config directory and use/reload the files::" msgstr "" -"Voer de volgende commando's in (**degene na de** ``>``). Dit zorgt ervoor" -" dat Supervisor zijn eigen configuratie opnieuw controleert en toepast::" +"Voer de volgende commando's in (**degene na de** ``>``). Dit zorgt ervoor dat " +"Supervisor zijn eigen configuratie opnieuw controleert en toepast::" -#: ../../installation.rst:336 +#: ../../installation.rst:350 msgid "" -"Three processes should be started or running. Make sure they don't end up" -" in ``ERROR`` or ``BACKOFF`` state, so refresh with the ``status`` " -"command a few times." +"Three processes should be started or running. Make sure they don't end up in " +"``ERROR`` or ``BACKOFF`` state, so refresh with the ``status`` command a few " +"times." msgstr "" "Er draaien als het goed is altijd **drie** processen. Kijk goed of ze " -"uiteindelijk niet in ``ERROR`` of ``BACKOFF`` status terecht zijn " -"gekomen. Je kunt het overzicht verversen door ``status`` te typen." +"uiteindelijk niet in ``ERROR`` of ``BACKOFF`` status terecht zijn gekomen. Je " +"kunt het overzicht verversen door ``status`` te typen." -#: ../../installation.rst:338 +#: ../../installation.rst:352 msgid "When still in ``supervisorctl``'s console, type::" msgstr "Typ het volgende wanneer je nog in ``supervisorctl``'s console bent::" -#: ../../installation.rst:342 +#: ../../installation.rst:356 msgid "Example of everything running well::" msgstr "Voorbeeld van wanneer alles naar behoren draait::" -#: ../../installation.rst:348 +#: ../../installation.rst:362 msgid "" -"Want to check whether the datalogger works? Just tail it's log in " -"supervisor with::" +"Want to check whether the datalogger works? Just tail it's log in supervisor " +"with::" msgstr "" "Wil je controleren of de datalogger zijn werk goed doet? Bekijk dan het " "logbestand in supervisor met::" -#: ../../installation.rst:352 +#: ../../installation.rst:366 msgid "" -"You should see similar output as the ``cu``-command printed earlier in " -"the installation process." +"You should see similar output as the ``cu``-command printed earlier in the " +"installation process." msgstr "" "Uiteindelijk zou je ongeveer dezelfde lap tekst moeten zien als toen we " "handmatig gemeten hebben met het ``cu``-programma." -#: ../../installation.rst:354 +#: ../../installation.rst:368 msgid "" -"Want to quit supervisor? ``CTRL + C`` to stop tailing and then ``CTRL + " -"D`` once to exit supervisor command line." +"Want to quit supervisor? ``CTRL + C`` to stop tailing and then ``CTRL + D`` " +"once to exit supervisor command line." msgstr "" -"Wil je uit supervisor? Druk dan op ``CTRL + C`` om het logbestand niet " -"meer te bekijken en vervolgens op ``CTRL + D`` om uit supervisor te gaan." +"Wil je uit supervisor? Druk dan op ``CTRL + C`` om het logbestand niet meer te " +"bekijken en vervolgens op ``CTRL + D`` om uit supervisor te gaan." -#: ../../installation.rst:357 +#: ../../installation.rst:371 msgid "" -"You now should have everything up and running! We're almost done and just" -" need to do a few last things on the next page." +"You now should have everything up and running! We're almost done and just need " +"to do a few last things on the next page." msgstr "" -"Alles zou nu moeten werken! We zijn bijna klaar, op een paar laatste " -"dingen na in het volgende hoofdstuk." +"Alles zou nu moeten werken! We zijn bijna klaar, op een paar laatste dingen na " +"in het volgende hoofdstuk." diff --git a/docs/locale/nl/LC_MESSAGES/intro.mo b/docs/locale/nl/LC_MESSAGES/intro.mo index 0aad4fe09..84916bcdf 100644 Binary files a/docs/locale/nl/LC_MESSAGES/intro.mo and b/docs/locale/nl/LC_MESSAGES/intro.mo differ diff --git a/docs/locale/nl/LC_MESSAGES/intro.po b/docs/locale/nl/LC_MESSAGES/intro.po index 44538cdfd..0313c3443 100644 --- a/docs/locale/nl/LC_MESSAGES/intro.po +++ b/docs/locale/nl/LC_MESSAGES/intro.po @@ -8,8 +8,6 @@ msgid "" msgstr "" "Project-Id-Version: DSMR Reader v1.x\n" "Report-Msgid-Bugs-To: Dennis Siemensma \n" -"POT-Creation-Date: 2017-02-18 00:28+0100\n" -"PO-Revision-Date: 2017-01-01 00:00+0100\n" "Last-Translator: Dennis Siemensma \n" "Language-Team: Dennis Siemensma \n" "MIME-Version: 1.0\n" diff --git a/docs/locale/nl/LC_MESSAGES/licence.mo b/docs/locale/nl/LC_MESSAGES/licence.mo index 65e8f241e..bb615b231 100644 Binary files a/docs/locale/nl/LC_MESSAGES/licence.mo and b/docs/locale/nl/LC_MESSAGES/licence.mo differ diff --git a/docs/locale/nl/LC_MESSAGES/licence.po b/docs/locale/nl/LC_MESSAGES/licence.po index 50ee834bd..d2448f132 100644 --- a/docs/locale/nl/LC_MESSAGES/licence.po +++ b/docs/locale/nl/LC_MESSAGES/licence.po @@ -8,8 +8,6 @@ msgid "" msgstr "" "Project-Id-Version: DSMR Reader v1.x\n" "Report-Msgid-Bugs-To: Dennis Siemensma \n" -"POT-Creation-Date: 2017-05-02 21:26+0200\n" -"PO-Revision-Date: 2017-01-01 00:00+0100\n" "Last-Translator: Dennis Siemensma \n" "Language-Team: Dennis Siemensma \n" "MIME-Version: 1.0\n" diff --git a/docs/locale/nl/LC_MESSAGES/mqtt.mo b/docs/locale/nl/LC_MESSAGES/mqtt.mo index 2b0e2318b..a81046443 100644 Binary files a/docs/locale/nl/LC_MESSAGES/mqtt.mo and b/docs/locale/nl/LC_MESSAGES/mqtt.mo differ diff --git a/docs/locale/nl/LC_MESSAGES/mqtt.po b/docs/locale/nl/LC_MESSAGES/mqtt.po index a6c901399..f1d944afb 100644 --- a/docs/locale/nl/LC_MESSAGES/mqtt.po +++ b/docs/locale/nl/LC_MESSAGES/mqtt.po @@ -8,8 +8,6 @@ msgid "" msgstr "" "Project-Id-Version: DSMR Reader 1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-06-13 17:34+0200\n" -"PO-Revision-Date: 2017-06-13 17:42+0200\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" diff --git a/docs/locale/nl/LC_MESSAGES/requirements.mo b/docs/locale/nl/LC_MESSAGES/requirements.mo index 87030c68b..89c15e25e 100644 Binary files a/docs/locale/nl/LC_MESSAGES/requirements.mo and b/docs/locale/nl/LC_MESSAGES/requirements.mo differ diff --git a/docs/locale/nl/LC_MESSAGES/requirements.po b/docs/locale/nl/LC_MESSAGES/requirements.po index 3e6c9b725..397abf3ba 100644 --- a/docs/locale/nl/LC_MESSAGES/requirements.po +++ b/docs/locale/nl/LC_MESSAGES/requirements.po @@ -8,8 +8,6 @@ msgid "" msgstr "" "Project-Id-Version: DSMR Reader 1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-06-13 21:36+0200\n" -"PO-Revision-Date: 2017-06-13 21:40+0200\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" diff --git a/docs/locale/nl/LC_MESSAGES/screenshots.mo b/docs/locale/nl/LC_MESSAGES/screenshots.mo index 891aa6e5a..732837bf3 100644 Binary files a/docs/locale/nl/LC_MESSAGES/screenshots.mo and b/docs/locale/nl/LC_MESSAGES/screenshots.mo differ diff --git a/docs/locale/nl/LC_MESSAGES/screenshots.po b/docs/locale/nl/LC_MESSAGES/screenshots.po index 41aec1d7a..3e53274ae 100644 --- a/docs/locale/nl/LC_MESSAGES/screenshots.po +++ b/docs/locale/nl/LC_MESSAGES/screenshots.po @@ -8,8 +8,6 @@ msgid "" msgstr "" "Project-Id-Version: DSMR Reader v1.x\n" "Report-Msgid-Bugs-To: Dennis Siemensma \n" -"POT-Creation-Date: 2017-02-16 15:58+0100\n" -"PO-Revision-Date: 2017-01-01 00:00+0100\n" "Last-Translator: Dennis Siemensma \n" "Language-Team: \n" "MIME-Version: 1.0\n" diff --git a/docs/locale/nl/LC_MESSAGES/settings.mo b/docs/locale/nl/LC_MESSAGES/settings.mo index c21f2a46a..ceb6862a5 100644 Binary files a/docs/locale/nl/LC_MESSAGES/settings.mo and b/docs/locale/nl/LC_MESSAGES/settings.mo differ diff --git a/docs/locale/nl/LC_MESSAGES/settings.po b/docs/locale/nl/LC_MESSAGES/settings.po index a0c58571e..9a47b41bb 100644 --- a/docs/locale/nl/LC_MESSAGES/settings.po +++ b/docs/locale/nl/LC_MESSAGES/settings.po @@ -8,8 +8,6 @@ msgid "" msgstr "" "Project-Id-Version: DSMR Reader 1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-02-19 16:32+0100\n" -"PO-Revision-Date: 2017-02-19 18:18+0100\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" diff --git a/docs/locale/nl/LC_MESSAGES/troubleshooting.mo b/docs/locale/nl/LC_MESSAGES/troubleshooting.mo index e792d9603..b9cef592b 100644 Binary files a/docs/locale/nl/LC_MESSAGES/troubleshooting.mo and b/docs/locale/nl/LC_MESSAGES/troubleshooting.mo differ diff --git a/docs/locale/nl/LC_MESSAGES/troubleshooting.po b/docs/locale/nl/LC_MESSAGES/troubleshooting.po index 70f69bc7c..807241ad5 100644 --- a/docs/locale/nl/LC_MESSAGES/troubleshooting.po +++ b/docs/locale/nl/LC_MESSAGES/troubleshooting.po @@ -8,8 +8,6 @@ msgid "" msgstr "" "Project-Id-Version: DSMR Reader 1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-02-19 18:05+0100\n" -"PO-Revision-Date: 2017-02-19 18:15+0100\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" diff --git a/dsmr_api/tests/v2/test_consumption.py b/dsmr_api/tests/v2/test_consumption.py index 9660635fd..270f3dca9 100644 --- a/dsmr_api/tests/v2/test_consumption.py +++ b/dsmr_api/tests/v2/test_consumption.py @@ -1,6 +1,35 @@ +from unittest import mock + +from django.utils import timezone + from dsmr_api.tests.v2 import APIv2TestCase +class TestToday(APIv2TestCase): + fixtures = ['dsmr_api/test_electricity_consumption.json', 'dsmr_api/test_electricity_consumption.json'] + + @mock.patch('django.utils.timezone.now') + def test_get(self, now_mock): + now_mock.return_value = timezone.make_aware(timezone.datetime(2017, 1, 1)) + + # No data. + result = self._request('today-consumption') + self.assertEqual(result, 'No electricity readings found for: 2017-01-01') + + now_mock.return_value = timezone.make_aware(timezone.datetime(2015, 12, 12, hour=12)) + result = self._request('today-consumption') + + self.assertEqual(result['day'], '2015-12-12') + + FIELDS = ( + 'day', 'electricity1', 'electricity2', 'electricity1_returned', 'electricity2_returned', + 'electricity1_cost', 'electricity2_cost', 'total_cost' + ) + + for x in FIELDS: + self.assertIn(x, result.keys()) + + class TestElectricity(APIv2TestCase): fixtures = ['dsmr_api/test_electricity_consumption.json'] diff --git a/dsmr_api/tests/v2/test_dsmrreading.py b/dsmr_api/tests/v2/test_dsmrreading.py index e9efd031d..b647ff6e3 100644 --- a/dsmr_api/tests/v2/test_dsmrreading.py +++ b/dsmr_api/tests/v2/test_dsmrreading.py @@ -65,7 +65,7 @@ def test_post(self): # Again, with UTC. TELEGRAM['timestamp'] = '2017-01-01T00:00:00Z' resultset = self._request('dsmrreading', expected_code=201, method='post', data=TELEGRAM) - self.assertEqual(resultset['timestamp'], '2017-01-01T00:00:00Z') + self.assertEqual(resultset['timestamp'], '2017-01-01T01:00:00+01:00') self.assertEqual(DsmrReading.objects.all().count(), 5) # Now with optional data. @@ -76,8 +76,8 @@ def test_post(self): TELEGRAM['phase_currently_delivered_l2'] = 0.75 TELEGRAM['phase_currently_delivered_l3'] = 0.25 resultset = self._request('dsmrreading', expected_code=201, method='post', data=TELEGRAM) - self.assertEqual(resultset['timestamp'], '2017-01-02T00:00:00Z') - self.assertEqual(resultset['extra_device_timestamp'], '2017-01-02T01:00:00Z') + self.assertEqual(resultset['timestamp'], '2017-01-02T01:00:00+01:00') + self.assertEqual(resultset['extra_device_timestamp'], '2017-01-02T02:00:00+01:00') self.assertEqual(float(resultset['extra_device_delivered']), 1234) self.assertEqual(float(resultset['phase_currently_delivered_l1']), 0.5) self.assertEqual(float(resultset['phase_currently_delivered_l2']), 0.75) diff --git a/dsmr_api/urls/v2.py b/dsmr_api/urls/v2.py index 79608e2c1..2e811c7c4 100644 --- a/dsmr_api/urls/v2.py +++ b/dsmr_api/urls/v2.py @@ -17,6 +17,7 @@ url(r'^gas$', views.GasConsumptionViewSet.as_view({ 'get': 'list', }), name='gas-consumption'), + url(r'^today$', views.TodayConsumptionView.as_view(), name='today-consumption'), ] statistics_url_patterns = [ diff --git a/dsmr_api/views/v2.py b/dsmr_api/views/v2.py index ef15c68a2..44ef0166d 100644 --- a/dsmr_api/views/v2.py +++ b/dsmr_api/views/v2.py @@ -1,4 +1,7 @@ from rest_framework import mixins, viewsets +from rest_framework.response import Response +from rest_framework.views import APIView +from django.utils import timezone from dsmr_consumption.serializers.consumption import ElectricityConsumptionSerializer, GasConsumptionSerializer from dsmr_consumption.models.consumption import ElectricityConsumption, GasConsumption @@ -8,6 +11,7 @@ from dsmr_datalogger.models.reading import DsmrReading from dsmr_api.filters import DsmrReadingFilter, DayStatisticsFilter, ElectricityConsumptionFilter,\ GasConsumptionFilter, HourStatisticsFilter +import dsmr_consumption.services class DsmrReadingViewSet(mixins.CreateModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet): @@ -19,6 +23,31 @@ class DsmrReadingViewSet(mixins.CreateModelMixin, mixins.ListModelMixin, viewset ordering = FIELD +class TodayConsumptionView(APIView): + """ Returns the consumption (so far) of the current day. """ + IGNORE_FIELDS = ( + 'electricity1_start', 'electricity2_start', 'electricity1_end', 'electricity2_end', 'notes', 'gas_start', + 'gas_end', 'electricity1_returned_start', 'electricity2_returned_start', 'electricity1_returned_end', + 'electricity2_returned_end', 'electricity_cost_merged', 'electricity_merged', 'electricity_returned_merged', + 'average_temperature', 'lowest_temperature', 'highest_temperature', 'latest_consumption' + ) + + def get(self, request): + try: + day_totals = dsmr_consumption.services.day_consumption( + day=timezone.localtime(timezone.now()).date() + ) + except LookupError as error: + return Response(str(error)) + + # Some fields are only for internal use. + for x in self.IGNORE_FIELDS: + if x in day_totals.keys(): + del day_totals[x] + + return Response(day_totals) + + class ElectricityConsumptionViewSet(viewsets.ReadOnlyModelViewSet): FIELD = 'read_at' queryset = ElectricityConsumption.objects.all() diff --git a/dsmr_backend/management/commands/development_reset.py b/dsmr_backend/management/commands/development_reset.py index 7fdca8d53..81958c1d5 100644 --- a/dsmr_backend/management/commands/development_reset.py +++ b/dsmr_backend/management/commands/development_reset.py @@ -7,27 +7,39 @@ from dsmr_mindergas.models.settings import MinderGasSettings from dsmr_notification.models.settings import NotificationSetting from dsmr_api.models import APISettings +from dsmr_frontend.models.message import Notification class Command(BaseCommand): help = _('Resets the environment for development purposes. Not intended for production.') + def add_arguments(self, parser): + super(Command, self).add_arguments(parser) + parser.add_argument( + '--no-api', + action='store_true', + dest='no_api', + default=False, + help=_('Whether the API should be disabled.') + ) + def handle(self, **options): if not settings.DEBUG: raise CommandError(_('Intended usage is NOT production! Only allowed when DEBUG = True')) # Just wipe all settings which can affect the environment. - APISettings.objects.update(allow=True, auth_key='test') + APISettings.objects.update(allow=not options['no_api'], auth_key='test') BackupSettings.objects.update(daily_backup=False) DropboxSettings.objects.update(access_token=None) MinderGasSettings.objects.update(export=False, auth_token=None) NotificationSetting.objects.update(send_notification=False, api_key=None) + Notification.objects.update(read=True) try: # Reset passwd. - admin = User.objects.get(pk=1) + admin = User.objects.get(username='admin') except User.DoesNotExist: - pass + User.objects.create_superuser('admin', 'root@localhost', 'admin') else: admin.set_password('admin') admin.save() diff --git a/dsmr_backend/management/commands/dsmr_backend_delete_aggregated_data.py b/dsmr_backend/management/commands/dsmr_backend_delete_aggregated_data.py index c233bd2b9..c3fc90942 100644 --- a/dsmr_backend/management/commands/dsmr_backend_delete_aggregated_data.py +++ b/dsmr_backend/management/commands/dsmr_backend_delete_aggregated_data.py @@ -1,4 +1,4 @@ -from django.core.management.base import BaseCommand, CommandError +from django.core.management.base import BaseCommand from django.utils.translation import ugettext as _ import dsmr_consumption.services @@ -13,22 +13,7 @@ class Command(BaseCommand): 'each and EVERY reading stored, as the application will attempt to recalculate all aggregated data deleted ' 'retroactively, using each reading stored.') - def add_arguments(self, parser): - super(Command, self).add_arguments(parser) - parser.add_argument( - '--ack-to-delete-my-data', - action='store_true', - dest='acked_warning', - default=False, - help=_('Required to acknowledge you that you WILL delete your statistics with this.') - ) - def handle(self, **options): - if not options.get('acked_warning'): - raise CommandError(_( - 'Intended usage is NOT production! Force by using --ack-to-delete-my-data' - )) - print(' - Clearing consumption data') dsmr_consumption.services.clear_consumption() diff --git a/dsmr_backend/tests/test_delete_aggregated_data.py b/dsmr_backend/tests/test_delete_aggregated_data.py index 26c98cc21..bd07b1cd0 100644 --- a/dsmr_backend/tests/test_delete_aggregated_data.py +++ b/dsmr_backend/tests/test_delete_aggregated_data.py @@ -1,7 +1,6 @@ from unittest import mock from django.test.testcases import TestCase -from django.core.management.base import CommandError from dsmr_backend.tests.mixins import InterceptStdoutMixin from dsmr_datalogger.models.reading import DsmrReading @@ -13,15 +12,10 @@ class TestManagementCommand(InterceptStdoutMixin, TestCase): @mock.patch('dsmr_consumption.services.clear_consumption') @mock.patch('dsmr_stats.services.clear_statistics') def test_dsmr_stats_clear_statistics(self, *mocks): - expected_error = 'Intended usage is NOT production! Force by using --ack-to-delete-my-data' - self.assertTrue(DsmrReading.objects.filter(processed=True).exists()) - with self.assertRaisesMessage(CommandError, expected_error): - self._intercept_command_stdout('dsmr_backend_delete_aggregated_data') - self.assertFalse(all([x.called for x in mocks])) - self._intercept_command_stdout('dsmr_backend_delete_aggregated_data', acked_warning=True) + self._intercept_command_stdout('dsmr_backend_delete_aggregated_data') self.assertTrue(all([x.called for x in mocks])) self.assertFalse(DsmrReading.objects.filter(processed=True).exists()) diff --git a/dsmr_backup/services/backup.py b/dsmr_backup/services/backup.py index 456828e2f..c8f24f8ae 100644 --- a/dsmr_backup/services/backup.py +++ b/dsmr_backup/services/backup.py @@ -58,7 +58,7 @@ def create(): settings.DSMRREADER_BACKUP_PG_DUMP, '--host={}'.format(settings.DATABASES['default']['HOST']), '--user={}'.format(settings.DATABASES['default']['USER']), - '--dbname={}'.format(settings.DATABASES['default']['NAME']), + settings.DATABASES['default']['NAME'], ], env={ 'PGPASSWORD': settings.DATABASES['default']['PASSWORD'] }, diff --git a/dsmr_consumption/fixtures/dsmr_consumption/test_energysupplierprice.json b/dsmr_consumption/fixtures/dsmr_consumption/test_energysupplierprice.json new file mode 100644 index 000000000..20ea49aa0 --- /dev/null +++ b/dsmr_consumption/fixtures/dsmr_consumption/test_energysupplierprice.json @@ -0,0 +1,14 @@ +[{ + "model": "dsmr_consumption.energysupplierprice", + "pk": 1, + "fields": { + "start": "2015-01-01", + "end": null, + "description": "Test", + "electricity_delivered_1_price": "1.00000", + "electricity_delivered_2_price": "2.00000", + "gas_price": "5.00000", + "electricity_returned_1_price": "0.50000", + "electricity_returned_2_price": "1.50000" + } +}] \ No newline at end of file diff --git a/dsmr_consumption/migrations/0008_energysupplier_return_prices.py b/dsmr_consumption/migrations/0008_energysupplier_return_prices.py new file mode 100644 index 000000000..5561b4eab --- /dev/null +++ b/dsmr_consumption/migrations/0008_energysupplier_return_prices.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2017-09-26 19:34 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dsmr_consumption', '0007_settings_documentation'), + ] + + operations = [ + migrations.RenameField( + model_name='energysupplierprice', + old_name='electricity_1_price', + new_name='electricity_delivered_1_price', + ), + migrations.RenameField( + model_name='energysupplierprice', + old_name='electricity_2_price', + new_name='electricity_delivered_2_price', + ), + migrations.AddField( + model_name='energysupplierprice', + name='electricity_returned_1_price', + field=models.DecimalField(decimal_places=5, default=0, help_text='Set to zero when unused', max_digits=11, verbose_name='Electricity returned 1 price (low tariff)'), + ), + migrations.AddField( + model_name='energysupplierprice', + name='electricity_returned_2_price', + field=models.DecimalField(decimal_places=5, default=0, help_text='Set to zero when unused', max_digits=11, verbose_name='Electricity returned 2 price (high tariff)'), + ), + migrations.AlterField( + model_name='energysupplierprice', + name='gas_price', + field=models.DecimalField(decimal_places=5, default=0, help_text='Set to zero when unused', max_digits=11, verbose_name='Gas price'), + ), + ] diff --git a/dsmr_consumption/models/consumption.py b/dsmr_consumption/models/consumption.py index 309b836ba..98b1da844 100644 --- a/dsmr_consumption/models/consumption.py +++ b/dsmr_consumption/models/consumption.py @@ -62,6 +62,15 @@ class ElectricityConsumption(models.Model): db_index=True ) + def __sub__(self, other): + """ Allows models to be subtracted from each other. """ + data = {} + + for current in ('delivered_1', 'returned_1', 'delivered_2', 'returned_2'): + data.update({current: getattr(self, current) - getattr(other, current)}) + + return data + def __str__(self): return '{} | {}: {} Watt'.format( self.__class__.__name__, self.read_at, self.currently_delivered * 1000 diff --git a/dsmr_consumption/models/energysupplier.py b/dsmr_consumption/models/energysupplier.py index 6ce4f0359..492139dad 100644 --- a/dsmr_consumption/models/energysupplier.py +++ b/dsmr_consumption/models/energysupplier.py @@ -26,7 +26,7 @@ class EnergySupplierPrice(models.Model): max_length=255, null=True, blank=True, verbose_name=_('Description'), help_text=_('For your own reference, i.e. the name of your supplier') ) - electricity_1_price = models.DecimalField( + electricity_delivered_1_price = models.DecimalField( max_digits=11, decimal_places=5, default=0, @@ -36,7 +36,7 @@ class EnergySupplierPrice(models.Model): 'in the frontend configuration' ) ) - electricity_2_price = models.DecimalField( + electricity_delivered_2_price = models.DecimalField( max_digits=11, decimal_places=5, default=0, @@ -46,7 +46,27 @@ class EnergySupplierPrice(models.Model): 'in the frontend configuration' ) ) - gas_price = models.DecimalField(max_digits=11, decimal_places=5, default=0, verbose_name=_('Gas price')) + gas_price = models.DecimalField( + max_digits=11, + decimal_places=5, + default=0, + verbose_name=_('Gas price'), + help_text=_('Set to zero when unused') + ) + electricity_returned_1_price = models.DecimalField( + max_digits=11, + decimal_places=5, + default=0, + verbose_name=_('Electricity returned 1 price (low tariff)'), + help_text=_('Set to zero when unused') + ) + electricity_returned_2_price = models.DecimalField( + max_digits=11, + decimal_places=5, + default=0, + verbose_name=_('Electricity returned 2 price (high tariff)'), + help_text=_('Set to zero when unused') + ) def __str__(self): return self.description or ugettext('Energy Supplier') diff --git a/dsmr_consumption/services.py b/dsmr_consumption/services.py index 34832a902..523b76627 100644 --- a/dsmr_consumption/services.py +++ b/dsmr_consumption/services.py @@ -169,10 +169,10 @@ def day_consumption(day): try: # This WILL fail when we either have no prices at all or conflicting ranges. - consumption['daily_energy_price'] = EnergySupplierPrice.objects.by_date(target_date=day) + daily_energy_price = EnergySupplierPrice.objects.by_date(target_date=day) except (EnergySupplierPrice.DoesNotExist, EnergySupplierPrice.MultipleObjectsReturned): # Default to zero prices. - consumption['daily_energy_price'] = EnergySupplierPrice() + daily_energy_price = EnergySupplierPrice() electricity_readings, gas_readings = consumption_by_range(start=day_start, end=day_end) @@ -183,6 +183,8 @@ def day_consumption(day): first_reading = electricity_readings[0] last_reading = electricity_readings[electricity_reading_count - 1] + + consumption['latest_consumption'] = last_reading consumption['electricity1'] = last_reading.delivered_1 - first_reading.delivered_1 consumption['electricity2'] = last_reading.delivered_2 - first_reading.delivered_2 consumption['electricity1_start'] = first_reading.delivered_1 @@ -195,21 +197,23 @@ def day_consumption(day): consumption['electricity1_returned_end'] = last_reading.returned_1 consumption['electricity2_returned_start'] = first_reading.returned_2 consumption['electricity2_returned_end'] = last_reading.returned_2 - consumption['electricity1_unit_price'] = consumption['daily_energy_price'].electricity_1_price - consumption['electricity2_unit_price'] = consumption['daily_energy_price'].electricity_2_price + consumption['electricity_merged'] = consumption['electricity1'] + consumption['electricity2'] + consumption['electricity_returned_merged'] = \ + consumption['electricity1_returned'] + consumption['electricity2_returned'] + + # Cost per tariff + direction. consumption['electricity1_cost'] = round_decimal( - consumption['electricity1'] * consumption['electricity1_unit_price'] + (consumption['electricity1'] * daily_energy_price.electricity_delivered_1_price) - + (consumption['electricity1_returned'] * daily_energy_price.electricity_returned_1_price) ) consumption['electricity2_cost'] = round_decimal( - consumption['electricity2'] * consumption['electricity2_unit_price'] + (consumption['electricity2'] * daily_energy_price.electricity_delivered_2_price) - + (consumption['electricity2_returned'] * daily_energy_price.electricity_returned_2_price) ) - consumption['electricity_merged'] = consumption['electricity1'] + consumption['electricity2'] - consumption['electricity_returned_merged'] = \ - consumption['electricity1_returned'] + consumption['electricity2_returned'] + + # Totals. consumption['electricity_cost_merged'] = consumption['electricity1_cost'] + consumption['electricity2_cost'] - consumption['total_cost'] = round_decimal( - consumption['electricity1_cost'] + consumption['electricity2_cost'] - ) + consumption['total_cost'] = round_decimal(consumption['electricity_cost_merged']) # Gas readings are optional, as not all meters support this. if gas_readings.exists(): @@ -219,9 +223,8 @@ def day_consumption(day): consumption['gas'] = last_reading.delivered - first_reading.delivered consumption['gas_start'] = first_reading.delivered consumption['gas_end'] = last_reading.delivered - consumption['gas_unit_price'] = consumption['daily_energy_price'].gas_price consumption['gas_cost'] = round_decimal( - consumption['gas'] * consumption['gas_unit_price'] + consumption['gas'] * daily_energy_price.gas_price ) consumption['total_cost'] += consumption['gas_cost'] @@ -240,6 +243,7 @@ def day_consumption(day): consumption['average_temperature'] = temperature_readings.aggregate( avg_temperature=Avg('degrees_celcius'), )['avg_temperature'] or 0 + consumption['average_temperature'] = round_decimal(consumption['average_temperature']) return consumption diff --git a/dsmr_consumption/tests/models/test_energysupplier.py b/dsmr_consumption/tests/models/test_energysupplier.py index 428959f5e..b329b33ee 100644 --- a/dsmr_consumption/tests/models/test_energysupplier.py +++ b/dsmr_consumption/tests/models/test_energysupplier.py @@ -11,9 +11,11 @@ def setUp(self): start=timezone.now(), end=timezone.now(), description='Test', - electricity_1_price=1, - electricity_2_price=2, + electricity_delivered_1_price=1, + electricity_delivered_2_price=2, gas_price=3, + electricity_returned_1_price=1, + electricity_returned_2_price=2, ) def test_admin(self): diff --git a/dsmr_consumption/tests/test_services.py b/dsmr_consumption/tests/test_services.py index 8f9131a13..8ff0f5a2d 100644 --- a/dsmr_consumption/tests/test_services.py +++ b/dsmr_consumption/tests/test_services.py @@ -13,7 +13,7 @@ class TestServices(InterceptStdoutMixin, TestCase): - fixtures = ['dsmr_consumption/test_dsmrreading.json'] + fixtures = ['dsmr_consumption/test_dsmrreading.json', 'dsmr_consumption/test_energysupplierprice.json'] support_gas_readings = None def setUp(self): @@ -138,9 +138,9 @@ def test_day_consumption(self): ElectricityConsumption.objects.create( read_at=now, # Now. delivered_1=1, - returned_1=1, + returned_1=1.5, delivered_2=2, - returned_2=2, + returned_2=2.5, currently_delivered=10, currently_returned=20, ) @@ -166,9 +166,14 @@ def test_day_consumption(self): data = dsmr_consumption.services.day_consumption(day=now) self.assertIsInstance(data, dict) self.assertEqual(data['electricity1'], 1) - self.assertEqual(data['electricity1_returned'], 2) + self.assertEqual(data['electricity1_returned'], Decimal('1.5')) self.assertEqual(data['electricity2'], 3) - self.assertEqual(data['electricity2_returned'], 4) + self.assertEqual(data['electricity2_returned'], Decimal('3.5')) + self.assertEqual(data['electricity_merged'], 4) + self.assertEqual(data['electricity_returned_merged'], 5) + self.assertEqual(data['electricity1_cost'], Decimal('0.25')) + self.assertEqual(data['electricity2_cost'], Decimal('0.75')) + self.assertEqual(data['total_cost'], 1) GasConsumption.objects.create( read_at=now, # Now. @@ -298,7 +303,7 @@ def test_clear_consumption(self): class TestServicesDSMRv5(InterceptStdoutMixin, TestCase): """ Biggest difference is the interval of gas readings. """ - fixtures = ['dsmr_consumption/test_dsmrreading_v5.json'] + fixtures = ['dsmr_consumption/test_dsmrreading_v5.json', 'dsmr_consumption/test_energysupplierprice.json'] def setUp(self): self.assertEqual(DsmrReading.objects.all().count(), 6) @@ -333,7 +338,7 @@ def test_processing_ungrouped(self): class TestServicesWithoutGas(TestServices): - fixtures = ['dsmr_consumption/test_dsmrreading_without_gas.json'] + fixtures = ['dsmr_consumption/test_dsmrreading_without_gas.json', 'dsmr_consumption/test_energysupplierprice.json'] def setUp(self): super(TestServicesWithoutGas, self).setUp() diff --git a/dsmr_datalogger/management/commands/dsmr_fake_datasource.py b/dsmr_datalogger/management/commands/dsmr_fake_datasource.py index cf9417bb3..06cca1fe1 100644 --- a/dsmr_datalogger/management/commands/dsmr_fake_datasource.py +++ b/dsmr_datalogger/management/commands/dsmr_fake_datasource.py @@ -40,6 +40,13 @@ def add_arguments(self, parser): default=False, help=_('Include electricity returned (solar panels)') ) + parser.add_argument( + '--hour-offset', + action='store', + dest='hour_offset', + default=0, + help=_('The offset in hours, can both be positive as negative (to go back in time).') + ) def run(self, **options): """ InfiniteManagementCommandMixin listens to handle() and calls run() in a loop. """ @@ -49,14 +56,19 @@ def run(self, **options): if not options.get('acked_warning'): raise CommandError(_('Intended usage is NOT production! Force by using --ack-to-mess-up-my-data')) - telegram = self._generate_data(options['with_gas'], options['with_electricity_returned']) + telegram = self._generate_data( + options['with_gas'], + options['with_electricity_returned'], + options['hour_offset'] + ) print(telegram) # For convenience dsmr_datalogger.services.telegram_to_reading(data=telegram) - def _generate_data(self, with_gas, with_electricity_returned): + def _generate_data(self, with_gas, with_electricity_returned, hour_offset): """ Generates 'random' data, but in a way that it keeps incrementing. """ - now = timezone.localtime(timezone.now()) # Must be local. + now = timezone.now() + timezone.timedelta(hours=int(hour_offset)) + now = timezone.localtime(now) # Must be local. self.stdout.write('-' * 32) self.stdout.write(str(now)) @@ -66,7 +78,8 @@ def _generate_data(self, with_gas, with_electricity_returned): self.stdout.write('') # 1420070400: 01 Jan 2015 00:00:00 GMT - second_since = int(time.time() - 1420070400) + current_unix_time = time.mktime(now.timetuple()) + second_since = int(current_unix_time - 1420070400) electricity_base = second_since * 0.00005 # Averages around 1500/1600 kWh for a year. electricity_1 = electricity_base @@ -80,7 +93,7 @@ def _generate_data(self, with_gas, with_electricity_returned): if with_electricity_returned: electricity_1_returned = electricity_1 * 0.1 # Random though of solar panel during night. - electricity_2_returned = electricity_1 * 1.05 # Random number. + electricity_2_returned = electricity_1 * 1.25 # Random number. currently_returned = random.randint(0, 2500) * 0.001 # kW data = [ diff --git a/dsmr_frontend/fixtures/dsmr_frontend/EnergySupplierPrice.json b/dsmr_frontend/fixtures/dsmr_frontend/EnergySupplierPrice.json index 25d124a9a..10c944d75 100644 --- a/dsmr_frontend/fixtures/dsmr_frontend/EnergySupplierPrice.json +++ b/dsmr_frontend/fixtures/dsmr_frontend/EnergySupplierPrice.json @@ -2,10 +2,10 @@ { "fields": { "start": "2015-01-01", - "electricity_1_price": "0.20123", + "electricity_delivered_1_price": "0.20123", "gas_price": "0.58685", "end": "2016-01-25", - "electricity_2_price": "0.40123", + "electricity_delivered_2_price": "0.40123", "description": "Nederlandse Energie Maatschappij" }, "model": "dsmr_consumption.energysupplierprice", diff --git a/dsmr_frontend/static/dsmr_frontend/css/dsmrreader.css b/dsmr_frontend/static/dsmr_frontend/css/dsmrreader.css index 5a080e0d8..67684f2cb 100644 --- a/dsmr_frontend/static/dsmr_frontend/css/dsmrreader.css +++ b/dsmr_frontend/static/dsmr_frontend/css/dsmrreader.css @@ -26,4 +26,9 @@ div.copyright { -ms-transform: rotate(315deg); -o-transform: rotate(315deg); transform: rotate(315deg); +} + +div.date-selector { + min-height: 100px; + height: 100px; } \ No newline at end of file diff --git a/dsmr_frontend/templates/dsmr_frontend/archive.html b/dsmr_frontend/templates/dsmr_frontend/archive.html index e7f40932e..9d5b1c0b2 100644 --- a/dsmr_frontend/templates/dsmr_frontend/archive.html +++ b/dsmr_frontend/templates/dsmr_frontend/archive.html @@ -24,15 +24,15 @@
-
+
{% trans "Days" %}
-
+
{% trans "Months" %}
-
+
{% trans "Years" %}
diff --git a/dsmr_frontend/templates/dsmr_frontend/base.html b/dsmr_frontend/templates/dsmr_frontend/base.html index 87b41bf57..8b3d83b16 100644 --- a/dsmr_frontend/templates/dsmr_frontend/base.html +++ b/dsmr_frontend/templates/dsmr_frontend/base.html @@ -8,7 +8,11 @@ {% block title %}{% endblock %} | DSMR Reader + + + + {% block stylesheets %} @@ -18,6 +22,7 @@ {% endblock %} + @@ -119,7 +124,7 @@
  • - + {% trans "Configuration" %}  
  • diff --git a/dsmr_frontend/templates/dsmr_frontend/compare.html b/dsmr_frontend/templates/dsmr_frontend/compare.html index 2415e81cd..529a741f7 100644 --- a/dsmr_frontend/templates/dsmr_frontend/compare.html +++ b/dsmr_frontend/templates/dsmr_frontend/compare.html @@ -25,15 +25,15 @@
    -
    +
    {% trans "Days" %}
    -
    +
    {% trans "Months" %}
    -
    +
    {% trans "Years" %}
    diff --git a/dsmr_frontend/templates/dsmr_frontend/dashboard.html b/dsmr_frontend/templates/dsmr_frontend/dashboard.html index 7cdb08d72..e558c3e50 100644 --- a/dsmr_frontend/templates/dsmr_frontend/dashboard.html +++ b/dsmr_frontend/templates/dsmr_frontend/dashboard.html @@ -18,7 +18,7 @@ {% endblock %} {% block header_right %} -
  • +
  • diff --git a/dsmr_frontend/templates/dsmr_frontend/fragments/archive-xhr-statistics.html b/dsmr_frontend/templates/dsmr_frontend/fragments/archive-xhr-statistics.html index b6134a4de..ddb3ae89b 100644 --- a/dsmr_frontend/templates/dsmr_frontend/fragments/archive-xhr-statistics.html +++ b/dsmr_frontend/templates/dsmr_frontend/fragments/archive-xhr-statistics.html @@ -28,7 +28,7 @@ {% if capabilities.electricity %}{% trans "Electricity (single tariff)" %}{% endif %} {% if capabilities.electricity %}{{ statistics.electricity_merged|default:'-'|floatformat:2 }} {% endif %} {% if capabilities.electricity_returned %}{{ statistics.electricity_returned_merged|default:'-'|floatformat:2 }}{% endif %} - {% if energy_price %}{{ energy_price.electricity_1_price|default:'-' }}{% endif %} + {% if energy_price %}{{ energy_price.electricity_delivered_1_price|default:'-' }}{% endif %} {% if capabilities.electricity %}{{ statistics.electricity_cost_merged|default:'-' }}{% endif %} {% else %} @@ -36,14 +36,14 @@ {% if capabilities.electricity %}{% trans "Electricity 1 (low tariff)" %}{% endif %} {% if capabilities.electricity %}{{ statistics.electricity1|default:'-'|floatformat:2 }} {% endif %} {% if capabilities.electricity_returned %}{{ statistics.electricity1_returned|default:'-'|floatformat:2 }}{% endif %} - {% if energy_price %}{{ energy_price.electricity_1_price|default:'-' }}{% endif %} + {% if energy_price %}{{ energy_price.electricity_delivered_1_price|default:'-' }}{% endif %} {% if capabilities.electricity %}{{ statistics.electricity1_cost|default:'-' }}{% endif %} {% if capabilities.electricity %}{% trans "Electricity 2 (high tariff)" %}{% endif %} {% if capabilities.electricity %}{{ statistics.electricity2|default:'-'|floatformat:2 }}{% endif %} {% if capabilities.electricity_returned %}{{ statistics.electricity2_returned|default:'-'|floatformat:2 }}{% endif %} - {% if energy_price %}{{ energy_price.electricity_2_price|default:'-' }}{% endif %} + {% if energy_price %}{{ energy_price.electricity_delivered_2_price|default:'-' }}{% endif %} {% if capabilities.electricity %}{{ statistics.electricity2_cost|default:'-' }}{% endif %} {% endif %} diff --git a/dsmr_frontend/templates/dsmr_frontend/statistics.html b/dsmr_frontend/templates/dsmr_frontend/statistics.html index f8e8887af..40163908f 100644 --- a/dsmr_frontend/templates/dsmr_frontend/statistics.html +++ b/dsmr_frontend/templates/dsmr_frontend/statistics.html @@ -213,11 +213,11 @@ {% trans "Electricity 1 price (low tariff)" %} - {{ energy_prices.electricity_1_price }} + {{ energy_prices.electricity_delivered_1_price }} {% trans "Electricity 2 price (high tariff)" %} - {{ energy_prices.electricity_2_price }} + {{ energy_prices.electricity_delivered_2_price }} {% trans "Gas price" %} diff --git a/dsmr_frontend/templates/dsmr_frontend/status.html b/dsmr_frontend/templates/dsmr_frontend/status.html index 86e1e5c5a..385bb815f 100644 --- a/dsmr_frontend/templates/dsmr_frontend/status.html +++ b/dsmr_frontend/templates/dsmr_frontend/status.html @@ -371,6 +371,9 @@ check_for_updates(); return false; }); + + setInterval(function(){ location.reload(); }, 10000); + }); /** diff --git a/dsmr_frontend/tests/webinterface/test_dashboard.py b/dsmr_frontend/tests/webinterface/test_dashboard.py index 23588664c..6a5557560 100644 --- a/dsmr_frontend/tests/webinterface/test_dashboard.py +++ b/dsmr_frontend/tests/webinterface/test_dashboard.py @@ -5,6 +5,7 @@ from django.utils import timezone from django.core.urlresolvers import reverse from django.contrib.auth.models import User +from django.db.models import F from dsmr_consumption.models.consumption import ElectricityConsumption, GasConsumption from dsmr_consumption.models.energysupplier import EnergySupplierPrice @@ -13,6 +14,7 @@ from dsmr_weather.models.settings import WeatherSettings from dsmr_stats.models.statistics import DayStatistics from dsmr_frontend.models.message import Notification +from dsmr_datalogger.models.reading import DsmrReading import dsmr_consumption.services @@ -83,6 +85,16 @@ def test_dashboard_xhr_header(self, now_mock): json_response['latest_electricity_cost'], '0.23' if current_tariff == 1 else '0.46' ) + def test_dashboard_xhr_header_future(self): + # Set timestamp to the future, so the view will reset the timestamp displayed to 'now'. + DsmrReading.objects.all().update(timestamp=F('timestamp') + timezone.timedelta(weeks=999)) + + response = self.client.get( + reverse('{}:dashboard-xhr-header'.format(self.namespace)) + ) + self.assertEqual(response.status_code, 200, response.content) + self.assertEqual(response['Content-Type'], 'application/json') + @mock.patch('django.utils.timezone.now') def test_dashboard_xhr_graphs(self, now_mock): now_mock.return_value = timezone.make_aware(timezone.datetime(2015, 11, 15)) diff --git a/dsmr_frontend/views/dashboard.py b/dsmr_frontend/views/dashboard.py index 8f6a3e676..7557f0a45 100644 --- a/dsmr_frontend/views/dashboard.py +++ b/dsmr_frontend/views/dashboard.py @@ -61,7 +61,13 @@ def get(self, request): # Don't even bother when no data available. return HttpResponse(json.dumps(data), content_type='application/json') - data['timestamp'] = naturaltime(latest_reading.timestamp) + latest_timestamp = latest_reading.timestamp + + # In case the smart meter is running a clock in the future. + if latest_timestamp > timezone.now(): + latest_timestamp = timezone.now() + + data['timestamp'] = naturaltime(latest_timestamp) data['currently_delivered'] = int(latest_reading.electricity_currently_delivered * 1000) data['currently_returned'] = int(latest_reading.electricity_currently_returned * 1000) @@ -77,8 +83,8 @@ def get(self, request): cost_per_hour = None tariff_map = { - 1: prices.electricity_1_price, - 2: prices.electricity_2_price, + 1: prices.electricity_delivered_1_price, + 2: prices.electricity_delivered_2_price, } try: diff --git a/dsmr_mindergas/tests/test_services.py b/dsmr_mindergas/tests/test_services.py index 9f135e1ed..5c7e72455 100644 --- a/dsmr_mindergas/tests/test_services.py +++ b/dsmr_mindergas/tests/test_services.py @@ -10,7 +10,6 @@ class TestServices(TestCase): - """ Test 'dsmr_backend' management command. """ fixtures = ['dsmr_mindergas/gas-consumption.json'] @mock.patch('django.utils.timezone.now') @@ -22,6 +21,7 @@ def test_should_export_default(self, now_mock): self.assertFalse(settings.export) self.assertIsNone(settings.auth_token) self.assertIsNone(settings.next_export) + self.assertFalse(dsmr_mindergas.services.should_export()) @mock.patch('django.utils.timezone.now') diff --git a/dsmr_pvoutput/__init__.py b/dsmr_pvoutput/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/dsmr_pvoutput/admin.py b/dsmr_pvoutput/admin.py new file mode 100644 index 000000000..9dd6d5467 --- /dev/null +++ b/dsmr_pvoutput/admin.py @@ -0,0 +1,25 @@ +from django.contrib import admin +from django.utils.translation import ugettext_lazy as _ +from solo.admin import SingletonModelAdmin + +from dsmr_pvoutput.models.settings import PVOutputAPISettings, PVOutputAddStatusSettings + + +@admin.register(PVOutputAPISettings) +class PVOutputAPISettingsAdmin(SingletonModelAdmin): + pass + + +@admin.register(PVOutputAddStatusSettings) +class PVOutputAddStatusSettingsAdmin(SingletonModelAdmin): + readonly_fields = ['next_export'] + fieldsets = ( + ( + None, { + 'fields': ['export', 'upload_interval', 'upload_delay', 'processing_delay', 'next_export'], + 'description': _( + 'Implements the following API call: https://pvoutput.org/help.html#api-addstatus' + ) + } + ), + ) diff --git a/dsmr_pvoutput/apps.py b/dsmr_pvoutput/apps.py new file mode 100644 index 000000000..b89e2d067 --- /dev/null +++ b/dsmr_pvoutput/apps.py @@ -0,0 +1,20 @@ +from django.apps import AppConfig +from django.utils.translation import ugettext_lazy as _ + +import dsmr_backend.signals + + +class AppConfig(AppConfig): + name = 'dsmr_pvoutput' + verbose_name = _('PVOutput') + + def ready(self): + dsmr_backend.signals.backend_called.connect( + receiver=self._on_backend_called_signal, + dispatch_uid=self.__class__ + ) + + def _on_backend_called_signal(self, sender, **kwargs): + # Import below prevents an AppRegistryNotReady error on Django init. + import dsmr_pvoutput.services + dsmr_pvoutput.services.export() diff --git a/dsmr_pvoutput/fixtures/dsmr_pvoutput/electricity-consumption.json b/dsmr_pvoutput/fixtures/dsmr_pvoutput/electricity-consumption.json new file mode 100644 index 000000000..7cc816524 --- /dev/null +++ b/dsmr_pvoutput/fixtures/dsmr_pvoutput/electricity-consumption.json @@ -0,0 +1,41 @@ +[ +{ + "pk": 1, + "fields": { + "delivered_1": "2000.000", + "delivered_2": "1500.000", + "returned_1": "1000.000", + "returned_2": "250.000", + "currently_returned": "0.500", + "currently_delivered": "1.500", + "read_at": "2017-10-01T02:00:00Z" + }, + "model": "dsmr_consumption.electricityconsumption" +}, +{ + "pk": 11, + "fields": { + "delivered_1": "2003.000", + "delivered_2": "1500.000", + "returned_1": "1005.000", + "returned_2": "250.000", + "currently_returned": "1.750", + "currently_delivered": "1.000", + "read_at": "2017-10-01T11:00:00Z" + }, + "model": "dsmr_consumption.electricityconsumption" +}, +{ + "pk": 12, + "fields": { + "delivered_1": "2005.000", + "delivered_2": "1500.000", + "returned_1": "1006.000", + "returned_2": "250.000", + "currently_returned": "1.050", + "currently_delivered": "1.500", + "read_at": "2017-10-01T13:00:00Z" + }, + "model": "dsmr_consumption.electricityconsumption" +} +] diff --git a/dsmr_pvoutput/migrations/0001_pvoutput_settings.py b/dsmr_pvoutput/migrations/0001_pvoutput_settings.py new file mode 100644 index 000000000..c4db2e9c0 --- /dev/null +++ b/dsmr_pvoutput/migrations/0001_pvoutput_settings.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2017-10-06 15:22 +from __future__ import unicode_literals + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='PVOutputAddStatusSettings', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('export', models.BooleanField(default=False, help_text='Whether the system uploads consumption using the Add Status Service API call.', verbose_name='Enabled')), + ('upload_interval', models.IntegerField(choices=[(5, '5 minutes'), (10, '10 minutes'), (15, '15 minutes')], default=5, help_text='The interval between each upload (in minutes). Please make sure this matches the device settings.', verbose_name='Upload interval')), + ('upload_delay', models.IntegerField(default=0, help_text='An artificial delay in uploading data to PVOutput. E.g.: When you set this to "5" and the application uploads the data at 10:45, then only data between 0:00 and 10:40 will be taken into account for upload at that moment. It effectively limits its upload data search by "X minutes ago".', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(30)], verbose_name='Upload delay (minutes)')), + ('processing_delay', models.IntegerField(blank=True, default=None, help_text='[!]: This feature is ONLY available when you have a DONATOR account for PVOutput.org! Leave EMPTY to disable the feature. This parameter allows the processing of the data to be delayed, by the specified number of minutes. Allowed values: empty or 0 to 120 (minutes)', null=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(120)], verbose_name='PVOutput: Processing delay (minutes)')), + ('next_export', models.DateTimeField(blank=True, default=None, help_text='Timestamp of the next export. Automatically updated by application.', null=True, verbose_name='Next export')), + ], + options={ + 'verbose_name': 'PVOutput: Add Status configuration', + 'default_permissions': (), + }, + ), + migrations.CreateModel( + name='PVOutputAPISettings', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('auth_token', models.CharField(blank=True, default=None, help_text='The API key for your PVOutput account. Listed in PVOutput at Settings -> "API Settings".', max_length=256, null=True, verbose_name='API key')), + ('system_identifier', models.CharField(blank=True, default=None, help_text='The "System ID" for your device. Listed in PVOutput at Settings -> "Registered Systems".', max_length=32, null=True, verbose_name='System ID (digit)')), + ], + options={ + 'verbose_name': 'PVOutput: API configuration', + 'default_permissions': (), + }, + ), + ] diff --git a/dsmr_pvoutput/migrations/__init__.py b/dsmr_pvoutput/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/dsmr_pvoutput/models/__init__.py b/dsmr_pvoutput/models/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/dsmr_pvoutput/models/settings.py b/dsmr_pvoutput/models/settings.py new file mode 100644 index 000000000..a6d6a8506 --- /dev/null +++ b/dsmr_pvoutput/models/settings.py @@ -0,0 +1,94 @@ +from django.db import models +from django.utils.translation import ugettext_lazy as _ +from django.core.validators import MinValueValidator, MaxValueValidator +from solo.models import SingletonModel + + +class PVOutputAPISettings(SingletonModel): + auth_token = models.CharField( + max_length=256, + null=True, + blank=True, + default=None, + verbose_name=_('API key'), + help_text=_('The API key for your PVOutput account. Listed in PVOutput at Settings -> "API Settings".') + ) + system_identifier = models.CharField( + null=True, + blank=True, + default=None, + max_length=32, + verbose_name=_('System ID (digit)'), + help_text=_('The "System ID" for your device. Listed in PVOutput at Settings -> "Registered Systems".') + ) + + def __str__(self): + return self._meta.verbose_name.title() + + class Meta: + default_permissions = tuple() + verbose_name = _('PVOutput: API configuration') + + +class PVOutputAddStatusSettings(SingletonModel): + """ API Docs: https://pvoutput.org/help.html#api-addstatus """ + API_URL = 'https://pvoutput.org/service/r2/addstatus.jsp' + + INTERVAL_5_MINUTES = 5 + INTERVAL_10_MINUTES = 10 + INTERVAL_15_MINUTES = 15 + INTERVAL_CHOICES = ( + (INTERVAL_5_MINUTES, _('5 minutes')), + (INTERVAL_10_MINUTES, _('10 minutes')), + (INTERVAL_15_MINUTES, _('15 minutes')), + ) + + export = models.BooleanField( + default=False, + verbose_name=_('Enabled'), + help_text=_('Whether the system uploads consumption using the Add Status Service API call.') + ) + upload_interval = models.IntegerField( + default=INTERVAL_5_MINUTES, + choices=INTERVAL_CHOICES, + verbose_name=_('Upload interval'), + help_text=_('The interval between each upload (in minutes). Please make sure this matches the device settings.') + ) + upload_delay = models.IntegerField( + default=0, + validators=[MinValueValidator(0), MaxValueValidator(30)], + verbose_name=_('Upload delay (minutes)'), + help_text=_( + 'An artificial delay in uploading data to PVOutput. E.g.: When you set this to "5" and the application ' + 'uploads the data at 10:45, then only data between 0:00 and 10:40 will be taken into account for upload at ' + 'that moment. It effectively limits its upload data search by "X minutes ago".' + ) + ) + processing_delay = models.IntegerField( + default=None, + null=True, + blank=True, + validators=[MinValueValidator(0), MaxValueValidator(120)], + verbose_name=_('PVOutput: Processing delay (minutes)'), + help_text=_( + '[!]: This feature is ONLY available when you have a DONATOR account for PVOutput.org! Leave EMPTY to ' + 'disable the feature. This parameter allows the processing of the data to be delayed, by the specified ' + 'number of minutes. Allowed values: empty or 0 to 120 (minutes)' + ) + ) + next_export = models.DateTimeField( + default=None, + null=True, + blank=True, + verbose_name=_('Next export'), + help_text=_( + 'Timestamp of the next export. Automatically updated by application.' + ) + ) + + def __str__(self): + return self._meta.verbose_name.title() + + class Meta: + default_permissions = tuple() + verbose_name = _('PVOutput: Add Status configuration') diff --git a/dsmr_pvoutput/services.py b/dsmr_pvoutput/services.py new file mode 100644 index 000000000..d718f3bec --- /dev/null +++ b/dsmr_pvoutput/services.py @@ -0,0 +1,92 @@ +from django.utils import timezone +import requests + +from dsmr_pvoutput.models.settings import PVOutputAddStatusSettings, PVOutputAPISettings +from dsmr_consumption.models.consumption import ElectricityConsumption +import dsmr_backend.services + + +def should_export(): + """ Checks whether we should export data yet, for Add Status calls. """ + api_settings = PVOutputAPISettings.get_solo() + status_settings = PVOutputAddStatusSettings.get_solo() + + # Only when enabled and credentials set. + if not status_settings.export or not api_settings.auth_token or not api_settings.system_identifier: + return False + + # Nonsense when having no data. + capabilities = dsmr_backend.services.get_capabilities() + + if not capabilities['electricity_returned']: + print(' - [!] PVOutput | No electricity return recorded by application!') + return False + + return dsmr_backend.services.is_timestamp_passed(timestamp=status_settings.next_export) + + +def schedule_next_export(): + """ Schedules the next export, according to user preference. """ + status_settings = PVOutputAddStatusSettings.get_solo() + + next_export = timezone.now() + timezone.timedelta(minutes=status_settings.upload_interval) + print(' - PVOutput | Delaying the next export until: {}'.format(next_export)) + + status_settings.next_export = next_export + status_settings.save() + + +def export(): + """ Exports data to PVOutput, calling Add Status. """ + if not should_export(): + return + + api_settings = PVOutputAPISettings.get_solo() + status_settings = PVOutputAddStatusSettings.get_solo() + + # Find the first and last consumption of today, taking any delay into account. + local_now = timezone.localtime(timezone.now()) + start = local_now.replace(hour=0, minute=0, second=0) # Midnight + end = local_now - timezone.timedelta(minutes=status_settings.upload_delay) + + ecs = ElectricityConsumption.objects.filter(read_at__gte=start, read_at__lte=end) + + if not ecs.exists(): + print(' [!] PVOutput: No data found for {}'.format(local_now)) + return schedule_next_export() + + first = ecs[0] + last = ecs.order_by('-read_at')[0] + diff = last - first # Custom operator + + total_consumption = diff['delivered_1'] + diff['delivered_2'] + net_power = last.currently_delivered - last.currently_returned # Negative when returning more Watt than requested. + + consumption_timestamp = timezone.localtime(last.read_at) + + data = { + 'd': consumption_timestamp.date().strftime('%Y%m%d'), + 't': consumption_timestamp.time().strftime('%H:%M'), + 'v3': int(total_consumption * 1000), # Energy Consumption (Wh) + 'v4': int(net_power * 1000), # Power Consumption (W) + 'n': 1, # Net Flag, always enabled for smart meters + } + + # Optional, paid PVOutput feature. + if status_settings.processing_delay: + data.update({'delay': status_settings.processing_delay}) + + print(' - PVOutput | Uploading data @ {}'.format(data['t'])) + response = requests.post( + PVOutputAddStatusSettings.API_URL, + headers={ + 'X-Pvoutput-Apikey': api_settings.auth_token, + 'X-Pvoutput-SystemId': api_settings.system_identifier, + }, + data=data + ) + + if response.status_code != 200: + print(' [!] PVOutput upload failed (HTTP {}): {}'.format(response.status_code, response.text)) + + schedule_next_export() diff --git a/dsmr_pvoutput/tests/__init__.py b/dsmr_pvoutput/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/dsmr_pvoutput/tests/test_services.py b/dsmr_pvoutput/tests/test_services.py new file mode 100644 index 000000000..daff1a97c --- /dev/null +++ b/dsmr_pvoutput/tests/test_services.py @@ -0,0 +1,176 @@ +from unittest import mock + +from django.test import TestCase +from django.utils import timezone + +from dsmr_pvoutput.models.settings import PVOutputAPISettings, PVOutputAddStatusSettings +from dsmr_consumption.models.consumption import ElectricityConsumption +import dsmr_pvoutput.services + + +class TestServices(TestCase): + fixtures = ['dsmr_pvoutput/electricity-consumption.json'] + + def _apply_fake_settings(self): + api_settings = PVOutputAPISettings.get_solo() + api_settings.auth_token = 'XXXXX' + api_settings.system_identifier = 12345 + api_settings.save() + + status_settings = PVOutputAddStatusSettings.get_solo() + status_settings.export = True + status_settings.upload_delay = 1 + status_settings.save() + + @mock.patch('django.utils.timezone.now') + def test_should_export_default(self, now_mock): + """ Test should_export() default behaviour. """ + now_mock.return_value = timezone.make_aware(timezone.datetime(2017, 10, 1, hour=15)) + + api_settings = PVOutputAPISettings.get_solo() + status_settings = PVOutputAddStatusSettings.get_solo() + + self.assertIsNone(api_settings.auth_token) + self.assertFalse(api_settings.system_identifier) + self.assertFalse(status_settings.export) + self.assertIsNone(status_settings.next_export) + + self.assertFalse(dsmr_pvoutput.services.should_export()) + + @mock.patch('django.utils.timezone.now') + def test_should_not_export(self, now_mock): + """ Test should_export() without data. """ + now_mock.return_value = timezone.make_aware(timezone.datetime(2017, 10, 1, hour=15)) + self._apply_fake_settings() + + # Drop all gas data. + ElectricityConsumption.objects.all().delete() + self.assertFalse(ElectricityConsumption.objects.exists()) + + self.assertFalse(dsmr_pvoutput.services.should_export()) + + @mock.patch('django.utils.timezone.now') + def test_should_export_no_need(self, now_mock): + """ Test should_export() when not needed, yet. """ + now_mock.return_value = timezone.make_aware(timezone.datetime(2017, 10, 1, hour=15)) + self._apply_fake_settings() + + PVOutputAddStatusSettings.objects.update(next_export=timezone.now() + timezone.timedelta(hours=1)) + self.assertFalse(dsmr_pvoutput.services.should_export()) + + @mock.patch('django.utils.timezone.now') + def test_should_export_okay(self, now_mock): + now_mock.return_value = timezone.make_aware(timezone.datetime(2017, 10, 1, hour=15)) + self._apply_fake_settings() + + self.assertTrue(dsmr_pvoutput.services.should_export()) + + @mock.patch('dsmr_pvoutput.services.should_export') + @mock.patch('django.utils.timezone.now') + def test_export_not_allowed(self, now_mock, should_export_mock): + """ Test export() blocking behaviour. """ + now_mock.return_value = timezone.make_aware(timezone.datetime(2017, 10, 1, hour=15)) + should_export_mock.return_value = False + self._apply_fake_settings() + + # Nothing should happen. + dsmr_pvoutput.services.export() + + self.assertTrue(should_export_mock.called) + + self.assertIsNone(PVOutputAddStatusSettings.get_solo().next_export) + + @mock.patch('requests.post') + @mock.patch('dsmr_pvoutput.services.should_export') + @mock.patch('django.utils.timezone.now') + def test_export_no_electricity(self, now_mock, should_export_mock, requests_mock): + """ Test export() without electricity. """ + now_mock.return_value = timezone.make_aware(timezone.datetime(2017, 10, 1, hour=15)) + should_export_mock.return_value = True + self._apply_fake_settings() + + # Drop all gas data. + ElectricityConsumption.objects.all().delete() + self.assertFalse(ElectricityConsumption.objects.exists()) + self.assertFalse(requests_mock.called) + + # Nothing should happen, as there is no data. + dsmr_pvoutput.services.export() + self.assertFalse(requests_mock.called) + + @mock.patch('requests.post') + @mock.patch('dsmr_pvoutput.services.should_export') + @mock.patch('django.utils.timezone.now') + def test_export_fail(self, now_mock, should_export_mock, requests_post_mock): + """ Test export() failing by denied API call. """ + now_mock.return_value = timezone.make_aware(timezone.datetime(2017, 10, 1, hour=15)) + should_export_mock.return_value = True + self._apply_fake_settings() + + requests_post_mock.return_value = mock.MagicMock(status_code=400, text='Error message') + dsmr_pvoutput.services.export() + settings = PVOutputAddStatusSettings.get_solo() + + self.assertEqual(settings.next_export, timezone.now() + timezone.timedelta(minutes=5)) + self.assertTrue(requests_post_mock.called) + + @mock.patch('requests.post') + @mock.patch('dsmr_pvoutput.services.should_export') + @mock.patch('django.utils.timezone.now') + def test_export_okay(self, now_mock, should_export_mock, requests_post_mock): + """ Test export() as designed. """ + now_mock.return_value = timezone.make_aware(timezone.datetime(2017, 10, 1, hour=15)) + + should_export_mock.return_value = True + requests_post_mock.return_value = mock.MagicMock(status_code=200, text='Fake accept') + self._apply_fake_settings() + + self.assertFalse(requests_post_mock.called) + + dsmr_pvoutput.services.export() + + self.assertIsNotNone(PVOutputAddStatusSettings.get_solo().next_export) + self.assertTrue(requests_post_mock.called) + + # Check API parameters. + api_settings = PVOutputAPISettings.get_solo() + requests_post_mock.assert_called_once_with( + PVOutputAddStatusSettings.API_URL, + headers={ + 'X-Pvoutput-Apikey': api_settings.auth_token, + 'X-Pvoutput-SystemId': api_settings.system_identifier, + }, + data={ + 'd': '20171001', + 'n': 1, + 't': '13:00', + 'v3': 3000, + 'v4': -750, + }, + ) + + # With processing delay as well. + requests_post_mock.reset_mock() + PVOutputAddStatusSettings.objects.update(processing_delay=5, next_export=None) + + dsmr_pvoutput.services.export() + + self.assertIsNotNone(PVOutputAddStatusSettings.get_solo().next_export) + self.assertTrue(requests_post_mock.called) + + api_settings = PVOutputAPISettings.get_solo() + requests_post_mock.assert_called_once_with( + PVOutputAddStatusSettings.API_URL, + headers={ + 'X-Pvoutput-Apikey': api_settings.auth_token, + 'X-Pvoutput-SystemId': api_settings.system_identifier, + }, + data={ + 'd': '20171001', + 'delay': 5, + 'n': 1, + 't': '13:00', + 'v3': 3000, + 'v4': -750, + }, + ) diff --git a/dsmr_pvoutput/tests/test_settings.py b/dsmr_pvoutput/tests/test_settings.py new file mode 100644 index 000000000..cbc41cbd8 --- /dev/null +++ b/dsmr_pvoutput/tests/test_settings.py @@ -0,0 +1,49 @@ +from django.test import TestCase +from django.contrib.admin.sites import site + +from dsmr_pvoutput.models.settings import PVOutputAPISettings, PVOutputAddStatusSettings + + +class TestPVOutputAPISettings(TestCase): + def setUp(self): + self.instance = PVOutputAPISettings().get_solo() + + def test_admin(self): + """ Model should be registered in Django Admin. """ + self.assertTrue(site.is_registered(PVOutputAPISettings)) + + def test_to_string(self): + self.assertNotEqual(str(self.instance), '{} object'.format(self.instance.__class__.__name__)) + + def test_auth_token(self): + self.assertIsNone(self.instance.auth_token) + + def test_system_identifier(self): + self.assertIsNone(self.instance.system_identifier) + + +class TestPVOutputAddStatusSettings(TestCase): + def setUp(self): + self.instance = PVOutputAddStatusSettings().get_solo() + + def test_admin(self): + """ Model should be registered in Django Admin. """ + self.assertTrue(site.is_registered(PVOutputAddStatusSettings)) + + def test_to_string(self): + self.assertNotEqual(str(self.instance), '{} object'.format(self.instance.__class__.__name__)) + + def test_export(self): + self.assertFalse(self.instance.export) + + def test_upload_interval(self): + self.assertEqual(self.instance.upload_interval, PVOutputAddStatusSettings.INTERVAL_5_MINUTES) + + def test_upload_delay(self): + self.assertEqual(self.instance.upload_delay, 0) + + def test_processing_delay(self): + self.assertIsNone(self.instance.processing_delay) + + def test_next_export(self): + self.assertIsNone(self.instance.next_export) diff --git a/dsmr_stats/fixtures/dsmr_stats/gas-consumption.json b/dsmr_stats/fixtures/dsmr_stats/gas-consumption.json index f949aad27..d2db996ba 100644 --- a/dsmr_stats/fixtures/dsmr_stats/gas-consumption.json +++ b/dsmr_stats/fixtures/dsmr_stats/gas-consumption.json @@ -277,5 +277,23 @@ "delivered": "962.558", "currently_delivered": "0.009" } +}, +{ + "pk": 32, + "model": "dsmr_consumption.gasconsumption", + "fields": { + "read_at": "2015-12-11T23:20:00Z", + "delivered": "956.761", + "currently_delivered": "0.022" + } +}, +{ + "pk": 33, + "model": "dsmr_consumption.gasconsumption", + "fields": { + "read_at": "2015-12-11T23:40:00Z", + "delivered": "956.864", + "currently_delivered": "0.103" + } } ] \ No newline at end of file diff --git a/dsmr_stats/services.py b/dsmr_stats/services.py index c4732fb08..f2722ac76 100644 --- a/dsmr_stats/services.py +++ b/dsmr_stats/services.py @@ -137,10 +137,15 @@ def create_hourly_statistics(hour_start): creation_kwargs['electricity1_returned'] = electricity_end.returned_1 - electricity_start.returned_1 creation_kwargs['electricity2_returned'] = electricity_end.returned_2 - electricity_start.returned_2 - if gas_readings.exists(): - # Gas readings are unique per hour anyway. + # DSMR v4. + if len(gas_readings) == 1: creation_kwargs['gas'] = gas_readings[0].currently_delivered + # DSMR v5 + elif len(gas_readings) > 1: + gas_readings = list(gas_readings) + creation_kwargs['gas'] = gas_readings[-1].delivered - gas_readings[0].delivered + HourStatistics.objects.create(**creation_kwargs) diff --git a/dsmr_stats/tests/test_services.py b/dsmr_stats/tests/test_services.py index c6a466f76..0539d46e1 100644 --- a/dsmr_stats/tests/test_services.py +++ b/dsmr_stats/tests/test_services.py @@ -1,4 +1,5 @@ from unittest import mock +from decimal import Decimal from django.db import connection from django.test import TestCase @@ -12,7 +13,6 @@ class TestServices(InterceptStdoutMixin, TestCase): - """ Test 'dsmr_backend' management command. """ fixtures = ['dsmr_stats/electricity-consumption.json', 'dsmr_stats/gas-consumption.json'] def _get_statistics_dict(self, target_date): @@ -88,6 +88,32 @@ def test_analyze_service(self, now_mock): self.assertFalse(DayStatistics.objects.exists()) self.assertFalse(HourStatistics.objects.exists()) + def test_create_hourly_gas_statistics_dsmr4(self): + if not dsmr_backend.services.get_capabilities(capability='gas'): + return self.skipTest('No gas') + + day_start = timezone.make_aware(timezone.datetime(2015, 12, 12, hour=0)) + GasConsumption.objects.filter(pk__in=(32, 33)).delete() # Pretend we only have 1 gas reading per hour. + + self.assertFalse(HourStatistics.objects.exists()) + dsmr_stats.services.create_hourly_statistics(hour_start=day_start) + self.assertEqual(HourStatistics.objects.count(), 1) + + stats = HourStatistics.objects.get() + self.assertEqual(stats.gas, Decimal('0.509')) + + def test_create_hourly_gas_statistics_dsmr5(self): + if not dsmr_backend.services.get_capabilities(capability='gas'): + return self.skipTest('No gas') + + day_start = timezone.make_aware(timezone.datetime(2015, 12, 12, hour=0)) + self.assertFalse(HourStatistics.objects.exists()) + dsmr_stats.services.create_hourly_statistics(hour_start=day_start) + self.assertEqual(HourStatistics.objects.count(), 1) + + stats = HourStatistics.objects.get() + self.assertEqual(stats.gas, Decimal('0.125')) + def test_create_hourly_statistics_integrity(self): day_start = timezone.make_aware(timezone.datetime(2015, 12, 13, hour=0)) ec_kwargs = { @@ -104,7 +130,7 @@ def test_create_hourly_statistics_integrity(self): dsmr_stats.services.create_hourly_statistics(hour_start=day_start) self.assertEqual(HourStatistics.objects.count(), 1) - # Should NOT raised any exception. + # Should NOT raise any exception. dsmr_stats.services.create_hourly_statistics(hour_start=day_start) def test_analyze_service_without_data(self): diff --git a/dsmr_weather/services.py b/dsmr_weather/services.py index f72b9eb47..535c22853 100644 --- a/dsmr_weather/services.py +++ b/dsmr_weather/services.py @@ -1,5 +1,6 @@ import xml.etree.ElementTree as ET import urllib.request +from decimal import Decimal from django.utils import timezone @@ -45,12 +46,19 @@ def read_weather(): ) temperature_element = root.find(xpath) temperature = temperature_element.text + print(' - Read temperature: {}'.format(temperature)) # Gas readings trigger these readings, so the 'read at' timestamp should be somewhat in sync. # Therefor we align temperature readings with them, having them grouped by hour that is.. read_at = timezone.now().replace(minute=0, second=0, microsecond=0) - TemperatureReading.objects.create(read_at=read_at, degrees_celcius=temperature) - # Push next sync back for an hour. - weather_settings.next_sync = read_at + timezone.timedelta(hours=1) + try: + TemperatureReading.objects.create(read_at=read_at, degrees_celcius=Decimal(temperature)) + except: + # Try again in 5 minutes. + weather_settings.next_sync = timezone.now() + timezone.timedelta(minutes=5) + else: + # Push next sync back for an hour. + weather_settings.next_sync = read_at + timezone.timedelta(hours=1) + weather_settings.save() diff --git a/dsmr_weather/tests/data/invalid-api.buienradar.nl.xml b/dsmr_weather/tests/data/invalid-api.buienradar.nl.xml new file mode 100644 index 000000000..19f154121 --- /dev/null +++ b/dsmr_weather/tests/data/invalid-api.buienradar.nl.xml @@ -0,0 +1,15 @@ +www.buienradar.nl - actuele weersinformatiehttp://www.buienradar.nlXML feed weersinformatienl-nl(C)opyright 2005 - 2016 Buienradar B.V. Alle rechten voorbehoudenDeze XML feed mag vrij worden gebruikt onder voorwaarde van bronvermelding BuienRadar.NL inclusief een hyperlink naar http://www.buienradar.nl. Aan de feed kunnen door gebruikers of andere personen geen rechten worden ontleend.Buienradar.nlhttp://www.buienradar.nl/http://www.buienradar.nl/include/images/header.jpg950786391Meetstation Arcen51.306.1202/04/2016 22:30:00993.20.761240.8WZW--1.0-http://xml.buienradar.nl/icons/pp.gif2.8http://www.buienradar.nl/weerstation/6391/Meetstation Arcen51.506.206275Meetstation Arnhem52.045.5302/04/2016 22:30:00963.21.541235.1ZW1025.286155002.5-http://xml.buienradar.nl/icons/pp.gif2.7http://www.buienradar.nl/weerstation/6275/Meetstation Arnhem52.075.886249Meetstation Berkhout52.394.5902/04/2016 22:30:00884.92.082226.6ZW-367002.7-http://xml.buienradar.nl/icons/pp.gif4.2http://www.buienradar.nl/weerstation/6249/Meetstation Berkhout52.654.986308Meetstation Cadzand51.233.2302/04/2016 22:00:00--2.442270.2W--3.2-http://xml.buienradar.nl/icons/pp.gif-http://www.buienradar.nl/weerstation/6308/Meetstation Cadzand51.383.386260Meetstation De Bilt52.065.1102/04/2016 22:30:0090-2.122218.4ZW1025.442268003.3-http://xml.buienradar.nl/icons/pp.gif4.1http://www.buienradar.nl/weerstation/6260/Meetstation De Bilt52.105.186235Meetstation Den Helder52.554.4702/04/2016 22:30:00765.63.382289.7WNW1024.441499004.6-http://xml.buienradar.nl/icons/pp.gif4.9http://www.buienradar.nl/weerstation/6235/Meetstation Den Helder52.924.786370Meetstation Eindhoven51.275.2502/04/2016 22:30:00965.00.761295.7WNW1025.82148601.7-http://xml.buienradar.nl/icons/pp.gif2.7http://www.buienradar.nl/weerstation/6370/Meetstation Eindhoven51.455.426377Meetstation Ell51.125.4602/04/2016 22:30:00985.10.431359.1N-113000.7-http://xml.buienradar.nl/icons/pp.gif4.7http://www.buienradar.nl/weerstation/6377/Meetstation Ell51.205.776321Meetstation Euro platform52.003.1702/04/2016 22:20:00--2.822283.3WNW1025.515261003.8-http://xml.buienradar.nl/icons/pp.gif-http://www.buienradar.nl/weerstation/6321/Meetstation Euro platform52.003.286350Meetstation Gilze Rijen51.344.5602/04/2016 22:30:00962.60.901257.0WZW1025.805146001.7-http://xml.buienradar.nl/icons/oo.gif0.4http://www.buienradar.nl/weerstation/6350/Meetstation Gilze Rijen51.574.936283Meetstation Groenlo-Hupsel52.046.3902/04/2016 22:30:00944.01.501260.3W--2.8-http://xml.buienradar.nl/icons/pp.gif3.6http://www.buienradar.nl/weerstation/6283/Meetstation Groenlo-Hupsel52.076.656280Meetstation Groningen53.086.3502/04/2016 22:30:00952.52.142232.1ZW1023.506233002.7-http://xml.buienradar.nl/icons/pp.gif1.8http://www.buienradar.nl/weerstation/6280/Meetstation Groningen53.136.586315Meetstation Hansweert51.274.0002/04/2016 22:00:00--3.052262.1W--3.7-http://xml.buienradar.nl/icons/pp.gif-http://www.buienradar.nl/weerstation/6315/Meetstation Hansweert51.454.006278Meetstation Heino52.266.1602/04/2016 22:30:00924.32.062245.4WZW--2.8-http://xml.buienradar.nl/icons/pp.gif3.9http://www.buienradar.nl/weerstation/6278/Meetstation Heino52.436.276356Meetstation Herwijnen51.525.0902/04/2016 22:30:00934.91.381169.2Z1025.123-1.8-http://xml.buienradar.nl/icons/pp.gif4.3http://www.buienradar.nl/weerstation/6356/Meetstation Herwijnen51.875.156330Meetstation Hoek van Holland51.594.0602/04/2016 22:30:00904.92.842303.4WNW1025.369-3.7-http://xml.buienradar.nl/icons/pp.gif3.2http://www.buienradar.nl/weerstation/6330/Meetstation Hoek van Holland51.984.106311Meetstation Hoofdplaat51.233.4002/04/2016 22:00:00--000--0-http://xml.buienradar.nl/icons/pp.gif-http://www.buienradar.nl/weerstation/6311/Meetstation Hoofdplaat51.383.676279Meetstation Hoogeveen52.446.3102/04/2016 22:30:00963.83.302256.7WZW1023.897181004.9-http://xml.buienradar.nl/icons/pp.gif3.3http://www.buienradar.nl/weerstation/6279/Meetstation Hoogeveen52.736.526251Meetstation Hoorn Terschelling53.235.2102/04/2016 22:30:00884.32.682265.7W1023.490361003.8-http://xml.buienradar.nl/icons/pp.gif3.6http://www.buienradar.nl/weerstation/6251/Meetstation Hoorn Terschelling53.385.356258Meetstation Houtribdijk52.395.2402/04/2016 22:30:00--3.322262.6W--4.2-http://xml.buienradar.nl/icons/pp.gif-http://www.buienradar.nl/weerstation/6258/Meetstation Houtribdijk52.655.406285Meetstation Huibertgat53.346.2402/04/2016 22:00:00--5.193310.1NW--6.3-http://xml.buienradar.nl/icons/pp.gif-http://www.buienradar.nl/weerstation/6285/Meetstation Huibertgat53.576.406209Meetstation IJmond52.284.3102/04/2016 22:00:00--000--0-http://xml.buienradar.nl/icons/pp.gif-http://www.buienradar.nl/weerstation/6209/Meetstation IJmond52.474.526225Meetstation IJmuiden52.284.3402/04/2016 22:30:00--2.022191.7ZZW--2.6-http://xml.buienradar.nl/icons/pp.gif-http://www.buienradar.nl/weerstation/6225/Meetstation IJmuiden52.474.576210Meetstation Katwijk52.114.2502/04/2016 22:30:00944.62.202204.4ZZW1025.173-2.8-http://xml.buienradar.nl/icons/pp.gif3.1http://www.buienradar.nl/weerstation/6210/Meetstation Katwijk52.184.426277Meetstation Lauwersoog53.256.1202/04/2016 22:30:00894.93.172245.7WZW--4.9-http://xml.buienradar.nl/icons/pp.gif4.1http://www.buienradar.nl/weerstation/6277/Meetstation Lauwersoog53.426.206320Meetstation LE Goeree51.563.4002/04/2016 22:20:00--4.073321.8NW1025.508379005.2-http://xml.buienradar.nl/icons/pp.gif-http://www.buienradar.nl/weerstation/6320/Meetstation LE Goeree51.933.676270Meetstation Leeuwarden53.135.4602/04/2016 22:30:00914.82.922242.8WZW1023.730499003.4-http://xml.buienradar.nl/icons/pp.gif4.4http://www.buienradar.nl/weerstation/6270/Meetstation Leeuwarden53.225.776269Meetstation Lelystad52.275.3202/04/2016 22:30:00894.51.481250.9WZW1024.909482002.0-http://xml.buienradar.nl/icons/pp.gif3.9http://www.buienradar.nl/weerstation/6269/Meetstation Lelystad52.455.536348Meetstation Lopik-Cabauw51.584.5602/04/2016 22:30:00954.51.792189.2Z1025.409135002.7-http://xml.buienradar.nl/icons/pp.gif3.1http://www.buienradar.nl/weerstation/6348/Meetstation Lopik-Cabauw51.974.936380Meetstation Maastricht50.555.4702/04/2016 22:30:00925.51.581289.2WNW1026.112149002.9-http://xml.buienradar.nl/icons/pp.gif5.2http://www.buienradar.nl/weerstation/6380/Meetstation Maastricht50.925.786273Meetstation Marknesse52.425.5302/04/2016 22:30:00914.01.812264.1W-418003.3-http://xml.buienradar.nl/icons/pp.gif2.4http://www.buienradar.nl/weerstation/6273/Meetstation Marknesse52.705.886286Meetstation Nieuw Beerta53.127.0902/04/2016 22:30:00952.63.382246.6WZW--4.1-http://xml.buienradar.nl/icons/pp.gif1.8http://www.buienradar.nl/weerstation/6286/Meetstation Nieuw Beerta53.207.156312Meetstation Oosterschelde51.463.3702/04/2016 22:00:00--3.352305.1NW--3.9-http://xml.buienradar.nl/icons/pp.gif-http://www.buienradar.nl/weerstation/6312/Meetstation Oosterschelde51.773.626344Meetstation Rotterdam51.574.2702/04/2016 22:30:00972.21.421199.1ZZW1025.42794602.6-http://xml.buienradar.nl/icons/aa.gif0.3http://www.buienradar.nl/weerstation/6344/Meetstation Rotterdam51.954.456343Meetstation Rotterdam Geulhaven51.534.1902/04/2016 22:30:00--2.022276.7W--4.1-http://xml.buienradar.nl/icons/pp.gif-http://www.buienradar.nl/weerstation/6343/Meetstation Rotterdam Geulhaven51.884.326316Meetstation Schaar51.393.4202/04/2016 22:00:00--2.872291.3WNW--3.3-http://xml.buienradar.nl/icons/pp.gif-http://www.buienradar.nl/weerstation/6316/Meetstation Schaar51.653.706240Meetstation Schiphol52.184.4602/04/2016 22:30:00915.32.222217.0ZW1025.092285003.2-http://xml.buienradar.nl/icons/pp.gif4.4http://www.buienradar.nl/weerstation/6240/Meetstation Schiphol52.304.776324Meetstation Stavenisse51.364.0002/04/2016 22:00:00--2.762284.0WNW--3.3-http://xml.buienradar.nl/icons/pp.gif-http://www.buienradar.nl/weerstation/6324/Meetstation Stavenisse51.604.006267Meetstation Stavoren52.535.2302/04/2016 22:30:00885.33.933255.3WZW-489005.0-http://xml.buienradar.nl/icons/pp.gif4.7http://www.buienradar.nl/weerstation/6267/Meetstation Stavoren52.885.386331Meetstation Tholen51.314.0802/04/2016 22:00:00--3.222276.9W--4.2-http://xml.buienradar.nl/icons/pp.gif-http://www.buienradar.nl/weerstation/6331/Meetstation Tholen51.524.136290Meetstation Twente52.166.5402/04/2016 22:30:00953.92.492248.5WZW1024.55061503.2-http://xml.buienradar.nl/icons/pp.gif3.6http://www.buienradar.nl/weerstation/6290/Meetstation Twente52.276.906313Meetstation Vlakte aan de Raan51.303.1502/04/2016 22:00:00--000--0-http://xml.buienradar.nl/icons/pp.gif-http://www.buienradar.nl/weerstation/6313/Meetstation Vlakte aan de Raan51.503.256242Meetstation Vlieland53.154.5502/04/2016 22:30:00766.24.903272.5W1023.807187006.8-http://xml.buienradar.nl/icons/pp.gif6.0http://www.buienradar.nl/weerstation/6242/Meetstation Vlieland53.254.926310Meetstation Vlissingen51.273.3602/04/2016 22:30:00937.03.853254.8WZW1026.20983404.6-http://xml.buienradar.nl/icons/pp.gif6.2http://www.buienradar.nl/weerstation/6310/Meetstation Vlissingen51.453.606375Meetstation Volkel51.395.4202/04/2016 22:30:00934.10.571292.5WNW1025.498109001.3-http://xml.buienradar.nl/icons/pp.gif3.6http://www.buienradar.nl/weerstation/6375/Meetstation Volkel51.655.706215Meetstation Voorschoten52.074.2602/04/2016 22:30:00982.92.122213.5ZZW1025.056198002.7-http://xml.buienradar.nl/icons/aa.gif2.1http://www.buienradar.nl/weerstation/6215/Meetstation Voorschoten52.124.436319Meetstation Westdorpe51.143.5002/04/2016 22:30:00946.42.612243.0WZW1026.291161003.2-http://xml.buienradar.nl/icons/pp.gif5.7http://www.buienradar.nl/weerstation/6319/Meetstation Westdorpe51.233.836248Meetstation Wijdenes52.385.1002/04/2016 22:30:00--1.912244.7WZW--3.9-http://xml.buienradar.nl/icons/pp.gif-http://www.buienradar.nl/weerstation/6248/Meetstation Wijdenes52.635.176257Meetstation Wijk aan Zee52.304.3602/04/2016 22:30:00885.6000--0-http://xml.buienradar.nl/icons/pp.gif5.0http://www.buienradar.nl/weerstation/6257/Meetstation Wijk aan Zee52.504.606340Meetstation Woensdrecht51.274.2002/04/2016 22:30:00962.80.961234.3ZW1026.099135002.2-http://xml.buienradar.nl/icons/aa.gif1.0http://www.buienradar.nl/weerstation/6340/Meetstation Woensdrecht51.454.336239Meetstation Zeeplatform F-354.514.4402/04/2016 22:30:00825.96.804260.0W1021.510499009.1-http://xml.buienradar.nl/icons/pp.gif-http://www.buienradar.nl/weerstation/6239/Meetstation Zeeplatform F-354.854.736252Meetstation Zeeplatform K1353.133.1302/04/2016 22:20:00--3.933244.0WZW1024.117-5.5-http://xml.buienradar.nl/icons/pp.gif-http://www.buienradar.nl/weerstation/6252/Meetstation Zeeplatform K1353.223.22102/04/2016 22:30:00]]>]]>http://xml.buienradar.nl/icons/pp.gif02/04/2016 08:15:5402/04/2016 17:32:5700http://www.buienradar.nl/weerbericht-nederland-komende-5-tot-9-dagenhttp://www.buienradar.nl/weerbericht-nederland-komende-5-tot-9-dagen + Zacht weer met tamelijk veel bewolking en vrijwel iedere dag regen of enkele buien. Begin volgende week veel wind. + + Aanhoudend wisselvallig. Zeer waarschijnlijk temperaturen iets boven normaal. + vrijdag 5 februari 2016vr107012441010ZW4http://xml.buienradar.nl/icons/m.gif0zaterdag 06 februari 2016za103000881010Z4http://xml.buienradar.nl/icons/c.gif0zondag 07 februari 2016zo20701288910ZW4http://xml.buienradar.nl/icons/f.gif0maandag 08 februari 2016ma20908115689ZW5http://xml.buienradar.nl/icons/k.gif0dinsdag 09 februari 2016di2080285678ZW4http://xml.buienradar.nl/icons/k.gif0http://www.buienradar.nl/weerbericht-nederlandhttp://www.buienradar.nl/weerbericht-nederlandGeleidelijk drogerOpgesteld op donderdag 4 feb 2016 om 17:47 uurGeleidelijk drogerHet is de komende dagen zacht en herfstachtig. Zo is het vandaag tot in de middag regenachtig weer. Ook tijdens het Carnavalsweekeinde houden we het niet droog. +Vanavond is het meest bewolkt en daarbij valt plaatselijk nog een beetje regen. In de loop van de avond wordt het op de meeste plekken droog en klaart het hier en daar op. +Vannacht begint met overwegend droog weer. In het oosten en noordoosten komen opklaringen voor en daalt de temperatuur naar waarden net boven nul (met kans op vorst aan de grond). In de loop van de nacht neemt de bewolking toe en volgt vanuit het westen regen. Tegelijkertijd stijgt de temperatuur. In het zuidwesten wordt het overigens niet kouder dan een graad of 8. +Morgen start de dag grijs met motregen en regen. ‘s Middags hebben de droge momenten vanuit het westen de overhand met vanuit die hoek een enkele opklaring. Koud is het zeker niet met 9 tot 11 graden. De zuidwestenwind is matig en aan zee vrij krachtig. In de middag en avond neemt de wind nog iets verder toe. +De dagen daarna is het wisselvallig en onstuimig met iedere dag regen of enkele stevige buien. Zaterdag verloopt wel overwegend droog. Daarbij is het zacht met maxima rond 10 graden overdag. Tijdens de nachten is het niet veel kouder. +Het is de komende dagen zacht en herfstachtig. Zo is het vandaag tot in de middag regenachtig weer. Ook tijdens het Carnavalsweekeinde houden we het niet droog. +Vanavond is het meest bewolkt en daarbij valt plaatselijk nog een beetje regen. In de loop van de avond wordt het op de meeste plekken droog en klaart het hier en daar op. +Vannacht begint met overwegend droog weer. In het oosten en noordoosten komen opklaringen voor en daalt de temperatuur naar waarden net boven nul (met kans op vorst aan de grond). In de loop van de nacht neemt de bewolking toe en volgt vanuit het westen regen. Tegelijkertijd stijgt de temperatuur. In het zuidwesten wordt het overigens niet kouder dan een graad of 8. +Morgen start de dag grijs met motregen en regen. ‘s Middags hebben de droge momenten vanuit het westen de overhand met vanuit die hoek een enkele opklaring. Koud is het zeker niet met 9 tot 11 graden. De zuidwestenwind is matig en aan zee vrij krachtig. In de middag en avond neemt de wind nog iets verder toe. +De dagen daarna is het wisselvallig en onstuimig met iedere dag regen of enkele stevige buien. Zaterdag verloopt wel overwegend droog. Daarbij is het zacht met maxima rond 10 graden overdag. Tijdens de nachten is het niet veel kouder. + \ No newline at end of file diff --git a/dsmr_weather/tests/test_services.py b/dsmr_weather/tests/test_services.py index 075f0cab3..28b770915 100644 --- a/dsmr_weather/tests/test_services.py +++ b/dsmr_weather/tests/test_services.py @@ -53,8 +53,10 @@ def test_weather_tracking(self): self.assertFalse(TemperatureReading.objects.all().exists()) @mock.patch('urllib.request.urlopen') - def test_weather_parsing(self, urlopen_mock): + @mock.patch('django.utils.timezone.now') + def test_weather_parsing(self, now_mock, urlopen_mock): """ Tests whether temperature readings are skipped when tracking is disabled. """ + now_mock.return_value = timezone.make_aware(timezone.datetime(2017, 1, 1)) weather_settings = WeatherSettings.get_solo() weather_settings.track = True weather_settings.next_sync = timezone.now() - timezone.timedelta(minutes=15) @@ -87,3 +89,38 @@ def test_weather_parsing(self, urlopen_mock): # Make sure that the next_sync is pushed forward as well. weather_settings = WeatherSettings.get_solo() + self.assertEqual(weather_settings.next_sync, timezone.now() + timezone.timedelta(hours=1)) + + @mock.patch('urllib.request.urlopen') + @mock.patch('django.utils.timezone.now') + def test_weather_parsing_error(self, now_mock, urlopen_mock): + """ Tests whether temperature readings are skipped when tracking is disabled. """ + now_mock.return_value = timezone.make_aware(timezone.datetime(2017, 1, 1)) + weather_settings = WeatherSettings.get_solo() + weather_settings.track = True + weather_settings.next_sync = timezone.now() - timezone.timedelta(minutes=15) + weather_settings.save() + weather_settings.refresh_from_db() + + self.assertGreater(timezone.now(), weather_settings.next_sync) + + # Fake URL opener and its http response object used for reading data. + http_response_mock = mock.MagicMock() + + test_data_file = os.path.join( + settings.BASE_DIR, '..', 'dsmr_weather', 'tests', 'data', 'invalid-api.buienradar.nl.xml' + ) + + with open(test_data_file, 'r') as data: + # Http response is in bytes, so make sure to equalize it. + http_response_mock.read.return_value = bytes(data.read(), encoding='utf-8') + + urlopen_mock.return_value = http_response_mock + + self.assertFalse(TemperatureReading.objects.all().exists()) + dsmr_weather.services.read_weather() + self.assertFalse(TemperatureReading.objects.all().exists()) + + # Make sure that the next_sync is pushed forward as well. + weather_settings = WeatherSettings.get_solo() + self.assertEqual(weather_settings.next_sync, timezone.now() + timezone.timedelta(minutes=5)) diff --git a/dsmrreader/__init__.py b/dsmrreader/__init__.py index 40b5a0547..ab354126a 100644 --- a/dsmrreader/__init__.py +++ b/dsmrreader/__init__.py @@ -17,6 +17,6 @@ from django.utils.version import get_version -VERSION = (1, 8, 2, 'final', 0) +VERSION = (1, 9, 0, 'final', 0) __version__ = get_version(VERSION) diff --git a/dsmrreader/config/base.py b/dsmrreader/config/base.py index 63b101cec..baf67117c 100644 --- a/dsmrreader/config/base.py +++ b/dsmrreader/config/base.py @@ -63,6 +63,7 @@ 'dsmr_mindergas.apps.AppConfig', 'dsmr_notification.apps.AppConfig', 'dsmr_mqtt.apps.AppConfig', + 'dsmr_pvoutput.apps.AppConfig', ) MIDDLEWARE_CLASSES = ( diff --git a/dsmrreader/locales/nl/LC_MESSAGES/django.mo b/dsmrreader/locales/nl/LC_MESSAGES/django.mo index b94bfdaa5..eef492a3c 100644 Binary files a/dsmrreader/locales/nl/LC_MESSAGES/django.mo and b/dsmrreader/locales/nl/LC_MESSAGES/django.mo differ diff --git a/dsmrreader/locales/nl/LC_MESSAGES/django.po b/dsmrreader/locales/nl/LC_MESSAGES/django.po index 9512896e7..ae3a038ac 100644 --- a/dsmrreader/locales/nl/LC_MESSAGES/django.po +++ b/dsmrreader/locales/nl/LC_MESSAGES/django.po @@ -43,6 +43,9 @@ msgstr "De database engine \"{}\" wordt niet actief ondersteund, sommige functie msgid "Resets the environment for development purposes. Not intended for production." msgstr "Reset de omgeving voor ontwikkelingsdoeleinden. Niet bedoeld voor gebruik in productie." +msgid "Whether the API should be disabled." +msgstr "Geeft aan of de API uitgeschakeld is." + msgid "Intended usage is NOT production! Only allowed when DEBUG = True" msgstr "Bedoeld voor gebruik buiten productie. Alleen mogelijk wanneer instelling DEBUG = True" @@ -52,12 +55,6 @@ msgstr "Genereert een generiek signaal dat gebruikt kan worden door plugins voor msgid "Deletes all aggregated data generated. Such as consumption and (day/hour) statistics. This command does NOT affect any readings stored. In fact, you should NEVER run this, unless you still have each and EVERY reading stored, as the application will attempt to recalculate all aggregated data deleted retroactively, using each reading stored." msgstr "Verwijdert alle geaggregeerde gegevens, zoals verbruik en dag/uur-statistieken. Dit heeft GEEN invloed op alle opgeslagen metingen. Let op: draai dit NOOIT tenzij je absoluut zeker weet dat je ELKE meting nog opgeslagen hebt. De applicatie gaat namelijk proberen om alle geaggregeerde gegevens opnieuw uit te rekenen, aan de hand van de opgeslagen metingen." -msgid "Required to acknowledge you that you WILL delete your statistics with this." -msgstr "Verplichte parameter om te bevestigen dat je beseft dat je hiermee (gegenereerde) data verwijdert." - -msgid "Intended usage is NOT production! Force by using --ack-to-delete-my-data" -msgstr "Bedoeld voor gebruik buiten productie. Forceer uitvoer met --ack-to-delete-my-data" - msgid "Forces single run, overriding Infinite Command mixin" msgstr "Forceert enkele uitvoer." @@ -181,6 +178,15 @@ msgstr "Prijs elektriciteit 2 (piektarief)" msgid "Gas price" msgstr "Gasprijs" +msgid "Set to zero when unused" +msgstr "Stel in op nul wanneer ongebruikt" + +msgid "Electricity returned 1 price (low tariff)" +msgstr "Prijs teruglevering elektriciteit 1 (daltarief)" + +msgid "Electricity returned 2 price (high tariff)" +msgstr "Prijs teruglevering elektriciteit 2 (piektarief)" + msgid "Energy Supplier" msgstr "Energieleverancier" @@ -223,6 +229,9 @@ msgstr "Neem gasverbruik mee" msgid "Include electricity returned (solar panels)" msgstr "neem teruglevering elektriciteit mee (zonnepanelen)" +msgid "The offset in hours, can both be positive as negative (to go back in time)." +msgstr "De afwijking in uren, kan zowel positief als negatief zijn (om terug in de tijd te gaan)." + msgid "Intended usage is NOT production! Force by using --ack-to-mess-up-my-data" msgstr "Bedoeld voor gebruik buiten productie. Forceer uitvoer met --ack-to-mess-up-my-data" @@ -1141,6 +1150,60 @@ msgstr "Gas verbruikt: {} m3\n" msgid "Total cost: € {}" msgstr "Totale kosten: € {}" +msgid "Implements the following API call: https://pvoutput.org/help.html#api-addstatus" +msgstr "Implementeert de volgende API call: https://pvoutput.org/help.html#api-addstatus" + +msgid "PVOutput" +msgstr "PVOutput" + +msgid "API key" +msgstr "API key" + +msgid "The API key for your PVOutput account. Listed in PVOutput at Settings -> \"API Settings\"." +msgstr "De API-key voor je PVOutput-account. Terug te vinden in PVOutput onder Instellingen -> \"API Settings\"." + +msgid "System ID (digit)" +msgstr "System ID (cijfer)" + +msgid "The \"System ID\" for your device. Listed in PVOutput at Settings -> \"Registered Systems\"." +msgstr "Het \"Systeem ID\" voor je apparaat. Terug te vinden in PVOutput onder Instellingen -> \"Registered Systems\"." + +msgid "PVOutput: API configuration" +msgstr "PVOutput: API-configuratie" + +msgid "5 minutes" +msgstr "5 minuten" + +msgid "10 minutes" +msgstr "10 minuten" + +msgid "15 minutes" +msgstr "15 minuten" + +msgid "Whether the system uploads consumption using the Add Status Service API call." +msgstr "Geeft aan of het systeem status-updates doorgeeft via de \"Add Status Service\" API call." + +msgid "Upload interval" +msgstr "Upload interval" + +msgid "The interval between each upload (in minutes). Please make sure this matches the device settings." +msgstr "De interval tussen elke upload (in minuten). Zorg ervoor dat dit overeenkomt met de apparaatinstellingen in PVOutput." + +msgid "Upload delay (minutes)" +msgstr "Uploadvertraging (in minuten)" + +msgid "An artificial delay in uploading data to PVOutput. E.g.: When you set this to \"5\" and the application uploads the data at 10:45, then only data between 0:00 and 10:40 will be taken into account for upload at that moment. It effectively limits its upload data search by \"X minutes ago\"." +msgstr "Een kunstmatige vertraging in het uploaden van gegevens naar PVOutput. Voorbeeld: Wanneer je dit instelt op \"5\" en de applicatie probeert om 10:45 gegevens te uploaden, dan worden alleen gegevens tussen 0:00 en 10:40 gebruikt. Effectief beperkt deze instelling dus de zoekradius met \"X minuten geleden\"." + +msgid "PVOutput: Processing delay (minutes)" +msgstr "PVOutput: Verwerkingsvertraging (in minuten)" + +msgid "[!]: This feature is ONLY available when you have a DONATOR account for PVOutput.org! Leave EMPTY to disable the feature. This parameter allows the processing of the data to be delayed, by the specified number of minutes. Allowed values: empty or 0 to 120 (minutes)" +msgstr "[!] Deze feature is alleen beschikbaar wanneer je een DONATIE-account bij PVOutput.org hebt! Deze parameter staat het vertraagd verwerken van gegevens toe. Je kunt de vertraging instellen op een aantal minuten. Toegestaan: leeg veld of 0 tot 120 (minuten)" + +msgid "PVOutput: Add Status configuration" +msgstr "PVOutput: \"Add Status\" configuratie" + msgid "Trend & statistics" msgstr "Trends & statistieken" @@ -1359,3 +1422,12 @@ msgstr "Nederlands" msgid "English" msgstr "Engels" + +#~ msgid "PVOutput: Delay" +#~ msgstr "PVOutput: Vertraging" + +#~ msgid "Required to acknowledge you that you WILL delete your statistics with this." +#~ msgstr "Verplichte parameter om te bevestigen dat je beseft dat je hiermee (gegenereerde) data verwijdert." + +#~ msgid "Intended usage is NOT production! Force by using --ack-to-delete-my-data" +#~ msgstr "Bedoeld voor gebruik buiten productie. Forceer uitvoer met --ack-to-delete-my-data" diff --git a/dsmrreader/provisioning/fake/fake_data.sh b/dsmrreader/provisioning/fake/fake_data.sh new file mode 100755 index 000000000..93a6fc835 --- /dev/null +++ b/dsmrreader/provisioning/fake/fake_data.sh @@ -0,0 +1,26 @@ +#!/bin/sh +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -24 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -23 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -22 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -21 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -20 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -19 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -18 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -17 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -16 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -15 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -14 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -13 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -12 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -11 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -10 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -9 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -8 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -7 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -6 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -5 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -4 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -3 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -2 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas --hour-offset -1 +./manage.py dsmr_fake_datasource --run-once --ack-to-mess-up-my-data --with-electricity-returned --with-gas diff --git a/dsmrreader/provisioning/requirements/base.txt b/dsmrreader/provisioning/requirements/base.txt index 9abe8588c..33963adca 100644 --- a/dsmrreader/provisioning/requirements/base.txt +++ b/dsmrreader/provisioning/requirements/base.txt @@ -1,17 +1,17 @@ crcmod==1.7 -coreapi==2.3.1 -django==1.10.7 +coreapi==2.3.3 +django==1.11.6 django-colorfield==0.1.14 django-debug-toolbar==1.8 django-filter==1.0.4 -djangorestframework==3.6.3 +djangorestframework==3.7.0 django-solo==1.1.2 -dropbox==8.0.0 +dropbox==8.2.0 gunicorn==19.7.1 paho-mqtt==1.2.3 -pyserial==3.3 -python-dateutil==2.6.0 +pyserial==3.4 +python-dateutil==2.6.1 pytz==2017.2 -raven==6.1.0 -requests==2.18.1 -urllib3==1.21.1 \ No newline at end of file +raven==6.2.1 +requests==2.18.4 +urllib3==1.22 diff --git a/dsmrreader/provisioning/requirements/dev.txt b/dsmrreader/provisioning/requirements/dev.txt index e975fb7fc..fcef1a5a6 100644 --- a/dsmrreader/provisioning/requirements/dev.txt +++ b/dsmrreader/provisioning/requirements/dev.txt @@ -1,4 +1,4 @@ -sphinx==1.6.2 -sphinx-autobuild==0.6.0 -sphinx-intl==0.9.9 +sphinx==1.6.4 +sphinx-autobuild==0.7.1 +sphinx-intl==0.9.10 sphinx-rtd-theme==0.2.4 diff --git a/dsmrreader/provisioning/requirements/mysql.txt b/dsmrreader/provisioning/requirements/mysql.txt index 95aa5b402..ccd50492e 100644 --- a/dsmrreader/provisioning/requirements/mysql.txt +++ b/dsmrreader/provisioning/requirements/mysql.txt @@ -1 +1 @@ -mysqlclient==1.3.10 \ No newline at end of file +mysqlclient==1.3.12 \ No newline at end of file diff --git a/dsmrreader/provisioning/requirements/postgresql.txt b/dsmrreader/provisioning/requirements/postgresql.txt index 3b4eaddf2..145972337 100644 --- a/dsmrreader/provisioning/requirements/postgresql.txt +++ b/dsmrreader/provisioning/requirements/postgresql.txt @@ -1 +1 @@ -psycopg2==2.7.1 +psycopg2==2.7.3.1 diff --git a/dsmrreader/provisioning/requirements/test.txt b/dsmrreader/provisioning/requirements/test.txt index b02b25705..663470127 100644 --- a/dsmrreader/provisioning/requirements/test.txt +++ b/dsmrreader/provisioning/requirements/test.txt @@ -1,5 +1,5 @@ polib==1.0.8 -pylama==7.3.3 +pylama==7.4.3 pytest-cov==2.5.1 pytest-django==3.1.2 -pytest-xdist==1.17.1 +pytest-xdist==1.20.1 diff --git a/dsmrreader/provisioning/requirements/travis.txt b/dsmrreader/provisioning/requirements/travis.txt index cbd17e414..6bdfe7726 100644 --- a/dsmrreader/provisioning/requirements/travis.txt +++ b/dsmrreader/provisioning/requirements/travis.txt @@ -1,2 +1,2 @@ # For some reason Travis needs to be forced installing this version, or the build pretend like it doesn't know 'pytest'. -pytest==3.1.2 +pytest==3.2.3 diff --git a/quick-test.sh b/quick-test.sh index 4a3a7a2cf..c452627d4 100755 --- a/quick-test.sh +++ b/quick-test.sh @@ -15,9 +15,12 @@ echo "OK" echo "" echo "--- Testing with SQLite (4 processes)..." -pytest --cov --cov-report=html:coverage_report/html --cov-report=term --ds=dsmrreader.config.test.sqlite -n 4 +pytest --cov --cov-report=html:coverage_report/html --cov-report=term --ds=dsmrreader.config.test.sqlite -n 4 # Remove annoying headers that get regenerated every time. sed -i '/"PO-Revision-Date:/d' dsmrreader/locales/nl/LC_MESSAGES/django.po sed -i '/"POT-Creation-Date:/d' dsmrreader/locales/nl/LC_MESSAGES/django.po + +sed -i '/"PO-Revision-Date:/d' docs/locale/nl/LC_MESSAGES/*.po +sed -i '/"POT-Creation-Date:/d' docs/locale/nl/LC_MESSAGES/*.po diff --git a/test-all.sh b/test-all.sh index ac0998574..12b080305 100755 --- a/test-all.sh +++ b/test-all.sh @@ -30,3 +30,6 @@ pytest --pylama --cov --cov-report=html:coverage_report/html --cov-report=term - # Remove annoying headers that get regenerated every time. sed -i '/"PO-Revision-Date:/d' dsmrreader/locales/nl/LC_MESSAGES/django.po sed -i '/"POT-Creation-Date:/d' dsmrreader/locales/nl/LC_MESSAGES/django.po + +sed -i '/"PO-Revision-Date:/d' docs/locale/nl/LC_MESSAGES/*.po +sed -i '/"POT-Creation-Date:/d' docs/locale/nl/LC_MESSAGES/*.po