comparison service/piNode/devices.py @ 407:864c8911ae73

PCA9685 pwm board support on piNode Ignore-this: ce0cf862ebcf7acff271a5ad327e9763
author drewp@bigasterisk.com
date Tue, 12 Mar 2019 00:13:03 -0700
parents 38a74c43639c
children f397ec8bd13d
comparison
equal deleted inserted replaced
406:7a0cb00d5032 407:864c8911ae73
127 return deviceType 127 return deviceType
128 128
129 @register 129 @register
130 class MotionSensorInput(DeviceType): 130 class MotionSensorInput(DeviceType):
131 """ 131 """
132 Triggering all the time? Try 5V VCC, per https://electronics.stackexchange.com/a/416295
133
132 0 30s 60s 90s 10min 134 0 30s 60s 90s 10min
133 | | | | ... | 135 | | | | ... |
134 Sensor input ******** ** ******* **** 136 Sensor input ******** ** ******* ****
135 :sees output ........ .. ....... .... 137 :sees output ........ .. ....... ....
136 :seesRecently ............................................................. 138 :seesRecently .............................................................
256 }] 258 }]
257 259
258 260
259 @register 261 @register
260 class TempHumidSensor(DeviceType): 262 class TempHumidSensor(DeviceType):
263 """
264 AM2302/DHT22 pinout is vcc-data-nc-gnd. VCC to 3.3V. Add 10k pullup on data.
265 """
261 deviceType = ROOM['TempHumidSensor'] 266 deviceType = ROOM['TempHumidSensor']
262 pollPeriod = 5 267 pollPeriod = 5
263 268
264 def __init__(self, *a, **kw): 269 def __init__(self, *a, **kw):
265 DeviceType.__init__(self, *a, **kw) 270 DeviceType.__init__(self, *a, **kw)
359 def __init__(self, *a, **kw): 364 def __init__(self, *a, **kw):
360 DeviceType.__init__(self, *a, **kw) 365 DeviceType.__init__(self, *a, **kw)
361 import w1thermsensor 366 import w1thermsensor
362 log.info("scan for w1 devices") 367 log.info("scan for w1 devices")
363 self.SensorNotReadyError = w1thermsensor.core.SensorNotReadyError 368 self.SensorNotReadyError = w1thermsensor.core.SensorNotReadyError
369 self.ResetValueError = w1thermsensor.core.ResetValueError
364 self._sensors = w1thermsensor.W1ThermSensor.get_available_sensors() 370 self._sensors = w1thermsensor.W1ThermSensor.get_available_sensors()
365 for s in self._sensors: 371 for s in self._sensors:
366 # Something looks different about these ids 372 # Something looks different about these ids
367 # ('000003a5a94c') vs the ones I get from arduino 373 # ('000003a5a94c') vs the ones I get from arduino
368 # ('2813bea50300003d'). Not sure if I'm parsing them 374 # ('2813bea50300003d'). Not sure if I'm parsing them
378 try: 384 try:
379 tempF = sensor.get_temperature(sensor.DEGREES_F) 385 tempF = sensor.get_temperature(sensor.DEGREES_F)
380 stmts.append((sensor.uri, ROOM['temperatureF'], 386 stmts.append((sensor.uri, ROOM['temperatureF'],
381 # see round() note in arduinoNode/devices.py 387 # see round() note in arduinoNode/devices.py
382 Literal(round(tempF, 2)))) 388 Literal(round(tempF, 2))))
383 except self.SensorNotReadyError as e: 389 except (self.SensorNotReadyError, self.ResetValueError) as e:
384 log.warning(e) 390 log.warning(e)
385 391
386 return stmts 392 return stmts
387 except Exception as e: 393 except Exception as e:
388 log.error(e) 394 log.error(e)
610 'element': 'output-rgb', 616 'element': 'output-rgb',
611 'subj': self.uri, 617 'subj': self.uri,
612 'pred': ROOM['color'], 618 'pred': ROOM['color'],
613 }] 619 }]
614 620
621 @register
622 class PwmBoard(DeviceType):
623 """
624 need this in /boot/config.txt
625 dtparam=i2c_arm=on
626 check for devices with
627 apt-get install -y i2c-tools
628 sudo i2cdetect -y 1
629
630 gpio8 = bcm2 = sda1
631 gpio9 = bcm3 = scl1
632 They're next to the 3v3 pin.
633 """
634 deviceType = ROOM['PwmBoard']
635 @classmethod
636 def findInstances(cls, graph, board, pi):
637 for row in graph.query("""SELECT DISTINCT ?dev WHERE {
638 ?board :hasI2cBus ?bus .
639 ?bus :connectedTo ?dev .
640 ?dev a :PwmBoard .
641 }""", initBindings=dict(board=board), initNs={'': ROOM}):
642 outs = {}
643 for out in graph.query("""SELECT DISTINCT ?area ?chan WHERE {
644 ?dev :output [:area ?area; :channel ?chan] .
645 }""", initBindings=dict(dev=row.dev), initNs={'': ROOM}):
646 outs[out.area] = out.chan.toPython()
647 yield cls(graph, row.dev, pi, outs)
648
649 def __init__(self, graph, dev, pi, outs):
650 super(PwmBoard, self).__init__(graph, dev, pi, pinNumber=None)
651 import PCA9685
652 self.pwm = PCA9685.PWM(pi, bus=1, address=0x40)
653 self.pwm.set_frequency(1200)
654 self.outs = outs
655 self.values = {uri: 0 for uri in self.outs.keys()} # uri: brightness
656
657 def hostStatements(self):
658 return [(uri, ROOM['brightness'], Literal(b))
659 for uri, b in self.values.items()]
660
661 def outputPatterns(self):
662 return [(area, ROOM['brightness'], None) for area in self.outs]
663
664 def sendOutput(self, statements):
665 assert len(statements) == 1
666 assert statements[0][1] == ROOM['brightness'];
667 chan = self.outs[statements[0][0]]
668 value = float(statements[0][2])
669 self.values[statements[0][0]] = value
670 self.pwm.set_duty_cycle(chan, value * 100)
671
672 def outputWidgets(self):
673 return [{
674 'element': 'output-slider',
675 'min': 0,
676 'max': 1,
677 'step': 1 / 255,
678 'subj': area,
679 'pred': ROOM['brightness'],
680 } for area in self.outs]
615 681
616 682
617 def makeDevices(graph, board, pi): 683 def makeDevices(graph, board, pi):
618 out = [] 684 out = []
619 for dt in sorted(_knownTypes, key=lambda cls: cls.__name__): 685 for dt in sorted(_knownTypes, key=lambda cls: cls.__name__):