--- /dev/null
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015 Andrey Koryagin
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+import smbus
+import time
+
+# BME280 default address.
+BME280_I2CADDR = 0x76
+
+# BME280 Registers
+BME280_CONTROL_MEAS = 0xF4
+BME280_CONTROL_HUM = 0xF2
+
+BME280_CONFIG = 0xF5
+BME280_PRESSURE = 0xF7
+BME280_TEMP = 0xFA
+BME280_HUMIDITY = 0xFD
+
+BME280_DIG_T1 = 0x88
+BME280_DIG_T2 = 0x8A
+BME280_DIG_T3 = 0x8C
+BME280_DIG_P1 = 0x8E
+BME280_DIG_P2 = 0x90
+BME280_DIG_P3 = 0x92
+BME280_DIG_P4 = 0x94
+BME280_DIG_P5 = 0x96
+BME280_DIG_P6 = 0x98
+BME280_DIG_P7 = 0x9A
+BME280_DIG_P8 = 0x9C
+BME280_DIG_P9 = 0x9E
+BME280_DIG_H1 = 0xA1
+BME280_DIG_H2 = 0xE1
+BME280_DIG_H3 = 0xE3
+BME280_DIG_H4 = 0xE4
+BME280_DIG_H5 = 0xE5
+BME280_DIG_H6 = 0xE7
+
+# Oversampling Setting
+BME280_OVERS_T1 = 0x20
+BME280_OVERS_T2 = 0x40
+BME280_OVERS_T4 = 0x60
+BME280_OVERS_T8 = 0x80
+BME280_OVERS_T16 = 0xA0
+
+BME280_OVERS_P1 = 0x04
+BME280_OVERS_P2 = 0x08
+BME280_OVERS_P4 = 0x0C
+BME280_OVERS_P8 = 0x10
+BME280_OVERS_P16 = 0x14
+
+BME280_OVERS_H1 = 0x01
+BME280_OVERS_H2 = 0x02
+BME280_OVERS_H4 = 0x03
+BME280_OVERS_H8 = 0x04
+BME280_OVERS_H16 = 0x05
+
+# Power Modes.
+# This lib uses NORMAL mode only!
+#BME280_SLEEP_MODE = 0x00
+#BME280_FORCED_MODE = 0x01
+BME280_NORMAL_MODE = 0x03
+
+BME280_TSB_0_5 = 0x00
+BME280_TSB_62_5 = 0x20
+BME280_TSB_125 = 0x40
+BME280_TSB_250 = 0x60
+BME280_TSB_500 = 0x80
+BME280_TSB_1000 = 0xA0
+BME280_TSB_2000 = 0xC0
+BME280_TSB_4000 = 0xE0
+
+BME280_FILTER_OFF = 0x00
+BME280_FILTER_COEFFICIENT2 = 0x04
+BME280_FILTER_COEFFICIENT4 = 0x08
+BME280_FILTER_COEFFICIENT8 = 0x0C
+BME280_FILTER_COEFFICIENT16 = 0x10
+
+BME280_SPI_OFF = 0x00
+BME280_SPI_ON = 0x01
+
+BME280_CONTROL_MEAS_SET = (BME280_OVERS_T16 | BME280_OVERS_P16 | BME280_NORMAL_MODE)
+BME280_CONTROL_HUM_SET = BME280_OVERS_H2
+BME280_CONFIG_SET = (BME280_TSB_0_5 | BME280_FILTER_COEFFICIENT16 | BME280_SPI_OFF)
+
+class BME280(object):
+ def __init__(self, port=1, address=BME280_I2CADDR):
+ self.bus = smbus.SMBus(port)
+ self.address = address
+
+ # Read calibration values
+ self.dig_t1 = self.read_word(BME280_DIG_T1) # Unsigned
+ self.dig_t2 = self.read_word_sign(BME280_DIG_T2)
+ self.dig_t3 = self.read_word_sign(BME280_DIG_T3)
+ self.dig_p1 = self.read_word(BME280_DIG_P1) # Unsigned
+ self.dig_p2 = self.read_word_sign(BME280_DIG_P2)
+ self.dig_p3 = self.read_word_sign(BME280_DIG_P3)
+ self.dig_p4 = self.read_word_sign(BME280_DIG_P4)
+ self.dig_p5 = self.read_word_sign(BME280_DIG_P5)
+ self.dig_p6 = self.read_word_sign(BME280_DIG_P6)
+ self.dig_p7 = self.read_word_sign(BME280_DIG_P7)
+ self.dig_p8 = self.read_word_sign(BME280_DIG_P8)
+ self.dig_p9 = self.read_word_sign(BME280_DIG_P9)
+
+ self.dig_h1 = self.read_byte(BME280_DIG_H1) # unsigned char
+ self.dig_h2 = self.read_word_sign(BME280_DIG_H2)
+ self.dig_h3 = self.read_byte(BME280_DIG_H3) # unsigned char
+
+ self.dig_h4 = (self.read_byte(BME280_DIG_H4) << 24) >> 20
+ self.dig_h4 = self.dig_h4 | self.read_byte(BME280_DIG_H4+1) & 0x0F
+
+ self.dig_h5 = (self.read_byte(BME280_DIG_H5+1) << 24) >> 20
+ self.dig_h5 = self.dig_h5 | (self.read_byte(BME280_DIG_H5) >> 4) & 0x0F
+
+ self.dig_h6 = self.read_byte(BME280_DIG_H6) # signed char
+ if self.dig_h6 > 127:
+ self.dig_h6 = 127-self.dig_h6
+
+ # Set Configuration
+ self.write_byte(BME280_CONFIG, BME280_CONFIG_SET)
+ self.write_byte(BME280_CONTROL_HUM, BME280_CONTROL_HUM_SET)
+ self.write_byte(BME280_CONTROL_MEAS, BME280_CONTROL_MEAS_SET)
+
+ def get_data(self):
+ adc_t = self.read_adc_long(BME280_TEMP)
+ adc_p = self.read_adc_long(BME280_PRESSURE)
+ adc_h = self.read_adc_word(BME280_HUMIDITY)
+
+ var1 = (adc_t/16384.0 - self.dig_t1/1024.0) * self.dig_t2;
+ var2 = ((adc_t/131072.0 - self.dig_t1/8192.0) * (adc_t/131072.0 - self.dig_t1/8192.0)) * self.dig_t3;
+ t_fine = (var1 + var2);
+ temperature = round((t_fine / 5120.0), 2);
+
+ var1 = (t_fine/2.0) - 64000.0;
+ var2 = var1 * var1 * self.dig_p6 / 32768.0;
+ var2 = var2 + var1 * self.dig_p5 * 2.0;
+ var2 = (var2/4.0)+(self.dig_p4 * 65536.0);
+ var1 = (self.dig_p3 * var1 * var1 / 524288.0 + self.dig_p2 * var1) / 524288.0;
+ var1 = (1.0 + var1 / 32768.0)*self.dig_p1;
+
+ # Avoid exception caused by division by zero
+ if (var1 == 0.0):
+ return -1
+
+ p = 1048576.0 - adc_p;
+ p = (p - (var2 / 4096.0)) * 6250.0 / var1;
+ var1 = self.dig_p9 * p * p / 2147483648.0;
+ var2 = p * self.dig_p8 / 32768.0;
+ pressure = round((p + (var1 + var2 + self.dig_p7) / 16.0), 2);
+
+ var_H = t_fine - 76800.0
+ var_H = (adc_h-(self.dig_h4*64.0+self.dig_h5 / 16384.0 * var_H))*(self.dig_h2/65536.0 * (1.0 + self.dig_h6/67108864.0 * var_H * (1.0+self.dig_h3/67108864.0 * var_H)))
+ humidity = round(var_H * (1.0 - self.dig_h1*var_H/524288.0), 2)
+ if (humidity > 100.0):
+ humidity = 100.0
+ else:
+ if(humidity < 0.0):
+ humidity = 0.0
+
+ return {'t':temperature, 'p':pressure, 'h':humidity}
+
+ def get_altitude(self, pressure):
+ temp = pressure/101325;
+ temp = 1-pow(temp, 0.19029);
+ altitude = round(44330*temp, 3);
+ return altitude;
+
+ def read_byte(self, adr):
+ return self.bus.read_byte_data(self.address, adr)
+
+ def read_word(self, adr):
+ # ATANTION! Joke from Bosch! LBS before HBS. For calibration registers only!
+ lbs = self.bus.read_byte_data(self.address, adr)
+ hbs = self.bus.read_byte_data(self.address, adr+1)
+ return (hbs << 8) + lbs
+
+ def read_word_sign(self, adr):
+ val = self.read_word(adr)
+ if (val >= 0x8000):
+ return -((65535 - val) + 1)
+ else:
+ return val
+
+ def read_adc_long(self, adr):
+ mbs = self.bus.read_byte_data(self.address, adr)
+ lbs = self.bus.read_byte_data(self.address, adr+1)
+ xbs = self.bus.read_byte_data(self.address, adr+2)
+ val = (mbs << 16) + (lbs << 8) + xbs
+ val = (val >> 4)
+ return val
+
+ def read_adc_word(self, adr):
+ mbs = self.bus.read_byte_data(self.address, adr)
+ lbs = self.bus.read_byte_data(self.address, adr+1)
+ val = (mbs << 8) + lbs
+ return val
+
+ def write_byte(self, adr, byte):
+ self.bus.write_byte_data(self.address, adr, byte)
--- /dev/null
+#!/usr/bin/expect
+
+proc lcdcmd {sid cmd} {
+ send -i ${sid} "${cmd}\n"
+ while { true } {
+ expect {
+ -i ${sid} -re "^[lindex [split "${cmd}"] 0]\[^\n\]*\r\n" {
+ while { true } {
+ expect {
+ -i ${sid} -re "^success\[^\n\]*\n" { return }
+ -i ${sid} -re "^\r\n" { }
+ -i ${sid} -re "^listen .*\n" {}
+ -i ${sid} -re "^ignore .*\n" {}
+ timeout { error "LCD protocol failure while waiting for success?" }
+ }
+ }
+ }
+ -i ${sid} -re "^listen .*\n" {}
+ -i ${sid} -re "^ignore .*\n" {}
+ timeout { error "LCD protocol failure while waiting for echo?" }
+ }
+ }
+}
+
+proc spawnlcd {host port} {
+ spawn socat STDIO "TCP:${host}:${port}"
+ send -i ${spawn_id} "hello\n"
+ expect {
+ -i ${spawn_id} -re "^hello\r\nconnect .*\r\n" { return ${spawn_id} }
+ timeout { error "LCD protocol failure while sending hello?" }
+ }
+}
+
+spawn tail --retry --follow=name /run/snakecontrol/monitor.log/current
+set logsid ${spawn_id}
+
+set sid [spawnlcd "localhost" "13666"]
+lcdcmd ${sid} "client_set -name test"
+
+lcdcmd ${sid} "screen_add 1"
+lcdcmd ${sid} "screen_set 1 -name Vivarium"
+lcdcmd ${sid} "screen_set 1 -priority hidden"
+lcdcmd ${sid} "screen_set 1 -cursor off"
+
+lcdcmd ${sid} "widget_add 1 ti title"
+lcdcmd ${sid} "widget_set 1 ti Vivarium"
+
+lcdcmd ${sid} "widget_add 1 i_up icon"
+lcdcmd ${sid} "widget_set 1 i_up 1 2 ARROW_UP"
+lcdcmd ${sid} "widget_add 1 i_th string"
+lcdcmd ${sid} "widget_set 1 i_th 2 2 T"
+lcdcmd ${sid} "widget_add 1 v_ut string"
+lcdcmd ${sid} "widget_add 1 i_uh string"
+lcdcmd ${sid} "widget_set 1 i_uh 8 2 H"
+lcdcmd ${sid} "widget_add 1 v_uh string"
+
+lcdcmd ${sid} "widget_add 1 i_l icon"
+lcdcmd ${sid} "widget_set 1 i_l 1 3 ARROW_LEFT"
+
+lcdcmd ${sid} "widget_add 1 i_r icon"
+lcdcmd ${sid} "widget_set 1 i_r 1 4 ARROW_RIGHT"
+
+lcdcmd ${sid} "widget_add 1 i_lh icon"
+lcdcmd ${sid} "widget_set 1 i_lh 2 3 ARROW_DOWN"
+lcdcmd ${sid} "widget_add 1 v_lh string"
+
+lcdcmd ${sid} "widget_add 1 i_rh icon"
+lcdcmd ${sid} "widget_set 1 i_rh 2 4 ARROW_DOWN"
+lcdcmd ${sid} "widget_add 1 v_rh string"
+
+lcdcmd ${sid} "widget_add 1 i_lt icon"
+lcdcmd ${sid} "widget_set 1 i_lt 9 3 ARROW_UP"
+lcdcmd ${sid} "widget_add 1 v_lt string"
+
+lcdcmd ${sid} "widget_add 1 i_rt icon"
+lcdcmd ${sid} "widget_set 1 i_rt 9 4 ARROW_UP"
+lcdcmd ${sid} "widget_add 1 v_rt string"
+
+lcdcmd ${sid} "widget_add 1 v_ldmxl string"
+lcdcmd ${sid} "widget_set 1 v_ldmxl 17 3 @"
+lcdcmd ${sid} "widget_add 1 v_ldmx string"
+
+lcdcmd ${sid} "widget_add 1 v_rdmxl string"
+lcdcmd ${sid} "widget_set 1 v_rdmxl 17 4 @"
+lcdcmd ${sid} "widget_add 1 v_rdmx string"
+
+lcdcmd ${sid} "screen_set 1 -priority info"
+
+proc drawtemp { scr wid x y } {
+ global sid
+ global expect_out
+ set t [expr round(${expect_out(1,string)}*10.0)/10.0]
+ lcdcmd ${sid} "widget_set ${scr} ${wid} ${x} ${y} ${t}"
+}
+
+set datapfx "^\[^ \]* DATA: "
+set datare "(\[^ \r\n]*)"
+
+while { true } {
+ expect {
+ -i ${logsid} -re "${datapfx}hide-near.* temp=${datare}.*\n" { drawtemp 1 "v_lh" 4 3 }
+ -i ${logsid} -re "${datapfx}hide-far.* temp=${datare}.*\n" { drawtemp 1 "v_rh" 4 4 }
+ -i ${logsid} -re "${datapfx}tank-near.* temp=${datare}.*\n" { drawtemp 1 "v_lt" 11 3 }
+ -i ${logsid} -re "${datapfx}tank-far.* temp=${datare}.*\n" { drawtemp 1 "v_rt" 11 4 }
+ -i ${logsid} -re "${datapfx}tank-top.* temp=${datare}.*\n" { drawtemp 1 "v_ut" 3 2 }
+ -i ${logsid} -re "${datapfx}tank-top.* humid=${datare}.*\n" { drawtemp 1 "v_uh" 9 2 }
+ -i ${logsid} -re "${datapfx}dmx-near.* dmx=${datare}.*\n" {
+ lcdcmd ${sid} "widget_set 1 v_ldmx 18 3 ${expect_out(1,string)}"
+ }
+ -i ${logsid} -re "${datapfx}dmx-mid.* dmx=${datare}.*\n" {
+ lcdcmd ${sid} "widget_set 1 v_rdmx 18 4 ${expect_out(1,string)}"
+ }
+ -i ${logsid} -re "\n" {}
+ -i ${sid} -re "^listen .*\n" {}
+ -i ${sid} -re "^ignore .*\n" {}
+ }
+}
echo "Content-Type: text/plain"
echo
-exec tail -n 40 /home/pi/sc/data/monitor.log/current
+exec tail -n 40 /run/snakecontrol/monitor.log/current
+++ /dev/null
-#!/usr/bin/python
-
-# Inspired by code found at http://wannabe.guru.org/scott/hobbies/temperature/
-
-import os
-import rrdtool
-import sched
-import time
-
-owdev_logname = {
- "/sys/bus/w1/devices/28-011620c718ee/w1_slave" : "/home/pi/sc/data/hide-far-temp.rrd",
- "/sys/bus/w1/devices/28-011620f10dee/w1_slave" : "/home/pi/sc/data/hide-near-temp.rrd",
- "/sys/bus/w1/devices/28-02161e26acee/w1_slave" : "/home/pi/sc/data/tank-far-temp.rrd",
- "/sys/bus/w1/devices/28-03164712aaff/w1_slave" : "/home/pi/sc/data/heater-temp.rrd",
- "/sys/bus/w1/devices/28-0416526de6ff/w1_slave" : "/home/pi/sc/data/tank-near-temp.rrd",
-}
-
-owdev_thresholds_heater1 = {
- "/sys/bus/w1/devices/28-011620c718ee/w1_slave" : (23.0, 25.0), # hide far
- "/sys/bus/w1/devices/28-02161e26acee/w1_slave" : (21.0, 25.0), # tank air far
- "/sys/bus/w1/devices/28-0416526de6ff/w1_slave" : (23.0, 27.0), # tank air near
-}
-
-# owdev_thresholds_heater2 = {
-# "/sys/bus/w1/devices/28-011620f10dee/w1_slave" : (29.0, 29.5), # hide near
-# }
-
-def nop (*arg, **kwarg):
- pass
-
-def with_ow_temp_fk_id(devfn, x, *arg, **kwarg):
- print("WARNING: failed to read %s" % devfn)
- return x
-
-def with_ow_temp(devfn, sk, fk, *arg, **kwarg):
- with open(devfn) as devf:
- devstr = devf.read()
- devlines = devstr.split("\n")
- if devlines[0].find("YES") > 0:
- return sk(devfn,float((devlines[1].split(" ")[9])[2:]) / 1000, *arg, **kwarg)
- return fk(devfn, *arg, **kwarg)
-
-
-def check_temps(sc):
- print ("check temps init")
- def check(devfn, temp, threshs, desire):
- # Anything too hot: turn off the heater
- if (temp > threshs[devfn][1]): desire = "OFF"
- # No stated preference and something too cold, turn on the heater
- elif (temp <= threshs[devfn][0] and desire == None): desire = "ON"
- return desire
-
- did_interact = False
- desire = None
- for devfn in owdev_thresholds_heater1:
- desire = with_ow_temp(devfn, check, with_ow_temp_fk_id, owdev_thresholds_heater1, desire)
- if desire is not None:
- did_interact = True
- print("Set heater 1 %s" % desire)
- os.system("/home/pi/sc/bin/rpb.expect 4 %s | grep -A 5 -e 'Plug ' | tr -d '\015'" % desire)
-
- # desire = None
- # for devfn in owdev_thresholds_heater2:
- # desire = with_ow_temp(devfn, check, with_ow_temp_fk_id, owdev_thresholds_heater2, desire)
- # if desire is not None:
- # did_interact = True
- # print("Set heater 2 %s" % desire)
- # os.system("/home/pi/sc/bin/rpb.expect 5 %s | grep -A 5 -e 'Plug ' | tr -d '\015'" % desire)
-
- if not did_interact:
- os.system("/home/pi/sc/bin/rpb.expect | grep -A 5 -e 'Plug ' | tr -d '\015'")
-
- sc.enter(300, 1, check_temps, (sc,))
- print ("check temps fini")
-
-def do_log_temp(devfn, temp):
- print("temp log: %s => %f" % (devfn, temp))
- rrdtool.update(owdev_logname[devfn], "N:" + ("%f" % temp))
-
-def read_temps(sc,itime):
- for devfn in owdev_logname: with_ow_temp(devfn, do_log_temp, nop)
- itime = itime + 60
- sc.enterabs(itime, 2, read_temps, (sc,itime))
-
-itime = time.time()
-s = sched.scheduler(time.time, time.sleep)
-s.enterabs(itime, 1, check_temps, (s,))
-s.enterabs(itime, 2, read_temps, (s,itime))
-
-print("Monitor starting...")
-s.run()
def _value (self, error, edeltasmooth) :
- print ("PID LOOP CONTRIBUTIONS: p=%r d=%r i=%r" % (self.kP * error, self.kD * edeltasmooth, self.kI * self.sum_error))
+ # print ("PID LOOP CONTRIBUTIONS: p=%r d=%r i=%r" % (self.kP * error, self.kD * edeltasmooth, self.kI * self.sum_error))
return (self.kP * error) + (self.kD * edeltasmooth) + (self.kI * self.sum_error)
elif self.hard_min is not None and ov <= self.hard_min and sum_error_delta < 0:
# Do not decrement error; we're already slammed up against the hard limit
pass
- else if sum_error_delta != 0:
+ elif sum_error_delta != 0:
# Update sum_error and recompute the output value
self.sum_error += sum_error_delta
ov = self._value(error, edeltasmooth)
import sched
import time
import serial
-import pidloop
import rrdtool
+import pidloop
+import BME280
+
dmxdev = serial.Serial("/dev/serial/by-id/usb-DMXking.com_DMX_USB_PRO_6A0SVM7J-if00-port0", 57600);
loop_hidenear = pidloop.PIDThresh(128,26,28,0,31,33,-128)
loop_hidenear.setKP(60.0)
loop_hidenear.setKI(0.004)
loop_hidenear.setKD(1000.0,0.95)
-loop_hidenear.sum_error = -3000.0 # XXX Initialize offset point a bit
+loop_hidenear.sum_error = -7600.0 # XXX Initialize offset point a bit
+
+bmetop = BME280.BME280(port=1, address=0x77)
-def with_ow_temp_fk_id(devfn, loop, s, *arg, **kwarg):
+def with_ow_temp_fk_id2(devfn, loop, s, *arg, **kwarg):
print("WARNING: failed to read %s" % devfn)
return s # an ugly default
-def with_ow_temp(devfn, sk, fk, *arg, **kwarg):
+def with_ow_temp(cache, devfn, sk, fk, *arg, **kwarg):
+ if devfn in cache :
+ return sk(devfn, cache[devfn], *arg, **kwarg)
with open(devfn) as devf:
devstr = devf.read()
devlines = devstr.split("\n")
if devlines[0].find("YES") > 0:
- return sk(devfn,float((devlines[1].split(" ")[9])[2:]) / 1000, *arg, **kwarg)
+ val = float((devlines[1].split(" ")[9])[2:]) / 1000
+ cache[devfn] = val
+ return sk(devfn, val, *arg, **kwarg)
return fk(devfn, *arg, **kwarg)
def check_temps(sc):
sc.enter(10, 1, check_temps, (sc,))
- def check(devfn, temp, loop, s, offset, rrd):
+ cache = {}
+
+ def log(devfn, temp, logname, rrd, kw="temp"):
+ rrdtool.update(rrd, "N:" + ("%f" % temp))
+ print ("DATA: %s %s=%s" % (logname, kw, temp))
+
+ def logfail(devfn, name, *arg):
+ print ("FAIL: %s %s %s" % (name, devfn, arg))
+
+ # BME280 atop
+ try:
+ top = bmetop.get_data()
+ log("bme280-77", top['t'], "tank-top", "/home/pi/sc/data/tank-top-temp.rrd")
+ log("bme280-77", top['h'], "tank-top", "/home/pi/sc/data/tank-top-humid.rrd", kw="humid")
+ log("bme280-77", top['p'], "tank-top", "/home/pi/sc/data/tank-top-press.rrd", kw="press")
+ except Exception, e:
+ logfail("bme280-77", "hide-top")
+
+ # Log (and populate cache, while we're at it)
+ with_ow_temp(cache,
+ "/sys/bus/w1/devices/28-011620f10dee/w1_slave", log, logfail,
+ "hide-near", "/home/pi/sc/data/hide-near-temp.rrd")
+
+ with_ow_temp(cache,
+ "/sys/bus/w1/devices/28-011620c718ee/w1_slave", log, logfail,
+ "hide-far", "/home/pi/sc/data/hide-far-temp.rrd")
+
+ with_ow_temp(cache,
+ "/sys/bus/w1/devices/28-02161e26acee/w1_slave", log, logfail,
+ "tank-far", "/home/pi/sc/data/tank-far-temp.rrd")
+
+ with_ow_temp(cache,
+ "/sys/bus/w1/devices/28-03164712aaff/w1_slave", log, logfail,
+ "heater-near", "/home/pi/sc/data/heater-temp.rrd")
+
+ with_ow_temp(cache,
+ "/sys/bus/w1/devices/28-0416526de6ff/w1_slave", log, logfail,
+ "tank-near", "/home/pi/sc/data/tank-near-temp.rrd")
+
+
+ def checkpid(devfn, temp, loop, s, offset, rrd, logname):
desire = 128.0 + loop.update(temp, time.time())
if desire < 0 :
loop.output = 255
rrdtool.update(rrd, "N:" + ("%f" % desire))
+ dmx = int(desire+0.5)
+ print("DATA: %s dmx=%s" % (logname, dmx))
- return s[:offset] + chr(int(desire+0.5)) + s[offset+1:]
+ return s[:offset] + chr(dmx) + s[offset+1:]
# DMX conttrol string; initialize to all channels full off
# 7E -- header
s = "\x7E\x06\x03\x00\x00\x00\x00\xE7"
# Drive loop
- s = with_ow_temp("/sys/bus/w1/devices/28-011620f10dee/w1_slave",
- check, with_ow_temp_fk_id, loop_hidenear, s, 5, "/home/pi/sc/data/hide-near-dmx.rrd")
+ s = with_ow_temp(cache, "/sys/bus/w1/devices/28-011620f10dee/w1_slave",
+ checkpid, with_ow_temp_fk_id2, loop_hidenear, s, 5, "/home/pi/sc/data/hide-near-dmx.rrd", "dmx-near")
+
+ # Log some other probes
print ("check temps fini: out=%r lhn=(%s)" % (s, loop_hidenear))
assert(dmxdev.write(s) == 8)
hide-far-temp
tank-near-temp
tank-far-temp
+ tank-top-temp
)
ARGS=(
for rrd in ${=RRDS[@]}; do
rrdtool create /home/pi/sc/data/${rrd}.rrd ${=ARGS[@]}
done
+
+rrdtool create /home/pi/sc/data/tank-top-humid.rrd \
+ --no-overwrite \
+ --step 60 \
+ DS:humid:GAUGE:900:-5:105 \
+ RRA:AVERAGE:0.5:6:525600 \
+ RRA:AVERAGE:0.25:360:87600 \
+ RRA:MIN:0.025:360:87600 \
+ RRA:MAX:0.025:360:87600
+
+
+rrdtool create /home/pi/sc/data/tank-top-press.rrd \
+ --no-overwrite \
+ --step 60 \
+ DS:press:GAUGE:900:-1000:120000 \
+ RRA:AVERAGE:0.5:6:525600 \
+ RRA:AVERAGE:0.25:360:87600 \
+ RRA:MIN:0.025:360:87600 \
+ RRA:MAX:0.025:360:87600
--- /dev/null
+#!/bin/sh
+exec chpst -u pi:pi expect /home/pi/sc/bin/lcdproc.expect >/dev/null
#!/bin/sh
-exec chpst -u pi svlogd -tt /home/pi/sc/data/monitor.log
+mkdir -p /run/snakecontrol/monitor.log
+chown -R pi:pi /run/snakecontrol
+exec chpst -u pi svlogd -tt /run/snakecontrol/monitor.log
#!/bin/sh
-exec chpst -u pi:pi:dialout python -u /home/pi/sc/bin/monitor.py
+exec chpst -u pi:pi:dialout:i2c python -u /home/pi/sc/bin/pidmonitor.py