对于当初下班打工族来说,当你带着惺忪的双眼,背着惨重的电脑包,爬着长长的楼梯,回到租的屋宇,一开门,乌七八黑,登时片刻的孤单席卷而来,奈何还须要用手沿着寒冷的墙壁,去摸索着开关。一开灯,扎眼的光辉射进眼球里,原本就惨重的心,又浇了一壶冰水。时光机往后拨一下,当你早晨回家,打开门的时候,一束和煦的灯光,随同着门的关上流露出来,有点像小学课本里,游子在家门不远处看到母亲打着灯笼的光若隐若散。时光机回到当初,对于新世纪的程序员,咱们艰巨着扭转世界的重任,实现一款智能灯APP,扭转大家对灯的意识是十分重要的。比方早上起床,随同着闹钟,冷光灯亮起,走到厨房,主动启动照明,早晨回家,暖光在开门前就曾经亮起。

那么如何实现一款智能灯APP呢?首先先理解下智能灯的根底性能

智能灯APP根底性能

智能定时性能
  • 能够依照日、周进行设计定时器,能够实现单次,循环定时,能够对分组进行设置定时。
近程管制性能
  • 通过家用无线路由器组成的局域网与其余终端设备(手机、平板等)进行通信,还能够近程遥控灯光操作,实现对灯光的开,关,调光,场景,彩光模式等管制。
色调调节性能
  • 通过色调调节性能,能够实现16777216 种颜色的调节。
天文围栏性能
  • 智能灯控APP能够为用户实现离家和到家模式。
智能音乐灯性能
  • 能够通过手机音乐和灯联合在一起,实现灯随着音乐有节律的闪动。
智能场景性能
  • 通过专家精心调优出四大场景性能,能够实现柔光模式、缤纷模式、炫彩模式、斑斓模式。

智能灯利用场景

办公场景
  • 针对办公场景,智能灯具备白光调节模式,还领有浏览模式的场景能够抉择
客厅餐厅会客日常场景
  • 能够采纳休闲模式,调节氛围。
客厅——卧室场景
  • 卧室场景举荐应用暖光模式
起床唤醒场景
  • 能够通过设置智能定时实现起床播放音乐,并唤醒音乐灯。

打造智能灯如何疾速实现?

筹备工作

注册开发者账号

返回 涂鸦智能开发平台 注册开发者账号、创立产品、创立性能点等,具体流程请参考接入流程

创立 SDK 利用

在涂鸦 IoT 平台中 “App 工作台” 中点击 “App SDK”,点击“创立 App”。

填写 App 相干信息,点击确认

  • 利用名称:填写您的 App 名称。
  • iOS 利用包名:填写您的 iOS App 包名(倡议格局:com.xxxxx.xxxxx)。
  • 安卓利用包名:填写您的安卓 App 包名(两者能够保持一致,也能够不统一)。
  • 渠道标识符:不是必填项,如果不填写,零碎会依据包名主动生成。

您能够依据理论需要抉择须要的抉择计划,反对多选,而后依据 Podfile 和 Gradle 进行 SDK 的集成。

点击获取明码,获取 SDK 的 AppKey,AppSecret,平安图片等信息。

集成 Home SDK

创立工程

在 Android Studio 中新建工程。

配置 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 获取。

集成平安图片

点击 "下载平安图片" ——"平安图片下载" 下载平安图片。

在集成筹备中点击“下载平安图片”。将下载的平安图片命名为 “t_s.bmp”,搁置到工程目录的 assets 文件夹下。

设置 Appkey 和 AppSecret

在 AndroidManifest.xml 文件里配置 appkey 和 appSecret,在配置相应的权限等

<meta-dataandroid:name="TUYA_SMART_APPKEY"android:value="利用 Appkey" /><meta-dataandroid: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 依赖,留神,必须应用大于等于此版本的SDKimplementation '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,如101、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 是 IDeviceListenertuyaDevice.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 平台。


获取产品的品类值(category)

通过产品 id 获取产品的品类值。

示例代码:

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

照明设备管制

涂鸦照明设备同时存在v1和v2新旧两种固件,即便应用了规范指令,也须要开发两套管制逻辑。

因而对照明设备性能进行封装,封装了灯具设施的开关、工作模式切换、亮度管制、冷暖管制、彩光管制和四种情景模式的管制。

疾速应用

首先,创立ITuyaLightDevice对象,灯相干的办法均封装在此办法中。

ITuyaLightDevice lightDevice = new TuyaLightDevice(String devId);

该对象封装了灯的所有dp点,包含控制指令的下发和上报。

这里提供几个简略的调用示例:

// 创立lightDeviceITuyaLightDevice 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);

参数阐明

工作模式

管制工作模式的切换。

办法阐明

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

参数阐明

调用示例

如切换到彩光模式:

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);

参数阐明

冷暖

管制灯的冷暖值

办法阐明

/** * 色温管制 * * @param status         色温的百分比,取值范畴0-100 * @param resultCallback callback */void colorTemperature(int status, IResultCallback resultCallback);

参数阐明

彩光

管制黑白灯的色彩

办法阐明

/** * 设置彩灯的色彩 * * @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) {    }});