نحن نتحكم في الإضاءة في الشقة (NooLite و Raspberry Pi و WebIOPi)

أريد مشاركة تجربة استخدام نظام المنزل الذكي NooLite مع Raspberry Pi Model B (المشار إليه فيما يلي باسم RPI ) في شقة من غرفتين.
حول نظام NooLite تمت كتابته بشكل متكرر على محور:

في هذه المقالة سأقول:



  • ( ): RPI + WebIOPi (UART+REST) + NooLite
  • : NooLite —
  • ( , ): Android, WEB-, bash shell (python script)

ربما يفكر شخص ما: "لن أزعج نفسك مع RPI من أجل هذه الوظيفة البسيطة - للتحكم في الإضاءة في الشقة من هاتف محمول ، ولكنني سأدرك كل شيء باستخدام كوب بلاستيكي ، حصاة وخيط على Arduino مع درع Wi-Fi أو أبسط. تنفيذ موجز على متحكم AVR ".
ولكن ، بما أنني كنت أجمع الغبار على رف RPI وتغلبت عليه الرغبة في جعل الإضاءة "الذكية" باستخدام منصة RPI ، قررت أن أعتبرها أساسًا. كما توفر إمكانية استخدام RPI هامشًا جيدًا لتوسيع وظائف "المنزل الذكي".

ادخال البيانات


  • 2 غرفة شقة P44T دون إصلاح في مبنى جديد
  • RPI (تم شراؤها قبل عامين من أجل الفائدة)
  • الرغبة في تحقيق الإضاءة الذكية

لبعض الوقت كنت أبحث في منصات وتقنيات مختلفة للمنزل الذكي ، ونتيجة لذلك ، وقع الاختيار على نظام NooLite ، بناءً على ما يلي:
  • سعر مناسب مقارنة بأنظمة مماثلة (Z-Wave ، EnOcean ، ZigBee)
  • أنا أثق في السلع المصنوعة في روسيا البيضاء
  • بروتوكول مفتوح
  • العديد من الأمثلة للاستخدام على الإنترنت
  • 433 ميغاهيرتز واسع الانتشار وصادق عليه SCRF

كما وجهت الانتباه إلى منصة Wiren Board القائمة على ARM9 لأتمتة المنزل مع وظائف غنية لجميع الاحتياجات التي لا يمكن تصورها والتي لا يمكن تصورها. لقد سررت بشكل خاص بميزة القاتل - وحدة راديو 433 ميجاهرتز ، والتي في حالتي مناسبة للتحكم في وحدات الطاقة NooLite. ولكن بما أن لدي بالفعل RPI ، فسوف نبني على هذا.
لتنفيذ الإضاءة "الذكية" في الشقة ، كنت بحاجة إلى حل المهام التالية:
  1. تحديد سيناريو الإضاءة المثلى في شقة من غرفتين
  2. تحديد طريقة للتكامل مع RPI ووضع تيار منخفض
  3. اختر غلاف للتحكم فيه
  4. اعمل قائمة تسوق
  5. تنسيق ما سبق مع زوجته
  6. شراء المكونات الضرورية
  7. ربط أجهزة التحكم عن بعد وتصحيح تكامل RPI> NooLite
  8. إيجاد وشراء مفاتيح مناسبة لأجهزة التحكم عن بعد
  9. وضع كتل ومفاتيح الطاقة
  10. تطوير تطبيق محمول لنظام Android

يمكن تكرار البنود 1 و 4-6 في دورة.
سعر الإصدار:
  • RPI [1 جهاز كمبيوتر]
  • وحدة NooLite MT1132 [1140 ₽ X 1 كمبيوتر] 1140 ₽
  • كتل الطاقة NL [1 240 × 11 قطعة] 13 640 ₽
  • لوحات تحكم ثابتة NL [1340 ₽ X 7 قطع] 9 380 ₽
  • سلسلة مفاتيح التحكم عن بعد NL [1 550 ₽ X 1 كمبيوتر] 1 550 ₽
  • مستشعر الحركة NL [1 550 ₽ X 1 كمبيوتر] 1 550 ₽
  • صناديق التركيب ، الدعم ، وحدات لوحة المفاتيح / الأزرار (المفاتيح) ، الإطارات (يتم شراؤها بشكل فردي)
  • مع طابعة ثلاثية الأبعاد - مجانًا

الإجمالي: ~ 27000 ₽ + تحكم من 3000 ₽.

سيناريو إضاءة الشقة


يتم إعطاء تخطيط سترة P44T الركنية ذات الغرفتين مع نافذة كبيرة أدناه.

من المخطط التحكم في الإضاءة باستخدام NooLite في جميع الغرف باستثناء لوجيا والحمام والمرحاض.
الممر

نقطتا إضاءة مع وضع التتابع (تشغيل / إيقاف).
يجب التحكم في نقطة ضوء واحدة غير ساطعة بواسطة مستشعر الحركة PM111 . هذا سيسمح في الظلام بإضاءة مسار المتجول الليلي بحثًا عن أضواء جوع الليل.

يجب التحكم في كلتا نقطتي الإضاءة بواسطة مفتاح ثابت يقع بجوار الباب الأمامي. يجب أن يتضمن المفتاح السيناريو "إطفاء الأنوار في الشقة بأكملها".
ينتقل مستشعر الحركة الحرارية إلى وضع الاستعداد (يبدأ في الاستجابة لحركة الأجسام الحرارية) عندما تقوم بتعيين المستوى المطلوب لإضاءة الغرفة والحساسية. عادة في النهار ليس هناك حاجة وميض الضوء في الممر لتمرير.
من تعليمات المستشعر:
إذا كانت الإضاءة بالقرب من مستشعر PM111 أعلى من تلك التي ضبطها منظم الإضاءة ، فإن المستشعر في وضع الاستعداد. في الوقت نفسه ، يكون استهلاكه الحالي ضئيلاً (أقل من 1 μA) ، ومستشعر الحركة الحرارية معطل. عندما تنخفض الإضاءة عن مستوى محدد مسبقًا ، يدخل المستشعر في وضع الاستعداد.

يتم التحكم في الأضواء في المرحاض والحمام بواسطة مفتاح ثابت كلاسيكي. يتم توصيل الضوء والمروحة في المرحاض عبر مرحل زمني F&F PO-415 (وأيضًا البيلاروسيون) على سكة DIN.

نتيجة لإغلاق جهة اتصال التحكم 6 ، يتم إغلاق جهات اتصال التتابع 11 و 12. يؤدي فتح جهة اتصال التحكم 6 إلى العد التنازلي للوقت المحدد ، وبعد ذلك يتوقف تشغيل PO-415.

يجب أن يكون مفتاح الممر الثابت من نوع الضغط ، لأن استدعاء البرنامج النصي ينطوي على الضغط على زر (لا يحتوي البرنامج النصي على حالات تشغيل / إيقاف).
أيضًا ، الزر ضروري إذا كنا بحاجة إلى إيقاف تشغيل الضوء الذي تم تشغيله بالفعل بواسطة مستشعر الحركة ، عندما يتم تكوين مؤقت المستشعر بحيث لا يتم إيقاف تشغيل الضوء لعدة دقائق بعد تشغيله. المفتاح لا يصلح في هذه الحالة.
مجموع أسفل القاعة:
  • وحدتا طاقة من نوع الترحيل 200 واط ( SU111-200 في وضع التتابع)
  • مفتاح ثابت بثلاثة أزرار (جهاز التحكم عن بعد PK313 ):
    • زر 1 - تشغيل / إيقاف إضاءة نقطة الضوء 1
    • زر 2 - تشغيل / إيقاف إضاءة نقطة الضوء 2
    • زر 3 - إيقاف الضوء في الشقة بأكملها (البرنامج النصي)



مطبخ

ثلاث نقاط إضاءة:
  • مصباح فوق الطاولة ( وضع التتابع SU111-200 )
  • إضاءة موضعية في سقف ممتد ( وضع التتابع SU111-200 )
  • شريط LED لإضاءة سطح العمل في المطبخ ( وضع التتابع SU111-200 )

يتم التحكم في نقاط الإضاءة بواسطة مفتاح بثلاثة أزرار (جهاز التحكم عن بعد PK311 ) الموجود عند مدخل المطبخ.

غرفة المعيشة والشرفة

نقطتا إضاءة في وضع التتابع ( SU111-200 ):
  • الإضاءة الرئيسية في غرفة المعيشة
  • ضوء على الشرفة

يتم التحكم في كل نقطة إضاءة بمفتاحين:
  • زر ثابت بزرين على الشرفة ( PK313 Remote ):
    • زر 1 - تشغيل / إيقاف الضوء على الشرفة
    • زر 2 - تشغيل / إيقاف الضوء في غرفة المعيشة

  • مفتاح ثابت ذو مفتاحين في غرفة المعيشة ( PK314 Remote ):
    • المفتاح 1 - تشغيل / إيقاف الضوء في غرفة المعيشة
    • مفتاح 2 - تشغيل / إيقاف الضوء على الشرفة



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

القسم 1 (سرير)
عادة ما توجد كتل الطاقة في كل نقطة من الإضاءة. نقطة إضاءة واحدة - وحدة طاقة واحدة. في سيناريو الإضاءة ، هناك خروج واحد عن المنطق التقليدي. في غرفة النوم "القسم 1" ، من المفترض أن يتم تركيب مصباح بوحدتين للطاقة ، واحدة ستصبح باهتة.
القسم 2 (نافذة كبيرة)
بالإضافة إلى المفاتيح الثابتة ، يجب التحكم في جميع نقاط الإضاءة من جهاز تحكم عن بعد في الجيب كوحدة تحكم احتياطية و RPI. لسلسلة المفاتيح:
  • الزر A (تشغيل / إيقاف الضوء في الردهة وفي المطبخ)
  • الزر B (تشغيل / إيقاف الضوء في غرفة المعيشة وعلى الشرفة)
  • الزر C (تشغيل / إيقاف الضوء في غرفة النوم)


تحديد وضع التيار المنخفض وطريقة تكامل NooLite C لـ RPI


سأقول على الفور ، التكامل بسيط. يحتوي NooLite على وحدة MT1132 . تتلقى الوحدة حزمة تحكم عبر UART من بعض وحدة التحكم ، في حالتي هي RPI ، تنقل أمرًا عبر الهواء إلى الأجهزة التنفيذية (كتل الطاقة) وتستجيب ببناء OK / r \ n ، كل شيء موصوف في تعليمات الوحدة .
جهد إمداد الوحدة (VCC Upit)2.7-5.5 فولت
نطاق جهد الدخل عند Rx0 - لأعلى
TTL HIGH LVL (وحدة منطقية) عند Upit = 5 V2 - Upit (5 فولت)
TTL LOW LVL (صفر منطقي) عند Upit = 5 V0-0.8 فولت
TTL HIGH LVL (وحدة منطقية) عند Upit = 3.3 فولت2-3.3 فولت
TTL LOW LVL (صفر منطقي) عند Upit = 3.3 فولت0-0.8 فولت
سرعة UART9600 باود


نظرًا لأن خطوط RPART UART تعمل بمستويات TTL تبلغ 3.3 فولت ، فسوف نستخدم 3.3 فولت كقوة U للوحدة.

يمكنك استخدام ثلاثة خطوط على MT1132: VCC ، GND ، و RX ، لإرسال حزمة تحكم. لقد فعلت ذلك عند تصحيح الأخطاء - لم أقرأ الإجابة "موافق \ r \ n" من MT1132 ، كان ذلك كافياً بالنسبة لي لمراقبة مؤشر وحدة الطاقة المرفقة. عند قبول أمر "الربط" بنجاح ، يبدأ وميض متكرر لمصباح LED المضمن في وحدة الطاقة.
نقطة أخرى ، قوة جهاز الإرسال اللاسلكي بطاقة U من 3.3 V إلى 3.3 mW ، مع طاقة U من 5 V إلى 5 mW. المسافة القصوى لوحدة الطاقة هي 70 م.

حول حزمة التحكم


تتكون حزمة التحكم من 12 بايت:
ST ، B0 ، B1 ، B2 ، B3 ، B4 ، B5 ، B6 ، B7 ، B8 ، CS ، SP
ST - بايت البداية ، دائمًا 85
B0..B8 - الحمولة (أوامر التحكم)
CS - تحقق المجموع. البايت المنخفض لمجموع أول 10 بايت (ST إلى B8)
SP - توقف بايت.
وفقًا للتعليمات ، كتبت بايت التحكم التي أحتاجها:
B1 - أمر التحكم مع القيم:
  • 0 - أوقف الحمل
  • 2 - قم بتشغيل الحمل
  • 4 - قم بتشغيل أو إيقاف الحمل
  • 9 - فصل (بدء عملية محو العنوان من ذاكرة وحدة الطاقة)
  • 15 - تجليد (تسجيل عنوان الوحدة في وحدة الطاقة)

B4 - عنوان القناة (من 0 إلى 31). فقط 32 قناة.
بايت أخرى بشكل افتراضي باستثناء المجموع الاختباري.
B0 - ضبط وضع الإرسال للوحدة النمطية.
إذا تم تمرير القيمة 80 (0x50) إلى B0 ، فعندئذٍ:
  • عدد التكرارات - 2
  • معدل البت 2-1000 بت في الثانية
  • الوضع 0 - إرسال أمر


ونتيجة لذلك ، جمعت مثل هذا الجدول مع حزم التحكم اللازمة لي.
وضع في اللوحة الكهربائية

تقرر تثبيت تيار ضعيف في لوحة التبديل الداخلية:
  • يتم تثبيت RPI على سكة DIN من خلال إرفاق الأصدقاء المطبوعين على طابعة ثلاثية الأبعاد
  • وحدة MT1132 للتحكم في وحدات الطاقة على الهواء
  • مأخذان ~ 220 على DIN لتوصيل وحدات إمداد الطاقة الخاصة بجهاز التوجيه و RPI


تكامل التصحيح واختيار الأغلفة للإدارة


الشروط:
  • RPI
  • وحدة MT1132
  • أسلاك من الأم إلى الأم لتوصيل المسامير MT1132 و RPI GPIO
  • بطاقة SD مع أي صورة RPI مثبتة مسبقًا
  • الوصول إلى SHELL (bash ، csh ، korn ، إلخ.) وحدة تحكم RPI (لوحة مفاتيح مباشرة أو عن بعد عبر SSH)
  • حزم التحكم المعدة
  • مكتبة للعمل مع UART عبر رأس GPIO في RPI

أثناء تحضير الصورة ، اكتشفت خللاً رائعًا على جهاز Macbook Air أثناء تسجيل صورة Raspbian-wheezy تحت الجذر (على الرغم من أن هذه ميزة بالنسبة لي - حماية إضافية للكتابة ، فكر مرة أخرى قبل الكتابة فوق البيانات):
dd bs=1m if=2015-02-16-raspbian-wheezy.img of=/dev/disk2

عادت وحدة التحكم:
dd: /dev/disk2: Permission denied 

مع القفل الذي تمت إزالته على بطاقة SD ، تحت الجذر والتعديلات الصحيحة على / dev / disk2 ....
ثم وجدت تجارة حول هذا الموضوع ، ساعد شخص ما على النفخ في فتحة SD على الخشخاش ، حصل شخص ما على آلة سلوت. إن ضرب جهاز macbook هو مضيعة اليوم ، ونتيجة لذلك ، ساعدتني فجوة صغيرة: إذا لم يتم إدخال بطاقة SD بالكامل ، فسيعمل كل شيء.
أثناء التصحيح ، اضطررت إلى المزرعة الجماعية ، لأنه لم يكن هناك موصلات مناسبة بين الأمهات والأمهات.

بالنظر إلى أنني بحاجة إلى غلاف للتحكم في وحدات الطاقة عبر WEB ، والقدرة على تقديم طلبات REST في المستقبل ومكتبة UART من مربع واحد - وقع الاختيار على WebIOPi .

على الرغم من أنني كنت أرغب في بناء OpenHAB بسبب الهندسة المعمارية الرائعة. تم وصف منصة الأتمتة في حبري .
بالتأكيد سأستخدم هذا النظام الأساسي في المستقبل ، ولكن بالنسبة إلى "قائمة الرغبات" الخاصة بي ، فإن النظام الأساسي المختار يكفي.
هندسة التفاعل العام


إعداد الحد الأدنى من WebIOPi
باستخدام الإرشادات المتوفرة على موقع المشروع:
  1. قم بتثبيت إطار عمل WebIOPi باتباع الخطوات التالية
    • التركيب
    • تشغيل WebIOPi (البرنامج الخفي)
    • البدء التلقائي عند التمهيد

  2. تكوين UART عن طريق تغيير 3 ملفات: / etc / inittab ، /boot/cmdline.txt ، / etc / webiopi / config. خطوات:
    • على متن uart
    • تكوين WebIOPi

  3. نقوم بإعادة إنتاج الإجراءات الموضحة في القسم
    • خدعة الاسترجاع التسلسلي (أرسل "السلسلة" إلى أنفسنا عبر UART واقرأ من خلال واجهة WEBIOPi في قسم Serial Monitor)
    • يعرض الفيديو في قسم مراقبة المسلسل العملية



قم بتثبيت وصلة مرور لاختبار حلقة UART.
باستخدام الجدول الذي تم تجميعه سابقًا مع حزم التحكم ، سنقوم بكتابة نص Python بسيط لإدارة الوحدة النمطية من RPI SHELL.
نص RPI Shell لوحدة MT1132
#!/usr/bin/python
import sys, getopt
def main(argv):
   ch = ''
   cmd = ''
   try:
      opts, args = getopt.getopt(argv,"h:",["ch=","cmd="])
   except getopt.GetoptError:
      print 'mt1132.py --ch <channel_number> --cmd <ON/OFF/BIND/UNBIND>'
      sys.exit(2)
   for opt, arg in opts:
      if opt == '-h':
         print 'mt1132.py --ch <channel_number> --cmd <ON/OFF/BIND/UNBIND>'
         sys.exit()
      elif opt in ("--ch"):
         ch = arg
      elif opt in ("--cmd"):
         cmd = arg
   print 'Channel: ', ch
   print 'Command: ', cmd
   if cmd=='ON' and ch!='':
        if ch=='0':
                print 'Switch ON channel 0'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00a7, 0x00aa])
        elif ch=='1':
                print 'Switch ON channel 1'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00a8, 0x00aa])
        elif ch=='2':
                print 'Switch ON channel 2'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00a9, 0x00aa])
        elif ch=='3':
                print 'Switch ON channel 3'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00aa, 0x00aa])
        elif ch=='4':
                print 'Switch ON channel 4'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00ab, 0x00aa])
        elif ch=='5':
                print 'Switch ON channel 5'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00ac, 0x00aa])
        elif ch=='6':
                print 'Switch ON channel 6'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00ad, 0x00aa])
        elif ch=='7':
                print 'Switch ON channel 7'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00ae, 0x00aa])
        elif ch=='8':
                print 'Switch ON channel 8'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00af, 0x00aa])
        elif ch=='9':
                print 'Switch ON channel 9'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00b0, 0x00aa])
        elif ch=='10':
                print 'Switch ON channel 10'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00b1, 0x00aa])
   if cmd=='OFF' and ch!='':
        if ch=='0':
                print 'Switch OFF channel 0'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00a5, 0x00aa])
        elif ch=='1':
                print 'Switch OFF channel 1'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00a6, 0x00aa])
        elif ch=='2':
                print 'Switch OFF channel 2'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00a7, 0x00aa])
        elif ch=='3':
                print 'Switch OFF channel 3'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00a8, 0x00aa])
        elif ch=='4':
                print 'Switch OFF channel 4'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00a9, 0x00aa])
        elif ch=='5':
                print 'Switch OFF channel 5'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00aa, 0x00aa])
        elif ch=='6':
                print 'Switch OFF channel 6'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00ab, 0x00aa])
        elif ch=='7':
                print 'Switch OFF channel 7'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00ac, 0x00aa])
        elif ch=='8':
                print 'Switch OFF channel 8'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00ad, 0x00aa])
        elif ch=='9':
                print 'Switch OFF channel 9'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00ae, 0x00aa])
        elif ch=='10':
                print 'Switch OFF channel 10'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00ae, 0x00aa])
   if cmd=='BIND' and ch!='':
        if ch=='0':
                print 'BIND channel 0'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00b4, 0x00aa])
        elif ch=='1':
                print 'BIND channel 1'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00b5, 0x00aa])
        elif ch=='2':
                print 'BIND channel 2'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00b6, 0x00aa])
        elif ch=='3':
                print 'BIND channel 3'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00b7, 0x00aa])
        elif ch=='4':
                print 'BIND channel 4'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00b8, 0x00aa])
        elif ch=='5':
                print 'BIND channel 5'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00b9, 0x00aa])
        elif ch=='6':
                print 'BIND channel 6'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00ba, 0x00aa])
        elif ch=='7':
                print 'BIND channel 7'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00bb, 0x00aa])
        elif ch=='8':
                print 'BIND channel 8'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00bc, 0x00aa])
        elif ch=='9':
                print 'BIND channel 9'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00bd, 0x00aa])
        elif ch=='10':
                print 'BIND channel 10'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00be, 0x00aa])
   if cmd=='UNBIND' and ch!='':
        if ch=='0':
                print 'UNBIND channel 0'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00ae, 0x00aa])
        elif ch=='1':
                print 'UNBIND channel 1'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00af, 0x00aa])
        elif ch=='2':
                print 'UNBIND channel 2'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00b0, 0x00aa])
        elif ch=='3':
                print 'UNBIND channel 3'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00b1, 0x00aa])
        elif ch=='4':
                print 'UNBIND channel 4'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00b2, 0x00aa])
        elif ch=='5':
                print 'UNBIND channel 5'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00b3, 0x00aa])
        elif ch=='6':
                print 'UNBIND channel 6'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00b4, 0x00aa])
        elif ch=='7':
                print 'UNBIND channel 7'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00b5, 0x00aa])
        elif ch=='8':
                print 'UNBIND channel 8'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00b6, 0x00aa])
        elif ch=='9':
                print 'UNBIND channel 9'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00b7, 0x00aa])
        elif ch=='10':
                print 'UNBIND channel 10'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00b8, 0x00aa])
if __name__ == "__main__":
   main(sys.argv[1:])


للتحكم في MT1132 من وحدة التحكم shell ، قم بتنفيذ الأوامر التالية

mt1132.py --ch <channel_number> --cmd <ON/OFF/BIND/UNBIND>

نحن
نربط REST API يوفر إطار عمل WebIOPi التحكم عبر طلبات HTTP بأسلوب REST ، مما يسهل تثبيت عملاء الأجهزة المحمولة ويبسط التفاعل بين العميل والخادم.
انسخ لصق إطار عمل REST API باستخدام الرابط أعلاه:
  • احصل على وظيفة GPIO
  • اضبط وظيفة GPIO
  • احصل على قيمة GPIO
  • قم بتعيين قيمة GPIO
  • إخراج نبضة واحدة
  • تسلسل بت الإخراج
  • إخراج PWM مع نسبة دورة العمل
  • إخراج PWM مع زاوية المؤازرة
  • استدعاء ماكرو على الخادم
  • احصل على حالة / تهيئة GPIO الكاملة

قضيتنا هي "استدعاء ماكرو على الخادم". الوصف غير دهني ، ولكنه كافٍ للتجربة:
HTTP POST / macros / (macro) / (args)
  • إرجاع القيمة التي أرجعها الماكرو

نظرًا لأن (الماكرو) لم يتم إعداده بعد ، فسوف نتحقق من REST "الحصول على حالة / تهيئة GPIO الكاملة" ، ولهذا نحتاج إلى تقديم طلب HTTP GET / *.
نفتح أي عميل REST API ، لقد استخدمت عميل DHC لمتصفح Chrome. نحن نحاول تنفيذ طلب REST للحصول على الوقت الحالي.

تهيئة WebIOPi (/ etc / webiopi / config)

في قسم [DEVICES] :
إضافة جهاز تسلسلي (UART GPIO) - هذه هي وحدة MT1132 ، حيث
ttyAMA0 هو الجهاز (المنفذ) الذي تراه نواة Raspbian ، فإن سرعة
البث بالباود تبادل المعلومات بالباود من خلال واجهة UART هذه.
9600 بود / (8 + 1 بت بداية + بت توقف واحد) = 960 بايت / ثانية.
في قسم [SCRIPTS] (نصوص برمجية مخصصة):
أضف السلسلة myscrypt = /home/pi/smarthome/python/mt1132.py - لربط النص البرمجي بالإطار.
في قسم [REST] (إعدادات التحكم GPIO عبر واجهة برمجة التطبيقات REST. اختياري):
gpio-post-value = false - منع تغيير مستويات LOW / HIGH المنطقية على دبابيس GPIO من خلال طلبات REST ؛
gpio-post-function = false - منع تغيير إعداد IN / OUT على أطراف GPIO من خلال طلبات REST.
يتم ترك الإعدادات المتبقية دون تغيير.
[COAP] :
لم ألمس ، قطع الاتصال. بينما ليس لدي أي فكرة عما يتم تناوله معه وأين يتم استخدامه. لقد سجلت هذا السطر فقط في رأسي: oAP - هو بروتوكول نقل ويب متخصص للاستخدام مع العقد المقيدة والشبكات المقيدة فيإنترنت الأشياء ، المصمم للتطبيقات من آلة إلى آلة (M2M) مثل الطاقة الذكية وأتمتة المباني. "
ربما على شخص هبر يفتح حالات مفيدة للاستخدام.
إضافة وحدات ماكرو لطلبات REST إلى برنامج نصي تم إعداده مسبقًا.
# Channel 0	
@webiopi.macro	
def ch0(cmd):
	if cmd=='on':
		serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00a7, 0x00aa])
		webiopi.sleep(1)
		resp = 'Channel: 0, Cmd: ' + cmd + ', Status: ' + serial.readString()
	if cmd=='off':
		serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00a5, 0x00aa])
		webiopi.sleep(1)
		resp = 'Channel: 0, Cmd: ' + cmd + ', Status: ' + serial.readString()
	if cmd=='unbind':
		serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00ae, 0x00aa])
		webiopi.sleep(1)
		resp = 'Channel: 0, Cmd: ' + cmd + ', Status: ' + serial.readString()
	if cmd=='bind':
		serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00b4, 0x00aa])
		webiopi.sleep(1)
		resp = 'Channel: 0, Cmd: ' + cmd + ', Status: ' + serial.readString()
	return resp 


اختبار طلبات REST باستخدام وحدات الماكرو

نرسل طلب REST لـ "ربط عنوان القناة الثالثة NooLite MT1132 إلى كتلة الطاقة التي يتم بدء الربط عليها" عبر DHC.
إذا تم إرسال حزمة التحكم بنجاح ، فسوف تستجيب وحدة MT1132 عبر UART TX إلى GPIO UART RX "OK". إذا نجحت ، ستتذكر وحدة الطاقة عنوان القناة وتومض بشدة مع مؤشر LED الأخضر المدمج.

عميل بسيط لنظام Android


في البداية ، لم أخطط لكتابة تطبيق لنظام Android ، نظرًا لأنه لم يكن لدي أي فكرة ، كنت أقصد تقييد نفسي على متصفح. ثم تجول بطريق الخطأ في قناة Start Android . يخبر المؤلف ، دميتري ، بالتفصيل مع Andryukha كيفية بدء مشروعه الأول بسرعة تحت منصة Androyd. شكرا جزيلا للمؤلف للمشروع والعمل الشاق!
بعد مشاهدة وإكمال ما لا يزيد عن عشرين درسًا ، بدأت في إنشاء تطبيق بسيط للتحكم في الإضاءة. من أجل التطوير ، استخدمت IDE Android Studio ، كما تطالب Google - استنادًا إلى IntelliJ IDEA.
الواجهة كانت
النتيجة واجهة زاهدة للغاية:

main.xml كما هو
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@color/hl7"
    android:padding="2dp"
    android:clickable="false">

    <!-- -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal">
        <TextView
            android:id="@+id/r1c1"
            android:textSize="18sp"
            android:layout_width="110dp"
            android:layout_height="match_parent"
            android:padding="4dp"
            android:layout_margin="1dp"
            android:text=""
            android:background="@color/hl4"
            android:layout_weight="1"
            android:gravity="center"
            android:textColor="@color/white" />
        <TextView
            android:textColor="@color/white"
            android:textSize="18sp"
            android:id="@+id/r1c2"
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:padding="4dp"
            android:text=" "
            android:layout_margin="1dp"
            android:background="@color/hl4"
            android:layout_weight="2"
            android:gravity="center"/>
        <TextView
            android:textColor="@color/white"
            android:textSize="18sp"
            android:id="@+id/r1c3"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:padding="4dp"
            android:text=""
            android:layout_margin="1dp"
            android:background="@color/hl4"
            android:layout_weight="3"
            android:gravity="center"/>
    </LinearLayout>

    <!--  -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:layout_width="110dp"
            android:layout_height="match_parent"
            android:textColor="@color/black"
            android:textSize="16sp"
            android:text="@string/room1txt"
            android:id="@+id/room1"
            android:layout_weight="1"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:gravity="center"
            android:background="@color/holotheme_color"
            android:textStyle="bold" />
        <LinearLayout
            android:orientation="vertical"
            android:background="@color/hl8"
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:layout_margin="1dp"
            android:gravity="center|top">
            <TextView
                android:layout_width="match_parent"
                android:textColor="@color/hl9"
                android:layout_height="36dp"
                android:text="@string/place1txt"
                android:id="@+id/r1switch1"
                android:textSize="13sp"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
            <TextView
                android:textSize="13sp"
                android:layout_width="match_parent"
                android:layout_height="36dp"
                android:textColor="@color/hl9"
                android:text="@string/place5txt"
                android:id="@+id/r1switch2"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
            <TextView
                android:textSize="13sp"
                android:layout_width="match_parent"
                android:layout_height="36dp"
                android:textColor="@color/hl9"
                android:text="@string/place2txt"
                android:id="@+id/r1switch3"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
        </LinearLayout>
        <LinearLayout
            android:background="@color/hl8"
            android:orientation="vertical"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:gravity="center"
            android:layout_margin="1dp">
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="36dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r1b1on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_weight="1"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r1b1off" />
            </LinearLayout>
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="36dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r1b2on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_weight="1"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r1b2off" />
            </LinearLayout>
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="36dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r1b3on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r1b3off" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>

    <!--  -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:orientation="horizontal">
        <TextView
            android:layout_width="110dp"
            android:layout_height="match_parent"
            android:textSize="16sp"
            android:text="@string/room2txt"
            android:id="@+id/room2"
            android:layout_weight="1"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:gravity="center"
            android:background="@color/holotheme_color"
            android:textColor="@color/black"
            android:textStyle="bold"/>
        <TextView
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:textSize="13sp"
            android:text="@string/place1txt"
            android:textColor="@color/hl9"
            android:id="@+id/r2switch1"
            android:layout_weight="2"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:gravity="center|left"
            android:background="@color/hl8"/>
        <LinearLayout
            android:background="@color/hl8"
            android:orientation="horizontal"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:gravity="center"
            android:layout_margin="1dp">
            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="wrap_content"
                android:layout_height="36dp"
                android:layout_weight="1"
                android:text=""
                android:id="@+id/r2b1on" />
            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="wrap_content"
                android:layout_weight="1"
                android:layout_height="36dp"
                android:text=""
                android:id="@+id/r2b1off" />
        </LinearLayout>
    </LinearLayout>

    <!--  -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:orientation="horizontal">
        <TextView
            android:layout_width="110dp"
            android:layout_height="match_parent"
            android:textSize="16sp"
            android:text="@string/room3txt"
            android:id="@+id/room3"
            android:layout_weight="1"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:textColor="@color/black"
            android:gravity="center"
            android:background="@color/holotheme_color"
            android:textStyle="bold"/>
        <TextView
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:textSize="13sp"
            android:textColor="@color/hl9"
            android:text="@string/place1txt"
            android:id="@+id/r3switch1"
            android:layout_weight="2"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:gravity="center|left"
            android:background="@color/hl8"
            android:clickable="true"/>
        <LinearLayout
            android:background="@color/hl8"
            android:orientation="horizontal"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:gravity="center"
            android:layout_margin="1dp">
            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="wrap_content"
                android:layout_height="36dp"
                android:layout_weight="1"
                android:text=""
                android:id="@+id/r3b1on" />
            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="wrap_content"
                android:layout_height="36dp"
                android:layout_weight="1"
                android:text=""
                android:id="@+id/r3b1off" />
        </LinearLayout>
    </LinearLayout>

    <!--    -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:layout_width="110dp"
            android:layout_height="match_parent"
            android:textSize="16sp"
            android:text="@string/room4txt"
            android:id="@+id/room4"
            android:layout_weight="1"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:gravity="center"
            android:background="@color/holotheme_color"
            android:textColor="@color/black"
            android:textStyle="bold" />
        <LinearLayout
            android:orientation="vertical"
            android:background="@color/hl8"
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:layout_margin="1dp"
            android:gravity="center">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="37dp"
                android:text="@string/place6txt"
                android:textColor="@color/hl9"
                android:id="@+id/r4switch1"
                android:textSize="13sp"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="37dp"
                android:text="@string/place8txt"
                android:textColor="@color/hl9"
                android:id="@+id/r4switch3"
                android:textSize="13sp"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
            <TextView
                android:textSize="13sp"
                android:layout_width="match_parent"
                android:textColor="@color/hl9"
                android:layout_height="37dp"
                android:text="@string/place7txt"
                android:id="@+id/r4switch2"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
        </LinearLayout>
        <LinearLayout
            android:background="@color/hl8"
            android:orientation="vertical"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:gravity="center"
            android:layout_margin="1dp">
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="37dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r4b1on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r4b1off" />
            </LinearLayout>
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="36dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r4b3on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r4b3off" />
            </LinearLayout>
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="36dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r4b2on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r4b2off" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>


    <!--  -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:layout_width="110dp"
            android:layout_height="match_parent"
            android:textSize="16sp"
            android:text="@string/room5txt"
            android:id="@+id/room5"
            android:layout_weight="1"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:gravity="center"
            android:textColor="@color/black"
            android:background="@color/holotheme_color"
            android:textStyle="bold" />
        <LinearLayout
            android:orientation="vertical"
            android:background="@color/hl8"
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:layout_margin="1dp"
            android:gravity="center">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="36dp"
                android:text="@string/place3txt"
                android:textColor="@color/hl9"
                android:id="@+id/r5switch1"
                android:textSize="13sp"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
            <TextView
                android:textSize="13sp"
                android:layout_width="match_parent"
                android:layout_height="37dp"
                android:textColor="@color/hl9"
                android:text="@string/place4txt"
                android:id="@+id/r5switch2"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
        </LinearLayout>
        <LinearLayout
            android:background="@color/hl8"
            android:orientation="vertical"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:gravity="center"
            android:layout_margin="1dp">
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="36dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r5b1on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r5b1off" />
            </LinearLayout>
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="37dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r5b2on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r5b2off" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>

</LinearLayout>


ترتبط أساليب OnClick بالأزرار.
@Override
    public void onClick(View v) {
        // define the button switch that invoked the listener by id
        switch (v.getId()) {
            // Buttons room1 
            case R.id.r1b1on: // 
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room1txt)+" > "+r1sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch4url) + "on";
                new ParseTask().execute();
                break;

يقوم Switch بتعريف طريقة عرض معرف عنصر الزر ، ويعرض رسالة TOAST على الشاشة ، ويقدم طلب HTTP إلى RPI عبر HttpURLConnection داخل AsyncTask (استدعاء ParseTask (). Execute ()؛).
التفاعل مع
HttpURLConnection الخلفية - فئة للتفاعل عبر بروتوكول HTTP.
أسلوب doInBackground فئة AsyncTask - يؤدي المهام الثقيلة في دفق خلفية منفصل ويعيد النتيجة مرة أخرى إلى دفق واجهة المستخدم.
يتم تنفيذ HttpURLConnection في طريقة doInBackground.
غالبًا ما يتم العثور على هذه التقنية على الإنترنت لتنفيذ تبادل البيانات عبر بروتوكول HTTP.
webiopiurl = getString(R.string.ch4url) + "on";

يستبدل ثابت من ملف strings.xml في موارد المشروع
<string name="ch4url">http://192.168.1.154:8000/macros/ch4/</string>

لذا فإن عنوان URL الكامل لتمكين القناة 4 يبدو هكذا
http://192.168.1.154:8000/macros/ch4/on

// HTTP Query to backend in REST style
    private class ParseTask extends AsyncTask<Void, Void, String> {
        HttpURLConnection urlConnection = null;
        BufferedReader reader = null;
        String result = "";
        String BASIC_AUTH = "Basic "
                + Base64.encodeToString((getString(R.string.login) + ":" + getString(R.string.pwd)).getBytes(), Base64.NO_WRAP);

        @Override
        protected String doInBackground(Void... params) {
            //    REST 
            try {
                URL url = new URL(webiopiurl);
                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("POST");
                urlConnection.setRequestProperty("Authorization", BASIC_AUTH);
                urlConnection.connect();
                //    backend webiopi
                InputStream inputStream = urlConnection.getInputStream();
                StringBuffer buffer = new StringBuffer();
                reader = new BufferedReader(new InputStreamReader(inputStream));
                String line;
                while ((line = reader.readLine()) != null) {
                    buffer.append(line);
                }
                result = buffer.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }

كود MainActivity.java كما هو
package ru.bbq.smarthome_App;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class MainActivity extends ActionBarActivity implements View.OnClickListener {
    // Add logger
    public static String LOG_TAG = "my_log";
    public static String webiopiurl = "";
    // switch buttons
    TextView r1sw1;
    TextView r1sw2;
    TextView r1sw3;
    TextView r2sw1;
    TextView r3sw1;
    TextView r4sw1;
    TextView r4sw2;
    TextView r4sw3;
    TextView r5sw1;
    TextView r5sw2;
    // ON OFF buttons
    Button r1b1on;
    Button r1b1off;
    Button r1b2on;
    Button r1b2off;
    Button r1b3on;
    Button r1b3off;
    Button r2b1on;
    Button r2b1off;
    Button r3b1on;
    Button r3b1off;
    Button r4b1on;
    Button r4b1off;
    Button r4b2on;
    Button r4b2off;
    Button r4b3on;
    Button r4b3off;
    Button r5b1on;
    Button r5b1off;
    Button r5b2on;
    Button r5b2off;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // find View-elements and buttons
        r1sw1 = (TextView) findViewById(R.id.r1switch1); // room1switch1
        r1sw2 = (TextView) findViewById(R.id.r1switch2); // room1switch2
        r1sw3 = (TextView) findViewById(R.id.r1switch3); // room1switch3
        r2sw1 = (TextView) findViewById(R.id.r2switch1); // room2switch1
        r3sw1 = (TextView) findViewById(R.id.r3switch1); // room3switch1
        r4sw1 = (TextView) findViewById(R.id.r4switch1); // room4switch1
        r4sw2 = (TextView) findViewById(R.id.r4switch2); // room4switch2
        r4sw3 = (TextView) findViewById(R.id.r4switch3); // room4switch3
        r5sw1 = (TextView) findViewById(R.id.r5switch1); // room5switch1
        r5sw2 = (TextView) findViewById(R.id.r5switch2); // room5switch2
        r1b1on = (Button) findViewById(R.id.r1b1on);    // room1 button1 ON
        r1b1off = (Button) findViewById(R.id.r1b1off);  // room1 button1 OFF
        r1b2on = (Button) findViewById(R.id.r1b2on);    // room1 button2 ON
        r1b2off = (Button) findViewById(R.id.r1b2off);  // room1 button2 OFF
        r1b3on = (Button) findViewById(R.id.r1b3on);    // room1 button3 ON
        r1b3off = (Button) findViewById(R.id.r1b3off);  // room1 button3 OFF
        r2b1on = (Button) findViewById(R.id.r2b1on);    // room2 button1 ON
        r2b1off = (Button) findViewById(R.id.r2b1off);  // room2 button1 OFF
        r3b1on = (Button) findViewById(R.id.r3b1on);    // room3 button1 ON
        r3b1off = (Button) findViewById(R.id.r3b1off);  // room3 button1 OFF
        r4b1on = (Button) findViewById(R.id.r4b1on);    // room4 button1 ON
        r4b1off = (Button) findViewById(R.id.r4b1off);  // room4 button1 OFF
        r4b2on = (Button) findViewById(R.id.r4b2on);    // room4 button2 ON
        r4b2off = (Button) findViewById(R.id.r4b2off);  // room4 button2 OFF
        r4b3on = (Button) findViewById(R.id.r4b3on);    // room4 button3 ON
        r4b3off = (Button) findViewById(R.id.r4b3off);  // room4 button3 OFF
        r5b1on = (Button) findViewById(R.id.r5b1on);    // room5 button1 ON
        r5b1off = (Button) findViewById(R.id.r5b1off);  // room5 button1 OFF
        r5b2on = (Button) findViewById(R.id.r5b2on);    // room5 button2 ON
        r5b2off = (Button) findViewById(R.id.r5b2off);  // room5 button2 OFF

        //assign listeners to buttons
        r1b1on.setOnClickListener(this);
        r1b1off.setOnClickListener(this);
        r1b2on.setOnClickListener(this);
        r1b2off.setOnClickListener(this);
        r1b3on.setOnClickListener(this);
        r1b3off.setOnClickListener(this);
        r2b1on.setOnClickListener(this);
        r2b1off.setOnClickListener(this);
        r3b1on.setOnClickListener(this);
        r3b1off.setOnClickListener(this);
        r4b1on.setOnClickListener(this);
        r4b1off.setOnClickListener(this);
        r4b2on.setOnClickListener(this);
        r4b2off.setOnClickListener(this);
        r4b3on.setOnClickListener(this);
        r4b3off.setOnClickListener(this);
        r5b1on.setOnClickListener(this);
        r5b1off.setOnClickListener(this);
        r5b2on.setOnClickListener(this);
        r5b2off.setOnClickListener(this);
    }

    // Define On ClickView method
    @Override
    public void onClick(View v) {
        // define the button switch that invoked the listener by id
        switch (v.getId()) {
            // Buttons room1 
            case R.id.r1b1on: // 
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room1txt)+" > "+r1sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch4url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r1b1off: // 
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room1txt)+" > "+r1sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch4url) + "off";
                new ParseTask().execute();
                break;
            case R.id.r1b2on: //  
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room1txt)+" > "+r1sw2.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch3url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r1b2off: //  
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room1txt)+" > "+r1sw2.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch3url) + "off";
                new ParseTask().execute();
                break;
            case R.id.r1b3on: // LED 
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room1txt)+" > "+r1sw3.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch2url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r1b3off: // LED 
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room1txt)+" > "+r1sw3.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch2url) + "off";
                new ParseTask().execute();
                break;
            // Buttons room2 
            case R.id.r2b1on:
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room2txt)+" > "+r2sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch6url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r2b1off:
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room2txt)+" > "+r2sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch6url) + "off";
                new ParseTask().execute();
                break;
            // Buttons room3 
            case R.id.r3b1on:
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room3txt)+" > "+r3sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch5url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r3b1off:
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room3txt)+" > "+r3sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch5url) + "off";
                new ParseTask().execute();
                break;
            // Buttons room4 bedroom
            case R.id.r4b1on: //    
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room4txt)+" > "+r4sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch8url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r4b1off: //    
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room4txt)+" > "+r4sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch8url) + "off";
                new ParseTask().execute();
                break;
            case R.id.r4b2on: //    
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room4txt)+" > "+r4sw2.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch7url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r4b2off: //    
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room4txt)+" > "+r4sw2.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch7url) + "off";
                new ParseTask().execute();
                break;
            case R.id.r4b3on: //   dimmer
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room4txt)+" > "+r4sw3.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch9url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r4b3off: //   dimmer
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room4txt)+" > "+r4sw3.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch9url) + "off";
                new ParseTask().execute();
                break;
            // Buttons room5 corridor
            case R.id.r5b1on:
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room5txt)+" > "+r5sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch1url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r5b1off:
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room5txt)+" > "+r5sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch1url) + "off";
                new ParseTask().execute();
                break;
            case R.id.r5b2on:
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room5txt)+" > "+r5sw2.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch0url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r5b2off:
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room5txt)+" > "+r5sw2.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch0url) + "off";
                new ParseTask().execute();
                break;
        }
    }

    // HTTP Query to backend in REST style
    private class ParseTask extends AsyncTask<Void, Void, String> {
        HttpURLConnection urlConnection = null;
        BufferedReader reader = null;
        String result = "";
        String BASIC_AUTH = "Basic "
                + Base64.encodeToString((getString(R.string.login) + ":" + getString(R.string.pwd)).getBytes(), Base64.NO_WRAP);
        @Override
        protected String doInBackground(Void... params) {
            //    REST 
            try {
                URL url = new URL(webiopiurl);
                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("POST");
                urlConnection.setRequestProperty("Authorization", BASIC_AUTH);
                urlConnection.connect();
                //    backend webiopi
                InputStream inputStream = urlConnection.getInputStream();
                StringBuffer buffer = new StringBuffer();
                reader = new BufferedReader(new InputStreamReader(inputStream));
                String line;
                while ((line = reader.readLine()) != null) {
                    buffer.append(line);
                }
                result = buffer.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }

        @Override
        protected void onPostExecute(String str) {
            super.onPostExecute(str);
            //  ,    plain text ( JSON)
            //    log
            Log.d(LOG_TAG, str);
            //  TOAST -   webiopi     MT1132
            Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show();
        }
    }

}



ابحث عن وشراء مفاتيح مناسبة لأجهزة التحكم عن بعد


استنادًا إلى سيناريو الإضاءة ، يستخدم هذا المشروع لوحات مفاتيح NooLite مدمجة ثابتة وأزرار / مفاتيح ، ومن الضروري توفير القدرة على تثبيت المفاتيح بثلاث وحدات (الأزرار / المفاتيح) ، مع الحفاظ على تصميم المفاتيح (يجب أن تبدو جميع المفاتيح متشابهة).
عند اختيار المفاتيح ، ضع في اعتبارك إمكانية:
  • تركيب وحدتين إلى ثلاث وحدات لدعم المحولات
  • تركيب وحدات الأزرار ولوحة المفاتيح

إن مفاتيح bticino Livinglight مناسبة لهذه الظروف. في الصورة أدناه ، الوحدات المجمعة مع جهاز التحكم عن بعد NooLite.


وحدة الطاقة على السقف أثناء التصحيح. التصحيح

في الموقع .

لوحة كهربائية بتيار ضعيف في الداخل.

شكرا لكم على اهتمامكم. أتمنى لك نهارا سعيد!

Source: https://habr.com/ru/post/ar382689/


All Articles