المنزل الذكي: رسم بياني لاستهلاك الماء والكهرباء في مساعد المنزل

المنزل الذكي: رسم بياني لاستهلاك الماء والكهرباء في مساعد المنزل
في كل مرة أتلقى فيها دفعة مقابل الكهرباء والمياه ، أتساءل - هل تستهلك عائلتي بالفعل الكثير؟ حسنًا ، نعم ، هناك أرضية دافئة ومرجل في الحمام ، لكنهم لا يعملون كرجال إطفاء طوال الوقت. يبدو أيضًا أننا نوفر الماء (على الرغم من أننا نحب أيضًا الرش في الحمام). قبل بضع سنوات كنت بالفعل عدادات المياه المتصلة и كهرباء إلى منزل ذكي ، ولكن هذا هو المكان الذي توقفت فيه الأمور. وصلت الأيدي إلى تحليل الاستهلاك الآن فقط ، وهو في الواقع ما يدور حوله هذا المقال.

لقد تحولت مؤخرًا إلى 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 ميجا بايت يوميًا. في غضون أسبوع ، بالكاد سيتقلب النظام ويتحول ، وفي غضون شهر سيموت محرك الأقراص المحمول (في حالة التثبيت النموذجي للمساعد المنزلي على 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. ينشئ التصميم مستشعرين جديدين 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 - سيتم إنشاء الرسم البياني بأعمدة تتماشى مع بداية الساعة
  • Points_per_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 هي التي تحكم كل شيء. وهذه مشكلة أخرى مع هذا المكون - تعمل النقاط في الساعة بشكل جيد على الرسوم البيانية لمدة ساعة أو أقل ، ولكن بشكل مثير للاشمئزاز على فترات زمنية أكبر. لذا للحصول على عمود واحد في يوم واحد ، كان علي إدخال القيمة 1/24 = 0.04166666. أنا لا أتحدث عن الرسوم البيانية الأسبوعية والشهرية.

النهج 2

بينما كنت لا أزال أكتشف المساعد المنزلي ، صادفت هذا الفيديو:


يجمع الرفيق بيانات الاستهلاك من عدة أنواع من مقابس Xiaomi. مهمته أبسط قليلاً - فقط اعرض قيمة الاستهلاك لليوم والأمس والشهر. لا الرسوم البيانية المطلوبة.

دعنا نترك جانباً الحجج حول التكامل اليدوي لقيم الطاقة اللحظية - لقد كتبت بالفعل عن "دقة" هذا النهج أعلاه. ليس من الواضح لماذا لم يستخدم قيم الاستهلاك المتراكمة ، والتي تم جمعها بالفعل من قبل نفس المنفذ. في رأيي ، سيعمل التكامل داخل قطعة الحديد بشكل أفضل.

من الفيديو ، سوف نأخذ فكرة حساب الاستهلاك يدويًا لفترة. بالنسبة للرجل ، يتم النظر فقط في قيم اليوم والأمس ، لكننا سنذهب إلى أبعد من ذلك ونحاول رسم رسم بياني. جوهر الطريقة المقترحة في حالتي على النحو التالي.

سننشئ متغير value_at_the_beginning_of_hour ، نكتب فيه قراءات العداد الحالية
وفقًا للمؤقت في نهاية الساعة (أو في بداية اليوم التالي) ، نحسب الفرق بين القراءة الحالية والقراءة المخزنة في بداية الساعة. سيكون هذا الاختلاف هو الاستهلاك للساعة الحالية - سنحفظ القيمة في المستشعر ، وفي المستقبل سنبني رسمًا بيانيًا بناءً على هذه القيمة.
تحتاج أيضًا إلى "إعادة تعيين" المتغير value_at_beginning_of_hour عن طريق كتابة القيمة الحالية للعداد هناك.

كل هذا يمكن القيام به بشكل جيد ... عن طريق المساعد المنزلي نفسه.

سيكون عليك كتابة رمز أكثر بقليل مما كان عليه في الطريقة السابقة. لنبدأ بهذه "المتغيرات". من خارج الصندوق ، ليس لدينا الكيان "المتغير" ، ولكن يمكنك استخدام خدمات وسيط mqtt. سنرسل القيم هناك مع الاحتفاظ = العلم الحقيقي - سيوفر هذا القيمة داخل الوسيط ، ويمكن سحبها في أي وقت ، حتى عند إعادة تشغيل المساعد المنزلي. لقد صنعت عدادات بالساعة واليوم دفعة واحدة.

- 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

تقوم كلتا الأتمتة بأمرين:

  • احسب القيمة لكل فترة على أنها الفرق بين قيمة البداية وقيمة النهاية
  • قم بتحديث القيمة الأساسية للفاصل الزمني التالي

يتم حل إنشاء الرسوم البيانية في هذه الحالة من خلال الرسم البياني التاريخي المعتاد:

      - 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
  • سيتم تنفيذ الاستعلام كل ساعة (الوقت (ساعة واحدة))
  • سيقوم الاستعلام بسحب جميع البيانات من القياس a homeassistant.autogen.l (لترات) ، بما في ذلك قراءات الماء البارد والساخن
  • سيتم تجميع البيانات المجمعة حسب معرف الكيان ، والذي سينشئ قيمًا منفصلة للمياه الباردة والساخنة.
  • نظرًا لأن عداد اللترات عبارة عن تسلسل متزايد بشكل رتيب خلال كل ساعة ، فستحتاج إلى أخذ القيمة القصوى ، لذلك سيتم تنفيذ التجميع بواسطة دالة max (value)
  • ستتم كتابة القيمة الجديدة على homeassistant.month.water_meter_hour حيث يمثل month اسم سياسة الاحتفاظ مع فترة احتفاظ مدتها شهر واحد. علاوة على ذلك ، سيتم توزيع البيانات الخاصة بالمياه الباردة والساخنة في سجلات منفصلة مع معرف الكيان المقابل والقيمة في حقل القيمة

في الليل أو عندما لا يكون هناك أحد في المنزل ، لا يوجد استهلاك للمياه ، وبالتالي لا توجد سجلات جديدة في 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

لاحظ أن القيم الموجودة في قاعدة البيانات مخزنة بالتوقيت العالمي المنسق ، لذلك تختلف هذه القائمة بمقدار 3 ساعات - تطابق قيم 7 صباحًا في إخراج InfluxDB قيم 10 صباحًا في الرسوم البيانية أعلاه. لاحظ أيضًا أنه ما بين الساعة 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 ، سنقوم بسحب البيانات الخاصة بالكيان_id = 'water_meter_cold' لليوم الأخير (الوقت> = الآن () -24 ساعة).
  • كما ذكرت ، قد تكون بعض الإدخالات مفقودة من تسلسل homeassistant.month.water_meter_hour. سنقوم بإعادة إنشاء هذه البيانات عن طريق تشغيل الاستعلام بوقت GROUP BY (ساعة واحدة). هذه المرة ، ستعمل التعبئة (السابقة) بشكل صحيح ، مما يؤدي إلى إنشاء البيانات المفقودة (ستأخذ الوظيفة القيمة السابقة)
  • أهم شيء في هذا الاستعلام هو دالة الفروق التي ستحسب الفرق بين علامات الساعة. في حد ذاته ، لا يعمل ويتطلب وظيفة تجميع. دع هذا يكون الحد الأقصى () المستخدم من قبل.

نتيجة التنفيذ تبدو هكذا

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) لم يكن هناك استهلاك. ومع ذلك ، سيعيد الاستعلام نفس قيمة الاستهلاك بفضل التعبئة (السابقة) ، وستقوم دالة الفرق بطرح هذه القيمة من نفسها والحصول على 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"

يرجى ملاحظة أن النطاق الزمني (آخر يومين) محدد هنا ، وليس في إعدادات لوحة القيادة.

المخطط يشبه هذا. لم أستخدم الماء الساخن في اليومين الماضيين ، لذلك يتم رسم رسم بياني للمياه الباردة فقط.

المنزل الذكي: رسم بياني لاستهلاك الماء والكهرباء في مساعد المنزل

لم أقرر بنفسي أي مخطط أفضل أفضل ، خط الخطوة ، أو الأعمدة الحقيقية. لذلك ، سأقدم ببساطة مثالاً لجدول الاستهلاك اليومي ، هذه المرة فقط في البارات. يتم إنشاء الاستعلامات بنفس الطريقة الموضحة أعلاه. خيارات العرض هي:

المنزل الذكي: رسم بياني لاستهلاك الماء والكهرباء في مساعد المنزل

يبدو هذا الرسم البياني كما يلي:

المنزل الذكي: رسم بياني لاستهلاك الماء والكهرباء في مساعد المنزل

لذلك ، حول معلمة Stack. في هذا الرسم البياني ، يتم رسم شريط ماء بارد أعلى شريط ساخن. الارتفاع الكلي يتوافق مع إجمالي استهلاك الماء البارد والساخن لهذه الفترة.

جميع الرسوم البيانية المعروضة ديناميكية. يمكنك تحريك الماوس فوق نقطة الاهتمام ومشاهدة التفاصيل والقيمة عند نقطة معينة.

لسوء الحظ ، لم يكن بدون ذبابة في المرهم. على الرسم البياني الشريطي (على عكس الرسم البياني الذي يحتوي على خطوط الخطوة) ، لا يقع منتصف الشريط في منتصف اليوم ، ولكن في الساعة 00:00. أولئك. يتم رسم النصف الأيسر من الشريط بدلاً من اليوم السابق. لذلك يتم رسم مخططات يومي السبت والأحد قليلاً إلى يسار المنطقة المزرقة. حتى اكتشفت كيف أفوز بها.

مشكلة أخرى هي عدم القدرة على العمل بشكل صحيح مع فترات شهرية. الحقيقة هي أن طول الساعة / اليوم / الأسبوع ثابت ، لكن طول الشهر يختلف في كل مرة. لا يمكن أن يعمل InfluxDB إلا بفواصل زمنية متساوية. حتى الآن ، كانت عقلي كافية لتحديد فترة زمنية ثابتة من 30 يومًا. نعم ، سوف يطفو الرسم البياني قليلاً خلال العام ولن تتوافق الأعمدة تمامًا مع الأشهر. ولكن نظرًا لأن هذا الشيء مثير للاهتمام بالنسبة لي كمقياس للعرض ، فأنا موافق على ذلك.

أرى حلين على الأقل:

  • للتسجيل في الرسوم البيانية الشهرية وقصر نفسك على الرسوم الأسبوعية. 52 شريطًا أسبوعيًا في السنة تبدو جيدة جدًا
  • اعتبر الاستهلاك الشهري نفسه هو الطريقة رقم 2 ، واستخدم الجرافانا فقط للرسوم البيانية الجميلة. إنه حل دقيق جدًا. يمكنك أيضًا تراكب المخططات للسنة الماضية للمقارنة - يمكن لـ grafana القيام بذلك.

اختتام

لا أعرف لماذا ، لكني أحب هذه الأنواع من الرسوم البيانية. يظهرون أن الحياة على قدم وساق وأن كل شيء يتغير. بالأمس كان هناك الكثير ، واليوم هناك القليل ، وغدًا سيكون هناك شيء آخر. يبقى العمل مع الأسر حول موضوع الاستهلاك. ولكن حتى مع وجود الشهية الحالية ، فإن مجرد رقم كبير وغير مفهوم في الفاتورة يتحول بالفعل إلى صورة مفهومة إلى حد ما عن الاستهلاك.

على الرغم من مسيرتي المهنية التي دامت 20 عامًا تقريبًا كمبرمج ، إلا أنني لم أتقاطع عمليًا مع قواعد البيانات. لذلك ، بدا تثبيت قاعدة بيانات خارجية أمرًا بالغ التعقيد وغير مفهوم. كل شئ تغير المقال أعلاه - اتضح أن شد الأداة المناسبة يتم بنقرتين ، وباستخدام أداة متخصصة ، تصبح مهمة التخطيط أسهل قليلاً.

في العنوان ذكرت استهلاك الكهرباء. لسوء الحظ ، لا يمكنني في الوقت الحالي تقديم أي رسم بياني. واحد متر SDM120 ميت ، والآخر هو عربات التي تجرها الدواب عند الوصول إليه عبر Modbus. ومع ذلك ، فإن هذا لا يؤثر على موضوع هذه المقالة بأي شكل من الأشكال - سيتم إنشاء الرسوم البيانية بنفس الطريقة مثل المياه.

في هذا المقال ، قدمت تلك الأساليب التي جربتها بنفسي. بالتأكيد هناك بعض الطرق الأخرى لتنظيم جمع وتصور البيانات التي لا أعرف عنها. أخبرني عنها في التعليقات ، سأكون مهتمًا جدًا. سأكون سعيدا للنقد البناء والأفكار الجديدة. آمل أن تساعد المواد المذكورة أعلاه شخصًا ما أيضًا.

المصدر: www.habr.com

إضافة تعليق