如何基於SDK快速開發一款IoT App控制智能燈泡(Android版)

  對於如今上班打工族來講,當你帶着惺忪的雙眼,揹着沉重的電腦包,爬着長長的樓梯,回到租的房屋,一開門,烏七八黑,頓時片刻的孤獨席捲而來,奈何還須要用手沿着冰冷的牆壁,去摸索着開關。一開燈,刺眼的光芒射進眼球裏,原本就沉重的心,又澆了一壺冰水。時光機日後撥一下,當你晚上回家,打開門的時候,一束溫暖的燈光,伴隨着門的打開流露出來,有點像小學課本里,遊子在家門不遠處看到母親打着燈籠的光若隱若散。時光機回到如今,對於新世紀的程序員,咱們艱鉅着改變世界的重任,實現一款智能燈APP,改變你們對燈的認識是很是重要的。好比早上起牀,伴隨着鬧鐘,冷光燈亮起,走到廚房,自動啓動照明,晚上回家,暖光在開門前就已經亮起。html

那麼如何實現一款智能燈APP呢?首先先了解下智能燈的基礎功能android

智能燈APP基礎功能

智能定時功能

  • 能夠按照日、周進行設計定時器,能夠實現單次,循環定時,能夠對分組進行設置定時。

遠程控制功能

  • 經過家用無線路由器組成的局域網與其餘終端設備(手機、平板等)進行通信,還能夠遠程遙控燈光操做,實現對燈光的開,關,調光,場景,彩光模式等控制。

色彩調節功能

  • 經過色彩調節功能,能夠實現16777216 種顏色的調節。

地理圍欄功能

  • 智能燈控APP能夠爲用戶實現離家和到家模式。

智能音樂燈功能

  • 能夠經過手機音樂和燈結合在一塊兒,實現燈隨着音樂有節律的閃爍。

智能場景功能

  • 經過專家精心調優出四大場景功能,能夠實現柔光模式、繽紛模式、炫彩模式、斑斕模式。

智能燈應用場景

辦公場景

  • 針對辦公場景,智能燈具備白光調節模式,還擁有閱讀模式的場景能夠選擇

客廳餐廳會客平常場景

  • 能夠採用休閒模式,調節氣氛。

客廳——臥室場景

  • 臥室場景推薦使用暖光模式

起牀喚醒場景

  • 能夠經過設置智能定時實現起牀播放音樂,並喚醒音樂燈。

打造智能燈如何快速實現?

準備工做

註冊開發者帳號

前往 塗鴉智能開發平臺 註冊開發者帳號、建立產品、建立功能點等,具體流程請參考接入流程c++

建立 SDK 應用

塗鴉 IoT 平臺中 「App 工做臺」 中點擊 「App SDK」,點擊「建立 App」。git

image.png

填寫 App 相關信息,點擊確認程序員

  • 應用名稱:填寫您的 App 名稱。
  • iOS 應用包名:填寫您的 iOS App 包名(建議格式:com.xxxxx.xxxxx)。
  • 安卓應用包名:填寫您的安卓 App 包名(二者能夠保持一致,也能夠不一致)。
  • 渠道標識符:不是必填項,若是不填寫,系統會根據包名自動生成。

image.png

您能夠根據實際需求選擇須要的選擇方案,支持多選,而後根據 Podfile 和 Gradle 進行 SDK 的集成。github

image.png

點擊獲取密碼,獲取 SDK 的 AppKey,AppSecret,安全圖片等信息。json

image.png

集成 Home SDK

建立工程

在 Android Studio 中新建工程。api

配置 build.gradle

build.gradle 文件裏添加集成準備中下載的 dependencies 依賴庫。安全

android {
    defaultConfig {
        ndk {
            abiFilters "armeabi-v7a", "arm64-v8a"
        }
    }
    packagingOptions {
        pickFirst 'lib/*/libc++_shared.so' // 多個aar存在此so,須要選擇第一個
    }
}
dependencies {
    implementation 'com.alibaba:fastjson:1.1.67.android'
    implementation 'com.squareup.okhttp3:okhttp-urlconnection:3.14.9'
      
    // Tuya Home 最新穩定版:
    implementation 'com.tuya.smart:tuyasmart:3.20.0'
}

在根目錄的 build.gradle 文件中增長 jcenter() 倉庫網絡

repositories {
    jcenter()
}

[!TIP]

  • 塗鴉智能 3.10.0 以前的版本的 sdk 默認只支持 armeabi-v7a,
  • 3.11.0 版本後已經將 armeabi-v7a、arm64-v8a 集成進 sdk,請將本地手動放入的 sdk 的相關 so 庫移除,使用 sdk 中提供的。
  • 若是集成新版本 so 庫。請移除以前老版本手動集成的庫,防止衝突或者代碼版本不一致致使的問題
  • 若有其餘平臺須要可前往 GitHub 獲取。

集成安全圖片

點擊 "下載安全圖片" ——"安全圖片下載" 下載安全圖片。

image.png

image.png

在集成準備中點擊「下載安全圖片」。將下載的安全圖片命名爲 「t_s.bmp」,放置到工程目錄的 assets 文件夾下。

image.png

設置 Appkey 和 AppSecret

在 AndroidManifest.xml 文件裏配置 appkey 和 appSecret,在配置相應的權限等

<meta-data
android:name="TUYA_SMART_APPKEY"
android:value="應用 Appkey" />
<meta-data
android:name="TUYA_SMART_SECRET"
android:value="應用密鑰 AppSecret" />

混淆配置

在 proguard-rules.pro 文件配置相應混淆配置

#fastJson
-keep class com.alibaba.fastjson.**{*;}
-dontwarn com.alibaba.fastjson.**

#mqtt
-keep class com.tuya.smart.mqttclient.mqttv3.** { *; }
-dontwarn com.tuya.smart.mqttclient.mqttv3.**

#OkHttp3
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
-dontwarn okhttp3.**

-keep class okio.** { *; }
-dontwarn okio.**

-keep class com.tuya.**{*;}
-dontwarn com.tuya.**

初始化 SDK

描述

用於初始化 SDK,請在 Application 中初始化 SDK,確保全部進程都能初始化。

示例代碼

public class TuyaSmartApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        TuyaHomeSdk.init(this);
    }
}

appId 和 appSecret 須要配置 AndroidManifest.xml 文件裏,也能夠在初始化代碼裏初始化。

TuyaHomeSdk.init(Application application, String appkey, String appSerect)

註銷塗鴉智能雲鏈接

在退出應用的時候調用如下接口註銷掉。

TuyaHomeSdk.onDestroy();

調試開關

在 debug 模式下能夠開啓 SDK 的日誌開關,查看更多的日誌信息,幫助快速定位問題。在 release 模式下建議關閉日誌開關。

TuyaHomeSdk.setDebugMode(true);

集成照明控制SDK

在接入 照明控制 SDK 以前,您能夠先了解一下 照明燈的DEMO,須要把DEMO跑起來,登錄成功以後,在進行下列操做,照明控制 SDK 須要依賴 Home SDK 其中的一部分,下面的文檔也會介紹到依賴的這一部分。

依賴說明

// homesdk 依賴,注意,必須使用大於等於此版本的SDK
implementation 'com.tuya.smart:tuyasmart:3.20.0'
// 控制SDK依賴
implementation 'com.tuya.smart:tuyasmart-centralcontrol:1.0.2'

須要注意的是,tuyasmart-centralcontrol使用了kotlin編譯,須要引入kotlin庫確保其正常使用。

項目中已引入kotlin的可忽略下面的配置。

kotlin接入

在根目錄的build.gradle中引入kotlin插件的依賴:

buildscript {
    ext.kotlin_version = '1.3.72'
    dependencies {
        ...
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

在app的build.gradle中引入kotlin插件和kotlin包:

apply plugin: 'kotlin-android'
dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

標準指令說明

使用標準指令以前

未使用標準控制指令時,設備控制 通常使用這種方式:

ITuyaDevice mDevice = TuyaHomeSdk.newDeviceInstance(String devId);
// 監聽控制結果
mDevice.registerDevListener(new IDevListener() {
    @Override
    public void onDpUpdate(String devId, String dpStr) {

    }
    @Override
    public void onRemoved(String devId) {

    }
    @Override
    public void onStatusChanged(String devId, boolean online) {

    }
    @Override
    public void onNetworkStatusChanged(String devId, boolean status) {

    }
    @Override
    public void onDevInfoUpdate(String devId) {

    }
});
mDevice.publishDps("{\"101\": true}", new IResultCallback() {
    @Override
    public void onError(String code, String error) {
        Toast.makeText(mContext, "開燈失敗", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onSuccess() {
        Toast.makeText(mContext, "開燈成功", Toast.LENGTH_SHORT).show();
    }
});

這種方式控制時,會發送dpId,如10一、102之類的給設備來控制。其中101就是這個設備定義的開關dpId。

這麼作的缺點是,若是另外一個設備也有開關功能,可是不是101控制開關,你就須要傳入不一樣的參數來控制。而當n個設備都有開關功能,可是卻dpId都不一樣,就要寫很是多的適配邏輯。

爲了解決同一個功能定義的id不一樣的問題,引入了標準指令的概念。

判斷當前產品是否支持標準指令

根據產品 id 判斷當前產品是否支持標準指令。

使用標準指令須要判斷當前設備是否支持標準指令控制,不支持的設備不可使用該控制方式,只能使用以前的接口控制。

示例代碼:

boolean isStandard = TuyaHomeSdk.getDataInstance().isStandardProduct("your_product_id");

其中的 productId 是產品 id,可從 DeviceBean 中獲取。

使用標準指令以後

什麼是標準指令

標準指令就是特定功能的標準編號。如照明類設備的開燈功能,其標準指令必定是"switch_led"。發送控制指令switch_led,必定能夠控制照明設備的開關。

在集成了此SDK以後,調用方式變化以下:

ITuyaDevice mDevice = TuyaHomeSdk.newDeviceInstance(String devId);
// 注意:這裏方法是registerDeviceListener,註冊的 Listener 是 IDeviceListener
tuyaDevice.registerDeviceListener(new IDeviceListener() {
    @Override
    public void onDpUpdate(String devId, Map<String, Object> dpCodeMap) {

    }

    @Override
    public void onRemoved(String devId) {

    }

    @Override
    public void onStatusChanged(String devId, boolean online) {

    }

    @Override
    public void onNetworkStatusChanged(String devId, boolean status) {

    }

    @Override
    public void onDevInfoUpdate(String devId) {

    }
});
HashMap<String, Object> dpCodeMap = new HashMap<>();
dpCodeMap.put("switch_led", true);
// 發送標準指令
tuyaDevice.publishCommands(dpCodeMap, new IResultCallback() {
    @Override
    public void onError(String code, String error) {
        Toast.makeText(mContext, "開燈失敗", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onSuccess() {
        Toast.makeText(mContext, "開燈成功", Toast.LENGTH_SHORT).show();
    }
});

注意:標準指令使用方法registerDeviceListener註冊監聽, 非標準是registerDevListener

值得注意的是,目前不是全部設備都支持標準指令控制,後文會說明如何判斷該設備是否支持標準指令控制。

若是不支持的設備,而又必須使用標準控制,須要聯繫塗鴉適配。

標準指令文檔

全部標準指令均可以在塗鴉智能平臺查找到:

燈具(dj) 標準指令集

開關-插座-排插(kg,cz,pc) 標準指令集

場景開關(cjkg) 標準指令集

等等。

有了tuyaDevice.publishCommands方法和上面的指令,就能夠發送標準指令來控制設備。

品類說明

塗鴉 iot 平臺上有不少品類的iot設備,不一樣的品類在塗鴉平臺上都有固定的編號(category)。

開發者文檔上體如今每一個品類指令集的標題上,如 燈具(dj) 標準指令集djdj就是燈具的category值。

使用 category 字段能夠判斷當前設備是什麼產品,來展現不一樣的面板。

品類列表

此表格包含大多數支持的品類,具體可參見 iot 平臺。

image.png
image.png

獲取產品的品類值(category)

經過產品 id 獲取產品的品類值。

示例代碼:

String category = TuyaHomeSdk.getDataInstance().getStandardProductConfig("your_product_id").category;

照明設備控制

塗鴉照明設備同時存在v1和v2新舊兩種固件,即便使用了標準指令,也須要開發兩套控制邏輯。

所以對照明設備功能進行封裝,封裝了燈具設備的開關、工做模式切換、亮度控制、冷暖控制、彩光控制和四種情景模式的控制。

快速使用

首先,建立ITuyaLightDevice對象,燈相關的方法均封裝在此方法中。

ITuyaLightDevice lightDevice = new TuyaLightDevice(String devId);

該對象封裝了燈的全部dp點,包括控制指令的下發和上報。

這裏提供幾個簡單的調用示例:

// 建立lightDevice
ITuyaLightDevice lightDevice = new TuyaLightDevice("vdevo159793004250542");

// 註冊監聽
lightDevice.registerLightListener(new ILightListener() {
    @Override
    public void onDpUpdate(LightDataPoint dataPoint) { // 返回LightDataPoint,包含燈全部功能點的值
        Log.i("test_light", "onDpUpdate:" + dataPoint);
    }

    @Override
    public void onRemoved() {
        Log.i("test_light", "onRemoved");
    }

    @Override
    public void onStatusChanged(boolean status) {
        Log.i("test_light", "onDpUpdate:" + status);
    }

    @Override
    public void onNetworkStatusChanged(boolean status) {
        Log.i("test_light", "onDpUpdate:" + status);
    }

    @Override
    public void onDevInfoUpdate() {
        Log.i("test_light", "onDevInfoUpdate:");
    }
});
// 開燈
lightDevice.powerSwitch(true, new IResultCallback() {
    @Override
    public void onError(String code, String error) {
        Log.i("test_light", "powerSwitch onError:" + code + error);
    }

    @Override
    public void onSuccess() {
        Log.i("test_light", "powerSwitch onSuccess:");
    }
});
// 晚安場景
lightDevice.scene(LightScene.SCENE_GOODNIGHT, new IResultCallback() {
    @Override
    public void onError(String code, String error) {
        Log.i("test_light", "scene onError:" + code + error);
    }

    @Override
    public void onSuccess() {
        Log.i("test_light", "scene onSuccess:");
    }
});
// 設置顏色
lightDevice.colorHSV(100, 100, 100, new IResultCallback() {
    @Override
    public void onError(String code, String error) {
        Log.i("test_light", "colorHSV onError:" + code + error);
    }
    @Override
    public void onSuccess() {
        Log.i("test_light", "colorHSV onSuccess:");
    }
});

更多API請參考下面的文檔。

註冊監聽

方法說明

/**
 * 註冊監聽
 */
void registerLightListener(ILightListener listener);

其中,ILightListener回調以下:

public interface ILightListener {
    /**
     * 監聽照明設備dp點變化
     *
     * @param dataPoint 該燈具全部dp點的狀態
     */
    void onDpUpdate(LightDataPoint dataPoint);

    /**
     * 設備移除
     */
    void onRemoved();

    /**
     * 設備上下線
     */
    void onStatusChanged(boolean online);

    /**
     * 網絡狀態
     */
    void onNetworkStatusChanged(boolean status);

    /**
     * 設備信息更新例如name之類的
     */
    void onDevInfoUpdate();
}

參數說明

值得說明的是LightDataPoint對象,該對象封裝了當前設備全部功能點。當功能點發生變化時,將會回調。每次回調的都會是完整的對象。

如下是該對象參數的具體含義:

public class LightDataPoint {
    /**
     * 開關
     */
    public boolean powerSwitch;
    /**
     * 工做模式。
     * <p>
     * MODE_WHITE爲白光模式;
     * MODE_COLOUR爲彩光模式;
     * MODE_SCENE爲情景模式;
     */
    public LightMode workMode;

    /**
     * 亮度百分比,從0到100
     */
    public int brightness;

    /**
     * 色溫百分比,從0到100
     */
    public int colorTemperature;

    /**
     * 顏色值,HSV色彩空間.
     * <p>
     * 其中H爲色調,取值範圍0-360;
     * 其中S爲飽和度,取值範圍0-100;
     * 其中V爲明度,取值範圍0-100;
     */
    public LightColourData colorHSV;
    /**
     * 彩燈情景。
     *
     * SCENE_GOODNIGHT爲晚安情景;
     * SCENE_WORK爲工做情景;
     * SCENE_READ爲閱讀情景;
     * SCENE_CASUAL爲休閒情景;
     */
    public LightScene scene;
}

獲取當前燈的類型

燈共分爲一路燈(僅有白光)、二路燈(白光+冷暖控制)、三路燈(僅有彩光模式)、四路燈(白光+彩光)、五路燈(白光+彩光+冷暖)。

這5種燈具在功能定義上有所區別,在開發相應的UI和控制時有所區別。

該方法可獲取當前燈的類型。

/**
 * 獲取當前是幾路燈
 *
 * @return {@link LightType}
 */
LightType lightType();

其中LightType中定義的類型有:

/**
 * 白光燈,dpCode:bright_value
 */
TYPE_C,
/**
 * 白光+冷暖,dpCode:bright_value + temp_value
 */
TYPE_CW,
/**
 * RGB,dpCode:colour_data
 */
TYPE_RGB,
/**
 * 白光+RGB,dpCode:bright_value + colour_data
 */
TYPE_RGBC,
/**
 * 白光+冷暖+RGB,dpCode:bright_value + temp_value + colour_data
 */
TYPE_RGBCW

獲取當前設備全部功能的值

打開一個設備面板時,須要獲取全部功能點值來展現。可經過此接口獲取上面提到的LightDataPoint對象。

/**
 * 獲取燈全部功能點的值
 */
LightDataPoint getLightDataPoint();

開關

控制燈的開關

方法說明

/**
 * 開燈 or 關燈
 *
 * @param status         true or false
 * @param resultCallback callback
 */
void powerSwitch(boolean status, IResultCallback resultCallback);

參數說明

image.png

工做模式

控制工做模式的切換。

方法說明

/**
 * 切換工做模式
 *
 * @param mode           工做模式
 * @param resultCallback callback
 */
void workMode(LightMode mode, IResultCallback resultCallback);

參數說明

image.png

調用示例

如切換到彩光模式:

lightDevice.workMode(LightMode.MODE_COLOUR, new IResultCallback() {
    @Override
    public void onError(String code, String error) {
        Log.i("test_light", "workMode onError:" + code + error);
    }

    @Override
    public void onSuccess() {
        Log.i("test_light", "workMode onSuccess");
    }
});

注意:部分燈具必須切換到對應的工做模式才能夠控制,好比控制彩光,必須先切換到彩光模式才能夠發顏色的值。

亮度

控制亮度

方法說明

/**
 * 亮度控制。
 *
 * @param status         亮度的百分比,取值範圍0-100
 * @param resultCallback callback
 */
void brightness(int status, IResultCallback resultCallback);

參數說明

image.png

冷暖

控制燈的冷暖值

方法說明

/**
 * 色溫控制
 *
 * @param status         色溫的百分比,取值範圍0-100
 * @param resultCallback callback
 */
void colorTemperature(int status, IResultCallback resultCallback);

參數說明

image.png

彩光

控制彩色燈的顏色

方法說明

/**
 * 設置彩燈的顏色
 *
 * @param hue            色調 (範圍:0-360)
 * @param saturation     飽和度(範圍:0-100)
 * @param value          明度(範圍:0-100)
 * @param resultCallback callback
 */
void colorHSV(int hue, int saturation, int value, IResultCallback resultCallback);

情景

切換彩燈的情景模式,目前共有四種模式:

LightScene.SCENE_GOODNIGHT爲晚安情景;
LightScene.SCENE_WORK爲工做情景;
LightScene.SCENE_READ爲閱讀情景;
LightScene.SCENE_CASUAL爲休閒情景;

方法說明

/**
 * @param lightScene     {@link LightScene}
 * @param resultCallback callback
 */
void scene(LightScene lightScene, IResultCallback resultCallback);

定時器

現有的定時器不支持標準Code 定時,須要進行標準Code轉義成Id才能進行設置定時器,參考原有定時器

方法調用
/**
 * @param dpCodes  標準DpCode指令
 * @param devId    設備ID
 */
Map<String, Object> convertCodeToIdMap(Map<String, Object> dpCodes, String devId);
示例代碼
Map<String, Object> dps=TuyaHomeSdk.getDataInstance().getStandardConverter().convertCodeToIdMap(Map<String, Object> dpCodes, String devId);
TuyaTimerBuilder builder = new TuyaTimerBuilder.Builder()
        .taskName(mTaskName)
        .devId("efw9990wedsew")
        .deviceType(TimerDeviceTypeEnum.DEVICE)
        .actions(dps)  
        .loops("1100011")
        .aliasName("Test")
        .status(1)
        .appPush(true)
        .build();
TuyaHomeSdk.getTimerInstance().addTimer(builder, new IResultCallback() {
    @Override
    public void onSuccess() {
            }

    @Override
    public void onError(String errorCode, String errorMsg) {

    }
});
相關文章
相關標籤/搜索