乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      “物聯(lián)網(wǎng)開(kāi)發(fā)實(shí)戰(zhàn)”學(xué)習(xí)筆記-(三)根據(jù)光線調(diào)節(jié)亮度

       曾淼Mark 2021-05-06

      讓智能電燈可以基于環(huán)境的明暗來(lái)自動(dòng)地打開(kāi)和關(guān)閉??梢苑譃閮蓚€(gè)階段,第一階段是打造傳感器設(shè)備來(lái)感知光照的強(qiáng)弱,判斷出環(huán)境的明暗狀態(tài),第二階段是創(chuàng)建一個(gè)場(chǎng)景聯(lián)動(dòng),根據(jù)傳感器的數(shù)值來(lái)控制智能電燈的狀態(tài)。

      1.通信技術(shù)-選擇 BLE 低功耗藍(lán)牙技術(shù)

      因?yàn)楣庹諅鞲衅髟O(shè)備的部署位置比較靈活,不太可能像智能電燈一樣連接房間里的電源線,所以我們要用一種比 Wi-Fi 功耗更低的通信技術(shù)。
      不過(guò)在正式開(kāi)發(fā)之前,還得補(bǔ)充說(shuō)明一些 BLE 的相關(guān)知識(shí)。
      BLE 設(shè)備可以在 4 種模式下工作:
      1.廣播模式),這里特指單純的廣播模式。這種模式下設(shè)備不可以被連接,只能夠以一定的時(shí)間間隔把數(shù)據(jù)廣播出來(lái),供其他設(shè)備使用,比如手機(jī)掃描處理。藍(lán)牙 Beacon 設(shè)備就是工作在這種模式。
      2.從機(jī)模式,這種模式下設(shè)備仍然可以廣播數(shù)據(jù),同時(shí)也可以被連接。建立連接后,雙方可以進(jìn)行雙向通信。比如你用手機(jī)連接一個(gè)具有藍(lán)牙功能的體溫計(jì),這時(shí)體溫計(jì)就是從機(jī)(Peripheral)。
      3.主機(jī)模式,這種模式下設(shè)備不進(jìn)行廣播,但是可以掃描周圍的藍(lán)牙廣播包,發(fā)現(xiàn)其他設(shè)備,然后主動(dòng)對(duì)這些設(shè)備發(fā)起連接。還是剛才那個(gè)例子,主動(dòng)連接藍(lán)牙體溫計(jì)的手機(jī)就是主機(jī)(Central)角色。
      4.觀察者模式,這種模式下設(shè)備像主機(jī)模式一樣,也不進(jìn)行廣播,而是掃描周圍的藍(lán)牙廣播包,但是不同的地方是,它不會(huì)與從機(jī)設(shè)備建立連接。一般收集藍(lán)牙設(shè)備廣播包的網(wǎng)關(guān)就是在這種模式下工作的,它會(huì)將收集的廣播數(shù)據(jù)通過(guò)網(wǎng)線、Wi-Fi 或者 4G 等蜂窩網(wǎng)絡(luò)上傳到云平臺(tái)。

      這里我們用的藍(lán)牙可以定義設(shè)備在廣播模式下工作。

      2.選擇開(kāi)發(fā)板- ESP32 芯片的 NodeMCU 開(kāi)發(fā)板

      因?yàn)?NodeMCU 是基于 ESP8266 芯片的,這款芯片并不支持低功耗藍(lán)牙。在市場(chǎng)上還有一款基于 ESP32 芯片的 NodeMCU 開(kāi)發(fā)板。MicroPython 也支持 ESP32 芯片,這樣我們就可以繼續(xù)使用 Python 語(yǔ)言來(lái)開(kāi)發(fā)了。
      最重要的是也不貴,某多上買一塊也就是二十來(lái)塊

      準(zhǔn)備 MicroPython 環(huán)境

      接下來(lái)就要在 NodeMCU(ESP32)上安裝 MicroPython 固件,準(zhǔn)備 Python 程序的運(yùn)行環(huán)境。
      MicroPython 官網(wǎng)已經(jīng)為我們準(zhǔn)備了編譯好的固件文件,這省掉了我們?cè)陔娔X上進(jìn)行交叉編譯的工作。你可以從這個(gè)鏈接 鏈接: link.
      中選擇“Firmware with ESP-IDF v3.x”下面的“GENERIC”類別,直接下載最新版本的固件文件到電腦中。

      然后使用一根 USB 數(shù)據(jù)線,將 NodeMCU 開(kāi)發(fā)板和電腦連接起來(lái)。我們使用 esptool 工具把這個(gè)固件燒錄到 NodeMCU 開(kāi)發(fā)板上。先在電腦終端上輸入下面的命令,清空一下 NodeMCU 的 Flash 存儲(chǔ)芯片。

      esptool.py --chip esp32 --port /dev/cu.usbserial-0001 erase_flash
      

      可以從命令里看到,和之前智能電燈用的命令相比,這里增加了芯片信息“esp32”。另外,“–port”后面的串口設(shè)備名稱,需要你替換為自己電腦上對(duì)應(yīng)的名稱。
      成功擦除 Flash 之后,就執(zhí)行下面的命令,將固件寫入 Flash 芯片。

      esptool.py --chip esp32 --port /dev/cu.usbserial-0001 --baud 460800 write_flash -z 0x1000 esp32-idf3-20200902-v1.13.bin
      

      這時(shí),我們使用電腦上的終端模擬器軟件,比如 SecureCRT,通過(guò)串口協(xié)議連接上開(kāi)發(fā)板,注意波特率(Baud rate)設(shè)置為 115200。
      然后你應(yīng)該就能看到下圖所示的內(nèi)容,并且可以進(jìn)行交互。

      在這里插入圖片描述

      4.搭建光照傳感器硬件電路

      現(xiàn)在,我們開(kāi)始基于 NodeMCU 搭建光照傳感器的硬件電路。
      首先,我們要準(zhǔn)備好實(shí)驗(yàn)的硬件:
      NodeMCU(ESP32)開(kāi)發(fā)板一個(gè)(二十多)
      光照傳感器模塊一個(gè)(幾塊錢)
      杜邦線 / 跳線若干個(gè)(幾塊錢一大把)
      面包板一個(gè)(7塊錢,物聯(lián)網(wǎng)必備工具)
      然后,你可以按照我畫的連線圖來(lái)搭建出自己的電路。
      在這里插入圖片描述

      這里說(shuō)明一下,在我的電路圖中,光照傳感器模塊從左到右,管腳分別是光強(qiáng)度模擬信號(hào)輸出管腳、電源地 GND 和電源正 VCC 管腳。你需要根據(jù)自己的傳感器模塊調(diào)整具體的連線。
      課程選擇的是基于 PT550 環(huán)保型光敏二極管的光照傳感器元器件,它的靈敏度更高,測(cè)量范圍是 0Lux~6000Lux。
      Lux(勒克斯)是光照強(qiáng)度的單位,它和另一個(gè)概念 Lumens(流明)是不同的。Lumens 是指一個(gè)光源(比如電燈、投影儀)發(fā)出的光能力的總量,而 Lux 是指空間內(nèi)一個(gè)位置接收到的光照的強(qiáng)度。
      這個(gè)元器件通過(guò)信號(hào)管腳輸出模擬量,我們讀取 NodeMCU ESP32 的 ADC 模數(shù)轉(zhuǎn)換器(ADC0,對(duì)應(yīng) GPIO36)的數(shù)值,就可以得到光照強(qiáng)度。這個(gè)數(shù)值越大,表示光照強(qiáng)度越大。
      因?yàn)?ADC 支持的最大位數(shù)是 12bit,所以這個(gè)數(shù)值范圍是 0~4095 之間。這里我們粗略地按照線性關(guān)系做一個(gè)轉(zhuǎn)換。具體計(jì)算過(guò)程,你可以參考下面的代碼:

      from machine import ADC
      from machine import Pin
      
      class LightSensor():
      
          def __init__(self, pin):
              self.light = ADC(Pin(pin))
      
          def value(self):
              value = self.light.read()
              print("Light ADC value:",value)
              return int(value/4095*6000)
      

      5.編寫藍(lán)牙程序

      NodeMCU ESP32 的固件已經(jīng)集成了 BLE 的功能,我們可以直接在這個(gè)基礎(chǔ)上進(jìn)行軟件的開(kāi)發(fā)。這里我們需要給廣播包數(shù)據(jù)定義一定的格式,讓其他設(shè)備可以順利地解析使用掃描到的數(shù)據(jù)。
      我們可以使用小米制定的MiBeacon藍(lán)牙協(xié)議。

      MiBeacon 藍(lán)牙協(xié)議的廣播包格式是基于 BLE 的 GAP制定的。GAP 控制了藍(lán)牙的廣播和連接,也就是控制了設(shè)備如何被發(fā)現(xiàn),以及如何交互。
      具體來(lái)說(shuō),GAP 定義了兩種方式來(lái)讓設(shè)備廣播數(shù)據(jù):
      一個(gè)是廣播數(shù)據(jù),這個(gè)是必須的,數(shù)據(jù)長(zhǎng)度是 31 個(gè)字節(jié);
      另一個(gè)是掃描回復(fù)數(shù)據(jù),它基于藍(lán)牙主機(jī)設(shè)備(比如手機(jī))發(fā)出的掃描請(qǐng)求來(lái)回復(fù)一些額外的信息。數(shù)據(jù)長(zhǎng)度和廣播數(shù)據(jù)一樣。

      所以,只要含有以下指定信息的廣播報(bào)文,就可以認(rèn)為是符合 MiBeacon 藍(lán)牙協(xié)議的。
      Advertising Data 中 Service Data (0x16) 含有 Mi Service UUID 的廣播包,UUID 是 0xFE95。
      Scan Response 中 Manufacturer Specific Data (0xFF) 含有小米公司識(shí)別碼的廣播包,識(shí)別碼 ID 是 0x038F。
      其中,無(wú)論是在 Advertising Data 中,還是 Scan Response 中,均采用統(tǒng)一格式定義。
      具體的廣播報(bào)文格式定義,你可以參考下面的表格。
      在這里插入圖片描述

      因?yàn)槲覀円獮楣庹諅鞲衅髟黾訌V播光照強(qiáng)度數(shù)據(jù)的能力,所以主要關(guān)注Object 的定義。Object 分為屬性和事件兩種,具體定義了設(shè)備數(shù)據(jù)的含義,比如體溫計(jì)的溫度、土壤的濕度等,數(shù)據(jù)格式如下表所示:
      在這里插入圖片描述
      按照 MiBeacon 的定義,光照傳感器的 Object ID 是 0x1007,數(shù)據(jù)長(zhǎng)度 3 個(gè)字節(jié),數(shù)值范圍是 0~120000 之間。
      這是課程代碼提供參考。

      #File:ble_lightsensor.py
      import bluetooth
      import struct
      import time
      from ble_advertising import advertising_payload
      
      from micropython import const
      
      _IRQ_CENTRAL_CONNECT = const(1)
      _IRQ_CENTRAL_DISCONNECT = const(2)
      _IRQ_GATTS_INDICATE_DONE = const(20)
      
      _FLAG_READ = const(0x0002)
      _FLAG_NOTIFY = const(0x0010)
      
      _ADV_SERVICE_DATA_UUID = 0xFE95
      _SERVICE_UUID_ENV_SENSE = 0x181A
      _CHAR_UUID_AMBIENT_LIGHT = 'FEC66B35-937E-4938-9F8D-6E44BBD533EE’
      
      # Service environmental sensing
      _ENV_SENSE_UUID = bluetooth.UUID(_SERVICE_UUID_ENV_SENSE)
      # Characteristic ambient light density
      _AMBIENT_LIGHT_CHAR = (
          bluetooth.UUID(_CHAR_UUID_AMBIENT_LIGHT),
          _FLAG_READ | _FLAG_NOTIFY ,
      )
      _ENV_SENSE_SERVICE = (
          _ENV_SENSE_UUID,
          (_AMBIENT_LIGHT_CHAR,),
      )
      
      # https://specificationrefs./assigned-values/Appearance%20Values.pdf
      _ADV_APPEARANCE_GENERIC_AMBIENT_LIGHT = const(1344)
      
      class BLELightSensor:
          def __init__(self, ble, name='Nodemcu’):
              self._ble = ble
              self._ble.active(True)
              self._ble.irq(self._irq)
              ((self._handle,),) = self._ble.gatts_register_services((_ENV_SENSE_SERVICE,))
              self._connections = set()
              time.sleep_ms(500)
              self._payload = advertising_payload(
                  name=name, services=[_ENV_SENSE_UUID], appearance=_ADV_APPEARANCE_GENERIC_AMBIENT_LIGHT
              )
              self._sd_adv = None
              self._advertise()
      
          def _irq(self, event, data):
              # Track connections so we can send notifications.
              if event == _IRQ_CENTRAL_CONNECT:
                  conn_handle, _, _ = data
                  self._connections.add(conn_handle)
              elif event == _IRQ_CENTRAL_DISCONNECT:
                  conn_handle, _, _ = data
                  self._connections.remove(conn_handle)
                  # Start advertising again to allow a new connection.
                  self._advertise()
              elif event == _IRQ_GATTS_INDICATE_DONE:
                  conn_handle, value_handle, status = data
      
          def set_light(self, light_den, notify=False):
              self._ble.gatts_write(self._handle, struct.pack(“!h”, int(light_den)))
              self._sd_adv = self.build_mi_sdadv(light_den)
              self._advertise()
              if notify:
                  for conn_handle in self._connections:
                      if notify:
                          # Notify connected centrals.
                          self._ble.gatts_notify(conn_handle, self._handle)
      
          def build_mi_sdadv(self, density):
              
              uuid = 0xFE95
              fc = 0x0010
              pid = 0x0002
              fcnt = 0x01
              mac = self._ble.config('mac’)
              objid = 0x1007
              objlen = 0x03
              objval = density
      
              service_data = struct.pack(“<3HB”,uuid,fc,pid,fcnt)+mac+struct.pack(“<H2BH”,objid,objlen,0,objval)
              print(“Service Data:”,service_data)
              
              return advertising_payload(service_data=service_data)
              
          def _advertise(self, interval_us=500000):
              self._ble.gap_advertise(interval_us, adv_data=self._payload)
              time.sleep_ms(100)
      
              print(“sd_adv”,self._sd_adv)
              if self._sd_adv is not None:
                  print(“sdddd_adv”,self._sd_adv)
                  self._ble.gap_advertise(interval_us, adv_data=self._sd_adv)
      

      驗(yàn)證光照傳感器

      我們可以通過(guò)手機(jī)上的藍(lán)牙調(diào)試軟件來(lái)掃描周圍藍(lán)牙設(shè)備,查看設(shè)備有沒(méi)有藍(lán)牙廣播包輸出,能不能跟手機(jī)正常交互。常用的軟件有 LightBlue、nRFConnect 和 BLEScanner,選擇其中一個(gè)就行了。
      比如課程選擇的是 nRF Connect,打開(kāi)之后,它會(huì)自動(dòng)掃描周圍的藍(lán)牙廣播包,將發(fā)現(xiàn)的設(shè)備以列表的形式展示。
      如果周圍藍(lán)牙設(shè)備很多的話,為了方便發(fā)現(xiàn)自己的開(kāi)發(fā)板,你可以點(diǎn)擊列表上方的“No Filter”,選擇將“Max.RSSI”打開(kāi)。拖動(dòng)其中的滑竿到合適的值,比如 -50dBm,就可以過(guò)濾掉藍(lán)牙信號(hào)強(qiáng)度比較弱(一般也是比較遠(yuǎn))的設(shè)備。
      在這里插入圖片描述
      下面是手機(jī)掃描到的基于 NodeMCU 開(kāi)發(fā)板的藍(lán)牙設(shè)備。
      在這里插入圖片描述
      其中名稱 Nodemcu 下面的就是廣播包的具體數(shù)據(jù)。
      到這里,我們就完成了光照傳感器設(shè)備的開(kāi)發(fā)工作。

      根據(jù)光照強(qiáng)度數(shù)據(jù)來(lái)聯(lián)動(dòng)控制智能電燈

      對(duì)于藍(lán)牙設(shè)備,我們需要借助網(wǎng)關(guān)來(lái)實(shí)現(xiàn)聯(lián)網(wǎng)的目的。需要用到樹(shù)莓派打造藍(lán)牙網(wǎng)關(guān),最終實(shí)現(xiàn)光照傳感器和智能電燈的場(chǎng)景聯(lián)動(dòng)。

      網(wǎng)關(guān)系統(tǒng)架構(gòu)

      網(wǎng)關(guān)的主要功能是協(xié)議轉(zhuǎn)換,一方面它需要接收低功耗藍(lán)牙技術(shù)的光照傳感器的廣播數(shù)據(jù),另一方面,它需要把解析的數(shù)據(jù)上傳到云平臺(tái)。
      具體的架構(gòu)圖如下所示。
      在這里插入圖片描述

      南向藍(lán)牙通信

      在樹(shù)莓派上進(jìn)行藍(lán)牙開(kāi)發(fā),可以使用bluepy軟件包。它提供了一個(gè) Python 語(yǔ)言版本的低功耗藍(lán)牙 API 接口,而且對(duì)樹(shù)莓派的適配非常好。

      通過(guò)終端登錄樹(shù)莓派

      在學(xué)習(xí)第 15 講的時(shí)候,應(yīng)該已經(jīng)在樹(shù)莓派上部署好了包含 Gladys Assistant 系統(tǒng)的 Raspbian 操作系統(tǒng),現(xiàn)在你可以直接使用這個(gè)系統(tǒng)。安裝軟件包之前,我們?cè)陔娔X終端上輸入下面的命令,通過(guò) SSH 協(xié)議登錄到樹(shù)莓派系統(tǒng)中。

      $ ssh pi@gladys.local
      

      其中,pi 就是默認(rèn)的登錄用戶名,gladys.local 是樹(shù)莓派開(kāi)發(fā)板的本地域名。
      當(dāng)提示輸入密碼時(shí),我們輸入默認(rèn)密碼 raspberry,然后回車,就登錄到了樹(shù)莓派系統(tǒng)中。

      在這里插入圖片描述

      通過(guò)圖形化窗口軟件登錄樹(shù)莓派

      當(dāng)然,你也可以使用提供圖形化窗口的軟件來(lái)登錄樹(shù)莓派,比如 SecureCRT,它除了支持串口協(xié)議,同時(shí)也支持 SSH 協(xié)議。你只需要新建一個(gè)連接會(huì)話,按照下圖所示的內(nèi)容填寫就行了:
      在這里插入圖片描述
      第一次登錄時(shí),SecureCRT 會(huì)彈窗提示我們查看“Host Key”,這時(shí)點(diǎn)擊“Accept Once”即可。
      在這里插入圖片描述

      然后我們輸入密碼“raspberry”,同時(shí)勾選“Save password”,省去以后重復(fù)輸入密碼的麻煩。點(diǎn)擊“OK”后,就進(jìn)入樹(shù)莓派系統(tǒng)了。
      在這里插入圖片描述

      在樹(shù)莓派開(kāi)發(fā)藍(lán)牙程序

      我們?cè)跇?shù)莓派的終端上輸入下面命令,就可以完成 bluepy 的安裝:

      $ sudo apt-get install python3-pip libglib2.0-dev
      $ sudo pip3 install bluepy
      

      另外,我們還需要安裝 interruptingcow 軟件包。它主要是便于編寫定時(shí)任務(wù)。它的安裝命令是:

      $ sudo pip3 install interruptingcow
      

      具體代碼如下,供參考:

      #File: blescan.py
      import time
      from threading import Thread
      from interruptingcow import timeout
      
      from bluepy.btle import DefaultDelegate, Peripheral, Scanner, UUID, capitaliseName, BTLEInternalError
      from bluepy.btle import BTLEDisconnectError, BTLEManagementError, BTLEGattError
      
      class LightScanner():
          SCAN_TIMEOUT = 5
      
          def __init__(self, name):
              self._name = name
          
          def status_update(self):
              results = self._get_data()
      
              # messages = [
              #     MqttMessage(
              #         topic=self.format_topic(“property/light”),
              #         payload=results.lightlevel,
              #     )
              # ]
      
              return results
      
          def _get_data(self):
      
              scan_processor = ScanProcessor(self._name)
              scanner = Scanner().withDelegate(scan_processor)
              scanner.scan(self.SCAN_TIMEOUT, passive=True)
      
              with timeout(
                  self.SCAN_TIMEOUT,
                  exception=Exception(
                      “Retrieving data from {} device {} timed out after {} seconds”.format(
                          repr(self), self._name, self.SCAN_TIMEOUT
                      )
                  ),
              ):
                  while not scan_processor.ready:
                      time.sleep(1)
                  return scan_processor.results
      
              return scan_processor.results
      
      class ScanProcessor:
      
          ADV_TYPE_SERVICE_DATA = 0x16
          def __init__(self, name):
              self._ready = False
              self._name = name
              self._results = MiBeaconData()
      
          def handleDiscovery(self, dev, isNewDev, _):
              is_nodemcu = False
              if isNewDev:
                  for (adtype, desc, value) in dev.getScanData():
                      #Service Data UUID == 0xFE95 according to MiBeacon
                      if adtype == self.ADV_TYPE_SERVICE_DATA and value.startswith(“95fe”):
                          print(“FOUND service Data:”,adtype, desc, value)
                          #Object ID == 0x1007 according to MiBeacon
                          if len(value) == 38 and value[26:30] == '0710’:
                              light_den = int((value[-2:] + value[-4:-2]), 16)
                              mac = value[14:26]
      
                              self._results.lightlevel = light_den
                              self._results.mac = mac
      
                              self.ready = True
      
          @property
          def mac(self):
              return self._mac
      
          @property
          def ready(self):
              return self._ready
      
          @ready.setter
          def ready(self, var):
              self._ready = var
      
          @property
          def results(self):
              return self._results
      
      class MiBeaconData:
          def __init__(self):
              self._lightlevel = None
              self._mac = None
      
          @property
          def lightlevel(self):
              return self._lightlevel
      
          @lightlevel.setter
          def lightlevel(self, var):
              self._lightlevel = var
      
          @property
          def mac(self):
              return self._mac
      
          @mac.setter
          def mac(self, var):
              self._mac = var
      

      北向 MQTT 對(duì)接云平臺(tái)

      接下來(lái)我們要實(shí)現(xiàn)網(wǎng)關(guān)和云平臺(tái)的對(duì)接。

      1.MQTT 開(kāi)發(fā)環(huán)境準(zhǔn)備-安裝軟件包

      藍(lán)牙網(wǎng)關(guān)與云平臺(tái)交互的通信協(xié)議也是使用 MQTT 協(xié)議,所以我們需要安裝 MQTT 的軟件包。這里我們選擇支持 Python 語(yǔ)言開(kāi)發(fā)的Eclipse Paho軟件包。我們?cè)跇?shù)莓派的終端上輸入下面的命令來(lái)安裝。

      $ sudo pip3 install paho-mqtt
      

      安裝成功后,我們可以寫一個(gè) demo 程序測(cè)試一下。下面是我測(cè)試的代碼,這段代碼仍然會(huì)連接到 test.mosquitto.org,并且訂閱“/geektime/iot”的主題消息。

      #File: mqttdemo.py 
      import paho.mqtt.client as mqtt
      
      def on_connect(client, userdata, flags, rc):
          print(“Connected with result code “+str(rc))
      
          client.subscribe(“/geektime/iot”)
      
      def on_message(client, userdata, msg):
          print(msg.topic+” “+str(msg.payload))
      
      client = mqtt.Client()
      client.on_connect = on_connect
      client.on_message = on_message
      
      #Still connect to mqtt.eclipse.org
      client.connect(“test.mosquitto.org”, 1883, 60)
      
      client.loop_forever()
      

      2.部署文件到樹(shù)莓派

      現(xiàn)在,我們把測(cè)試文件 mqttdemo.py 上傳到樹(shù)莓派上。
      你可以在電腦終端上,運(yùn)行下面的命令。(注意,你需要先在樹(shù)莓派上創(chuàng)建 pi-gateway 這個(gè)目錄。

      $ scp mqttdemo.py pi@gladys.local:/home/pi/pi-gateway/
      

      其中這個(gè) scp 命令是基于 SSH 協(xié)議實(shí)現(xiàn)的安全文檔傳輸功能。
      當(dāng)然,你也可能更習(xí)慣圖形化的軟件,所以我再介紹一個(gè)能實(shí)現(xiàn) scp 功能的軟件 FileZilla。它支持 MacOS、Windows 和 Linux 操作系統(tǒng),操作界面也非常直觀。
      打開(kāi)“站點(diǎn)管理器”,創(chuàng)建“新站點(diǎn)”。你可以按照下圖設(shè)置具體配置參數(shù),然后點(diǎn)擊“連接”,登錄到樹(shù)莓派系統(tǒng)。為了方便之后的使用,你可以勾選“保存密碼”選項(xiàng)。

      在這里插入圖片描述
      在軟件界面的左半部分是你的電腦上的文件目錄,右半部分是樹(shù)莓派上的目錄。你只需要雙擊左邊的某個(gè)文件,就可以將文件傳輸?shù)綐?shù)莓派上。當(dāng)然你也可以雙擊右邊樹(shù)莓派上的文件,將它傳輸?shù)侥愕碾娔X。
      在這里插入圖片描述
      把文件傳輸?shù)綐?shù)莓派之后,我們就可以在樹(shù)莓派的終端上輸入下面的命令,運(yùn)行上面的 demo 程序。

      $ sudo python3 mqttdemo.py
      

      云平臺(tái)創(chuàng)建光照傳感器設(shè)備

      現(xiàn)在,我們已經(jīng)做好了對(duì)接云平臺(tái)的準(zhǔn)備工作。在樹(shù)莓派上開(kāi)發(fā)與云平臺(tái)的通信代碼之前,我們還需要在騰訊云平臺(tái)上創(chuàng)建對(duì)應(yīng)的光照傳感器設(shè)備。
      在“新建產(chǎn)品”中,產(chǎn)品類別選擇“智慧生活”—>“安防報(bào)警”—>“光照度傳感器”。數(shù)據(jù)協(xié)議仍然選擇“數(shù)據(jù)模板”,其他的保持默認(rèn)值即可。

      在這里插入圖片描述

      創(chuàng)建成功后,我們點(diǎn)擊進(jìn)入數(shù)據(jù)模板的設(shè)置界面。為了盡量簡(jiǎn)單,課程只定義了一個(gè)屬性“光照度”,而且是只讀類型。你可以直接導(dǎo)入下面的 JSON 文件完成數(shù)據(jù)模板的設(shè)置。

      {
        “version”: “1.0”,
        “profile”: {
          “ProductId”: “你的ProductID”,
          “CategoryId”: “112”
        },
        “properties”: [
          {
            “id”: “Illuminance”,
            “name”: “光照度”,
            “desc”: “光照度檢測(cè)”,
            “mode”: “r”,
            “define”: {
              “type”: “float”,
              “min”: “0”,
              “max”: “6000”,
              “start”: “0”,
              “step”: “1”,
              “unit”: “Lux”
            }
          }
        ],
        “events”: [],
        “actions”: []
      }
      

      在這里插入圖片描述
      在“交互開(kāi)發(fā)”標(biāo)簽頁(yè)中,和智能電燈一樣,我們?nèi)匀槐3帧笆褂霉俜叫〕绦蚩刂飘a(chǎn)品”選項(xiàng)是打開(kāi)狀態(tài)。另外,還有一個(gè)配置項(xiàng)需要關(guān)注,那就是“智能聯(lián)動(dòng)配置”,因?yàn)楹竺嫖覀円獮楣庹諅鞲衅髟O(shè)置聯(lián)動(dòng)場(chǎng)景。
      在這里插入圖片描述

      我們點(diǎn)擊“配置”,在設(shè)置頁(yè)面中,就可以看到“光照度”這個(gè)屬性,因?yàn)樗侵蛔x屬性,所以只能作為聯(lián)動(dòng)的觸發(fā)條件。我們勾選“作為條件”的選項(xiàng),完成配置。

      在這里插入圖片描述
      下一步,在“設(shè)備調(diào)試”界面中,我們創(chuàng)建一個(gè)測(cè)試設(shè)備。點(diǎn)擊“新建設(shè)備”,輸入設(shè)備名稱“Lightsensor_1”。
      在這里插入圖片描述
      創(chuàng)建成功后,在測(cè)試設(shè)備列表中,點(diǎn)擊“Lightsensor_1”,進(jìn)入設(shè)備的詳情頁(yè)面,我們可以看到設(shè)備三元組的信息。你需要將這些信息記錄下來(lái),因?yàn)楹竺娴拈_(kāi)發(fā)中需要使用。
      在測(cè)試設(shè)備列表中,我們點(diǎn)擊“二維碼”操作,獲取測(cè)試設(shè)備的二維碼,以便在小程序“騰訊連連”中添加這個(gè)設(shè)備。
      到這里,騰訊云平臺(tái)上的產(chǎn)品創(chuàng)建工作就完成了。

      產(chǎn)品聯(lián)網(wǎng)開(kāi)發(fā)

      在騰訊云平臺(tái)準(zhǔn)備好產(chǎn)品的配置工作之后,我們繼續(xù)在樹(shù)莓派上完成北向的通信交互的開(kāi)發(fā)工作。
      之前在第二部分已經(jīng)了解了 MQTT 通信的主題 Topic ,以及 Broker 服務(wù)器地址、端口號(hào)、設(shè)備 ID、用戶名和密碼等連接參數(shù)的知識(shí)。
      我們還是可以使用 sign.html 這個(gè)網(wǎng)頁(yè)工具生產(chǎn)用戶名和密碼,然后就能得到所有的參數(shù)。這時(shí),把這些參數(shù)替換到下面這段代碼的對(duì)應(yīng)位置就可以了。

      #File: gateway.py
      from blescan import LightScanner, MiBeaconData
      
      import time 
      import asyncio
      import json
      import uuid
      import paho.mqtt.client as MQTTClient
      
      “””
      QCloud Device Info
      “””
      DEVICE_NAME = “Lightsensor_1”
      PRODUCT_ID = “MAO3SVUCFO”
      DEVICE_KEY = “TYjuKNc2GpDykXUv4MWBOA==“
      
      “””
      MQTT topic
      “””
      MQTT_CONTROL_TOPIC = “$thing/down/property/“+PRODUCT_ID+”/“+DEVICE_NAME
      MQTT_CONTROL_REPLY_TOPIC = “$thing/up/property/“+PRODUCT_ID+”/“+DEVICE_NAME
      
      def mqtt_callback(client, userdata, msg):
          # Callback
          print(f”Received `{msg.payload.decode()}` from `{msg.topic}` topic”)
      
      async def mqtt_connect():
          #connect callback
          def on_connect(client, userdata, flags, rc):
              if rc == 0:
                  print(“Connected to MQTT Broker!”)
              else:
                  print(“Failed to connect, return code %d\n”, rc)
      
          mqtt_client = None
          MQTT_SERVER = PRODUCT_ID + “.iotcloud.tencentdevices.com”
          MQTT_PORT = 1883
          MQTT_CLIENT_ID = PRODUCT_ID+DEVICE_NAME
          MQTT_USER_NAME = “MAO3SVUCFOLightsensor_1;12010126;2OYA5;1609057368”
          MQTTT_PASSWORD = “8f79b7f1b0bef9cde7fd9652383b6ff8bfeb8003cc994c64f3c8e069c11fd4c7;hmacsha256”
      
          mqtt_client = MQTTClient.Client(MQTT_CLIENT_ID)
          mqtt_client.username_pw_set(MQTT_USER_NAME, MQTTT_PASSWORD)
          mqtt_client.on_connect = on_connect
          
          mqtt_client.connect(MQTT_SERVER, MQTT_PORT, 60)
      
          return mqtt_client
      
      def mqtt_report(client, light_level):
          client_token = “clientToken-“ + str(uuid.uuid4())
      
          msg = {
              “method”: “report”,
              “clientToken”: client_token,
              “params”: {
                  “Illuminance”: light_level
              }
          }
      
          client.publish(MQTT_CONTROL_REPLY_TOPIC, json.dumps(msg))
      
      async def light_loop(mclient):
      
          bles = LightScanner('Nodemcu’)
      
          mclient.subscribe(MQTT_CONTROL_TOPIC)
          mclient.on_message = mqtt_callback
      
          mclient.loop_start()
      
          while True:
              try:
                  data = bles.status_update()
              except Exception as e:
                  print(“BLE SCAN error:”, e)
                  continue
              
              print(“Light Level:”, data.lightlevel)
      
              mqtt_report(mclient, data.lightlevel)
              
              time.sleep(0.1)
      
      async def main():
          mqtt_client = None
          # MQTT connection
          try:
              mqtt_client = await asyncio.wait_for(mqtt_connect(), 20)
          except asyncio.TimeoutError:
              print(“mqtt connected timeout!”)
      
          if mqtt_client is not None:
              await asyncio.gather(light_loop(mqtt_client))
      
      asyncio.run(main())
      

      在樹(shù)莓派上部署軟件

      接下來(lái),我們把代碼文件 gateway.py 和 blescan.py 兩個(gè)文件也上傳到樹(shù)莓派的 /home/pi/pi-gateway 目錄中。
      同時(shí),為了讓程序作為后臺(tái)服務(wù)運(yùn)行,并且能夠開(kāi)機(jī)自啟動(dòng),我們來(lái)做一個(gè) Pi Gateway Service。
      首先,你需要新建一個(gè) service.sh 腳本文件,內(nèi)容如下:

      #!/bin/sh
      set -e
      SCRIPT_DIR=$( cd “$( dirname “$0” )” >/dev/null 2>&1 && pwd )
      
      cd “$SCRIPT_DIR”
      sudo python3 ./gateway.py “$@“
      
      然后,創(chuàng)建我們 service 的配置文件,內(nèi)容如下:
      
      
      [Unit]
      Description=Pi Gateway
      Documentation=https://time./column/intro/100063601
      After=network.target
      
      [Service]
      Type=simple
      WorkingDirectory=/home/pi/pi-gateway
      ExecStart=/home/pi/pi-gateway/service.sh
      Restart=always
      
      [Install]
      WantedBy=multi-user.target
      

      接著,把這兩個(gè)文件上傳到樹(shù)莓派系統(tǒng)的 /home/pi/pi-gateway 目錄中,并且運(yùn)行下面命令,修改文件的屬性。

      $ sudo chmod a+x service.sh 
      $ sudo chmod a+x pi-gateway.service
      
      最后,執(zhí)行下面的幾條命令,為樹(shù)莓派系統(tǒng)增添上 Pi Gateway 這個(gè)服務(wù)。
      
      ```javascript
      $ sudo cp /home/pi/pi-gateway/pi-gateway.service /etc/systemd/system/
      $ sudo systemctl daemon-reload
      $ sudo systemctl start pi-gateway
      $ sudo systemctl status pi-gateway
      $ sudo systemctl enable pi-gateway
      

      到這里,網(wǎng)關(guān)程序已經(jīng)在樹(shù)莓派上運(yùn)行起來(lái)。我們?cè)隍v訊云物聯(lián)網(wǎng)平臺(tái)上可以看到,光照傳感器變?yōu)椤霸诰€”狀態(tài)。

      設(shè)置場(chǎng)景聯(lián)動(dòng)

      現(xiàn)在可以為它們?cè)O(shè)置場(chǎng)景聯(lián)動(dòng)了。

      場(chǎng)景聯(lián)動(dòng)任務(wù)分解

      我們希望實(shí)現(xiàn)的聯(lián)動(dòng)場(chǎng)景是,基于環(huán)境的光照強(qiáng)度自動(dòng)控制電燈的開(kāi)和關(guān)。具體來(lái)說(shuō),這個(gè)目標(biāo)可以拆解為 3 個(gè)自動(dòng)觸發(fā)任務(wù):
      當(dāng)光照強(qiáng)度大于 1024Lux 時(shí),關(guān)閉電燈。
      當(dāng)光照強(qiáng)度小于 1024Lux 時(shí),打開(kāi)電燈。
      至于光照強(qiáng)度等于 1024Lux 時(shí),也打開(kāi)電燈。
      注意,這里的 1024Lux 是我自己選擇的一個(gè)值,你可以根據(jù)房屋情況自己調(diào)整。

      聯(lián)動(dòng)設(shè)備準(zhǔn)備

      如果你還沒(méi)有在小程序中添加光照傳感器設(shè)備,這時(shí)可以打開(kāi)微信中的騰訊連連小程序,掃描上面云平臺(tái)“設(shè)備調(diào)試”中保存的那個(gè)二維碼,添加光照傳感器測(cè)試設(shè)備“Lightsensor_1”。
      現(xiàn)在你的小程序里面已經(jīng)有了兩個(gè)設(shè)備,如下圖所示。
      在這里插入圖片描述

      剛才我們已經(jīng)在騰訊云物聯(lián)網(wǎng)平臺(tái)上,為光照傳感器設(shè)置了“智能聯(lián)動(dòng)配置”?,F(xiàn)在,我們來(lái)為智能電燈配置智能聯(lián)動(dòng)能力。
      我們進(jìn)入智能電燈的“交互開(kāi)發(fā)”頁(yè)面,打開(kāi)下面的“智能聯(lián)動(dòng)配置”頁(yè)面,然后,像下圖顯示的那樣,把“電燈開(kāi)關(guān)”的“作為任務(wù)”條件勾選上。
      在這里插入圖片描述

      聯(lián)動(dòng)任務(wù)創(chuàng)建

      然后,我們進(jìn)入騰訊連連小程序,點(diǎn)擊下面的“+”,選擇“添加智能”,開(kāi)始配置工作。
      在這里插入圖片描述

      我們從彈框里選擇“自動(dòng)智能”,可以看到下圖的配置界面:
      在這里插入圖片描述

      首先,我們添加條件,選擇光照傳感器設(shè)備,然后就會(huì)看到光照度屬性。我們先設(shè)置大于 1024Lux 的條件。
      在這里插入圖片描述
      然后,我們添加任務(wù),選擇智能電燈設(shè)備后,可以看到電燈開(kāi)關(guān)的屬性,選擇“關(guān)”,點(diǎn)擊保存。
      在這里插入圖片描述

      這時(shí),我們可以看到這個(gè)智能聯(lián)動(dòng)的條件和任務(wù)已經(jīng)配置完成。騰訊連連小程序還支持配置“生效時(shí)間段”,可以限定智能聯(lián)動(dòng)在選定的時(shí)間段內(nèi)運(yùn)行。

      在這里插入圖片描述

      接下來(lái),我們還可以設(shè)置一個(gè)主題圖片和名稱,這個(gè)根據(jù)喜好來(lái)就行了。
      在這里插入圖片描述
      按照相同的方法,我們可以設(shè)置其他兩個(gè)條件,如下圖所示:
      在這里插入圖片描述
      最終的智能聯(lián)動(dòng),包括了剛才提到的 3 個(gè)不同的觸發(fā)條件。
      在這里插入圖片描述
      現(xiàn)在,可以通過(guò)控制光照傳感器的光照明暗(比如用手遮擋光敏元器件然后再把手拿開(kāi)),來(lái)觀察智能電燈的打開(kāi)和關(guān)閉,檢驗(yàn)功能是否正常。

      學(xué)習(xí)筆記總結(jié)自'物聯(lián)網(wǎng)開(kāi)發(fā)實(shí)戰(zhàn)’–郭朝斌
      –筆記只用于學(xué)習(xí)交流,請(qǐng)不要用于商業(yè)用途。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多