Skip to content

Commit

Permalink
Merge for release
Browse files Browse the repository at this point in the history
  • Loading branch information
theyosh committed May 31, 2018
2 parents 641b1d3 + 4baac21 commit c1367e4
Show file tree
Hide file tree
Showing 22 changed files with 3,384 additions and 2,959 deletions.
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# TerrariumPI 3.5
# TerrariumPI 3.6.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.
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. In order to lower the humidity you can add a dehumidifier.

The software is that flexible that there is no limit in amount of sensors, relay boards or door sensors. The usage can be endless. All power switches have support for timers to trigger based on a time pattern.

Expand All @@ -27,7 +27,7 @@ And all this is controlled with a nice webinterface based on [Gentelella a Boots
9. [About](#about)

## Features
- Controlling electronic devices like lights, sprayers, heating, cooling and water pump equipment
- Controlling electronic devices like lights, sprayers, heating, cooling, water pump equipment etc
- Support for dimming electronic devices
- Manual dimming through web interface
- Predefined on and off dimming durations
Expand All @@ -39,6 +39,10 @@ And all this is controlled with a nice webinterface based on [Gentelella a Boots
- Support for Energenie USB and LAN powerswitches [EG-PM(s)2](http://energenie.com/item.aspx?id=7556)
- Support for multiple temperature and humidity sensors
- Support for ultrasonic sound range sensors
- Support for ph sensors
- Support for conductivity sensors
- Support for moisture sensors
- support for light sensors
- Support for native Raspberry Pi cam out of the box
- Support for USB and remote webcams
- Support for analog devices through a MCP3008
Expand All @@ -48,7 +52,8 @@ And all this is controlled with a nice webinterface based on [Gentelella a Boots
- Support for BME280
- Support for HTU21D
- Support for Si7021
- Open door detection (sprayer will not spray when a door is open)
- Support for Chirp
- Open door detection. This can be used in different environment parts
- Total power and water usage for costs calculation
- Lights control based on sun rise and sun set or timers
- Rain control based on humidity sensors and timers
Expand Down
4 changes: 3 additions & 1 deletion contrib/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ server {

access_log /var/log/nginx/terrariumpi.access.log;
location / {
proxy_pass http://localhost:8090;
proxy_pass http://localhost:8090;

client_max_body_size 1G;

proxy_set_header X-Real-IP $remote_addr; # http://wiki.nginx.org/HttpProxyModule
proxy_http_version 1.1; # recommended with keepalive connections
Expand Down
4 changes: 2 additions & 2 deletions defaults.cfg
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[terrariumpi]
host = ::
port = 8090
version = 3.5.0
version = 3.6.0
title = TerrariumPI %(version)s
power_usage = 5
owfs_port = 4304
Expand All @@ -16,7 +16,7 @@ soundcard = bcm2835 ALSA
always_authenticate = false

[weather]
location = http://www.yr.no/place/Netherlands/Groningen/Groningen
location = https://www.yr.no/place/Netherlands/Groningen/Groningen
windspeed = kmh

[profile]
Expand Down
4 changes: 2 additions & 2 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ if grep -qs "${TMPFS} " /proc/mounts; then
# There is an existing logfile already. Move it
mv ${LOGFILE} ${TMPFS}
fi
ln -s "${TMPFS}/terrariumpi.log" "${LOGFILE}"
su -c "ln -s ${TMPFS}/terrariumpi.log ${LOGFILE}" -s /bin/bash ${SCRIPT_USER}
fi

if ! [ -h "${ACCESSLOGFILE}" ]; then
Expand All @@ -236,7 +236,7 @@ if grep -qs "${TMPFS} " /proc/mounts; then
# There is an existing logfile already. Move it
mv ${ACCESSLOGFILE} ${TMPFS}
fi
ln -s "${TMPFS}/terrariumpi.access.log" "${ACCESSLOGFILE}"
su -c "ln -s ${TMPFS}/terrariumpi.access.log ${ACCESSLOGFILE}" -s /bin/bash ${SCRIPT_USER}
fi
fi

Expand Down
Binary file modified locales/en_US/LC_MESSAGES/terrariumpi.mo
Binary file not shown.
1,202 changes: 577 additions & 625 deletions locales/en_US/LC_MESSAGES/terrariumpi.po

Large diffs are not rendered by default.

1,098 changes: 525 additions & 573 deletions locales/terrariumpi.pot

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion logging.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ formatter=webFormatter
args=('log/terrariumpi.access.log','midnight',1,30)

[formatter_simpleFormatter]
format=%(asctime)s - %(levelname)-7s - %(module)-18s - %(message)s
format=%(asctime)s - %(levelname)-7s - %(module)-20s - %(message)s
datefmt=

[formatter_webFormatter]
Expand Down
11 changes: 10 additions & 1 deletion static/css/terrariumpi.css
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,16 @@ div#dashboard div.row.environment small span:first-child {
}

div#dashboard div.row.environment table.tile_info td:first-child {
width: 70%;
width: 55%;
}

div#dashboard div.row.environment table.tile_info td span.day i.fa,
div#dashboard div.row.environment table.tile_info td span.night i.fa {
font-size: 0.8em;
float:none;
margin-right: 0px;
width: auto;
line-height: auto;
}

/* End Dashboard */
Expand Down
86 changes: 58 additions & 28 deletions static/js/terrariumpi.js
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,12 @@ function websocket_init(reconnect) {
break;

case 'environment':
$.each(['heater','sprayer','light','cooler','watertank','moisture','ph','light'], function(index, value) {
update_dashboard_environment(value, data.data[value]);
var dashboard = $('div.row.environment div.pull-right div.x_content');
$.each(data.data, function(key, value) {
update_dashboard_environment(key, value);
if ('disabled' == value.config.mode) {
dashboard.find('div.row.environment_' + key).detach().appendTo(dashboard);
}
});
break;
case 'sensor_gauge':
Expand Down Expand Up @@ -636,7 +640,6 @@ function init_form_settings(pType) {
});
break;
}

}

function check_form_data(form) {
Expand Down Expand Up @@ -679,7 +682,7 @@ function process_form() {
function prepare_form_data(form) {
var formdata = [];
var form_type = form.attr('action').split('/').pop();
var re = /(sensor|switch|webcam|light|sprayer|watertank|moisture|heater|cooler|ph|door|profile|playlist)(_\d+)?_(.*)/i;
var re = /(sensor|switch|webcam|light|humidity|temperature|watertank|moisture|conductivity|ph|door|profile|playlist)(_\d+)?_(.*)/i;
var matches = null;
var objectdata = {};
var prev_nr = -1;
Expand All @@ -702,6 +705,7 @@ function prepare_form_data(form) {
break;
case 'sensors':
case 'switches':
case 'powerswitches':
case 'environment':
case 'webcams':
case 'doors':
Expand Down Expand Up @@ -730,7 +734,7 @@ function prepare_form_data(form) {
prev_nr = current_nr;
}

if (['timer_start','timer_stop','start','stop','on','off'].indexOf(matches[3]) != -1) {
if (matches[3].match(/timer_(start|stop)$/)) {
// Load from local format, and store in 24h format. Do not use UNIX timestamp formats
field_value = moment(field_value, 'LT').format('HH:mm');
}
Expand All @@ -757,6 +761,21 @@ function prepare_form_data(form) {
}
/* General functions - End form functions */

function flatten (obj) {
var newObj = {};
for (var key in obj) {
if (obj[key] !== null && obj[key].constructor === Object) {
var temp = flatten(obj[key])
for (var key2 in temp) {
newObj[key+"_"+key2] = temp[key2];
}
} else {
newObj[key] = obj[key];
}
}
return newObj;
}

/* General functions - System functions */
function online_updater() {
clearTimeout(globals.online_timer);
Expand Down Expand Up @@ -1095,7 +1114,6 @@ function history_graph(name, data, type) {
break;

case 'humidity':
case 'sprayer':
case 'average_humidity':
case 'moisture':
val = formatNumber(val) + ' %';
Expand Down Expand Up @@ -1134,7 +1152,6 @@ function history_graph(name, data, type) {
};

switch (type) {
case 'sprayer':
case 'humidity':
case 'temperature':
case 'distance':
Expand Down Expand Up @@ -1521,26 +1538,35 @@ function update_dashboard_environment(name, data) {
if (data === undefined) {
return false;
}

var systempart = $('div.environment_' + name);
if (!data.enabled) {
systempart.find('h4').removeClass('orange blue red').addClass('');
systempart.find('h4 small span').hide().filter('.disabled').show();
systempart.find('table').toggle(false);
setContentHeight();
return false;
}

var enabledColor = '';
var indicator = globals.temperature_indicator;
switch (name) {
case 'light':
enabledColor = 'orange';
break;
case 'heater':
break
case 'conductivity':
enabledColor = 'orange';
indicator = 'mS';
break
case 'temperature':
enabledColor = 'red';
break;
case 'sprayer':
case 'humidity':
case 'moisture':
indicator = '%';
enabledColor = 'blue';
break;
case 'watertank':
indicator = 'L';
case 'cooler':
enabledColor = 'blue';
break;
case 'ph':
Expand All @@ -1549,16 +1575,17 @@ function update_dashboard_environment(name, data) {
}

systempart.find('h4').removeClass('orange blue red').addClass(data.enabled ? enabledColor : '');
systempart.find('h4 small span').hide().filter('.' + (data.enabled ? data.mode : 'disabled')).show();
if (data.sensors !== undefined && data.sensors.length > 0) {
systempart.find('h4 small span').hide().filter('.' + data.config.mode).show();

if (data.config.sensors !== undefined && data.config.sensors.length > 0) {
systempart.find('h4 small span.sensor').show();
}

$.each(data, function(key, value) {
switch (key) {
case 'state':
// Find all i elements withing the .state table row. Hide them all, then filter the enabled one and show that. Then go up and show the complete state table row... Nice!
systempart.find('.state i').hide().filter('.' + (value == 'on' ? 'green' : 'red')).show().parent().parent().toggle(data.enabled && data.power_switches.length > 0);
systempart.find('.state i').hide().filter('.' + (value ? 'green' : 'red')).show().parent().parent().toggle(true);
break;

case 'alarm':
Expand All @@ -1569,30 +1596,33 @@ function update_dashboard_environment(name, data) {
systempart.find('span.glyphicon-exclamation-sign').toggle(value);
break;

case 'on':
case 'off':
systempart.find('.' + key).text(moment(value,'HH:mm').format('LT')).parent().toggle(data.mode != 'sensor');
systempart.find('.duration').text(moment.duration(data.duration * 1000).humanize()).parent().toggle(data.mode != 'sensor');
break;

case 'current':
systempart.find('.' + key).text(formatNumber(value,3) + ' ' + indicator).parent().toggle(data.mode === 'sensor' || data.sensors.length > 0);
systempart.find('.' + key).text(formatNumber(value,3) + ' ' + indicator).parent().toggle(data.config.mode === 'sensor' || data.config.sensors.length > 0);
break;

case 'alarm_min':
case 'alarm_max':
if (['heater','cooler'].indexOf(name) != -1) {
systempart.find('.' + key).text(formatNumber(data.alarm_min,1) + ' - ' + formatNumber(data.alarm_max,1) + ' ' + indicator).parent().toggle(data.mode === 'sensor' || data.sensors.length > 0);
} else {
systempart.find('.' + key).text(formatNumber(value,3) + ' ' + indicator).parent().toggle(data.mode === 'sensor' || data.sensors.length > 0);
systempart.find('.' + key).text(formatNumber(data.alarm_min,1) + ' - ' + formatNumber(data.alarm_max,1) + ' ' + indicator).parent().toggle(data.config.mode === 'sensor' || data.config.sensors.length > 0);
break;

case 'is_night':
if (data.config.day_night_difference > 0) {
systempart.find('.day_night_difference').text(formatNumber(data.config.day_night_difference,3) + ' ' + indicator).parent().toggle(data.config.day_night_difference != 0);
}
systempart.find('span.day, span.night').hide();
systempart.find('span.' + (value ? 'night' : 'day')).show();
break;

case 'night_difference':
systempart.find('.' + key).text(formatNumber(value,3) + ' ' + indicator).parent().toggle(data.night_difference != 0);
case 'timer_min':
case 'timer_max':
if (value.time_table != undefined && ('timer_min' == key && data.config.alarm_min.powerswitches.length > 0 || 'timer_max' == key && data.config.alarm_max.powerswitches.length > 0 )) {
systempart.find('.' + key).text(moment(value.time_table[0][0] * 1000).format('LT') + ' - ' + moment(value.time_table[value.time_table.length-1][1] * 1000).format('LT')).parent().toggle(data.config.mode != 'sensor');
systempart.find('.' + key + '.duration').text(moment.duration(value.duration * 1000).humanize()).parent().toggle(data.config.mode != 'sensor');
}
break;
}
});

systempart.find('table').toggle(data.enabled);
setContentHeight();
}
Expand Down
1 change: 1 addition & 0 deletions terrariumCollector.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ def __upgrade(self,to_version):
if 'duplicate column name' not in str(ex):
logger.error('Error updating collector database. Please contact support. Error message: %s' % (ex,))

logger.info('Cleaning up disk space. This will take a couple of minutes depending on the database size and sd card disk speed.')
cur.execute('VACUUM')
cur.execute('PRAGMA user_version = ' + str(to_version))
logger.info('Updated collector database. Set version to: %s' % (to_version,))
Expand Down
Loading

0 comments on commit c1367e4

Please sign in to comment.