騰訊IOT之樹莓派物聯網裝置
本次實驗的目的是將樹莓派設定為一個物聯網終端,通過微信小程式可以控制樹莓派,實現蜂鳴器的開關。
微信小程式介面如下所示,點選這個開關,就可以控制蜂鳴器。
專案地址:https://github.com/xiaohuiduan/IotForTecentBeep
硬體配置
- 樹莓派
- 蜂鳴器
在這裡我將樹莓派接的是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開發,因此直接點選下一步。
點選下一步就到了微信小程式配置。
微信小程式配置
騰訊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