Умен дом: Строим графики на потреблението на вода и електричество в 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.

Същността на компонента е, че той вътре създава променлива текуще_накоплениe_значение и я нулира след изтичането на зададения период (час/седмица/месец). Компонентът сам мониторира входящата променлива (стойността на някакъв сензор), сам се абонира за промените в стойността — вие просто получавате готовия резултат. Описва се тази функция само с няколко реда в конфигурационния файл.

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: 'Часово потребление на вода с помощта на променливи'
        hours_to_show: 48
        entities:
          - sensor.water_hour

      - type: history-graph
        title: 'Дневно потребление на вода с помощта на променливи'
        hours_to_show: 360
        entities:
          - sensor.water_day

Собствено в този алгоритъм се крие проблемът на подхода. Както споменах, за всяко входящо значение (текущото показание на измервателя за всеки следващ литър) се генерират по 1кб запис в базата. Всеки измервател на комунални услуги също генерира ново значение, което се записва в базата. Ако искам да събирам почасови/дневни/седмични/месечни показания, и за няколко стояка вода, а и да добавя пакет с електромери — това ще бъде изключително много данни. Всъщност, данните не са много, но тъй като home assistant записва куп ненужна информация в базата, размерът ѝ ще расте бързо. Страхувам се дори да правя приблизителни оценки за размера на базата за седмични и месечни графици.

Освен това измервателят на комунални услуги сам по себе си не решава зададeната задача. Графикът на стойностите, които предоставя измервателят на комунални услуги, е монотонно нарастваща функция, която се нулира на 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: "Часово потребление на вода, агрегирано по измервател на комунални услуги"
        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

Не обръщайте внимание на реда от колонки отляво — това е стандартно поведение на компонента, ако няма данни. А данни нямаше — само преди няколко часа активирах събирането на данни по измервателя на комунални услуги единствено за тази статия (сегашният ми подход ще споделя малко по-долу).

На тази картинка исках да покажа, че понякога визуализацията на данни наистина работи и колоните отразяват правилните стойности. Но не всичките. Избраната колона за интервала от 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: "Дневно потребление на вода агрегирано по измервателен уред"
        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

И двете автоматизации извършват 2 действия:

  • Изчисляват стойността за интервала като разлика между началната и крайната стойност
  • Актуализират основната стойност за следващия интервал

Изграждането на графики в този случай се решава с обикновен history-graph:

      - type: history-graph
        title: 'Часово потребление на вода с помощта на променливи'
        hours_to_show: 48
        entities:
          - sensor.water_hour

      - type: history-graph
        title: 'Дневно потребление на вода с помощта на променливи'
        hours_to_show: 360
        entities:
          - sensor.water_day

Изглежда така:

Умен дом: Строим графики на потреблението на вода и електричество в Home Assistant

В принципе това вече е необходимо. Предимството на този метод е, че данните се генерират веднъж за интервала. Т.е. общо 24 записа за денонощие за часовия график.

За съжаление, общата задача на нарастващата база не се решава. Ако искам месечен отчет за потреблението, ще трябва да съхранявам данни поне за година. А тъй като home assistant предоставя само една настройка за продължителността на съхранение за цялата база, това означава, че ВСИЧКИ данни в системата ще трябва да се съхраняват цяла година. Например за година потребявам 200 кубически метра вода, което означава 200000 записа в базата. А ако вземем предвид и други сензори, числото става изобщо неприлично.

Подход 3

Щастливо, умните хора вече решиха този проблем, създавайки базата данни InfluxDB. Тази база е специално оптимизирана за съхранение на времево базирани данни и е идеална за съхранение на стойностите на различни сензори. Системата също така предоставя SQL-подобен език за запитвания, който позволява извличане на стойности от базата, а след това ги агрегира по различни начини. Накрая, различни данни може да се съхраняват различно време. Например, често променящите се показания като температура или влажност могат да се съхраняват само няколко седмици, докато дневните показания за потребление на вода могат да се съхраняват цяла година.

Освен InfluxDB, умните хора също изобретиха Grafana — система за визуализация на данни от InfluxDB. Grafana може да рисува различни видове графики, да ги персонализира подробно и, което е най-важно, тези графики могат да се "вградят" в 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’a homeassistant.autogen.l (литри), включително данните за студена и гореща вода.
  • Агрегираните данни ще се групират по entity_id, което ще създаде отделни стойности за студената и гореща вода.
  • Тъй като броячът на литрите е монотонно растяща последователност, в рамките на всеки час ще трябва да вземем максималната стойност, затова агрегацията ще се извършва с функцията max(value).
  • Новото значение ще бъде записано в homeassistant.month.water_meter_hour, където month е името на retention policy с срок на съхранение един месец. Освен това данните за студена и гореща вода ще бъдат разпределени в отделни записи с съответното entity_id и стойност в полето value.

През нощта или когато няма никой у дома потреблението на вода е нулево, а следователно и нови записи в homeassistant.autogen.l няма. За да избегнем пропуски на стойности в обикновените запитвания, можем да използваме fill(previous). Това ще накара InfluxDB да използва стойността от предишния час.

За съжаление, в continuous query има особеност: трикът fill(previous) не работи и записите просто не се създават. Освен това, това е непостоянен проблем, който се обсъжда вече не за първа година. С този проблем ще се занимаем по-късно, а fill(previous) в continuous query нека остане — не пречи.

Нека проверим какво се е получило (разбира се, трябва да изчакаме няколко часa):

> 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' за последните 24 часа (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

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster