
Home Assistant به عنوان یکی از محبوبترین پلتفرمهای خانه هوشمند، اتوماسیونها را بر اساس وضعیت فعلی موجودیتها (Entities) اجرا میکند. اما یک بررسی نشان میدهد اگر سنسوری بیصدا از کار بیفتد، Home Assistant ممکن است آخرین مقدار را برای مدت نامحدود معتبر نگه دارد.
سنسوری که پنج روز ساکت بود، اما «خانه» اعلام میشد
نویسنده پس از ریاستارت سرور Proxmox در ساعت ۳ بامداد ۸ اکتبر، متوجه شد Home Assistant او را پنج روز متوالی «خانه» ثبت کرده است. آیفون هیچ بهروزرسانی جدیدی ارسال نکرده بود، نه خطایی، نه هشداری و نه برچسب unavailable. در ۱۳ اکتبر، وضعیت Person و device tracker آیفون و باتری آیفون همه ۱۲۱.۴ ساعت قدیمی بودند، در حالی که چاپگر Brother با وجود ۸۰ ساعت بدون تغییر مقدار، چند دقیقه پیش گزارش داده بود.
چرا Home Assistant سنسور ساکت را از سنسور مرده تشخیص نمیدهد؟
هر موجودیت در Home Assistant فقط یک state دارد و تنها دو مقدار معنای خاص دارند: unavailable و unknown. اگر یک integration این مقادیر را صریحاً تنظیم نکند، موجودیت آخرین مقدار خود را نامحدود حفظ میکند. اتوماسیونها نیز وضعیت را فقط یک بار پس از trigger بررسی میکنند و دوباره بررسی نمیکنند؛ بنابراین شرط «شخص خانه است» میتواند مقدار پنج روز پیش را بخواند.
last_reported؛ زمانسنجی که باید بررسی شود
Home Assistant سه timestamp برای هر state نگه میدارد: last_changed فقط با تغییر مقدار بهروز میشود، last_updated با تغییر state یا هر attribute، و last_reported زمانی که integration state را مینویسد، حتی اگر چیزی تغییر نکرده باشد. last_reported که از نسخه 2024.4 اضافه شده، برای تشخیص سنسور مرده مناسب است. اما یک استثنا مهم وجود دارد: موجودیتهای MQTT و بسیاری از دستگاههای Zigbee تا زمانی که force_update فعال نباشد، last_reported را بهروز نمیکنند. Zigbee2MQTT نیز بهطور پیشفرض ۲۵ ساعت صبر میکند تا دستگاه باتریدار را offline اعلام کند.
راهحل: شرط تازگی داده در اتوماسیون
نویسنده یک اتوماسیون آزمایشی ساخت که هر ۱۵ دقیقه باتری Krono را بررسی میکرد و اگر بالای ۲۰ درصد بود اعلان میفرستاد. این اتوماسیون روی دادهای اجرا شد که حداقل پنج روز قدیمی بود. راهحل، افزودن یک شرط template است که سن داده را بررسی میکند، نه فقط مقدار آن. این شرط اگر سنسور وجود نداشته باشد، unknown یا unavailable باشد، یا در شش ساعت گذشته گزارش نداده باشد، از اجرای اتوماسیون جلوگیری میکند. شش ساعت یک نقطه شروع است و بازه منطقی معمولاً دو تا سه برابر فاصله گزارشدهی عادی دستگاه است. برای MQTT یا Zigbee2MQTT بدون force_update باید last_reported را با last_updated جایگزین و بازه را بزرگتر کرد.
مشکل ریاستارت: داده کهنه، تازه به نظر میرسد
اما این شرط بهتنهایی کافی نبود. Home Assistant برای یک آپدیت Core دوباره راهاندازی شده بود و ریاستارت، زمان همه موجودیتهای بازیابیشده را تازه کرده بود. بنابراین داده ۷۲ درصدی Krono که از ۸ اکتبر تغییر نکرده بود، ادعا میکرد کمی بیش از یک ساعت پیش گزارش شده است. راهحل، استفاده از integration Uptime است که زمان بارگذاری خود را ثبت میکند و پس از هر ریاستارت، همان زمان بوت است. سپس سنسور باید بعد از بوت گزارش داده باشد. پس از یک ریاستارت دیگر، نسخه مقاوم در برابر ریاستارت اجرا نشد، در حالی که نسخه محافظتشده ساده دوباره اجرا شد. هزینه این کار این است که بلافاصله پس از ریاستارت، حتی سنسور سالم هم تا زمان گزارش بعدی مرده فرض میشود؛ اما این خطا در جهت امن است.
شناسایی سنسور یخزده پیش از اتوماسیون
محافظت از تکتک اتوماسیونها فقط نشانه را درمان میکند. نویسنده یک اتوماسیون ساعتی اضافه کرد که هر موجودیت تحت نظر را با بازه خودش و آخرین بوت مقایسه میکند و فهرست موارد کهنه را اعلان میکند. در آزمایش، این اتوماسیون هر دو گوشی را علامت زد و چاپگر را درست نادیده گرفت. در جامعه Home Assistant نیز گزینههایی مانند integration HACS به نام Device Sentinel در دست توسعه است، اما هنوز پیشانتشار است و قابلیت تشخیص توقف آن عرضه نشده؛ بنابراین فعلاً گزینهای برای تماشا است، نه نصب.
نتیجه: Home Assistant با صدا خراب میشود، سنسورها بیصدا
Home Assistant خودش اگر از کار بیفتد بهسرعت دیده میشود، اما سنسورهای تغذیهکننده آن میتوانند در سکوت کامل بمیرند. قالب (Template) بررسی تازگی داده حدود یک دقیقه زمان میبرد و از مسیر Settings -> Tools -> Template قابل اجراست. اگر اتوماسیونهای خانه هوشمند به حضور یا داده سنسورها وابستهاند، بهتر است پیش از هر چیز یک بررسی تازگی داده اضافه شود.