Skip to content

Instantly share code, notes, and snippets.

@Chak10
Last active June 21, 2017 07:49
Show Gist options
  • Save Chak10/4995d669d09dc362053c3b0f9bf04cdb to your computer and use it in GitHub Desktop.
Save Chak10/4995d669d09dc362053c3b0f9bf04cdb to your computer and use it in GitHub Desktop.
Weather Python
#!/usr/bin/python
#--------------------------------------
# ___ ___ _ ____
# / _ \/ _ \(_) __/__ __ __
# / , _/ ___/ /\ \/ _ \/ // /
# /_/|_/_/ /_/___/ .__/\_, /
# /_/ /___/
#
# bme280.py
#
# Read data from a digital pressure sensor.
#
# Official datasheet available from :
# https://www.bosch-sensortec.com/bst/products/all_products/bme280
#
# Author : Matt Hawkins
# Date : 25/07/2016
#
# http://www.raspberrypi-spy.co.uk/
#
# Author : Francesco Sorbello
# Date : 16/06/2017
#
# http://www.weathertemplate.altervista.org
#
# Version 1.1
#
# 1. Json Output
# 2. Timestamp
# 3. converters.py required for dewpoint, heat index and absolute humidity
# 4. Args Added (python bme280.py <station altitude> <bus address> <device address>)
#
#--------------------------------------
import smbus
import sys
import time
import json
from ctypes import c_short
from ctypes import c_byte
from ctypes import c_ubyte
from converters import *
try:
st_a = int(sys.argv[1])
except IndexError:
st_a = 0
try:
b_adre = int(sys.argv[2])
except IndexError:
b_adre = 0
try:
i_adre = int(sys.argv[3],16)
except IndexError:
i_adre = 0x76
DEVICE = i_adre # Default device I2C address
STAT_ALT = st_a # Station Altitude in m
bus = smbus.SMBus(b_adre) # Rev 2 Pi, Pi 2 & Pi 3 uses bus 1
# Rev 1 Pi uses bus 0
def getShort(data, index):
# return two bytes from data as a signed 16-bit value
return c_short((data[index+1] << 8) + data[index]).value
def getUShort(data, index):
# return two bytes from data as an unsigned 16-bit value
return (data[index+1] << 8) + data[index]
def getChar(data,index):
# return one byte from data as a signed char
result = data[index]
if result > 127:
result -= 256
return result
def getUChar(data,index):
# return one byte from data as an unsigned char
result = data[index] & 0xFF
return result
def readBME280ID(addr=DEVICE):
# Chip ID Register Address
REG_ID = 0xD0
(chip_id, chip_version) = bus.read_i2c_block_data(addr, REG_ID, 2)
return (chip_id, chip_version)
def readBME280All(addr=DEVICE,station_altitude=STAT_ALT):
# Register Addresses
REG_DATA = 0xF7
REG_CONTROL = 0xF4
REG_CONFIG = 0xF5
REG_CONTROL_HUM = 0xF2
REG_HUM_MSB = 0xFD
REG_HUM_LSB = 0xFE
# Oversample setting - page 27
OVERSAMPLE_TEMP = 2
OVERSAMPLE_PRES = 2
MODE = 1
# Oversample setting for humidity register - page 26
OVERSAMPLE_HUM = 2
bus.write_byte_data(addr, REG_CONTROL_HUM, OVERSAMPLE_HUM)
control = OVERSAMPLE_TEMP<<5 | OVERSAMPLE_PRES<<2 | MODE
bus.write_byte_data(addr, REG_CONTROL, control)
# Read blocks of calibration data from EEPROM
# See Page 22 data sheet
cal1 = bus.read_i2c_block_data(addr, 0x88, 24)
cal2 = bus.read_i2c_block_data(addr, 0xA1, 1)
cal3 = bus.read_i2c_block_data(addr, 0xE1, 7)
# Convert byte data to word values
dig_T1 = getUShort(cal1, 0)
dig_T2 = getShort(cal1, 2)
dig_T3 = getShort(cal1, 4)
dig_P1 = getUShort(cal1, 6)
dig_P2 = getShort(cal1, 8)
dig_P3 = getShort(cal1, 10)
dig_P4 = getShort(cal1, 12)
dig_P5 = getShort(cal1, 14)
dig_P6 = getShort(cal1, 16)
dig_P7 = getShort(cal1, 18)
dig_P8 = getShort(cal1, 20)
dig_P9 = getShort(cal1, 22)
dig_H1 = getUChar(cal2, 0)
dig_H2 = getShort(cal3, 0)
dig_H3 = getUChar(cal3, 2)
dig_H4 = getChar(cal3, 3)
dig_H4 = (dig_H4 << 24) >> 20
dig_H4 = dig_H4 | (getChar(cal3, 4) & 0x0F)
dig_H5 = getChar(cal3, 5)
dig_H5 = (dig_H5 << 24) >> 20
dig_H5 = dig_H5 | (getUChar(cal3, 4) >> 4 & 0x0F)
dig_H6 = getChar(cal3, 6)
# Wait in ms (Datasheet Appendix B: Measurement time and current calculation)
wait_time = 1.25 + (2.3 * OVERSAMPLE_TEMP) + ((2.3 * OVERSAMPLE_PRES) + 0.575) + ((2.3 * OVERSAMPLE_HUM)+0.575)
time.sleep(wait_time/1000) # Wait the required time
# Read temperature/pressure/humidity
data = bus.read_i2c_block_data(addr, REG_DATA, 8)
pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4)
hum_raw = (data[6] << 8) | data[7]
#Refine temperature
var1 = ((((temp_raw>>3)-(dig_T1<<1)))*(dig_T2)) >> 11
var2 = (((((temp_raw>>4) - (dig_T1)) * ((temp_raw>>4) - (dig_T1))) >> 12) * (dig_T3)) >> 14
t_fine = var1+var2
temperature = float(((t_fine * 5) + 128) >> 8);
# Refine pressure and adjust for temperature
var1 = t_fine / 2.0 - 64000.0
var2 = var1 * var1 * dig_P6 / 32768.0
var2 = var2 + var1 * dig_P5 * 2.0
var2 = var2 / 4.0 + dig_P4 * 65536.0
var1 = (dig_P3 * var1 * var1 / 524288.0 + dig_P2 * var1) / 524288.0
var1 = (1.0 + var1 / 32768.0) * dig_P1
if var1 == 0:
pressure=0
pressure_sea=0
else:
pressure = 1048576.0 - pres_raw
pressure = ((pressure - var2 / 4096.0) * 6250.0) / var1
var1 = dig_P9 * pressure * pressure / 2147483648.0
var2 = pressure * dig_P8 / 32768.0
pressure = pressure + (var1 + var2 + dig_P7) / 16.0
pressure_sea = (pressure / pow((1.0 - station_altitude / 44330.0), 5.255)) / 100;
# Refine humidity
humidity = t_fine - 76800.0
humidity = (hum_raw - (dig_H4 * 64.0 + dig_H5 / 16384.0 * humidity)) * (dig_H2 / 65536.0 * (1.0 + dig_H6 / 67108864.0 * humidity * (1.0 + dig_H3 / 67108864.0 * humidity)))
humidity = humidity * (1.0 - dig_H1 * humidity / 524288.0)
if humidity > 100:
humidity = 100
elif humidity < 0:
humidity = 0
dewp=dewPoint(temperature/100.0,humidity)
heat=heatIndex(temperature/100.0,humidity)
abs_humy=abs_hum(temperature/100.0,humidity)
return temperature/100.0,pressure/100.0,humidity,pressure_sea,dewp,heat,abs_humy
def main():
(chip_id, chip_version) = readBME280ID()
temperature,pressure,humidity,pressure_sea,dewp,heat,abs_humy = readBME280All()
print json.dumps({"ChipID":chip_id,"ChipVersion":chip_version,"Temperature":temperature,"T_DewPoint":dewp,"T_HeatIndex":heat,"Pressure":pressure,"PressureSea":pressure_sea,"Humidity":humidity,"HumidityAbsolute":abs_humy,"timestamp":time.time()},sort_keys=True)
if __name__ == "__main__":
main()
#!/usr/bin/python
#####################################
# #
# Converters for Weather in Pyhton #
# By Francesco Sorbello (2017) #
# Weathertemplate.altervista.org #
# #
# V 1.2 #
# #
# #
#####################################
import sys , getopt , math
def pvsIce(T):
lnP = math.exp(-5.8666426e3 / T + 2.232870244e1 + (1.39387003e-2 + (-3.4262402e-5 + (2.7040955e-8 * T)) * T) * T + 6.7063522e-1 * math.log(T))
return lnP
def pvsWater(T):
th = T + (-0.23855557567849) / (T - 0.65017534844798e3)
A = (th + 0.11670521452767e4) * th + (-0.72421316703206e6)
B = (-0.17073846940092e2 * th + 0.12020824702470e5) * th + (-0.32325550322333e7)
C = (0.14915108613530e2 * th + (-0.48232657361591e4)) * th + 0.40511340542057e6
p = 2 * C / (-B + math.sqrt(B * B - 4 * A * C))
p *= p
p *= p
return p * 1e6
def PVS(T):
if T < 173 or T > 678:
return -1000
elif T < 273.15:
return pvsIce(T)
else:
return pvsWater(T)
def re_solve(y, x0):
x = x0
count = 0
while (1):
xNew=0
dx = x / 1000
z = PVS(x)
xNew = x + dx * (y - z) / (PVS(x + dx) - z)
if math.fabs((xNew - x) / xNew) < 0.0001:
return xNew
elif count > 10:
xNew = -1000
return 273.15
x = xNew
count+=1
def dewPoint(T, RH):
T = T + 273.15
return re_solve(RH / 100 * PVS(T), T) - 273.15
def heatIndex(T, RH):
HI = -42.379 + 2.04901523 * T + 10.14333127 * RH - 2.2475541e-1 * T * RH - 6.83783e-3 * T * T - 5.481717e-2 * RH * RH + 1.22874e-3 * T * T * RH + 8.5282e-4 * T * RH * RH - 1.99e-6 * T * T * RH * RH
if RH < 13 and T <= 112 and T >= 80:
correction = ((13 - RH) / 4) * math.sqrt((17 - math.fabs(T - 95)) / 17)
return HI - correction
elif RH > 85 and T <= 87 and T >= 80:
correction = ((RH - 85) / 10) * ((87 - T) / 5)
return HI + correction
return 0.5 * (T + 61.0 + ((T - 68.0) * 1.2) + (RH * 0.094))
def cel2far(n):
return (n * 1.8) + 32
def far2cel(n):
return (n - 32) * 5 / 9;
def abs_hum(T, RH):
return (6.111 * math.exp((17.67 * T) / (T + 243.5)) * RH * 18.02) / ((273.15 + T) * 100 * 8.314e-2)
def index_thw(T, RH, W):
HI = heatIndex(T, RH)
return HI - ( 1.072 * W )
def wind_chill(T, V):
# T = F / V = mph / return F
return 35.74 + (0.6215 * T) - (35.75 * (V**0.16))+ (0.4275 * T * (V**0.16))
def wind_chill_wc(T, V):
# T = c / V = m/s / return w/m2
return (12.1452 + 11.6222 * math.sqrt(V) - 1.16222 * V) * (33 - T)
def app_temp (T,H,W):
# T = c / H = % / V = m/s / retun temp = c
return T + 0.33 * ((H / 100) * 6.105 * math.exp((17.27 * T) / (237.7 + T))) - 0.7 * W - 4
def main(argv):
start_conv=False
start=False
start_2=False
start_3=False
input_t=0
input_h=0
input_w=0
type=0
convt=0
try:
opts, args = getopt.getopt(argv,"hco:t:dianwpg:y:v:",["temp_out=","temp_in=","temp=","hum=","wind="])
except getopt.GetoptError:
print 'converters.py -c -o <output temperature (c or f)> -t <input temperature (NUMBER)>'
print 'converters.py -d -g <temperature (c)> -y <humidity (%)>'
print 'converters.py -i -g <temperature (f)> -y <humidity (%)>'
print 'converters.py -a -g <temperature (c)> -y <humidity (%)>'
print 'converters.py -w -g <temperature (f)> -v <wind speed (mph)>'
print 'converters.py -n -g <temperature (f)> -y <humidity (%)> -v <wind speed (mph)>'
print 'converters.py -p -g <temperature (f)> -y <humidity (%)> -v <wind speed (mph)>'
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print '[-c] Temperature Converter Celsius to Fahrenheit or Fahrenheit to Celsius>'
print 'Arguments: [-o] Output Scale> | [-t] Degree temperature'
print 'converters.py -c -o <output temperature (c or f)> -t <input temperature (NUMBER)>'
print '[-d] Dewpoint>'
print 'Arguments: [-g / --temp=] Temperature> | [-y / --hum=] Humidity'
print 'converters.py -d -g <temperature (c)> -y <humidity (%)>'
print '[-i] Heat Index>'
print 'Arguments: [-g / --temp=] Temperature> | [-y / --hum=] Humidity'
print 'converters.py -i -g <temperature (f)> -y <humidity (%)>'
print '[-a] Absolute Humidity>'
print 'Arguments: [-g / --temp=] Temperature> | [-y / --hum=] Humidity'
print 'converters.py -a -g <temperature (c)> -y <humidity (%)>'
print '[-n] THW Index>'
print 'Arguments: [-g / --temp=] Temperature> | [-y / --hum=] Humidity | [-v / --wind=] Wind Speed'
print 'converters.py -n -g <temperature (f)> -y <humidity (%)> -v <wind speed (mph)>'
print '[-w] Wind Chill>'
print 'Arguments: [-g / --temp=] Temperature> | [-v / --wind=] Wind Speed'
print 'converters.py -w -g <temperature (f)> -v <wind speed (mph)>'
print '[-p] Australian Apparent Temperature>'
print 'Arguments: [-g / --temp=] Temperature> | [-y / --hum=] Humidity | [-v / --wind=] Wind Speed'
print 'converters.py -p -g <temperature (c)> -y <humidity (%)> -v <wind speed (m/s)>'
sys.exit(2)
elif opt == "-c":
type=1
elif opt == "-d":
type=2
elif opt == "-i":
type=3
elif opt == "-a":
type=4
elif opt == "-n":
type=5
elif opt == "-w":
type=6
elif opt == "-p":
type=7
elif opt in ("-t","--temp_in"):
if arg.lstrip('-').replace('.','',1).isdigit():
input_t=arg
start_conv=True
else:
print "Wrong Temperature"
elif opt in ("-o","--temp_out"):
if arg == 'c':
convt=1
elif arg == 'f':
convt=2
elif opt in ("-g","--temp"):
if arg.lstrip('-').replace('.','',1).isdigit():
input_t=arg
start=True
else:
print "Wrong Temperature"
elif opt in ("-y","--hum"):
if arg.replace('.','',1).replace('%','',1).isdigit():
input_h=arg
start_2=True
else:
print "Wrong Humidity"
elif opt in ("-v","--wind"):
if arg.replace('.','',1).isdigit():
input_w=arg
start_3=True
else:
print "Wrong Wind"
else:
print 'converters.py -c -o <output temperature (c or f)> -t <input temperature (NUMBER)>'
print 'converters.py -d -g <temperature (c)> -y <humidity (%)>'
print 'converters.py -i -g <temperature (f)> -y <humidity (%)>'
print 'converters.py -a -g <temperature (c)> -y <humidity (%)>'
print 'converters.py -n -g <temperature (f)> -y <humidity (%)> -v <wind speed (mph)>'
print 'converters.py -w -g <temperature (f)> -v <wind speed (mph)>'
print 'converters.py -p -g <temperature (c)> -y <humidity (%)> -v <wind speed (m/s)>'
sys.exit(2)
if type == 1:
if start_conv==True:
if convt==1:
temp=far2cel(float(input_t))
if float(temp) < -273.15:
print "Temperature < 0 Kelvin (Not Possible!!!)"
else:
print temp
elif convt==2:
temp = cel2far(float(input_t))
if float(temp) < -459.67:
print "Temperature < 0 Kelvin (Not Possible!!!)"
else:
print temp
else:
print "Output Temperature Not Setted..."
else:
print "Wrong Temperature"
elif type==2:
if start==False:
print "Temperature Not Setted"
print 'converters.py -d -g <temperature (c)> -y <humidity>'
elif start_2==False:
print "Humidity Not Setted"
print 'converters.py -d -g <temperature (c)> -y <humidity>'
else:
print dewPoint(float(input_t),float(input_h.replace('%','',1)))
elif type==3:
if start==False:
print "Temperature Not Setted"
print 'converters.py -i -g <temperature (f)> -y <humidity (%)>'
elif start_2==False:
print "Humidity Not Setted"
print 'converters.py -i -g <temperature (f)> -y <humidity (%)>'
else:
print heatIndex(float(input_t),float(input_h.replace('%','',1)))
elif type==4:
if start==False:
print "Temperature Not Setted"
print 'converters.py -a -g <temperature (c)> -y <humidity (%)>'
elif start_2==False:
print "Humidity Not Setted"
print 'converters.py -a -g <temperature (c)> -y <humidity (%)>'
else:
print abs_hum(float(input_t),float(input_h.replace('%','',1)))
elif type==5:
if start==False:
print "Temperature Not Setted"
print 'converters.py -n -g <temperature (f)> -y <humidity (%)> -v <wind speed (mph)>'
elif start_2==False:
print "Humidity Not Setted"
print 'converters.py -n -g <temperature (f)> -y <humidity (%)> -v <wind speed (mph)>'
elif start_3==False:
print "Wind Not Setted"
print 'converters.py -n -g <temperature (f)> -y <humidity (%)> -v <wind speed (mph)>'
else:
print index_thw(float(input_t),float(input_h.replace('%','',1)),float(input_w))
elif type==6:
if start==False:
print "Temperature Not Setted"
print 'converters.py -w -g <temperature (f)> -v <wind speed (mph)>'
elif start_3==False:
print "Wind Not Setted"
print 'converters.py -w -g <temperature (f)> -v <wind speed (mph)>'
else:
print wind_chill(float(input_t),float(input_w))
elif type==7:
if start==False:
print "Temperature Not Setted"
print 'converters.py -p -g <temperature (f)> -y <humidity (%)> -v <wind speed (mph)>'
elif start_2==False:
print "Humidity Not Setted"
print 'converters.py -p -g <temperature (f)> -y <humidity (%)> -v <wind speed (mph)>'
elif start_3==False:
print "Wind Not Setted"
print 'converters.py -p -g <temperature (f)> -y <humidity (%)> -v <wind speed (mph)>'
else:
print app_temp(float(input_t),float(input_h.replace('%','',1)),float(input_w))
else:
print '[-c] Temperature Converter Celsius to Fahrenheit or Fahrenheit to Celsius>'
print 'Arguments: [-o] Output Scale> | [-t] Degree temperature'
print 'converters.py -c -o <output temperature (c or f)> -t <input temperature (NUMBER)>'
print '[-d] Dewpoint>'
print 'Arguments: [-g / --temp=] Temperature> | [-y / --hum=] Humidity'
print 'converters.py -d -g <temperature (c)> -y <humidity (%)>'
print '[-i] Heat Index>'
print 'Arguments: [-g / --temp=] Temperature> | [-y / --hum=] Humidity'
print 'converters.py -i -g <temperature (f)> -y <humidity (%)>'
print '[-a] Absolute Humidity>'
print 'Arguments: [-g / --temp=] Temperature> | [-y / --hum=] Humidity'
print 'converters.py -a -g <temperature (c)> -y <humidity (%)>'
print '[-n] THW Index>'
print 'Arguments: [-g / --temp=] Temperature> | [-y / --hum=] Humidity | [-v / --wind=] Wind Speed'
print 'converters.py -n -g <temperature (f)> -y <humidity (%)> -v <wind speed (mph)>'
print '[-w] Wind Chill>'
print 'Arguments: [-g / --temp=] Temperature> | [-v / --wind=] Wind Speed'
print 'converters.py -w -g <temperature (f)> -y <humidity (%)> -v <wind speed (mph)>'
print '[-p] Australian Apparent Temperature>'
print 'Arguments: [-g / --temp=] Temperature> | [-y / --hum=] Humidity | [-v / --wind=] Wind Speed'
print 'converters.py -p -g <temperature (c)> -y <humidity (%)> -v <wind speed (m/s)>'
sys.exit(2)
if __name__ == "__main__":
main(sys.argv[1:])
#!/bin/bash
sudo apt-get update
sudo apt-get install build-essential python-dev python-smbus git
git clone https://gist.github.com/4995d669d09dc362053c3b0f9bf04cdb.git
sudo mkdir /usr/local/etc/bme280
sudo mv 4995d669d09dc362053c3b0f9bf04cdb/* /usr/local/etc/bme280
sudo rm -rf 4995d669d09dc362053c3b0f9bf04cdb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment