Розумний будинок: Будуємо графіки споживання води та електрики в Home Assistant

Розумний будинок: Будуємо графіки споживання води та електрики в Home Assistant
Щоразу отримуючи платіжку за електрику і воду я дивуюся - невже моя родина стооооолько споживає? Ну так, у ванній встановлена ​​тепла підлога і бойлер, але ж вони не кочегарять постійно. Воду теж як економимо (хоча поплескатися у ванній теж любимо). Кілька років тому я вже підключив лічильники води и електрики до розумного будинку, але на цьому справа так і застрягла. До аналізу споживання руки дійшли тільки зараз, про що, власне, ця стаття.

Нещодавно я перейшов на Home Assistant як систему розумного будинку. Однією з причин була можливість організувати збір великої кількості даних з можливістю зручної побудови різноманітних графіків.

Інформація, описана в цій статті, не нова, всі ці штуки під різними соусами вже були описані в Інтернеті. Але кожна стаття, як правило, описує лише один підхід чи аспект. Порівнювати всі ці підходи та вибирати найбільш підходящий довелося самому. Стаття все одно не дає вичерпної інформації щодо збору даних, але є свого роду конспектом того, як зробив я. Тож конструктивна критика та пропозиції щодо покращення вітаються.

Постановка завдання

Отже, мета сьогоднішньої вправи в тому, щоб отримати гарні графіки споживання води та електрики:

  • Погодинний за 2 дні
  • Подобовий за 2 тижні
  • (опціонально) понеділок та помісячний

У цьому нас чатують деякі складнощі:

  • Стандартні компоненти графіків, як правило, дуже убогі. У найкращому разі можна побудувати лінійний графік по точках.

    Якщо добре пошукати, можна знайти сторонні компоненти, які розширюють можливості стандартного графіка. Для home assistant, в принципі, непоганий і красивий компонент mini-graph-card, Але і він дещо обмежений:

    • Складно задавати параметри стовпчикового графіка на великих проміжках (ширина стовпчика задається в частках години, а значить проміжки довші за годину задаватимуться дробовими числами)
    • Не можна на один графік додавати різні сутності (наприклад, температуру і вологість, або стовпчиковий графік поєднати з лінією)
  • Мало того, що home assistant за замовчуванням використовує найпримітивнішу базу даних SQLite (а я, рукожоп, не подужав встановлення MySQL або Postgres), так і дані зберігаються не оптимальним чином. Так, наприклад, при кожній зміні кожного навіть найдрібнішого цифрового параметра параметра в базу записується величезний json розміром близько кілобайта
    {"entity_id": "sensor.water_cold_hourly", "old_state": {"entity_id": "sensor.water_cold_hourly", "state": "3", "attributes": {"source": "sensor.water_meter_cold", "status": "collecting", "last_period": "29", "last_reset": "2020-02-23T21:00:00.022246+02:00", "meter_period": "hourly", "unit_of_measurement": "l", "friendly_name": "water_cold_hourly", "icon": "mdi:counter"}, "last_changed": "2020-02-23T19:05:06.897604+00:00", "last_updated": "2020-02-23T19:05:06.897604+00:00", "context": {"id": "aafc8ca305ba4e49ad4c97f0eddd8893", "parent_id": null, "user_id": null}}, "new_state": {"entity_id": "sensor.water_cold_hourly", "state": "4", "attributes": {"source": "sensor.water_meter_cold", "status": "collecting", "last_period": "29", "last_reset": "2020-02-23T21:00:00.022246+02:00", "meter_period": "hourly", "unit_of_measurement": "l", "friendly_name": "water_cold_hourly", "icon": "mdi:counter"}, "last_changed": "2020-02-23T19:11:11.251545+00:00", "last_updated": "2020-02-23T19:11:11.251545+00:00", "context": {"id": "0de64b8af6f14bb9a419dcf3b200ef56", "parent_id": null, "user_id": null}}}

    Датчиків у мене досить багато (температурні датчики у кожній кімнаті, лічильники води та електрики), а деякі до того ж генерують чимало даних. Так наприклад, тільки лічильник електрики SDM220 генерує близько десятка значень кожні 10-15 секунд, а таких лічильників я б хотів встановити штук 8. А ще є ціла пачка параметрів, які обчислюються на основі інших датчиків. Т.о. всі ці значення легко можуть роздмухувати базу на 100-200 Мб щодня. Через тиждень система ледве повертатиметься, а через місяць здохне флешка (у разі типової установки home assistant на raspberry PI), а вже про зберігання даних цілий рік і мови бути не може.

  • Якщо вам пощастило, ваш лічильник сам вміє рахувати споживання. Ви будь-якої миті можете звернутися до лічильника і запитати котра година накопичене значення споживання. Як правило, всі лічильники електрики у яких є цифровий інтерфейс (RS232/RS485/Modbus/Zigbee) надають таку можливість.

    Гірше якщо пристрій може просто вимірювати якийсь миттєвий параметр (наприклад, миттєву потужність або струм), або просто генерувати імпульси кожні X ват-годин або літрів. Тоді треба думати, як і чим це інтегрувати і де накопичувати значення. Є ризик пропустити черговий звіт з якоїсь причини, та й точність системи загалом викликає питання. Можна, звичайно, це все доручити системі розумного будинку на зразок home assistant, але пункт про кількість записів у базі ніхто не скасовував, та й опитування датчиків частіше ніж раз на секунду влаштувати не вдасться (обмеження архітектури home assistant).

підхід 1

Спочатку подивимося, що надається home assistant з коробки. Вимір споживання за період - дуже потрібна функціональність. Зрозуміло, її давно реалізували у вигляді спеціалізованого компонента — utility_meter.

Суть компонента в тому, що він усередині заводить змінну поточне_накопичене_значення, і скидає її після закінчення заданого періоду (година/тиждень/місяць). Компонент сам моніторить вхідну змінну (значення якогось сенсора), сам підписується на зміни значення - ви просто отримуєте готовий результат. Описується ця штука всього кількома рядками в файлі конфігурації

utility_meter:
  water_cold_hour_um:
    source: sensor.water_meter_cold
    cycle: hourly
  water_cold_day_um:
    source: sensor.water_meter_cold
    cycle: daily

Тут sensor.water_meter_cold це поточне значення лічильника в літрах, які я отримую безпосередньо від залізяки по mqtt. Конструкція створює 2 нових сенсори water_cold_hour_um і water_cold_day_um, які накопичують годинні та денні показання, обнуляючи їх після закінчення періоду. Ось графік вартового акумулятора за півдня.

Розумний будинок: Будуємо графіки споживання води та електрики в Home Assistant

Код годинного та денного графіків для lovelace-UI виглядає так:

      - type: history-graph
        title: 'Hourly water consumption using vars'
        hours_to_show: 48
        entities:
          - sensor.water_hour

      - type: history-graph
        title: 'Daily water consumption using vars'
        hours_to_show: 360
        entities:
          - sensor.water_day

Власне, у цьому алгоритмі й криється проблема такого підходу. Як я вже згадував, на кожне значення (поточне показання лічильника на кожен наступний літр) генерується по 1кб запису в базі. Кожен utility meter також генерує за новим значенням, яке складається в базу. Якщо я хочу збирати годинникові/денні/тижневі/місячні показання, та за кількома стояками води, та ще пачку електролічильників додати — це буде дуже багато даних. Ну точніше даних щось небагато, але оскільки home assistant в базу пише купу зайвої інформації розмір бази зростатиме як на дріжджах. Боюся навіть прикидати розмір бази для потижневих та помісячних графіків.

Крім цього utility meter сам собою не вирішує поставлене завдання. Графік значень, які видає utility meter це монотонно зростаюча функція, яка скидається в 0 щогодини. Нам потрібен зрозумілий для користувача графік споживання, скільки ж літрів було з'їдено за період. Стандартний компонент history-graph такого не вміє, але може допомогти зовнішній компонент mini-graph-card.

Це код картки для lovelace-UI:

      - aggregate_func: max
        entities:
          - color: var(--primary-color)
            entity: sensor.water_cold_hour_um
        group_by: hour
        hours_to_show: 48
        name: "Hourly water consumption aggregated by utility meter"
        points_per_hour: 1
        show:
          graph: bar
        type: 'custom:mini-graph-card'

Крім стандартних налаштувань на кшталт імені сенсора, типу графіка, кольору (стандартний помаранчевий мені не сподобався) тут важливо відзначити 3 налаштування:

  • group_by:hour — графік генеруватиметься з вирівнюванням стовпчиків на початку години
  • points_per_hour: 1 — один стовпчик на кожну годину
  • І найважливіше, aggregate_func: max – брати максимальне значення в межах кожної години. Саме цей параметр і перетворює пилкоподібний графік на стовпчики.

Розумний будинок: Будуємо графіки споживання води та електрики в Home Assistant

На ряд стовпчиків зліва не звертайте уваги - це стандартна поведінка компонента, якщо немає даних. А даних і не було - я лише кілька годин тому включив збір даних по utility meter тільки заради цієї статті (свій поточний підхід я розповім трохи нижче).

На цій картинці я хотів показати, що іноді відображення даних навіть працює, і стовпчики справді відображають правильні значення. Тільки далеко не всі. Виділений стовпчик за проміжок з 11 до 12 ранку чомусь відображає 19 літрів, хоча на зубастому графіку трохи вище за цей же період з того ж самого сенсора бачимо споживання 62 літри. Або баг, або руки криві. А ось чому відламалися дані справа я поки не зрозумів - споживання там було в нормі, що також видно за зубастим графіком.

Загалом, правдоподібності цього підходу мені досягти не вдалося — графік майже завжди показує якусь брехню.

Аналогічний код для денного детектора.

      - aggregate_func: max
        entities:
          - color: var(--primary-color)
            entity: sensor.water_cold_day_um
        group_by: interval
        hours_to_show: 360
        name: "Daily water consumption aggregated by utility meter"
        points_per_hour: 0.0416666666
        show:
          graph: bar
        type: 'custom:mini-graph-card'

Зверніть увагу, що параметр group_by встановлений у значення interval, і рулює всім параметр points_per_hour. І в цьому полягає інша проблема цього компонента - points_per_hour добре працює на графіках за годину або менше, але огидно на більших проміжках. Так щоб отримати один стовпчик за день довелося вписати значення 1/24=0.04166666. Я вже не говорю про тижневі та місячні графіки.

підхід 2

Ще тільки розбираючись з home assistant я натрапив на ось це відео:


Товариш збирає дані споживання з кількох видів розеток Xiaomi. Завдання у нього трохи простіше просто виводити значення споживання за сьогодні, вчора і за місяць. Жодних графіків не потрібно.

Залишимо осторонь міркування про ручне інтегрування миттєвих значень потужності — про “точність” такого підходу я вже писав вище. Не зрозуміло, чому він не став використовувати накопичені значення споживання, які вже збираються тією ж розеткою. На мій погляд, інтегрування всередині залізяки буде працювати краще.

Від відео ми візьмемо ідею ручного підрахунку споживання за період. У мужика вважаються лише значення за сьогодні та за вчора, але ми підемо далі та спробуємо намалювати графік. Суть запропонованого методу у разі полягає в следующем.

Заведемо змінну значення_на початку_години, в яку запишемо поточні показання лічильника
За таймером наприкінці години (або на початку наступної) порахуємо різницю між поточним показанням та запам'ятаним на початку години. Ця різниця і буде споживанням за поточну годину — збережемо значення сенсор, і в майбутньому будемо за цим значенням будувати графік.
Також потрібно "обнулити" змінну значення_на початку_години записавши туди поточне значення лічильника.

Все це можна зробити через ж… засобами самого home assistant.

Коду доведеться написати дещо більше, ніж у попередньому підході. Для початку заведемо ці самі "змінні". З коробки у нас немає сутності "змінна", але можна скористатися послугами mqtt брокера. Відправлятимемо туди значення з прапором retain = true - це збереже значення всередині брокера, і його будь-якої миті можна звідти висмикнути, навіть при перезавантаженні home assistant. Я зробив відразу вартові та денні лічильники.

- platform: mqtt
  state_topic: "test/water/hour"
  name: water_hour
  unit_of_measurement: l

- platform: mqtt
  state_topic: "test/water/hour_begin"
  name: water_hour_begin
  unit_of_measurement: l

- platform: mqtt
  state_topic: "test/water/day"
  name: water_day
  unit_of_measurement: l

- platform: mqtt
  state_topic: "test/water/day_begin"
  name: water_day_begin
  unit_of_measurement: l

Вся магія відбувається в автоматизації, яка запускається щогодини і щоночі відповідно.

- id: water_new_hour
  alias: water_new_hour
  initial_state: true
  trigger:
    - platform: time_pattern
      minutes: 0
  action:
    - service: mqtt.publish
      data:
        topic: "test/water/hour"
        payload_template: >
          {{ (states.sensor.water_meter_cold.state|int) - (states.sensor.water_hour_begin.state|int) }}
        retain: true
    - service: mqtt.publish
      data:
        topic: "test/water/hour_begin"
        payload_template: >
          {{ states.sensor.water_meter_cold.state }}
        retain: true

- id: water_new_day
  alias: water_new_day
  initial_state: true
  trigger:
    - platform: time
      at: "00:00:00"
  action:
    - service: mqtt.publish
      data:
        topic: "test/water/day"
        payload_template: >
          {{ (states.sensor.water_meter_cold.state|int) - (states.sensor.water_day_begin.state|int) }}
        retain: true
    - service: mqtt.publish
      data:
        topic: "test/water/day_begin"
        payload_template: >
          {{ states.sensor.water_meter_cold.state }}
        retain: true

Обидві автоматизації виконують дві дії:

  • Обчислюють значення за інтервал як різницю між початковим та кінцевим значенням
  • Оновлення базового значення для наступного інтервалу

Побудова графіків у разі вирішується звичайним history-graph:

      - type: history-graph
        title: 'Hourly water consumption using vars'
        hours_to_show: 48
        entities:
          - sensor.water_hour

      - type: history-graph
        title: 'Daily water consumption using vars'
        hours_to_show: 360
        entities:
          - sensor.water_day

Виглядає це так:

Розумний будинок: Будуємо графіки споживання води та електрики в Home Assistant

У принципі, це вже те, що потрібно. Плюсом цього методу є те, що дані генеруються один раз за інтервал. Тобто. всього 24 записи на добу для годинного графіка.

На жаль, загальну проблему бази, що росте, це все одно не вирішує. Якщо я захочу графік помісячного споживання, то доведеться зберігати дані як мінімум протягом року. А оскільки home assistant надає лише одне налаштування тривалості зберігання на всю базу, то це означає, що ВСІ дані в системі доведеться зберігати цілий рік. Наприклад, за рік я споживаю 200 кубів води, а значить це 200000 записів у базу. А якщо врахувати ще й інші сенсори, то цифра взагалі стає непристойною.

підхід 3

На щастя, розумні люди вже вирішили цю проблему, написавши базу даних InfluxDB. Ця база спеціальним чином оптимізована під зберігання time-based даних та ідеально підходить для зберігання значень різних сенсорів. Система також надає SQL-подібну мову запитів, яка дозволяє виколупувати з бази значення, а потім їх агрегувати різними способами. Нарешті різні дані можна зберігати різний час. Наприклад, часто мінливі показання на кшталт температури чи вологості можна зберігати лише кілька тижнів, тоді як денні показання споживання води можна зберігати цілий рік.

Крім InfluxDB, розумні люди також винайшли Grafana — систему малювання графіків за даними з InfluxDB. Графана вміє малювати різні види графіків, детально їх кастомізувати, і, що найголовніше, ці графіки можна "устромити" на lovelace-UI home assistant'а.

Надихатися тут и тут. У статтях докладно описано процес встановлення та підключення InfluxDB та Grafana до home assistant. Я ж зосереджуся на вирішенні свого конкретного завдання.

Отже, насамперед почнемо складати значення лічильника в influxDB. Шматок конфігурації home assistant (у цьому прикладі я розважатимуся не тільки холодною, а й гарячою водою):

influxdb:
  host: localhost
  max_retries: 3
  default_measurement: state
  database: homeassistant
  include:
    entities:
      - sensor.water_meter_hot
      - sensor.water_meter_cold

Відключимо збереження цих самих даних внутрішню базу home assistant, щоб не роздмухувати її зайвий раз:

recorder:
  purge_keep_days: 10
  purge_interval: 1
  exclude:
    entities:
      - sensor.water_meter_hot
      - sensor.water_meter_cold

Перейдемо тепер до консолі InfluxDB і налаштуємо нашу базу. Зокрема, потрібно налаштувати скільки часу будуть зберігатися ті чи інші дані. Це регулюється т.зв. retention policy - це схоже на бази даних всередині основної бази даних, причому кожна внутрішня база має свої налаштування. За замовчуванням всі дані складаються в retention policy під назвою autogen, ці дані зберігаються тиждень. Я хотів би, щоб годинні дані зберігалися місяць, тижневі — рік, а місячні взагалі ніколи не видалялися. Створимо відповідні retention policy

CREATE RETENTION POLICY "month" ON "homeassistant" DURATION 30d REPLICATION 1
CREATE RETENTION POLICY "year" ON "homeassistant" DURATION 52w REPLICATION 1
CREATE RETENTION POLICY "infinite" ON "homeassistant" DURATION INF REPLICATION 1

Тепер, власне, головний трюк – агрегація даних за допомогою continuous query. Це механізм, який автоматично запускає запит через задані проміжки часу, агрегує дані з цього запиту, а результат складає нове значення. Розберемо на прикладі (я пишу в стовпчик для зручності читання, але насправді мені довелося вводити цю команду одним рядком)

CREATE CONTINUOUS QUERY cq_water_hourly ON homeassistant 
BEGIN 
  SELECT max(value) AS value 
  INTO homeassistant.month.water_meter_hour 
  FROM homeassistant.autogen.l 
  GROUP BY time(1h), entity_id fill(previous) 
END

Ця команда:

  • Створює continuous query на ім'я cq_water_cold_hourly у базі homeassistant
  • Запит буде виконуватися щогодини (time(1h))
  • Запит вигрібатиме всі дані з measurement'а homeassistant.autogen.l (літри), включаючи показання холодної та гарячої води
  • Агреговані дані будуть групуватися за entity_id, що створить нам окремі значення холодної та гарячої води
  • Оскільки лічильник літрів це монотонно зростаюча послідовність у межах кожної години, потрібно буде брати максимальне значення, тому агрегація буде проводитися функцією max(value)
  • Нове значення буде записано в homeassistant.month.water_meter_hour, де місяць це ім'я retention policy з терміном зберігання на місяць. Причому дані щодо холодної та гарячої води будуть розкидані в окремі записи з відповідним entity_id та значенням у полі value

Вночі або коли нікого немає вдома споживання води немає, а відповідно нових записів у homeassistant.autogen.l також немає. Щоб не було пропусків значень у звичайних запитах, можна використовувати fill(previous). Це змусить InfluxDB використовувати значення минулої години.

На жаль, у continuous query є особливість: трюк fill(previous) не працює і записи просто не створюються. Причому це якась непереборна проблема, яка обговорюється вже не перший рік. З цією проблемою ми розберемося пізніше, а fill(previous) у continuous query нехай буде - воно не заважає.

Перевіримо що вийшло (зрозуміло, потрібно почекати пару годин):

> select * from homeassistant.month.water_meter_hour group by entity_id
...
name: water_meter_hour
tags: entity_id=water_meter_cold
time                 value
----                 -----
...
2020-03-08T01:00:00Z 370511
2020-03-08T02:00:00Z 370513
2020-03-08T05:00:00Z 370527
2020-03-08T06:00:00Z 370605
2020-03-08T07:00:00Z 370635
2020-03-08T08:00:00Z 370699
2020-03-08T09:00:00Z 370761
2020-03-08T10:00:00Z 370767
2020-03-08T11:00:00Z 370810
2020-03-08T12:00:00Z 370818
2020-03-08T13:00:00Z 370827
2020-03-08T14:00:00Z 370849
2020-03-08T15:00:00Z 370921

Зверніть увагу, що значення бази зберігаються в UTC, тому у цьому списку відрізняються на 3 години — значення за 7 ранку у виведенні InfluxDB відповідають значенням за 10 ранку на графіках вище. Також зверніть увагу, що між 2 і 5 ранку записів просто немає - це та сама особливість continuous query.

Як бачите, агреговане значення також є монотонно зростаючою послідовністю, тільки записи йдуть рідше - раз на годину. Але це не проблема — ми можемо написати ще один запит, який видобуватиме правильні дані для графіка.

SELECT difference(max(value)) 
FROM homeassistant.month.water_meter_hour 
WHERE entity_id='water_meter_cold' and time >= now() -24h 
GROUP BY time(1h), entity_id 
fill(previous)

Розшифрую:

  • З бази homeassistant.month.water_meter_hour витягнемо дані для entity_id='water_meter_cold' за останню добу (time >= now() -24h).
  • Як я вже згадував у послідовності homeassistant.month.water_meter_hour можуть бути відсутні деякі записи. Ці дані ми знову згенеруємо, запустивши запит з GROUP BY time(1h). Цього разу fill(previous) спрацює як слід, згенерувавши відсутні дані (функція візьме попереднє значення)
  • Найголовніше у цьому запиті це функція difference, яка й вважатиме різницю між часовими відмітками. Сама по собі вона не працює і вимагає функцію, що агрегує. Нехай це буде max() використаний раніше.

Результат виконання виглядає так

name: water_meter_hour
tags: entity_id=water_meter_cold
time                 difference
----                 ----------
...
2020-03-08T02:00:00Z 2
2020-03-08T03:00:00Z 0
2020-03-08T04:00:00Z 0
2020-03-08T05:00:00Z 14
2020-03-08T06:00:00Z 78
2020-03-08T07:00:00Z 30
2020-03-08T08:00:00Z 64
2020-03-08T09:00:00Z 62
2020-03-08T10:00:00Z 6
2020-03-08T11:00:00Z 43
2020-03-08T12:00:00Z 8
2020-03-08T13:00:00Z 9
2020-03-08T14:00:00Z 22
2020-03-08T15:00:00Z 72

З 2 до 5 ранку (UTC) споживання не було. Проте запит поверне те саме значення споживання завдяки fill(previous), а функція difference це значення відніме саме з себе і на виході отримаємо 0, що власне і потрібно.

Залишилася справа за малим — збудувати графік. Для цього відкриємо Grafana, відкриємо якийсь існуючий (або створимо новий) дашборд, створимо нову панель. Налаштування графіків будуть такими.

Розумний будинок: Будуємо графіки споживання води та електрики в Home Assistant

Я відображатиму дані по холодній та гарячій воді на одному графіку. Запит такий же, як я описав вище.

Параметри відображення задаються так. У мене це буде графік лініями (lines), що йде сходинками (stairs). Параметр Stack я поясню трохи нижче. Там нижче ще пара параметрів відображення, але вони не такі цікаві.

Розумний будинок: Будуємо графіки споживання води та електрики в Home Assistant

Щоб додати отриманий графік до home assistant потрібно:

  • вийти із режиму редагування графіка. Чомусь правильні налаштування шарингу графіків пропонуються лише зі сторінки дашборду
  • Натиснути на трикутник біля імені графіка, у меню вибрати share
  • У вікні, що відкрилося, перейти на вкладку embed
  • Прибрати галочку current time range — часовий діапазон ми будемо задавати через URL
  • Вибрати потрібну тему. У моєму випадку це light
  • Скопіювати URL-адресу в картку налаштувань lovelace-UI

      - type: iframe
        id: graf_water_hourly
        url: "http://192.168.10.200:3000/d-solo/rZARemQWk/water?orgId=1&panelId=2&from=now-2d&to=now&theme=light"

Зверніть увагу, що тимчасовий діапазон (останні 2 дні) задається саме тут, а не в налаштуваннях дашборду.

Виглядає графік ось так. Гарячу воду не за останні 2 дні не використовував, тому малюється тільки графік холодної води.

Розумний будинок: Будуємо графіки споживання води та електрики в Home Assistant

Я так для себе і не вирішив який графік мені більше подобається, лінією-сходинкою, чи реальними стовпчиками. Тому просто наведу приклад денного графіка споживання, лише цього разу стовпчиками. Запити будуються аналогічно вищеописаним. Параметри відображення такі:

Розумний будинок: Будуємо графіки споживання води та електрики в Home Assistant

Виглядає цей графік так:

Розумний будинок: Будуємо графіки споживання води та електрики в Home Assistant

Так ось про параметр Stack. У цьому графіку стовпчик холодної води малюється поверх гарячої стовпчика. Загальна висота відповідає сумарному споживанню холодної та гарячої води за період.

Усі показані графіки – динамічні. Можна навести мишкою на точку, що цікавить, і подивитися деталі і значення в конкретній точці.

На жаль, без пари ложок дьогтю не обійшлося. На стовпчиковому графіку (на відміну від графіка лініями-сходинками) середина стовпчика знаходиться не в середині доби, а о 00:00. Тобто. ліва половина стовпчика намальована на місці попереднього дня. Так ось графіки за суботу та неділю намальовані трохи лівіше за синювату зону. Поки що я не придумав, як це перемогти.

Інша проблема полягає у неможливості правильно працювати з інтервалами на місяць. Справа в тому, що довжина години/дня/тижня фіксована, а ось довжина місяця щоразу різна. InfluxDB вміє працювати лише з однаковими інтервалами. Поки моїх мізків вистачило, щоб задати фіксований інтервал у 30 днів. Так, графік протягом року трохи попливе і стовпчики не зовсім точно відповідатимуть місяцям. Але оскільки мені ця штука цікава просто як показометр, то я з цим ок.

Рішень бачу як мінімум два:

  • Забити на помісячні графіки та обмежитися тижневими. 52 тижневі стовпчики за рік цілком непогано виглядають
  • Саме помісячне споживання вважати способом №2, а графану лише для гарних графіків використати. Цілком собі точне рішення вийде. Можна навіть накласти графіки за минулий рік для порівняння — графа і таке вміє.

Висновок

Не знаю чому, але я тягнуся від таких графіків. Вони показують, що життя кипить і все змінюється. Вчора було багато, сьогодні мало, завтра буде якось ще. Залишилося попрацювати із домочадцями на тему споживання. Але навіть за поточних апетитів просто велика і незрозуміла цифра в платіжці вже перетворюється на досить зрозумілу картину споживання.

Незважаючи на майже 20-річну кар'єру програміста, з базами даних практично не перетинався. Тому встановлення зовнішньої бази даних здавалося чимось таким незрозумілим. Все змінила вищезгадана стаття - виявилося, що прикручування відповідного інструменту робиться в пару кліків, а зі спеціалізованим інструментом завдання побудови графіків стає трохи простіше.

У заголовку я згадав споживання електрики. На жаль, на даний момент я не можу навести жодного графіка. Один лічильник SDM120 у мене здох, а інший глючить при зверненні по Modbus. Втім, на тему цієї статті це ніяк не впливає — графіки будуть будуватися тим самим способом, як і для води.

У цій статті я навів ті підходи, які випробував сам. Напевно, є ще якісь способи організації збору та візуалізації даних, про які я не знаю. Розкажіть мені про це у коментарях, мені буде дуже цікаво. Буду радий конструктивній критиці та новим ідеям. Сподіваюся викладений матеріал також комусь допоможе.

Джерело: habr.com

Додати коментар або відгук