前言

前面我们已经实现了智能烧水壶的离线控制,现在我们将完成最后一部分功能,实现烧水壶的云端控制

一、烧水壶的云端控制功能点

  • 此次实现的智能烧水壶可以远程控制保温、加热、定时煮沸等功能,具体的云端控制功能点如下:

功能名称

控制选项

煮沸

开启/关闭

设置保温温度

45-90摄氏度

保温

开启/关闭

水质选择

自来水/纯净水

温度显示

显示当前室温

当前温度显示

时间自行设定

定时煮沸

时间自行设定

干烧状态显示

正常/缺水

实现云端控制首先要实现dp数据触发的执行函数,下面我们将实现这些执行函数

1.实现煮沸控制的执行函数

此执行函数需要根据下发的dp数据控制水壶的煮沸功能,开和关触发后要实现的具体功能如下:

开:
1.水壶进入煮沸模式
2.煮沸和保温是互斥事件,关闭保温
3.更新煮沸和保温的dp数据,上报到云端
关:
1.水壶进入自然模式(无加热动作)
2.更新煮沸的dp数据,上报到云端
  • 功能点已确定,下面我们开始进行代码实现:
    在kettle_app.c中增加执行函数
static void dp_boil_handle(IN BOOL_T bONOFF)
{
    //开启煮沸
    if(bONOFF == TRUE) {
        set_kettle_work_status(boil);//切换水壶的工作状态到煮沸模式
        set_dp_boil_value(TRUE);//设置dp_boil控制点的值为1,即开启
        set_dp_keep_warm_switch(FALSE);//设置dp_keep_warm控制点的值为0,即关闭
        PR_DEBUG("dp_boil on");
    }else {//关闭煮沸
        set_kettle_work_status(nature);//切换水壶的工作状态到自然模式
        set_dp_boil_value(FALSE);//设置dp_boil控制点的值为0,即开启
        PR_DEBUG("dp_boil off");
    }
    report_one_dp_status(DP_BOIL);//上报dp_boil数据
    report_one_dp_status(DP_KEEP_WARM);//上报dp_keep_warm数据
}
//设定烧水壶的工作状态
void set_kettle_work_status(int status)
{
    tuya_hal_mutex_lock(mutex);
    kettle_work_information.status = status;
    tuya_hal_mutex_unlock(mutex);
}
//设置dp_boil的数据值
void set_dp_boil_value(bool value)
{
    tuya_hal_mutex_lock(mutex);
    boil_s.power = value;
    tuya_hal_mutex_unlock(mutex);
}
//设置dp_keep_warm的数据值
void set_dp_keep_warm_switch(bool value)
{

    tuya_hal_mutex_lock(mutex);
    keep_warm_s.power = value;
    tuya_hal_mutex_unlock(mutex);

}

此时煮沸控制的执行函数已实现。

2.实现设定保温温度的函数

设定保温温度的函数是通过云端设定进行触发,触发后要实现的具体功能如下:

1.根据云端发送的设置值设定保温温度值
2.更新dp_keep_warm_set的值为所设的温度值,并上报到云端
  • 功能点已确定,下面我们开始进行代码实现:
    在kettle_app.c中增加执行函数
static void dp_keep_warm_set_handle(IN int value)
{
    set_kettle_keep_warm_temper(value);//设置保温温度,注意设定保温温度不会直接触发保温
    report_one_dp_status(DP_TEMP_SET);//上报dp_keep_warm_set这个dp点的设定值到云端
}
//保温温度设置范围为45-90摄氏度
void set_kettle_keep_warm_temper(int value)
{
    if(44 < value < 91) {
        tuya_hal_mutex_lock(mutex);
        temp_set_s.value = value;
        kettle_work_information.warm_temperature = value;
        tuya_hal_mutex_unlock(mutex);
        PR_DEBUG("set keep warm temper:%d",value);
    }
}

此时保温温度设定函数已实现。

3.实现保温控制的执行函数

云端可以控制界面上的保温按钮决定是否开启保温,触发后要实现的具体功能如下:

开启:
1.判断当前设定的水质模式,若设定为自来水模式,烧水壶切换到保温1模式(先煮沸再保温)
2.判断当前设定的水质模式,若设定为纯净水模式,烧水壶切换到保温2模式(直接保温到设定温度)
3.关闭煮沸dp,上报煮沸dp和保温dp数据到云端
关闭:
1.切换烧水壶的工作状态到自然模式(无操作)
  • 功能点已确定,下面我们开始进行代码实现:
    在kettle_app.c中增加执行函数
static void dp_keep_warm_handle(IN BOOL_T bONOFF)
{
	//保温开启,水质模式为自来水模式,烧水壶进入保温1模式(先煮沸再保温)
    if(bONOFF == TRUE && (get_water_type() == tap_water)) {
        set_kettle_work_status(keep_warm_mode1);
        set_dp_keep_warm_switch(TRUE);
        set_dp_boil_value(FALSE);
        PR_DEBUG("keep_warm_mode1");
        //保温开启,水质模式为纯净水模式,烧水壶进入保温2模式(直接保温)
    }else if(bONOFF == TRUE && (get_water_type() == clear_water)){
        set_kettle_work_status(keep_warm_mode2);
        set_dp_keep_warm_switch(TRUE);
        set_dp_boil_value(FALSE);
        PR_DEBUG("keep_warm_mode2");
    }else {
    //关闭保温
        set_kettle_work_status(nature);
        set_dp_keep_warm_switch(FALSE);
        PR_DEBUG("close keep warm");
    }
    //上报dp数据
    report_one_dp_status(DP_KEEP_WARM);
    report_one_dp_status(DP_BOIL);
}

此时保温设置的执行函数已实现。

4.实现水质选择设定函数

云端可以控制水质选择,触发后要实现的具体功能如下:

1.根据传下的设定值设置水质模式:自来水/纯净水
2.若此时水壶处于自来水保温状态,且此时云端控制水质模式切换为纯净水,水壶状态切换到纯净水保温模式
3.若此时水壶处于纯净水保温状态,且此时云端控制水质模式切换为自来水,水壶状态切换到自来水保温模式
4.更新水质模式的dp数据并上报
  • 功能点已确定,下面我们开始进行代码实现:
    在kettle_app.c中增加执行函数
void dp_water_type_handle(int value)
{
    if(value == tap_water || value == clear_water) {
        //设置水质模式
        tuya_hal_mutex_lock(mutex);
        kettle_work_information.water_mode = value;
        water_type_s.value = value;
        tuya_hal_mutex_unlock(mutex);
        //此时水壶处于自来水保温状态,且此时云端控制水质模式切换为纯净水,水壶状态切换到纯净水保温模式
        if(get_kettle_work_status() == keep_warm_mode1 && get_water_type() == clear_water) {
            set_kettle_work_status(keep_warm_mode2);
        //此时水壶处于纯净水保温状态,且此时云端控制水质模式切换为自来水,水壶状态切换到自来水保温模式
        }else if(get_kettle_work_status() == keep_warm_mode2 && get_water_type() == tap_water) {
            set_kettle_work_status(keep_warm_mode1);
        }
        PR_DEBUG("water choose :%d",value);
        report_one_dp_status(DP_WATER_TYPE);
    }

}
//获取当前水壶的工作状态
int get_kettle_work_status()
{
    return kettle_work_information.status;
}
//获取当前的水质模式
int get_water_type()
{
    return kettle_work_information.water_mode;
}

此时水质选择设定函数已实现。

5.云端定时与温度云端显示说明

云端定时煮沸实际上是在云端设定定时任务,到达定时时间后云端会下发控制命令触发dp_boil这个dp点数据下发,从而触发烧水壶执行煮沸功能;温度云端显示和过温报警功能在前面的温度采集文章已经说明,故不在此说明。

云定时煮沸开启:
1.触发后发送煮沸dp_boil为开启状态
2.执行后将定时开启的状态清零

二、实现云端远程控制

上面已经实现了相应的执行函数,下面我们将实现app下发dp数据控制设备的功能。

  • 云端控制代码实现
//云端下发命令后触发此回调函数,从而触发deal_dp_proc函数,实现远程控制烧水壶工作
VOID dev_obj_dp_cb(IN CONST TY_RECV_OBJ_DP_S *dp)
{
    PR_DEBUG("dp->cid:%s dp->dps_cnt:%d",dp->cid,dp->dps_cnt);
    UCHAR_T i = 0;

    for(i = 0;i < dp->dps_cnt;i++) {
        deal_dp_proc(&(dp->dps[i]));
        //dev_report_dp_json_async(get_gw_cntl()->gw_if.id, dp->dps, dp->dps_cnt);
    }
}
//app下发命令后将会触发回调函数从而执行该函数,根据下发的DP_ID以及控制值执行相关函数
VOID_T deal_dp_proc(IN CONST TY_OBJ_DP_S *root)
{
    UCHAR_T dpid;
    dpid = root->dpid;
    
    switch (dpid){
    //煮沸控制
    case DP_BOIL: {
        dp_boil_handle(root->value.dp_bool);
        
        }
        break;
	//保温温度设置
    case DP_TEMP_SET: {
        dp_keep_warm_set_handle(root->value.dp_value);
        }
        break;
	//保温设置
    case DP_KEEP_WARM: {
        dp_keep_warm_handle(root->value.dp_bool);

        }
        break;
	//水质模式设置
    case DP_WATER_TYPE: {
        dp_water_type_handle(root->value.dp_enum);
        }
        break;

    default:
    
        break;
    }

}

至此我们已经实现了智能烧水的所有功能,将一个普通水壶改装成一个智能烧水壶。整体的功能设计和功能实现难免有些遗漏,欢迎大家提出问题或者提出你的想法,我们可以一同交流提高;后面也将推出更多有趣的、实用的智能化产品实现方案,欢迎大家去关注。