导航链接
(1)香橙派+apache2与php+天猫精灵=自建平台语音支持--前言
(2)香橙派+apache2与php+天猫精灵=自建平台语音支持--香橙派操作系统安装
(3)香橙派+apache2与php+天猫精灵=自建平台语音支持--香橙派环境配置
(4)香橙派+apache2与php+天猫精灵=自建平台语音支持--apache2与php
(5)香橙派+apache2与php+天猫精灵=自建平台语音支持--MariaDB的安装
(6)香橙派+apache2与php+天猫精灵=自建平台语音支持--天猫精灵对接1
(7)香橙派+apache2与php+天猫精灵=自建平台语音支持--天猫精灵对接2
(8)香橙派+apache2与php+天猫精灵=自建平台语音支持--天猫精灵对接3
(9)香橙派+apache2与php+天猫精灵=自建平台语音支持--天猫精灵对接4
(10)香橙派+apache2与php+天猫精灵=自建平台语音支持--天猫精灵对接5
(11)香橙派+apache2与php+天猫精灵=自建平台语音支持--天猫精灵对接6
(12)香橙派+apache2与php+天猫精灵=自建平台语音支持--天猫精灵对接7
设备控制
下面我们来讲解设备控制的过程,先放上一个时序图。
下图所示为设备控制协议的详细内容和解析,只截出打开指令协议的详细内容,其他的协议内容于此类似
case 'AliGenie.Iot.Device.Control': {
error_log('----case in Control----');
$result = device_control($obj, $messageId);
break;
}
device_control解析处理后传回来,device_control在aligenies_handle.php中就是对发送过来的设备名,设备动作,查看天猫POST过来的数据包是否正确,如果正确给出正确的响应,如果不正确给出错误的响应,不再列举具体的解析协议,只给出处理的过程。
function device_control($obj, $messageId)
{
error_log('----device_control in----');
global $sqlFileName;
$deviceId = $obj->payload->deviceId;
$action = '';
$deviceType = '';//Customize device type
$deviceType = device_id_to_type($deviceId);
error_log("deviceType-->".$deviceType);
$action = get_control_action($obj->header->name);
error_log("action-->".$action);
if ($action == "" || $deviceType == "") {
error_log('----get_control_action failed----');
$ret = new AliGenie\ControlResponse(true);
$ret->header->putResponseMessageId($messageId);
$ret->payload->putResponseError("SERVICE_ERROR",
"action or device not support,name:".$obj->header->name." device:".substr($deviceId,0,stripos($deviceId,".")));
$retJson = json_encode($ret);
return $retJson;
}
$validArray = array (
"deviceId" => $deviceId,
"deviceType" => $deviceType,
"actionName" => $obj->header->name,
"action" => $action,
"attribute" => $obj->payload->attribute,
"value" => $obj->payload->value
);
$checkResult = control_checker($validArray);
if ($checkResult != 'succeed') {
error_log('----control_checker failed----');
$ret = new AliGenie\ControlResponse(true);
$ret->header->putResponseMessageId($messageId);
$ret->payload->putResponseError("DEVICE_NOT_SUPPORT_FUNCTION");
$retJson = json_encode($ret);
return $retJson;
}
//-----------------------------------
if (($txtRes = fopen($sqlFileName, "r+")) === false) {
error_log('----get_control fopen failed----');
$ret = new AliGenie\ControlResponse(true);
$ret->header->putResponseMessageId($messageId);
$ret->payload->putResponseError("SERVICE_ERROR", "CANNOT_OPEN");
$retJson = json_encode($ret);
return $retJson;
}
$str = fread($txtRes, filesize($sqlFileName));
error_log("str-->".$str);
$sqlObj = json_decode($str);
//error_log("sqlObj-->".print_r($sqlObj, true));
$ret = new AliGenie\ControlResponse();
$ret->header->putResponseMessageId($messageId);
$ret->header->putResponseName($obj->header->name);
$ret->payload->putResponseDeviceId($obj->payload->deviceId);
foreach ($sqlObj->dev_array as $devElement) {
error_log('entity_id-->'.$devElement->entity_id);
if ($devElement->entity_id == $validArray['deviceId']) {
$ret->payload->putResponseDeviceId($devElement->entity_id);
switch ($devElement->device_type) {
case 'ceiling_lamp': {
switch ($validArray['action']) {
case 'turn_on': {
foreach ($devElement->properties as $propertie) {
error_log('name-->'.$propertie->name);
if ($propertie->name == "powerstate") {
$propertie->value = "on";
break;
}
}
break;
}
case 'turn_off': {
foreach ($devElement->properties as $propertie) {
error_log('name-->'.$propertie->name);
if ($propertie->name == "powerstate") {
$propertie->value = "off";
break;
}
}
break;
}
case 'bright_set': {
foreach ($devElement->properties as $propertie) {
error_log('name-->'.$propertie->name);
if ($propertie->name == "brightness_w" && $propertie->value != 0) {
$propertie->value = $validArray['value'];
} else if ($propertie->name == "brightness_y" && $propertie->value != 0) {
$propertie->value = $validArray['value'];
}
}
break;
}
case 'bright_up': {
foreach ($devElement->properties as $propertie) {
error_log('name-->'.$propertie->name);
if ($propertie->name == "brightness_w" && $propertie->value != 0) {
$propertie->value += $validArray['value'];
if ($propertie->value > 100) {
$propertie->value = 100;
}
} else if ($propertie->name == "brightness_y" && $propertie->value != 0) {
$propertie->value += $validArray['value'];
if ($propertie->value > 100) {
$propertie->value = 100;
}
}
if ($propertie->name == "powerstate") {
$propertie->value = "on";
break;
}
}
break;
}
case 'bright_down': {
$brightnessWhite = '10';
$brightnessYellow = '10';
foreach ($devElement->properties as $propertie) {
error_log('name-->'.$propertie->name);
if ($propertie->name == "brightness_w" && $propertie->value != 0) {
$propertie->value -= $validArray['value'];
if ($propertie->value < 0) {
$propertie->value = 0;
}
$brightnessWhite = $propertie->value;
} else if ($propertie->name == "brightness_y" && $propertie->value != 0) {
$propertie->value -= $validArray['value'];
if ($propertie->value < 0) {
$propertie->value = 0;
}
$brightnessYellow = $propertie->value;
}
if ($brightnessWhite == 0 && $brightnessYellow == 0) {
foreach ($devElement->properties as $propertie) {
error_log('name-->'.$propertie->name);
if ($propertie->name == "powerstate") {
$propertie->value = "off";
break;
}
}
}
}
break;
}
case 'mode_set': {
$brightnessWhite = '0';
$brightnessYellow = '0';
foreach ($devElement->properties as $propertie) {
error_log('name-->'.$propertie->name);
if ($propertie->name == "brightness_w") {
$brightnessWhite = $propertie->value;
} else if ($propertie->name == "brightness_y") {
$brightnessYellow = $propertie->value;
}
}
$brightness = ($brightnessWhite>$brightnessYellow)?$brightnessWhite:$brightnessYellow;
foreach ($devElement->properties as $propertie) {
error_log('name-->'.$propertie->name);
if ($propertie->name == "brightness_w" || $propertie->name == "brightness_y") {
$propertie->value = $brightness;
}
}
break;
}
case 'color_set': {
if ($validArray['value'] == 'White') {
foreach ($devElement->properties as $propertie) {
error_log('name-->'.$propertie->name);
if ($propertie->name == "brightness_w") {
$propertie->value = 100;
} else if ($propertie->name == "brightness_y") {
$propertie->value = 0;
}
}
} else if ($validArray['value'] == 'Yellow') {
foreach ($devElement->properties as $propertie) {
error_log('name-->'.$propertie->name);
if ($propertie->name == "brightness_w") {
$propertie->value = 0;
} else if ($propertie->name == "brightness_y") {
$propertie->value = 100;
}
}
}
break;
}
}
break;
}
}
}
}
$jsonData = json_encode($sqlObj);
error_log('jsonData-->'.$jsonData);
fclose($txtRes);
if (($txtRes = fopen($sqlFileName, "w+")) === false) {
error_log('----get_control fopen failed----');
$ret = new AliGenie\ControlResponse(true);
$ret->header->putResponseMessageId($messageId);
$ret->payload->putResponseError("SERVICE_ERROR", "CANNOT_OPEN");
$retJson = json_encode($ret);
return $retJson;
}
if (!fwrite($txtRes, $jsonData)) {
fclose($txtRes);
error_log('----get_control fwrite failed----');
$ret = new AliGenie\ControlResponse(true);
$ret->header->putResponseMessageId($messageId);
$ret->payload->putResponseError("SERVICE_ERROR", "CANNOT_WRITE");
$retJson = json_encode($ret);
return $retJson;
}
fclose($txtRes);
$retJson = json_encode($ret);
error_log('----device_control out----');
return $retJson;
}
这里就不一一讲解了,基本就是时序图中显示的逻辑,读取文件,判断控制是否能够执行,执行就是保存sqldata的过程,原因在前面已经提到过了,最后将需要返回的json数据上报给天猫精灵。
天猫精灵特别有意思,记得在设备发现中需要提供可以支持查询的类别和可以控制的指令吗?其中对于颜色的查询和控制,天猫精灵并不支持所有颜色,而且并不支持“自然光”这种颜色,我们一般认为黄光和白光一半一半是自然光(严格来说当然不是,但是一般产品都是这么做的,约定俗成),但是你对天猫说“设置为自然光”,天猫精灵居然发过来的是key是mode,value是“自然光”,即使你再控制指令中没有包含“mode”他也会发过来,你甚至可以说“把灯调整为自然风模式”,天猫精灵都会发送过来mode,真是不知道设备发现中的那些参数到底有什么意义,而且在查询灯的状态时,会自动填上“正常模式”,我都没有传送mode属性自己就给填上这个属性,也是醉了,真是不知道其他厂商对于这种错误的参数处理需要增加多少逻辑代码。这也是我要转小度的原因之一。
至此控制基本完成,下一篇讲解最后的设备状态查询,估计到了这里设备状态查询都差不多的道理了。