Խելացի տուն. գծագրել ջրի և էլեկտրաէներգիայի սպառումը տնային օգնական

Խելացի տուն. գծագրել ջրի և էլեկտրաէներգիայի սպառումը տնային օգնական
Ամեն անգամ, երբ ես ստանում եմ էլեկտրաէներգիայի և ջրի համար վճարում, մտածում եմ՝ իսկապե՞ս ընտանիքս այդքան շատ է սպառում: Դե, այո, լոգարանում կա տաքացվող հատակ և կաթսա, բայց նրանք անընդհատ չեն աշխատում որպես հրշեջ: Մենք, թվում է, նաև խնայում ենք ջուրը (չնայած մեզ դուր է գալիս նաև լոգարանում շաղ տալը): Մի քանի տարի առաջ ես արդեն միացված ջրաչափեր и էլեկտրականություն դեպի խելացի տուն, բայց այստեղ ամեն ինչ խրվել է: Սպառման վերլուծությանը ձեռքերը հասել են միայն հիմա, ինչի մասին, ըստ էության, այս հոդվածն է։

Ես վերջերս անցել եմ Home Assistant-ին՝ որպես իմ խելացի տան համակարգին: Պատճառներից մեկը պարզապես մեծ քանակությամբ տվյալների հավաքագրումը կազմակերպելու ունակությունն էր՝ տարբեր տեսակի գրաֆիկների հարմար կառուցման հնարավորությամբ։

Այս հոդվածում նկարագրված տեղեկատվությունը նոր չէ, այս բոլոր բաները տարբեր սոուսների տակ արդեն նկարագրված են համացանցում։ Բայց յուրաքանչյուր հոդված, որպես կանոն, նկարագրում է միայն մեկ մոտեցում կամ ասպեկտ։ Ես պետք է համեմատեի այս բոլոր մոտեցումները և ինքս ընտրեի ամենահարմարը։ Հոդվածը դեռևս չի տրամադրում տվյալների հավաքագրման վերաբերյալ սպառիչ տեղեկատվություն, բայց մի տեսակ ամփոփում է, թե ինչպես եմ դա արել: Այսպիսով, կառուցողական քննադատությունը և բարելավման առաջարկները ողջունելի են:

Խնդրի ձևակերպում

Այսպիսով, այսօրվա վարժության նպատակն է ստանալ ջրի և էլեկտրաէներգիայի սպառման գեղեցիկ գրաֆիկներ.

  • Ժամային 2 օր
  • Ամեն օր 2 շաբաթ
  • (ըստ ցանկության) շաբաթական և ամսական

Այս հարցում որոշ դժվարություններ կան.

  • Ստանդարտ գծապատկերների բաղադրիչները հակված են բավականին վատ լինելուն: Լավագույն դեպքում, դուք կարող եք կառուցել գծային գրաֆիկ ըստ կետերի:

    Եթե ​​լավ որոնեք, կարող եք գտնել երրորդ կողմի բաղադրիչներ, որոնք ընդլայնում են ստանդարտ գծապատկերի հնարավորությունները: Տնային օգնականի համար, սկզբունքորեն, լավ և գեղեցիկ բաղադրիչ մինի գրաֆիկական քարտ, բայց նաև որոշ չափով սահմանափակ է.

    • Դժվար է սահմանել գծապատկերի պարամետրերը մեծ ընդմիջումներով (գոտի լայնությունը սահմանվում է ժամի կոտորակներով, ինչը նշանակում է, որ մեկ ժամից ավելի երկար ընդմիջումները կսահմանվեն կոտորակային թվերով)
    • Դուք չեք կարող մեկ գրաֆիկում ավելացնել տարբեր միավորներ (օրինակ՝ ջերմաստիճան և խոնավություն, կամ միավորել գծապատկերը գծի հետ)
  • Տնային օգնականը ոչ միայն լռելյայն օգտագործում է 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 ՄԲ-ով: Մեկ շաբաթից համակարգը հազիվ կթռչի, իսկ մեկ ամսից ֆլեշ կրիչը կմեռնի (տնային օգնականի տիպիկ տեղադրման դեպքում raspberry PI-ի վրա), և մի ամբողջ տարի տվյալների պահպանման մասին խոսք լինել չի կարող։

  • Եթե ​​դուք հաջողակ եք, ձեր հաշվիչն ինքնին կարող է հաշվել սպառումը: Դուք կարող եք ցանկացած պահի կապվել հաշվիչի հետ և հարցնել, թե որ ժամին է կուտակված սպառման արժեքը: Որպես կանոն, նման հնարավորություն են տալիս բոլոր էլեկտրաէներգիայի հաշվիչները, որոնք ունեն թվային ինտերֆեյս (RS232/RS485/Modbus/Zigbee):

    Ավելի վատ, եթե սարքը կարող է պարզապես չափել որոշ ակնթարթային պարամետր (օրինակ՝ ակնթարթային հզորություն կամ հոսանք), կամ պարզապես իմպուլսներ արտադրել յուրաքանչյուր X վտ/ժ կամ լիտր: Այնուհետև պետք է մտածել, թե ինչպես և ինչով այն ինտեգրել և որտեղ արժեք կուտակել: Որևէ պատճառով հաջորդ զեկույցը բաց թողնելու վտանգ կա, և ընդհանուր առմամբ համակարգի ճշգրտությունը հարցեր է առաջացնում: Դուք, իհարկե, կարող եք այս ամենը վստահել խելացի տան համակարգին, ինչպիսին է տնային օգնականը, բայց ոչ ոք չեղյալ չի հայտարարել տվյալների բազայում գրառումների քանակի մասին կետը, և սոցհարցման սենսորները վայրկյանը մեկից ավելի չեն աշխատի (սահմանափակման սահմանափակում. տան օգնական ճարտարապետություն):

Մոտեցում 1

Նախ, եկեք տեսնենք, թե ինչ տնային օգնական է տրամադրվում տուփից: Սպառման չափումը որոշակի ժամանակահատվածում խիստ պահանջված գործառույթ է: Իհարկե, այն վաղուց ներդրվել է որպես մասնագիտացված բաղադրիչ՝ 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, որոնք կուտակում են ժամային և ամենօրյա ընթերցումները՝ որոշակի ժամանակահատվածից հետո դրանք զրոյացնելով: Ահա կես օրվա ժամային մարտկոցի գրաֆիկը:

Խելացի տուն. գծագրել ջրի և էլեկտրաէներգիայի սպառումը տնային օգնական

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կբ գրառում: Յուրաքանչյուր կոմունալ հաշվիչ առաջացնում է նաև նոր արժեք, որը նույնպես ավելացվում է բազայի վրա: Եթե ​​ես ուզում եմ հավաքել ժամային/օրական/շաբաթական/ամսական ընթերցումներ, այո, մի քանի ջրի բարձրացնող սարքերի համար, և նույնիսկ մի տուփ էլեկտրական հաշվիչներ ավելացնել, սա շատ տվյալներ կլինի: Դե, ավելի ճիշտ, շատ տվյալներ չկան, բայց քանի որ տնային օգնականը ավելորդ տեղեկությունների մի փունջ է գրում տվյալների բազայում, տվյալների բազայի չափը կաճի թռիչքներով և սահմաններով: Ես նույնիսկ վախենում եմ շաբաթական և ամսական գծապատկերների բազայի չափը գնահատել:

Բացի այդ, կոմունալ հաշվիչը ինքնին չի լուծում խնդիրը: Օգտակար հաշվիչի սյուժեն միապաղաղ աճող ֆունկցիա է, որը ամեն ժամ վերականգնվում է 0-ի: Մեզ անհրաժեշտ է նաև օգտագործման համար հարմար ժամանակացույց, թե քանի լիտր է կերել այդ ժամանակահատվածում։ Ստանդարտ պատմություն-գրաֆիկ բաղադրիչը դա չի անում, բայց արտաքին մինի-գրաֆիկ-քարտ բաղադրիչը կարող է օգնել մեզ:

Սա 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 - գծապատկերը կստեղծվի սյունակներով, որոնք հավասարեցված են ժամի սկզբին
  • միավոր_ժամ. 1 - ժամում մեկ բար
  • Եվ ամենակարևորը, aggregate_func. max-ը յուրաքանչյուր ժամվա ընթացքում առավելագույն արժեք վերցնելն է: Հենց այս պարամետրն է, որ սղոցի գծապատկերը վերածում է ձողերի:

Խելացի տուն. գծագրել ջրի և էլեկտրաէներգիայի սպառումը տնային օգնական

Ուշադրություն մի դարձրեք ձախ կողմում գտնվող սյունակների շարքին. սա բաղադրիչի ստանդարտ վարքագիծն է, եթե տվյալներ չկան: Բայց ոչ մի տվյալ չկար. ես միայն մի քանի ժամ առաջ միացրեցի տվյալների հավաքագրումը կոմունալ հաշվիչի միջոցով հենց այս հոդվածի համար (ես կնկարագրեմ իմ ներկայիս մոտեցումը մի փոքր ավելի ցածր):

Այս նկարում ես ուզում էի ցույց տալ, որ երբեմն տվյալների ցուցադրումը նույնիսկ աշխատում է, և գծերը իսկապես արտացոլում են ճիշտ արժեքները: Բայց սա դեռ ամենը չէ: Չգիտես ինչու, ժամը 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 պարամետրը սահմանված է ընդմիջումով, և points_per_hour պարամետրը կարգավորում է ամեն ինչ: Եվ սա ևս մեկ խնդիր է այս բաղադրիչի հետ կապված. points_per_hour-ը լավ է աշխատում մեկ ժամ կամ պակաս գծապատկերների վրա, բայց զզվելի է ավելի մեծ ընդմիջումներով: Այսպիսով, մեկ օրում մեկ սյունակ ստանալու համար ես պետք է մուտքագրեի 1/24=0.04166666 արժեքը: Ես չեմ խոսում շաբաթական և ամսական աղյուսակների մասին:

Մոտեցում 2

Տնային օգնականին դեռ պարզելիս հանդիպեցի այս տեսանյութին.


Ընկերը սպառման տվյալներ է հավաքում Xiaomi-ի մի քանի տեսակի վարդակից: Նրա խնդիրը մի փոքր ավելի պարզ է. պարզապես ցուցադրեք սպառման արժեքը այսօրվա, երեկվա և ամսվա համար: Դիագրամներ չեն պահանջվում:

Եկեք մի կողմ թողնենք ակնթարթային հզորության արժեքների ձեռքով ինտեգրման մասին փաստարկները - ես արդեն գրել եմ վերևում այս մոտեցման «ճշգրտության» մասին: Անհասկանալի է, թե ինչու նա չի օգտագործել կուտակված սպառման արժեքները, որոնք արդեն հավաքագրվում են նույն կետով։ Իմ կարծիքով, երկաթի կտորի ներսում ինտեգրումն ավելի լավ կաշխատի:

Տեսանյութից մենք կվերցնենք սպառումը որոշակի ժամանակահատվածի համար ձեռքով հաշվելու գաղափարը: Տղամարդու համար հաշվի են առնվում միայն այսօրվա և երեկվա արժեքները, բայց մենք ավելի հեռուն կգնանք և կփորձենք գծել գրաֆիկ: Առաջարկվող մեթոդի էությունը իմ դեպքում հետևյալն է.

Մենք կստեղծենք փոփոխական value_at_the_beginning_of_hour, որտեղ կգրենք ընթացիկ հաշվիչների ընթերցումները
Համաձայն ժամի վերջի (կամ հաջորդի սկզբի) ժամանակաչափի, մենք հաշվարկում ենք ընթացիկ ընթերցման և ժամի սկզբում պահվածի տարբերությունը: Այս տարբերությունը կլինի ընթացիկ ժամի սպառումը. մենք արժեքը կպահենք սենսորում, իսկ ապագայում մենք կկառուցենք գրաֆիկ այս արժեքի հիման վրա:
Պետք է նաև «վերակայել» value_at_beginning_of_hour փոփոխականը՝ այնտեղ գրելով հաշվիչի ընթացիկ արժեքը:

Այս ամենը կարելի է անել լավ ... տնային օգնականի միջոցով:

Դուք ստիպված կլինեք գրել մի փոքր ավելի շատ կոդ, քան նախորդ մոտեցմամբ: Սկսենք այս «փոփոխականներից». Մենք չունենք «փոփոխական» էություն, բայց դուք կարող եք օգտվել mqtt բրոքերի ծառայություններից: Մենք արժեքներ կուղարկենք այնտեղ retain=true դրոշակով. սա կպահի արժեքը բրոքերի ներսում, և այն կարող է դուրս հանվել ցանկացած պահի, նույնիսկ երբ տնային օգնականը վերագործարկվի: Միանգամից ժամային և ամենօրյա հաշվիչներ էի անում։

- 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 բան.

  • Հաշվարկեք արժեքը մեկ ընդմիջումով որպես սկզբի և ավարտի արժեքի տարբերություն
  • Թարմացրեք բազային արժեքը հաջորդ միջակայքի համար

Գրաֆիկների կառուցումն այս դեպքում լուծվում է սովորական պատմություն-գրաֆիկով.

      - 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

Այն կարծես այսպիսին է.

Խելացի տուն. գծագրել ջրի և էլեկտրաէներգիայի սպառումը տնային օգնական

Սկզբունքորեն, սա արդեն այն է, ինչ ձեզ հարկավոր է: Այս մեթոդի առավելությունն այն է, որ տվյալները գեներացվում են մեկ ընդմիջումով: Նրանք. օրական ընդհանուր 24 գրառում ժամային աղյուսակի համար:

Ցավոք սրտի, դա դեռ չի լուծում աճող բազայի ընդհանուր խնդիրը։ Եթե ​​ես ուզում եմ ամսական սպառման գրաֆիկ, ես պետք է տվյալները պահեմ առնվազն մեկ տարի: Եվ քանի որ տնային օգնականը տրամադրում է միայն մեկ պահպանման տևողության կարգավորում ամբողջ տվյալների բազայի համար, սա նշանակում է, որ համակարգի ԲՈԼՈՐ տվյալները պետք է պահվեն մեկ ամբողջ տարի: Օրինակ՝ մեկ տարվա ընթացքում ես սպառում եմ 200 խմ ջուր, ինչը նշանակում է տվյալների բազայում 200000 գրառում։ Եվ եթե հաշվի առնեք այլ սենսորներ, ապա գործիչը դառնում է ընդհանուր առմամբ անպարկեշտ:

Մոտեցում 3

Բարեբախտաբար, խելացի մարդիկ արդեն լուծել են այս խնդիրը՝ գրելով InfluxDB տվյալների բազան։ Այս տվյալների բազան հատուկ օպտիմիզացված է ժամանակի վրա հիմնված տվյալների պահպանման համար և իդեալական է տարբեր սենսորների արժեքները պահելու համար: Համակարգը նաև տրամադրում է SQL-ի նման հարցման լեզու, որը թույլ է տալիս արժեքներ հանել տվյալների շտեմարանից և այնուհետև դրանք համախմբել տարբեր ձևերով: Ի վերջո, տարբեր տվյալներ կարող են պահպանվել տարբեր ժամանակների համար: Օրինակ, հաճախակի փոփոխվող ցուցանիշները, ինչպիսիք են ջերմաստիճանը կամ խոնավությունը, կարող են պահպանվել ընդամենը մի քանի շաբաթ, մինչդեռ ջրի սպառման ամենօրյա ցուցանիշները կարող են պահպանվել մեկ ամբողջ տարի:

Բացի InfluxDB-ից, խելացի մարդիկ նաև հայտնագործել են Grafana-ն՝ InfluxDB-ի տվյալներից գրաֆիկներ նկարելու համակարգ: Grafana-ն կարող է նկարել տարբեր տեսակի գծապատկերներ, դրանք մանրամասնորեն հարմարեցնել, և, ամենակարևորը, այս գծապատկերները կարող են «միացվել» lovelace-UI տնային օգնականին:

ոգեշնչվել այստեղ и այստեղ. Հոդվածները մանրամասն նկարագրում են InfluxDB-ի և Grafana-ի տնային օգնականին տեղադրելու և միացնելու գործընթացը: Ես կկենտրոնանամ իմ կոնկրետ խնդրի լուծման վրա։

Այսպիսով, առաջին հերթին, եկեք սկսենք ավելացնել հաշվիչի արժեքը influxDB-ում: Տնային օգնականի կոնֆիգուրացիայի մի մասը (այս օրինակում ես զվարճանալու եմ ոչ միայն սառը, այլև տաք ջրով).

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

Եկեք անջատենք նույն տվյալների պահպանումը տնային օգնականի ներքին տվյալների բազայում, որպեսզի այն ևս մեկ անգամ չուռճացնենք.

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

Եկեք հիմա գնանք InfluxDB վահանակ և ստեղծենք մեր տվյալների բազան: Մասնավորապես, դուք պետք է կազմաձևեք, թե որքան ժամանակ կպահվեն որոշակի տվյալներ: Սա կարգավորվում է այսպես կոչված. պահպանման քաղաքականություն - սա նման է հիմնական տվյալների բազայի տվյալների բազաներին, որտեղ յուրաքանչյուր ներքին տվյալների բազա ունի իր կարգավորումները: Լռելյայնորեն, բոլոր տվյալները ավելացվում են պահպանման քաղաքականությանը, որը կոչվում է autogen, այս տվյալները կպահվեն մեկ շաբաթ: Ես կցանկանայի, որ ժամային տվյալները պահվեն մեկ ամսվա ընթացքում, շաբաթական տվյալները մեկ տարվա համար, իսկ ամսական տվյալները ընդհանրապես երբեք չջնջվեն: Մենք կստեղծենք պահպանման համապատասխան քաղաքականություն

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

Այժմ, փաստորեն, հիմնական հնարքը տվյալների համախմբումն է՝ օգտագործելով շարունակական հարցումը: Սա մեխանիզմ է, որն ավտոմատ կերպով գործարկում է հարցումը նշված ընդմիջումներով, ագրեգացնում է այս հարցման տվյալները և ավելացնում արդյունքը նոր արժեքի: Եկեք նայենք օրինակին (ես գրում եմ սյունակում ընթեռնելիության համար, բայց իրականում ես ստիպված էի այս հրամանը մուտքագրել մեկ տողով)

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

Այս հրամանը.

  • Ստեղծում է շարունակական հարցում՝ cq_water_cold_hourly անունով homeassistant տվյալների բազայում
  • Հարցումը կկատարվի ամեն ժամ (ժամ (1ժ))
  • Հարցումը կհանի չափման'a homeassistant.autogen.l (լիտր) բոլոր տվյալները, ներառյալ սառը և տաք ջրի ցուցանիշները:
  • Համախմբված տվյալները կխմբավորվեն ըստ entity_id-ի, որը կստեղծի առանձին արժեքներ սառը և տաք ջրի համար:
  • Քանի որ լիտրերի հաշվիչը յուրաքանչյուր ժամվա ընթացքում միապաղաղ աճող հաջորդականություն է, դուք պետք է վերցնեք առավելագույն արժեքը, ուստի ագրեգացումը կիրականացվի max(value) ֆունկցիայի միջոցով:
  • Նոր արժեքը կգրվի homeassistant.month.water_meter_hour հասցեում, որտեղ ամիսը պահպանման քաղաքականության անվանումն է՝ մեկ ամիս պահպանման ժամկետով: Ավելին, սառը և տաք ջրի տվյալները կցրվեն առանձին գրառումների մեջ՝ համապատասխան entity_id-ով և արժեքի դաշտում գտնվող արժեքով:

Գիշերը կամ երբ տանը մարդ չկա, ջրի սպառում չկա, և համապատասխանաբար homeassistant.autogen.l-ում նույնպես նոր գրառումներ չկան։ Սովորական հարցումներում արժեքները բացակայելու համար կարող եք օգտագործել լրացնել (նախորդ): Սա կստիպի InfluxDB-ին օգտագործել անցած ժամի արժեքը:

Ցավոք, շարունակական հարցումն ունի մի յուրահատկություն՝ լրացման (նախորդ) հնարքը չի աշխատում, և գրառումները պարզապես չեն ստեղծվում։ Ավելին, սա ինչ-որ անհաղթահարելի խնդիր է, որը քննարկվում է ավելի քան մեկ տարի. Մենք կզբաղվենք այս խնդրի հետ ավելի ուշ, և թողեք լրացնել(նախորդ) շարունակական հարցումը, դա չի խանգարում:

Եկեք ստուգենք, թե ինչ է տեղի ունեցել (իհարկե, պետք է սպասել մի քանի ժամ).

> 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 ժամով. InfluxDB ելքի 7am արժեքները համընկնում են վերը նշված գծապատկերների 10am արժեքների հետ: Նկատի ունեցեք նաև, որ առավոտյան ժամը 2-ից 5-ն ընկած ժամանակահատվածում գրանցումներ պարզապես չկան. սա շարունակական հարցման առանձնահատկությունն է:

Ինչպես տեսնում եք, ագրեգացված արժեքը նույնպես միապաղաղ աճող հաջորդականություն է, միայն մուտքերն ավելի քիչ հաճախակի են՝ ժամը մեկ անգամ: Բայց սա խնդիր չէ. մենք կարող ենք գրել ևս մեկ հարցում, որը կհանի գծապատկերի ճիշտ տվյալները:

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 ժամանակով (1ժ): Այս անգամ լրացնելը (նախորդը) ճիշտ կաշխատի՝ առաջացնելով բացակայող տվյալները (ֆունկցիան կվերցնի նախորդ արժեքը)
  • Այս հարցման մեջ ամենակարևորը տարբերություն ֆունկցիան է, որը կհաշվի ժամի նշանների տարբերությունը։ Ինքնին այն չի աշխատում և պահանջում է ագրեգացման ֆունկցիա: Թող սա լինի նախկինում օգտագործված 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) շնորհիվ, և տարբերություն ֆունկցիան ինքն իրենից կհանի այս արժեքը և ելքում կստանա 0, որն իրականում պահանջվում է։

Մնում է միայն գրաֆիկ կառուցել: Դա անելու համար բացեք Grafana-ն, բացեք գոյություն ունեցող (կամ ստեղծեք նոր) վահանակ, ստեղծեք նոր վահանակ: Գծապատկերի կարգավորումները կլինեն հետևյալը.

Խելացի տուն. գծագրել ջրի և էլեկտրաէներգիայի սպառումը տնային օգնական

Ես կցուցադրեմ սառը և տաք ջրի տվյալները նույն գրաֆիկի վրա: Հարցումը ճիշտ նույնն է, ինչ վերը նկարագրեցի:

Ցուցադրման պարամետրերը սահմանվում են հետևյալ կերպ. Ինձ համար դա կլինի գծերով (գծերով) գրաֆիկ, որը գնում է աստիճաններով (աստիճաններով): Stack պարամետրը կբացատրվի ստորև: Ստորև կան ևս մի քանի ցուցադրման տարբերակներ, բայց դրանք այնքան էլ հետաքրքիր չեն:

Խելացի տուն. գծագրել ջրի և էլեկտրաէներգիայի սպառումը տնային օգնական

Ստացված գրաֆիկը տնային օգնականին ավելացնելու համար անհրաժեշտ է.

  • դուրս գալ գծապատկերի խմբագրման ռեժիմից: Չգիտես ինչու, գծապատկերների համօգտագործման ճիշտ կարգավորումներն առաջարկվում են միայն վահանակի էջից
  • Կտտացրեք գծապատկերի անվան կողքին գտնվող եռանկյունին, ընտրացանկից ընտրեք համօգտագործում
  • Բացվող պատուհանում անցեք ներկառուցման ներդիր
  • Անջատեք ընթացիկ ժամանակային միջակայքը. մենք ժամանակային միջակայքը կսահմանենք URL-ի միջոցով
  • Ընտրեք անհրաժեշտ թեման: Իմ դեպքում դա թեթեւ է
  • Պատճենեք ստացված 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 օրվա ընթացքում ես տաք ջուր չեմ օգտագործել, ուստի գծված է միայն սառը ջրի գրաֆիկը։

Խելացի տուն. գծագրել ջրի և էլեկտրաէներգիայի սպառումը տնային օգնական

Ես ինքս չեմ որոշել, թե որ գծապատկերն եմ ինձ ամենաշատը դուր գալիս, քայլ գիծը, թե իրական գծերը: Ուստի ուղղակի օրական սպառման գրաֆիկի օրինակ կբերեմ միայն այս անգամ բարերում։ Հարցումները կառուցվում են նույն կերպ, ինչպես նկարագրված է վերևում: Ցուցադրման ընտրանքներն են.

Խելացի տուն. գծագրել ջրի և էլեկտրաէներգիայի սպառումը տնային օգնական

Այս աղյուսակն ունի հետևյալ տեսքը.

Խելացի տուն. գծագրել ջրի և էլեկտրաէներգիայի սպառումը տնային օգնական

Այսպիսով, Stack պարամետրի մասին: Այս գծապատկերում տաք ձողի վրա գծված է սառը ջրի շերտ: Ընդհանուր բարձրությունը համապատասխանում է ժամանակաշրջանի համար սառը և տաք ջրի ընդհանուր սպառմանը:

Ցուցադրված բոլոր գրաֆիկները դինամիկ են: Դուք կարող եք մկնիկը տեղափոխել հետաքրքրության կետի վրա և տեսնել մանրամասներն ու արժեքը որոշակի կետում:

Ցավոք, դա առանց մի երկու ճանճի չեղավ։ Գծաձև գծապատկերում (ի տարբերություն փուլային գծերով գրաֆիկի), գծի կեսը գտնվում է ոչ թե օրվա կեսին, այլ ժամը 00:00-ին: Նրանք. գծի ձախ կեսը գծված է նախորդ օրվա փոխարեն: Այսպիսով, շաբաթ և կիրակի օրերի գծապատկերները գծված են կապտավուն գոտուց մի փոքր դեպի ձախ: Մինչև ես հասկացա, թե ինչպես հաղթել այն:

Մեկ այլ խնդիր է ամսական ընդմիջումներով ճիշտ աշխատելու անկարողությունը: Փաստն այն է, որ ժամի/օր/շաբաթի տեւողությունը ֆիքսված է, սակայն ամսվա տեւողությունը ամեն անգամ տարբեր է: InfluxDB-ն կարող է աշխատել միայն հավասար ընդմիջումներով: Առայժմ ուղեղս բավականացրել է 30 օրվա ֆիքսված ինտերվալ սահմանելու համար: Այո, աղյուսակը տարվա ընթացքում մի փոքր կլողանա, և ձողերը ճշգրիտ չեն համապատասխանի ամիսներին: Բայց քանի որ այս բանն ինձ համար հետաքրքիր է հենց որպես ցուցադրման չափիչ, ես լավ եմ այս հարցում:

Ես տեսնում եմ առնվազն երկու լուծում.

  • Ամսական աղյուսակներում միավորներ հավաքելու և ձեզ շաբաթականներով սահմանափակելու համար: Մեկ տարվա ընթացքում 52 շաբաթական բարերը բավականին լավ տեսք ունեն
  • Հաշվի առեք ամսական սպառումը որպես թիվ 2 մեթոդ և օգտագործեք գրաֆանան միայն գեղեցիկ գրաֆիկների համար: Դա բավականին ճշգրիտ լուծում է: Համեմատության համար կարող եք նույնիսկ ծածկել անցած տարվա գծապատկերները. grafana-ն կարող է դա անել:

Ամփոփում

Չգիտեմ ինչու, բայց ես սիրում եմ այս տեսակի աղյուսակները: Նրանք ցույց են տալիս, որ կյանքը եռում է, և ամեն ինչ փոխվում է։ Երեկ շատ էր, այսօր քիչ է, վաղը այլ բան կլինի։ Մնում է տնային տնտեսությունների հետ աշխատել սպառման թեմայով։ Բայց նույնիսկ ներկայիս ախորժակների պայմաններում օրինագծում առկա ընդամենը մեծ ու անհասկանալի թիվն արդեն վերածվում է սպառման բավականին հասկանալի պատկերի։

Չնայած ծրագրավորողի իմ գրեթե 20 տարվա կարիերային, ես գործնականում չէի հատվում տվյալների բազաների հետ։ Հետևաբար, արտաքին տվյալների բազայի տեղադրումը այնքան անհասկանալի և անհասկանալի բան էր թվում: Ամեն ինչ փոխվել է վերը նշված հոդվածը - պարզվեց, որ հարմար գործիքը պտուտակելը կատարվում է մի քանի կտտոցով, իսկ մասնագիտացված գործիքի միջոցով գծագրման խնդիրը մի փոքր հեշտանում է։

Վերնագրում նշել էի էլեկտրաէներգիայի սպառումը. Ցավոք սրտի, այս պահին ես չեմ կարող որևէ գրաֆիկ տրամադրել։ SDM120 մետրը մեռած է, իսկ մյուսը՝ խելագարված՝ Modbus-ի միջոցով մուտք գործելիս: Այնուամենայնիվ, սա ոչ մի կերպ չի ազդում այս հոդվածի թեմայի վրա. գրաֆիկները կկառուցվեն այնպես, ինչպես ջրի համար:

Այս հոդվածում ես տվել եմ այն ​​մոտեցումները, որոնք ինքս փորձել եմ։ Անշուշտ, կան տվյալների հավաքագրումն ու արտացոլումը կազմակերպելու այլ եղանակներ, որոնց մասին ես չգիտեմ: Ասեք ինձ այդ մասին մեկնաբանություններում, ինձ շատ կհետաքրքրի։ Ուրախ կլինեմ կառուցողական քննադատության և նոր գաղափարների համար։ Հուսով եմ, որ վերը նշված նյութը նույնպես կօգնի ինչ-որ մեկին:

Source: www.habr.com

Добавить комментарий