Важное предупреждение: Эта статья не для слабонервных. Если ты всё ещё веришь в официальные данные Росгидромета и МЧС — закрой страницу и иди смотреть котиков. Если ты хочешь знать, КОГДА РЕАЛЬНО можно будет дышать, а когда пора заклеивать окна скотчем и надевать противогаз — добро пожаловать в клуб параноиков. У нас есть печеньки. И датчики. Очень много датчиков.
Часть 1. Философия параноика: «Измеряй всё, что движется, и то, что нет»
Обычный человек смотрит новости и верит. Параноик собирает данные и ПРОВЕРЯЕТ. Официальные данные — это усреднённая температура по больнице. А меня интересует температура на моём балконе, радиация у моего подъезда и количество формальдегида, которое выделяет новый ламинат у соседа. Только так я пойму, когда официальная ложь закончится и начнётся настоящая жесть.
Цель: Создать систему мониторинга, которая замерит всё: от погоды до уровня безумия в атмосфере. Данные будем складывать в базу, писать скрипты и ждать, когда цифры подтвердят, что мы не параноики, а просто хорошо информированные люди.
Часть 2. Железо: Список датчиков для «Апокалипсис-мониторинга»
Это не просто метеостанция. Это лаборатория по измерению конца света. Вот полный комплект датчиков, которые превратят твою Raspberry Pi в центр сбора данных о деградации окружающей среды.
🌦️ Базовая метеостанция (Климат)
- Датчик температуры/влажности/давления (BME280). Основа основ. Покажет, как быстро воздух становится суше и теплее.
- Датчик освещённости (TSL2591). Измеряет в люксах. Нужен, чтобы понять, сколько солнца реально доходит до панелей, а не "по данным астрономического календаря".
- Датчик УФ-индекса (VEML6075). Покажет, не собираемся ли мы сгореть нафиг из-за очередной озоновой аномалии.
☢️ Радиация и частицы (То, о чём молчат)
- Датчик радиации (RadiationD v1.0 на трубке СБМ-20). Гамма и бета в мкЗв/ч. Узнать, когда «Фукусима» или местная АЭС решат напомнить о себе. Или когда очередной «товарищ майор» решит где-то что-то обронить.
- Датчик пыли PM2.5 и PM10 (Sensirion SPS30). Сажа, дым, аллергены. Понять, когда в Москву пришёл смог от пожаров не «где-то там», а прямо к тебе в форточку.
🧪 Токсичные газы (Промышленность и транспорт)
- Датчик диоксида азота (NO₂). Выбросы от машин и ТЭЦ. Научное обоснование, почему дышать на ТТК нельзя.
- Датчик диоксида серы (SO₂). Кислотный запах от промышленных выбросов. Раннее обнаружение «нештатной ситуации» на ближайшем заводе.
- Датчик озона (O₃). Приземный озон. В больших концентрациях убивает всё живое.
- Датчик оксида углерода (CO). Угарный газ. Главный убийца при пожарах и неисправных обогревателях.
🏠 Летучие органические соединения (Домашний ад)
- Датчик TVOC (Sensirion SGP40). Формальдегид, бензол, ацетон. Доказательство, что твоя соседская «гарантированно безопасная» стяжка потихоньку тебя травит.
🔊 Шум
- MEMS микрофон. Уровень шума в дБ. Доказательство, что «тишина в мегаполисе» — это миф.
Главное правило параноика: Покупай датчики сейчас. Когда всё пойдёт по пизде, их будут разбирать, как тушенку перед дефолтом.
Часть 3. Софт: База данных для хранения всего этого безумия
Всё это хозяйство должно где-то храниться. Обычная SQLite не вывезет объём. Нужен нормальный PostgreSQL для временных рядов.
Структура базы данных (с учётом всех датчиков)
-- Таблица для хранения СЫРЫХ показаний (каждые 10 минут)
CREATE TABLE sensor_data (
id SERIAL PRIMARY KEY,
timestamp TIMESTAMPTZ DEFAULT NOW(),
-- Базовая метео
temp_c REAL,
humidity REAL,
pressure_hpa REAL,
illuminance_lux REAL,
uv_index REAL,
-- Радиация и пыль
radiation_usv REAL, -- Радиационный фон
pm25 REAL, -- Мелкая пыль (дым, смог)
pm10 REAL, -- Крупная пыль (песок, пыльца)
-- Токсичные газы
no2_ppm REAL, -- Диоксид азота (выхлопы)
so2_ppm REAL, -- Диоксид серы (заводы)
o3_ppm REAL, -- Озон
co_ppm REAL, -- Угарный газ
-- Летучие вещества и шум
tvoc_ppb REAL, -- Формальдегид и прочая гадость
noise_db REAL -- Уровень шума
);
-- Таблица для агрегированных данных (часовые/дневные средние)
CREATE TABLE daily_stats (
date DATE PRIMARY KEY,
avg_temp REAL, max_temp REAL, min_temp REAL,
total_light_kwh REAL, -- Интеграл освещённости
avg_uv REAL,
avg_radiation REAL,
avg_pm25 REAL, avg_pm10 REAL,
avg_no2 REAL, avg_so2 REAL, avg_o3 REAL, avg_co REAL,
avg_tvoc REAL, avg_noise REAL
);
Примечание параноика: Базу данных обязательно реплицируй на два диска. Один — в квартире, второй — у бабки в деревне. Чтобы, когда прилетит, данные не пропали.
Часть 4. Скрипт для сбора данных (sensor_logger.py)
Этот скрипт будет крутиться в бесконечном цикле и дёргать все датчики. Он написан так, чтобы ты мог добавить любой новый датчик, просто дописав пару строк.
import time
import psycopg2
from datetime import datetime
import Adafruit_BME280
import board
import adafruit_tsl2591
import adafruit_veml6075
import serial # для радиации
import pms5003 # для пыли
# ... и другие библиотеки для газов
# Инициализация датчиков (упрощённо)
bme280 = Adafruit_BME280.BME280()
i2c = board.I2C()
tsl = adafruit_tsl2591.TSL2591(i2c)
veml = adafruit_veml6075.VEML6075(i2c)
# ... инициализация остальных датчиков
conn = psycopg2.connect(database="apocalypse_db", user="pi", password="pass", host="localhost")
def read_all_sensors():
return {
'timestamp': datetime.now(),
# База
'temp_c': bme280.temperature,
'humidity': bme280.humidity,
'pressure_hpa': bme280.pressure,
'illuminance_lux': tsl.lux,
'uv_index': veml.uvi,
# Радиация
'radiation_usv': get_radiation(), # Функция чтения с ком-порта
# Пыль
'pm25': pms.pm_ug_per_m3(2.5),
'pm10': pms.pm_ug_per_m3(10),
# Газы (заглушки, добавь свои функции)
'no2_ppm': read_no2(),
'so2_ppm': read_so2(),
'o3_ppm': read_o3(),
'co_ppm': read_co(),
'tvoc_ppb': read_tvoc(),
'noise_db': read_noise()
}
while True:
data = read_all_sensors()
cur = conn.cursor()
cur.execute("""
INSERT INTO sensor_data (timestamp, temp_c, humidity, pressure_hpa, illuminance_lux, uv_index,
radiation_usv, pm25, pm10, no2_ppm, so2_ppm, o3_ppm, co_ppm, tvoc_ppb, noise_db)
VALUES (%(timestamp)s, %(temp_c)s, %(humidity)s, %(pressure_hpa)s, %(illuminance_lux)s, %(uv_index)s,
%(radiation_usv)s, %(pm25)s, %(pm10)s, %(no2_ppm)s, %(so2_ppm)s, %(o3_ppm)s, %(co_ppm)s, %(tvoc_ppb)s, %(noise_db)s)
""", data)
conn.commit()
cur.close()
time.sleep(600) # Раз в 10 минут. Можно реже, чтобы база не распухла.
Часть 5. Аналитика: Главный скрипт для выявления лжи (analytics.py)
Этот скрипт — сердце паранойи. Он будет искать тренды, считать корреляции и выдавать готовые графики для твоего блога.
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
import pandas as pd
import psycopg2
conn = psycopg2.connect(database="apocalypse_db", user="pi", host="localhost")
df = pd.read_sql("SELECT * FROM daily_stats ORDER BY date", conn, index_col='date')
# 1. Анализ радиации (самое страшное)
y_rad = df['avg_radiation'].values
x = np.arange(len(y_rad))
slope_rad, _, _, p_rad, _ = stats.linregress(x, y_rad)
print(f"☢️ Тренд радиации: {slope_rad:.4f} мкЗв/ч в день (p={p_rad:.3f})")
if slope_rad > 0 and p_rad < 0.05:
print(" -> ТРЕВОГА! Радиационный фон растёт. Пора закупать йодид калия и думать о бункере.")
# 2. Анализ пыли и смога
y_pm25 = df['avg_pm25'].values
slope_pm, _, _, p_pm, _ = stats.linregress(x, y_pm25)
print(f"😷 Тренд PM2.5 (мелкая пыль): {slope_pm:.2f} мкг/м³ в год")
if slope_pm > 0 and p_pm < 0.05:
print(" -> Воздух становится грязнее. Рекомендуется респулёр класса N95.")
# 3. Анализ газов (индустриальный ад)
y_no2 = df['avg_no2'].values
slope_no2, _, _, p_no2, _ = stats.linregress(x, y_no2)
print(f"🚗 Тренд NO₂: {slope_no2:.3f} ppm в год")
if slope_no2 > 0:
print(" -> Машин меньше не становится. Дышать нечем.")
# 4. Индекс качества жизни (собирательный)
df['pollution_index'] = (df['avg_pm25'] / 10) + (df['avg_no2'] * 10) + (df['avg_tvoc'] / 100)
y_pollution = df['pollution_index'].values
slope_poll, _, _, p_poll, _ = stats.linregress(x, y_pollution)
print(f"🤢 Индекс загрязнения: {slope_poll:.2f} пунктов в год")
if slope_poll > 0 and p_poll < 0.05:
print(" -> Город реально становится токсичнее. Это не субъективно, это данные.")
# 5. Генерируем график для блога (самый страшный)
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(12, 12))
fig.suptitle('Апокалипсис по данным моей метеостанции', fontsize=16)
ax1.plot(df.index, df['avg_radiation'], label='Радиация', color='red')
ax1.set_ylabel('мкЗв/ч')
ax1.axhline(y=0.3, color='r', linestyle='--', label='Опасный уровень')
ax1.legend()
ax1.grid(True)
ax2.plot(df.index, df['avg_pm25'], label='PM2.5 (смог)', color='orange')
ax2.set_ylabel('мкг/м³')
ax2.axhline(y=25, color='r', linestyle='--', label='ПДК')
ax2.legend()
ax2.grid(True)
ax3.plot(df.index, df['avg_no2'], label='NO₂ (выхлопы)', color='brown')
ax3.set_ylabel('ppm')
ax3.legend()
ax3.grid(True)
plt.tight_layout()
plt.savefig('/var/www/html/apocalypse_report.png')
print("✅ График апокалипсиса сохранён. Можно постить в блог.")
Часть 6. Выводы для параноика (Что мы будем знать через 2 года)
- Про радиацию: «Фон вырос на X% с момента запуска. Источник пока не найден, но тренд пугающий.»
- Про воздух: «Количество дней с превышением ПДК по PM2.5 выросло в 2 раза. Официальные данные занижены.»
- Про газы: «NO₂ стабильно превышает норму по ночам (фуры) и в часы пик. Выхлопные газы — наше всё.»
- Про климат: «Температура выросла, инсоляция упала, УФ-индекс подскочил. Это не «аномалия», это тренд.»
- Про жизнь в мегаполисе: «Шум и вибрация превышают санитарные нормы в 3-5 раз. Доказано документально.»
И самое главное: когда соседи спросят, зачем тебе этот безумный пульт с датчиками, ты просто покажешь им графики. И скажешь: «Я не параноик. Я просто знаю правду. И она вот здесь, в этих цифрах.»
Комментарии
Пока нет комментариев. Будьте первым!