騰訊IOT之樹莓派物聯網裝置

段小輝發表於2021-01-11

騰訊IOT之樹莓派物聯網裝置

本次實驗的目的是將樹莓派設定為一個物聯網終端,通過微信小程式可以控制樹莓派,實現蜂鳴器的開關。

微信小程式介面如下所示,點選這個開關,就可以控制蜂鳴器。

專案地址:https://github.com/xiaohuiduan/IotForTecentBeep

硬體配置

  1. 樹莓派
  2. 蜂鳴器

在這裡我將樹莓派接的是GPIO_00,使用的樹莓派是樹莓派4B版本。不同的樹莓派的GPIO介面可能不同,可以根據自己的需要按情況考慮。

實物圖如下所示,VCC——3.3V ,GND ——GND,IO——GPIO_00(低電平觸發)

軟體配置

程式語言使用的是Java,也就是說將使用Java實現騰訊雲IOT平臺的連線和樹莓派GPIO口的控制。使用的IDE是IntelliJ IDEA

Tecent IOT 開發平臺的使用

Tecent IOT開發平臺的官方參考文件網址:https://cloud.tencent.com/document/product/1081,不過個人覺得其文件對於Java SDK的描述不夠詳細,建議去看其 Demo 原始碼才能明白其工作流程。

騰訊雲IOT開發平臺的專案結構如下所示:分為兩層——專案產品。在使用其平臺的時候,既需要建立project,也需要建立product。

我們可以將專案理解為智慧家居整個系統,因此在專案中有很多產品,比如說智慧空調,智慧報警器等等產品。而在空調中有溫度、溼度等屬性,同時也有著開關等控制器

而在這篇部落格中,專案名稱是物聯網實訓,產品名為樹莓派,但是樹莓派只有一個功能——控制蜂鳴器。也就是說,沒有屬性,只有控制器

新建專案

開啟網址:https://console.cloud.tencent.com/iotexplorer新建專案,專案名稱隨意就行,建立好專案後,進入專案,然後建立產品。

新建產品

建立產品的選項如下:

  • 裝置:因為我們是準備將樹莓派作為一臺裝置來使用的,因此,應該選擇”裝置“,當然,如果是準備將它作為閘道器,則看著選就行了。
  • 認證方式:認證方式選擇金鑰認證,這樣在程式碼中間直接寫裝置的密碼就行,比證照稍微方便一點(不過實際上證照方便一點)。
  • 資料協議:使用資料模板即可。

新增自定義功能

物聯網裝置,之所以叫物聯網,是因為大家想把感測器獲得的資料放在雲端,或者通過雲端去控制物聯網裝置。那麼放什麼資料,控制什麼功能,則需要我們去定義。這裡選擇控制樹莓派上面的蜂鳴器,因此只需要定義蜂鳴器即可。

在騰訊IOT中,可以使用新建功能定義這些功能。選擇屬性,資料型別選擇布林型(因為只有控制蜂鳴器的開/關)。請記住這個識別符號beep_switch,這個將在後面的程式碼中用到。

關於功能型別的不同,可以參考下面的表格。(不過在個人看來,在他的官方 Demo 中,無論是物聯裝置的資料(比如說溫度溼度),還是物聯網的控制(比如說燈的開關),它都定義成為了屬性。也就是說,儘管 蜂鳴器的開關 是人為下發的控制,但是還是定義為屬性。至於事件和行為有什麼作用,我也不清楚……)

以下來自官方文件

功能元素 功能描述 功能識別符號
屬性 用於描述裝置的實時狀態,支援讀取和設定,如模式、亮度、開關等。 PropertiesId
事件 用於描述裝置執行時的事件,包括告警、資訊和故障等三種事件型別,可新增多個輸出引數,如環境感測器檢測到空氣質量很差,空調異常告警等。 EventId
行為 用於描述複雜的業務邏輯,可新增多個呼叫引數和返回引數,用於讓裝置執行某項特定的任務,例如,開鎖動作需要知道是哪個使用者在什麼時間開鎖,鎖的狀態如何等。 ActionId

點選下一步,進入裝置開發。

裝置開發

因為這裡使用的是Java SDK進行開發,沒有使用模組也沒有基於OS開發,因此直接點選下一步。

image-20210106165342612

點選下一步就到了微信小程式配置。

微信小程式配置

騰訊IOT平臺相比較於其他平臺,有一個很大的特點就是可以很好的支援小程式。也就是說,在開發的階段,就可以使用小程式去驗證裝置的功能。並且這個微信小程式不需要自己寫樣式程式碼,只需要進行簡單的配置,就可以直接從小程式上面看到物聯網裝置的資料。

因為這裡我們使用的資料很簡單,只有開關,所以隨便配置一下皮膚即可。

皮膚配置

這裡皮膚型別選擇標準皮膚,簡單的配置一下開關即可,效果圖如右圖所示。

儲存退出之後,就進入到新建裝置功能頁面。

新建裝置

新建裝置`的意義:建立一個裝置代表啟動了一個賬號(這個裝置會提供一個金鑰),我們的裝置使用這個金鑰,就可以讓我們的裝置連線騰訊雲IOT平臺進行資料互動。

從現實意義來說,就是我手中有一個樹莓派,我需要讓它連線騰訊雲IOT平臺,就需要賬號密碼,所以就需要建立一個裝置。

新建裝置的步驟如下所示:

使用裝置

點選 my_pi ,進入裝置管理。

裝置管理介面如下所示:

  • 裝置資訊:這裡面是裝置的一些基本屬性,其中通過裝置名稱裝置金鑰,和產品ID就可以唯一定位一個裝置,然後對其進行操作。

  • 裝置日誌:裝置日誌裡面儲存著裝置的上行和下行資料。

  • 線上除錯:通過線上除錯,可以模擬裝置的行為,或者對裝置下發控制命令。

線上除錯

可以使用線上的除錯功能對物聯網裝置進行功能下發。(比如說下發開關資料,控制蜂鳴器的開關)

裝置日誌

可以在裝置中看到物聯網裝置與雲平臺之間的上行和下行資料。

?,以上的所有就是騰訊IOT平臺的介紹,通過上面的操作,就可以建立一個裝置,獲得其name,key,id,然後對其進行開發。

樹莓派Java開發

針對於樹莓派開發,相信大家聽過最多的都是Python開發,使用Python去控制樹莓派的GPIO口,但是,因為騰訊提供的平臺沒有Python的SDK,因此,只能選擇Java去控制樹莓派的GPIO口。

Pi4j是一個專門用來控制樹莓派GPIO口的裝置。關於使用安裝可以去看樹莓派---JAVA操作GPIO(不過基本上比較新的樹莓派系統都不需要安裝了)。

因為我們是在Windows平臺開發然後在樹莓派上面執行Java程式(打包成jar執行),因此需要在樹莓派上面安裝Java環境(不過一般來說樹莓派都自帶了Java環境)。

建立專案

使用IDEA建立maven專案。

通過上述操作就建立一個Java maven專案。

配置maven檔案

然後配置maven檔案,也就是pom.xml,在其中匯入依賴庫,以及進行配置。

具體配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <appendAssemblyId>false</appendAssemblyId>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <!--注意,此處必須是main()方法對應類的完整路徑  -->
                            <mainClass>Main</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>assembly</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
	
    <!--    生成的包名-->
    <groupId>org.example</groupId>
    <artifactId>IotForTecentBeep</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--    新增依賴庫-->
    <dependencies>
        <!--        騰訊IOT庫-->
        <dependency>
            <groupId>com.tencent.iot.explorer</groupId>
            <artifactId>explorer-device-java</artifactId>
            <version>1.0.0</version>
        </dependency>
        <!--        樹莓派GPIO 庫-->
        <dependency>
            <groupId>com.pi4j</groupId>
            <artifactId>pi4j-core</artifactId>
            <version>1.2</version>
        </dependency>


    </dependencies>

</project>

專案檔案配置

在專案的目錄下面新增data.json檔案。

data.json需要存放一些資料。這個資料實際上就是自定義功能的json資料,從頁面複製之後貼上到data.json檔案中即可。

程式碼編寫

使用Java編寫程式碼,具體的解釋可以看程式碼中間的註釋。不過要注意,需要根據自己的裝置情況更改如下的資訊。

同時,在這個地方需要根據自己的情況修改。(儘管在雲平臺中定義的是布林型資料,但是實際上騰訊雲傳送過來的是int型別資料。)

在程式碼中要注意,必須先訂閱(也就是執行subscribeTopic函式),才能夠進行接收到平臺傳送過來的資料。

import com.pi4j.io.gpio.*;
import com.tencent.iot.explorer.device.java.common.Status;
import com.tencent.iot.explorer.device.java.data_template.TXDataTemplateDownStreamCallBack;
import com.tencent.iot.explorer.device.java.mqtt.TXMqttActionCallBack;
import com.tencent.iot.explorer.device.java.server.samples.data_template.DataTemplateSample;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.json.JSONObject;

/**
 * @author XiaoHui
 */
public class Main {
    /**
     * IOT平臺URL
     */
    public static String mBrokerURL = "ssl://iotcloud-mqtt.gz.tencentdevices.com:8883";
    /**
     * 產品ID
     */
    public static String mProductID = "64ONICJ3N8";
    /**
     * 裝置名稱
     */
    public static String mDevName = "my_pi";
    /**
     * 裝置金鑰
     */
    public static String mDevPSK = "1ktYq8uojYiuJgX7iZxAoQ==";
    /**
     * 儲存屬性的json檔名
     */
    public static String mJsonFileName = "data.json";

    private static DataTemplateSample mDataTemplateSample;

    /**
     * 獲得GPIO的控制器
     */
    public static final GpioController gpio = GpioFactory.getInstance();
    /**
     * GPIO輸出,使用GPIO_00 ,預設輸出為High
     */
    public static final GpioPinDigitalOutput beep = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_00, "beep", PinState.HIGH);


    public static void main(String[] args) {
        // CallBack 代表的是MQTT協議的回撥函式,MyDownCallback代表的是IOT平臺下發訊息的回撥
        mDataTemplateSample = new DataTemplateSample(mBrokerURL, mProductID, mDevName, mDevPSK,
                null, null, new CallBack(), mJsonFileName, new MyDownCallback());
        // 進行連線
        mDataTemplateSample.connect();
        // 進行訂閱,只有訂閱後,訊息才能下發。
        mDataTemplateSample.subscribeTopic();
        mDataTemplateSample.propertyClearControl();
    }

    /**
     * MQTT的回撥函式,可以不用管
     */
    public static class CallBack extends TXMqttActionCallBack {

        @Override
        public void onConnectCompleted(Status status, boolean reconnect, Object userContext, String msg) {

        }

        @Override
        public void onConnectionLost(Throwable cause) {

        }

        @Override
        public void onDisconnectCompleted(Status status, Object userContext, String msg) {
        }

        @Override
        public void onPublishCompleted(Status status, IMqttToken token, Object userContext, String errMsg) {
        }

        @Override
        public void onSubscribeCompleted(Status status, IMqttToken asyncActionToken, Object userContext, String errMsg) {
        }

        @Override
        public void onMessageReceived(final String topic, final MqttMessage message) {

        }

    }

    /**
     * 實現下行訊息處理的回撥介面
     */
    private static class MyDownCallback extends TXDataTemplateDownStreamCallBack {

        @Override
        public void onReplyCallBack(String msg) {

        }

        @Override
        public void onGetStatusReplyCallBack(JSONObject data) {


        }

        /**
         * 在微信小程式點選關閉按鈕後,IOT平臺會向樹莓派傳送命令訊息,此命令訊息會在這這裡進行回撥
         * beep是低電平觸發!!!!!!!!!!!!
         *
         * @param msg 接收到的訊息。
         * @return
         */
        @Override
        public JSONObject onControlCallBack(JSONObject msg) {

			// 獲得開關的資料,beep_switch是開關的識別符號。儘管我們在雲平臺中定義的是布林型資料,但是實際上騰訊雲傳送過來的是int型別資料。
            int power = msg.getInt("beep_switch");
            // 開啟開關
            if (power == 1) {
                beep.low();
                System.out.println("開啟");
            } else {
                // 關閉蜂鳴器
                beep.high();
                System.out.println("關閉");
            }
            // 返回訊息
            JSONObject result = new JSONObject();
            result.put("code", 0);
            result.put("status", "ok");
            return result;
        }

        @Override
        public JSONObject onActionCallBack(String actionId, JSONObject params) {
           return null;
        }
    }

}

程式碼打包

因為我們的程式碼是在windows上面編譯的,因此需要將其編譯成jar檔案,這個也就是之前配置pom.xml檔案的原因。IDEA上面編譯還是挺簡單的,如下圖所示:

經過如上的操作我們就將專案編譯成了jar包,jar包在target目錄下。

程式執行

將編譯好的jar檔案放到樹莓派中,使用VNC或者XShell皆可。然後在jar包檔案目錄下使用如下命令:

java -jar 包名

此次專案生成的包名為IotForTecentBeep-1.0-SNAPSHOT.jar,因此命令如下所示:

當程式執行起來的時候,就可以在微信小程式或者線上除錯工具中對蜂鳴器進行控制。

微信小程式控制

前面說了,可以是用微信小程式對開發的物聯網裝置進行開發除錯,然後在如下的頁面得到裝置的二維碼。

然後開啟”騰訊連連“小程式,對二維碼進行掃描,即可將裝置加入。

點選中間的按鈕就可以實現對蜂鳴器的控制了!!!

總結

相比較於上一篇騰訊IOT安卓開發初探,這一次實現訊息的下發接收控制。不過有一說一,官方文件是真的坑,連一個比較詳細的說明文件都沒有,還得自己一個一個Debug,檢視為什麼訊息傳送失敗,檢視為什麼沒有接收到下發的訊息……

GitHub:https://github.com/xiaohuiduan/IotForTecentBeep

參考

  1. 騰訊IOT安卓開發初探

  2. 物聯網開發平臺使用文件:物聯網開發平臺 - 文件中心 - 騰訊雲 (tencent.com)

  3. Github:iot-device-java

  4. 樹莓派4的GPIO介面介紹 – 八色木 (basemu.com)

  5. 樹莓派---JAVA操作GPIO

相關文章