『瀚思彼岸』» 智能家居技术论坛

 找回密码
 立即注册
查看: 1393|回复: 14

[经验分享] 万和热水器API方式探索(23-12-15更新)

[复制链接]

1

主题

5

帖子

65

积分

注册会员

Rank: 2

积分
65
金钱
60
HASS币
0
发表于 2023-12-13 16:48:34 | 显示全部楼层 |阅读模式
本帖最后由 linmohc 于 2023-12-15 16:08 编辑

以下API逆向得到,一边还要编写程序接入到ha,基本上是用到哪写到哪,还需要继续完善,精力有限可能有不准确的地方,但是大致可用,欢迎大家一起讨论。

1. HTTP请求登录

POST https://rubyuserapi.vanward.com/api/user/login application/x-www-form-urlencoded

code=&mobile=手机号&password=万和智能app密码明文

响应:
{"User":{"Uuid":"用户id需要保存后续用到","Token":"token需要保存后续用到","Mobile":"手机号","UnReadMsgCount":0},"Domain":["rubyusercomet.vanward.com"]}


2. 刷新TOKEN

第一步获得的token在连接ws后失效,下次再连接除了用第一步重新登录,还可以用这个接口获得新token

POST https://rubyuserapi.vanward.com/api/user/autoLogin application/x-www-form-urlencoded

uuid=用户id&token=旧token

响应与第一步相同

3. 连接websocket

用第一步中返回的Domain字段中随便一个域名,固定端口2301构成,如:wss://rubyusercomet.vanward.com:2301/ws

使用的是binaryframe

连接后需要马上发送认证消息

数据包由heaer+payload构成,其中header固定5字节,第一位为操作码,后4字段为大端int32,标识payload长度,如发送Hello,操作码为1,构数据包如下:

0x01, 0x05, 0x00, 0x00, 0x00, 0x48, 0x65, 0x6C, 0x6C, 0x6F

payload是一个json对象

已知操作码:

0x00: 登录,响应与请求相同,payload:  {"Id": "用户UUid", "Token": "xxxx"}
0x0A: 心跳,响应与请求相同
WebSocket协议

登录请求操作码: 0x00
{"Id": "用户UUid", "Token": "xxx"}

登录响应操作码: 0x00
{
    "Code": 0,
    "Devices": [
        {
            "ActiveDate": "设备激活日期?",
            "Alias": "设备别名(在app中设置)",
            "DeviceId": "设备id,需要记录保存",
            "Mac": "设备mac地址",
            "Master": "暂时不知道什么东西",
            "Product": {
                "CtrlPageUrl": "http://local/u2",
                "FirmwareId": "固件id,估计没什么用",
                "Icon": "https://smart-vanward.oss-cn-shenzhen.aliyuncs.com/vanwardsmart/1/JSLQ27-LS5W16/%E8%AE%BE%E5%A4%87%E5%9B%BE%E6%A0%871585561034123.png",
                "Model": "JSLQ27-LS5W16",     // 设备型号
                "Name": "JSLQ27-LS5W16",
                "Pid": "不清楚有什么用处",
                "Script": {
                    "Content": "s[1] === 1 ? '已打开':'已关闭';",
                    "Showonoff": true
                },
                "Series": "LS5  系列号,这个要保存,后面需要用来判断功能",
                "Type": "燃气热水器",     // 设备类型,如果有多种类型设备需要用这个值进行判断
                "catagoryId": 0,
                "catagoryName": "燃气热水器"
            },
            "Status": [0,1,4,0,15,0,45,24,0,0,0,0,24,9,7,9,0,0,0,38,0,0,0,0,23,0,7,16,12,24,0,0,0,0,0,0],    // 设备状态包括水温模式等,详见下面
            "Version": "1.4.3",   // 固件版本
            "deviceType": 0,     // 看起来像设备类型,但是官方并没有用这个值进行判断,反而用的是Product.Type
            "firmwareId": "frt92421-1e3f-479e-a98b-aa5692da1599",
            "isOnline": true,     // 设备离线(如断开WiFi)这里为false
            "serverId": "comet-CNS-01"
        }
    ],
    "Msg": "登录成功"
}

--------------------------------------------------------------------------------
心跳请求操作码:0x0A
心跳只需要发header的5字节包出去即可,即固定
0x0A 0x00, 0x00, 0x00, 0x00, 0x00
连接空闲时每60秒要发送一次心跳,否则服务端会断开连接

心跳响应
无,服务器不发送响应
--------------------------------------------------------------------------------

设备心跳请求
无,不需要客户端发送,服务端会主动推送过来

设备心跳响应操作码:0x23
{"Id":"设备id"}

--------------------------------------------------------------------------------

设备状态报告请求
无,不需要客户端发送,服务端会主动推送过来

设备状态报告响应操作码:0x22

{"Id":"设备id", "Status": [0,1,4,0,15,0,45,24,0,0,0,0,24,9,7,9,0,0,0,38,0,0,0,0,23,0,7,16,12,24,0,0,0,0,0,0]}

--------------------------------------------------------------------------------
更新设备状态请求,操作码:0x04
{
        "Status": [1, 4, 44, 0, 15, 0, 40, 0, 0, 0, 0, 0],    // 写设备状态,与读状态序列不同注意甄别
        "Id": "设备id",
        "MsgId": 1,                                                     // 消息id,实际官方并没有实现此值增长,保持为1即可
        "Timestamp": 1702620580,                           // 当前Unix时间戳
        "Model": "JSLQ27-LS5W16",                         // 设备型号,从登录请求中获得
        "Series": "LS5"                                               // 设备系列,从登录请求中获得
}

更新设备状态请求



--------------------------------------------------------------------------------

读设备状态(这个是服务器端返回的Status字段
(因为家里只有万和热水器,没有其他万和设备,所以下面的状态可能在其他类型设备上不通用,但是所有万和热水器都适用下面的状态
索引 说明
1
热水器通电状态:0待机/1正常通电
2
热水器模式,1普通/2厨房/4节能/5自适温/6自定义1/7自定义2/8自定义3/21温水浴
4
未知
5
未知
6
水温
8
加热状态,需要按位与运算判断,1加热中/2通水中/4散热风扇/8防冻功能
11
实时产水量,需要/10为L/min
18
零冷水巡航模式设置,高地址第3位为水增压,高地址第5-8位为巡航模式
19
零冷水温度
20
未知
21
未知
23
手动零冷水巡航,0未运行/1运行中
25
未知
33
零冷水预约模式,0非预约模式/1预约模式

其中索引8加热状态要按位运算得出,如第8位非0时说明防冻功能正在运行,其他的直接取值即可

零冷水巡航模式设置(读18)
二进制数位
说明
B7
固定为0
B6
固定为0
B5
1为水增压
B4
固定为0
B3巡航模式,0关闭/1全天候/2点动
    其中预约模式为0
B2
B1
B0

--------------------------------------------------------------------------------

写设备状态(发送到服务器端的Status字段)

索引 说明
0
热水器通电状态,用读设备状态(1)初始化
1
模式,用读设备状态(2)初始化
2
水温,用读设备状态(6)初始化
3
未知,用读设备状态(25)初始化
4
未知,用读设备状态(4)初始化
5
零冷水巡航设置,用读设备状态(18)初始化
6
零冷水温度,用读设备状态(19)初始化
7
未知,用读设备状态(20)初始化
8
未知,用读设备状态(21)初始化
9
触发一次零冷水巡航,用读设备状态(23)初始化,此项设1时会触发一次巡航且热水器完成时自动停止。除非实现自动化需要,否则填0
10
固定为0
11
零冷水预约模式,用读设备状态(33)初始化

补充:
Series为LS5时,最低温度为30,否则为35


基于以上信息基本上可以对热水器的完全控制,这两天看情况会用Go实现一个简单的接口以供大家调用或参考。

有遗漏或错误的地方也欢迎大家一起继续探讨






评分

参与人数 2金钱 +13 收起 理由
aourwz + 5 厉害了word楼主!
就要注册 + 8 厉害了word楼主!

查看全部评分

回复

使用道具 举报

1

主题

86

帖子

872

积分

高级会员

Rank: 4

积分
872
金钱
786
HASS币
0
发表于 2023-12-14 09:21:30 | 显示全部楼层
厉害,可否指导研究一下万家乐的呢
回复

使用道具 举报

1

主题

86

帖子

872

积分

高级会员

Rank: 4

积分
872
金钱
786
HASS币
0
发表于 2023-12-14 09:22:34 | 显示全部楼层
回复

使用道具 举报

1

主题

108

帖子

1412

积分

金牌会员

Rank: 6Rank: 6

积分
1412
金钱
1304
HASS币
0
发表于 2023-12-14 09:50:34 | 显示全部楼层
yxy2888 发表于 2023-12-14 09:22
https://bbs.hassbian.com/thread-21262-1-1.html

不是所有设备都支持快捷指令的,不支持快捷指令你的怎么用那个教程?你给个解决方案看下
回复

使用道具 举报

1

主题

86

帖子

872

积分

高级会员

Rank: 4

积分
872
金钱
786
HASS币
0
发表于 2023-12-14 13:05:13 | 显示全部楼层
yaojogd 发表于 2023-12-14 09:50
不是所有设备都支持快捷指令的,不支持快捷指令你的怎么用那个教程?你给个解决方案看下 ...

我的万家乐热水器,可以抓包,但不太懂
回复

使用道具 举报

1

主题

5

帖子

65

积分

注册会员

Rank: 2

积分
65
金钱
60
HASS币
0
 楼主| 发表于 2023-12-14 17:08:11 | 显示全部楼层
yxy2888 发表于 2023-12-14 09:21
厉害,可否指导研究一下万家乐的呢

不好意思我这边没有万家乐的设备估计难帮上忙,总体思路差不多都是抓包再逆向得到的
回复

使用道具 举报

1

主题

5

帖子

65

积分

注册会员

Rank: 2

积分
65
金钱
60
HASS币
0
 楼主| 发表于 2023-12-14 17:10:32 | 显示全部楼层
刚才编辑的内容保存后就不见了,稍后重新编辑一下
回复

使用道具 举报

1

主题

23

帖子

379

积分

中级会员

Rank: 3Rank: 3

积分
379
金钱
356
HASS币
0
发表于 2023-12-14 17:21:41 | 显示全部楼层
[0,0,1,0,15,0,60,33,0,0,0,0,15,71,25,71,0,0,33,43,0,0,0,0,30,0,25,16,12,24,0,0,0,0,0,0]
这种结构的状态你能对应上吗?我看每次发送控制指令都会把所有的状态发到服务器
回复

使用道具 举报

1

主题

23

帖子

379

积分

中级会员

Rank: 3Rank: 3

积分
379
金钱
356
HASS币
0
发表于 2023-12-14 17:26:07 | 显示全部楼层
本帖最后由 aourwz 于 2023-12-14 17:29 编辑
aourwz 发表于 2023-12-14 17:21
[0,0,1,0,15,0,60,33,0,0,0,0,15,71,25,71,0,0,33,43,0,0,0,0,30,0,25,16,12,24,0,0,0,0,0,0]
这种结构的状 ...

看错了,这是服务器发回来的,帖子已经更新了,刚刚没看到,感谢大佬
回复

使用道具 举报

1

主题

5

帖子

65

积分

注册会员

Rank: 2

积分
65
金钱
60
HASS币
0
 楼主| 发表于 2023-12-14 17:27:27 | 显示全部楼层
aourwz 发表于 2023-12-14 17:21
[0,0,1,0,15,0,60,33,0,0,0,0,15,71,25,71,0,0,33,43,0,0,0,0,30,0,25,16,12,24,0,0,0,0,0,0]
这种结构的状 ...

并不是发送所有回去的,而且索引位置也有不同,后面再补充上来
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian

GMT+8, 2024-5-9 04:47 , Processed in 0.277470 second(s), 32 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表