騰訊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