Advertisement
Guest User

Untitled

a guest
Jan 25th, 2012
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.81 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 iocpreactor
  19. #iocpreactor.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. import logging
  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. ## WS-MCU protocol
  41. ##
  42. class WsMcuProtocol(WampServerProtocol):
  43.  
  44.     def onSessionOpen(self):
  45.         ## register topic under which we will publish MCU measurements
  46.         ##
  47.         self.registerForPubSub("http://example.com/mcu#measure1")
  48.  
  49.  
  50. lastTemp = 0.0
  51. lastRH = 0.0
  52. lastTimestamp = 0
  53.  
  54. class THOptions(usage.Options):
  55.     optParameters = [
  56.         ['baudrate', 'b', 9600, 'Serial baudrate'],
  57.         ['port', 'p', 3, 'Serial port to use'],
  58.         ]
  59.  
  60. class indexPage(resource.Resource):
  61.     isLeaf = True
  62.  
  63.     def render_GET(self, request):
  64.         ccStr = ' Temp:%f Humidity:%f\n' % (lastTemp, lastRH)
  65.         return ccStr
  66.  
  67. class Echo(LineReceiver):
  68.  
  69.     ## need a reference to our WS-MCU gateway factory to dispatch PubSub events
  70.     ##
  71.     def __init__(self, wsMcuFactory):
  72.         self.wsMcuFactory = wsMcuFactory
  73.  
  74.     def processData(self, data):
  75.         """Convert raw ADC counts into SI units as per datasheets"""
  76.         # Skip bad reads
  77.         if len(data) != 2:
  78.             return
  79.  
  80.         global lastTemp, lastRH, lastTimestamp
  81.  
  82.         tempCts = int(data[0])
  83.         rhCts = int(data[1])
  84.  
  85.         rhVolts = rhCts * 0.0048828125
  86.         # 10mV/degree, 1024 count/5V
  87.         temp = tempCts * 0.48828125
  88.         # RH temp correction is -0.7% per deg C
  89.         rhcf = (-0.7 * (temp - 25.0)) / 100.0
  90.  
  91.         # Uncorrected humidity
  92.         humidity = (rhVolts * 45.25) - 42.76
  93.  
  94.         # Add correction factor
  95.         humidity = humidity + (rhcf * humidity)
  96.  
  97.  
  98.         lastTemp = tempCts
  99.         lastRH = rhCts
  100.         #lastTemp = temp
  101.         #lastRH = humidity
  102.         # Update screen now and then
  103.         if (time.time() - lastTimestamp) > 20.0:
  104.  
  105.             ## dispatch Temp/Humidity as a PubSub event to all clients subscribed to
  106.             ## topic http://example.com/mcu#measure1
  107.             ##
  108.             self.wsMcuFactory._dispatchEvent("http://example.com/mcu#measure1", (temp, humidity))
  109.  
  110.             logging.info('Temp: %f C Relative humidity: %f %%' % (temp, humidity))
  111.             logging.debug('Temp: %f counts: %d RH: %f counts: %d volts: %f' % (temp, tempCts, humidity, rhCts, rhVolts))
  112.             lastTimestamp = time.time()
  113.  
  114.         return temp, humidity
  115.  
  116.     def connectionMade(self):
  117.         logging.info('Serial connection made!')
  118.  
  119.     def lineReceived(self, line):
  120.         try:
  121.             data = line.split()
  122.             logging.debug(data)
  123.             self.processData(data)
  124.         except ValueError:
  125.             logging.error('Unable to parse data %s' % line)
  126.             return
  127.  
  128. if __name__ == '__main__':
  129.     logging.basicConfig(level=logging.INFO, \
  130.                 format='%(asctime)s %(levelname)s [%(funcName)s] %(message)s')
  131.  
  132.     ## create MCU-WS gateway factory/protocol
  133.     ##
  134.     wsMcuFactory = WampServerFactory("ws://localhost:9000", debugWamp = True)
  135.     wsMcuFactory.protocol = WsMcuProtocol
  136.     listenWS(wsMcuFactory)
  137.  
  138.     o = THOptions()
  139.     try:
  140.         o.parseOptions()
  141.     except usage.UsageError, errortext:
  142.         logging.error('%s %s' % (sys.argv[0], errortext))
  143.         logging.info('Try %s --help for usage details' % sys.argv[0])
  144.         raise SystemExit, 1
  145.  
  146.     if o.opts['baudrate']:
  147.         baudrate = int(o.opts['baudrate'])
  148.  
  149.     port = o.opts['port']
  150.  
  151.     logging.debug('About to open port %s' % port)
  152.     s = SerialPort(Echo(wsMcuFactory), port, reactor, baudrate=baudrate)
  153.  
  154.     # HTTP interface
  155.     logging.debug('Setting up webserver on http://localhost:2000/')
  156.     root = indexPage()
  157.     site = server.Site(root)
  158.     reactor.listenTCP(2000, site)
  159.  
  160.     reactor.run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement