Hi, Paul Alfille: > What I'd like to find is something that the system clock and kick > off every second, whether polling happens then, or not. I've never used > interrupt-driven Unix programming, and my C experience was in 1989. Do > you have any resources you point to folks like me, with this situation? > Umm, no. You want that thing to wake up when polling should happen. That's about once per minute, I'd say. Plus you need to add in the time the actual reading of values takes, since the bus is unusable during that time. :-(
I'll just append the script I currently use to deal with pulling nice little numbers out of my hat ^w^w the 1-wire bus. I just store them in an ugly bunch of scary RRD arrays. That gets me long-term aggregation as well as nice little graphs to show off. The code is butt ugly at the moment, but since my bus is really stable I don't worry about what'll happen if it breaks. Check out http://smurf.noris.de/haus/ for the resulting pretty images. #!/usr/bin/python # -*- coding: utf-8 -*- #build the RRDs with something like: # rrdtool create light.front.rrd --step 60 DS:light:GAUGE:60:0:5 RRA:AVERAGE:0.9:1:2880 RRA:MIN:0.9:60:1440 RRA:MAX:0.9:60:1440 RRA:AVERAGE:0.9:60:1440 RRA:MIN:0.9:1440:1000 RRA:MAX:0.9:1440:1000 RRA:AVERAGE:0.9:1440:1000 # Adjust as preferred. (Most important: "0:5" is the min and max value.) import ow import time import rrdtool ow.init("localhost:4304") sensors = {} rrd_info={} def get_address(sensor): r = sensor.address return r[2:-2] class Sensor(object): def __init__(self,real,attr=None): super(Sensor,self).__init__() self.real = real if attr is not None: self.attr = attr if self.real.address not in sensors: sensors[self.addr] = self self.found() def __repr__(self): return "<%s:%s:%s>" % (self.__class__.__name__,self.addr,self.real.type) def _get_addr(self): return get_address(self.real) addr = property(_get_addr) def _get_value(self): """will break if self.attr is not set""" return getattr(self.real,self.attr) value = property(_get_value) def found(self): """Called if this sensor is new on the bus""" pass def poll(self): """Called periodically""" pass def gone(self): """Called if this sensor has vanished from the bus""" pass class RRDSensor(Sensor): def found(self): """Called if this sensor is new on the bus""" try: what,where,attr = rrd_info[self.addr] except KeyError: self.attr = None else: self.what = what self.where = where self.attr = attr def poll(self): if self.attr is not None: v = float(self.value) #print self.what, self.where,v rrdtool.update("/var/lib/homevent/rrd/%s.%s.rrd" % (self.what,self.where), "-t",self.what,"N:"+str(float(v))) class RRDSensor2(RRDSensor): # This is a two-step voltage sensor, necessary since the range of the # photoresistor I use for daylight sensing is too high for accurate # readings in low *and* bright light. Quick schematic: # +5V <-> photoresistor <-> pin D <-> 2.2k <-> pin A <-> 47k <-> gnd # which means that by pulling pin A low I can change the range of # resistance that can be read with a sufficient level of accurracy. # (I originally used pin B, but that had a hardware failure.) # The graph looks sensible enough, so I just use the voltage offset # instead of bothering to calcualte the actual resistance value. # (The switchover point is the resistance where both voltages, i.e. # with and without pulling to GND, change at the same rate.) def found(self): what,where,attr = rrd_info[self.addr] self.what = what self.where = where self.attr = "volt_D" self.pio = 1 self.real.PIO_A = "1" def _get_value(self): v = float(getattr(self.real,self.attr)) if self.pio: if v > 4.2: self.pio = 0 self.real.PIO_A = "0" vn = float(getattr(self.real,self.attr)) print "v",self.pio,v,vn v=vn else: if v < 0.95: self.pio = 1 self.real.PIO_A = "1" vn = float(getattr(self.real,self.attr)) print "v",self.pio,v,vn v=vn if self.pio: d = 0 else: d = 4.2-0.95 v = (v+d)*5/(5+4.2-0.95) print v return v value = property(_get_value) def enum(s): for sx in s.sensors(): yield sx for sy in enum(sx): yield sy # 65AD39010800 temp backyard temperature : beside the one for the heating def read_rrd_params(path): old_rrd_info = rrd_info.copy() for l in open("/etc/homevent/1wire.rrd.cf"): try: id,what,where,attr,_ = l.split(None,4) except ValueError: pass else: try: del old_rrd_info[id] except KeyError: pass if what != "-": rrd_info[id] = (what,where,attr) for r in old_rrd_info.iterkeys(): del rrd_info[r] def re_enum_bus(): old_sensors = sensors.copy() for s in enum(ow.Sensor("/uncached")): addr = get_address(s) try: del old_sensors[addr] except KeyError: pass if addr not in rrd_info: Sensor(s) elif rrd_info[addr][2] == "thr_vorne": RRDSensor2(s) else: RRDSensor(s) for addr,s in old_sensors.iteritems(): del sensors[addr] s.gone() read_rrd_params("/etc/homevent/1wire.rrd.cf") re_enum_bus() while True: for s in sensors.itervalues(): s.poll() time.sleep(10) -- Matthias Urlichs | {M:U} IT Design @ m-u-it.de | [EMAIL PROTECTED] Disclaimer: The quote was selected randomly. Really. | http://smurf.noris.de - - BOFH excuse #38: secretary plugged hairdryer into UPS ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ Owfs-developers mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/owfs-developers
