diff --git a/.gitignore b/.gitignore index dc0fc06e8..46f77f409 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ /dsmrreader/settings.py /coverage_report/ /backups/ +/logs/ /.coverage diff --git a/docs/api.rst b/docs/api.rst index 55174c95f..5314d5784 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1,6 +1,6 @@ API === -The application has a simple, one-command API for remote dataloggers. +The application has a simple, one-command API for remote dataloggers. It allows you to run the datalogger and application separately. .. contents:: @@ -12,8 +12,10 @@ Configuration Enable API ^^^^^^^^^^ -By default the API is disabled in the application. You may enable it in your configuration or admin settings. +The API is disabled by default in the application. You may enable it in your configuration or admin settings. +Example +~~~~~~~ .. image:: _static/screenshots/admin_api_settings.png :target: _static/screenshots/admin_api_settings.png :alt: API admin settings @@ -22,16 +24,16 @@ Authentication ^^^^^^^^^^^^^^ Besides allowing the API to listen for requests, you will also need use the generated API Auth Key. It can be found on the same page as in the screenshot above. The configuration page will also display it, but only partly. -Feel free to alter the API Auth Key when required. The application initially randomly generates one for you. +Feel free to alter the API Auth Key when required. The application initially generates one randomly for you. You should pass it in the header of every API call. The header should be defined as ``X-AUTHKEY``. See below for an example. Examples -^^^^^^^^ +~~~~~~~~ Using ``cURL``:: - curl http://YOUR-DSMR-URL/api/v1/endpointX \ + curl http://YOUR-DSMR-URL/api/v1/datalogger/dsmrreading \ -d 'telegram=xxxxx' \ -H 'X-AUTHKEY: YOUR-DSMR-API-AUTHKEY' @@ -49,8 +51,13 @@ API calls POST ``/api/v1`` ``/datalogger/dsmrreading`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Description +~~~~~~~~~~~ This allows you to insert a raw telegram, read from your meter remotely, into the application as if it was read locally using the serial cable. +Parameters +~~~~~~~~~~ - Method: ``POST`` - Data: ``telegram`` (as raw string containing all linefeeds ``\n``, and carriage returns ``\r``, as well!) - Status code returned: ``HTTP 200`` on success, any other on failure. @@ -100,4 +107,145 @@ Example if response.status_code != 200: # Or you will find the error (hint) in the reponse body on failure. print('Error: {}'.format(response.text)) - \ No newline at end of file + + +Script +------ +Below is a more detailed script you can use to run via Supervisor. It will send telegrams to one or multiple instances of DSMR-reader. + + +.. note:: + + You will still require the ``dsmr`` user and VirtualEnv, :doc:`as discussed in the install guide` in **chapters 3 and 6**! + +**VirtualEnv**:: + + sudo su - dsmr + pip install pyserial==3.2.1 + pip install requests==2.12.4 + + +.. note:: + + The serial connection in this example is based on ``DSMR v4``. + +.. warning:: + + Don't forget to insert your own configuration below in ``API_SERVERS``. + +Client file in ``/home/dsmr/dsmr_datalogger_api_client.py``:: + + from time import sleep + + from serial.serialutil import SerialException + import requests + import serial + + + API_SERVERS = ( + ('http://HOST-OR-IP-ONE/api/v1/datalogger/dsmrreading', 'APIKEY-BLABLABLA-ABCDEFGHI'), + ### ('http://HOST-OR-IP-TWO/api/v1/datalogger/dsmrreading', 'APIKEY-BLABLABLA-JKLMNOPQR'), + ) + + + def main(): + print ('Starting...') + + while True: + telegram = read_telegram() + print('Read telegram', telegram) + + for current_server in API_SERVERS: + api_url, api_key = current_server + send_telegram(telegram, api_url, api_key) + print('Sent telegram to:', api_url) + + sleep(1) + + + def read_telegram(): + """ Reads the serial port until we can create a reading point. """ + serial_handle = serial.Serial() + serial_handle.port = '/dev/ttyUSB0' + serial_handle.baudrate = 115200 + serial_handle.bytesize = serial.EIGHTBITS + serial_handle.parity = serial.PARITY_NONE + serial_handle.stopbits = serial.STOPBITS_ONE + serial_handle.xonxoff = 1 + serial_handle.rtscts = 0 + serial_handle.timeout = 20 + + # This might fail, but nothing we can do so just let it crash. + serial_handle.open() + + telegram_start_seen = False + telegram = '' + + # Just keep fetching data until we got what we were looking for. + while True: + try: + data = serial_handle.readline() + except SerialException as error: + # Something else and unexpected failed. + print('Serial connection failed:', error) + return + + try: + # Make sure weird characters are converted properly. + data = str(data, 'utf-8') + except TypeError: + pass + + # This guarantees we will only parse complete telegrams. (issue #74) + if data.startswith('/'): + telegram_start_seen = True + + # Delay any logging until we've seen the start of a telegram. + if telegram_start_seen: + telegram += data + + # Telegrams ends with '!' AND we saw the start. We should have a complete telegram now. + if data.startswith('!') and telegram_start_seen: + serial_handle.close() + return telegram + + + def send_telegram(telegram, api_url, api_key): + # Register telegram by simply sending it to the application with a POST request. + response = requests.post( + api_url, + headers={'X-AUTHKEY': api_key}, + data={'telegram': telegram}, + ) + + # You will receive a status 200 when successful. + if response.status_code != 200: + # Or you will find the error (hint) in the response body on failure. + print('[!] Error: {}'.format(response.text)) + + + if __name__ == '__main__': + main() + + +Supervisor config in ``/etc/supervisor/conf.d/dsmr-client.conf``:: + + [program:dsmr_client_datalogger] + command=/usr/bin/nice -n 5 /home/dsmr/.virtualenvs/dsmrclient/bin/python3 -u /home/dsmr/dsmr_datalogger_api_client.py + pidfile=/var/tmp/dsmrreader--%(program_name)s.pid + user=dsmr + group=dsmr + autostart=true + autorestart=true + startsecs=1 + startretries=100 + stopwaitsecs=20 + stdout_logfile=/var/log/supervisor/%(program_name)s.log + stdout_logfile_maxbytes=10MB + stdout_logfile_backups=3 + + +**Supervisor**:: + + sudo supervisorctl reread + sudo supervisorctl update diff --git a/docs/application.rst b/docs/application.rst index f6645a457..dfeb43dff 100644 --- a/docs/application.rst +++ b/docs/application.rst @@ -47,7 +47,10 @@ Data preservation & backups - The SD card is by far **the weakest link** of this setup and **will** fail you some day. -- The application will, by default, create a backup every night. However, as the data is still stored **locally** on your 'vulnerable' SD card, you must export it off your RaspberryPi as well. +- The application will, by default, create a database backup every night. + + - 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. + - However, as the data is still stored **locally** on your 'vulnerable' SD card, you must export it off your RaspberryPi as well. - There is an builtin option to have backups synced to your **Dropbox**, *without exposing your Dropbox account and your private files in it*. diff --git a/docs/changelog.rst b/docs/changelog.rst index e0f79f45d..adced6187 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -17,6 +17,20 @@ Please make sure you have a fresh **database backup** before upgrading! Upgradin - `About upgrading `_. + +v1.5.2 - 2017-01-09 +^^^^^^^^^^^^^^^^^^^ + +**Tickets resolved in this release:** + +- Automatic refresh of dashboard charts (`#210 `_). +- Mindergas.nl API: Tijdstip van verzending willekeurig maken (`#204 `_). +- Extend API docs with additional example (`#185 `_). +- Docs: How to restore backup (`#190 `_). +- Log errors occured to file (`#181 `_). + + + v1.5.1 - 2017-01-04 ^^^^^^^^^^^^^^^^^^^ @@ -30,6 +44,7 @@ v1.5.1 - 2017-01-04 - Fix for issues `#200 `_ & `#217 `_, which is caused by omitting the switch to the VirtualEnv. This was not documented well enough in early versions of this project, causing failed upgrades. + v1.5.0 - 2017-01-01 ^^^^^^^^^^^^^^^^^^^ diff --git a/docs/faq.rst b/docs/faq.rst index 65c3aada2..e91200e37 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -135,8 +135,8 @@ This application displays separate tariffs by default, but supports merging them 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. -I want to see my electricity phases as well -------------------------------------------- +I want to see the load of each electricity phase as well +--------------------------------------------------------- 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. @@ -171,6 +171,58 @@ 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. +How do I restore a database backup? +----------------------------------- + +.. warning:: + + Restoring a backup will replace any existing data stored in the database and is irreversible! + +.. note:: + + 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**. + +Only want to restore the database? + +- This asumes you are still running the same application version as the backup was created in. + +- Stop the application first with ``sudo supervisorctl stop all``. This will disconnect it from the database as well. + +For **PostgreSQL** restores:: + + sudo sudo -u postgres dropdb dsmrreader + sudo sudo -u postgres createdb -O dsmrreader dsmrreader + + # Either restore an uncompressed (.sql) backup: + sudo sudo -u postgres psql dsmrreader -f + + # OR + + # Restore a compressed (.gz) backup with: + zcat | sudo sudo -u postgres psql dsmrreader + + +For **MySQL** restores:: + + sudo mysqladmin create dsmrreader + sudo mysqladmin drop dsmrreader + + # Either restore an uncompressed (.sql) backup: + cat | sudo mysql -D dsmrreader --defaults-file=/etc/mysql/debian.cnf + + # OR + + # Restore a compressed (.gz) backup with: + zcat | sudo mysql -D dsmrreader --defaults-file=/etc/mysql/debian.cnf + + +- Start the application again with ``sudo supervisorctl start all``. + +.. note:: + + In case the version differs, you can try forcing a deployment reload by: ``sudo su - dsmr`` and then executing ``./post-deploy.sh``. + Feature/bug report ------------------ diff --git a/docs/installation.rst b/docs/installation.rst index ae8dc0a8d..f00795df6 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -87,6 +87,18 @@ Does Postgres not start due to locales? Try: ``dpkg-reconfigure locales``. Stil sudo sudo -u postgres psql -c "alter user dsmrreader with password 'dsmrreader';" +.. note:: + + **Optional**: Do you need to restore a **PostgreSQL** database backup as well? + + Restore an uncompressed (``.sql``) backup with:: + + sudo sudo -u postgres psql dsmrreader -f + + Or restore a compressed (``.gz``) backup with:: + + zcat | sudo sudo -u postgres psql dsmrreader + (Option B.) MySQL/MariaDB ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -112,6 +124,18 @@ Install MariaDB. You can also choose to install the closed source MySQL, as they sudo mysqladmin reload --defaults-file=/etc/mysql/debian.cnf +.. note:: + + **Optional**: Do you need to restore a **MySQL** database backup as well? + + Restore an uncompressed (``.sql``) backup with:: + + cat | sudo mysql -D dsmrreader --defaults-file=/etc/mysql/debian.cnf + + Or restore a compressed (``.gz``) backup with:: + + zcat | sudo mysql -D dsmrreader --defaults-file=/etc/mysql/debian.cnf + 2. Dependencies --------------- diff --git a/docs/locale/nl/LC_MESSAGES/api.mo b/docs/locale/nl/LC_MESSAGES/api.mo index 5ad6b1e07..06ef8fd93 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 e5727dc15..ddae49f99 100644 --- a/docs/locale/nl/LC_MESSAGES/api.po +++ b/docs/locale/nl/LC_MESSAGES/api.po @@ -8,10 +8,9 @@ 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" +"POT-Creation-Date: 2017-01-02 21:13+0100\n" +"PO-Revision-Date: 2017-01-02 21:24+0100\n" "Last-Translator: Dennis Siemensma \n" -"Language-Team: Dennis Siemensma \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" @@ -25,10 +24,13 @@ msgid "API" msgstr "API" #: ../../api.rst:3 -msgid "The application has a simple, one-command API for remote dataloggers." +msgid "" +"The application has a simple, one-command API for remote dataloggers. It " +"allows you to run the datalogger and application separately." msgstr "" "De applicatie heeft een eenvoudige, enkele API-call voor dataloggers op " -"afstand." +"afstand. Hiermee kun je de datalogger en applicatie gescheiden van elkaar " +"draaien." #: ../../api.rst msgid "Contents" @@ -44,32 +46,36 @@ msgstr "API inschakelen" #: ../../api.rst:15 msgid "" -"By default the API is disabled in the application. You may enable it in " -"your configuration or admin settings." +"The API is disabled by default in the application. You may enable it in your " +"configuration or admin settings." msgstr "" -"Standaard is de API in de applicatie uitgeschakeld. Je kunt deze " -"inschakelen in het configuratiescherm of beheerderpaneel." +"Standaard is de API in de applicatie uitgeschakeld. Je kunt deze inschakelen " +"in het configuratiescherm of beheerderpaneel." + +#: ../../api.rst:18 ../../api.rst:66 +msgid "Example" +msgstr "Voorbeeld" -#: ../../api.rst:22 +#: ../../api.rst:24 msgid "Authentication" msgstr "Autorisatie" -#: ../../api.rst:23 +#: ../../api.rst:25 msgid "" -"Besides allowing the API to listen for requests, you will also need use " -"the generated API Auth Key. It can be found on the same page as in the " +"Besides allowing the API to listen for requests, you will also need use the " +"generated API Auth Key. It can be found on the same page as in the " "screenshot above. The configuration page will also display it, but only " "partly. Feel free to alter the API Auth Key when required. The application " -"initially randomly generates one for you." +"initially generates one randomly for you." msgstr "" "Naast het inschakelen van de API zul je ook een (automatisch) gegenereerde " -"API autorisatiesleutel moeten gebruiken. Deze kun je terugvinden op " -"dezelfde pagina als in bovenstaand screenshot. Op de configuratiepagina " -"staat de sleutel ook, maar slechts ten delete. Pas overigens gerust de API " +"API autorisatiesleutel moeten gebruiken. Deze kun je terugvinden op dezelfde " +"pagina als in bovenstaand screenshot. Op de configuratiepagina staat de " +"sleutel ook, maar slechts ten delete. Pas overigens gerust de API " "autorisatiesleutel naar wens aan. De applicatie genereert initieel " "(eenmalig) een voor je." -#: ../../api.rst:27 +#: ../../api.rst:29 msgid "" "You should pass it in the header of every API call. The header should be " "defined as ``X-AUTHKEY``. See below for an example." @@ -77,27 +83,31 @@ msgstr "" "Je moet deze gebruiken voor elke API call die je uitvoert. De header heet " "``X-AUTHKEY``. Zie hieronder voor een voorbeeld." -#: ../../api.rst:30 +#: ../../api.rst:32 msgid "Examples" msgstr "Voorbeelden" -#: ../../api.rst:32 +#: ../../api.rst:34 msgid "Using ``cURL``::" msgstr "Met ``cURL``::" -#: ../../api.rst:38 +#: ../../api.rst:40 msgid "Using ``requests``::" msgstr "Met ``requests``::" -#: ../../api.rst:48 +#: ../../api.rst:50 msgid "API calls" msgstr "API calls" -#: ../../api.rst:51 +#: ../../api.rst:53 msgid "POST ``/api/v1`` ``/datalogger/dsmrreading``" msgstr "POST ``/api/v1`` ``/datalogger/dsmrreading``" -#: ../../api.rst:52 +#: ../../api.rst:56 +msgid "Description" +msgstr "Beschrijving" + +#: ../../api.rst:57 msgid "" "This allows you to insert a raw telegram, read from your meter remotely, " "into the application as if it was read locally using the serial cable." @@ -105,28 +115,78 @@ msgstr "" "Dit staat je toe om een ruwe telegram aan de applicatie door te geven, " "wanneer je deze op afstand uitleest." -#: ../../api.rst:54 +#: ../../api.rst:60 +msgid "Parameters" +msgstr "Parameters" + +#: ../../api.rst:61 msgid "Method: ``POST``" msgstr "Methode: ``POST``" -#: ../../api.rst:55 +#: ../../api.rst:62 msgid "" "Data: ``telegram`` (as raw string containing all linefeeds ``\\n``, and " "carriage returns ``\\r``, as well!)" msgstr "" -"Data: ``telegram`` (als een ruwe tekenreeks inclusief zowel alle " -"regeleindes ``\\n`` als 'carriage returns' ``\\r``)" +"Data: ``telegram`` (als een ruwe tekenreeks inclusief zowel alle regeleindes " +"``\\n`` als 'carriage returns' ``\\r``)" -#: ../../api.rst:56 +#: ../../api.rst:63 msgid "Status code returned: ``HTTP 200`` on success, any other on failure." msgstr "" -"Status code resultaat: ``HTTP 200`` wanneer succesvol, elke andere code " -"bij falen." - -#: ../../api.rst:59 -msgid "Example" -msgstr "Voorbeeld" +"Status code resultaat: ``HTTP 200`` wanneer succesvol, elke andere code bij " +"falen." -#: ../../api.rst:61 +#: ../../api.rst:68 msgid "(using the ``requests`` library available on PIP)::" msgstr "(met de ``requests`` tool beschikbaar in PIP)::" + +#: ../../api.rst:113 +msgid "Script" +msgstr "Script" + +#: ../../api.rst:114 +msgid "" +"Below is a more detailed script you can use to run via Supervisor. It will " +"send telegrams to one or multiple instances of DSMR-reader." +msgstr "" +"Hieronder staat een uitgebreider script die je via Supervisor kan draaien. " +"Dit script stuurt telegrammen door naar één of meerdere instanties van DSMR-" +"reader." + +#: ../../api.rst:119 +msgid "" +"You will still require the ``dsmr`` user and VirtualEnv, :doc:`as discussed " +"in the install guide` in **chapters 3 and 6**!" +msgstr "" +"Je hebt nog steeds de ``dsmr`` gebruiker en VirtualEnv nodig, :doc:`zoals " +"besproken in de installatiehandleiding` in **hoofdstukken 3 en " +"6**!" + +#: ../../api.rst:121 +msgid "**VirtualEnv**::" +msgstr "**VirtualEnv**::" + +#: ../../api.rst:130 +msgid "The serial connection in this example is based on ``DSMR v4``." +msgstr "" +"De seriële verbinding in het voorbeeld hieronder is gebaseerd op ``DSMR v4``." + +#: ../../api.rst:134 +msgid "Don't forget to insert your own configuration below in ``API_SERVERS``." +msgstr "" +"Vergeet niet om je eigen configuratie hieronder in te stellen in " +"``API_SERVERS``." + +#: ../../api.rst:136 +msgid "Client file in ``/home/dsmr/dsmr_datalogger_api_client.py``::" +msgstr "Client bestand in ``/home/dsmr/dsmr_datalogger_api_client.py``::" + +#: ../../api.rst:231 +msgid "Supervisor config in ``/etc/supervisor/conf.d/dsmr-client.conf``::" +msgstr "" +"Supervisor configuratie in ``/etc/supervisor/conf.d/dsmr-client.conf``::" + +#: ../../api.rst:248 +msgid "**Supervisor**::" +msgstr "**Supervisor**::" diff --git a/docs/locale/nl/LC_MESSAGES/application.mo b/docs/locale/nl/LC_MESSAGES/application.mo index ed840e83c..d5e3cafc8 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 68c97a0e0..7ed57bfa7 100644 --- a/docs/locale/nl/LC_MESSAGES/application.po +++ b/docs/locale/nl/LC_MESSAGES/application.po @@ -2,8 +2,8 @@ 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 14:30+0100\n" +"POT-Creation-Date: 2017-01-03 20:39+0100\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" @@ -117,16 +117,29 @@ msgstr "" "gegarandeerd kapot** op een dag." #: ../../application.rst:50 +msgid "The application will, by default, create a database backup every night." +msgstr "De applicatie maakt standaard elke nacht een back-up." + +#: ../../application.rst:52 msgid "" -"The application will, by default, create a backup every night. However, as the " -"data is still stored **locally** on your 'vulnerable' SD card, you must export " -"it off your RaspberryPi as well." +"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 "" -"De applicatie maakt standaard elke nacht een back-up. 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." +"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:52 +#: ../../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." +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." + +#: ../../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*." @@ -135,7 +148,7 @@ msgstr "" "uploaden. *Zonder dat de applicatie toegang tot je (privé) bestanden in je " "Dropbox-account heeft*." -#: ../../application.rst:54 +#: ../../application.rst:57 msgid "" "Please either use this service or manage offloading backups on your own (see " "below)." @@ -143,12 +156,12 @@ msgstr "" "Zorg ervoor dat je ofwel deze feature gebruikt ofwel zelf back-ups maakt en ze " "regelmatig ergens heen kopieert (zie hieronder)." -#: ../../application.rst:56 +#: ../../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." -#: ../../application.rst:58 +#: ../../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 " @@ -159,7 +172,7 @@ msgstr "" "handmatig een back-up te maken naar een USB-stick die aan mijn RaspberryPi " "hangt." -#: ../../application.rst:60 +#: ../../application.rst:63 msgid "" "For **MySQL/MariaDB** you can use ``dsmrreader/provisioning/mysql/mysql-backup." "sh``." @@ -167,7 +180,7 @@ msgstr "" "Voor **MySQL/MariaDB** kun je dit script gebruiken: ``dsmrreader/provisioning/" "mysql/mysql-backup.sh``." -#: ../../application.rst:62 +#: ../../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``." @@ -175,7 +188,7 @@ 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``." -#: ../../application.rst:64 +#: ../../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 " @@ -185,7 +198,7 @@ msgstr "" "mogelijkheid toevoegen om oude metingen (niet de dagtotalen) te verwijderen na " "een X-periode." -#: ../../application.rst:66 +#: ../../application.rst:69 msgid "" "Everything OK? Congratulations, this was the hardest part and now the fun " "begins by monitoring your energy consumption." @@ -193,19 +206,19 @@ msgstr "" "Alles gelukt? Gefeliciteerd! Dit was het lastigste gedeelte en nu kun je " "eindelijk gebruikmaken van de applicatie en je energieverbruik meten." -#: ../../application.rst:70 +#: ../../application.rst:73 msgid "Application updates (bug fixes & new features)" msgstr "Applicatie updates (bugfixes & nieuwe mogelijkheden)" -#: ../../application.rst:74 +#: ../../application.rst:77 msgid ":doc:`This information can be found here`." msgstr ":doc:`Deze informatie kun je hier terugvinden`." -#: ../../application.rst:78 +#: ../../application.rst:81 msgid "Public webinterface warning" msgstr "Waarschuwing voor publiekelijke toegang" -#: ../../application.rst:82 +#: ../../application.rst:85 msgid "" "If you expose your application to the outside world or a public network, you " "might want to take additional steps:" @@ -213,7 +226,7 @@ msgstr "" "Wanneer je de applicatie koppelt aan het Internet wil je sowieso extra " "maatregelen nemen:" -#: ../../application.rst:84 +#: ../../application.rst:87 msgid "" "Please make sure to **alter** the ``SECRET_KEY`` setting in your ``dsmrreader/" "settings.py``." @@ -221,7 +234,7 @@ msgstr "" "Zorg ervoor dat je de instelling ``SECRET_KEY`` wijzigt in het bestand " "``dsmrreader/settings.py``." -#: ../../application.rst:86 +#: ../../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 " @@ -231,7 +244,7 @@ msgstr "" "hoogste map van project), die ervoor zorgt dat de hele applicatie zichzelf " "herlaadt en daarmee de nieuwe instellingen per direct gebruikt." -#: ../../application.rst:88 +#: ../../application.rst:91 msgid "" "Install a firewall, such as ``ufw`` `UncomplicatedFirewall `_ and restrict traffic to port ``22`` (only for " @@ -241,7 +254,7 @@ msgstr "" "ubuntu.com/UncomplicatedFirewall>`_) and beperk al het toegestane verkeer tot " "poort ``22`` (puur voor jezelf) en poort ``80``." -#: ../../application.rst:90 +#: ../../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 " @@ -252,7 +265,7 @@ msgstr "" "tekenreeks via `een van de vele websites die dit voor je kunnen doen `_." -#: ../../application.rst:94 +#: ../../application.rst:97 msgid "" "It's safe to a htpasswd generator, **just make sure to NEVER enter personal " "credentials** there **used for other applications or personal accounts**." @@ -261,11 +274,11 @@ msgstr "" "persoonlijke informatie of gegevens invoert die je ook op andere websites " "gebruikt**!" -#: ../../application.rst:96 +#: ../../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:98 +#: ../../application.rst:101 msgid "" "Open the site's vhost in ``/etc/nginx/sites-enabled/dsmr-webinterface`` and " "**uncomment** the following lines (remove the ##)::" @@ -273,15 +286,15 @@ msgstr "" "Open de website's vhost in ``/etc/nginx/sites-enabled/dsmr-webinterface`` en " "schakel de volgende regels in (verwijder de ## tekens)::" -#: ../../application.rst:103 +#: ../../application.rst:106 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:107 +#: ../../application.rst:110 msgid "And reload with::" msgstr "En herlaad met::" -#: ../../application.rst:111 +#: ../../application.rst:114 msgid "" "You should be prompted for login credentials the next time your browser " "accesses the application. For more information regarding this topic, see the " diff --git a/docs/locale/nl/LC_MESSAGES/changelog.mo b/docs/locale/nl/LC_MESSAGES/changelog.mo index fad99a195..6e92d9d89 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 3ffb97381..7ac8ba393 100644 --- a/docs/locale/nl/LC_MESSAGES/changelog.po +++ b/docs/locale/nl/LC_MESSAGES/changelog.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: DSMR Reader v1.x\n" "Report-Msgid-Bugs-To: Dennis Siemensma \n" -"POT-Creation-Date: 2017-01-04 19:34+0100\n" -"PO-Revision-Date: 2017-01-04 19:37+0100\n" +"POT-Creation-Date: 2017-01-03 19:26+0100\n" +"PO-Revision-Date: 2017-01-04 20:37+0100\n" "Last-Translator: Dennis Siemensma \n" "Language-Team: Dennis Siemensma \n" "MIME-Version: 1.0\n" @@ -36,9 +36,9 @@ msgid "" "Please make sure you have a fresh **database backup** before upgrading! " "Upgrading is very easy due to a builtin mechanism." msgstr "" -"Zorg er alsjeblieft voor dat je altijd een versie **database back-up** " -"hebt, vóórdat je upgrade! Het upgraden zelf is overigens erg eenvoudig " -"via een ingebouwd mechanisme." +"Zorg er alsjeblieft voor dat je altijd een versie **database back-up** hebt, " +"vóórdat je upgrade! Het upgraden zelf is overigens erg eenvoudig via een " +"ingebouwd mechanisme." #: ../../changelog.rst:16 msgid "" @@ -50,31 +50,57 @@ msgstr "" #: ../../changelog.rst:17 msgid "" -"`About upgrading `_." +"`About upgrading `_." msgstr "" "`Over update `_." +#: ../../changelog.rst:22 +msgid "v1.6.0 - 2017-xx-xx" +msgstr "" + +#: ../../changelog.rst:24 ../../changelog.rst:45 ../../changelog.rst:69 +#: ../../changelog.rst:81 ../../changelog.rst:95 ../../changelog.rst:102 +#: ../../changelog.rst:112 ../../changelog.rst:123 ../../changelog.rst:139 +#: ../../changelog.rst:146 ../../changelog.rst:153 ../../changelog.rst:166 +#: ../../changelog.rst:28 ../../changelog.rst:46 ../../changelog.rst:70 +#: ../../changelog.rst:82 ../../changelog.rst:96 ../../changelog.rst:103 +#: ../../changelog.rst:113 ../../changelog.rst:124 ../../changelog.rst:140 +#: ../../changelog.rst:147 ../../changelog.rst:154 ../../changelog.rst:167 +msgid "**Tickets resolved in this release:**" +msgstr "**Tickets die opgelost zijn in deze release:**" + +#: ../../changelog.rst:26 +msgid "" +"Automatic refresh of dashboard charts (`#210 `_)." +msgstr "" + +#: ../../changelog.rst:27 +msgid "" +"Extend API docs with additional example (`#185 `_)." +msgstr "" + +#: ../../changelog.rst:28 +msgid "" +"Docs: How to restore backup (`#190 `_)." +msgstr "" + #: ../../changelog.rst:21 msgid "v1.5.1 - 2017-01-04" msgstr "" #: ../../changelog.rst:25 msgid "" -"This patch contains no new features and **only solves upgrading issues** " -"for some users." +"This patch contains no new features and **only solves upgrading issues** for " +"some users." msgstr "" "Deze patch bevat geen nieuwe features en **lost alleen upgrade-problemen " "op** voor sommige gebruikers." -#: ../../changelog.rst:28 ../../changelog.rst:46 ../../changelog.rst:70 -#: ../../changelog.rst:82 ../../changelog.rst:96 ../../changelog.rst:103 -#: ../../changelog.rst:113 ../../changelog.rst:124 ../../changelog.rst:140 -#: ../../changelog.rst:147 ../../changelog.rst:154 ../../changelog.rst:167 -msgid "**Tickets resolved in this release:**" -msgstr "**Tickets die opgelost zijn in deze release:**" - #: ../../changelog.rst:30 msgid "" "Fix for issues `#200 `_ & `#217 `_, welke veroorzaakt worden door het niet wisselen " -"naar de VirtualEnv voor de upgrade. In eerdere versies van de project-" -"documentatie stond dit niet duidelijk genoeg beschreven en dat " -"veroorzaakt deze problemen." +"Oplossing voor tickets `#200 `_ & `#217 `_, welke veroorzaakt worden door het niet wisselen naar de " +"VirtualEnv voor de upgrade. In eerdere versies van de project-documentatie " +"stond dit niet duidelijk genoeg beschreven en dat veroorzaakt deze problemen." -#: ../../changelog.rst:34 +#: ../../changelog.rst:33 msgid "v1.5.0 - 2017-01-01" msgstr "" -#: ../../changelog.rst:36 ../../changelog.rst:78 +#: ../../changelog.rst:35 ../../changelog.rst:77 msgid "**Change in Python support**" msgstr "**Wijziging in Python-ondersteuning**" -#: ../../changelog.rst:38 +#: ../../changelog.rst:37 msgid "" "The support for ``Python 3.3`` has been **dropped** due to the Django " "upgrade (`#103 `_)." -#: ../../changelog.rst:39 +#: ../../changelog.rst:38 msgid "" "There is **experimental support** for ``Python 3.6`` and ``Python 3.7 " -"(nightly)`` as the unittests are `now built against those versions " -"`_ as well " -"(`#167 `_)." +"(nightly)`` as the unittests are `now built against those versions `_ as well (`#167 " +"`_)." msgstr "" -"Er is **experimentele ondersteuning** voor ``Python 3.6`` en ``Python " -"3.7 (nightly)`` gezien de unittests `momenteel ook in voor die versies " -"worden uitgevoerd. `_ (`#167 `_)." +"Er is **experimentele ondersteuning** voor ``Python 3.6`` en ``Python 3.7 " +"(nightly)`` gezien de unittests `momenteel ook in voor die versies worden " +"uitgevoerd. `_ " +"(`#167 `_)." -#: ../../changelog.rst:41 +#: ../../changelog.rst:40 msgid "**Legacy warning**" msgstr "**Waarschuwing voor legacy**" -#: ../../changelog.rst:43 +#: ../../changelog.rst:42 msgid "" "The migrations that were squashed together in (`#31 `_) have been **removed**. This " -"will only affect you when you are currently still running a dsmrreader-" -"version of **before** ``v0.13 (β)``." +"dennissiemensma/dsmr-reader/issues/31>`_) have been **removed**. This will " +"only affect you when you are currently still running a dsmrreader-version of " +"**before** ``v0.13 (β)``." msgstr "" "De migraties die samengevoegd zijn in (`#31 `_) zijn **verwijderd**. Hier heb " -"je alleen maar te maken wanneer je nog gebruik maakt van een dsmrreader-" -"versie **vóór** ``v0.13 (β)``." +"dennissiemensma/dsmr-reader/issues/31>`_) zijn **verwijderd**. Hier heb je " +"alleen maar te maken wanneer je nog gebruik maakt van een dsmrreader-versie " +"**vóór** ``v0.13 (β)``." -#: ../../changelog.rst:44 +#: ../../changelog.rst:43 msgid "" -"If you are indeed still running ``< v0.13 (β)``, please upgrade to " -"``v1.4`` first (!), followed by an upgrade to ``v1.5``." +"If you are indeed still running ``< v0.13 (β)``, please upgrade to ``v1.4`` " +"first (!), followed by an upgrade to ``v1.5``." 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``." +"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:48 +#: ../../changelog.rst:47 msgid "" -"Verify telegrams' CRC (`#188 `_)." +"Verify telegrams' CRC (`#188 `_)." msgstr "" -#: ../../changelog.rst:49 +#: ../../changelog.rst:48 msgid "" "Display last 24 hours on dashboard (`#164 `_)." msgstr "" -#: ../../changelog.rst:50 +#: ../../changelog.rst:49 msgid "" -"Status page visualisation (`#172 `_)." +"Status page visualisation (`#172 `_)." msgstr "" -#: ../../changelog.rst:51 +#: ../../changelog.rst:50 msgid "" "Store and display phases consumption (`#161 `_)." msgstr "" -#: ../../changelog.rst:52 +#: ../../changelog.rst:51 msgid "" "Weather graph not showing when no gas data is available (`#170 `_)." msgstr "" -#: ../../changelog.rst:53 +#: ../../changelog.rst:52 msgid "" "Upgrade to ChartJs 2.0 (`#127 `_)." msgstr "" -#: ../../changelog.rst:54 +#: ../../changelog.rst:53 msgid "" "Improve Statistics page performance (`#173 `_)." msgstr "" -#: ../../changelog.rst:55 +#: ../../changelog.rst:54 msgid "" -"Version checker at github (`#166 `_)." +"Version checker at github (`#166 `_)." msgstr "" -#: ../../changelog.rst:56 +#: ../../changelog.rst:55 msgid "" -"Remove required login for dismissal of in-app notifications (`#179 " -"`_)." +"Remove required login for dismissal of in-app notifications (`#179 `_)." msgstr "" -#: ../../changelog.rst:57 +#: ../../changelog.rst:56 msgid "" "Round numbers displayed in GUI to 2 decimals (`#183 `_)." msgstr "" -#: ../../changelog.rst:58 +#: ../../changelog.rst:57 msgid "" "Switch Nosetests to Pytest (+ pytest-cov) (`#167 `_)." msgstr "" -#: ../../changelog.rst:59 +#: ../../changelog.rst:58 msgid "" -"PyLama code audit (+ pytest-cov) (`#158 `_)." +"PyLama code audit (+ pytest-cov) (`#158 `_)." msgstr "" -#: ../../changelog.rst:60 +#: ../../changelog.rst:59 msgid "" "Double upgrade of Django framework ``Django 1.8`` -> ``Django 1.9`` -> " "``Django 1.10`` (`#103 `_)." msgstr "" -#: ../../changelog.rst:61 +#: ../../changelog.rst:60 msgid "" -"Force ``PYTHONUNBUFFERED`` for supervisor commands (`#176 `_)." +"Force ``PYTHONUNBUFFERED`` for supervisor commands (`#176 `_)." msgstr "" -#: ../../changelog.rst:62 +#: ../../changelog.rst:61 msgid "" -"Documentation updates for v1.5 (`#171 `_)." +"Documentation updates for v1.5 (`#171 `_)." msgstr "" -#: ../../changelog.rst:63 +#: ../../changelog.rst:62 msgid "" "Requirements update for v1.5 (december 2016) (`#182 `_)." msgstr "" -#: ../../changelog.rst:64 +#: ../../changelog.rst:63 msgid "" -"Improved backend process logging (`#184 `_)." +"Improved backend process logging (`#184 `_)." msgstr "" -#: ../../changelog.rst:68 +#: ../../changelog.rst:67 msgid "v1.4.1 - 2016-12-12" msgstr "" -#: ../../changelog.rst:72 +#: ../../changelog.rst:71 msgid "" -"Consumption chart hangs due to unique_key violation (`#174 `_)." +"Consumption chart hangs due to unique_key violation (`#174 `_)." msgstr "" -#: ../../changelog.rst:73 +#: ../../changelog.rst:72 msgid "" "NoReverseMatch at / Reverse for 'docs' (`#175 `_)." msgstr "" -#: ../../changelog.rst:77 +#: ../../changelog.rst:76 msgid "v1.4.0 - 2016-11-28" msgstr "" -#: ../../changelog.rst:80 +#: ../../changelog.rst:79 msgid "" -"Support for ``Python 3.5`` has been added officially (`#55 `_)." +"Support for ``Python 3.5`` has been added officially (`#55 `_)." msgstr "" -#: ../../changelog.rst:84 +#: ../../changelog.rst:83 msgid "" -"Push notifications for Notify My Android / Prowl (iOS), written by " -"Jeroen Peters (`#152 `_)." +"Push notifications for Notify My Android / Prowl (iOS), written by Jeroen " +"Peters (`#152 `_)." msgstr "" -#: ../../changelog.rst:85 +#: ../../changelog.rst:84 msgid "" "Support for both single and high/low tariff (`#130 `_)." msgstr "" -#: ../../changelog.rst:86 +#: ../../changelog.rst:85 msgid "" -"Add new note from Dashboard has wrong time format (`#159 `_)." +"Add new note from Dashboard has wrong time format (`#159 `_)." msgstr "" -#: ../../changelog.rst:87 +#: ../../changelog.rst:86 msgid "" "Display estimated price for current usage in Dashboard (`#155 `_)." msgstr "" -#: ../../changelog.rst:88 +#: ../../changelog.rst:87 msgid "" "Dropbox API v1 deprecated in June 2017 (`#142 `_)." msgstr "" -#: ../../changelog.rst:89 +#: ../../changelog.rst:88 msgid "" -"Improve code coverage (`#151 `_)." +"Improve code coverage (`#151 `_)." msgstr "" -#: ../../changelog.rst:90 +#: ../../changelog.rst:89 msgid "" -"Restyle configuration overview (`#156 `_)." +"Restyle configuration overview (`#156 `_)." msgstr "" -#: ../../changelog.rst:91 +#: ../../changelog.rst:90 msgid "" "Capability based push notifications (`#165 `_)." msgstr "" -#: ../../changelog.rst:95 +#: ../../changelog.rst:94 msgid "v1.3.2 - 2016-11-08" msgstr "" -#: ../../changelog.rst:98 +#: ../../changelog.rst:97 msgid "" "Requirements update (november 2016) (`#150 `_)." msgstr "" -#: ../../changelog.rst:102 +#: ../../changelog.rst:101 msgid "v1.3.1 - 2016-08-16" msgstr "" -#: ../../changelog.rst:105 +#: ../../changelog.rst:104 msgid "" "CSS large margin-bottom (`#144 `_)." msgstr "" -#: ../../changelog.rst:106 +#: ../../changelog.rst:105 msgid "" "Django security releases issued: 1.8.14 (`#147 `_)." msgstr "" -#: ../../changelog.rst:107 +#: ../../changelog.rst:106 msgid "" -"Requirements update (August 2016) (`#148 `_)." +"Requirements update (August 2016) (`#148 `_)." msgstr "" -#: ../../changelog.rst:108 +#: ../../changelog.rst:107 msgid "" -"Query performance improvements (`#149 `_)." +"Query performance improvements (`#149 `_)." msgstr "" -#: ../../changelog.rst:112 +#: ../../changelog.rst:111 msgid "v1.3.0 - 2016-07-15" msgstr "" -#: ../../changelog.rst:115 +#: ../../changelog.rst:114 msgid "" -"API endpoint for datalogger (`#140 `_)." +"API endpoint for datalogger (`#140 `_)." msgstr "" -#: ../../changelog.rst:116 +#: ../../changelog.rst:115 msgid "" "Colors for charts (`#137 `_)." msgstr "" -#: ../../changelog.rst:117 +#: ../../changelog.rst:116 msgid "" "Data export: Mindergas.nl (`#10 `_)." msgstr "" -#: ../../changelog.rst:118 +#: ../../changelog.rst:117 msgid "" -"Requirement upgrade (`#143 `_)." +"Requirement upgrade (`#143 `_)." msgstr "" -#: ../../changelog.rst:119 +#: ../../changelog.rst:118 msgid "" "Installation wizard for first time use (`#139 `_)." msgstr "" -#: ../../changelog.rst:123 +#: ../../changelog.rst:122 msgid "v1.2.0 - 2016-05-18" msgstr "" -#: ../../changelog.rst:126 +#: ../../changelog.rst:125 msgid "" -"Energy supplier prices does not indicate tariff type (Django admin) " -"(`#126 `_)." +"Energy supplier prices does not indicate tariff type (Django admin) (`#126 " +"`_)." msgstr "" -#: ../../changelog.rst:127 +#: ../../changelog.rst:126 msgid "" -"Requirements update (`#128 `_)." +"Requirements update (`#128 `_)." msgstr "" -#: ../../changelog.rst:128 +#: ../../changelog.rst:127 msgid "" "Force backup (`#123 `_)." msgstr "" -#: ../../changelog.rst:129 +#: ../../changelog.rst:128 msgid "" "Update clean-install.md (`#131 `_)." msgstr "" -#: ../../changelog.rst:130 +#: ../../changelog.rst:129 msgid "" -"Improve data export field names (`#132 `_)." +"Improve data export field names (`#132 `_)." msgstr "" -#: ../../changelog.rst:131 +#: ../../changelog.rst:130 msgid "" "Display average temperature in archive (`#122 `_)." msgstr "" -#: ../../changelog.rst:132 +#: ../../changelog.rst:131 msgid "" -"Pie charts on trends page overlap their canvas (`#136 `_)." +"Pie charts on trends page overlap their canvas (`#136 `_)." msgstr "" -#: ../../changelog.rst:133 +#: ../../changelog.rst:132 msgid "" -"'Slumber' consumption (`#115 `_)." +"'Slumber' consumption (`#115 `_)." msgstr "" -#: ../../changelog.rst:134 +#: ../../changelog.rst:133 msgid "" -"Show lowest & highest Watt peaks (`#138 `_)." +"Show lowest & highest Watt peaks (`#138 `_)." msgstr "" -#: ../../changelog.rst:135 +#: ../../changelog.rst:134 msgid "" "Allow day & hour statistics reset due to changing energy prices (`#95 " "`_)." msgstr "" -#: ../../changelog.rst:139 +#: ../../changelog.rst:138 msgid "v1.1.2 - 2016-05-01" msgstr "" -#: ../../changelog.rst:142 +#: ../../changelog.rst:141 msgid "" "Trends page giving errors (when lacking data) (`#125 `_)." msgstr "" -#: ../../changelog.rst:146 +#: ../../changelog.rst:145 msgid "v1.1.1 - 2016-04-27" msgstr "" -#: ../../changelog.rst:149 +#: ../../changelog.rst:148 msgid "" "Improve readme (`#124 `_)." msgstr "" -#: ../../changelog.rst:153 +#: ../../changelog.rst:152 msgid "v1.1.0 - 2016-04-23" msgstr "" -#: ../../changelog.rst:156 +#: ../../changelog.rst:155 msgid "" -"Autorefresh dashboard (`#117 `_)." +"Autorefresh dashboard (`#117 `_)." msgstr "" -#: ../../changelog.rst:157 +#: ../../changelog.rst:156 msgid "" -"Improve line graphs' visibility (`#111 `_)." +"Improve line graphs' visibility (`#111 `_)." msgstr "" -#: ../../changelog.rst:158 +#: ../../changelog.rst:157 msgid "" "Easily add notes (`#110 `_)." msgstr "" -#: ../../changelog.rst:159 +#: ../../changelog.rst:158 msgid "" -"Export data points in CSV format (`#2 `_)." +"Export data points in CSV format (`#2 `_)." msgstr "" -#: ../../changelog.rst:160 +#: ../../changelog.rst:159 msgid "" -"Allow day/month/year comparison (`#94 `_)." +"Allow day/month/year comparison (`#94 `_)." msgstr "" -#: ../../changelog.rst:161 +#: ../../changelog.rst:160 msgid "" "Docs: Add FAQ and generic application info (`#113 `_)." msgstr "" -#: ../../changelog.rst:162 +#: ../../changelog.rst:161 msgid "" "Support for Iskra meter (DSMR 2.x) (`#120 `_)." msgstr "" -#: ../../changelog.rst:166 +#: ../../changelog.rst:165 msgid "v1.0.1 - 2016-04-07" msgstr "" -#: ../../changelog.rst:169 +#: ../../changelog.rst:168 msgid "" "Update licence to OSI compatible one (`#119 `_)." msgstr "" -#: ../../changelog.rst:173 +#: ../../changelog.rst:172 msgid "v1.0.0 - 2016-04-07" msgstr "" -#: ../../changelog.rst:174 +#: ../../changelog.rst:173 msgid "First official stable release." msgstr "Eerste officiële stabiele release." -#: ../../changelog.rst:178 +#: ../../changelog.rst:177 msgid "[β] v0.1 (2015-10-29) to 0.16 (2016-04-06)" msgstr "" -#: ../../changelog.rst:181 +#: ../../changelog.rst:180 msgid "" -"All previous beta releases/changes have been combined to a single list " -"below." +"All previous beta releases/changes have been combined to a single list below." msgstr "" "Alle vorige bèta releases/veranderingen zijn gecombineerd tot een enkele " "lijst hieronder." -#: ../../changelog.rst:183 +#: ../../changelog.rst:182 msgid "" -"Move documentation to wiki or RTD (`#90 `_)." +"Move documentation to wiki or RTD (`#90 `_)." msgstr "" -#: ../../changelog.rst:184 +#: ../../changelog.rst:183 msgid "" "Translate README to Dutch (`#16 `_)." msgstr "" -#: ../../changelog.rst:185 +#: ../../changelog.rst:184 msgid "" -"Delete (recent) history page (`#112 `_)." +"Delete (recent) history page (`#112 `_)." msgstr "" -#: ../../changelog.rst:186 +#: ../../changelog.rst:185 msgid "" "Display most recent temperature in dashboard (`#114 `_)." msgstr "" -#: ../../changelog.rst:187 +#: ../../changelog.rst:186 msgid "" "Upgrade Django to 1.8.12 (`#118 `_)." msgstr "" -#: ../../changelog.rst:189 +#: ../../changelog.rst:188 msgid "" -"Redesign trends page (`#97 `_)." +"Redesign trends page (`#97 `_)." msgstr "" -#: ../../changelog.rst:190 +#: ../../changelog.rst:189 msgid "" "Support for summer time (`#105 `_)." msgstr "" +#: ../../changelog.rst:190 +msgid "" +"Support for Daylight Saving Time (DST) transition (`#104 `_)." +msgstr "" + #: ../../changelog.rst:191 msgid "" -"Support for Daylight Saving Time (DST) transition (`#104 `_)." +"Add (error) hints to status page (`#106 `_)." msgstr "" #: ../../changelog.rst:192 msgid "" -"Add (error) hints to status page (`#106 `_)." +"Keep track of version (`#108 `_)." msgstr "" -#: ../../changelog.rst:193 +#: ../../changelog.rst:194 msgid "" -"Keep track of version (`#108 `_)." +"Django 1.8.11 released (`#82 `_)." msgstr "" #: ../../changelog.rst:195 msgid "" -"Django 1.8.11 released (`#82 `_)." +"Prevent tests from failing due to moment of execution (`#88 `_)." msgstr "" #: ../../changelog.rst:196 msgid "" -"Prevent tests from failing due to moment of execution (`#88 `_)." -msgstr "" - -#: ../../changelog.rst:197 -msgid "" "Statistics page meter positions are broken (`#93 `_)." msgstr "" -#: ../../changelog.rst:198 +#: ../../changelog.rst:197 msgid "" "Archive only shows graph untill 23:00 (11 pm) (`#77 `_)." msgstr "" -#: ../../changelog.rst:199 +#: ../../changelog.rst:198 msgid "" -"Trends page crashes due to nullable fields average (`#100 `_)." +"Trends page crashes due to nullable fields average (`#100 `_)." msgstr "" -#: ../../changelog.rst:200 +#: ../../changelog.rst:199 msgid "" -"Trends: Plot peak and off-peak relative to each other (`#99 `_)." +"Trends: Plot peak and off-peak relative to each other (`#99 `_)." msgstr "" -#: ../../changelog.rst:201 +#: ../../changelog.rst:200 msgid "" "Monitor requirements with requires.io (`#101 `_)." msgstr "" -#: ../../changelog.rst:202 +#: ../../changelog.rst:201 msgid "" "Terminology (`#41 `_)." msgstr "" -#: ../../changelog.rst:203 +#: ../../changelog.rst:202 msgid "" "Obsolete signals in dsmr_consumption (`#63 `_)." msgstr "" -#: ../../changelog.rst:204 +#: ../../changelog.rst:203 msgid "" -"Individual app testing coverage (`#64 `_)." +"Individual app testing coverage (`#64 `_)." msgstr "" -#: ../../changelog.rst:205 +#: ../../changelog.rst:204 msgid "" -"Support for extra devices on other M-bus (0-n:24.1) (`#92 `_)." +"Support for extra devices on other M-bus (0-n:24.1) (`#92 `_)." msgstr "" -#: ../../changelog.rst:206 +#: ../../changelog.rst:205 msgid "" -"Separate post-deployment commands (`#102 `_)." +"Separate post-deployment commands (`#102 `_)." msgstr "" -#: ../../changelog.rst:208 +#: ../../changelog.rst:207 msgid "" "Show exceptions in production (webinterface) (`#87 `_)." msgstr "" -#: ../../changelog.rst:209 +#: ../../changelog.rst:208 msgid "" -"Keep Supervisor processes running (`#79 `_)." +"Keep Supervisor processes running (`#79 `_)." msgstr "" -#: ../../changelog.rst:210 +#: ../../changelog.rst:209 msgid "" "Hourly stats of 22:00:00+00 every day lack gas (`#78 `_)." msgstr "" -#: ../../changelog.rst:211 +#: ../../changelog.rst:210 msgid "" -"Test Travis-CI with MySQL + MariaDB + PostgreSQL (`#54 `_)." +"Test Travis-CI with MySQL + MariaDB + PostgreSQL (`#54 `_)." msgstr "" -#: ../../changelog.rst:212 +#: ../../changelog.rst:211 msgid "" -"PostgreSQL tests + nosetests + coverage failure: unrecognized " -"configuration parameter \"foreign_key_checks\" (`#62 `_)." +"PostgreSQL tests + nosetests + coverage failure: unrecognized configuration " +"parameter \"foreign_key_checks\" (`#62 `_)." msgstr "" -#: ../../changelog.rst:213 +#: ../../changelog.rst:212 msgid "" "Performance check (`#83 `_)." msgstr "" -#: ../../changelog.rst:214 +#: ../../changelog.rst:213 msgid "" -"Allow month & year archive (`#66 `_)." +"Allow month & year archive (`#66 `_)." msgstr "" -#: ../../changelog.rst:215 +#: ../../changelog.rst:214 msgid "" "Graphs keep increasing height on tablet (`#89 `_)." msgstr "" -#: ../../changelog.rst:217 +#: ../../changelog.rst:216 msgid "" "Delete StatsSettings(.track) settings model (`#71 `_)." msgstr "" -#: ../../changelog.rst:218 +#: ../../changelog.rst:217 msgid "" "Drop deprecated commands (`#22 `_)." msgstr "" -#: ../../changelog.rst:219 +#: ../../changelog.rst:218 msgid "" -"Datalogger doesn't work properly with DSMR 4.2 (KAIFA-METER) (`#73 " -"`_)." +"Datalogger doesn't work properly with DSMR 4.2 (KAIFA-METER) (`#73 `_)." msgstr "" -#: ../../changelog.rst:220 +#: ../../changelog.rst:219 msgid "" -"Dashboard month statistics costs does not add up (`#75 `_)." +"Dashboard month statistics costs does not add up (`#75 `_)." msgstr "" -#: ../../changelog.rst:221 +#: ../../changelog.rst:220 msgid "" "Log unhandled exceptions and errors (`#65 `_)." msgstr "" -#: ../../changelog.rst:222 +#: ../../changelog.rst:221 msgid "" "Datalogger crashes with IntegrityError because 'timestamp' is null (`#74 " "`_)." msgstr "" -#: ../../changelog.rst:223 +#: ../../changelog.rst:222 msgid "" "Trends are always shown in UTC (`#76 `_)." msgstr "" -#: ../../changelog.rst:224 +#: ../../changelog.rst:223 msgid "" "Squash migrations (`#31 `_)." msgstr "" -#: ../../changelog.rst:225 +#: ../../changelog.rst:224 msgid "" -"Display 'electricity returned' graph in dashboard (`#81 `_)." +"Display 'electricity returned' graph in dashboard (`#81 `_)." msgstr "" -#: ../../changelog.rst:226 +#: ../../changelog.rst:225 msgid "" -"Optional gas (and electricity returned) capabilities tracking (`#70 " -"`_)." +"Optional gas (and electricity returned) capabilities tracking (`#70 `_)." msgstr "" -#: ../../changelog.rst:227 +#: ../../changelog.rst:226 msgid "" "Add 'electricity returned' to trends page (`#84 `_)." msgstr "" -#: ../../changelog.rst:229 +#: ../../changelog.rst:228 msgid "" -"Archive: View past days details (`#61 `_)." +"Archive: View past days details (`#61 `_)." msgstr "" -#: ../../changelog.rst:230 +#: ../../changelog.rst:229 msgid "" "Dashboard: Consumption total for current month (`#60 `_)." msgstr "" -#: ../../changelog.rst:231 +#: ../../changelog.rst:230 msgid "" "Check whether gas readings are optional (`#34 `_)." msgstr "" -#: ../../changelog.rst:232 +#: ../../changelog.rst:231 msgid "" "Django security releases issued: 1.8.10 (`#68 `_)." msgstr "" -#: ../../changelog.rst:233 +#: ../../changelog.rst:232 msgid "" "Notes display in archive (`#69 `_)." msgstr "" -#: ../../changelog.rst:235 +#: ../../changelog.rst:234 msgid "" "Status page/alerts when features are disabled/unavailable (`#45 `_)." msgstr "" -#: ../../changelog.rst:236 +#: ../../changelog.rst:235 msgid "" -"Integrate Travis CI (`#48 `_)." +"Integrate Travis CI (`#48 `_)." msgstr "" -#: ../../changelog.rst:237 +#: ../../changelog.rst:236 msgid "" "Testing coverage (`#38 `_)." msgstr "" -#: ../../changelog.rst:238 +#: ../../changelog.rst:237 msgid "" -"Implement automatic backups & Dropbox cloud storage (`#44 `_)." +"Implement automatic backups & Dropbox cloud storage (`#44 `_)." msgstr "" -#: ../../changelog.rst:239 +#: ../../changelog.rst:238 msgid "" "Link code coverage service to repository (`#56 `_)." msgstr "" +#: ../../changelog.rst:239 +msgid "" +"Explore timezone.localtime() as replacement for datetime.astimezone() (`#50 " +"`_)." +msgstr "" + #: ../../changelog.rst:240 msgid "" -"Explore timezone.localtime() as replacement for datetime.astimezone() " -"(`#50 `_)." +"Align GasConsumption.read_at to represent the start of hour (`#40 `_)." msgstr "" -#: ../../changelog.rst:241 +#: ../../changelog.rst:242 msgid "" -"Align GasConsumption.read_at to represent the start of hour (`#40 " -"`_)." +"Cleanup unused static files (`#47 `_)." msgstr "" #: ../../changelog.rst:243 msgid "" -"Cleanup unused static files (`#47 `_)." +"Investigated mysql_tzinfo_to_sql — Load the Time Zone Tables (`#35 `_)." msgstr "" #: ../../changelog.rst:244 msgid "" -"Investigated mysql_tzinfo_to_sql — Load the Time Zone Tables (`#35 " -"`_)." +"Make additional DSMR data optional (`#46 `_)." msgstr "" #: ../../changelog.rst:245 msgid "" -"Make additional DSMR data optional (`#46 `_)." +"Localize graph x-axis (`#42 `_)." msgstr "" #: ../../changelog.rst:246 msgid "" -"Localize graph x-axis (`#42 `_)." -msgstr "" - -#: ../../changelog.rst:247 -msgid "" "Added graph formatting string to gettext file (`#42 `_)." msgstr "" -#: ../../changelog.rst:248 +#: ../../changelog.rst:247 msgid "" -"Different colors for peak & off-peak electricity (`#52 `_)." +"Different colors for peak & off-peak electricity (`#52 `_)." msgstr "" -#: ../../changelog.rst:249 +#: ../../changelog.rst:248 msgid "" "Admin: Note widget (`#51 `_)." msgstr "" -#: ../../changelog.rst:250 +#: ../../changelog.rst:249 msgid "" -"Allow GUI to run without data (`#26 `_)." +"Allow GUI to run without data (`#26 `_)." msgstr "" -#: ../../changelog.rst:252 +#: ../../changelog.rst:251 msgid "" "Moved project to GitHub (`#28 `_)." msgstr "" -#: ../../changelog.rst:253 +#: ../../changelog.rst:252 msgid "Added stdout to dsmr_backend to reflect progress." msgstr "" -#: ../../changelog.rst:254 +#: ../../changelog.rst:253 msgid "" "Restore note usage in GUI (`#39 `_)." msgstr "" -#: ../../changelog.rst:256 +#: ../../changelog.rst:255 msgid "" -"Store daily, weekly, monthly and yearly statistics (`#3 `_)." +"Store daily, weekly, monthly and yearly statistics (`#3 `_)." msgstr "" -#: ../../changelog.rst:257 +#: ../../changelog.rst:256 msgid "" -"Improved Recent History page performance a bit. (as result of `#3 " -"`_)" +"Improved Recent History page performance a bit. (as result of `#3 `_)" msgstr "" -#: ../../changelog.rst:258 +#: ../../changelog.rst:257 msgid "" "Updates ChartJS library tot 1.1, disposing django-chartjs plugin. Labels " "finally work! (as result of `#3 `_)" msgstr "" -#: ../../changelog.rst:259 +#: ../../changelog.rst:258 msgid "" "Added trends page. (as result of `#3 `_)" msgstr "" -#: ../../changelog.rst:261 +#: ../../changelog.rst:260 msgid "" -"Recent history setting: set range (`#29 `_)." +"Recent history setting: set range (`#29 `_)." msgstr "" -#: ../../changelog.rst:262 +#: ../../changelog.rst:261 msgid "" -"Mock required for test: dsmr_weather.test_weather_tracking (`#32 " -"`_)." +"Mock required for test: dsmr_weather.test_weather_tracking (`#32 `_)." msgstr "" -#: ../../changelog.rst:264 +#: ../../changelog.rst:263 msgid "" -"Massive refactoring: Separating apps & using signals (`#19 `_)." +"Massive refactoring: Separating apps & using signals (`#19 `_)." msgstr "" -#: ../../changelog.rst:265 +#: ../../changelog.rst:264 msgid "" "README update: Exit character for cu (`#27 `_, by Jeroen Peters)." msgstr "" -#: ../../changelog.rst:266 +#: ../../changelog.rst:265 msgid "Fixed untranslated strings in admin interface." msgstr "" -#: ../../changelog.rst:267 +#: ../../changelog.rst:266 msgid "Upgraded Django to 1.8.9." msgstr "" diff --git a/docs/locale/nl/LC_MESSAGES/faq.mo b/docs/locale/nl/LC_MESSAGES/faq.mo index f0978c3b8..3199432c3 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 3f087b33f..d2fb7dadc 100644 --- a/docs/locale/nl/LC_MESSAGES/faq.po +++ b/docs/locale/nl/LC_MESSAGES/faq.po @@ -8,8 +8,8 @@ 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" +"POT-Creation-Date: 2017-01-03 20:52+0100\n" +"PO-Revision-Date: 2017-01-03 20:58+0100\n" "Last-Translator: Dennis Siemensma \n" "Language-Team: Dennis Siemensma \n" "MIME-Version: 1.0\n" @@ -319,8 +319,8 @@ msgstr "" "interfaceconfiguratie." #: ../../faq.rst:139 -msgid "I want to see my electricity phases as well" -msgstr "Ik wil mijn elektriciteitsfasen ook inzien" +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 msgid "" @@ -417,15 +417,78 @@ msgstr "" "sowieso slechts een keer per uur bijgewerkt (voor DSMR v4). De Status-pagina " "geeft je hier overigens ook inzicht in." -#: ../../faq.rst:176 +#: ../../faq.rst:175 +msgid "How do I restore a database backup?" +msgstr "Hoe zet ik een databaseback-up terug?" + +#: ../../faq.rst:179 +msgid "" +"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!" + +#: ../../faq.rst:183 +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**." +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**." + +#: ../../faq.rst:186 +msgid "Only want to restore the database?" +msgstr "Wil je alleen een databaseback-up terugzetten?" + +#: ../../faq.rst:188 +msgid "" +"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." + +#: ../../faq.rst:190 +msgid "" +"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." + +#: ../../faq.rst:192 +msgid "For **PostgreSQL** restores::" +msgstr "Voor herstellen van **PostgreSQL**::" + +#: ../../faq.rst:206 +msgid "For **MySQL** restores::" +msgstr "Voor herstellen van **MySQL**::" + +#: ../../faq.rst:220 +msgid "Start the application again with ``sudo supervisorctl start all``." +msgstr "Start de applicatie weer met ``sudo supervisorctl start all``." + +#: ../../faq.rst:224 +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." + +#: ../../faq.rst:228 msgid "Feature/bug report" msgstr "Verzoek/fout melden" -#: ../../faq.rst:177 +#: ../../faq.rst:229 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:181 +#: ../../faq.rst:233 msgid "" "`Just create a ticket at Github `_." diff --git a/docs/locale/nl/LC_MESSAGES/installation.mo b/docs/locale/nl/LC_MESSAGES/installation.mo index 996d25a0f..a67342935 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 0f25bebc6..4d677934f 100644 --- a/docs/locale/nl/LC_MESSAGES/installation.po +++ b/docs/locale/nl/LC_MESSAGES/installation.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: DSMR Reader v1.x\n" "Report-Msgid-Bugs-To: Dennis Siemensma \n" -"POT-Creation-Date: 2017-01-01 14:54+0100\n" -"PO-Revision-Date: 2017-01-01 14:56+0100\n" +"POT-Creation-Date: 2017-01-03 19:26+0100\n" +"PO-Revision-Date: 2017-01-03 19:29+0100\n" "Last-Translator: Dennis Siemensma \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -180,7 +180,7 @@ msgstr "" "PostgreSQL te kiezen. Dit vanwege de uitstekende ingebouwde ondersteuning voor " "tijdzones (nodig voor zomer-/wintertijd)." -#: ../../installation.rst:67 ../../installation.rst:245 +#: ../../installation.rst:67 ../../installation.rst:269 msgid "(Option A.) PostgreSQL" msgstr "(Keuze A.) PostgreSQL" @@ -192,7 +192,7 @@ msgstr "" "Installeer PostgreSQL. Daarnaast is ``postgresql-server-dev-all`` nodig voor " "het installeren van de VirtualEnv later." -#: ../../installation.rst:70 ../../installation.rst:95 +#: ../../installation.rst:70 ../../installation.rst:107 msgid "Install database::" msgstr "Installeer database::" @@ -215,7 +215,7 @@ msgstr "" "(!) Negeer voor de volgende drie commando's de foutmelding: '*could not change " "directory to \"/root\": Permission denied*'." -#: ../../installation.rst:78 ../../installation.rst:103 +#: ../../installation.rst:78 ../../installation.rst:115 msgid "Create database user::" msgstr "Creëer databasegebruiker::" @@ -229,11 +229,25 @@ msgstr "" msgid "Set password for database user::" msgstr "Stel wachtwoord in voor databasegebruiker::" -#: ../../installation.rst:92 ../../installation.rst:253 +#: ../../installation.rst:92 +msgid "" +"**Optional**: Do you need to restore a **PostgreSQL** database backup as well?" +msgstr "" +"**Optioneel**: Wil je ook nog een **PostgreSQL** database back-up herstellen?" + +#: ../../installation.rst:94 ../../installation.rst:131 +msgid "Restore an uncompressed (``.sql``) backup with::" +msgstr "Herstel een ongecomprimeerde (``.sql``) back-up met::" + +#: ../../installation.rst:98 ../../installation.rst:135 +msgid "Or restore a compressed (``.gz``) backup with::" +msgstr "Of herstel een gecomprimeerde (``.gz``) back-up met::" + +#: ../../installation.rst:104 ../../installation.rst:277 msgid "(Option B.) MySQL/MariaDB" msgstr "(Keuze B.) MySQL/MariaDB" -#: ../../installation.rst:93 +#: ../../installation.rst:105 msgid "" "Install MariaDB. You can also choose to install the closed source MySQL, as " "they should be interchangeable anyway. ``libmysqlclient-dev`` is required for " @@ -243,23 +257,27 @@ msgstr "" "installeren. Welke je ook kiest, ``libmysqlclient-dev`` is later nodig voor de " "VirtualEnv." -#: ../../installation.rst:99 +#: ../../installation.rst:111 msgid "Create database::" msgstr "Creëer database::" -#: ../../installation.rst:107 +#: ../../installation.rst:119 msgid "Set privileges for database user::" msgstr "Stel rechten in voor databasegebruiker::" -#: ../../installation.rst:111 +#: ../../installation.rst:123 msgid "Flush privileges to activate them::" msgstr "Pas de databaserechten toe::" -#: ../../installation.rst:117 +#: ../../installation.rst:129 +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:141 msgid "2. Dependencies" msgstr "2. Afhankelijkheden" -#: ../../installation.rst:118 +#: ../../installation.rst:142 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 " @@ -269,7 +287,7 @@ msgstr "" "de Gunicorn applicatieserver en voor het binnenhalen van de code van de " "applicatie vanaf Github::" -#: ../../installation.rst:122 +#: ../../installation.rst:146 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 " @@ -279,11 +297,11 @@ msgstr "" "verbinding testen naar je slimme meter toe. Erg handig om te kijken of dat " "überhaupt al lekker werkt." -#: ../../installation.rst:128 +#: ../../installation.rst:152 msgid "3. Application user" msgstr "3. Applicatiegebruiker" -#: ../../installation.rst:129 +#: ../../installation.rst:153 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." @@ -291,7 +309,7 @@ msgstr "" "De applicatie draait standaard onder de gebruiker ``dsmr``. Hierdoor heeft het " "geen ``root``-rechten (nodig), wat over het algemeen zeer afgeraden wordt." -#: ../../installation.rst:131 +#: ../../installation.rst:155 msgid "" "Create user with homedir. The application code and virtualenv will reside in " "this directory as well::" @@ -299,7 +317,7 @@ msgstr "" "Maak een aparte gebruiker aan met eigen homedir. De code voor de applicatie en " "VirtualEnv zetten we later hier in::" -#: ../../installation.rst:135 +#: ../../installation.rst:159 msgid "" "Our user also requires dialout permissions. So allow the user to perform a " "dialout by adding it to the ``dialout`` group::" @@ -307,7 +325,7 @@ msgstr "" "De gebruiker heeft ook toegang nodig om de kabel te kunnen uitlezen. Hiervoor " "voegen de we gebruiker toe aan de groep ``dialout``::" -#: ../../installation.rst:139 +#: ../../installation.rst:163 msgid "" "Either proceed to the next heading **for a test reading** or continue at " "chapter 4." @@ -315,11 +333,11 @@ msgstr "" "Ga ofwel door naar het volgende hoofdstuk **voor een testmeting** of ga direct " "door naar stap 4." -#: ../../installation.rst:143 +#: ../../installation.rst:167 msgid "Your first reading (optional)" msgstr "Je allereerste (optionele) meting" -#: ../../installation.rst:147 +#: ../../installation.rst:171 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 " @@ -331,7 +349,7 @@ msgstr "" "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:149 +#: ../../installation.rst:173 msgid "" "Now login as the user we have just created, to perform our very first " "reading! ::" @@ -339,15 +357,15 @@ msgstr "" "Log nu in als de gebruiker die we zojuist hebben aangemaakt voor de eerste " "testmeting! ::" -#: ../../installation.rst:153 +#: ../../installation.rst:177 msgid "Test with ``cu`` for **DSMR 4+**::" msgstr "Test met ``cu`` voor **DSMR 4+**::" -#: ../../installation.rst:157 +#: ../../installation.rst:181 msgid "Or test with ``cu`` for **DSMR 2.2** (untested)::" msgstr "Of test met ``cu`` voor **DSMR 2.2** (ongetest)::" -#: ../../installation.rst:161 +#: ../../installation.rst:185 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 " @@ -360,7 +378,7 @@ msgstr "" "Of `kijk op een nuttig weblog `_." -#: ../../installation.rst:163 +#: ../../installation.rst:187 msgid "" "To exit cu, type \"``q.``\", hit Enter and wait for a few seconds. It should " "exit with the message ``Disconnected.``." @@ -368,11 +386,11 @@ 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.``." -#: ../../installation.rst:167 +#: ../../installation.rst:191 msgid "4. Webserver/Nginx (part 1)" msgstr "4. Webserver/Nginx (deel 1)" -#: ../../installation.rst:169 +#: ../../installation.rst:193 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, " @@ -382,11 +400,11 @@ msgstr "" "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:171 +#: ../../installation.rst:195 msgid "Make sure you are still acting here as ``root`` or ``sudo`` user." msgstr "Zorg ervoor dat je hier nog steeds ``root``- of ``sudo``-gebruiker bent." -#: ../../installation.rst:173 +#: ../../installation.rst:197 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::" @@ -394,11 +412,11 @@ msgstr "" "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:181 +#: ../../installation.rst:205 msgid "5. Clone project code from Github" msgstr "5. Kloon project code vanaf Github" -#: ../../installation.rst:182 +#: ../../installation.rst:206 msgid "" "Now is the time to clone the code from the repository into the homedir we " "created." @@ -406,7 +424,7 @@ msgstr "" "Nu kunnen we de code van de applicatie van Github downloaden en in de homedir " "zetten die we net aangemaakt hebben." -#: ../../installation.rst:184 +#: ../../installation.rst:208 msgid "" "Make sure you are now acting as ``dsmr`` user (if not then enter: ``sudo su - " "dsmr``)" @@ -414,11 +432,11 @@ msgstr "" "Zorg ervoor dat je ingelogd bent als ``dsmr``-gebruiker (zo niet, typ dan: " "``sudo su - dsmr``)" -#: ../../installation.rst:186 +#: ../../installation.rst:210 msgid "Clone the repository::" msgstr "Kloon de repository::" -#: ../../installation.rst:190 +#: ../../installation.rst:214 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." @@ -427,11 +445,11 @@ msgstr "" "genaamd ``dsmr-reader``, met daarin een kopie van de repository zoals die op " "Github staat." -#: ../../installation.rst:194 +#: ../../installation.rst:218 msgid "6. Virtualenv" msgstr "6. VirtualEnv" -#: ../../installation.rst:196 +#: ../../installation.rst:220 msgid "" "The dependencies our application uses are stored in a separate environment, " "also called **VirtualEnv**." @@ -439,7 +457,7 @@ msgstr "" "Alle (externe) afhankelijkheden worden opgeslagen in een aparte omgeving, ook " "wel **VirtualEnv** genoemd." -#: ../../installation.rst:198 +#: ../../installation.rst:222 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 " @@ -452,7 +470,7 @@ msgstr "" "dat dat elkaar bijt. Meer informatie hierover `kan hier gevonden worden `_." -#: ../../installation.rst:201 +#: ../../installation.rst:225 msgid "" "Make sure you are still acting as ``dsmr`` user (if not then enter: ``sudo su - " "dsmr``)" @@ -460,11 +478,11 @@ msgstr "" "Zorg ervoor dat je nog steeds ingelogd bent als ``dsmr``-gebruiker (zo niet, " "typ dan: ``sudo su - dsmr``)" -#: ../../installation.rst:203 +#: ../../installation.rst:227 msgid "Create folder for the virtualenv(s) of this user::" msgstr "Maak map aan voor de VirtualEnv van deze gebruiker::" -#: ../../installation.rst:207 +#: ../../installation.rst:231 msgid "" "Create a new virtualenv, we usually use the same name for it as the application " "or project::" @@ -472,14 +490,14 @@ msgstr "" "Maak een nieuwe VirtualEnv aan. Het is gebruikelijk om hiervoor dezelfde naam " "te gebruiken als die van de applicatie of het project." -#: ../../installation.rst:213 +#: ../../installation.rst:237 msgid "" "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::" -#: ../../installation.rst:215 +#: ../../installation.rst:239 msgid "" "Put both commands below in the ``dsmr`` user's ``~/.bashrc`` file with your " "favorite text editor::" @@ -487,7 +505,7 @@ msgstr "" "Zet beide commands in het ``~/.bashrc`` bestand van de ``dsmr`` gebruiker met " "je favoriete bestandseditor::" -#: ../../installation.rst:221 +#: ../../installation.rst:245 msgid "" "This will both **activate** the virtual environment and cd you into the right " "directory on your **next login** as ``dsmr`` user." @@ -495,7 +513,7 @@ msgstr "" "Hiermee wordt zowel de VirtualEnv geactiveerd én ga je direct naar de juiste " "map. Dit werkt de **eerstvolgende keer** dat je inlogt als ``dsmr`` gebruiker." -#: ../../installation.rst:225 +#: ../../installation.rst:249 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``." @@ -503,7 +521,7 @@ 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``." -#: ../../installation.rst:227 +#: ../../installation.rst:251 msgid "" "You should see the terminal have a ``(dsmrreader)`` prefix now, for example: " "``(dsmrreader)dsmr@rasp:~/dsmr-reader $``" @@ -511,7 +529,7 @@ msgstr "" "Als het goed is heeft je terminal nu een ``(dsmrreader)`` prefix, bijvoorbeeld: " "``(dsmrreader)dsmr@rasp:~/dsmr-reader $``" -#: ../../installation.rst:229 +#: ../../installation.rst:253 msgid "" "Make sure you've read and executed the note above, because you'll need it for " "the next chapter." @@ -519,11 +537,11 @@ msgstr "" "Zorg ervoor dat je bovenstaande notities hebt gelezen én uitgevoerd, aangezien " "ze nodig zijn voor het volgende hoofdstuk." -#: ../../installation.rst:233 +#: ../../installation.rst:257 msgid "7. Application configuration & setup" msgstr "7. Applicatieconfiguratie" -#: ../../installation.rst:234 +#: ../../installation.rst:258 msgid "" "Earlier in this guide you had to choose for either **(A.) PostgreSQL** or " "**(B.) MySQL/MariaDB**. Our application needs to know which backend used in " @@ -533,7 +551,7 @@ msgstr "" "ofwel **(B.) MySQL/MariaDB**. De applicatie moet zelf ook weten met welke " "variant hij communiceert." -#: ../../installation.rst:236 +#: ../../installation.rst:260 msgid "" "Therefor I created two default (Django-)settings files you can copy, one for " "each backend. The application will also need the appropriate database client, " @@ -546,7 +564,7 @@ msgstr "" "Daarvoor heb ik ook een tweetal requirements-bestanden gemaakt, waar alles al " "in staat wat nodig is. Zoals bijvoorbeeld Django en de databaseverbinding." -#: ../../installation.rst:238 +#: ../../installation.rst:262 msgid "" "The ``base.txt`` contains requirements which the application needs anyway, no " "matter which backend you've choosen." @@ -554,7 +572,7 @@ msgstr "" "Het bestand ``base.txt`` bevat alle afhankelijkheden die de applicatie sowieso " "nodig heeft, ongeacht de databasekeuze die je gemaakt hebt." -#: ../../installation.rst:242 +#: ../../installation.rst:266 msgid "" "**Installation of the requirements below might take a while**, depending on " "your Internet connection, RaspberryPi speed and resources (generally CPU) " @@ -565,15 +583,15 @@ msgstr "" "verbinding en je RaspberryPi. Je hoeft je dus niet zorgen te maken wanneer dit " "lang lijkt te duren. :]" -#: ../../installation.rst:246 +#: ../../installation.rst:270 msgid "Did you choose PostgreSQL? Then execute these two lines::" msgstr "Heb je gekozen voor PostgreSQL? Voer dan deze twee regels uit::" -#: ../../installation.rst:254 +#: ../../installation.rst:278 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:261 +#: ../../installation.rst:285 msgid "" "Did everything install without fatal errors? If either of the database clients " "refuses to install due to missing files/configs, make sure you've installed " @@ -588,11 +606,11 @@ msgstr "" "(voor **MySQL**) geïnstalleerd, tegelijkertijd met de databaseserver. Die zijn " "namelijk hiervoor nodig." -#: ../../installation.rst:267 +#: ../../installation.rst:291 msgid "8. Bootstrapping" msgstr "8. Initialisatie" -#: ../../installation.rst:268 +#: ../../installation.rst:292 msgid "" "Now it's time to bootstrap the application and check whether all settings are " "good and requirements are met." @@ -600,11 +618,11 @@ msgstr "" "Tijd om te kijken of alles goed is ingesteld. We gaan de applicatie proberen te " "initialiseren." -#: ../../installation.rst:270 +#: ../../installation.rst:294 msgid "Execute this to initialize the database we've created earlier::" msgstr "Voer dit uit om de database te initialiseren::" -#: ../../installation.rst:274 +#: ../../installation.rst:298 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 " @@ -615,11 +633,11 @@ msgstr "" "hebben aangemaakt. Het zorgt ervoor dat Nginx deze bestanden kan hosten buiten " "de code-bestanden." -#: ../../installation.rst:277 +#: ../../installation.rst:301 msgid "Sync static files::" msgstr "Synchroniseer statische bestanden::" -#: ../../installation.rst:281 +#: ../../installation.rst:305 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 " @@ -631,11 +649,11 @@ msgstr "" "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:284 +#: ../../installation.rst:308 msgid "Create your user::" msgstr "Creëer je eigen gebruiker::" -#: ../../installation.rst:290 +#: ../../installation.rst:314 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::" @@ -643,15 +661,15 @@ msgstr "" "Wachtwoord ooit vergeten? Via de command line kun je je wachtwoord (bij " "verlies) hiermee aanpassen::" -#: ../../installation.rst:294 +#: ../../installation.rst:318 msgid "You've almost completed the installation now." msgstr "Je bent op dit punt bijna klaar met de installatie." -#: ../../installation.rst:298 +#: ../../installation.rst:322 msgid "9. Webserver/Nginx (part 2)" msgstr "9. Webserver/Nginx (deel 2)" -#: ../../installation.rst:302 +#: ../../installation.rst:326 msgid "" "This installation guide asumes you run the Nginx webserver for this application " "only." @@ -659,7 +677,7 @@ msgstr "" "Deze installatiehandleiding gaat er vanuit dat je de Nginx webserver alleen " "gebruikt voor deze applicatie." -#: ../../installation.rst:304 +#: ../../installation.rst:328 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 " @@ -669,7 +687,7 @@ msgstr "" "daarvoor zul je de wildcard moet weghalen in de ``dsmr-webinterface`` vhost, " "die je hieronder kopieert." -#: ../../installation.rst:306 +#: ../../installation.rst:330 msgid "" "Go back to ``root`` / ``sudo`` user to configure the webserver (press ``CTRL + " "D`` once)." @@ -677,7 +695,7 @@ msgstr "" "Ga terug naar de ``root`` / ``sudo``-gebruiker om de webserver in te stellen " "(druk op ``CTRL + D``)." -#: ../../installation.rst:308 +#: ../../installation.rst:332 msgid "" "Remove the default Nginx vhost (**only when you do not use it yourself, see the " "note above**)::" @@ -685,7 +703,7 @@ msgstr "" "Verwijder de standaard vhost van Nginx **wanneer je deze niet zelf gebruikt** " "(zie de notitie hierboven)::" -#: ../../installation.rst:312 +#: ../../installation.rst:336 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 " @@ -694,18 +712,18 @@ msgstr "" "Kopieer de vhost voor de applicatie. Deze luistert standaard naar **elke " "hostname** (wildcard), maar dat is natuurlijk naar eigen wens aan te passen::" -#: ../../installation.rst:316 +#: ../../installation.rst:340 msgid "" "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::" -#: ../../installation.rst:325 +#: ../../installation.rst:349 msgid "10. Supervisor" msgstr "10. Supervisor" -#: ../../installation.rst:326 +#: ../../installation.rst:350 msgid "" "Now we configure `Supervisor `_, which is used to run " "our application's web interface and background jobs used. It's also configured " @@ -716,15 +734,15 @@ msgstr "" "Supervisor ervoor dat deze processen bij het (opnieuw) opstarten automatisch " "draaien." -#: ../../installation.rst:329 +#: ../../installation.rst:353 msgid "Copy the configuration file for Supervisor::" msgstr "Kopieer het configuratie-bestand voor Supervisor::" -#: ../../installation.rst:333 +#: ../../installation.rst:357 msgid "Login to ``supervisorctl`` management console::" msgstr "Wissel naar de ``supervisorctl`` beheerconsole::" -#: ../../installation.rst:337 +#: ../../installation.rst:361 msgid "" "Enter these commands (**listed after the** ``>``). It will ask Supervisor to " "recheck its config directory and use/reload the files::" @@ -732,7 +750,7 @@ msgstr "" "Voer de volgende commando's in (**degene na de** ``>``). Dit zorgt ervoor dat " "Supervisor zijn eigen configuratie opnieuw controleert en toepast::" -#: ../../installation.rst:343 +#: ../../installation.rst:367 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 " @@ -742,15 +760,15 @@ msgstr "" "uiteindelijk niet in ``ERROR`` of ``BACKOFF`` status terecht zijn gekomen. Je " "kunt het overzicht verversen door ``status`` te typen." -#: ../../installation.rst:345 +#: ../../installation.rst:369 msgid "When still in ``supervisorctl``'s console, type::" msgstr "Typ het volgende wanneer je nog in ``supervisorctl``'s console bent::" -#: ../../installation.rst:349 +#: ../../installation.rst:373 msgid "Example of everything running well::" msgstr "Voorbeeld van wanneer alles naar behoren draait::" -#: ../../installation.rst:355 +#: ../../installation.rst:379 msgid "" "Want to check whether the datalogger works? Just tail it's log in supervisor " "with::" @@ -758,7 +776,7 @@ msgstr "" "Wil je controleren of de datalogger zijn werk goed doet? Bekijk dan het " "logbestand in supervisor met::" -#: ../../installation.rst:359 +#: ../../installation.rst:383 msgid "" "You should see similar output as the ``cu``-command printed earlier in the " "installation process." @@ -766,7 +784,7 @@ msgstr "" "Uiteindelijk zou je ongeveer dezelfde lap tekst moeten zien als toen we " "handmatig gemeten hebben met het ``cu``-programma." -#: ../../installation.rst:361 +#: ../../installation.rst:385 msgid "" "Want to quit supervisor? ``CTRL + C`` to stop tailing and then ``CTRL + D`` " "once to exit supervisor command line." @@ -774,7 +792,7 @@ 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." -#: ../../installation.rst:364 +#: ../../installation.rst:388 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." diff --git a/dsmr_api/views.py b/dsmr_api/views.py index d8bac3332..d1571bc37 100644 --- a/dsmr_api/views.py +++ b/dsmr_api/views.py @@ -1,13 +1,19 @@ +import logging + from django.http.response import HttpResponseNotAllowed, HttpResponseForbidden,\ HttpResponseBadRequest, HttpResponseServerError, HttpResponse from django.views.generic.base import View from django.utils.translation import ugettext as _ +from dsmr_datalogger.exceptions import InvalidTelegramChecksum from dsmr_api.models import APISettings from dsmr_api.forms import DsmrReadingForm import dsmr_datalogger.services +logger = logging.getLogger('dsmrreader') + + class DataloggerDsmrReading(View): def post(self, request): api_settings = APISettings.get_solo() @@ -24,12 +30,16 @@ def post(self, request): # Data omitted. if not post_form.is_valid(): + logger.warning('API validation failed with POST data: {}'.format(request.POST)) return HttpResponseBadRequest(_('Invalid data')) + dsmr_reading = None + try: dsmr_reading = dsmr_datalogger.services.telegram_to_reading(data=post_form.cleaned_data['telegram']) - except: - dsmr_reading = None + except InvalidTelegramChecksum: + # The service called already logs the error. + pass # Data invalid. if not dsmr_reading: diff --git a/dsmr_backend/services.py b/dsmr_backend/services.py index dc8b0ac5c..478f2ca4b 100644 --- a/dsmr_backend/services.py +++ b/dsmr_backend/services.py @@ -3,6 +3,7 @@ import requests from django.conf import settings +from django.utils import timezone from dsmr_consumption.models.consumption import ElectricityConsumption, GasConsumption from dsmr_weather.models.reading import TemperatureReading @@ -49,3 +50,11 @@ def is_latest_version(): remote_version = '.'.join(remote_version.groups()) return StrictVersion(local_version) >= StrictVersion(remote_version) + + +def is_timestamp_passed(timestamp): + """ Generic service to check whether a timestamp has passed/is happening or is empty (None). """ + if timestamp is None: + return True + + return timezone.now() >= timestamp diff --git a/dsmr_backend/tests/test_backend.py b/dsmr_backend/tests/test_backend.py index 811e35031..9ee7099bb 100644 --- a/dsmr_backend/tests/test_backend.py +++ b/dsmr_backend/tests/test_backend.py @@ -77,7 +77,7 @@ def test_timezone(self): def test_version(self): """ Verify version setting. """ - self.assertIsNotNone(settings.DSMR_VERSION) + self.assertIsNotNone(settings.DSMRREADER_VERSION) def test_pending_migrations(self): """ Tests whether there are any model changes, which are not reflected in migrations. """ diff --git a/dsmr_backend/tests/test_services.py b/dsmr_backend/tests/test_services.py index 40a2c67a7..523b72b04 100644 --- a/dsmr_backend/tests/test_services.py +++ b/dsmr_backend/tests/test_services.py @@ -186,3 +186,24 @@ def test_false(self, request_mock): request_mock.return_value = response_mock self.assertFalse(dsmr_backend.services.is_latest_version()) + + +class TestIsLocalTimestampPassed(TestCase): + @mock.patch('django.utils.timezone.now') + def test_true(self, now_mock): + now_mock.return_value = timezone.make_aware(timezone.datetime(2017, 1, 1, hour=13, minute=37)) + + self.assertTrue( + dsmr_backend.services.is_timestamp_passed(timestamp=timezone.now() - timezone.timedelta(minutes=1)) + ) + self.assertTrue( + dsmr_backend.services.is_timestamp_passed(timestamp=timezone.now()) + ) + + def test_false(self): + self.assertFalse( + dsmr_backend.services.is_timestamp_passed(timestamp=timezone.now() + timezone.timedelta(minutes=1)) + ) + + def test_none(self): + self.assertTrue(dsmr_backend.services.is_timestamp_passed(None)) diff --git a/dsmr_datalogger/management/commands/dsmr_datalogger.py b/dsmr_datalogger/management/commands/dsmr_datalogger.py index 75d69a9c5..f86cd8635 100644 --- a/dsmr_datalogger/management/commands/dsmr_datalogger.py +++ b/dsmr_datalogger/management/commands/dsmr_datalogger.py @@ -3,6 +3,7 @@ from dsmr_backend.mixins import InfiniteManagementCommandMixin from dsmr_datalogger.models.settings import DataloggerSettings +from dsmr_datalogger.exceptions import InvalidTelegramChecksum import dsmr_datalogger.services @@ -24,4 +25,8 @@ def run(self, **options): # Reflect output to STDOUT for logging and convenience. self.stdout.write(telegram) - dsmr_datalogger.services.telegram_to_reading(data=telegram) + try: + dsmr_datalogger.services.telegram_to_reading(data=telegram) + except InvalidTelegramChecksum: + # The service called already logs the error. + pass diff --git a/dsmr_datalogger/migrations/0005_verify_telegram_crc_setting.py b/dsmr_datalogger/migrations/0005_verify_telegram_crc_setting.py new file mode 100644 index 000000000..475a013ac --- /dev/null +++ b/dsmr_datalogger/migrations/0005_verify_telegram_crc_setting.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.4 on 2017-01-08 18:29 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dsmr_datalogger', '0004_phase_currently_delivered'), + ] + + operations = [ + migrations.AddField( + model_name='dataloggersettings', + name='verify_telegram_crc', + field=models.BooleanField(default=True, help_text='Whether we should verify the CRC of any telegrams read by / sent to the application.', verbose_name='Verify telegram CRC'), + ), + ] diff --git a/dsmr_datalogger/models/settings.py b/dsmr_datalogger/models/settings.py index 25df842b3..7fd17dbb2 100644 --- a/dsmr_datalogger/models/settings.py +++ b/dsmr_datalogger/models/settings.py @@ -38,6 +38,11 @@ class DataloggerSettings(SingletonModel): 'when actually you have three phases. The dashboard will display any data read, after enabling this.' ) ) + verify_telegram_crc = models.BooleanField( + default=True, + verbose_name=_('Verify telegram CRC'), + help_text=_('Whether we should verify the CRC of any telegrams read by / sent to the application.') + ) dsmr_version = models.IntegerField( default=DSMR_VERSION_4, @@ -45,7 +50,6 @@ class DataloggerSettings(SingletonModel): verbose_name=_('DSMR version'), help_text=_('The DSMR version your meter supports. Version should be printed on meter.') ) - com_port = models.CharField( max_length=196, default='/dev/ttyUSB0', diff --git a/dsmr_datalogger/services.py b/dsmr_datalogger/services.py index ff0a3917a..a91a996e4 100644 --- a/dsmr_datalogger/services.py +++ b/dsmr_datalogger/services.py @@ -1,3 +1,5 @@ +import logging +import base64 import re from serial.serialutil import SerialException @@ -14,6 +16,9 @@ from dsmr_datalogger.dsmr import DSMR_MAPPING +logger = logging.getLogger('dsmrreader') + + def get_dsmr_connection_parameters(): """ Returns the communication settings required for the DSMR version set. """ DSMR_VERSION_MAPPING = { @@ -102,7 +107,10 @@ def verify_telegram_checksum(data): content, crc = matches.groups() except AttributeError: # AttributeError: 'NoneType' object has no attribute 'groups'. This happens where there is not support for CRC. - raise InvalidTelegramChecksum('CRC not found') + content = crc = None + + if not content or not crc: + raise InvalidTelegramChecksum('Content or CRC data not found') telegram = content.encode('ascii') # TypeError: Unicode-objects must be encoded before calculating a CRC @@ -113,8 +121,9 @@ def verify_telegram_checksum(data): calculated_checksum = crc16_function(telegram) # For example: 56708 if telegram_checksum != calculated_checksum: - raise InvalidTelegramChecksum('{} (telegram) != {} (calculated) {}'.format( - telegram_checksum, calculated_checksum, hex(calculated_checksum).upper())) + raise InvalidTelegramChecksum( + 'CRC mismatch: {} (telegram) != {} (calculated)'.format(telegram_checksum, calculated_checksum) + ) def telegram_to_reading(data): # noqa: C901 @@ -158,16 +167,22 @@ def _convert_legacy_dsmr_gas_line(parsed_reading, current_line, next_line): parsed_reading['extra_device_delivered'] = legacy_gas_result.group(2) return parsed_reading - # Discard CRC check when any support is lacking anyway. + # We will log the telegrams in base64 for convenience and debugging 'n stuff. + base64_data = base64.b64encode(data.encode()) + datalogger_settings = DataloggerSettings.get_solo() + + # Discard CRC check when any support is lacking anyway. Or when it's disabled. connection_parameters = get_dsmr_connection_parameters() - if connection_parameters['crc']: + if connection_parameters['crc'] and datalogger_settings.verify_telegram_crc: try: # Verify telegram by checking it's CRC. verify_telegram_checksum(data=data) - except InvalidTelegramChecksum: + except InvalidTelegramChecksum as error: # Hook to keep track of failed readings count. MeterStatistics.objects.all().update(rejected_telegrams=F('rejected_telegrams') + 1) + logger.warning('Rejected telegram (base64 encoded): {}'.format(base64_data)) + logger.exception(error) raise # Defaults all fields to NULL. @@ -219,8 +234,6 @@ def _convert_legacy_dsmr_gas_line(parsed_reading, current_line, next_line): if parsed_reading['timestamp'] is None: parsed_reading['timestamp'] = timezone.now() - datalogger_settings = DataloggerSettings.get_solo() - # Optional tracking of phases, but since we already mapped this above, just remove it again... :] if not datalogger_settings.track_phases: parsed_reading.update({ @@ -238,6 +251,8 @@ def _convert_legacy_dsmr_gas_line(parsed_reading, current_line, next_line): statistics_kwargs = {k: parsed_reading[k] for k in _get_statistics_fields()} # There should already be one in database, created when migrating. MeterStatistics.objects.all().update(**statistics_kwargs) + + logger.info('Received telegram (base64 encoded): {}'.format(base64_data)) return new_reading diff --git a/dsmr_datalogger/tests/datalogger/test_error.py b/dsmr_datalogger/tests/datalogger/test_error.py index 64d9fed8c..e8ccc7036 100644 --- a/dsmr_datalogger/tests/datalogger/test_error.py +++ b/dsmr_datalogger/tests/datalogger/test_error.py @@ -5,6 +5,7 @@ from dsmr_backend.tests.mixins import InterceptStdoutMixin from dsmr_datalogger.models.reading import DsmrReading +from dsmr_datalogger.models.settings import DataloggerSettings class TestDataloggerError(InterceptStdoutMixin, TestCase): @@ -89,3 +90,64 @@ def test_interrupt(self, serial_readline_mock, serial_open_mock): self._intercept_command_stdout('dsmr_datalogger') self.assertFalse(DsmrReading.objects.exists()) + + +class TestDataloggerCrcError(InterceptStdoutMixin, TestCase): + def _dsmr_dummy_data(self): + """ Returns invalid telegram. """ + return [ + "/KFM5KAIFA-METER\r\n", + "\r\n", + "1-3:0.2.8(42)\r\n", + "0-0:1.0.0(160303164347W)\r\n", + "0-0:96.1.1(*******************************)\r\n", + "1-0:1.8.1(001073.079*kWh)\r\n", + "1-0:1.8.2(001263.199*kWh)\r\n", + "1-0:2.8.1(000000.000*kWh)\r\n", + "1-0:2.8.2(000000.000*kWh)\r\n", + "0-0:96.14.0(0002)\r\n", + "1-0:1.7.0(00.143*kW)\r\n", + "1-0:2.7.0(00.000*kW)\r\n", + "0-0:96.7.21(00006)\r\n", + "0-0:96.7.9(00003)\r\n", + "1-0:99.97.0(1)(0-0:96.7.19)(000101000001W)(2147483647*s)\r\n", + "1-0:32.32.0(00000)\r\n", + "1-0:32.36.0(00000)\r\n", + "0-0:96.13.1()\r\n", + "0-0:96.13.0()\r\n", + "1-0:31.7.0(000*A)\r\n", + "1-0:21.7.0(00.143*kW)\r\n", + "1-0:22.7.0(00.000*kW)\r\n", + "!ABCD\n", # <<< Invalid CRC. + ] + + @mock.patch('serial.Serial.open') + @mock.patch('serial.Serial.readline') + def test_fail(self, serial_readline_mock, serial_open_mock): + """ Fake & process an DSMR vX telegram reading. """ + serial_open_mock.return_value = None + serial_readline_mock.side_effect = self._dsmr_dummy_data() + + self.assertFalse(DsmrReading.objects.exists()) + + self._intercept_command_stdout('dsmr_datalogger') + + self.assertFalse(DsmrReading.objects.exists()) + + @mock.patch('serial.Serial.open') + @mock.patch('serial.Serial.readline') + def test_okay(self, serial_readline_mock, serial_open_mock): + """ Fake & process an DSMR vX telegram reading. """ + serial_open_mock.return_value = None + serial_readline_mock.side_effect = self._dsmr_dummy_data() + + # The big difference here is that CRc verification should be off. + datalogger_settings = DataloggerSettings.get_solo() + datalogger_settings.verify_telegram_crc = False + datalogger_settings.save() + + self.assertFalse(DsmrReading.objects.exists()) + + self._intercept_command_stdout('dsmr_datalogger') + + self.assertTrue(DsmrReading.objects.exists()) diff --git a/dsmr_datalogger/tests/models/test_settings.py b/dsmr_datalogger/tests/models/test_settings.py index aa033703e..14672da25 100644 --- a/dsmr_datalogger/tests/models/test_settings.py +++ b/dsmr_datalogger/tests/models/test_settings.py @@ -25,6 +25,9 @@ def test_track_meter_statistics(self): def test_track_phases(self): self.assertFalse(self.instance.track_phases) + def test_verify_telegram_crc(self): + self.assertTrue(self.instance.verify_telegram_crc) + def test_dsmr_version(self): self.assertEqual(self.instance.dsmr_version, DataloggerSettings.DSMR_VERSION_4) diff --git a/dsmr_frontend/context_processors/__init__.py b/dsmr_frontend/context_processors/__init__.py index 6d223dd1f..66fe50187 100644 --- a/dsmr_frontend/context_processors/__init__.py +++ b/dsmr_frontend/context_processors/__init__.py @@ -3,6 +3,6 @@ def version(request): return { - 'dsmr_version': settings.DSMR_VERSION, + 'dsmr_version': settings.DSMRREADER_VERSION, 'LANGUAGE_CODE': request.LANGUAGE_CODE, } diff --git a/dsmr_frontend/templates/dsmr_frontend/dashboard.html b/dsmr_frontend/templates/dsmr_frontend/dashboard.html index 8058e14ff..5ce2b45a2 100644 --- a/dsmr_frontend/templates/dsmr_frontend/dashboard.html +++ b/dsmr_frontend/templates/dsmr_frontend/dashboard.html @@ -365,6 +365,7 @@ /* Auto refresh. */ update_header(); setInterval(function(){ update_header(); }, 2500); + setInterval(function(){ update_graphs(); }, 5000); initialize_graphs(); }); diff --git a/dsmr_mindergas/migrations/0003_mindergas_next_export_datetime.py b/dsmr_mindergas/migrations/0003_mindergas_next_export_datetime.py new file mode 100644 index 000000000..0a5b6a2de --- /dev/null +++ b/dsmr_mindergas/migrations/0003_mindergas_next_export_datetime.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.4 on 2017-01-04 19:41 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dsmr_mindergas', '0002_mindergas_notification'), + ] + + operations = [ + migrations.AlterField( + model_name='mindergassettings', + name='next_export', + field=models.DateTimeField(blank=True, default=None, help_text='Timestamp of the next export. Automatically updated by application.', null=True, verbose_name='Next export'), + ), + ] diff --git a/dsmr_mindergas/models/settings.py b/dsmr_mindergas/models/settings.py index f9cd63882..5ad0064f5 100644 --- a/dsmr_mindergas/models/settings.py +++ b/dsmr_mindergas/models/settings.py @@ -25,7 +25,7 @@ class MinderGasSettings(SingletonModel): 'More information can be found here: https://www.mindergas.nl/member/api' ) ) - next_export = models.DateField( + next_export = models.DateTimeField( default=None, null=True, blank=True, diff --git a/dsmr_mindergas/services.py b/dsmr_mindergas/services.py index a30b12e5b..507a9e50b 100644 --- a/dsmr_mindergas/services.py +++ b/dsmr_mindergas/services.py @@ -1,3 +1,4 @@ +import random import json from django.utils import timezone @@ -22,10 +23,7 @@ def should_export(): if not capabilities['gas']: return False - if settings.next_export is not None and timezone.localtime(timezone.now()).date() < settings.next_export: - return False - - return True + return dsmr_backend.services.is_timestamp_passed(timestamp=settings.next_export) def export(): @@ -34,7 +32,7 @@ def export(): return # For backend logging in Supervisor. - print(' - Exporting gas meter position to MinderGas.') + print(' - Attempting to export gas meter position to MinderGas.') # Just post the latest reading of the day before. today = timezone.localtime(timezone.now()) @@ -53,9 +51,10 @@ def export(): except IndexError: # Just continue, even though we have no data... yet. last_gas_reading = None - - if last_gas_reading: + print(' - No gas readings found to export to MinderGas') + else: settings = MinderGasSettings.get_solo() + print(' - Exporting gas meter position to MinderGas:', last_gas_reading.delivered) # Register telegram by simply sending it to the application with a POST request. response = requests.post( @@ -70,8 +69,10 @@ def export(): if response.status_code != 201: raise AssertionError('MinderGas upload failed: %s (HTTP %s)'.format(response.text, response.status_code)) - # Push back for a day. - tomorrow = (today + timezone.timedelta(hours=24)).date() + # Push back for a day and a bit. + next_export = midnight + timezone.timedelta(hours=24, minutes=random.randint(15, 59)) + print(' - Delaying the next export to MinderGas until:', next_export) + settings = MinderGasSettings.get_solo() - settings.next_export = tomorrow + settings.next_export = next_export settings.save() diff --git a/dsmr_mindergas/tests/test_services.py b/dsmr_mindergas/tests/test_services.py index 602d39b5d..76b42fe0e 100644 --- a/dsmr_mindergas/tests/test_services.py +++ b/dsmr_mindergas/tests/test_services.py @@ -44,7 +44,7 @@ def test_should_export_no_gas(self, now_mock): 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(2015, 12, 12, hour=0, minute=5)) - tomorrow = (timezone.localtime(timezone.now()) + timezone.timedelta(hours=24)).date() + tomorrow = timezone.localtime(timezone.now()) + timezone.timedelta(hours=24) settings = MinderGasSettings.get_solo() settings.export = True @@ -102,6 +102,29 @@ def test_export_no_gas(self, now_mock, should_export_mock): dsmr_mindergas.services.export() self.assertIsNone(settings.next_export) + @mock.patch('requests.post') + @mock.patch('dsmr_mindergas.services.should_export') + @mock.patch('django.utils.timezone.now') + def test_export_random_schedule(self, now_mock, should_export_mock, requests_post_mock): + """ Test export() setting the next export randomly. """ + now_mock.return_value = timezone.make_aware(timezone.datetime(2015, 12, 12, hour=0, minute=5)) + should_export_mock.return_value = True + requests_post_mock.return_value = mock.MagicMock(status_code=201, text='Fake accept') + + # We should at least have two different values (out of 10 attempts) + random_values = [] + + for _ in range(0, 10): + dsmr_mindergas.services.export() + + settings = MinderGasSettings.get_solo() + self.assertIsNotNone(settings.next_export) + random_values.append(settings.next_export) + + # Make unique and count them. + random_values = list(set(random_values)) + self.assertGreater(len(random_values), 2) + @mock.patch('requests.post') @mock.patch('dsmr_mindergas.services.should_export') @mock.patch('django.utils.timezone.now') diff --git a/dsmrreader/__init__.py b/dsmrreader/__init__.py index 8fb36d385..43d7dc489 100644 --- a/dsmrreader/__init__.py +++ b/dsmrreader/__init__.py @@ -17,6 +17,6 @@ from django.utils.version import get_version -VERSION = (1, 5, 1, 'final', 0) +VERSION = (1, 5, 2, 'final', 0) __version__ = get_version(VERSION) diff --git a/dsmrreader/config/base.py b/dsmrreader/config/base.py index f9fc6716a..c0101f4cf 100644 --- a/dsmrreader/config/base.py +++ b/dsmrreader/config/base.py @@ -163,6 +163,6 @@ DSMR_MANAGEMENT_COMMANDS_PID_FOLDER = '/var/tmp/' -DSMR_VERSION = dsmrreader.__version__ +DSMRREADER_VERSION = dsmrreader.__version__ DSMR_RAW_VERSION = dsmrreader.VERSION DSMR_LATEST_VERSION_FILE = 'https://raw.githubusercontent.com/dennissiemensma/dsmr-reader/master/dsmrreader/__init__.py' diff --git a/dsmrreader/config/production.py b/dsmrreader/config/production.py index 2d1f23da6..43bae52bc 100644 --- a/dsmrreader/config/production.py +++ b/dsmrreader/config/production.py @@ -3,7 +3,7 @@ However, since this project is localhost only, I do not care ;-) """ -from dsmrreader.config.development import * +from dsmrreader.config.base import * DEBUG = False @@ -14,3 +14,42 @@ STATIC_ROOT = '/var/www/dsmrreader/static' CACHES['default']['TIMEOUT'] = 1 * 60 + + +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'formatters': { + 'verbose': { + 'format': '[%(asctime)s] %(levelname)s @ %(module)s | %(message)s' + }, + }, + 'handlers': { + 'django_file': { + 'class': 'logging.handlers.RotatingFileHandler', + 'filename': os.path.join(BASE_DIR, '..', 'logs', 'django.log'), + 'formatter': 'verbose', + 'maxBytes': 5 * 1024 * 1024, # 5 MB max. + 'backupCount': 7, + }, + 'dsmrreader_file': { + 'class': 'logging.handlers.RotatingFileHandler', + 'filename': os.path.join(BASE_DIR, '..', 'logs', 'dsmrreader.log'), + 'formatter': 'verbose', + 'maxBytes': 5 * 1024 * 1024, # 5 MB max. + 'backupCount': 7, + }, + }, + 'loggers': { + 'django': { + 'handlers': ['django_file'], + 'level': 'WARNING', + 'propagate': True, + }, + 'dsmrreader': { + 'handlers': ['dsmrreader_file'], + 'level': 'INFO', + 'propagate': True, + }, + }, +} diff --git a/dsmrreader/config/test.py b/dsmrreader/config/test/base.py similarity index 100% rename from dsmrreader/config/test.py rename to dsmrreader/config/test/base.py diff --git a/dsmrreader/config/test_mysql.py b/dsmrreader/config/test/mysql.py similarity index 90% rename from dsmrreader/config/test_mysql.py rename to dsmrreader/config/test/mysql.py index 7b81016f6..d480f0c91 100644 --- a/dsmrreader/config/test_mysql.py +++ b/dsmrreader/config/test/mysql.py @@ -1,5 +1,5 @@ """ Tests with MySQL backend. """ -from dsmrreader.config.test import * +from dsmrreader.config.test.base import * # Use for TESTING only: diff --git a/dsmrreader/config/test_postgresql.py b/dsmrreader/config/test/postgresql.py similarity index 90% rename from dsmrreader/config/test_postgresql.py rename to dsmrreader/config/test/postgresql.py index 6b7201d4c..05560d2ad 100644 --- a/dsmrreader/config/test_postgresql.py +++ b/dsmrreader/config/test/postgresql.py @@ -1,5 +1,5 @@ """ Tests with PostgreSQL backend. """ -from dsmrreader.config.test import * +from dsmrreader.config.test.base import * # Use for TESTING only: ALTER USER dsmrreader CREATEDB; diff --git a/dsmrreader/config/test_sqlite.py b/dsmrreader/config/test/sqlite.py similarity index 89% rename from dsmrreader/config/test_sqlite.py rename to dsmrreader/config/test/sqlite.py index c6f53cba3..3edcc626f 100644 --- a/dsmrreader/config/test_sqlite.py +++ b/dsmrreader/config/test/sqlite.py @@ -1,5 +1,5 @@ """ Tests with PostgreSQL backend. """ -from dsmrreader.config.test import * +from dsmrreader.config.test.base import * # Use for TESTING only: ALTER USER dsmrreader CREATEDB; diff --git a/dsmrreader/config/travis/mysql.py b/dsmrreader/config/travis/mysql.py index 6c022d510..57118ef55 100644 --- a/dsmrreader/config/travis/mysql.py +++ b/dsmrreader/config/travis/mysql.py @@ -1,4 +1,4 @@ -from dsmrreader.config.test_mysql import * +from dsmrreader.config.test.mysql import * # https://docs.travis-ci.com/user/database-setup/#MySQL diff --git a/dsmrreader/config/travis/postgresql.py b/dsmrreader/config/travis/postgresql.py index af6b50d64..594ab8596 100644 --- a/dsmrreader/config/travis/postgresql.py +++ b/dsmrreader/config/travis/postgresql.py @@ -1,4 +1,4 @@ -from dsmrreader.config.test_postgresql import * +from dsmrreader.config.test.postgresql import * # https://docs.travis-ci.com/user/database-setup/#PostgreSQL diff --git a/dsmrreader/config/travis/sqlite.py b/dsmrreader/config/travis/sqlite.py index 4f2c401fe..920cdcecf 100644 --- a/dsmrreader/config/travis/sqlite.py +++ b/dsmrreader/config/travis/sqlite.py @@ -1 +1 @@ -from dsmrreader.config.test_sqlite import * +from dsmrreader.config.test.sqlite import * diff --git a/dsmrreader/locales/nl/LC_MESSAGES/django.mo b/dsmrreader/locales/nl/LC_MESSAGES/django.mo index 9ec8eda86..ca58ec853 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 7afb5b4bb..f9141eb0d 100644 --- a/dsmrreader/locales/nl/LC_MESSAGES/django.po +++ b/dsmrreader/locales/nl/LC_MESSAGES/django.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: DSMR Reader v1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-01-01 15:13+0100\n" -"PO-Revision-Date: 2017-01-01 00:00+0100\n" +"POT-Creation-Date: 2017-01-09 21:05+0100\n" +"PO-Revision-Date: 2017-01-08 20:19+0100\n" "Last-Translator: Dennis Siemensma \n" "Language-Team: Dennis Siemensma \n" "Language: nl\n" @@ -291,6 +291,12 @@ msgstr "Houd elektriciteitsfasen bij" msgid "Whether we should track your phases (if any) as well. By default you only have one phase, but some meters have three due to solar panels or an electric stove. This feature is only useful (and will only work) when actually you have three phases. The dashboard will display any data read, after enabling this." msgstr "Geeft aan of we de elektriciteitsfasen moeten bijhouden (wanneer aanwezig). Standaard heeft iedereen één fase thuis, maar sommige slimme meters zijn aangesloten op drie fasen. Bijvoorbeeld voor zonnepanelen of elektrisch koken. Deze feature is alleen nuttig (en werkt tevens alleen) wanneer er daadwerkelijk drie fasen aanwezig zijn. Het dashboard toont deze gegevens wanneer dit ingeschakeld is." +msgid "Verify telegram CRC" +msgstr "Controleer de CRC van telegrammen" + +msgid "Whether we should verify the CRC of any telegrams read by / sent to the application." +msgstr "Geeft aan of we de CRC (checksum) van binnenkomende telegrammen moeten controleren." + msgid "DSMR version" msgstr "DSMR-versie" diff --git a/dsmrreader/provisioning/django/mysql.py b/dsmrreader/provisioning/django/mysql.py index b991dbf04..290a510bb 100644 --- a/dsmrreader/provisioning/django/mysql.py +++ b/dsmrreader/provisioning/django/mysql.py @@ -8,7 +8,7 @@ 'USER': 'dsmrreader', 'PASSWORD': 'dsmrreader', 'HOST': 'localhost', - 'CONN_MAX_AGE': 300, + 'CONN_MAX_AGE': 60, } } diff --git a/dsmrreader/provisioning/django/postgresql.py b/dsmrreader/provisioning/django/postgresql.py index a3c39ff7c..3b11809ee 100644 --- a/dsmrreader/provisioning/django/postgresql.py +++ b/dsmrreader/provisioning/django/postgresql.py @@ -8,7 +8,7 @@ 'USER': 'dsmrreader', 'PASSWORD': 'dsmrreader', 'HOST': 'localhost', - 'CONN_MAX_AGE': 300, + 'CONN_MAX_AGE': 60, } } diff --git a/logs/.dummy b/logs/.dummy new file mode 100644 index 000000000..65b57007a --- /dev/null +++ b/logs/.dummy @@ -0,0 +1 @@ +#VCS \ No newline at end of file diff --git a/quick-test.sh b/quick-test.sh index 741409791..800ea8ea3 100755 --- a/quick-test.sh +++ b/quick-test.sh @@ -15,4 +15,4 @@ 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 diff --git a/test-all.sh b/test-all.sh index a4fdff028..9b77ca875 100755 --- a/test-all.sh +++ b/test-all.sh @@ -14,14 +14,14 @@ echo "OK" echo "" echo "--- Testing with SQLite (4 processes)..." -pytest --pylama --cov --cov-report=html:coverage_report/html --cov-report=term --ds=dsmrreader.config.test_sqlite -n 4 +pytest --pylama --cov --cov-report=html:coverage_report/html --cov-report=term --ds=dsmrreader.config.test.sqlite -n 4 echo "" echo "--- Testing with PostgreSQL (4 processes)..." -pytest --pylama --cov --cov-report=html:coverage_report/html --cov-report=term --ds=dsmrreader.config.test_postgresql -n 4 +pytest --pylama --cov --cov-report=html:coverage_report/html --cov-report=term --ds=dsmrreader.config.test.postgresql -n 4 echo "" echo "--- Testing with MySQL (1 proces due to concurrency limitations)..." -pytest --pylama --cov --cov-report=html:coverage_report/html --cov-report=term --ds=dsmrreader.config.test_mysql +pytest --pylama --cov --cov-report=html:coverage_report/html --cov-report=term --ds=dsmrreader.config.test.mysql