أتعرف ما الذي يملك العالم ما يكفي منه؟ الناس الذين يتحدثون عمّا سيفعلونه يوماً ما. الحالمون جالسون بلا حراك، ينتظرون اللحظة المثالية، الإعداد المثالي، أي شيء مثالي. وفي هذه الأثناء، الحياة تمضي دون توقف.
"شعرت مرة أخرى كم السعادة شيء بسيط ومتواضع: كأس من النبيذ، كستناء مشوية، موقد صغير بائس، صوت البحر. لا شيء آخر." نيكوس كازانتزاكيس، زوربا اليوناني
زوربا لم ينتظر. زوربا رقص. زوربا فشل فشلاً مذهلاً وضحك على ذلك. عندما انهارت عملية التعدين الكبرى، انهارت حرفياً، أمسك زجاجة نبيذ وبدأ يرقص على الشاطئ. الأفضل أن تفشل مثل زوربا من أن تجلس بلا حراك.
لذا اليوم، أنا وابني ننفّذ. الخطة مرسومة. الأجهزة جاهزة. معظمها تم اختباره بشكل منفرد: الأتمتة تعمل، المستشعرات تكتشف، الكود يُجمع. الآن نرى هل يعمل كل شيء معاً. هل سيحدث خطأ ما؟ على الأرجح. هل نحن مستعدون للتحديات؟ بالتأكيد. هذا هو الجزء الممتع.
بدون خطة، لا يوجد طريق للأمام. فقط أناس يتكلمون ليسمعوا أنفسهم. مجرد أحلام. هذا ليس حلماً. هذا ملخص تنفيذي.
المهمة
بحلول الوقت الذي نشوي فيه العشاء الليلة، سيكون هذا المنزل:
- يُشعل الأضواء في الغرفة التي تدخلها، ويخفتها خلفك عند الخروج
- يقفل كل الأبواب عندما يستشعر السرير أننا نمنا
- يغلق المرآب تلقائياً عندما ننسى (مرة أخرى)
- يضبط المناخ بناءً على أي الغرف مشغولة فعلاً
- يولّد ضوضاء WiFi حتى لا يستطيع أحد في الخارج استخدام نفس تقنية الاستشعار ضدنا
ولن تعرف أمازون شيئاً عن ذلك. كل شيء يعمل محلياً. بدون سحابة. بدون اشتراكات. بدون جمع بيانات.
الترسانة (جاهزة ومُعدّة)
العقل: Raspberry Pi 5 - جاهز
هذا الجهاز جالس على مكتبي منذ أسبوعين، مُعدّ بالكامل، ينتظر اليوم. Pi 5 أقوى مما يلزم للأتمتة المنزلية الأساسية. أنا أحب الأقوى مما يلزم. يعمل عليه Raspberry Pi OS Lite، Docker مُثبت، Portainer يعمل. كل ما عليّ فعله هو توصيله في مكانه الدائم.
اخترت حزمة Argon ONE V3 M.2 NVME PCIE Case. مُجمّع بالفعل:
- قرص M.2 SSD مع نظام التشغيل (لا أعطال بطاقات SD لنا)
- Docker + Portainer مثبتان ومختبران
- حاوية Home Assistant جاهزة للنشر
- عنوان IP ثابت مُعيّن على الشبكة
قائمة التحقق قبل الإطلاق - مكتملة
- ☑ تم تثبيت Raspberry Pi OS Lite على SSD
- ☑ SSH مُفعّل، بيانات الاعتماد مُعدّة
- ☑ الشبكة مُعدّة بعنوان IP ثابت
- ☑ Docker + Portainer يعملان
- ☑ ملفات تكوين Home Assistant جاهزة
المستشعرات: لوحات ESP32 - مُبرمجة ومُختبرة
هذه لوحات ESP32 الصغيرة كانت الجزء الأكثر متعة. أنا وابني أمضينا عطلة نهاية الأسبوع الماضية نبرمجها ونراقب بيانات إشارة WiFi تتدفق. تعمل. مؤكد.
- وحدة استشعار WiFi - تكتشف الحركة عبر قياس اضطراب إشارة WiFi. اختُبرت بالمشي في غرفة المعيشة، تلتقط الحركة عبر الجدران، بمدى يصل إلى 4.5 حتى 6 أمتار تقريباً.
- وحدة ضباب WiFi - تولّد ضوضاء لتعمية أي استشعار WiFi خارجي. تعمل بمعزل، تخلق فوضى جميلة في فضاء الإشارات.
اليوم ندمجها في Home Assistant ونرى هل تنطلق الأتمتة بشكل صحيح. الكود يعمل في الاختبار. السؤال هو: هل يعمل عندما يكون كل شيء متصلاً؟
(إذا أردت معرفة الخلفية ولماذا هذا مهم، اقرأ مقالاتي عن استشعار WiFi وإجراءات مضادة لـ WiFi.)
البنية التحتية الموجودة - مُثبتة بالفعل
نحن لا نبدأ من الصفر. المنزل لديه بالفعل أجهزة ذكية، لكنها تعمل على تطبيقات منفصلة مثل جزر متناثرة. اليوم نوحّد المملكة:
- لمبات Philips Hue - مثبتة في كل مكان. حالياً تُتحكم بها عبر تطبيق Hue. اليوم: Home Assistant يتولى الأمر.
- ثرموستات Ecobee - يعرف بالفعل أي الغرف مشغولة عبر مستشعراته. اليوم: ندمج تلك البيانات.
- سرير Eight Sleep - يتتبع بالفعل متى أنام. اليوم: يطلق أتمتة القفل.
- أقفال Kwikset (Z-Wave) - على الأبواب بالفعل. اليوم: تتعلم أن تقفل نفسها.
- مرآب MyQ - مُثبت بالفعل. اليوم: لا مزيد من العودة للمنزل لأنني نسيت إغلاقه.
المغزى: ربما لديك بالفعل أجهزة منزل ذكي أكثر مما تظن. إنها فقط لا تتحدث مع بعضها بعد.
المرحلة الأولى: البنية التحتية (تمّت)
هذا عمل عطلة نهاية الأسبوع الماضية. إذا كنت تتابع لاحقاً، هذا ما فعلناه. إذا قرأت مقالتي عن Docker، فأنت تعرف لماذا وضعنا كل شيء في حاويات.
bash# Docker + Portainer - Already running
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
docker volume create portainer_data
docker run -d -p 9000:9000 --name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-cePortainer يعمل على http://raspberrypi.local:9000. واجهة رسومية جميلة لإدارة الحاويات. تم التحقق.
المرحلة الثانية: Home Assistant (المهمة الأولى اليوم)
ملف docker-compose مكتوب. مجلد التكوين جاهز. اليوم نشغّله فعلاً ونبدأ بتوصيل الأجهزة.
yaml# docker-compose.yml - ready to deploy
version: '3'
services:
homeassistant:
container_name: homeassistant
image: ghcr.io/home-assistant/home-assistant:stable
volumes:
- /home/pi/homeassistant:/config
- /etc/localtime:/etc/localtime:ro
restart: unless-stopped
privileged: true
network_mode: hostالخطة: تشغيل docker-compose up -d، فتح معالج الإعداد، وتوصيل هذه التكاملات واحدة تلو الأخرى:
- Philips Hue - يجب أن يُكتشف تلقائياً على الشبكة
- Ecobee - تدفق OAuth، أحتاج التطبيق في متناول اليد
- Eight Sleep - تكامل API، بيانات الاعتماد جاهزة
- Z-Wave - هذا قد يكون حاراً، الأقفال قد تكون عنيدة
- MyQ - بسيط، فعلته من قبل
- ESPHome - لأجهزة ESP32 التي برمجناها عطلة نهاية الأسبوع الماضية
التحدي المتوقع: Z-Wave. الأقفال دائماً لها مزاج. سنرى.
المرحلة الثالثة: دمج استشعار WiFi (الجزء الممتع اليوم)
وحدة الاستشعار - جاهزة للتوصيل
عطلة نهاية الأسبوع الماضية، راقب ابني الشاشة التسلسلية بينما اكتشف هذا الجهاز أنني أمشي في غرفة المعيشة. كلماته بالضبط: "بابا، هذا مخيف ورائع في نفس الوقت."
ESP32 مبرمج بالفعل بـ ESPHome. يكتشف بالفعل الحركة عبر WiFi CSI (معلومات حالة القناة). اليوم نوصله بـ Home Assistant ونعطيه اسماً: binary_sensor.living_room_occupied
الاختبار: ادخل غرفة المعيشة. هل يراها Home Assistant؟ إذا نعم، فنحن جاهزون.
وحدة الضباب - طبقة الخصوصية جاهزة
ESP32 الثاني يشغّل مولّد الضوضاء من مقالتي عن الإجراءات المضادة. يعمل على طاولة العمل منذ أسبوع، يولّد فوضى جميلة في طيف WiFi.
نعم، نحن نستخدم استشعار WiFi لأتمتتنا الخاصة بينما نحمي أنفسنا في نفس الوقت من الآخرين الذين يفعلون نفس الشيء ضدنا. هذا ليس نفاقاً. هذا أمن عملياتي. وابني يعتقد أنه أروع شيء على الإطلاق.
التوسع المستقبلي: 3+3
هدف اليوم هو إثبات المفهوم بمستشعر واحد وجهاز ضباب واحد. بمجرد أن نكون واثقين:
- 3 أجهزة استشعار: غرفة المعيشة، المطبخ، غرفة النوم
- 3 أجهزة ضباب: موزعة في أنحاء المنزل لتغطية كاملة
ذلك حوالي $50 من لوحات ESP32 لترقية المنزل بالكامل. لكن أولاً، لنتأكد أن اليوم ينجح.
المرحلة الرابعة: الأتمتة (الهدف الحقيقي)
هذا ما كنّا نبني نحوه طوال الوقت. ملفات YAML هذه مكتوبة، مُختبرة في رأسي مائة مرة، وجاهزة للصق. هل ستعمل من أول محاولة؟ لنكتشف.
الأتمتة 1: الإضاءة المتابعة (نجمة العرض)
الرؤية: ادخل غرفة، تُضيء الأنوار لاستقبالك. اخرج، وتخفت خلفك مثل خادم محترم. منزل توني ستارك. هذا الهدف.
التفصيل: إذا أشعلت ضوءاً يدوياً، النظام يتركه كما هو. اختيارك يُحترم. نتتبع هذا بمساعدي input_boolean. لأن لا شيء أسوأ من أتمتة تحاربك.
yaml# configuration.yaml additions
input_text:
last_occupied_room:
name: "Last Occupied Room"
initial: "none"
input_boolean:
living_room_auto_triggered:
name: "Living Room Auto Triggered"
kitchen_auto_triggered:
name: "Kitchen Auto Triggered"
bedroom_auto_triggered:
name: "Bedroom Auto Triggered"الآن الأتمتة:
yaml# automations.yaml
- alias: "Follow Me - Living Room Entry"
trigger:
- platform: state
entity_id: binary_sensor.living_room_occupied
to: "on"
condition:
- condition: state
entity_id: light.living_room
state: "off"
action:
# Dim the previous room if it was auto-triggered
- choose:
- conditions:
- condition: template
value_template: "{{ states('input_text.last_occupied_room') == 'kitchen' }}"
- condition: state
entity_id: input_boolean.kitchen_auto_triggered
state: "on"
sequence:
- service: light.turn_on
target:
entity_id: light.kitchen
data:
brightness_pct: 20
transition: 3
# Turn on current room
- service: light.turn_on
target:
entity_id: light.living_room
data:
brightness_pct: 100
- service: input_boolean.turn_on
target:
entity_id: input_boolean.living_room_auto_triggered
- service: input_text.set_value
target:
entity_id: input_text.last_occupied_room
data:
value: "living_room"
- alias: "Follow Me - Living Room Vacancy"
trigger:
- platform: state
entity_id: binary_sensor.living_room_occupied
to: "off"
for:
minutes: 2
condition:
- condition: state
entity_id: input_boolean.living_room_auto_triggered
state: "on"
action:
- service: light.turn_off
target:
entity_id: light.living_room
data:
transition: 5
- service: input_boolean.turn_off
target:
entity_id: input_boolean.living_room_auto_triggeredالاختبار: بمجرد نشر هذا، سأمشي أنا وابني في المنزل ونرى هل يتبعنا. إذا نجح، سنشعر كأننا في فيلم. إذا لم ينجح، سنصلحه على البيتزا.
الأتمتة 2: قفل وقت النوم (راحة البال)
السيناريو: الساعة 10 مساءً. أصعد إلى السرير. بعد خمس دقائق، يؤكد Eight Sleep أنني نائم فعلاً (لست فقط مستلقياً أتصفح الهاتف). المنزل يستجيب: كل الأبواب تُقفل، المرآب يُغلق إذا نسيت (مرة أخرى)، الثرموستات ينتقل لوضع النوم، والأضواء التي أُشعلت تلقائياً تخفت.
yaml- alias: "Bedtime - Eight Sleep Triggered Lockdown"
trigger:
- platform: state
entity_id: binary_sensor.eight_sleep_bed_presence
to: "on"
for:
minutes: 5
condition:
- condition: time
after: "21:00:00"
before: "06:00:00"
action:
# Lock all doors
- service: lock.lock
target:
entity_id:
- lock.front_door
- lock.back_door
# Close garage if open
- service: cover.close_cover
target:
entity_id: cover.garage_door
# Set Ecobee to sleep mode
- service: climate.set_preset_mode
target:
entity_id: climate.ecobee
data:
preset_mode: "Sleep"
# Turn off auto-triggered lights
- service: light.turn_off
target:
entity_id:
- light.living_room
- light.kitchen
data:
transition: 5ليس لديك Eight Sleep؟ استبدله بمشغّل زمني (10:30 مساءً) أو اكتشاف شحن الهاتف. المنطق نفسه.
الأتمتة 3: إغلاق المرآب التلقائي (مُنقذ الزواج)
المشكلة: "هل أغلقت المرآب؟" سؤال يُطرح 3 مرات أسبوعياً في هذا المنزل. انتهى الأمر. بعد 10 دقائق مفتوحاً، يُغلق نفسه ويرسل لي إشعاراً.
yaml- alias: "Garage - Auto Close After 10 Minutes"
trigger:
- platform: state
entity_id: cover.garage_door
to: "open"
for:
minutes: 10
action:
- service: cover.close_cover
target:
entity_id: cover.garage_door
- service: notify.mobile_app_your_phone
data:
title: "Garage Secured"
message: "Garage was open for 10 minutes. Auto-closed."
data:
tag: "garage-closed"الأتمتة 4: تحكم ذكي بالمناخ (موفّر الطاقة)
المنطق: لماذا تدفئ منزلاً فارغاً؟ عندما تقول مستشعرات WiFi أن لا أحد في المنزل منذ 30 دقيقة، ينتقل Ecobee لوضع الغياب. عندما يدخل أحد، يستيقظ مرة أخرى.
yaml- alias: "Ecobee - Away When House Empty"
trigger:
- platform: state
entity_id: binary_sensor.home_occupied
to: "off"
for:
minutes: 30
action:
- service: climate.set_preset_mode
target:
entity_id: climate.ecobee
data:
preset_mode: "Away"
- alias: "Ecobee - Home When Occupied"
trigger:
- platform: state
entity_id: binary_sensor.home_occupied
to: "on"
condition:
- condition: state
entity_id: climate.ecobee
attribute: preset_mode
state: "Away"
action:
- service: climate.set_preset_mode
target:
entity_id: climate.ecobee
data:
preset_mode: "Home"إنشاء المستشعر المجمّع
binary_sensor.home_occupied هو مستشعر قالب يجمع كل مستشعرات الغرف:
yamltemplate:
- binary_sensor:
- name: "Home Occupied"
state: >
{{ is_state('binary_sensor.living_room_occupied', 'on')
or is_state('binary_sensor.kitchen_occupied', 'on')
or is_state('binary_sensor.bedroom_occupied', 'on') }}ما الذي قد يخطئ؟ (الجزء الممتع)
الأمر كالتالي: شيء ما سيخطئ اليوم. هذا ليس تشاؤماً. هذا واقع. ولا بأس بذلك. هذا هو الهدف.
المرشحون المحتملون لمغامرة اليوم:
- أقفال Z-Wave - هذه الأشياء لها مزاج. الاقتران قد يحتاج عدة محاولات.
- معايرة مستشعر WiFi - يعمل على الطاولة، لكن ماذا عندما يكون في موقعه؟
- حالات حدودية للأتمتة - ماذا يحدث إذا مرّ شخص عبر غرفة في ثانيتين؟
- مشكلة "كان يعمل أمس" - النكتة المفضلة للتكنولوجيا.
لكن لهذا نفعل هذا معاً. أب وابن، نحلّ المشاكل، نتعلم، ربما نتجادل حول لماذا YAML لا يتم تحليله. هكذا تتعلم فعلاً: تبني شيئاً حقيقياً وتراقبه يتعطل وتصلحه.
منجم زوربا انهار. ردة فعله؟ الرقص على الشاطئ. مهما تعطّل اليوم، سنحلّه. وإن لم نستطع، ستكون لدينا قصة رائعة للعشاء.
الفلسفة
هذا ما يفصل بين الفاعلين والحالمين:
الحالمون يبحثون لأشهر. يقرؤون كل مقال. ينتظرون الأجهزة "الصحيحة". يحسّنون خطتهم حتى تصبح مثالية. لا يبدؤون أبداً.
الفاعلون يكتبون خطة، يجمعون ما يحتاجونه، وينفذون. يتوقعون التحديات. يتكيفون أثناء العمل. يفشلون نحو الأمام.
بدون خطة، لا يوجد طريق للأمام. فقط أناس يتكلمون ليسمعوا أنفسهم. لكن خطة بدون تنفيذ مجرد حلم بخطوات إضافية.
معايير النجاح لليوم
- ☐ Home Assistant يعمل مع كل الأجهزة متصلة
- ☐ مستشعر WiFi يكتشف الحركة في غرفة المعيشة
- ☐ الإضاءة المتابعة تعمل في غرفة واحدة على الأقل
- ☐ أتمتة قفل وقت النوم مُفعّلة
- ☐ ابني يقول "هذا مثل منزل توني ستارك"
ما التالي (بعد نجاح اليوم)
بافتراض أننا سننجح، وسننجح، حتى لو استغرق الأمر وقتاً أطول مما هو متوقع:
- نشر ESP32 كامل 3+3 - استشعار في كل غرفة رئيسية، تغطية ضباب في كل مكان
- لوحة تحكم بجهاز لوحي على الحائط - لوحة تحكم تعمل دائماً في الممر
- تحكم صوتي محلي - Wyoming/Piper لأوامر صوتية لا تغادر المنزل
- مستشعرات تسرب المياه - تحت كل حوض وبجانب سخّان المياه
لكن أولاً: اليوم. أولاً: التنفيذ. أولاً: إثبات أن كل هذا التخطيط يعمل فعلاً.
"الحياة هي ما يحدث لك بينما أنت مشغول بوضع خطط أخرى." جون لينون
خطأ. الحياة هي ما يحدث عندما تتوقف عن التخطيط وتبدأ بالعمل. أراك على الجانب الآخر. حان وقت بناء شيء ما.