diff --git a/CHANGELOG.md b/CHANGELOG.md index ad1407129..2a4d98f11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,43 @@ Changelog ========= +3.2.0 (2017-11-24) +------------------ + +**New** +- Add TOC. [TheYOSH] +- Add config upgrade. [TheYOSH] +- Add files via upload. [TheYOSH] +- Add remote switches support. For now READONLY [#51](https://github.com/theyosh/TerrariumPI/issues/51). [TheYOSH] +- Add support for remote (HTTP/HTTPS) temperature and humidity sensors + through JSON REST API. [#51](https://github.com/theyosh/TerrariumPI/issues/51). [TheYOSH] +- Add static url parser. [TheYOSH] +- Add CORS headers for Ajax REST calls. [TheYOSH] + +**Fixes** +- Fix for remote data timeouts. [TheYOSH] +- Fix remote dimmer data collectin. [TheYOSH] +- Fix remote dimmer state updates. [TheYOSH] + +**Updates** +- Update README.md. [TheYOSH] +- Update README.md. [TheYOSH] +- Update language files. [TheYOSH] +- Update dashboard. Hide not enabled environment parts. [TheYOSH] +- Small player updates. [TheYOSH] +- Update soundcard code to support random soundcard order (2) [TheYOSH] +- Update soundcard code to support random soundcard order. [TheYOSH] +- Update readme. [TheYOSH] +- Update version number. [TheYOSH] + +**Other** +- Better load indicator. (2) [TheYOSH] +- Better load indicator. [TheYOSH] +- Merge branch 'master' into feature/remote_data. [TheYOSH] +- Merge branch 'master' into feature/remote_data. [TheYOSH] +- Code cleanup and add connection timeouts. [TheYOSH] + + 3.1.1 (2017-11-20) ------------------ @@ -10,6 +47,7 @@ Changelog - Add Apple icon. [TheYOSH] **Updates** +- Update changelog. [TheYOSH] - Updated top indicators. Hide disabled indicators on small screens. [TheYOSH] diff --git a/README.md b/README.md index 053b5523a..8156104ec 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# TerrariumPI 3.1.0 +# TerrariumPI 3.2.0 Software for cheap home automation of your reptile terrarium or any other enclosed environment. With this software you are able to control for example a terrarium so that the temperature and humidity is of a constant value. Controlling the temperature can be done with heat lights, external heating or cooling system. As long as there is one temperature sensor available the software is able to keep a constant temperature. For humidity control there is support for a spraying system. The sprayer can be configured to spray for an X amount of seconds and there is a minumal period between two spray actions. Use at least one humitidy sensors to get a constant humidity value. @@ -12,6 +12,19 @@ Think off: - Growhouse And all this is controlled with a nice webinterface based on [Gentelella a Bootstrap 3 template](https://github.com/puikinsh/gentelella/). + +## Table of Contents +1. [Features](#features) +2. [Translations](#translations) +3. [Installation](#installation) +4. [Updating](#updating) +5. [Hardware](#hardware) + 1. [GPIO numbering](#gpio-numbering) + 2. [New hardware](#new-hardware) +6. [Remote data](#remote-data) +7. [Screenshots](#screenshots) +8. [About](#about) + ## Features - Controlling electronic devices like lights, sprayers, heating and cooling equipment - Support for dimming electronic devices @@ -35,6 +48,7 @@ And all this is controlled with a nice webinterface based on [Gentelella a Boots - Volume controle in the webinterface - Uploadig audio files through webinterface - Audio meta data support +- Remote temperature and humidity sensors through HTTP(S) JSON API's. JSON Data format can be found on [Remote data wiki](https://github.com/theyosh/TerrariumPI/wiki/Remote-data). It is currently controling my reptile terrarium for more then three years! And my Madagascar Day Gecko is very happy with it! @@ -92,9 +106,20 @@ This software requires a Raspberry Pi and some extra hardware in order to run an - OWFS - GPIO - 1 Wire interface + +### GPIO numbering +All hardware that connects to the GPIO pins use Physical GPIO numbering (1 - 40). The software will translate it to BCM if needed for a supported device or sensor. [More information about GPIO pin numbering](https://pinout.xyz/) +### New hardware If there is some other hardware which is not working with TerrariumPI, open an issue on [Github](https://github.com/theyosh/TerrariumPI/issues) and we will try to support it. Raspberry Pi Zero is not tested. +## Remote data +It is possible to use external sensor data that is available through HTTP(S) in JSON format. This way you can combine multiple Raspberry Pi's with TerrariumPI running to one single system. By using multiple Rapsberry PI's you can cover a bigger area. But there are limitations. + +Currently it is READONLY. So you can read out remote sensors and switches but you cannot control the remote switches. But this way you can combine the power swiches total costs and power usage. + +more information is here: [Remote data wiki](https://github.com/theyosh/TerrariumPI/wiki/Remote-data) + ## Screenshots (made on a very big screen :P ) ### Dashboard diff --git a/defaults.cfg b/defaults.cfg index 47c409cef..8d76a6248 100644 --- a/defaults.cfg +++ b/defaults.cfg @@ -1,7 +1,7 @@ [terrariumpi] host = :: port = 8090 -version = 3.1.1 +version = 3.2.0 title = TerrariumPI %(version)s power_usage = 5 owfs_port = 4304 @@ -11,7 +11,7 @@ language = en_US temperature_indicator = C power_price = 0 water_price = 0 -soundcard = 0 +soundcard = bcm2835 ALSA [weather] location = http://www.yr.no/place/Netherlands/Groningen/Groningen diff --git a/install.sh b/install.sh index da350985b..e28c74c2a 100755 --- a/install.sh +++ b/install.sh @@ -15,7 +15,7 @@ apt-get -y autoremove # Install required packages to get the terrarium software running aptitude -y update aptitude -y safe-upgrade -aptitude -y install libftdi1 screen python-imaging python-dateutil python-ow python-rpi.gpio python-psutil git subversion watchdog build-essential python-dev python-picamera python-opencv python-pip python-pigpio i2c-tools owfs ow-shell sqlite3 vlc-nox python-mediainfodll libasound2-dev +aptitude -y install libftdi1 screen python-imaging python-dateutil python-ow python-rpi.gpio python-psutil git subversion watchdog build-essential python-dev python-picamera python-opencv python-pip python-pigpio python-requests i2c-tools owfs ow-shell sqlite3 vlc-nox python-mediainfodll libasound2-dev # Basic config: raspi-config diff --git a/locales/en_US/LC_MESSAGES/terrariumpi.mo b/locales/en_US/LC_MESSAGES/terrariumpi.mo index 170c629bc..f92dce29a 100644 Binary files a/locales/en_US/LC_MESSAGES/terrariumpi.mo and b/locales/en_US/LC_MESSAGES/terrariumpi.mo differ diff --git a/locales/en_US/LC_MESSAGES/terrariumpi.po b/locales/en_US/LC_MESSAGES/terrariumpi.po index 985aaa93d..f300674cd 100644 --- a/locales/en_US/LC_MESSAGES/terrariumpi.po +++ b/locales/en_US/LC_MESSAGES/terrariumpi.po @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: TerrariumPI 0.1\n" -"POT-Creation-Date: 2017-11-12 18:09+CET\n" -"PO-Revision-Date: 2017-11-12 18:09+0100\n" +"POT-Creation-Date: 2017-11-24 12:57+CET\n" +"PO-Revision-Date: 2017-11-24 12:57+0100\n" "Last-Translator: Joshua (TheYOSH) Rubingh \n" "Language-Team: \n" "Language: en_US\n" @@ -29,8 +29,12 @@ msgid "Holds the sensor hardware type. Supported hardware types are: %s." msgstr "Holds the sensor hardware type. Supported hardware types are: %s." #: terrariumTranslations.py:27 -msgid "Holds the sensor address. Depending on hardware type, it is either a read only hex number or GPIO pin. For GPIO use physical GPIO pin numbering." -msgstr "Holds the sensor address. Depending on hardware type, it is either a read only hex number or GPIO pin. For GPIO use physical GPIO pin numbering." +msgid "Holds the sensor address. Depending on hardware type, it is either a read only hex number, a GPIO pin or a full HTTP(S) adress. Full url specification can be found on the %s wiki page. For GPIO use physical GPIO pin numbering." +msgstr "Holds the sensor address. Depending on hardware type, it is either a read only hex number, a GPIO pin or a full HTTP(S) adress. Full url specification can be found on the %s wiki page. For GPIO use physical GPIO pin numbering." + +#: terrariumTranslations.py:27 +msgid "Remote data" +msgstr "Remote data" #: terrariumTranslations.py:28 msgid "Holds the sensor type. Supported sensor types are: %s." @@ -443,11 +447,11 @@ msgstr "Data saved" msgid "Your changes are saved" msgstr "Your changes are saved" -#: terrariumWebserver.py:319 views/inc/menu.tpl:146 +#: terrariumWebserver.py:320 views/inc/menu.tpl:146 msgid "Log out" msgstr "Log out" -#: terrariumWebserver.py:320 +#: terrariumWebserver.py:321 msgid "You are now logged out" msgstr "You are now logged out" @@ -510,8 +514,8 @@ msgstr "Duration" #: views/inc/usage_sensors.tpl:171 views/inc/usage_switches.tpl:117 #: views/inc/usage_switches.tpl:140 views/inc/usage_webcams.tpl:104 #: views/inc/usage_webcams.tpl:134 views/profile.tpl:56 -#: views/sensor_settings.tpl:28 views/sensor_settings.tpl:113 -#: views/switch_settings.tpl:25 views/switch_settings.tpl:95 +#: views/sensor_settings.tpl:28 views/sensor_settings.tpl:114 +#: views/switch_settings.tpl:25 views/switch_settings.tpl:97 #: views/webcam_settings.tpl:27 views/webcam_settings.tpl:86 msgid "Name" msgstr "Name" @@ -523,7 +527,7 @@ msgstr "Album" #: views/audio_files.tpl:68 views/inc/usage_dashboard.tpl:153 #: views/inc/usage_sensors.tpl:125 views/inc/usage_sensors.tpl:168 #: views/profile.tpl:63 views/sensor_settings.tpl:25 -#: views/sensor_settings.tpl:104 +#: views/sensor_settings.tpl:105 msgid "Type" msgstr "Type" @@ -539,7 +543,7 @@ msgstr "Channels" msgid "Frequency" msgstr "Frequency" -#: views/audio_files.tpl:85 +#: views/audio_files.tpl:86 msgid "Preview player" msgstr "Preview player" @@ -612,13 +616,13 @@ msgstr "new" #: views/audio_playlist.tpl:122 views/door_settings.tpl:93 #: views/inc/usage_doors.tpl:70 views/inc/usage_sensors.tpl:80 #: views/inc/usage_switches.tpl:70 views/inc/usage_webcams.tpl:66 -#: views/sensor_settings.tpl:142 views/switch_settings.tpl:135 +#: views/sensor_settings.tpl:143 views/switch_settings.tpl:137 #: views/webcam_settings.tpl:108 msgid "Close" msgstr "Close" #: views/audio_playlist.tpl:123 views/door_settings.tpl:94 -#: views/sensor_settings.tpl:143 views/switch_settings.tpl:136 +#: views/sensor_settings.tpl:144 views/switch_settings.tpl:138 #: views/webcam_settings.tpl:109 msgid "Add" msgstr "Add" @@ -630,13 +634,13 @@ msgstr "Uptime" #: views/dashboard.tpl:24 views/inc/usage_dashboard.tpl:93 #: views/inc/usage_switches.tpl:121 views/inc/usage_switches.tpl:143 -#: views/switch_settings.tpl:28 views/switch_settings.tpl:99 +#: views/switch_settings.tpl:28 views/switch_settings.tpl:101 msgid "Power usage in Watt" msgstr "Power usage in Watt" #: views/dashboard.tpl:35 views/inc/usage_dashboard.tpl:99 #: views/inc/usage_switches.tpl:125 views/inc/usage_switches.tpl:146 -#: views/switch_settings.tpl:31 views/switch_settings.tpl:103 +#: views/switch_settings.tpl:31 views/switch_settings.tpl:105 msgid "Water flow in L/m" msgstr "Water flow in L/m" @@ -659,7 +663,7 @@ msgstr "Total water in L" #: views/inc/usage_sensors.tpl:154 views/inc/usage_sensors.tpl:186 #: views/inc/usage_sensors.tpl:203 views/inc/usage_weather.tpl:13 #: views/inc/usage_weather.tpl:85 views/sensor_settings.tpl:43 -#: views/sensor_settings.tpl:133 views/weather_forecast.tpl:7 +#: views/sensor_settings.tpl:134 views/weather_forecast.tpl:7 msgid "Current" msgstr "Current" @@ -695,7 +699,7 @@ msgid "mode" msgstr "mode" #: views/dashboard.tpl:83 views/dashboard.tpl:112 views/dashboard.tpl:135 -#: views/dashboard.tpl:164 views/inc/menu.tpl:203 +#: views/dashboard.tpl:164 views/inc/menu.tpl:180 views/inc/menu.tpl:206 #: views/inc/usage_environment.tpl:24 views/inc/usage_environment.tpl:120 #: views/inc/usage_environment.tpl:128 views/inc/usage_environment.tpl:212 #: views/inc/usage_environment.tpl:220 views/inc/usage_environment.tpl:306 @@ -742,7 +746,7 @@ msgstr "Sprayer" #: views/dashboard.tpl:128 views/dashboard.tpl:151 views/dashboard.tpl:186 #: views/inc/usage_sensors.tpl:138 views/inc/usage_sensors.tpl:174 -#: views/sensor_settings.tpl:31 views/sensor_settings.tpl:117 +#: views/sensor_settings.tpl:31 views/sensor_settings.tpl:118 msgid "Alarm min" msgstr "Alarm min" @@ -754,7 +758,7 @@ msgstr "Heater" #: views/dashboard.tpl:157 views/dashboard.tpl:180 #: views/inc/usage_sensors.tpl:142 views/inc/usage_sensors.tpl:177 -#: views/sensor_settings.tpl:34 views/sensor_settings.tpl:121 +#: views/sensor_settings.tpl:34 views/sensor_settings.tpl:122 msgid "Alarm max" msgstr "Alarm max" @@ -837,8 +841,8 @@ msgstr "Hardware" #: views/inc/usage_doors.tpl:106 views/inc/usage_doors.tpl:122 #: views/inc/usage_sensors.tpl:120 views/inc/usage_sensors.tpl:165 #: views/inc/usage_switches.tpl:112 views/inc/usage_switches.tpl:137 -#: views/sensor_settings.tpl:22 views/sensor_settings.tpl:99 -#: views/switch_settings.tpl:22 views/switch_settings.tpl:90 +#: views/sensor_settings.tpl:22 views/sensor_settings.tpl:100 +#: views/switch_settings.tpl:22 views/switch_settings.tpl:92 msgid "Address" msgstr "Address" @@ -1060,12 +1064,12 @@ msgid "Forecast" msgstr "Forecast" #: views/inc/menu.tpl:46 views/inc/usage_dashboard.tpl:159 -#: views/inc/usage_sensors.tpl:128 views/sensor_settings.tpl:107 +#: views/inc/usage_sensors.tpl:128 views/sensor_settings.tpl:108 msgid "Temperature" msgstr "Temperature" #: views/inc/menu.tpl:49 views/inc/usage_dashboard.tpl:158 -#: views/inc/usage_sensors.tpl:129 views/sensor_settings.tpl:108 +#: views/inc/usage_sensors.tpl:129 views/sensor_settings.tpl:109 msgid "Humidity" msgstr "Humidity" @@ -1105,33 +1109,33 @@ msgstr "Lock" msgid "date/time" msgstr "date/time" -#: views/inc/menu.tpl:163 views/inc/usage_dashboard.tpl:43 +#: views/inc/menu.tpl:163 views/inc/usage_dashboard.tpl:19 +msgid "Online" +msgstr "Online" + +#: views/inc/menu.tpl:166 views/inc/usage_dashboard.tpl:26 +msgid "Offline" +msgstr "Offline" + +#: views/inc/menu.tpl:172 views/inc/menu.tpl:192 views/inc/menu.tpl:212 +msgid "No messages" +msgstr "No messages" + +#: views/inc/menu.tpl:183 views/inc/usage_dashboard.tpl:43 #: views/inc/usage_doors.tpl:82 msgid "Door is closed" msgstr "Door is closed" -#: views/inc/menu.tpl:166 views/inc/usage_dashboard.tpl:50 +#: views/inc/menu.tpl:186 views/inc/usage_dashboard.tpl:50 #: views/inc/usage_doors.tpl:81 msgid "Door is open" msgstr "Door is open" -#: views/inc/menu.tpl:172 views/inc/menu.tpl:189 views/inc/menu.tpl:209 -msgid "No messages" -msgstr "No messages" - -#: views/inc/menu.tpl:180 views/inc/usage_dashboard.tpl:19 -msgid "Online" -msgstr "Online" - -#: views/inc/menu.tpl:183 views/inc/usage_dashboard.tpl:26 -msgid "Offline" -msgstr "Offline" - -#: views/inc/menu.tpl:197 +#: views/inc/menu.tpl:200 msgid "Playing" msgstr "Playing" -#: views/inc/menu.tpl:200 +#: views/inc/menu.tpl:203 msgid "Stopped" msgstr "Stopped" @@ -1597,12 +1601,12 @@ msgid "The history graph will shows the measured value. The flat lines are the m msgstr "The history graph will shows the measured value. The flat lines are the minimum and maximum values that are configured. When the measured value is outside this range an alarm will be given. Hover above the graph lines to get detailed information." #: views/inc/usage_sensors.tpl:146 views/inc/usage_sensors.tpl:180 -#: views/sensor_settings.tpl:37 views/sensor_settings.tpl:125 +#: views/sensor_settings.tpl:37 views/sensor_settings.tpl:126 msgid "Limit min" msgstr "Limit min" #: views/inc/usage_sensors.tpl:150 views/inc/usage_sensors.tpl:183 -#: views/sensor_settings.tpl:40 views/sensor_settings.tpl:129 +#: views/sensor_settings.tpl:40 views/sensor_settings.tpl:130 msgid "Limit max" msgstr "Limit max" @@ -1918,6 +1922,10 @@ msgstr "Here you can configure your sensors." msgid "Add new sensor" msgstr "Add new sensor" +#: views/sensor_settings.tpl:95 views/switch_settings.tpl:86 +msgid "Remote" +msgstr "Remote" + #: views/switch_settings.tpl:16 msgid "Here you can configure your power switches." msgstr "Here you can configure your power switches." @@ -1934,23 +1942,27 @@ msgstr "GPIO Inverse" msgid "PWM Dimmer" msgstr "PWM Dimmer" -#: views/switch_settings.tpl:109 +#: views/switch_settings.tpl:87 +msgid "Remote Dimmer" +msgstr "Remote Dimmer" + +#: views/switch_settings.tpl:111 msgid "Dimmer action duration" msgstr "Dimmer action duration" -#: views/switch_settings.tpl:113 +#: views/switch_settings.tpl:115 msgid "Dimmer on duration" msgstr "Dimmer on duration" -#: views/switch_settings.tpl:117 +#: views/switch_settings.tpl:119 msgid "Dimmer on percentage" msgstr "Dimmer on percentage" -#: views/switch_settings.tpl:121 +#: views/switch_settings.tpl:123 msgid "Dimmer off duration" msgstr "Dimmer off duration" -#: views/switch_settings.tpl:125 +#: views/switch_settings.tpl:127 msgid "Dimmer off percentage" msgstr "Dimmer off percentage" @@ -2262,6 +2274,10 @@ msgstr "System environment screenshot" msgid "TerrariumPI test setup" msgstr "TerrariumPI test setup" +#: Missing text string +msgid "There are zero door sensors configured." +msgstr "There are zero door sensors configured." + #: Missing text string msgid "Toggle power switch" msgstr "Toggle power switch" diff --git a/locales/nl_NL/LC_MESSAGES/terrariumpi.mo b/locales/nl_NL/LC_MESSAGES/terrariumpi.mo index 139e8f191..d2df66059 100644 Binary files a/locales/nl_NL/LC_MESSAGES/terrariumpi.mo and b/locales/nl_NL/LC_MESSAGES/terrariumpi.mo differ diff --git a/locales/nl_NL/LC_MESSAGES/terrariumpi.po b/locales/nl_NL/LC_MESSAGES/terrariumpi.po index 2ee6b2d14..fbef65c3b 100644 --- a/locales/nl_NL/LC_MESSAGES/terrariumpi.po +++ b/locales/nl_NL/LC_MESSAGES/terrariumpi.po @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: TerrariumPI 0.1\n" -"POT-Creation-Date: 2017-11-12 18:10+0100\n" -"PO-Revision-Date: 2017-11-12 18:11+0100\n" +"POT-Creation-Date: 2017-11-24 12:57+0100\n" +"PO-Revision-Date: 2017-11-24 13:01+0100\n" "Last-Translator: Joshua (TheYOSH) Rubingh \n" "Language-Team: \n" "Language: nl_NL\n" @@ -36,13 +36,19 @@ msgstr "Bevat de sensor hardware type. Ondersteunde hardware types zijn: %s." #: terrariumTranslations.py:27 msgid "" "Holds the sensor address. Depending on hardware type, it is either a read " -"only hex number or GPIO pin. For GPIO use physical GPIO pin " -"numbering." +"only hex number, a GPIO pin or a full HTTP(S) adress. Full url specification " +"can be found on the %s wiki page. For GPIO use physical " +"GPIO pin numbering." msgstr "" -" Bevat het sensor adres. Afhankelijk van het type hardware is het een alleen-" -"lezen hex-nummer of een GPIO-pin. Voor GPIO gebruikt u fysiekefysieke GPIO pin nummering." +#: terrariumTranslations.py:27 +msgid "Remote data" +msgstr "Externe data" + #: terrariumTranslations.py:28 msgid "Holds the sensor type. Supported sensor types are: %s." msgstr "Bevat het sensor type. Ondersteunde sensor types zijn: %s." @@ -654,11 +660,11 @@ msgstr "Data is opgeslagen" msgid "Your changes are saved" msgstr "Je wijzigingen zijn opgeslagen" -#: terrariumWebserver.py:319 views/inc/menu.tpl:146 +#: terrariumWebserver.py:320 views/inc/menu.tpl:146 msgid "Log out" msgstr "Log uit" -#: terrariumWebserver.py:320 +#: terrariumWebserver.py:321 msgid "You are now logged out" msgstr "Je bent nu uitgelogd" @@ -732,8 +738,8 @@ msgstr "Tijdsduur" #: views/inc/usage_sensors.tpl:171 views/inc/usage_switches.tpl:117 #: views/inc/usage_switches.tpl:140 views/inc/usage_webcams.tpl:104 #: views/inc/usage_webcams.tpl:134 views/profile.tpl:56 -#: views/sensor_settings.tpl:28 views/sensor_settings.tpl:113 -#: views/switch_settings.tpl:25 views/switch_settings.tpl:95 +#: views/sensor_settings.tpl:28 views/sensor_settings.tpl:114 +#: views/switch_settings.tpl:25 views/switch_settings.tpl:97 #: views/webcam_settings.tpl:27 views/webcam_settings.tpl:86 msgid "Name" msgstr "Naam" @@ -745,7 +751,7 @@ msgstr "Album" #: views/audio_files.tpl:68 views/inc/usage_dashboard.tpl:153 #: views/inc/usage_sensors.tpl:125 views/inc/usage_sensors.tpl:168 #: views/profile.tpl:63 views/sensor_settings.tpl:25 -#: views/sensor_settings.tpl:104 +#: views/sensor_settings.tpl:105 msgid "Type" msgstr "Type" @@ -761,7 +767,7 @@ msgstr "Kanalen" msgid "Frequency" msgstr "Frequentie" -#: views/audio_files.tpl:85 +#: views/audio_files.tpl:86 msgid "Preview player" msgstr "Preview speler" @@ -837,13 +843,13 @@ msgstr "nieuw" #: views/audio_playlist.tpl:122 views/door_settings.tpl:93 #: views/inc/usage_doors.tpl:70 views/inc/usage_sensors.tpl:80 #: views/inc/usage_switches.tpl:70 views/inc/usage_webcams.tpl:66 -#: views/sensor_settings.tpl:142 views/switch_settings.tpl:135 +#: views/sensor_settings.tpl:143 views/switch_settings.tpl:137 #: views/webcam_settings.tpl:108 msgid "Close" msgstr "Sluiten" #: views/audio_playlist.tpl:123 views/door_settings.tpl:94 -#: views/sensor_settings.tpl:143 views/switch_settings.tpl:136 +#: views/sensor_settings.tpl:144 views/switch_settings.tpl:138 #: views/webcam_settings.tpl:109 msgid "Add" msgstr "Voeg toe" @@ -855,13 +861,13 @@ msgstr "Actief" #: views/dashboard.tpl:24 views/inc/usage_dashboard.tpl:93 #: views/inc/usage_switches.tpl:121 views/inc/usage_switches.tpl:143 -#: views/switch_settings.tpl:28 views/switch_settings.tpl:99 +#: views/switch_settings.tpl:28 views/switch_settings.tpl:101 msgid "Power usage in Watt" msgstr "Stroomverbruik in Watt" #: views/dashboard.tpl:35 views/inc/usage_dashboard.tpl:99 #: views/inc/usage_switches.tpl:125 views/inc/usage_switches.tpl:146 -#: views/switch_settings.tpl:31 views/switch_settings.tpl:103 +#: views/switch_settings.tpl:31 views/switch_settings.tpl:105 msgid "Water flow in L/m" msgstr "Waterverbruik in L/m" @@ -884,7 +890,7 @@ msgstr "Totaal waterverbruik in L" #: views/inc/usage_sensors.tpl:154 views/inc/usage_sensors.tpl:186 #: views/inc/usage_sensors.tpl:203 views/inc/usage_weather.tpl:13 #: views/inc/usage_weather.tpl:85 views/sensor_settings.tpl:43 -#: views/sensor_settings.tpl:133 views/weather_forecast.tpl:7 +#: views/sensor_settings.tpl:134 views/weather_forecast.tpl:7 msgid "Current" msgstr "Huidig" @@ -920,7 +926,7 @@ msgid "mode" msgstr "modus" #: views/dashboard.tpl:83 views/dashboard.tpl:112 views/dashboard.tpl:135 -#: views/dashboard.tpl:164 views/inc/menu.tpl:203 +#: views/dashboard.tpl:164 views/inc/menu.tpl:180 views/inc/menu.tpl:206 #: views/inc/usage_environment.tpl:24 views/inc/usage_environment.tpl:120 #: views/inc/usage_environment.tpl:128 views/inc/usage_environment.tpl:212 #: views/inc/usage_environment.tpl:220 views/inc/usage_environment.tpl:306 @@ -967,7 +973,7 @@ msgstr "Sproeier" #: views/dashboard.tpl:128 views/dashboard.tpl:151 views/dashboard.tpl:186 #: views/inc/usage_sensors.tpl:138 views/inc/usage_sensors.tpl:174 -#: views/sensor_settings.tpl:31 views/sensor_settings.tpl:117 +#: views/sensor_settings.tpl:31 views/sensor_settings.tpl:118 msgid "Alarm min" msgstr "Alarm min" @@ -979,7 +985,7 @@ msgstr "Verwarming" #: views/dashboard.tpl:157 views/dashboard.tpl:180 #: views/inc/usage_sensors.tpl:142 views/inc/usage_sensors.tpl:177 -#: views/sensor_settings.tpl:34 views/sensor_settings.tpl:121 +#: views/sensor_settings.tpl:34 views/sensor_settings.tpl:122 msgid "Alarm max" msgstr "Alarm max" @@ -1062,8 +1068,8 @@ msgstr "Hardware" #: views/inc/usage_doors.tpl:106 views/inc/usage_doors.tpl:122 #: views/inc/usage_sensors.tpl:120 views/inc/usage_sensors.tpl:165 #: views/inc/usage_switches.tpl:112 views/inc/usage_switches.tpl:137 -#: views/sensor_settings.tpl:22 views/sensor_settings.tpl:99 -#: views/switch_settings.tpl:22 views/switch_settings.tpl:90 +#: views/sensor_settings.tpl:22 views/sensor_settings.tpl:100 +#: views/switch_settings.tpl:22 views/switch_settings.tpl:92 msgid "Address" msgstr "Adres" @@ -1369,12 +1375,12 @@ msgid "Forecast" msgstr "Voorspelling" #: views/inc/menu.tpl:46 views/inc/usage_dashboard.tpl:159 -#: views/inc/usage_sensors.tpl:128 views/sensor_settings.tpl:107 +#: views/inc/usage_sensors.tpl:128 views/sensor_settings.tpl:108 msgid "Temperature" msgstr "Temperatuur" #: views/inc/menu.tpl:49 views/inc/usage_dashboard.tpl:158 -#: views/inc/usage_sensors.tpl:129 views/sensor_settings.tpl:108 +#: views/inc/usage_sensors.tpl:129 views/sensor_settings.tpl:109 msgid "Humidity" msgstr "Luchtvochtigheid" @@ -1414,33 +1420,33 @@ msgstr "Vergrendelen" msgid "date/time" msgstr "datum/tijd" -#: views/inc/menu.tpl:163 views/inc/usage_dashboard.tpl:43 +#: views/inc/menu.tpl:163 views/inc/usage_dashboard.tpl:19 +msgid "Online" +msgstr "Online" + +#: views/inc/menu.tpl:166 views/inc/usage_dashboard.tpl:26 +msgid "Offline" +msgstr "Offline" + +#: views/inc/menu.tpl:172 views/inc/menu.tpl:192 views/inc/menu.tpl:212 +msgid "No messages" +msgstr "Geen berichten" + +#: views/inc/menu.tpl:183 views/inc/usage_dashboard.tpl:43 #: views/inc/usage_doors.tpl:82 msgid "Door is closed" msgstr "Deur is gesloten" -#: views/inc/menu.tpl:166 views/inc/usage_dashboard.tpl:50 +#: views/inc/menu.tpl:186 views/inc/usage_dashboard.tpl:50 #: views/inc/usage_doors.tpl:81 msgid "Door is open" msgstr "Deur is geopend" -#: views/inc/menu.tpl:172 views/inc/menu.tpl:189 views/inc/menu.tpl:209 -msgid "No messages" -msgstr "Geen berichten" - -#: views/inc/menu.tpl:180 views/inc/usage_dashboard.tpl:19 -msgid "Online" -msgstr "Online" - -#: views/inc/menu.tpl:183 views/inc/usage_dashboard.tpl:26 -msgid "Offline" -msgstr "Offline" - -#: views/inc/menu.tpl:197 +#: views/inc/menu.tpl:200 msgid "Playing" msgstr "Spelen" -#: views/inc/menu.tpl:200 +#: views/inc/menu.tpl:203 msgid "Stopped" msgstr "Gestopt" @@ -2149,12 +2155,12 @@ msgstr "" "grafieklijnen om gedetailleerde informatie te krijgen." #: views/inc/usage_sensors.tpl:146 views/inc/usage_sensors.tpl:180 -#: views/sensor_settings.tpl:37 views/sensor_settings.tpl:125 +#: views/sensor_settings.tpl:37 views/sensor_settings.tpl:126 msgid "Limit min" msgstr "Limiet min" #: views/inc/usage_sensors.tpl:150 views/inc/usage_sensors.tpl:183 -#: views/sensor_settings.tpl:40 views/sensor_settings.tpl:129 +#: views/sensor_settings.tpl:40 views/sensor_settings.tpl:130 msgid "Limit max" msgstr "Limiet max" @@ -2587,6 +2593,10 @@ msgstr "Hier kunt u uw sensoren configureren." msgid "Add new sensor" msgstr "Voeg nieuwe sensor toe" +#: views/sensor_settings.tpl:95 views/switch_settings.tpl:86 +msgid "Remote" +msgstr "Extern" + #: views/switch_settings.tpl:16 msgid "Here you can configure your power switches." msgstr "Hier kunt u uw stroomschakelaars configureren." @@ -2603,23 +2613,27 @@ msgstr "GPIO omgekeerd" msgid "PWM Dimmer" msgstr "PWM Dimmer" -#: views/switch_settings.tpl:109 +#: views/switch_settings.tpl:87 +msgid "Remote Dimmer" +msgstr "Externe dimmer" + +#: views/switch_settings.tpl:111 msgid "Dimmer action duration" msgstr "Dimmer tijd" -#: views/switch_settings.tpl:113 +#: views/switch_settings.tpl:115 msgid "Dimmer on duration" msgstr "Dimmer aan tijd in seconden" -#: views/switch_settings.tpl:117 +#: views/switch_settings.tpl:119 msgid "Dimmer on percentage" msgstr "Dimmer aan percentage" -#: views/switch_settings.tpl:121 +#: views/switch_settings.tpl:123 msgid "Dimmer off duration" msgstr "Dimmer uit in seconden" -#: views/switch_settings.tpl:125 +#: views/switch_settings.tpl:127 msgid "Dimmer off percentage" msgstr "Dimmer uit percentage" @@ -2935,6 +2949,10 @@ msgstr "Systeem omgeving screenshot" msgid "TerrariumPI test setup" msgstr "TerrariumPI test setup" +#: Missing text string +msgid "There are zero door sensors configured." +msgstr "Er zijn geen deursensoren geconfigureerd." + #: Missing text string msgid "Toggle power switch" msgstr "Klik de stroom schakelaar" @@ -3039,6 +3057,15 @@ msgstr "Systeem omgeving" msgid "System settings" msgstr "Systeem instellingen" +#~ msgid "" +#~ "Holds the sensor address. Depending on hardware type, it is either a read " +#~ "only hex number or GPIO pin. For GPIO use physical GPIO " +#~ "pin numbering." +#~ msgstr "" +#~ " Bevat het sensor adres. Afhankelijk van het type hardware is het een " +#~ "alleen-lezen hex-nummer of een GPIO-pin. Voor GPIO gebruikt u " +#~ "fysieke GPIO pin nummering." + #~ msgid "error" #~ msgstr "error" diff --git a/locales/terrariumpi.pot b/locales/terrariumpi.pot index cf210d274..7d40e6511 100644 --- a/locales/terrariumpi.pot +++ b/locales/terrariumpi.pot @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2017-11-12 18:09+CET\n" +"POT-Creation-Date: 2017-11-24 12:57+CET\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -28,7 +28,11 @@ msgid "Holds the sensor hardware type. Supported hardware types are: %s." msgstr "" #: terrariumTranslations.py:27 -msgid "Holds the sensor address. Depending on hardware type, it is either a read only hex number or GPIO pin. For GPIO use physical GPIO pin numbering." +msgid "Holds the sensor address. Depending on hardware type, it is either a read only hex number, a GPIO pin or a full HTTP(S) adress. Full url specification can be found on the %s wiki page. For GPIO use physical GPIO pin numbering." +msgstr "" + +#: terrariumTranslations.py:27 +msgid "Remote data" msgstr "" #: terrariumTranslations.py:28 @@ -442,11 +446,11 @@ msgstr "" msgid "Your changes are saved" msgstr "" -#: terrariumWebserver.py:319 views/inc/menu.tpl:146 +#: terrariumWebserver.py:320 views/inc/menu.tpl:146 msgid "Log out" msgstr "" -#: terrariumWebserver.py:320 +#: terrariumWebserver.py:321 msgid "You are now logged out" msgstr "" @@ -509,8 +513,8 @@ msgstr "" #: views/inc/usage_sensors.tpl:171 views/inc/usage_switches.tpl:117 #: views/inc/usage_switches.tpl:140 views/inc/usage_webcams.tpl:104 #: views/inc/usage_webcams.tpl:134 views/profile.tpl:56 -#: views/sensor_settings.tpl:28 views/sensor_settings.tpl:113 -#: views/switch_settings.tpl:25 views/switch_settings.tpl:95 +#: views/sensor_settings.tpl:28 views/sensor_settings.tpl:114 +#: views/switch_settings.tpl:25 views/switch_settings.tpl:97 #: views/webcam_settings.tpl:27 views/webcam_settings.tpl:86 msgid "Name" msgstr "" @@ -522,7 +526,7 @@ msgstr "" #: views/audio_files.tpl:68 views/inc/usage_dashboard.tpl:153 #: views/inc/usage_sensors.tpl:125 views/inc/usage_sensors.tpl:168 #: views/profile.tpl:63 views/sensor_settings.tpl:25 -#: views/sensor_settings.tpl:104 +#: views/sensor_settings.tpl:105 msgid "Type" msgstr "" @@ -538,7 +542,7 @@ msgstr "" msgid "Frequency" msgstr "" -#: views/audio_files.tpl:85 +#: views/audio_files.tpl:86 msgid "Preview player" msgstr "" @@ -611,13 +615,13 @@ msgstr "" #: views/audio_playlist.tpl:122 views/door_settings.tpl:93 #: views/inc/usage_doors.tpl:70 views/inc/usage_sensors.tpl:80 #: views/inc/usage_switches.tpl:70 views/inc/usage_webcams.tpl:66 -#: views/sensor_settings.tpl:142 views/switch_settings.tpl:135 +#: views/sensor_settings.tpl:143 views/switch_settings.tpl:137 #: views/webcam_settings.tpl:108 msgid "Close" msgstr "" #: views/audio_playlist.tpl:123 views/door_settings.tpl:94 -#: views/sensor_settings.tpl:143 views/switch_settings.tpl:136 +#: views/sensor_settings.tpl:144 views/switch_settings.tpl:138 #: views/webcam_settings.tpl:109 msgid "Add" msgstr "" @@ -629,13 +633,13 @@ msgstr "" #: views/dashboard.tpl:24 views/inc/usage_dashboard.tpl:93 #: views/inc/usage_switches.tpl:121 views/inc/usage_switches.tpl:143 -#: views/switch_settings.tpl:28 views/switch_settings.tpl:99 +#: views/switch_settings.tpl:28 views/switch_settings.tpl:101 msgid "Power usage in Watt" msgstr "" #: views/dashboard.tpl:35 views/inc/usage_dashboard.tpl:99 #: views/inc/usage_switches.tpl:125 views/inc/usage_switches.tpl:146 -#: views/switch_settings.tpl:31 views/switch_settings.tpl:103 +#: views/switch_settings.tpl:31 views/switch_settings.tpl:105 msgid "Water flow in L/m" msgstr "" @@ -658,7 +662,7 @@ msgstr "" #: views/inc/usage_sensors.tpl:154 views/inc/usage_sensors.tpl:186 #: views/inc/usage_sensors.tpl:203 views/inc/usage_weather.tpl:13 #: views/inc/usage_weather.tpl:85 views/sensor_settings.tpl:43 -#: views/sensor_settings.tpl:133 views/weather_forecast.tpl:7 +#: views/sensor_settings.tpl:134 views/weather_forecast.tpl:7 msgid "Current" msgstr "" @@ -694,7 +698,7 @@ msgid "mode" msgstr "" #: views/dashboard.tpl:83 views/dashboard.tpl:112 views/dashboard.tpl:135 -#: views/dashboard.tpl:164 views/inc/menu.tpl:203 +#: views/dashboard.tpl:164 views/inc/menu.tpl:180 views/inc/menu.tpl:206 #: views/inc/usage_environment.tpl:24 views/inc/usage_environment.tpl:120 #: views/inc/usage_environment.tpl:128 views/inc/usage_environment.tpl:212 #: views/inc/usage_environment.tpl:220 views/inc/usage_environment.tpl:306 @@ -741,7 +745,7 @@ msgstr "" #: views/dashboard.tpl:128 views/dashboard.tpl:151 views/dashboard.tpl:186 #: views/inc/usage_sensors.tpl:138 views/inc/usage_sensors.tpl:174 -#: views/sensor_settings.tpl:31 views/sensor_settings.tpl:117 +#: views/sensor_settings.tpl:31 views/sensor_settings.tpl:118 msgid "Alarm min" msgstr "" @@ -753,7 +757,7 @@ msgstr "" #: views/dashboard.tpl:157 views/dashboard.tpl:180 #: views/inc/usage_sensors.tpl:142 views/inc/usage_sensors.tpl:177 -#: views/sensor_settings.tpl:34 views/sensor_settings.tpl:121 +#: views/sensor_settings.tpl:34 views/sensor_settings.tpl:122 msgid "Alarm max" msgstr "" @@ -836,8 +840,8 @@ msgstr "" #: views/inc/usage_doors.tpl:106 views/inc/usage_doors.tpl:122 #: views/inc/usage_sensors.tpl:120 views/inc/usage_sensors.tpl:165 #: views/inc/usage_switches.tpl:112 views/inc/usage_switches.tpl:137 -#: views/sensor_settings.tpl:22 views/sensor_settings.tpl:99 -#: views/switch_settings.tpl:22 views/switch_settings.tpl:90 +#: views/sensor_settings.tpl:22 views/sensor_settings.tpl:100 +#: views/switch_settings.tpl:22 views/switch_settings.tpl:92 msgid "Address" msgstr "" @@ -1059,12 +1063,12 @@ msgid "Forecast" msgstr "" #: views/inc/menu.tpl:46 views/inc/usage_dashboard.tpl:159 -#: views/inc/usage_sensors.tpl:128 views/sensor_settings.tpl:107 +#: views/inc/usage_sensors.tpl:128 views/sensor_settings.tpl:108 msgid "Temperature" msgstr "" #: views/inc/menu.tpl:49 views/inc/usage_dashboard.tpl:158 -#: views/inc/usage_sensors.tpl:129 views/sensor_settings.tpl:108 +#: views/inc/usage_sensors.tpl:129 views/sensor_settings.tpl:109 msgid "Humidity" msgstr "" @@ -1104,33 +1108,33 @@ msgstr "" msgid "date/time" msgstr "" -#: views/inc/menu.tpl:163 views/inc/usage_dashboard.tpl:43 -#: views/inc/usage_doors.tpl:82 -msgid "Door is closed" +#: views/inc/menu.tpl:163 views/inc/usage_dashboard.tpl:19 +msgid "Online" msgstr "" -#: views/inc/menu.tpl:166 views/inc/usage_dashboard.tpl:50 -#: views/inc/usage_doors.tpl:81 -msgid "Door is open" +#: views/inc/menu.tpl:166 views/inc/usage_dashboard.tpl:26 +msgid "Offline" msgstr "" -#: views/inc/menu.tpl:172 views/inc/menu.tpl:189 views/inc/menu.tpl:209 +#: views/inc/menu.tpl:172 views/inc/menu.tpl:192 views/inc/menu.tpl:212 msgid "No messages" msgstr "" -#: views/inc/menu.tpl:180 views/inc/usage_dashboard.tpl:19 -msgid "Online" +#: views/inc/menu.tpl:183 views/inc/usage_dashboard.tpl:43 +#: views/inc/usage_doors.tpl:82 +msgid "Door is closed" msgstr "" -#: views/inc/menu.tpl:183 views/inc/usage_dashboard.tpl:26 -msgid "Offline" +#: views/inc/menu.tpl:186 views/inc/usage_dashboard.tpl:50 +#: views/inc/usage_doors.tpl:81 +msgid "Door is open" msgstr "" -#: views/inc/menu.tpl:197 +#: views/inc/menu.tpl:200 msgid "Playing" msgstr "" -#: views/inc/menu.tpl:200 +#: views/inc/menu.tpl:203 msgid "Stopped" msgstr "" @@ -1596,12 +1600,12 @@ msgid "The history graph will shows the measured value. The flat lines are the m msgstr "" #: views/inc/usage_sensors.tpl:146 views/inc/usage_sensors.tpl:180 -#: views/sensor_settings.tpl:37 views/sensor_settings.tpl:125 +#: views/sensor_settings.tpl:37 views/sensor_settings.tpl:126 msgid "Limit min" msgstr "" #: views/inc/usage_sensors.tpl:150 views/inc/usage_sensors.tpl:183 -#: views/sensor_settings.tpl:40 views/sensor_settings.tpl:129 +#: views/sensor_settings.tpl:40 views/sensor_settings.tpl:130 msgid "Limit max" msgstr "" @@ -1917,6 +1921,10 @@ msgstr "" msgid "Add new sensor" msgstr "" +#: views/sensor_settings.tpl:95 views/switch_settings.tpl:86 +msgid "Remote" +msgstr "" + #: views/switch_settings.tpl:16 msgid "Here you can configure your power switches." msgstr "" @@ -1933,23 +1941,27 @@ msgstr "" msgid "PWM Dimmer" msgstr "" -#: views/switch_settings.tpl:109 +#: views/switch_settings.tpl:87 +msgid "Remote Dimmer" +msgstr "" + +#: views/switch_settings.tpl:111 msgid "Dimmer action duration" msgstr "" -#: views/switch_settings.tpl:113 +#: views/switch_settings.tpl:115 msgid "Dimmer on duration" msgstr "" -#: views/switch_settings.tpl:117 +#: views/switch_settings.tpl:119 msgid "Dimmer on percentage" msgstr "" -#: views/switch_settings.tpl:121 +#: views/switch_settings.tpl:123 msgid "Dimmer off duration" msgstr "" -#: views/switch_settings.tpl:125 +#: views/switch_settings.tpl:127 msgid "Dimmer off percentage" msgstr "" @@ -2261,6 +2273,10 @@ msgstr "" msgid "TerrariumPI test setup" msgstr "" +#: Missing text string +msgid "There are zero door sensors configured." +msgstr "" + #: Missing text string msgid "Toggle power switch" msgstr "" diff --git a/static/css/terrariumpi.css b/static/css/terrariumpi.css index 8de4ea2d2..953844d9a 100644 --- a/static/css/terrariumpi.css +++ b/static/css/terrariumpi.css @@ -132,7 +132,11 @@ div.modal div.row.webcam{ .top_nav .nav_menu ul.nav.navbar-nav.navbar-right li#door_indicator .open, .top_nav .nav_menu ul.nav.navbar-nav.navbar-right li#door_indicator .closed, .top_nav .nav_menu ul.nav.navbar-nav.navbar-right li#player_indicator .running, -.top_nav .nav_menu ul.nav.navbar-nav.navbar-right li#player_indicator .stopped { +.top_nav .nav_menu ul.nav.navbar-nav.navbar-right li#player_indicator .stopped, +div.row.environment_light.disabled, +div.row.environment_sprayer.disabled, +div.row.environment_heater.disabled, +div.row.environment_cooler.disabled { display:none; } diff --git a/static/js/terrariumpi.js b/static/js/terrariumpi.js index d46a0c489..a90b0258e 100644 --- a/static/js/terrariumpi.js +++ b/static/js/terrariumpi.js @@ -637,9 +637,9 @@ function update_dashboard_uptime(data) { update_dashboard_tile('uptime', format_uptime(data.uptime)); $('#system_time span').text(moment(data.timestamp * 1000).format('LLLL')); $('#system_time i').removeClass('fa-clock-o fa-sun-o fa-moon-o').addClass((data.day ? 'fa-sun-o' : 'fa-moon-o')); - $("#uptime .progress-bar-success").css('height', (data.load[0] * 100) + '%'); - $("#uptime .progress-bar-warning").css('height', (data.load[1] * 100) + '%'); - $("#uptime .progress-bar-danger").css('height', (data.load[2] * 100) + '%'); + $("#uptime .progress-bar-success").css('height', ((data.load[0] / data.cores) * 100) + '%'); + $("#uptime .progress-bar-warning").css('height', ((data.load[1] / data.cores) * 100) + '%'); + $("#uptime .progress-bar-danger").css('height', ( (data.load[2] / data.cores) * 100) + '%'); } function update_dashboard_power_usage(data) { @@ -706,9 +706,10 @@ function update_dashboard_environment(name, value) { 'timer':'{{_('Timer')}}'}; var systempart = $('div.environment_' + name); if (systempart.length === 0 || Object.keys(value).length === 0 || !value.enabled) { - systempart.find('table.tile_info').hide(); + systempart.addClass('disabled'); return; } + systempart.removeClass('disabled'); var enabledColor = ''; var indicator = '°' + globals.temperature_indicator; switch (name) { @@ -730,6 +731,7 @@ function update_dashboard_environment(name, value) { systempart.find('h4').removeClass('orange blue red') .addClass(value.enabled ? enabledColor : '') .attr('title', value.enabled ? "{{_('Enabled')}}" : "{{_('Disabled')}}"); + systempart.find('h4 small span').text(mode_translations[value.mode]); if (value.on !== undefined) { @@ -1151,6 +1153,9 @@ function sensor_gauge(name, data) { globals.gauges[name].setMinValue(data.limit_min); } // Update values + if (name == 'system_load') { + data.current /= data.cores; + } globals.gauges[name].set(data.current); if (name == 'system_disk' || name == 'system_memory') { $('#' + name + ' .gauge-value').text(formatBytes(data.current)) @@ -1274,6 +1279,10 @@ function history_graph(name, data, type) { val = moment.duration(val * 1000).humanize(); break; + case 'system_load': + val = formatNumber(val); + break; + case 'weather': val = formatNumber(val) + ' °' + globals.temperature_indicator; break; @@ -1462,6 +1471,37 @@ function check_form_data(form) { return fieldsok; } +function parse_remote_data(type,url) { + $.get(url,function(data) { + var json_path = url.indexOf('#'); + if (json_path != -1) { + json_path = url.substring(json_path+1).split('/'); + // TerrariumPI API is known, and can be used to fill in all values + var is_remote_terrarium_pi = json_path.length == 3 + && (json_path[0] === 'sensors' || json_path[0] === 'switches') + && json_path[1] === '0' + && (json_path[2] === 'current' || json_path[2] === 'state'); + + if (is_remote_terrarium_pi) { + // Loop through the fields and fill in the fields with remote information + $.each(data[json_path[0]][json_path[1]],function(fieldname,value) { + // Never overrule fields in array below + if ($.inArray(fieldname,['address','hardwaretype','id']) == -1) { + $('input[name="' + type + '_[nr]_' + fieldname + '"]').val(value); + $('select[name="' + type + '_[nr]_' + fieldname + '"]').val(value).change(); + } + }); + } else { + // Here we loop over the JSON structure to get the end value which should be the current value + $.each(json_path,function(index,value){ + data = data[value]; + }); + $('input[name="' + type + '_[nr]_current"]').val(data); + } + } + }); +} + function add_sensor() { var form = $('.new-sensor-form'); if (!check_form_data(form)) return false; @@ -1476,8 +1516,11 @@ function add_sensor() { form.find('input[name="sensor_[nr]_limit_min"]').val(), form.find('input[name="sensor_[nr]_limit_max"]').val(), -1); - - $('.new-sensor-form').modal('hide'); + // Reset form + form.find('input').val(''); + form.find('select').val(null).trigger('change'); + // Hide form + form.modal('hide'); } function add_sensor_row(id,hardwaretype,address,type,name,alarm_min,alarm_max,limit_min,limit_max,current) { @@ -1497,11 +1540,14 @@ function add_sensor_row(id,hardwaretype,address,type,name,alarm_min,alarm_max,li sensor_row.find("select").select2({ placeholder: '{{_('Select an option')}}', allowClear: false, - minimumResultsForSearch: Infinity + minimumResultsForSearch: Infinity, }).on('change',function() { + // Changing should not be possible. But disabling will cripple the form post data + /* if (this.name.indexOf('hardwaretype') >= 0) { $("input[name='" + this.name.replace('hardwaretype','address') + "']").attr("readonly", this.value == 'owfs' || this.value == 'w1'); } + */ }); } @@ -1522,7 +1568,11 @@ function add_switch() { form.find('input[name="switch_[nr]_dimmer_off_percentage"]').val() ); - $('.new-switch-form').modal('hide'); + // Reset form + form.find('input').val(''); + form.find('select').val(null).trigger('change'); + // Hide form + form.modal('hide'); } function add_switch_row(id,hardwaretype,address,name,power_wattage,water_flow, dimmer_duration,dimmer_on_duration,dimmer_on_percentage,dimmer_off_duration,dimmer_off_percentage) { @@ -1545,9 +1595,9 @@ function add_switch_row(id,hardwaretype,address,name,power_wattage,water_flow, d allowClear: false, minimumResultsForSearch: Infinity }).on('change',function() { - switch_row.find('.row.dimmer').toggle(this.value === 'pwm-dimmer'); + //switch_row.find('.row.dimmer').toggle(this.value === 'pwm-dimmer'); }); - switch_row.find('.row.dimmer').toggle(hardwaretype === 'pwm-dimmer'); + switch_row.find('.row.dimmer').toggle('pwm-dimmer' === hardwaretype || 'remote-dimmer' === hardwaretype); } function add_door() { @@ -1621,7 +1671,7 @@ function add_webcam_row(id,location,name,rotation,preview) { function update_power_switch(id, data) { var power_switch = $('#switch_' + id); var update_data = ''; - if (data.hardwaretype === 'pwm-dimmer') { + if ('pwm-dimmer' === data.hardwaretype || 'remote-dimmer' === data.hardwaretype) { update_data = formatNumber(data.current_power_wattage) + 'W / ' } update_data += formatNumber(data.power_wattage) + 'W'; @@ -1632,7 +1682,7 @@ function update_power_switch(id, data) { power_switch.find('h2 span.title').text('{{_('Switch')}} ' + data.name); power_switch.find('h2 small.data_update').text(update_data); - if (data.hardwaretype === 'pwm-dimmer') { + if ('pwm-dimmer' === data.hardwaretype || 'remote-dimmer' === data.hardwaretype) { power_switch.find('div.power_switch').removeClass('big').addClass('dimmer').html(''); power_switch.find('.knob').knob({ diff --git a/terrariumAudio.py b/terrariumAudio.py index 24fb44102..3155376e3 100644 --- a/terrariumAudio.py +++ b/terrariumAudio.py @@ -35,7 +35,7 @@ def __init__(self,playlistdata,cardid,pwmdimmer,callback=None): self.__load_audio_files() self.__load_playlists(playlistdata) - if pwmdimmer and self.__hwid == 0: + if pwmdimmer and cardid == 'bcm2835 ALSA': logger.warning('Disabled audio playing due to hardware conflict with PWM dimmers and onboard soundcard') else: self.__load_audio_mixer() diff --git a/terrariumCollector.py b/terrariumCollector.py index 0d40d7044..7b1e61462 100644 --- a/terrariumCollector.py +++ b/terrariumCollector.py @@ -301,7 +301,7 @@ def __calculate_door_usage(self,history): history['doors'][doorid]['totals'] = totals def log_switch_data(self,data): - if data['hardwaretype'] != 'pwm-dimmer': + if data['hardwaretype'] not in ['pwm-dimmer','remote-dimmer']: # Store normal switches with value 100 indicating full power (aka no dimming) data['state'] = (100 if data['state'] == 1 else 0) diff --git a/terrariumConfig.py b/terrariumConfig.py index cbf1bccca..6a2774e6c 100644 --- a/terrariumConfig.py +++ b/terrariumConfig.py @@ -98,6 +98,12 @@ def __upgrade_config(self,to_version): if 'pwm-dimmer' == switch_data['hardwaretype']: self.__config.set(section, 'address', str(terrariumUtils.to_BOARD_port_number(switch_data['address']))) + elif version == 312: + logger.info('Updating configuration file to version: %s' % (version,)) + data = self.__get_config('terrariumpi') + if 'soundcard' in data and data['soundcard'] == '0': + self.__config.set('terrariumpi', 'soundcard', 'bcm2835 ALSA') + # Update version number self.__config.set('terrariumpi', 'version', str(to_version)) self.__save_config() diff --git a/terrariumEngine.py b/terrariumEngine.py index 460f310b8..cc036ecee 100644 --- a/terrariumEngine.py +++ b/terrariumEngine.py @@ -268,6 +268,13 @@ def __engine_loop(self): # Websocket callback self.__send_message({'type':'sensor_gauge','data':average_data}) + # Update (remote) power switches + for power_switch_id in self.power_switches: + # Update the current sensor. + self.power_switches[power_switch_id].update() + # Make time for other web request + sleep(0.1) + # Websocket messages back self.get_uptime(socket=True) self.get_power_usage_water_flow(socket=True) @@ -825,12 +832,12 @@ def get_system_stats(self, socket = False): 'temperature' : cpu_temp} if socket: - gauge_data = {'system_load' : {'current' : data['load']['load1'] * 100, 'alarm_min' : 0, 'alarm_max': 80, 'limit_min' : 0, 'limit_max': 100}, + gauge_data = {'system_load' : {'current' : data['load']['load1'] * 100, 'alarm_min' : 0, 'alarm_max': 80, 'limit_min' : 0, 'limit_max': 100, 'cores' : data['cores']}, 'system_temperature' : {'current' : data['temperature'], 'alarm_min' : 30, 'alarm_max': 60, 'limit_min' : 0, 'limit_max': 80}, 'system_memory' : {'current' : data['memory']['used'], 'alarm_min' : data['memory']['total'] * 0.1, 'alarm_max': data['memory']['total'] * 0.9, 'limit_min' : 0, 'limit_max': data['memory']['total']}, 'system_disk' : {'current' : data['disk']['used'], 'alarm_min' : data['disk']['total'] * 0.1, 'alarm_max': data['disk']['total'] * 0.9, 'limit_min' : 0, 'limit_max': data['disk']['total']}} - gauge_data['system_load']['alarm'] = not(gauge_data['system_load']['alarm_min'] < gauge_data['system_load']['current'] < gauge_data['system_load']['alarm_max']) + gauge_data['system_load']['alarm'] = not(gauge_data['system_load']['alarm_min'] < gauge_data['system_load']['current'] / data['cores'] < gauge_data['system_load']['alarm_max']) gauge_data['system_temperature']['alarm'] = not(gauge_data['system_temperature']['alarm_min'] < gauge_data['system_temperature']['current'] < gauge_data['system_temperature']['alarm_max']) gauge_data['system_memory']['alarm'] = not(gauge_data['system_memory']['alarm_min'] < gauge_data['system_memory']['current'] < gauge_data['system_memory']['alarm_max']) gauge_data['system_disk']['alarm'] = not(gauge_data['system_disk']['alarm_min'] < gauge_data['system_disk']['current'] < gauge_data['system_disk']['alarm_max']) @@ -843,7 +850,8 @@ def get_uptime(self, socket = False): data = {'uptime' : uptime.uptime(), 'timestamp' : int(time.time()), 'day' : self.weather.is_day(), - 'load' : os.getloadavg()} + 'load' : os.getloadavg(), + 'cores' : psutil.cpu_count()} if socket: self.__send_message({'type':'uptime','data':data}) diff --git a/terrariumSensor.py b/terrariumSensor.py index 0ce93cb7d..d0d65e3e1 100644 --- a/terrariumSensor.py +++ b/terrariumSensor.py @@ -8,6 +8,7 @@ import Adafruit_DHT as dht import glob import re +import requests from hashlib import md5 from terrariumUtils import terrariumUtils @@ -18,7 +19,7 @@ class terrariumSensor: VALID_DHT_SENSORS = { 'dht11' : dht.DHT11, 'dht22' : dht.DHT22, 'am2302': dht.AM2302 } - VALID_HARDWARE_TYPES = ['owfs','w1'] + VALID_DHT_SENSORS.keys() + VALID_HARDWARE_TYPES = ['owfs','w1','remote'] + VALID_DHT_SENSORS.keys() W1_BASE_PATH = '/sys/bus/w1/devices/' W1_TEMP_REGEX = re.compile(r'(?Pt|f)=(?P[0-9]+)',re.IGNORECASE) @@ -40,6 +41,8 @@ def __init__(self, id, hardware_type, sensor_type, sensor, name = '', alarm_min self.sensor = dht # Dirty hack to replace OWFS sensor object for GPIO pin nr self.sensor_address = sensor + elif 'remote' == self.get_hardware_type(): + self.sensor_address = sensor self.set_name(name) self.set_type(sensor_type,indicator) @@ -180,9 +183,33 @@ def update(self, force = False): current = None try: starttime = time.time() - if 'temperature' == self.get_type(): + if 'remote' == self.get_hardware_type(): + url_data = terrariumUtils.parse_url(self.get_address()) + if url_data is False: + logger.error('Remote url \'%s\' for sensor \'%s\' is not a valid remote source url!' % (self.get_address(),self.get_name())) + else: + data = requests.get(self.get_address(),auth=(url_data['username'],url_data['password']),timeout=3) + + if data.status_code == 200: + data = data.json() + json_path = url_data['fragment'].split('/') if 'fragment' in url_data and url_data['fragment'] is not None else [] + + for item in json_path: + # Dirty hack to process array data.... + try: + item = int(item) + except Exception, ex: + item = str(item) + + data = data[item] + current = float(data) + else: + logger.warning('Remote sensor \'%s\' got error from remote source \'%s\': %s' % (self.get_name(),self.get_address(),data.status_code)) + + elif 'temperature' == self.get_type(): if self.get_hardware_type() == 'owfs': current = float(self.sensor.temperature) + elif self.get_hardware_type() == 'w1': data = '' with open(terrariumSensor.W1_BASE_PATH + self.get_address() + '/w1_slave', 'r') as w1data: @@ -191,8 +218,7 @@ def update(self, force = False): w1data = terrariumSensor.W1_TEMP_REGEX.search(data) if w1data: # Found data - temperature = float(w1data.group('value')) / 1000 - current = float(temperature) + current = float(w1data.group('value')) / 1000 elif self.get_hardware_type() in terrariumSensor.VALID_DHT_SENSORS.keys(): humidity, temperature = self.sensor.read_retry(terrariumSensor.VALID_DHT_SENSORS[self.get_hardware_type()], float(terrariumUtils.to_BCM_port_number(self.sensor_address)), @@ -203,9 +229,11 @@ def update(self, force = False): elif 'humidity' == self.get_type(): if self.get_hardware_type() == 'owfs': current = float(self.sensor.humidity) + elif self.get_hardware_type() == 'w1': # Not tested / No hardware to test with pass + elif self.get_hardware_type() in terrariumSensor.VALID_DHT_SENSORS.keys(): humidity, temperature = self.sensor.read_retry(terrariumSensor.VALID_DHT_SENSORS[self.get_hardware_type()], float(terrariumUtils.to_BCM_port_number(self.sensor_address)), diff --git a/terrariumSwitch.py b/terrariumSwitch.py index 05786c7cb..239308a6b 100644 --- a/terrariumSwitch.py +++ b/terrariumSwitch.py @@ -8,13 +8,14 @@ import thread import time import math +import requests from pylibftdi import Driver, BitBangDevice, SerialDevice, Device from hashlib import md5 from terrariumUtils import terrariumUtils class terrariumSwitch(): - VALID_HARDWARE_TYPES = ['ftdi','gpio','gpio-inverse','pwm-dimmer'] + VALID_HARDWARE_TYPES = ['ftdi','gpio','gpio-inverse','pwm-dimmer','remote','remote-dimmer'] OFF = False ON = True @@ -46,6 +47,8 @@ def __init__(self, id, hardware_type, address, name = '', power_wattage = 0.0, w self.__load_ftdi_device() elif self.get_hardware_type() == 'pwm-dimmer': self.__load_pwm_device() + elif 'remote' in self.get_hardware_type(): + pass elif 'gpio' in self.get_hardware_type(): self.__load_gpio_device() @@ -178,6 +181,9 @@ def set_state(self, state, force = False): duration = self.get_dimmer_off_duration() thread.start_new_thread(self.__dim_switch, (self.state,state,duration)) + elif 'remote' in self.get_hardware_type(): + # Not yet implemented + pass self.state = state if self.get_hardware_type() != 'pwm-dimmer': @@ -210,6 +216,38 @@ def get_data(self): return data + def update(self): + if 'remote' in self.get_hardware_type(): + url_data = terrariumUtils.parse_url(self.get_address()) + if url_data is False: + logger.error('Remote url \'%s\' for switch \'%s\' is not a valid remote source url!' % (self.get_address(),self.get_name())) + else: + try: + data = requests.get(self.get_address(),auth=(url_data['username'],url_data['password']),timeout=3) + + if data.status_code == 200: + data = data.json() + json_path = url_data['fragment'].split('/') if 'fragment' in url_data and url_data['fragment'] is not None else [] + + for item in json_path: + # Dirty hack to process array data.... + try: + item = int(item) + except Exception, ex: + item = str(item) + + data = data[item] + + if 'remote' == self.get_hardware_type(): + self.set_state(terrariumUtils.is_true(data)) + elif 'remote-dimmer' == self.get_hardware_type(): + self.set_state(int(data)) + + else: + logger.warning('Remote switch \'%s\' got error from remote source \'%s\': %s' % (self.get_name(),self.get_address(),data.status_code)) + except Exception, ex: + logger.error('Remote switch \'%s\' got error from remote source \'%s\': %s' % (self.get_name(),self.get_address(),ex)) + def get_id(self): return self.id @@ -243,7 +281,7 @@ def get_power_wattage(self): def get_current_power_wattage(self): wattage = 0.0 - if self.get_hardware_type() == 'pwm-dimmer': + if self.get_hardware_type() in ['pwm-dimmer','remote-dimmer']: wattage = self.get_power_wattage() * (self.get_state() / 100.0) else: wattage = self.get_power_wattage() @@ -261,7 +299,7 @@ def get_water_flow(self): def get_current_water_flow(self): waterflow = 0.0 - if self.get_hardware_type() == 'pwm-dimmer': + if self.get_hardware_type() in ['pwm-dimmer','remote-dimmer']: waterflow = self.get_water_flow() * (self.get_state() / 100.0) else: waterflow = self.get_water_flow() @@ -285,13 +323,13 @@ def toggle(self): return None def is_on(self): - if self.get_hardware_type() == 'pwm-dimmer': + if self.get_hardware_type() in ['pwm-dimmer','remote-dimmer']: return self.get_state() > self.get_dimmer_off_percentage() else: return self.get_state() is terrariumSwitch.ON def is_off(self): - if self.get_hardware_type() == 'pwm-dimmer': + if self.get_hardware_type() in ['pwm-dimmer','remote-dimmer']: return self.get_state() == self.get_dimmer_off_percentage() else: return self.get_state() is terrariumSwitch.OFF @@ -318,32 +356,32 @@ def set_dimmer_duration(self,value): self.__dimmer_duration = value if value >= 0.0 else 0.0 def get_dimmer_duration(self): - return (self.__dimmer_duration if self.get_hardware_type() == 'pwm-dimmer' else 0.0) + return (self.__dimmer_duration if self.get_hardware_type() in ['pwm-dimmer','remote-dimmer'] else 0.0) def set_dimmer_on_duration(self,value): value = float(value) if terrariumUtils.is_float(value) else 0.0 self.__dimmer_on_duration = value if value >= 0.0 else 0.0 def get_dimmer_on_duration(self): - return (self.__dimmer_on_duration if self.get_hardware_type() == 'pwm-dimmer' else 0.0) + return (self.__dimmer_on_duration if self.get_hardware_type() in ['pwm-dimmer','remote-dimmer'] else 0.0) def set_dimmer_off_duration(self,value): value = float(value) if terrariumUtils.is_float(value) else 0.0 self.__dimmer_off_duration = value if value >= 0.0 else 0.0 def get_dimmer_off_duration(self): - return (self.__dimmer_off_duration if self.get_hardware_type() == 'pwm-dimmer' else 0.0) + return (self.__dimmer_off_duration if self.get_hardware_type() in ['pwm-dimmer','remote-dimmer'] else 0.0) def set_dimmer_on_percentage(self,value): value = float(value) if terrariumUtils.is_float(value) else 0.0 self.__dimmer_on_percentage = value if (0.0 <= value <= 100.0) else 100.0 def get_dimmer_on_percentage(self): - return (self.__dimmer_on_percentage if self.get_hardware_type() == 'pwm-dimmer' else 100.0) + return (self.__dimmer_on_percentage if self.get_hardware_type() in ['pwm-dimmer','remote-dimmer'] else 100.0) def set_dimmer_off_percentage(self,value): value = float(value) if terrariumUtils.is_float(value) else 0.0 self.__dimmer_off_percentage = value if (0.0 <= value <= 100.0) else 100.0 def get_dimmer_off_percentage(self): - return (self.__dimmer_off_percentage if self.get_hardware_type() == 'pwm-dimmer' else 0.0) + return (self.__dimmer_off_percentage if self.get_hardware_type() in ['pwm-dimmer','remote-dimmer'] else 0.0) diff --git a/terrariumTranslations.py b/terrariumTranslations.py index 1d044b3a5..42233cec4 100644 --- a/terrariumTranslations.py +++ b/terrariumTranslations.py @@ -24,7 +24,7 @@ def __load(self): # Sensors self.translations['sensor_field_hardware'] = _('Holds the sensor hardware type. Supported hardware types are: %s.') % ('' + ', '.join(terrariumSensor.VALID_HARDWARE_TYPES) + '') - self.translations['sensor_field_address'] = _('Holds the sensor address. Depending on hardware type, it is either a read only hex number or GPIO pin. For GPIO use physical GPIO pin numbering.') + self.translations['sensor_field_address'] = _('Holds the sensor address. Depending on hardware type, it is either a read only hex number, a GPIO pin or a full HTTP(S) adress. Full url specification can be found on the %s wiki page. For GPIO use physical GPIO pin numbering.') % ('\'' + _('Remote data') + '\'') self.translations['sensor_field_type'] = _('Holds the sensor type. Supported sensor types are: %s.') % ('' + ', '.join(terrariumSensor.VALID_SENSOR_TYPES) + '') self.translations['sensor_field_name'] = _('Holds the name of the sensor.') self.translations['sensor_field_alarm_min'] = _('Holds the sensor lower alarm value of the sensor. When below this value, alarms can be triggered.') diff --git a/terrariumUtils.py b/terrariumUtils.py index a168fb83e..85de32909 100644 --- a/terrariumUtils.py +++ b/terrariumUtils.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import re class terrariumUtils(): @@ -18,6 +19,10 @@ def is_float(value): except ValueError: return False + @staticmethod + def is_true(value): + return value in ['true','True','1',1,'on',True] + @staticmethod def to_BCM_port_number(value): pinout = {'gpio3' : 2, @@ -93,3 +98,16 @@ def to_BOARD_port_number(value): return pinout[index] return False + + @staticmethod + def parse_url(url): + url = url.strip() + if '' == url: + return False + + regex = ur"^((?Phttps?|ftp):\/)?\/?((?P.*?)(:(?P.*?)|)@)?(?P[^:\/\s]+)(:(?P(\d*))?)?(?P(\/\w+)*\/)(?P[-\w.]+[^#?\s]*)?(?P\?([^#]*))?(#(?P(.*))?)?$" + matches = re.search(regex, url) + if matches: + return matches.groupdict() + + return False diff --git a/terrariumWebserver.py b/terrariumWebserver.py index e2ff2cd0a..ef07fc1ce 100644 --- a/terrariumWebserver.py +++ b/terrariumWebserver.py @@ -235,6 +235,7 @@ def __update_api_call(self,path): def __get_api_call(self,path): response.headers['Expires'] = (datetime.datetime.utcnow() + datetime.timedelta(minutes=1)).strftime('%a, %d %b %Y %H:%M:%S GMT') + response.headers['Access-Control-Allow-Origin'] = '*' result = {} parameters = path.strip('/').split('/') diff --git a/views/dashboard.tpl b/views/dashboard.tpl index d52d5f43e..5cdc5f3b3 100644 --- a/views/dashboard.tpl +++ b/views/dashboard.tpl @@ -79,7 +79,7 @@
-
+

{{_('Lights')}} {{_('mode')}}: {{_('Disabled')}}

@@ -108,7 +108,7 @@
-
+

{{_('Sprayer')}} {{_('mode')}}: {{_('Disabled')}}

@@ -131,7 +131,7 @@
-
+

{{_('Heater')}} {{_('mode')}}: {{_('Disabled')}}

@@ -160,7 +160,7 @@
-
+

{{_('Cooler')}} {{_('mode')}}: {{_('Disabled')}}

diff --git a/views/sensor_settings.tpl b/views/sensor_settings.tpl index ae87fad8b..57a0b431d 100644 --- a/views/sensor_settings.tpl +++ b/views/sensor_settings.tpl @@ -92,6 +92,7 @@ + @@ -148,15 +149,22 @@