Разработка мобильного приложения для мониторинга энергопотребления
Счётчик электроэнергии, к которому можно подключиться через Modbus RTU, отдаёт сырые регистры: напряжение, ток, активную и реактивную мощность, накопленную энергию в кВт·ч. Перевести это в понятный дашборд — задача мобильного приложения. Но перед дашбордом стоит задача поважнее: как эти данные вообще добыть и доставить на телефон.
Протоколы счётчиков и шлюзы
Промышленные счётчики (Меркурий 230, АГАТ, Eastron SDM630) говорят Modbus RTU через RS-485. Умные счётчики для частного сектора (Sagemcom, Itron) — DLMS/COSEM, M-Bus, или P1-порт (Dutch Smart Meter). Новые коммерческие счётчики с GPRS/NB-IoT модулем — облачный API производителя.
Для Modbus-счётчиков нужен RS-485 → Ethernet шлюз (Moxa NPort, Anybus X-gateway) или IoT-шлюз с Modbus-агентом. Мобильное приложение всегда работает с бэкендом или MQTT-брокером — не с счётчиком напрямую.
Для P1-порта (Нидерланды, Бельгия) существуют P1-to-MQTT адаптеры — маленькие ESP32/Raspberry Pi устройства, которые парсят DSMR-телеграммы и публикуют в MQTT.
Работа с данными: агрегация и хранение
Счётчик отдаёт моментальные значения. Приложению нужны тренды за час, сутки, месяц — это требует агрегации с сохранением. На бэкенде — InfluxDB или TimescaleDB (PostgreSQL extension). TimescaleDB подходит для небольших инсталляций: SQL-запросы, time_bucket функция:
SELECT
time_bucket('1 hour', time) AS hour,
device_id,
MAX(active_energy_kwh) - MIN(active_energy_kwh) AS consumption_kwh,
AVG(active_power_w) AS avg_power_w
FROM energy_readings
WHERE device_id = $1
AND time BETWEEN $2 AND $3
GROUP BY 1, 2
ORDER BY 1;
Разница между MAX и MIN накопленной энергии за период — потребление за этот период. Простая и надёжная формула, не требующая дельт.
Мобильное приложение: дашборд реального времени
На Flutter с BLoC:
class EnergyDashboardBloc extends Bloc<EnergyEvent, EnergyDashboardState> {
final EnergyRepository _repo;
StreamSubscription? _realtimeSub;
EnergyDashboardBloc(this._repo) : super(EnergyDashboardInitial()) {
on<LoadDashboard>((event, emit) async {
emit(EnergyDashboardLoading());
try {
final current = await _repo.getCurrentReadings(event.meterId);
final todayChart = await _repo.getHourlyConsumption(
event.meterId,
DateTime.now().subtract(const Duration(hours: 24)),
DateTime.now(),
);
emit(EnergyDashboardLoaded(current: current, hourlyChart: todayChart));
_startRealtimeUpdates(event.meterId);
} catch (e) {
emit(EnergyDashboardError(message: e.toString()));
}
});
on<RealtimeUpdated>((event, emit) {
if (state is EnergyDashboardLoaded) {
emit((state as EnergyDashboardLoaded).copyWith(current: event.reading));
}
});
}
void _startRealtimeUpdates(String meterId) {
_realtimeSub = _repo.realtimeStream(meterId)
.listen((reading) => add(RealtimeUpdated(reading)));
}
}
Карточки дашборда: активная мощность (кВт), напряжение по фазам (для трёхфазных счётчиков — три значения), cosφ (коэффициент мощности), потребление за текущий день, потребление за месяц vs прошлый месяц.
График потребления
fl_chart с BarChart для почасового потребления — стандарт в энергетических приложениях. Цветовая кодировка по тарифным зонам (ночной тариф — синий, дневной — оранжевый):
BarChartGroupData buildHourBarGroup(int hour, double consumption) {
final isNightTariff = hour < 7 || hour >= 23;
return BarChartGroupData(
x: hour,
barRods: [
BarChartRodData(
toY: consumption,
color: isNightTariff ? Colors.blue.shade300 : Colors.orange.shade400,
width: 12,
borderRadius: const BorderRadius.vertical(top: Radius.circular(4)),
),
],
);
}
Алерты по порогам
Мониторинг превышения договорной мощности — одна из ключевых функций для коммерческих объектов. Превышение максимальной мощности ведёт к штрафам от энергосбыта. Логика на бэкенде проверяет скользящий 15-минутный максимум, мобильное приложение получает алерт через FCM/APNs.
Для Andriod push-уведомление с PRIORITY_HIGH через FCM Data Message (не Notification Message) — доставляется даже в Doze mode. FCM Data Message обрабатывается в FirebaseMessagingService.onMessageReceived() и отображается как локальное уведомление с кастомным звуком.
Многообъектный мониторинг
Для управляющих компаний, которые следят за 50-100 объектами — список объектов с цветовой индикацией статуса (норма/превышение/нет данных), сортировка по потреблению. Ленивая загрузка через ListView.builder с пагинацией по 20 объектов.
Разработка приложения для мониторинга одного счётчика с дашбордом и историческими данными: 3-4 недели. Многообъектный мониторинг с управлением нагрузкой и алертами: 2-3 месяца. Стоимость рассчитывается после анализа оборудования и требований.







