导航链接

(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

程序总体框架

首先我们需要模拟一个真正的外部设备通过天猫精灵进行交互的过程,对于一个设备来说主要是由控制,状态等组成,天猫精灵给了3中方式实现,分别是发现、控制和状态查询(Discovery,Control,Query)。对于一个服务器来说真的通过一些方法去控制远端的设备是很难的,因为远端的设备往往是无法直接访问,一般的实现方法是远端设备去定时访问服务器来同步最新的状态,如果服务器记录的状态改变则设备状态变化,如果本地的设备有主动变化则主动上报服务器去修改记录。服务器端一般是由一个对应设备的数据库来记录设备的状态,我们这里为了简便,我们使用一个txt文本模拟数据库,文本中的数据代表着远端设备的状态。

首先展示一下我们目录结构:

.
├── aligenie (针对天猫精灵的php文件)
│   ├── aligenies_authorize.php
│   ├── aligenies_gate.php
│   ├── aligenies_handle.php
│   ├── aligenies_server.php
│   ├── aligenies_token.php
│   ├── ControlResponse.php
│   ├── DiscoveryResponse.php
│   └── QueryResponse.php
├── icon (显示使用的图标)
│   ├── cz.png
│   └── td.png
├── oauth2-server-php (下载的认证源码)
└── sqldata.txt (模拟数据库的文本文件)

其中sqldata.txt就是我们用来模拟设备数据库的文件,其中的内容是我们设备需要记录的一个json结构,比如我们需要记录一个具有黄白双色的可调光的吸顶灯,一个开关。

{"dev_array": [{"entity_id": "light.ceiling_lamp.34ce008dc8c3","device_type": "ceiling_lamp","properties": [{"name": "powerstate","value": "on"},{"name": "brightness_w","value": 0},{"name": "brightness_y","value": 100}]},{"entity_id": "switch.gateway_switch.34ce008dc8c3","device_type": "gateway_switch","properties": [{"name": "powerstate","value": "on"}]}]
}

entity_id是设备ID,device_type是设备的类型,这个类型不是天猫使用的,而是我们自己定义的设备类型,properties是该设备具有的属性,powerstate是灯的状态属性,brightness_w是白色的亮度属性,brightness_y是黄色的亮度属性。在我们自己的app上可以比天猫精灵控制更多的属性(一般都是这样),比如我们可以自由的组合黄白双色的亮度比例,而天猫精灵一次对话只能控制其中一个属性的变化。

总的天猫精灵控制流程就是首先会进入aligenies_gate.php文件,这个是天猫精灵控制的入口,也是我们在天猫精灵服务器网页设置的网址,aligenies_gate.php中会调用aligenies_handle.php去处理数据,把天猫精灵的格式转为我们自己的格式,并做相应的动作。

ControlResponse.php,DiscoveryResponse.php,QueryResponse.php分别是天猫精灵需要回复的json格式的类,我们需要将类填充并转为json格式传给天猫精灵即可。

三种回复的格式

DiscoveryResponse.php文件是设备发现使用的回复格式

设备发现主要是如下的格式例子

正确相应

{"header":{"namespace":"AliGenie.Iot.Device.Discovery","name":"DiscoveryDevicesResponse","messageId":"1bd5d003-31b9-476f-ad03-71d471922820","payLoadVersion":1},"payload":{"devices":[{"deviceId":"34ea34cf2e63","deviceName":"light1","deviceType":"light","zone":"",          "brand":"","model":"",     "icon":"https://git.cn-hangzhou.oss-cdn.aliyun-inc.com/uploads/aicloud/aicloud-proxy-service/41baa00903a71c97e3533cf4e19a88bb/image.png","properties":[{"name":"color","value":"Red"}],"actions":["TurnOn","TurnOff","SetBrightness",       "AdjustBrightness",     "SetTemperature","Query"        ],"extensions":{"extension1":"","extension2":""}}]}
}

错误相应

{"header":{"namespace":"AliGenie.Iot.Device.XXXX","name":"ErrorResponse","messageId":"1bd5d003-31b9-476f-ad03-71d471922820","payLoadVersion":1},"payload":{"deviceId":"34234","errorCode":"DEVICE_NOT_SUPPORT_FUNCTION","message":"device not support"}}

所以总结上面的格式我们定义了个回复设备发现的类DiscoveryResponse.php

<?php
namespace AliGenie;class DiscoveryResponse {public $header;public $payload;public function __construct($isError = false) {$this->header = new DiscoveryHeader();if ($isError) {$this->header->putResponseName("Error");$this->payload = new DiscoveryErrPayload();} else {$this->payload = new DiscoveryPayload();}}
}class DiscoveryHeader {public $namespace = "AliGenie.Iot.Device.Discovery";public $name = "DiscoveryDevicesResponse";public $messageId = "";public $payLoadVersion = 1;public function putResponseName($name) {$this->name = $name."Response";}public function putResponseMessageId($messageId) {$this->messageId = $messageId;}
}class DiscoveryPayload {public $devices = array();public function putResponseDevices($device) {$this->devices[] = $device;}
}class DiscoveryErrPayload extends DiscoveryPayload{public $errorCode;public $message;public function putResponseError($errorCode, $message = "") {$this->errorCode = $errorCode;switch ($errorCode) {case "INVALIDATE_CONTROL_ORDER":if ($message == "") {$this->message = "invalidate control order";}break;case "SERVICE_ERROR":break;case "DEVICE_NOT_SUPPORT_FUNCTION":if ($message == "") {$this->message = "device not support";}break;case "INVALIDATE_PARAMS":if ($message == "") {$this->message = "invalidate params";}break;case "DEVICE_IS_NOT_EXIST":if ($message == "") {$this->message = "device is not exist";}break;case "IOT_DEVICE_OFFLINE":if ($message == "") {$this->message = "device is offline";}break;case "ACCESS_TOKEN_INVALIDATE":if ($message == "") {$this->message = "access_token is invalidate";}break;default:break;}}
}class DiscoveryDevice {public $deviceId;public $deviceName;public $deviceType;public $zone = "";public $brand = "";public $model = "";public $icon;public $properties = array();public $actions = array();public $extensions;public function putResponseDeviceInfo($deviceId, $deviceName, $deviceType, $icon) {$this->deviceId = $deviceId;$this->deviceName = $deviceName;$this->deviceType = $deviceType;$this->icon = $icon;}public function putResponseProperties($propertie) {$this->properties[] = $propertie;}public function putResponseExtensions($extension) {$this->extensions = $extension;}
}class DiscoveryPropertie {public $name;public $value;public function __construct($name, $value) {$this->name = $name;$this->value = $value;}
}class DiscoveryExtension {public $extension1 = "";public $extension2 = "";
}class DiscoveryExtensionEx extends DiscoveryExtension {public $parentId;public function __construct($parentId) {$this->parentId = $parentId;}
}function discovery_response_demo()
{$res = new DiscoveryResponse();$res->header->putResponseMessageId("1bd5d003-31b9-476f-ad03-71d471922820");$dev = new DiscoveryDevice();$dev->putResponseDeviceInfo("34ea34cf2e63", "单孔插座", "outlet", "https://git.cn-hangzhou.oss-cdn.aliyun-inc.com/uploads/aicloud/aicloud-proxy-service/41baa00903a71c97e3533cf4e19a88bb/image.png");$pro = new DiscoveryPropertie("powerstate", "off");$dev->putResponseProperties($pro);$ext = new DiscoveryExtension();$dev->putResponseExtensions($ext);$dev->actions = array("TurnOn", "TurnOff");$res->payload->putResponseDevices($dev);$dev = new DiscoveryDevice();$dev->putResponseDeviceInfo("34ea34cf2eff", "灯", "light", "https://git.cn-hangzhou.oss-cdn.aliyun-inc.com/uploads/aicloud/aicloud-proxy-service/41baa00903a71c97e3533cf4e19a88bb/image.png");$pro = new DiscoveryPropertie("powerstate", "off");$dev->putResponseProperties($pro);$ext = new DiscoveryExtensionEx("34ea34cf2e63");$dev->putResponseExtensions($ext);$dev->actions = array("TurnOn", "TurnOff");$res->payload->putResponseDevices($dev);$resJson = json_encode($res);echo "$resJson";
}?>

ControlResponse.php文件是设备控制使用的回复格式

设备控制主要是如下的格式例子

正确相应

{"header":{"namespace":"AliGenie.Iot.Device.Control","name":"TurnOnResponse","messageId":"1bd5d003-31b9-476f-ad03-71d471922820","payLoadVersion":1},"payload":{"deviceId":"34234"}}

错误相应同上。

所以总结上面的格式我们定义了个回复设备控制的类ControlResponse.php

<?php
namespace AliGenie;class ControlResponse {public $header;public $payload;public function __construct($isError = false) {$this->header = new ControlHeader();if ($isError) {$this->header->putResponseName("Error");$this->payload = new ControlErrPayload();} else {$this->payload = new ControlPayload();}}
}class ControlHeader {public $namespace = "AliGenie.Iot.Device.Control";public $name = "";public $messageId = "";public $payLoadVersion = 1;public function putResponseName($name) {$this->name = $name."Response";}public function putResponseMessageId($messageId) {$this->messageId = $messageId;}
}class ControlPayload {public $deviceId;public function putResponseDeviceId($deviceId) {$this->deviceId = $deviceId;}
}class ControlErrPayload extends ControlPayload{public $errorCode;public $message;public function putResponseError($errorCode, $message = "") {$this->errorCode = $errorCode;switch ($errorCode) {case "INVALIDATE_CONTROL_ORDER":if ($message == "") {$this->message = "invalidate control order";}break;case "SERVICE_ERROR":break;case "DEVICE_NOT_SUPPORT_FUNCTION":if ($message == "") {$this->message = "device not support";}break;case "INVALIDATE_PARAMS":if ($message == "") {$this->message = "invalidate params";}break;case "DEVICE_IS_NOT_EXIST":if ($message == "") {$this->message = "device is not exist";}break;case "IOT_DEVICE_OFFLINE":if ($message == "") {$this->message = "device is offline";}break;case "ACCESS_TOKEN_INVALIDATE":if ($message == "") {$this->message = "access_token is invalidate";}break;default:break;}}
}function control_response_demo()
{$res = new ControlResponse();$res->header->putResponseName("TurnOn");$res->header->putResponseMessageId("1bd5d003-31b9-476f-ad03-71d471922820");$res->payload->putResponseDeviceId("34234");$resJson = json_encode($res);echo "$resJson";$res = new ControlResponse(true);$res->header->putResponseMessageId("1bd5d003-31b9-476f-ad03-71d471922820");$res->payload->putResponseDeviceId("34234");$res->payload->putResponseError("DEVICE_NOT_SUPPORT_FUNCTION");$resJson = json_encode($res);echo "$resJson";
}?>

QueryResponse.php文件是设备状态查询使用的回复格式

设备状态查询主要是如下的格式例子

正确相应

{"properties":[{"name":"temperature","value":"27"} ],"header":{"namespace":"AliGenie.Iot.Device.Query","name":"QueryTemperatureResponse","messageId":"1bd5d003-31b9-476f-ad03-71d471922820","payLoadVersion":1},"payload":{"deviceId":"34234"}}

错误相应同上

所以总结上面的格式我们定义了个回复设备状态查询的类QueryResponse.php

<?php
namespace AliGenie;class QueryResponse {public $header;public $payload;public function __construct($isError = false) {$this->header = new QueryHeader();if ($isError) {$this->header->putResponseName("Error");$this->payload = new QueryErrPayload();} else {$this->payload = new QueryPayload();$this->properties = array();}}
}class QueryPropertie {public $name;public $value;public function __construct($name, $value) {$this->name = $name;$this->value = $value;}
}class QueryHeader {public $namespace = "AliGenie.Iot.Device.Query";public $name = "";public $messageId = "";public $payLoadVersion = 1;public function putResponseName($name) {$this->name = $name."Response";}public function putResponseMessageId($messageId) {$this->messageId = $messageId;}
}class QueryPayload {public $deviceId;public function putResponseDeviceId($deviceId) {$this->deviceId = $deviceId;}
}class QueryErrPayload extends QueryPayload{public $errorCode;public $message;public function putResponseError($errorCode, $message = "") {$this->errorCode = $errorCode;switch ($errorCode) {case "INVALIDATE_CONTROL_ORDER":if ($message == "") {$this->message = "invalidate control order";}break;case "SERVICE_ERROR":break;case "DEVICE_NOT_SUPPORT_FUNCTION":if ($message == "") {$this->message = "device not support";}break;case "INVALIDATE_PARAMS":if ($message == "") {$this->message = "invalidate params";}break;case "DEVICE_IS_NOT_EXIST":if ($message == "") {$this->message = "device is not exist";}break;case "IOT_DEVICE_OFFLINE":if ($message == "") {$this->message = "device is offline";}break;case "ACCESS_TOKEN_INVALIDATE":if ($message == "") {$this->message = "access_token is invalidate";}break;default:break;}}
}function query_response_demo()
{$res = new QueryResponse();$res->header->putResponseName("Query");$res->header->putResponseMessageId("1bd5d003-31b9-476f-ad03-71d471922820");$res->payload->putResponseDeviceId("34234");$pro = new QueryPropertie("powerstate", "on");$res->properties[] = $pro;$pro = new QueryPropertie("color", "Red");$res->properties[] = $pro;$pro = new QueryPropertie("temperature", "27");$res->properties[] = $pro;$pro = new QueryPropertie("humidity", "20");$res->properties[] = $pro;$pro = new QueryPropertie("windspeed", "2");$res->properties[] = $pro;$pro = new QueryPropertie("humidity", "23");$res->properties[] = $pro;$pro = new QueryPropertie("pm2.5", "20");$res->properties[] = $pro;$pro = new QueryPropertie("direction", "left");$res->properties[] = $pro;$pro = new QueryPropertie("angle", "60");$res->properties[] = $pro;$resJson = json_encode($res);echo "$resJson";$res = new QueryResponse(true);$res->header->putResponseMessageId("1bd5d003-31b9-476f-ad03-71d471922820");$res->payload->putResponseDeviceId("34234");$res->payload->putResponseError("DEVICE_NOT_SUPPORT_FUNCTION");$resJson = json_encode($res);echo "$resJson";
}?>

以上是三种类型的回复,其实这里实现的并不是很好,因为三种错误的回复格式都是一样的,可以把错误回复提炼成一个类,但是懒得做了,因为在做的过程中开始渐渐的对天猫精灵失去了信心,想把这里做完了就去实现小度的语音开发,后面我们在说天猫精灵的各种问题。

(8)香橙派+apache2与php+天猫精灵=自建平台语音支持--天猫精灵对接3相关推荐

  1. (6)香橙派+apache2与php+天猫精灵=自建平台语音支持--天猫精灵对接1

    导航链接 (1)香橙派+apache2与php+天猫精灵=自建平台语音支持--前言 (2)香橙派+apache2与php+天猫精灵=自建平台语音支持--香橙派操作系统安装 (3)香橙派+apache2 ...

  2. (11)香橙派+apache2与php+天猫精灵=自建平台语音支持--天猫精灵对接6

    导航链接 (1)香橙派+apache2与php+天猫精灵=自建平台语音支持--前言 (2)香橙派+apache2与php+天猫精灵=自建平台语音支持--香橙派操作系统安装 (3)香橙派+apache2 ...

  3. (13)香橙派+apache2与php+天猫精灵=自建平台语音支持--duerOS对接

    这篇主要总结一下小度音箱的对接方法,答题流程与天猫精灵一样,只是php稍有不同,我也会把php源码上传,需要的可以下载,流程与天猫精灵的php文件大体相同,只是其中的细节稍有差异. php文件链接:h ...

  4. 【阿里云生活物联网架构师专题 ②】esp8266 sdk 直连接入阿里云物联网平台,实现天猫精灵找队友零配网功能和语音控制;

    本系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 1.esp32接入阿里云物联网平台,实现天猫精灵语音控制: 2.es ...

  5. 【阿里云生活物联网架构师专题 ①】esp32 sdk 直连接入阿里云物联网平台,实现天猫精灵语音控制;

    本系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 1.esp32接入阿里云物联网平台,实现天猫精灵语音控制: 2.es ...

  6. Mysql orangepi_SSH远程登录香橙派Orange Pi Zero2开发板的操作方法

    香橙派Zero2开发板是新一代开源的单板电脑,采用全志H616 四核 64位处理器,拥有512MB/1GB 内存可选,集成千兆以太网卡.蓝牙5.0+双频WiFi.Micro-HDMI输出.USB2.0 ...

  7. 香橙派PC Plus电脑开发板制作网络打印服务器

    香橙派PC Plus是一款开源的单板电脑,新一代的arm开发板,使用全志Allwinner H3系统级芯片,拥有1GB DDR3 内存,板载8GB EMMC Flash 存储,可以运行Android4 ...

  8. 【工程师整活】Ai-WB1-A1S实现离线语音+APP+天猫精灵控制风扇

    文章目录 前言 一.控制主板 二.转接板原理图 三.接线与烧录 1.转接板接线 2.固件烧录 四.离线语音功能 五.App 控制功能 1.云平台产品创建 2.添加设备 3.五元组烧录 4.进入配网 4 ...

  9. 香橙派Zero2电视盒子开发板连接HDMI如何修改分辨率

    香橙派Zero2开发板采用全志H616 四核 64位处理器,拥有512MB/1GB 内存可选,集成千兆以太网卡.蓝牙5.0+双频WiFi(2.4GHz和5GHz).USB2.0.TF卡槽.板载2MB ...

最新文章

  1. 自然语言处理(NLP)前沿进展报告
  2. c语言联合体作用,C语言 联合体(Unions)
  3. 如何写一个清晰明了的Bug
  4. 支持delete吗_Spark Delta Lake 0.4.0 发布,支持 Python API 和部分 SQL
  5. JQuery:deferred对象的方法
  6. 用chrome模拟微信浏览器访问需要OAuth2.0网页授权的页面
  7. Java的四种引用方式
  8. 瑞幸咖啡业绩造假22亿:市场监管总局罚款1000万
  9. 你是怎么发现你的同事很有钱的?
  10. js 中meta 移除head_浅析JS中数据结构
  11. 服务器TIME_WAIT和CLOSE_WAIT分析和解决办法
  12. python import from区别,python中import与from方法总结
  13. 大写数字时钟屏保下载
  14. Win10任务栏无响应解决方法集锦
  15. os系统服务器防火墙怎么关闭,mac防火墙如何关闭
  16. 深度:戴尔中国十年之变
  17. 【Android】二进制图片和Bitmap的getPixel方法解析
  18. [引擎搭建记录] 时间性抗锯齿(TAA)
  19. python一键安装神器_一键安装python
  20. 人民币大写在线转换工具

热门文章

  1. op积分上反馈电阻 作用 理解 op 积分
  2. HTML5实现首页动态视频背景
  3. 6-1 判断顺序表是否有序(Java语言描述 ) (15 分)
  4. 微信开发者工具 当前系统代理不是安全代理,是否信任?问题之完美解决
  5. display:flex flex-grow
  6. Android开发——使用ActivityLifecycleCallbacks监控App是否处于后台
  7. 如何操作 Office Open XML 格式文档
  8. Python之warnings模块忽略warning警告错误
  9. GitHub开源了一款程序员摸鱼神器!上班摸鱼还不会被老板发现。。。
  10. 视觉SLAM小知识——叉乘的物理意义