Skip to content

Instantly share code, notes, and snippets.

@NicolaiSoeborg
Last active January 30, 2022 16:03
Show Gist options
  • Save NicolaiSoeborg/3e97a6f6da87ab1e870a5237f4afcd29 to your computer and use it in GitHub Desktop.
Save NicolaiSoeborg/3e97a6f6da87ab1e870a5237f4afcd29 to your computer and use it in GitHub Desktop.
Save and plot data from BME680 (Raspberry Pi)
#!/usr/bin/env python3
import json, os, sqlite3
from datetime import datetime
from random import randint
from time import time, sleep
try:
from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient # pip3 install azure-storage-blob
except: pass
def get_db():
conn = sqlite3.connect('sensor-data.db')
conn.execute('''CREATE TABLE IF NOT EXISTS data (
time INTEGER PRIMARY KEY,
gas_ohms REAL,
humidity_pctRH REAL,
temperature_degC REAL,
pressure_hPa REAL,
heat_stable INT)''')
conn.commit()
return conn
last_uploaded_ts = -1
def insert_data(db, data, blob_service_client):
global last_uploaded_ts
ts = int(time())
db.execute("INSERT INTO data VALUES (?, ?, ?, ?, ?, ?)", (
ts,
data.gas_resistance,
data.humidity,
data.temperature,
data.pressure,
data.heat_stable
))
# This is called every 45 sec
# (10% chance of commit) * 5 == 50% chance
# 45 sec * 5 = a commit every 3.75 min
if randint(0, 9) == 3:
db.commit()
# This is called every 3.75 min
# 225 sec * 5 = a commit every 18 min
if randint(0, 9) == 3:
try:
blob_name = datetime.utcfromtimestamp(ts).strftime("%Y/%m") + '/' + str(ts)
blob_client = blob_service_client.get_blob_client(container="data", blob=blob_name)
blob = json.dumps(db.execute("SELECT * FROM data WHERE time > ?", (last_uploaded_ts,)).fetchall())
blob_client.upload_blob(blob.encode())
last_uploaded_ts = ts
except Exception as ex:
print(f"[ERR] while updating: {ex}")
def plot():
import plotly.express as px # python3 -m pip install dash
import pandas as pd # python3 -m pip install pandas
import dash
from dash import dcc
from dash import html
df = pd.read_sql_query("SELECT * FROM data", get_db())
# 'time'-col from ints to 'real datetimes'
df['time'] = list(map(datetime.fromtimestamp, df['time']))
cols = ['gas_ohms', 'humidity_pctRH', 'temperature_degC', 'pressure_hPa']
app = dash.Dash()
app.layout = html.Div([
dcc.Graph(figure=px.line(df, x='time', y=col)) for col in cols
])
#t0 = min(df['time'])
#df['days'] = [(t-t0).days for t in df['time']]
#fig = px.line(df,
# x='temperature_degC', range_x=[min(df['temperature_degC']), max(df['temperature_degC'])],
# y='humidity_pctRH', range_y=[min(df['humidity_pctRH']), max(df['humidity_pctRH'])],
# animation_frame='days')
#fig.show()
#
#fig = px.scatter(df, x="gdpPercap", y="lifeExp", animation_frame="year", animation_group="country",
# size="pop", color="continent", hover_name="country", facet_col="continent",
# log_x=True, size_max=45, range_x=[100,100000], range_y=[25,90])
#fig.write_html("/tmp/file.html")
def collect_data():
import bme680 # python3 -m pip install bme680
connect_str = os.getenv('AZURE_STORAGE_CONNECTION_STRING')
blob_service_client = BlobServiceClient.from_connection_string(connect_str)
try:
sensor = bme680.BME680(bme680.I2C_ADDR_PRIMARY)
except IOError:
sensor = bme680.BME680(bme680.I2C_ADDR_SECONDARY)
db = get_db()
sensor.set_gas_heater_temperature(320) # "Target temperature in degrees celsius, between 200 and 400"
sensor.set_gas_heater_duration(150) # "Heating durations between 1 ms and 4032 ms"
# sensor.select_gas_heater_profile(0)
while True:
sleep(45)
if sensor.get_sensor_data():
insert_data(db, sensor.data, blob_service_client)
else:
print(f"[{int(time())}] get_sensor_data() => False")
if __name__ == "__main__":
from sys import argv
if len(argv) > 1:
assert argv[1] == '--plot'
plot()
else:
collect_data()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment