温度单位切换(°C ↔ °F)方案设计

内容包含:

✔ 切换单位的正确流程(指令 + UI + 控制器)
✔ 关键命令表
✔ 转换逻辑
✔ 控制器应该怎么写
✔ UI 切换按钮应该怎么写
✔ 你应该把逻辑放在哪一层(最终建议)
✔ 避免协议误用/温度范围不一致问题


🧩 一、理解协议关键点(核心是 0x24 返回 0x24 / 0xA4)

协议让我们知道:

协议含义
0x24返回摄氏温度设定(°C)
0xA4返回华氏温度设定(°F)
0x22设置摄氏温度范围:25–65°C
0x23设置华氏温度范围:77–149°F

所以:

⭐设备温度单位不是 UI 决定

⭐设备温度单位由设备自己决定(通过 0x24 返回的 ID 判断)


🔍 如何判断设备当前使用 °C 还是 °F?

收到回包:

AB 24 30 34 30 XX → 摄氏(0x24)
AB A4 30 34 30 XX → 华氏(0xA4)

即:

bool isCelsius = (packet.id == 0x24);
bool isFahrenheit = (packet.id == 0xA4);

🧭 二、最终专业设计:Should unit switching be done in UI or controller?

📌 正确答案:

✅ “温度单位切换”必须由 设备协议层决定

❌ 不应该仅由 UI 自己换算(非常不安全)

因为:

  • 温度范围不同(25–65 vs 77–149)

  • 温度设定命令不同(0x22 vs 0x23)

  • 设备内部控制逻辑基于真实单位(安全逻辑依赖单位)

  • 控制加热是危险操作,必须依赖设备真实单位

⚠ 如果仅在 UI 做换算,会出现非常严重错误:

  • UI 认为是 149°F(= 65°C 以上)

  • 设备内部依然当摄氏使用 -> 过温风险

  • 或相反导致无法加热到目标值

因此:

所有单位切换、实际设定、读取必须遵守设备协议。
UI 只做展示,不做真实业务逻辑。


⭐ 三、完整流程:切换 °C → °F 或 °F → °C

假设用户点击 UI 切换按钮:


✔ 1)第一步 → 发送 0x24 查询当前单位

AA 24 00 00 00 CE

BLE 返回:

情况 A:0x24(摄氏)

→ 当前是摄氏,需要切换到华氏
→ 你要做 单位转换 & 发送 0x23

情况 B:0xA4(华氏)

→ 当前是华氏,需要切换到摄氏
→ 你要做 单位转换 & 发送 0x22


✔ 2)第二步 → 把当前温度转换单位

摄氏 → 华氏:

F = C × 1.8 + 32

华氏 → 摄氏:

C = (F – 32) / 1.8

✔ 3)第三步 → 裁剪到合法范围(非常重要)

如果切换到 °C:

C 必须限制在 25–65

如果切换到 °F:

F 必须限制在 77–149

否则设备不接受。


✔ 4)第四步 → 发送设定(0x22 / 0x23)

如果切到摄氏:

AA 22 + ascii(C/10) + ascii(C%10) + "0" + checksum

如果切到华氏:

AA 23 + ascii(F/100) + ascii((F/10)%10) + ascii(F%10) + checksum

⭐ 四、完整控制器实现(DeviceManagerController)

给你最专业实现伪代码:

Future<void> switchUnit(bool toCelsius) async {
  // 1) 查询当前温度单位
  final cur = await queryCurrentTempUnit();  // packet.id == 0x24 or 0xA4

  final isC = (cur == 0x24);
  final isF = (cur == 0xA4);

  // 如果已是目标单位,不做任何处理
  if ((toCelsius && isC) || (!toCelsius && isF)) return;

  // 获取当前温度设定
  final curTemp = currentSettingTemp; // app 中保存的值

  double newTemp;

  if (toCelsius) {
    // 华氏 → 摄氏
    newTemp = (curTemp - 32) / 1.8;
    newTemp = newTemp.clamp(25, 65);
    await sendSetCelsius(newTemp.toInt()); // 0x22
    isCelsius.value = true;
  } else {
    // 摄氏 → 华氏
    newTemp = curTemp * 1.8 + 32;
    newTemp = newTemp.clamp(77, 149);
    await sendSetFahrenheit(newTemp.toInt()); // 0x23
    isCelsius.value = false;
  }

  targetTemp.value = newTemp;
}

非常清晰。


⭐ 五、UI 的逻辑应该做什么?

UI 层只做:

① 显示 °C 或 °F

② 处理点击 → 调 controller.switchUnit

③ 显示切换动画

UI 不做温度换算,不做协议,不做数据处理。


⭐ 六、把上面流程总结为最终“命令清单”

📌 查询当前设定单位

AA 24 00 00 00 CE
返回:
AB 24 ... 表示摄氏
AB A4 ... 表示华氏

📌 设定摄氏温度(25–65°C)

AA 22 3X 3Y 30 checksum

📌 设定华氏温度(77–149°F)

AA 23 3X 3Y 3Z checksum

📌 读取当前实际温度(含加热状态、单位)

AA 02 00 00 00 AC

回包数据:

0x02 / 0x82 → 摄氏(加热/停止)
0x72 / 0xF2 → 华氏(加热/停止)

🎯 最终答案

温度单位必须由设备协议层决定,不由前端自行处理。
你应该在 controller 中做单位切换逻辑(按协议 0x24、0x22、0x23),UI 只显示结果。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值