Beispiel #1
0
def parseBitStream(bits, elevation=0.0, inputDataDict=None, verbose=False):
    """
	Given a sequence of bits from readRTL/readRTLFile, find all of the 
	valid Oregon Scientific v2.1 packets and return the data contained
	within the packets as a dictionary.  In the process, compute various
	derived quantities (dew point, windchill, and sea level corrected
	pressure).
	
	.. note::
		The sea level corrected pressure is only compute if the elevation 
		(in meters) is set to a non-zero value.  
	"""

    # Setup the output dictionary
    output = {}
    if inputDataDict is not None:
        for key, value in inputDataDict.iteritems():
            output[key] = value

    # Find the packets and save the output
    i = 0
    while i < len(bits) - 32:
        ## Check for a valid preamble (and its logical negation counterpart)
        if sum(bits[i:i + 32:2]) == 16 and sum(bits[i + 1:i + 1 + 32:2]) == 0:
            ### Assume nothing
            valid = False

            ### Packet #1
            packet = bits[i + 0::2]
            try:
                valid, sensorName, channel, sensorData = parsePacketv21(
                    packet, verbose=verbose)
            except IndexError:
                pass

            if not valid:
                ### Packet #2
                packet = bits[i + 1::2]
                try:
                    valid, sensorName, channel, sensorData = parsePacketv21(
                        packet, verbose=verbose)
                except IndexError:
                    pass

            ### Data reorganization and computed quantities
            if valid:
                #### Dew point - indoor and output
                if sensorName in ('BHTR968', 'THGR268', 'THGR968'):
                    sensorData['dewpoint'] = computeDewPoint(
                        sensorData['temperature'], sensorData['humidity'])
                #### Sea level corrected barometric pressure
                if sensorName in ('BHTR968', ) and elevation != 0.0:
                    sensorData['pressure'] = computeSeaLevelPressure(
                        sensorData['pressure'], elevation)
                #### Disentangle the indoor temperatures from the outdoor temperatures
                if sensorName == 'BHTR968':
                    for key in ('temperature', 'humidity', 'dewpoint'):
                        newKey = 'indoor%s' % key.capitalize()
                        sensorData[newKey] = sensorData[key]
                        del sensorData[key]
                #### Multiplex the THGR268 values
                for key in sensorData.keys():
                    if key in ('temperature', 'humidity', 'dewpoint'):
                        if sensorName == 'THGR968':
                            output[key] = sensorData[key]
                        else:
                            try:
                                output['alt%s' %
                                       key.capitalize()][channel -
                                                         1] = sensorData[key]
                            except KeyError:
                                output['alt%s' % key.capitalize()] = [
                                    None, None, None, None
                                ]
                                output['alt%s' %
                                       key.capitalize()][channel -
                                                         1] = sensorData[key]
                    else:
                        output[key] = sensorData[key]

        i += 1

    # Compute combined quantities
    if 'temperature' in output.keys() and 'average' in output.keys():
        output['windchill'] = computeWindchill(output['temperature'],
                                               output['average'])

    # Done
    return output
Beispiel #2
0
def parsePacketStream(packets, elevation=0.0, inputDataDict=None):
	"""
	Given a sequence of two-element type,payload packets from read433, 
	find all of the Oregon Scientific sensor values and return the data 
	as a dictionary.  In the process, compute various derived quantities 
	(dew point, windchill, and sea level correctedpressure).
	
	.. note::
		The sea level corrected pressure is only compute if the elevation 
		(in meters) is set to a non-zero value.  
	"""

	# Setup the output dictionary
	output = {}
	if inputDataDict is not None:
		for key,value in inputDataDict.iteritems():
			output[key] = value

	# Parse the packet payload and save the output
	gspd = []
	gdir = []
	for pType,pPayload in packets:
		if pType == 'OSV2':
			valid, sensorName, channel, sensorData = parsePacketv21(pPayload)
		else:
			continue
			
		## Data reorganization and computed quantities
		if valid:
			### Gust tracker
			if sensorName == 'WGR968':
				gspd.append( sensorData['gust'] )
				gdir.append( sensorData['direction'] )
			### Dew point - indoor and output
			if sensorName in ('BHTR968', 'THGR268', 'THGR968'):
				sensorData['dewpoint'] = computeDewPoint(sensorData['temperature'], sensorData['humidity'])
			### Sea level corrected barometric pressure
			if sensorName in ('BHTR968',) and elevation != 0.0:
				sensorData['pressure'] = computeSeaLevelPressure(sensorData['pressure'], elevation)
			### Disentangle the indoor temperatures from the outdoor temperatures
			if sensorName == 'BHTR968':
				for key in ('temperature', 'humidity', 'dewpoint'):
					newKey = 'indoor%s' % key.capitalize()
					sensorData[newKey] = sensorData[key]
					del sensorData[key]
			### Multiplex the THGR268 values
			for key in sensorData.keys():
				if key in ('temperature', 'humidity', 'dewpoint'):
					if sensorName == 'THGR968':
						output[key] = sensorData[key]
					else:
						try:
							output['alt%s' % key.capitalize()][channel-1] = sensorData[key]
						except KeyError:
							output['alt%s' % key.capitalize()] = [None, None, None, None]
							output['alt%s' % key.capitalize()][channel-1] = sensorData[key]
				else:
					output[key] = sensorData[key]
					
	# Compute combined quantities
	## Maximum gust observed
	if len(gspd) > 0:
		best = gspd.index( max(gspd) )
		output['gust'] = gspd[best]
		output['gustDirection'] = gdir[best]
	## Windchill
	if 'temperature' in output.keys() and 'average' in output.keys():
		output['windchill'] = computeWindchill(output['temperature'], output['average'])

	# Done
	return output
Beispiel #3
0
    def run(self):
        tLastUpdate = 0.0
        sensorData = self.sensorData

        while self.alive.isSet():
            ## Begin the loop
            t0 = time.time()

            ## Load in the current configuration
            wuID = self.config.get('Account', 'id')
            wuPW = self.config.get('Account', 'password')

            radioPin = self.config.getint('Station', 'radiopin')
            duration = self.config.getfloat('Station', 'duration')
            elevation = self.config.getfloat('Station', 'elevation')
            enableBMP085 = self.config.getbool('Station', 'enablebmp085')
            includeIndoor = self.config.getbool('Station', 'includeindoor')

            ## Read from the 433 MHz radio
            for i in xrange(self.loopsForState):
                self.leds['red'].on()
                tData = time.time() + int(round(duration - 5)) / 2.0
                packets = read433(radioPin, int(round(duration - 5)))
                self.leds['red'].off()

                ## Process the received packets and update the internal state
                self.leds['yellow'].on()
                sensorData = parsePacketStream(packets,
                                               elevation=elevation,
                                               inputDataDict=sensorData)
                self.leds['yellow'].off()

                # Poll the BMP085/180 - if needed
                if enableBMP085:
                    self.leds['red'].on()
                    ps = BMP085(address=0x77, mode=3)
                    pressure = ps.readPressure() / 100.0
                    temperature = ps.readTemperature()
                    self.leds['red'].off()

                    self.leds['yellow'].on()
                    sensorData['pressure'] = pressure
                    sensorData['pressure'] = computeSeaLevelPressure(
                        sensorData['pressure'], elevation)
                    if 'indoorHumidity' in sensorData.keys():
                        sensorData['indoorTemperature'] = ps.readTemperature()
                        sensorData['indoorDewpoint'] = computeDewPoint(
                            sensorData['indoorTemperature'],
                            sensorData['indoorHumidity'])
                    self.leds['yellow'].off()

            ## Have we built up the state?
            if self.buildState:
                self.loopsForState = 1

            ## Check if there is anything to update in the archive
            self.leds['yellow'].on()
            if tData != tLastUpdate:
                self.db.writeData(tData, sensorData)
                pollLogger.info('Saving current state to archive')
            else:
                pollLogger.warning(
                    'Data timestamp has not changed since last poll, archiving skipped'
                )
            self.leds['yellow'].off()

            ## Post the results to WUnderground
            if tData != tLastUpdate:
                uploadStatus = wuUploader(wuID,
                                          wuPW,
                                          tData,
                                          sensorData,
                                          archive=self.db,
                                          includeIndoor=includeIndoor)

                if uploadStatus:
                    tLastUpdate = 1.0 * tData

                    pollLogger.info('Posted data to WUnderground')
                    self.leds['green'].blink()
                    time.sleep(3)
                    self.leds['green'].blink()
                else:
                    pollLogger.error('Failed to post data to WUnderground')
                    self.leds['red'].blink()
                    time.sleep(3)
                    self.leds['red'].blink()

            else:
                pollLogger.warning(
                    'Data timestamp has not changed since last poll, archiving skipped'
                )

            ## Done
            t1 = time.time()
            tSleep = duration - (t1 - t0)
            tSleep = tSleep if tSleep > 0 else 0

            ## Sleep
            time.sleep(tSleep)
Beispiel #4
0
def parseBitStream(bits, elevation=0.0, inputDataDict=None, verbose=False):
	"""
	Given a sequence of bits from readRTL/readRTLFile, find all of the 
	valid Oregon Scientific v2.1 packets and return the data contained
	within the packets as a dictionary.  In the process, compute various
	derived quantities (dew point, windchill, and sea level corrected
	pressure).
	
	.. note::
		The sea level corrected pressure is only compute if the elevation 
		(in meters) is set to a non-zero value.  
	"""
	
	# Setup the output dictionary
	output = {}
	if inputDataDict is not None:
		for key,value in inputDataDict.iteritems():
			output[key] = value
			
	# Find the packets and save the output
	i = 0
	while i < len(bits)-32:
		## Check for a valid preamble (and its logical negation counterpart)
		if sum(bits[i:i+32:2]) == 16 and sum(bits[i+1:i+1+32:2]) == 0:
			### Assume nothing
			valid = False
			
			### Packet #1
			packet = bits[i+0::2]
			try:
				valid, sensorName, channel, sensorData = parsePacketv21(packet, verbose=verbose)
			except IndexError:
				pass
				
			if not valid:
				### Packet #2
				packet = bits[i+1::2]
				try:
					valid, sensorName, channel, sensorData = parsePacketv21(packet, verbose=verbose)
				except IndexError:
					pass
				
			### Data reorganization and computed quantities
			if valid:
				#### Dew point - indoor and output
				if sensorName in ('BTHGN129', 'THGN800', 'THGN800'):
					sensorData['dewpoint'] = computeDewPoint(sensorData['temperature'], sensorData['humidity'])
				
				#### Disentangle the indoor temperatures from the outdoor temperatures
				if sensorName == 'BTHGN129':
					for key in ('temperature', 'humidity', 'dewpoint','pressure'):
						output[key] = sensorData[key]
				#### Multiplex the THGN800 values
				for key in sensorData.keys():
					if key in ('temperature', 'humidity', 'dewpoint'):
						if sensorName == 'THGN800':
							output[key] = sensorData[key]
						else:
							try:
								output['alt%s' % key.capitalize()][channel-1] = sensorData[key]
							except KeyError:
								output['alt%s' % key.capitalize()] = [None, None, None, None]
								output['alt%s' % key.capitalize()][channel-1] = sensorData[key]
					else:
						output[key] = sensorData[key]
						
		i += 1
		
	# Compute combined quantities
	if 'temperature' in output.keys() and 'average' in output.keys():
		output['windchill'] = computeWindchill(output['temperature'], output['average'])
		
	# Done
	return output
Beispiel #5
0
	def run(self):
		tLastUpdate = 0.0
		sensorData = self.sensorData
		
		while self.alive.isSet():
			## Begin the loop
			t0 = time.time()
			
			## Load in the current configuration
			wuID = self.config.get('Account', 'id')
			wuPW = self.config.get('Account', 'password')
			
			radioPin = self.config.getint('Station', 'radiopin')
			duration = self.config.getfloat('Station', 'duration')
			elevation = self.config.getfloat('Station', 'elevation')
			enableBMP085 = self.config.getbool('Station', 'enablebmp085')
			includeIndoor = self.config.getbool('Station', 'includeindoor')
			
			## Read from the 433 MHz radio
			for i in xrange(self.loopsForState):
				self.leds['red'].on()
				tData = time.time() + int(round(duration-5))/2.0
				packets = read433(radioPin, int(round(duration-5)))
				self.leds['red'].off()
				
				## Process the received packets and update the internal state
				self.leds['yellow'].on()
				sensorData = parsePacketStream(packets, elevation=elevation, 
												inputDataDict=sensorData)
				self.leds['yellow'].off()
				
				# Poll the BMP085/180 - if needed
				if enableBMP085:
					self.leds['red'].on()
					ps = BMP085(address=0x77, mode=3)
					pressure = ps.readPressure() / 100.0
					temperature = ps.readTemperature()
					self.leds['red'].off()
			
					self.leds['yellow'].on()
					sensorData['pressure'] =  pressure
					sensorData['pressure'] = computeSeaLevelPressure(sensorData['pressure'], elevation)
					if 'indoorHumidity' in sensorData.keys():
						sensorData['indoorTemperature'] = ps.readTemperature()
						sensorData['indoorDewpoint'] = computeDewPoint(sensorData['indoorTemperature'], sensorData['indoorHumidity'])
					self.leds['yellow'].off()
					
			## Have we built up the state?
			if self.buildState:
				self.loopsForState = 1
				
			## Check if there is anything to update in the archive
			self.leds['yellow'].on()
			if tData != tLastUpdate:
				self.db.writeData(tData, sensorData)
				pollLogger.info('Saving current state to archive')
			else:
				pollLogger.warning('Data timestamp has not changed since last poll, archiving skipped')
			self.leds['yellow'].off()
			
			## Post the results to WUnderground
			if tData != tLastUpdate:
				uploadStatus = wuUploader(wuID, wuPW, 
											tData, sensorData, archive=self.db, 
											includeIndoor=includeIndoor)
											
				if uploadStatus:
					tLastUpdate = 1.0*tData
					
					pollLogger.info('Posted data to WUnderground')
					self.leds['green'].blink()
					time.sleep(3)
					self.leds['green'].blink()
				else:
					pollLogger.error('Failed to post data to WUnderground')
					self.leds['red'].blink()
					time.sleep(3)
					self.leds['red'].blink()
					
			else:
				pollLogger.warning('Data timestamp has not changed since last poll, archiving skipped')
				
			## Done
			t1 = time.time()
			tSleep = duration - (t1-t0)
			tSleep = tSleep if tSleep > 0 else 0
			
			## Sleep
			time.sleep(tSleep)
			
Beispiel #6
0
def parsePacketStream(packets, elevation=0.0, inputDataDict=None):
	"""
	Given a sequence of two-element type,payload packets from read433, 
	find all of the Oregon Scientific sensor values and return the data 
	as a dictionary.  In the process, compute various derived quantities 
	(dew point, windchill, and sea level correctedpressure).
	
	.. note::
		The sea level corrected pressure is only compute if the elevation 
		(in meters) is set to a non-zero value.  
	"""

	# Setup the output dictionary
	output = {}
	if inputDataDict is not None:
		for key,value in inputDataDict.iteritems():
			output[key] = value

	# Parse the packet payload and save the output
	gspd = []
	gdir = []
	for pType,pPayload in packets:
		if pType == 'OSV2':
			valid, sensorName, channel, sensorData = parsePacketv21(pPayload)
		else:
			continue
			
		## Data reorganization and computed quantities
		if valid:
			### Gust tracker
			if sensorName == 'WGR968':
				gspd.append( sensorData['gust'] )
				gdir.append( sensorData['direction'] )
			### Dew point - indoor and output
			if sensorName in ('BHTR968', 'THGR268', 'THGR968'):
				sensorData['dewpoint'] = computeDewPoint(sensorData['temperature'], sensorData['humidity'])
			### Sea level corrected barometric pressure
			if sensorName in ('BHTR968',) and elevation != 0.0:
				sensorData['pressure'] = computeSeaLevelPressure(sensorData['pressure'], elevation)
			### Disentangle the indoor temperatures from the outdoor temperatures
			if sensorName == 'BHTR968':
				for key in ('temperature', 'humidity', 'dewpoint'):
					newKey = 'indoor%s' % key.capitalize()
					sensorData[newKey] = sensorData[key]
					del sensorData[key]
			### Multiplex the THGR268 values
			for key in sensorData.keys():
				if key in ('temperature', 'humidity', 'dewpoint'):
					if sensorName == 'THGR968':
						output[key] = sensorData[key]
					else:
						try:
							output['alt%s' % key.capitalize()][channel-1] = sensorData[key]
						except KeyError:
							output['alt%s' % key.capitalize()] = [None, None, None, None]
							output['alt%s' % key.capitalize()][channel-1] = sensorData[key]
				else:
					output[key] = sensorData[key]
					
	# Compute combined quantities
	## Maximum gust observed
	if len(gspd) > 0:
		best = gspd.index( max(gspd) )
		output['gust'] = gspd[best]
		output['gustDirection'] = gdir[best]
	## Windchill
	if 'temperature' in output.keys() and 'average' in output.keys():
		output['windchill'] = computeWindchill(output['temperature'], output['average'])

	# Done
	return output