Advertisement
Guest User

Untitled

a guest
Jan 25th, 2012
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.10 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. # pfh 6/15/09
  4. # Starting from http://itamarst.org/writings/etech04/twisted_internet-22.html
  5. # Goal: Listen to arduino, save data in engineering units, to CSV, also present
  6. # in twisted.web or similar. Socket server?
  7. #
  8. # Design: For now, have arduino send raw ADC counts over and we'll do the
  9. # calibration - seems smarter. I can then use config file parser to move
  10. # all the constants into a config file.
  11. #
  12. # I really want something like rrdtool-based graphs with different timescales.
  13. # Maybe graphite?
  14. # http://somic.org/2009/05/21/graphite-rabbitmq-integration/
  15. # Or even AMQP for fun?
  16. # Serial code from http://twistedmatrix.com/projects/core/documentation/examples/gpsfix.py
  17.  
  18. from twisted.internet import win32eventreactor
  19. win32eventreactor.install()
  20.  
  21. from twisted.protocols.basic import LineReceiver
  22.  
  23. from twisted.internet import reactor
  24. from twisted.internet.serialport import SerialPort
  25. from twisted.web import server, resource, client
  26.  
  27. from twisted.python import usage
  28. from twisted.python import log
  29. import sys
  30. import time
  31.  
  32. ## import stuff from Autobahn
  33. ##
  34. from autobahn.websocket import listenWS
  35. from autobahn.wamp import WampServerFactory, WampServerProtocol
  36.  
  37. print "using Twisted reactor", reactor.__class__
  38. print
  39.  
  40.  
  41. ## WS-MCU protocol
  42. ##
  43. class WsMcuProtocol(WampServerProtocol):
  44.  
  45.     def onSessionOpen(self):
  46.         ## register topic under which we will publish MCU measurements
  47.         ##
  48.         self.registerForPubSub("http://example.com/mcu#", True)
  49.  
  50.  
  51. ## WS-MCU factory
  52. ##
  53. class WsMcuFactory(WampServerFactory):
  54.  
  55.     protocol = WsMcuProtocol
  56.  
  57.     def pubKeepAlive(self):
  58.         self.keepAlive += 1
  59.         self._dispatchEvent("http://example.com/mcu#keepalive", self.keepAlive)
  60.         reactor.callLater(1, self.pubKeepAlive)
  61.  
  62.     def startFactory(self):
  63.         WampServerFactory.startFactory(self)
  64.         self.keepAlive = 0
  65.         self.pubKeepAlive()
  66.  
  67.  
  68. lastTemp = 0.0
  69. lastRH = 0.0
  70. lastTimestamp = 0
  71.  
  72. class THOptions(usage.Options):
  73.     optParameters = [
  74.         ['baudrate', 'b', 9600, 'Serial baudrate'],
  75.         ['port', 'p', 3, 'Serial port to use'],
  76.         ]
  77.  
  78. class indexPage(resource.Resource):
  79.     isLeaf = True
  80.  
  81.     def render_GET(self, request):
  82.         ccStr = ' Temp:%f Humidity:%f\n' % (lastTemp, lastRH)
  83.         return ccStr
  84.  
  85. class Echo(LineReceiver):
  86.  
  87.     ## need a reference to our WS-MCU gateway factory to dispatch PubSub events
  88.     ##
  89.     def __init__(self, wsMcuFactory):
  90.         self.wsMcuFactory = wsMcuFactory
  91.  
  92.     def processData(self, data):
  93.         """Convert raw ADC counts into SI units as per datasheets"""
  94.         # Skip bad reads
  95.         if len(data) != 2:
  96.             return
  97.  
  98.         global lastTemp, lastRH, lastTimestamp
  99.  
  100.         tempCts = int(data[0])
  101.         rhCts = int(data[1])
  102.  
  103.         rhVolts = rhCts * 0.0048828125
  104.         # 10mV/degree, 1024 count/5V
  105.         temp = tempCts * 0.48828125
  106.         # RH temp correction is -0.7% per deg C
  107.         rhcf = (-0.7 * (temp - 25.0)) / 100.0
  108.  
  109.         # Uncorrected humidity
  110.         humidity = (rhVolts * 45.25) - 42.76
  111.  
  112.         # Add correction factor
  113.         humidity = humidity + (rhcf * humidity)
  114.  
  115.  
  116.         lastTemp = tempCts
  117.         lastRH = rhCts
  118.         #lastTemp = temp
  119.         #lastRH = humidity
  120.         # Update screen now and then
  121.         if (time.time() - lastTimestamp) > 20.0:
  122.  
  123.             ## dispatch Temp/Humidity as a PubSub event to all clients subscribed to
  124.             ## topic http://example.com/mcu#measure1
  125.             ##
  126.             self.wsMcuFactory._dispatchEvent("http://example.com/mcu#measure1", (temp, humidity))
  127.  
  128.             log.msg('Temp: %f C Relative humidity: %f %%' % (temp, humidity))
  129.             log.msg('Temp: %f counts: %d RH: %f counts: %d volts: %f' % (temp, tempCts, humidity, rhCts, rhVolts))
  130.             lastTimestamp = time.time()
  131.  
  132.         return temp, humidity
  133.  
  134.     def connectionMade(self):
  135.         log.msg('Serial connection made!')
  136.  
  137.     def lineReceived(self, line):
  138.         try:
  139.             data = line.split()
  140.             log.msg(data)
  141.             self.processData(data)
  142.         except ValueError:
  143.             log.err('Unable to parse data %s' % line)
  144.             return
  145.  
  146. if __name__ == '__main__':
  147.  
  148.     log.startLogging(sys.stdout)
  149.  
  150.     ## create MCU-WS gateway factory/protocol
  151.     ##
  152.     wsMcuFactory = WsMcuFactory("ws://localhost:9000", debug = False, debugCodePaths = False, debugWamp = True)
  153.     listenWS(wsMcuFactory)
  154.  
  155.     o = THOptions()
  156.     try:
  157.         o.parseOptions()
  158.     except usage.UsageError, errortext:
  159.         log.err('%s %s' % (sys.argv[0], errortext))
  160.         log.msg('Try %s --help for usage details' % sys.argv[0])
  161.         raise SystemExit, 1
  162.  
  163.     if o.opts['baudrate']:
  164.         baudrate = int(o.opts['baudrate'])
  165.  
  166.     port = o.opts['port']
  167.  
  168.     log.msg('About to open port %s' % port)
  169.     s = SerialPort(Echo(wsMcuFactory), port, reactor, baudrate=baudrate)
  170.  
  171.     # HTTP interface
  172.     log.msg('Setting up webserver on http://localhost:2000/')
  173.     root = indexPage()
  174.     site = server.Site(root)
  175.     reactor.listenTCP(2000, site)
  176.  
  177.     reactor.run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement