changeset 1309:b54164bcded3

rm old code to read a shaft encoder on an rpi, and a simple thermostat service that switches a house heater on Ignore-this: b199393215c152f5daf5f0c781387d51 darcs-hash:3e25f2056470b710fb1cf5bfc34f585914469d56
author drewp <drewp@bigasterisk.com>
date Sun, 21 Apr 2019 03:18:45 -0700
parents 68c04c74db71
children 68e172d9791e
files service/thermostat/rpi_buttons.py service/thermostat/thermostat.py
diffstat 2 files changed, 0 insertions(+), 218 deletions(-) [+]
line wrap: on
line diff
--- a/service/thermostat/rpi_buttons.py	Sun Apr 21 03:14:14 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-#!/usr/bin/python3
-"""
-read button and knob on rpi, send back to thermostat program
-"""
-from RPi.GPIO import setmode, PUD_UP, setup, BCM, IN, input as pinInput
-import time, json
-# using a copy of urllib/request.py from py3.3 which supports 'method'
-from request import urlopen, Request
-
-requestedTemperature = 'http://bang.bigasterisk.com:10001/requestedTemperature'
-requestOpts = dict(headers={'user-agent': 'rpi buttons'})
-
-def getRequestedTemp():
-    return (json.loads(urlopen(
-        Request(requestedTemperature, **requestOpts)).read().decode('utf-8'))
-    )['tempF']
-
-def setRequestedTemp(f):
-    urlopen(Request(url=requestedTemperature,
-            method='PUT',
-            data=json.dumps({'tempF' : f}).encode('utf-8'),
-            **requestOpts))
-
-PIN_KNOB_A = 1
-PIN_KNOB_B = 4
-PIN_BUTTON = 0
-
-setmode(BCM)
-setup(PIN_KNOB_A, IN, PUD_UP)
-setup(PIN_KNOB_B, IN, PUD_UP)
-setup(PIN_BUTTON, IN, PUD_UP)
-
-print("reading knob and button, writing to %s" % requestedTemperature)
-prev = None
-prevButton = 0
-buttonHold = 0
-step = .02
-while True:
-    a, b = pinInput(PIN_KNOB_A), pinInput(PIN_KNOB_B)
-    button = not pinInput(PIN_BUTTON)
-    pos = (b * 2) + (a ^ b)
-
-    if prev is None:
-        prev = pos
-    dpos = (pos - prev) % 4
-
-    if dpos == 1:
-        print ("up")
-        setRequestedTemp(getRequestedTemp() + 1)
-    elif dpos == -1 % 4:
-        print ("down")
-        setRequestedTemp(getRequestedTemp() - 1)
-    else:
-        pass # 0 or unknown
-    prev = pos
-    
-    if button:
-        buttonHold += 1
-        if buttonHold == int(.1 / step):
-            print ("button to", button)
-    else:
-        buttonHold = 0
-
-    time.sleep(step)
--- a/service/thermostat/thermostat.py	Sun Apr 21 03:14:14 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +0,0 @@
-from __future__ import division
-"""
-drives the heater output pin according to a requested temperature that you can edit. The temp is stored in mongodb.
-"""
-import cyclone.web, sys, urllib, time, pymongo, json, datetime
-from dateutil.tz import tzlocal
-from cyclone.httpclient import fetch
-from twisted.internet import reactor
-from twisted.internet.defer import inlineCallbacks, returnValue
-from twisted.internet.task import LoopingCall
-sys.path.append("/my/proj/homeauto/lib")
-from cycloneerr import PrettyErrorHandler
-from logsetup import log
-
-db = pymongo.Connection("bang")['thermostat']
-
-@inlineCallbacks
-def http(method, url, body=None):
-    resp = (yield fetch(url, method=method, postdata=body,
-                        headers={'user-agent': ['thermostat.py']}))
-    if resp.code != 200:
-        raise ValueError("%s returned %s: %s" % (url, resp.code, resp.body))
-    returnValue(resp.body)
-
-class Unknown(object):
-    pass
-    
-class Therm(object):
-    def __init__(self):
-        self._lastOn = Unknown
-        self._lastOff = time.time() - 1000
-
-        # the non-logging path
-        self.graphite = 'http://bang:9037/render' 
-        
-        # get this from devices.n3
-        self.heaterPin = 'http://bang:9056/pin/d4'
-
-    def getRequest(self):
-        return (db['request'].find_one(sort=[('t', -1)]) or
-                {'tempF':60}
-               )['tempF']
-    
-    def setRequest(self, f):
-        db['request'].insert({'tempF': f, 't':datetime.datetime.now(tzlocal())})
-        self.step()
-        http('POST', 'http://bang:9102/refreshTemperature')
-        # magma might also like to know
-        
-    @inlineCallbacks
-    def step(self):
-        roomF = yield self.getRoomTempF()
-        requestedF = self.getRequest()
-        active = yield self.active()
-        # bug here where, if something else turned off the heater, we
-        # don't count minsOff right
-        minsOff = self.minutesSinceOff()
-        minsOn = self.minutesSinceOn()
-
-        log.info("roomF=%(roomF)s requestedF=%(requestedF)s active=%(active)s "
-                 "minsOn=%(minsOn)s minsOff=%(minsOff)s" % vars())
-        if not active:
-            if roomF < requestedF - 1:
-                if minsOff > 5:
-                    log.info("start heater")
-                    self.startCycle()
-                else:
-                    log.info("wait to start")
-            else:
-                pass
-        else:
-            if roomF > requestedF + 1:
-                log.info("stop heater")
-                self.stopCycle()
-            elif minsOn > 50:
-                log.info("heater on too long- stopping")
-                self.stopCycle()
-            else:
-                log.info("ok to keep warming")
-
-    @inlineCallbacks
-    def getRoomTempF(self):
-        target = 'system.house.temp.livingRoom'
-        body = (yield http('GET', self.graphite + '?' +
-                           urllib.urlencode({
-                               'target':"keepLastValue(%s)" % target,
-                               'rawData':'true',
-                               'from':'-60minutes',
-                           })))
-        latest = float(body.split(',')[-1])
-        returnValue(latest)
-
-    @inlineCallbacks
-    def active(self):
-        ret = yield http('GET', self.heaterPin)
-        returnValue(bool(int(ret.strip())))
-
-    @inlineCallbacks
-    def stopCycle(self):
-        log.info("heater off")
-        # need to make it be an output!
-        yield http('PUT', self.heaterPin, body='0')
-        self._lastOff = time.time()
-
-    @inlineCallbacks
-    def startCycle(self):
-        log.info("heater on")
-        yield http('PUT', self.heaterPin, body='1')
-        self._lastOn = time.time()
-        
-    def minutesSinceOff(self):
-        if self._lastOff is Unknown:
-            self._lastOff = time.time()
-            return 0
-        return (time.time() - self._lastOff) / 60
-
-    def minutesSinceOn(self):
-        if self._lastOn is Unknown:
-            self._lastOn = time.time()
-            return 0
-        return (time.time() - self._lastOn) / 60
-        
-
-class Index(PrettyErrorHandler, cyclone.web.RequestHandler):
-    def get(self):
-        self.write("thermostat. requested temp is %s." %
-                   self.settings.therm.getRequest())
-
-class RequestedTemperature(PrettyErrorHandler, cyclone.web.RequestHandler):
-    def get(self):
-        self.write(json.dumps({"tempF" : self.settings.therm.getRequest()}))
-    def put(self):
-        f = json.loads(self.request.body)['tempF']
-        if not isinstance(f, (int, float)):
-            raise TypeError("tempF was %r" % f)
-        self.settings.therm.setRequest(f)
-        self.write("ok")
-        
-if __name__ == '__main__':
-    t = Therm()
-    def step():
-        try:
-            t.step()
-        except Exception, e:
-            log.warn(e)
-            
-    LoopingCall(step).start(interval=30)
-    
-    reactor.listenTCP(10001, cyclone.web.Application([
-        (r'/', Index),
-        (r'/requestedTemperature', RequestedTemperature),
-        ], therm=t))
-    
-    reactor.run()