Mercurial > code > home > repos > homeauto
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__): |