Akıllı ev: Ev Asistanı'nda su ve elektrik tüketimi grafikleri oluşturuyoruz

Akıllı ev: Ev Asistanı'nda su ve elektrik tüketimi grafikleri oluşturuyoruz
Elektrik ve su için her ödeme aldığımda şaşırıyorum: Ailem gerçekten bu kadar çok mu tüketiyor? Evet, banyoda ısıtmalı zemin ve kombi var ama her zaman ateş yakmıyorlar. Aynı zamanda su tasarrufu da yapıyoruz (ancak banyoda etrafa su sıçratmayı da seviyoruz). Birkaç yıl önce ben zaten bağlı su sayaçları и elektrik akıllı bir eve, ama işlerin sıkıştığı yer burası. Bu makalenin asıl konusu olan tüketimi analiz etmeye ancak şimdi başladık.

Yakın zamanda akıllı ev sistemim olarak Ev Asistanı'na geçtim. Bunun nedenlerinden biri, çeşitli grafik türlerini uygun bir şekilde oluşturma yeteneği ile büyük miktarda verinin toplanmasını organize etme fırsatıydı.

Bu makalede açıklanan bilgiler yeni değil, tüm bunlar farklı soslar altında zaten internette anlatılmıştır. Ancak her makale genellikle yalnızca bir yaklaşımı veya yönü açıklar. Tüm bu yaklaşımları karşılaştırıp en uygun olanı kendim seçmem gerekiyordu. Makale hala veri toplama konusunda kapsamlı bilgi vermiyor ancak bunu nasıl yaptığımın bir nevi özeti niteliğinde. Bu nedenle yapıcı eleştiri ve iyileştirme önerileri memnuniyetle karşılanmaktadır.

Sorunun formüle edilmesi

Dolayısıyla bugünkü alıştırmanın amacı güzel su ve elektrik tüketimi grafikleri elde etmektir:

  • 2 gün boyunca saatlik
  • 2 hafta boyunca her gün
  • (isteğe bağlı) haftalık ve aylık

Bu konuda bazı zorluklar var:

  • Standart grafik bileşenleri genellikle oldukça zayıftır. En iyi ihtimalle, noktadan noktaya bir çizgi grafiği oluşturabilirsiniz.

    Yeterince dikkatli bakarsanız standart grafiğin yeteneklerini genişleten üçüncü taraf bileşenleri bulabilirsiniz. Bir ev asistanı için prensip olarak bu iyi ve güzel bir bileşendir mini grafik kartı, ancak aynı zamanda biraz sınırlıdır:

    • Bir çubuk grafiğin parametrelerini büyük aralıklara ayarlamak zordur (çubuğun genişliği bir saatin kesirleri cinsinden ayarlanır; bu, bir saatten daha uzun aralıkların kesirli sayılarla ayarlanacağı anlamına gelir)
    • Bir grafiğe farklı varlıklar ekleyemezsiniz (örneğin sıcaklık ve nem veya çubuk grafiği bir çizgiyle birleştiremezsiniz)
  • Ev asistanı varsayılan olarak en ilkel SQLite veritabanını kullanmakla kalmıyor (ve ben bir tamirci olarak MySQL veya Postgres'i kurmayı beceremedim), aynı zamanda veriler en uygun şekilde saklanmıyor. Yani örneğin bir parametrenin en küçük dijital parametresini bile her değiştirdiğinizde, veritabanına yaklaşık bir kilobayt boyutunda devasa bir json yazılır.
    {"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}}}

    Oldukça fazla sensörüm var (her odadaki sıcaklık sensörleri, su ve elektrik sayaçları) ve bazıları da oldukça fazla veri üretiyor. Örneğin, SDM220 elektrik sayacı tek başına her 10-15 saniyede bir yaklaşık bir düzine değer üretiyor ve ben bu tür yaklaşık 8 sayaç kurmak istiyorum.Ayrıca diğer sensörlere göre hesaplanan bir sürü parametre de var. O. tüm bu değerler veritabanını günlük 100-200 MB kolaylıkla şişirebilir. Bir hafta içinde sistem zar zor hareket edecek ve bir ay içinde flash sürücü ölecek (Raspberry PI'ye tipik bir ev asistanı kurulumu durumunda) ve bir yıl boyunca veri depolamak söz konusu bile olamaz.

  • Şanslıysanız ölçüm cihazınız tüketimi kendisi sayabilir. Dilediğiniz zaman sayaca dönüp birikmiş tüketim değerinin saat kaçta olduğunu sorabilirsiniz. Kural olarak dijital arayüze (RS232/RS485/Modbus/Zigbee) sahip tüm elektrik sayaçları bu imkanı sağlamaktadır.

    Cihazın bazı anlık parametreleri (örneğin anlık güç veya akım) basitçe ölçebilmesi veya her X watt-saat veya litrede bir darbe üretebilmesi daha da kötüdür. O zaman onu nasıl ve neyle entegre edeceğinizi, nerede değer biriktireceğinizi düşünmeniz gerekir. Bir sonraki raporun herhangi bir nedenle kaçırılma riski vardır ve sistemin bir bütün olarak doğruluğu soru işaretleri doğurmaktadır. Elbette tüm bunları ev asistanı gibi bir akıllı ev sistemine emanet edebilirsiniz, ancak hiç kimse veritabanındaki kayıt sayısıyla ilgili noktayı iptal etmedi ve sensörleri saniyede bir defadan fazla yoklamak mümkün olmayacak (bir ev asistanı mimarisinin sınırlandırılması).

Yaklaşım 1

Öncelikle ev asistanının kutudan neler sunduğuna bakalım. Belirli bir dönemdeki tüketimin ölçülmesi oldukça aranan bir işlevselliktir. Tabii ki, uzun zaman önce özel bir bileşen - Utility_meter biçiminde uygulandı.

Bileşenin özü, dahili olarak bir current_accumulated_value değişkeni oluşturması ve bunu belirli bir süre (saat/hafta/ay) sonrasında sıfırlamasıdır. Bileşenin kendisi giriş değişkenini (bazı sensörlerin değeri) izler, değerdeki değişikliklere kendisi abone olur - yalnızca bitmiş sonucu alırsınız. Bu şey konfigürasyon dosyasında sadece birkaç satırda anlatılıyor

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

Burada sensör.water_meter_cold, aldığım litre cinsinden geçerli sayaç değeridir doğrudan demir parçasından mqtt tarafından. Tasarım, saatlik ve günlük okumaları toplayan ve süre dolduktan sonra bunları sıfırlayan 2 yeni water_cold_hour_um ve water_cold_day_um sensörünü oluşturur. İşte yarım günlük saatlik pil grafiği.

Akıllı ev: Ev Asistanı'nda su ve elektrik tüketimi grafikleri oluşturuyoruz

Lovelace-UI için saatlik ve günlük grafiklerin kodu şuna benzer:

      - 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

Aslında bu yaklaşımın sorunu bu algoritmada yatmaktadır. Daha önce de belirttiğim gibi, her giriş değeri için (her bir sonraki litre için geçerli sayaç okuması) veri tabanında 1kb'lık kayıt oluşturulur. Her kullanım sayacı ayrıca tabana eklenen yeni bir değer üretir. Eğer saatlik/günlük/haftalık/aylık ve birkaç su yükseltici için okumalar toplamak ve bir paket elektrik sayacı eklemek istersem, bu çok fazla veri olacaktır. Daha doğrusu, çok fazla veri yok, ancak ev asistanı veritabanına bir sürü gereksiz bilgi yazdığından, veritabanının boyutu hızla artacak. Haftalık ve aylık grafiklerde tabanın boyutunu tahmin etmekten bile korkuyorum.

Ayrıca sayaç tek başına sorunu çözmez. Fayda sayacının ürettiği değerlerin grafiği, her saat başı 0'a sıfırlanan, monoton olarak artan bir fonksiyondur. Kullanıcının anlayabileceği, dönem içerisinde kaç litre tüketildiğini gösteren bir tüketim grafiğine ihtiyacımız var. Standart geçmiş grafik bileşeni bunu yapamaz ancak mini grafik kartı harici bileşeni bize yardımcı olabilir.

Bu lovelace-UI'nin kart kodu:

      - 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'

Sensör adı, grafik türü, renk gibi standart ayarlara ek olarak (standart turuncuyu beğenmedim), 3 ayarı not etmek önemlidir:

  • group_by:hour — grafik, çubuklar saatin başına hizalanacak şekilde oluşturulur
  • point_per_hour: 1 - her saat için bir çubuk
  • Ve en önemlisi,grega_func:max - her saat içindeki maksimum değeri alır. Testere dişi grafiğini çubuklara dönüştüren bu parametredir

Akıllı ev: Ev Asistanı'nda su ve elektrik tüketimi grafikleri oluşturuyoruz

Soldaki sütun sırasına dikkat etmeyin; bu, veri olmadığında bileşenin standart davranışıdır. Ancak veri yoktu - sadece birkaç saat önce sadece bu makalenin uğruna sayaç veri toplamayı açtım (mevcut yaklaşımımı aşağıda anlatacağım).

Bu resimde bazen veri ekranının çalıştığını ve çubukların aslında doğru değerleri yansıttığını göstermek istedim. Ama hepsi bu değil. Bazı nedenlerden dolayı, sabah 11'den 12'ye kadar olan süre için seçilen sütun 19 litre gösteriyor, ancak dişlek grafikte biraz daha yüksek olmasına rağmen aynı sensörden aynı süre için 62 litre tüketimi görüyoruz. Ya bir hata var ya da eller çarpık. Ancak sağdaki verilerin neden bozulduğunu hala anlamıyorum - oradaki tüketim normaldi, bu da dişlek grafikte de görülebiliyor.

Genel olarak bu yaklaşımın inandırıcılığını elde edemedim - grafik neredeyse her zaman bir tür sapkınlık gösteriyor.

Gündüz sensörü için benzer kod.

      - 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 parametresinin aralık olarak ayarlandığını ve point_per_hour parametresinin her şeyi yönettiğini lütfen unutmayın. Ve bu bileşenle ilgili başka bir sorun da burada yatmaktadır - point_per_hour bir saatlik veya daha kısa grafiklerde iyi çalışır, ancak daha büyük aralıklarda berbattır. Yani bir günde bir sütun alabilmek için 1/24=0.04166666 değerini girmem gerekiyordu. Haftalık ve aylık grafiklerden bahsetmiyorum bile.

Yaklaşım 2

Hala ev asistanını anlarken şu videoyla karşılaştım:


Bir arkadaş çeşitli Xiaomi soket türlerinden tüketim verilerini topluyor. Görevi biraz daha basit; sadece bugün, dün ve ay için tüketim değerini görüntülemek. Programa gerek yok.

Anlık güç değerlerinin manuel entegrasyonu hakkındaki tartışmaları bir kenara bırakalım - yukarıda bu yaklaşımın "doğruluğu" hakkında yazmıştım. Zaten aynı satış noktası tarafından toplanan birikmiş tüketim değerlerini neden kullanmadığı belli değil. Donanım içi entegrasyonun daha iyi çalışacağını düşünüyorum.

Videodan belirli bir süre boyunca tüketimi manuel olarak sayma fikrini ele alacağız. Adam sadece bugünün ve dünün değerlerini sayıyor ama biz daha da ileri giderek grafik çizmeye çalışacağız. Benim durumumda önerilen yöntemin özü aşağıdaki gibidir.

Mevcut sayaç okumalarını kaydedeceğimiz value_at_the_beginning_of_hour değişkenini oluşturalım
Zamanlayıcıyı kullanarak saatin sonunda (veya bir sonraki saatin başında) mevcut okuma ile saatin başında saklanan okuma arasındaki farkı hesaplarız. Bu fark, mevcut saatin tüketimi olacaktır - değeri sensöre kaydedeceğiz ve gelecekte bu değere dayalı bir grafik oluşturacağız.
Ayrıca mevcut sayaç değerini buraya yazarak value_at_beginning_of_hour değişkenini de “sıfırlamanız” gerekir.

Bütün bunlar ev asistanının kendisi aracılığıyla yapılabilir.

Önceki yaklaşıma göre biraz daha fazla kod yazmanız gerekecek. Öncelikle aynı “değişkenleri” oluşturalım. Kutunun dışında "değişken" varlığımız yok, ancak mqtt aracısının hizmetlerini kullanabiliriz. Değerleri oraya keep=true bayrağıyla göndereceğiz - bu, aracı içindeki değeri kaydeder ve ev asistanı yeniden başlatılsa bile herhangi bir zamanda oradan çıkarılabilir. Saatlik ve günlük sayaçları bir arada yaptım.

- 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

Tüm sihir, sırasıyla her saat ve her gece çalışan otomasyonda gerçekleşiyor.

- 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

Her iki otomasyon da 2 eylem gerçekleştirir:

  • Başlangıç ​​ve bitiş değerleri arasındaki fark olarak bir aralığın değerini hesaplayın
  • Bir sonraki aralık için temel değeri güncelle

Bu durumda grafiklerin oluşturulması olağan geçmiş grafiğiyle çözülür:

      - 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

Şuna benziyor:

Akıllı ev: Ev Asistanı'nda su ve elektrik tüketimi grafikleri oluşturuyoruz

Prensip olarak zaten ihtiyaç duyulan şey budur. Bu yöntemin avantajı, verilerin aralık başına bir kez oluşturulmasıdır. Onlar. saatlik grafik için günde yalnızca 24 kayıt.

Ne yazık ki, bu hala büyüyen bir tabanın genel sorununu çözmüyor. Aylık tüketim grafiği istersem en az bir yıl boyunca veri depolamam gerekecek. Ev asistanı tüm veritabanı için yalnızca tek bir depolama süresi ayarı sağladığından, sistemdeki TÜM verilerin bir yıl boyunca saklanması gerektiği anlamına gelir. Mesela ben yılda 200 metreküp su tüketiyorum, bu da veri tabanına 200000 kayıt anlamına geliyor. Ve diğer sensörleri hesaba katarsanız, rakam genellikle uygunsuz hale gelir.

Yaklaşım 3

Neyse ki akıllı insanlar InfluxDB veritabanını yazarak bu sorunu zaten çözmüşlerdir. Bu veritabanı, zamana dayalı verileri depolamak için özel olarak optimize edilmiştir ve farklı sensörlerin değerlerini depolamak için idealdir. Sistem ayrıca veritabanından değerleri çıkarmanıza ve daha sonra bunları çeşitli şekillerde toplamanıza olanak tanıyan SQL benzeri bir sorgulama dili de sağlar. Son olarak, farklı veriler farklı zamanlar için saklanabilir. Örneğin, sıcaklık veya nem gibi sıklıkla değişen değerler yalnızca birkaç hafta boyunca saklanabilirken, günlük su tüketimi değerleri bir yıl boyunca saklanabilir.

Akıllı insanlar, InfluxDB'nin yanı sıra, InfluxDB'den gelen verilere dayalı grafik çizme sistemi olan Grafana'yı da icat etti. Grafana farklı türde grafikler çizebilir, bunları ayrıntılı olarak özelleştirebilir ve en önemlisi bu grafikler, lovelace-UI ev asistanına "takılabilir".

İlham almak burada и burada. Makalelerde InfluxDB ve Grafana'nın kurulum ve ev asistanına bağlanma süreci ayrıntılı olarak açıklanmaktadır. Özel sorunumu çözmeye odaklanacağım.

O halde öncelikle influxDB'ye sayaç değerini eklemeye başlayalım. Ev asistanı konfigürasyonunun bir parçası (bu örnekte sadece soğuk değil, aynı zamanda sıcak suyla da eğleneceğim):

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

Tekrar şişirmemek için aynı verileri dahili ev asistanı veritabanına kaydetmeyi devre dışı bırakalım:

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

Şimdi InfluxDB konsoluna gidip veritabanımızı yapılandıralım. Özellikle belirli verilerin ne kadar süreyle saklanacağını yapılandırmanız gerekir. Bu sözde tarafından düzenlenir. saklama politikası - bu, her dahili veritabanının kendi ayarlarına sahip olduğu, ana veritabanındaki veritabanlarına benzer. Varsayılan olarak tüm veriler autogen adı verilen bir saklama politikasında saklanır; bu veriler bir hafta boyunca saklanacaktır. Saatlik verilerin bir ay, haftalık verilerin bir yıl saklanmasını, aylık verilerin ise hiçbir zaman silinmemesini istiyorum. Uygun saklama politikasını oluşturalım

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

Aslında asıl püf noktası, sürekli sorgulamayı kullanarak veri toplamaktır. Belirli aralıklarla otomatik olarak bir sorgu çalıştıran, bu sorguya ait verileri toplayan ve sonucu yeni bir değere ekleyen bir mekanizmadır. Bir örneğe bakalım (Okunabilirlik için bir sütuna yazıyorum ama gerçekte bu komutu tek satıra girmek zorunda kaldım)

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

Bu komut:

  • Homeassistant veritabanında cq_water_cold_hourly adında sürekli bir sorgu oluşturur
  • İstek her saat başı (zaman (1 saat)) yürütülecek
  • İstek, soğuk ve sıcak su okumaları da dahil olmak üzere homeassistant.autogen.l (litre) ölçümünden tüm verileri kazıyacaktır.
  • Toplanan veriler, soğuk ve sıcak su için bize ayrı değerler verecek olan varlık_id'sine göre gruplandırılacaktır.
  • Litre sayacı her saat içinde monoton olarak artan bir dizi olduğundan maksimum değerin alınması gerekecektir, bu nedenle toplama işlemi max(value) fonksiyonu tarafından gerçekleştirilecektir.
  • Yeni değer homeassistant.month.water_meter_hour dosyasına yazılacaktır; burada ay, bir aylık saklama süresiyle birlikte saklama politikasının adıdır. Ayrıca, soğuk ve sıcak suya ilişkin veriler, değer alanındaki ilgili varlık_id ve değer ile ayrı kayıtlara dağıtılacaktır.

Geceleri veya evde kimse olmadığında su tüketimi olmaz ve bu nedenle homeassistant.autogen.l'ye yeni giriş yapılmaz. Normal sorgularda değerlerin kaybolmasını önlemek için fill(önceki) komutunu kullanabilirsiniz. Bu, InfluxDB'yi son saatin değerini kullanmaya zorlayacaktır.

Ne yazık ki, sürekli sorgulamanın bir özelliği vardır: doldurma (önceki) hilesi çalışmaz ve kayıtlar oluşturulmaz. Üstelik bu aşılmaz bir sorundur birkaç yıldır tartışılıyor. Bu sorunu daha sonra ele alacağız, ancak fill(preview)'in sürekli sorguda olmasına izin verin - bu müdahale etmez.

Gelin ne olduğuna bakalım (tabii ki birkaç saat beklemeniz gerekiyor):

> 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

Veritabanındaki değerlerin UTC'de saklandığını unutmayın, dolayısıyla bu liste 3 saat farklılık gösterir - InfluxDB çıkışındaki sabah 7 değerleri, yukarıdaki grafiklerde sabah 10 değerlerine karşılık gelir. Ayrıca sabah 2 ile 5 arasında hiçbir kayıt bulunmadığını da unutmayın; bu, sürekli sorgulamanın aynı özelliğidir.

Gördüğünüz gibi, toplanan değer de monoton olarak artan bir dizidir; yalnızca girişler daha az sıklıkla - saatte bir kez gerçekleşir. Ancak bu bir sorun değil; grafik için doğru verileri getirecek başka bir sorgu yazabiliriz.

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)

Şifresini çözeceğim:

  • homeassistant.month.water_meter_hour veritabanından son güne ait asset_id='water_meter_cold' verilerini çıkaracağız (zaman >= şimdi() -24 saat).
  • Daha önce de belirttiğim gibi homeassistant.month.water_meter_hour dizisinde bazı girişler eksik olabilir. GROUP BY time(1h) ile bir sorgu çalıştırarak bu verileri yeniden oluşturacağız. Bu sefer fill(preview) beklendiği gibi çalışacak ve eksik verileri oluşturacaktır (fonksiyon önceki değeri alacaktır)
  • Bu istekte en önemli şey saat işaretleri arasındaki farkı hesaplayacak olan fark fonksiyonudur. Kendi başına çalışmaz ve bir toplama işlevi gerektirir. Bu daha önce kullanılan max() olsun.

Yürütme sonucu şöyle görünüyor

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

Sabah 2'den 5'e (UTC) kadar tüketim yoktu. Yine de sorgu fill(önceki) sayesinde aynı tüketim değerini döndürecek ve fark fonksiyonu bu değeri kendisinden çıkaracak ve çıktı 0 olacaktır ki bu da tam olarak olması gerekendir.

Geriye kalan tek şey bir grafik oluşturmaktır. Bunu yapmak için Grafana'yı açın, mevcut bazı kontrol panellerini açın (veya yeni bir kontrol paneli oluşturun) ve yeni bir panel oluşturun. Grafik ayarları bu şekilde olacaktır.

Akıllı ev: Ev Asistanı'nda su ve elektrik tüketimi grafikleri oluşturuyoruz

Soğuk ve sıcak su verilerini aynı grafikte göstereceğim. Talep yukarıda anlattığım ile tamamen aynı.

Ekran parametreleri aşağıdaki gibi ayarlanır. Benim için bu, adımlarla (merdivenlerle) giden çizgilerden oluşan bir grafik olacak. Stack parametresini aşağıda açıklayacağım. Aşağıda birkaç görüntüleme seçeneği daha var, ancak bunlar o kadar da ilginç değil.

Akıllı ev: Ev Asistanı'nda su ve elektrik tüketimi grafikleri oluşturuyoruz

Ortaya çıkan grafiği ev asistanına eklemek için yapmanız gerekenler:

  • grafik düzenleme modundan çıkın. Bazı nedenlerden dolayı doğru grafik paylaşım ayarları yalnızca kontrol paneli sayfasından sunuluyor
  • Grafik adının yanındaki üçgene tıklayın ve menüden paylaş'ı seçin
  • Açılan pencerede yerleştirme sekmesine gidin
  • Geçerli zaman aralığının işaretini kaldırın; zaman aralığını URL aracılığıyla ayarlayacağız
  • Gerekli konuyu seçin. Benim durumumda hafif
  • Ortaya çıkan URL'yi lovelace-UI ayarları kartına kopyalayın

      - 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"

Zaman aralığının (son 2 gün) kontrol paneli ayarlarında değil burada ayarlandığını lütfen unutmayın.

Grafik şuna benziyor. Son 2 gündür sıcak su kullanmadığım için sadece soğuk su grafiği çizildi.

Akıllı ev: Ev Asistanı'nda su ve elektrik tüketimi grafikleri oluşturuyoruz

Hangi grafiği, çizgi adımını mı yoksa gerçek çubukları mı daha çok sevdiğime hâlâ kendim karar vermedim. Bu nedenle sadece günlük tüketim grafiğinin bir örneğini vereceğim, bu sefer sadece barlarda. Sorgular yukarıda açıklananlara benzer şekilde oluşturulur. Görüntüleme seçenekleri şunlardır:

Akıllı ev: Ev Asistanı'nda su ve elektrik tüketimi grafikleri oluşturuyoruz

Bu grafik şuna benzer:

Akıllı ev: Ev Asistanı'nda su ve elektrik tüketimi grafikleri oluşturuyoruz

Stack parametresi hakkında. Bu grafikte bir sıcak su sütununun üstüne bir soğuk su sütunu çizilmiştir. Toplam yükseklik, o dönemdeki toplam soğuk ve sıcak su tüketimine karşılık gelir.

Gösterilen tüm grafikler dinamiktir. Farenizi ilgi çekici noktanın üzerine getirerek belirli bir noktanın ayrıntılarını ve değerini görebilirsiniz.

Ne yazık ki merhemde birkaç sinek vardı. Çubuk grafikte (adım çizgileri olan grafikten farklı olarak), çubuğun ortası gün ortasında değil saat 00:00'dadır. Onlar. sütunun sol yarısı önceki günün yerine çizilir. Yani Cumartesi ve Pazar grafikleri mavimsi bölgenin biraz soluna çiziliyor. Ta ki onu nasıl yeneceğimi bulana kadar.

Bir diğer sorun ise aylık aralıklarla düzgün çalışamamaktır. Gerçek şu ki saatin/gün/haftanın uzunluğu sabittir, ancak ayın uzunluğu her seferinde farklıdır. InfluxDB yalnızca eşit aralıklarla çalışabilir. Şu ana kadar beynim 30 günlük sabit bir aralık belirlemeye yetti. Evet, grafik yıl boyunca biraz dalgalanacak ve çubuklar aylara tam olarak uymayacaktır. Ancak bu şeyle sadece bir ekran ölçer olarak ilgilendiğim için bunda bir sakınca görmüyorum.

En az iki çözüm görüyorum:

  • Aylık çizelgelerden vazgeçin ve kendinizi haftalık çizelgelerle sınırlayın. Yılın 52 haftalık barı oldukça iyi görünüyor
  • Aylık tüketimin kendisini 2 numaralı yöntem olarak düşünün ve grafana'yı yalnızca güzel grafikler için kullanın. Oldukça doğru bir çözüm olacaktır. Karşılaştırma için geçen yılın grafiklerini bile üst üste koyabilirsiniz; grafana da bunu yapabilir.

Sonuç

Nedenini bilmiyorum ama bu tür grafiklere takıntılıyım. Hayatın tüm hızıyla devam ettiğini ve her şeyin değiştiğini gösteriyorlar. Dün çok vardı, bugün az, yarın başka bir şey olacak. Geriye kalan tek şey hane halkı üyeleriyle tüketim konusunda çalışmak. Ancak mevcut iştahla bile, ödeme makbuzundaki sadece büyük ve anlaşılmaz bir rakam, halihazırda oldukça anlaşılır bir tüketim resmine dönüşüyor.

Programcı olarak neredeyse 20 yıllık kariyerime rağmen veritabanlarıyla neredeyse hiç bağlantım olmadı. Bu nedenle harici bir veritabanı kurmak çok karmaşık ve anlaşılmaz bir şey gibi görünüyordu. Her şeyi değiştirdim yukarıdaki makale - uygun bir aletin takılmasının birkaç tıklamayla yapıldığı ve özel bir araçla grafik çizme işinin biraz daha kolaylaştığı ortaya çıktı.

Başlıkta elektrik tüketiminden bahsetmiştim. Ne yazık ki şu anda herhangi bir grafik sunamıyorum. Bir SDM120 ölçüm cihazı benim için öldü ve diğeri Modbus üzerinden erişildiğinde arızalı. Ancak bu, bu makalenin konusunu hiçbir şekilde etkilemez - grafikler su ile aynı şekilde oluşturulacaktır.

Bu yazıda bizzat denediğim yaklaşımları sundum. Elbette veri toplama ve görselleştirmeyi organize etmenin benim bilmediğim başka yolları da var. Yorumlarda bana bundan bahsedin, çok ilgileneceğim. Yapıcı eleştirilerden ve yeni fikirlerden memnuniyet duyacağım. Umarım sunulan materyal de birine yardımcı olacaktır.

Kaynak: habr.com

Yorum ekle