删除条件配置功能,修改成联动配置DP,并且增加31天运行记录,修改程序需求

This commit is contained in:
2026-09-03 10:21:11 +08:00
parent 5377186cfb
commit d56d8204e1
31 changed files with 1609 additions and 1430 deletions
+48 -59
View File
@@ -1,6 +1,6 @@
/* ================================================================
* jb_product.c — 用户层实现(薄适配:只写 DP,不写业务算法)
* 设备: 温湿度风扇 | 生成时间: 2026-08-29cond_config 已按 Excel 重生 7 字节
* 设备: 温湿度风扇 | 生成: 2026-09-02V3.0.0:删条件 DP,加联动/运行记录
*
* ══ 开发流程 ══
* 1. 实现硬件抽象: jbGetTimerCount(定时器由 SOC SDK 提供)
@@ -8,14 +8,17 @@
* 2. userInit() 设置 DP 默认值
* 3. userHandle() 填温湿度 DP500ms
* 4. jbEventProcess() APP 下行:只写 gDevData 并转调 app_*,不在这里写业务
* ================================================================
*/
*
* ⚠ 规格书第 0 章第 2 条:**业务算法一律不进本文件**。
* 联动开停 → app_linkage31 天秒数 → app_runrec;定时窗 → app_timer_task。
* ================================================================ */
#include "jb_product.h"
#include "app_th.h"
#include "app_fan.h"
#include "app_mode.h"
#include "app_cond.h"
#include "app_linkage.h"
#include "app_runrec.h"
#include "app_timer_task.h"
#include "app_arbiter.h"
#include "app_nvm.h"
@@ -45,14 +48,8 @@ void userInit(void)
gDevData.fan_gear = 0; /* FAN_GEAR_0 (关闭风扇) */
gDevData.current_temp = 0.0f; /* DP3 当前温度 (float) */
gDevData.current_humi = 0; /* DP4 当前湿度 */
gDevData.cond_en = 0; /* DP5 条件使能 0=关 1=开 */
memset(gDevData.cond_config1, 0, 7); /* DP6 条件配置17 字节 */
memset(gDevData.cond_config2, 0, 7); /* DP7 条件配置2 */
memset(gDevData.cond_config3, 0, 7); /* DP8 条件配置3 */
memset(gDevData.cond_config4, 0, 7); /* DP9 条件配置4 */
memset(gDevData.cond_config5, 0, 7); /* DP10 条件配置5 */
memset(gDevData.cond_config6, 0, 7); /* DP11 条件配置6 */
memset(gDevData.cond_config7, 0, 7); /* DP12 条件配置7 */
gDevData.linkage_delete = 0; /* DP5 联动删除(脉冲,写 1 触发后清回 0) */
memset(gDevData.linkage_config, 0, 20); /* DP6 联动配置(20B10.2 布局 */
gDevData.time_en = 0; /* DP13 定时使能 0=关 1=开 */
memset(gDevData.time_config1, 0, 8); /* DP14 定时配置1 */
memset(gDevData.time_config2, 0, 8); /* DP15 定时配置2 */
@@ -61,19 +58,22 @@ void userInit(void)
memset(gDevData.time_config5, 0, 8); /* DP18 定时配置5 */
memset(gDevData.time_config6, 0, 8); /* DP19 定时配置6 */
memset(gDevData.time_config7, 0, 8); /* DP20 定时配置7 */
gDevData.fault_en = 0; /* DP21 设备故障使能 */
gDevData.fault_code = 0; /* DP22 设备故障 */
gDevData.alarm_en = 0; /* DP23 设备告警使能 */
gDevData.alarm_code = 0; /* DP24 设备告警(保持 0 */
gDevData.factory_reset = 0; /* DP25 恢复出厂设置 0=关 1=开 */
gDevData.reserva_dp1 = 0; /* DP26 预留DP1 */
gDevData.reserva_dp2 = 0; /* DP27 预留DP2 */
gDevData.reserva_dp3 = 0; /* DP28 预留DP3 */
memset(gDevData.run_record, 0, 124); /* DP21 运行记录(RO,由 app_runrec 填) */
gDevData.heartbeat = 0; /* DP22 心跳(本版忽略) */
gDevData.fault_en = 0; /* DP23 设备故障使能 */
gDevData.fault_code = 0; /* DP24 设备故障 */
gDevData.alarm_en = 0; /* DP25 设备告警使能 */
gDevData.alarm_code = 0; /* DP26 设备告警(保持 0 */
gDevData.factory_reset = 0; /* DP27 恢复出厂设置(WO,写 1 触发) */
gDevData.reserva_dp1 = 0; /* DP28 预留DP1 */
gDevData.reserva_dp2 = 0; /* DP29 预留DP2 */
gDevData.reserva_dp3 = 0; /* DP30 预留DP3 */
}
/* ════════════════════════════════════════════════════════════════
* userHandle — 用户数据采集(500ms 由 usr_timer_loop 调用)
* 只填温湿度上报 DP;档位/模式/fault 由 app_function_poll20ms)同步
* 只填温湿度上报 DP;档位/模式/fault 由 app_function_poll20ms)同步
* DP21 运行记录由 app_runrec 在任务上下文灌
* ════════════════════════════════════════════════════════════════ */
void userHandle(void)
{
@@ -105,55 +105,34 @@ int8_t jbEventProcess(jb_event_info_t *info, jb_data_point_t *ctrl)
case DP_ID_POWER:
break;
/* ── DP1 模式:写则手动抢权(仲裁器释放自动化占用)── */
/* ── DP1 模式:写则手动抢权(仲裁器释放自动化占用 + 联动作废)── */
case DP_ID_MODE:
gDevData.mode = ctrl->mode;
app_arbiter_manual_intervene(); /* 手动动作:条件/定时让位 */
app_arbiter_manual_intervene(); /* 手动动作:联动/定时让位 */
app_mode_set_manual(ctrl->mode);
break;
/* ── DP2 风速挡位:写则手动抢权,退模式 ── */
case DP_ID_FAN_GEAR:
gDevData.fan_gear = ctrl->fan_gear;
app_arbiter_manual_intervene(); /* 手动动作:条件/定时让位 */
app_arbiter_manual_intervene(); /* 手动动作:联动/定时让位 */
app_mode_set_manual(0);
app_fan_set_gear(ctrl->fan_gear);
break;
/* ── DP5 条件使能 ── */
case DP_ID_COND_EN:
gDevData.cond_en = ctrl->cond_en ? 1 : 0;
app_cond_set_en(gDevData.cond_en);
/* ── DP5 联动删除:脉冲(10.4)。写 1 → 清配置并让出风扇,
* 然后把 linkage_delete 清回 0 再上报;写 0 = 无操作 ── */
case DP_ID_LINKAGE_DELETE:
if (ctrl->linkage_delete) {
app_linkage_delete();
gDevData.linkage_delete = 0; /* 脉冲:清回 0 供上报 */
}
break;
/* ── DP6~12 条件配置(7 字节 memcpy + 条件状态机复位该组计时)── */
case DP_ID_COND_CONFIG1:
memcpy(gDevData.cond_config1, ctrl->cond_config1, 7);
app_cond_set_config(1);
break;
case DP_ID_COND_CONFIG2:
memcpy(gDevData.cond_config2, ctrl->cond_config2, 7);
app_cond_set_config(2);
break;
case DP_ID_COND_CONFIG3:
memcpy(gDevData.cond_config3, ctrl->cond_config3, 7);
app_cond_set_config(3);
break;
case DP_ID_COND_CONFIG4:
memcpy(gDevData.cond_config4, ctrl->cond_config4, 7);
app_cond_set_config(4);
break;
case DP_ID_COND_CONFIG5:
memcpy(gDevData.cond_config5, ctrl->cond_config5, 7);
app_cond_set_config(5);
break;
case DP_ID_COND_CONFIG6:
memcpy(gDevData.cond_config6, ctrl->cond_config6, 7);
app_cond_set_config(6);
break;
case DP_ID_COND_CONFIG7:
memcpy(gDevData.cond_config7, ctrl->cond_config7, 7);
app_cond_set_config(7);
/* ── DP6 联动配置:20B memcpy + 存 VM + 清手动作废 + 立刻重判(10.5)── */
case DP_ID_LINKAGE_CONFIG:
memcpy(gDevData.linkage_config, ctrl->linkage_config, 20);
app_linkage_set_config();
break;
/* ── DP13 定时使能 ── */
@@ -192,7 +171,16 @@ int8_t jbEventProcess(jb_event_info_t *info, jb_data_point_t *ctrl)
app_timer_set_config(7);
break;
/* ── DP21/23 使能:原样存,P0 不做位级过滤 ── */
/* ── DP21 运行记录:RO,禁止 APP 写(规格书第 15 章)── */
case DP_ID_RUN_RECORD:
break;
/* ── DP22 心跳:本版忽略(规格书 0 章第 11 条 / 15 章)。
* 写了也不停温湿度上报,不做 12s 停报 ── */
case DP_ID_HEARTBEAT:
break;
/* ── DP23/25 使能:原样存,P0 不做位级过滤 ── */
case DP_ID_FAULT_EN:
gDevData.fault_en = ctrl->fault_en;
break;
@@ -200,7 +188,8 @@ int8_t jbEventProcess(jb_event_info_t *info, jb_data_point_t *ctrl)
gDevData.alarm_en = ctrl->alarm_en;
break;
/* ── DP25 恢复出厂设置:清业务 VM(留配对)+ RAM 复位,不断开不软复位(14 章)── */
/* ── DP27 恢复出厂设置(原 DP25:清业务 VM(留配对)+ RAM 复位,
* 不断开不软复位(规格书第 14 章)── */
case DP_ID_FACTORY_RESET:
gDevData.factory_reset = ctrl->factory_reset ? 1 : 0;
if (gDevData.factory_reset) {
@@ -208,7 +197,7 @@ int8_t jbEventProcess(jb_event_info_t *info, jb_data_point_t *ctrl)
}
break;
/* ── DP26~28 预留:存 RAM,可不实现动作 ── */
/* ── DP28~30 预留:存 RAM,可不实现动作 ── */
case DP_ID_RESERVA_DP1:
gDevData.reserva_dp1 = ctrl->reserva_dp1;
break;
+1 -1
View File
@@ -20,7 +20,7 @@
* 版本管理
* ════════════════════════════════════════════════════════════════ */
/* MCU software version: Vmajor.minor.patch */
#define JB_MCU_SW_VERSION_MAJOR 1
#define JB_MCU_SW_VERSION_MAJOR 2
#define JB_MCU_SW_VERSION_MINOR 0
#define JB_MCU_SW_VERSION_PATCH 0
+67 -202
View File
@@ -1,6 +1,6 @@
/* ================================================================
* jb_protocol.c — 见宝 IOT 协议实现(自动生成)
* 设备: 温湿度风扇 | 生成时间: 2026-08-29 10:31:50
* 设备: 温湿度风扇 | 生成时间: 2026-09-02 16:01:44
* ================================================================
*/
@@ -188,60 +188,18 @@ static uint16_t jbPackDps(const jb_data_point_t *dp,
bitmap[DP_ID_CURRENT_HUMI / 8] |= (1 << (DP_ID_CURRENT_HUMI % 8));
out[valIdx++] = (uint8_t)dp->current_humi;
}
/* DP5 条件使能 (bool, 1B, RW) */
if (mask[DP_ID_COND_EN / 8] & (1 << (DP_ID_COND_EN % 8)))
/* DP5 联动删除 (bool, 1B, RW) */
if (mask[DP_ID_LINKAGE_DELETE / 8] & (1 << (DP_ID_LINKAGE_DELETE % 8)))
{
bitmap[DP_ID_COND_EN / 8] |= (1 << (DP_ID_COND_EN % 8));
out[valIdx++] = dp->cond_en ? 1 : 0;
bitmap[DP_ID_LINKAGE_DELETE / 8] |= (1 << (DP_ID_LINKAGE_DELETE % 8));
out[valIdx++] = dp->linkage_delete ? 1 : 0;
}
/* DP6 条件配置1 (raw, 7B, RW) */
if (mask[DP_ID_COND_CONFIG1 / 8] & (1 << (DP_ID_COND_CONFIG1 % 8)))
/* DP6 联动配置 (raw, 20B, RW) */
if (mask[DP_ID_LINKAGE_CONFIG / 8] & (1 << (DP_ID_LINKAGE_CONFIG % 8)))
{
bitmap[DP_ID_COND_CONFIG1 / 8] |= (1 << (DP_ID_COND_CONFIG1 % 8));
memcpy(&out[valIdx], dp->cond_config1, 7);
valIdx += 7;
}
/* DP7 条件配置2 (raw, 7B, RW) */
if (mask[DP_ID_COND_CONFIG2 / 8] & (1 << (DP_ID_COND_CONFIG2 % 8)))
{
bitmap[DP_ID_COND_CONFIG2 / 8] |= (1 << (DP_ID_COND_CONFIG2 % 8));
memcpy(&out[valIdx], dp->cond_config2, 7);
valIdx += 7;
}
/* DP8 条件配置3 (raw, 7B, RW) */
if (mask[DP_ID_COND_CONFIG3 / 8] & (1 << (DP_ID_COND_CONFIG3 % 8)))
{
bitmap[DP_ID_COND_CONFIG3 / 8] |= (1 << (DP_ID_COND_CONFIG3 % 8));
memcpy(&out[valIdx], dp->cond_config3, 7);
valIdx += 7;
}
/* DP9 条件配置4 (raw, 7B, RW) */
if (mask[DP_ID_COND_CONFIG4 / 8] & (1 << (DP_ID_COND_CONFIG4 % 8)))
{
bitmap[DP_ID_COND_CONFIG4 / 8] |= (1 << (DP_ID_COND_CONFIG4 % 8));
memcpy(&out[valIdx], dp->cond_config4, 7);
valIdx += 7;
}
/* DP10 条件配置5 (raw, 7B, RW) */
if (mask[DP_ID_COND_CONFIG5 / 8] & (1 << (DP_ID_COND_CONFIG5 % 8)))
{
bitmap[DP_ID_COND_CONFIG5 / 8] |= (1 << (DP_ID_COND_CONFIG5 % 8));
memcpy(&out[valIdx], dp->cond_config5, 7);
valIdx += 7;
}
/* DP11 条件配置6 (raw, 7B, RW) */
if (mask[DP_ID_COND_CONFIG6 / 8] & (1 << (DP_ID_COND_CONFIG6 % 8)))
{
bitmap[DP_ID_COND_CONFIG6 / 8] |= (1 << (DP_ID_COND_CONFIG6 % 8));
memcpy(&out[valIdx], dp->cond_config6, 7);
valIdx += 7;
}
/* DP12 条件配置7 (raw, 7B, RW) */
if (mask[DP_ID_COND_CONFIG7 / 8] & (1 << (DP_ID_COND_CONFIG7 % 8)))
{
bitmap[DP_ID_COND_CONFIG7 / 8] |= (1 << (DP_ID_COND_CONFIG7 % 8));
memcpy(&out[valIdx], dp->cond_config7, 7);
valIdx += 7;
bitmap[DP_ID_LINKAGE_CONFIG / 8] |= (1 << (DP_ID_LINKAGE_CONFIG % 8));
memcpy(&out[valIdx], dp->linkage_config, 20);
valIdx += 20;
}
/* DP13 定时使能 (bool, 1B, RW) */
if (mask[DP_ID_TIME_EN / 8] & (1 << (DP_ID_TIME_EN % 8)))
@@ -298,45 +256,52 @@ static uint16_t jbPackDps(const jb_data_point_t *dp,
memcpy(&out[valIdx], dp->time_config7, 8);
valIdx += 8;
}
/* DP21 设备故障使能 (uint8, 1B, RW) */
/* DP21 运行记录 (raw, 124B, RO) */
if (mask[DP_ID_RUN_RECORD / 8] & (1 << (DP_ID_RUN_RECORD % 8)))
{
bitmap[DP_ID_RUN_RECORD / 8] |= (1 << (DP_ID_RUN_RECORD % 8));
memcpy(&out[valIdx], dp->run_record, 124);
valIdx += 124;
}
/* DP23 设备故障使能 (uint8, 1B, RW) */
if (mask[DP_ID_FAULT_EN / 8] & (1 << (DP_ID_FAULT_EN % 8)))
{
bitmap[DP_ID_FAULT_EN / 8] |= (1 << (DP_ID_FAULT_EN % 8));
out[valIdx++] = (uint8_t)dp->fault_en;
}
/* DP22 设备故障 (uint8, 1B, RO) */
/* DP24 设备故障 (uint8, 1B, RO) */
if (mask[DP_ID_FAULT_CODE / 8] & (1 << (DP_ID_FAULT_CODE % 8)))
{
bitmap[DP_ID_FAULT_CODE / 8] |= (1 << (DP_ID_FAULT_CODE % 8));
out[valIdx++] = (uint8_t)dp->fault_code;
}
/* DP23 设备告警使能 (uint8, 1B, RW) */
/* DP25 设备告警使能 (uint8, 1B, RW) */
if (mask[DP_ID_ALARM_EN / 8] & (1 << (DP_ID_ALARM_EN % 8)))
{
bitmap[DP_ID_ALARM_EN / 8] |= (1 << (DP_ID_ALARM_EN % 8));
out[valIdx++] = (uint8_t)dp->alarm_en;
}
/* DP24 设备告警 (uint8, 1B, RO) */
/* DP26 设备告警 (uint8, 1B, RO) */
if (mask[DP_ID_ALARM_CODE / 8] & (1 << (DP_ID_ALARM_CODE % 8)))
{
bitmap[DP_ID_ALARM_CODE / 8] |= (1 << (DP_ID_ALARM_CODE % 8));
out[valIdx++] = (uint8_t)dp->alarm_code;
}
/* DP26 预留DP1 (uint32, 4B, RW) */
/* DP28 预留DP1 (uint32, 4B, RW) */
if (mask[DP_ID_RESERVA_DP1 / 8] & (1 << (DP_ID_RESERVA_DP1 % 8)))
{
bitmap[DP_ID_RESERVA_DP1 / 8] |= (1 << (DP_ID_RESERVA_DP1 % 8));
jbWriteU32BE(&out[valIdx], (uint32_t)dp->reserva_dp1);
valIdx += 4;
}
/* DP27 预留DP2 (uint32, 4B, RW) */
/* DP29 预留DP2 (uint32, 4B, RW) */
if (mask[DP_ID_RESERVA_DP2 / 8] & (1 << (DP_ID_RESERVA_DP2 % 8)))
{
bitmap[DP_ID_RESERVA_DP2 / 8] |= (1 << (DP_ID_RESERVA_DP2 % 8));
jbWriteU32BE(&out[valIdx], (uint32_t)dp->reserva_dp2);
valIdx += 4;
}
/* DP28 预留DP3 (uint32, 4B, RW) */
/* DP30 预留DP3 (uint32, 4B, RW) */
if (mask[DP_ID_RESERVA_DP3 / 8] & (1 << (DP_ID_RESERVA_DP3 % 8)))
{
bitmap[DP_ID_RESERVA_DP3 / 8] |= (1 << (DP_ID_RESERVA_DP3 % 8));
@@ -397,107 +362,29 @@ static void jbUnpackDps(const uint8_t *bitmap, const uint8_t *values,
info->dp_ids[info->count++] = DP_ID_FAN_GEAR;
}
}
/* DP5 条件使能 (bool, 1B, RW) */
if (bitmap[DP_ID_COND_EN / 8] & (1 << (DP_ID_COND_EN % 8)))
/* DP5 联动删除 (bool, 1B, RW) */
if (bitmap[DP_ID_LINKAGE_DELETE / 8] & (1 << (DP_ID_LINKAGE_DELETE % 8)))
{
if (valIdx < valLen)
{
dp->cond_en = (values[valIdx++] != 0);
dp->linkage_delete = (values[valIdx++] != 0);
}
if (info && info->count < DP_ID_MAX)
{
info->dp_ids[info->count++] = DP_ID_COND_EN;
info->dp_ids[info->count++] = DP_ID_LINKAGE_DELETE;
}
}
/* DP6 条件配置1 (raw, 7B, RW) */
if (bitmap[DP_ID_COND_CONFIG1 / 8] & (1 << (DP_ID_COND_CONFIG1 % 8)))
/* DP6 联动配置 (raw, 20B, RW) */
if (bitmap[DP_ID_LINKAGE_CONFIG / 8] & (1 << (DP_ID_LINKAGE_CONFIG % 8)))
{
if (valIdx + 7 <= valLen)
if (valIdx + 20 <= valLen)
{
memcpy(dp->cond_config1, &values[valIdx], 7);
valIdx += 7;
memcpy(dp->linkage_config, &values[valIdx], 20);
valIdx += 20;
}
if (info && info->count < DP_ID_MAX)
{
info->dp_ids[info->count++] = DP_ID_COND_CONFIG1;
}
}
/* DP7 条件配置2 (raw, 7B, RW) */
if (bitmap[DP_ID_COND_CONFIG2 / 8] & (1 << (DP_ID_COND_CONFIG2 % 8)))
{
if (valIdx + 7 <= valLen)
{
memcpy(dp->cond_config2, &values[valIdx], 7);
valIdx += 7;
}
if (info && info->count < DP_ID_MAX)
{
info->dp_ids[info->count++] = DP_ID_COND_CONFIG2;
}
}
/* DP8 条件配置3 (raw, 7B, RW) */
if (bitmap[DP_ID_COND_CONFIG3 / 8] & (1 << (DP_ID_COND_CONFIG3 % 8)))
{
if (valIdx + 7 <= valLen)
{
memcpy(dp->cond_config3, &values[valIdx], 7);
valIdx += 7;
}
if (info && info->count < DP_ID_MAX)
{
info->dp_ids[info->count++] = DP_ID_COND_CONFIG3;
}
}
/* DP9 条件配置4 (raw, 7B, RW) */
if (bitmap[DP_ID_COND_CONFIG4 / 8] & (1 << (DP_ID_COND_CONFIG4 % 8)))
{
if (valIdx + 7 <= valLen)
{
memcpy(dp->cond_config4, &values[valIdx], 7);
valIdx += 7;
}
if (info && info->count < DP_ID_MAX)
{
info->dp_ids[info->count++] = DP_ID_COND_CONFIG4;
}
}
/* DP10 条件配置5 (raw, 7B, RW) */
if (bitmap[DP_ID_COND_CONFIG5 / 8] & (1 << (DP_ID_COND_CONFIG5 % 8)))
{
if (valIdx + 7 <= valLen)
{
memcpy(dp->cond_config5, &values[valIdx], 7);
valIdx += 7;
}
if (info && info->count < DP_ID_MAX)
{
info->dp_ids[info->count++] = DP_ID_COND_CONFIG5;
}
}
/* DP11 条件配置6 (raw, 7B, RW) */
if (bitmap[DP_ID_COND_CONFIG6 / 8] & (1 << (DP_ID_COND_CONFIG6 % 8)))
{
if (valIdx + 7 <= valLen)
{
memcpy(dp->cond_config6, &values[valIdx], 7);
valIdx += 7;
}
if (info && info->count < DP_ID_MAX)
{
info->dp_ids[info->count++] = DP_ID_COND_CONFIG6;
}
}
/* DP12 条件配置7 (raw, 7B, RW) */
if (bitmap[DP_ID_COND_CONFIG7 / 8] & (1 << (DP_ID_COND_CONFIG7 % 8)))
{
if (valIdx + 7 <= valLen)
{
memcpy(dp->cond_config7, &values[valIdx], 7);
valIdx += 7;
}
if (info && info->count < DP_ID_MAX)
{
info->dp_ids[info->count++] = DP_ID_COND_CONFIG7;
info->dp_ids[info->count++] = DP_ID_LINKAGE_CONFIG;
}
}
/* DP13 定时使能 (bool, 1B, RW) */
@@ -603,7 +490,19 @@ static void jbUnpackDps(const uint8_t *bitmap, const uint8_t *values,
info->dp_ids[info->count++] = DP_ID_TIME_CONFIG7;
}
}
/* DP21 设备故障使能 (uint8, 1B, RW) */
/* DP22 心跳 (bool, 1B, WO) */
if (bitmap[DP_ID_HEARTBEAT / 8] & (1 << (DP_ID_HEARTBEAT % 8)))
{
if (valIdx < valLen)
{
dp->heartbeat = (values[valIdx++] != 0);
}
if (info && info->count < DP_ID_MAX)
{
info->dp_ids[info->count++] = DP_ID_HEARTBEAT;
}
}
/* DP23 设备故障使能 (uint8, 1B, RW) */
if (bitmap[DP_ID_FAULT_EN / 8] & (1 << (DP_ID_FAULT_EN % 8)))
{
if (valIdx < valLen)
@@ -615,7 +514,7 @@ static void jbUnpackDps(const uint8_t *bitmap, const uint8_t *values,
info->dp_ids[info->count++] = DP_ID_FAULT_EN;
}
}
/* DP23 设备告警使能 (uint8, 1B, RW) */
/* DP25 设备告警使能 (uint8, 1B, RW) */
if (bitmap[DP_ID_ALARM_EN / 8] & (1 << (DP_ID_ALARM_EN % 8)))
{
if (valIdx < valLen)
@@ -627,7 +526,7 @@ static void jbUnpackDps(const uint8_t *bitmap, const uint8_t *values,
info->dp_ids[info->count++] = DP_ID_ALARM_EN;
}
}
/* DP25 恢复出厂设置 (bool, 1B, WO) */
/* DP27 恢复出厂设置 (bool, 1B, WO) */
if (bitmap[DP_ID_FACTORY_RESET / 8] & (1 << (DP_ID_FACTORY_RESET % 8)))
{
if (valIdx < valLen)
@@ -639,7 +538,7 @@ static void jbUnpackDps(const uint8_t *bitmap, const uint8_t *values,
info->dp_ids[info->count++] = DP_ID_FACTORY_RESET;
}
}
/* DP26 预留DP1 (uint32, 4B, RW) */
/* DP28 预留DP1 (uint32, 4B, RW) */
if (bitmap[DP_ID_RESERVA_DP1 / 8] & (1 << (DP_ID_RESERVA_DP1 % 8)))
{
if (valIdx + 4 <= valLen)
@@ -652,7 +551,7 @@ static void jbUnpackDps(const uint8_t *bitmap, const uint8_t *values,
info->dp_ids[info->count++] = DP_ID_RESERVA_DP1;
}
}
/* DP27 预留DP2 (uint32, 4B, RW) */
/* DP29 预留DP2 (uint32, 4B, RW) */
if (bitmap[DP_ID_RESERVA_DP2 / 8] & (1 << (DP_ID_RESERVA_DP2 % 8)))
{
if (valIdx + 4 <= valLen)
@@ -665,7 +564,7 @@ static void jbUnpackDps(const uint8_t *bitmap, const uint8_t *values,
info->dp_ids[info->count++] = DP_ID_RESERVA_DP2;
}
}
/* DP28 预留DP3 (uint32, 4B, RW) */
/* DP30 预留DP3 (uint32, 4B, RW) */
if (bitmap[DP_ID_RESERVA_DP3 / 8] & (1 << (DP_ID_RESERVA_DP3 % 8)))
{
if (valIdx + 4 <= valLen)
@@ -721,52 +620,16 @@ static uint8_t jbBuildDiffMask(const jb_data_point_t *last,
mask[DP_ID_CURRENT_HUMI / 8] |= (1 << (DP_ID_CURRENT_HUMI % 8));
hasChange = 1;
}
/* DP5 条件使能 */
if (last->cond_en != cur->cond_en)
/* DP5 联动删除 */
if (last->linkage_delete != cur->linkage_delete)
{
mask[DP_ID_COND_EN / 8] |= (1 << (DP_ID_COND_EN % 8));
mask[DP_ID_LINKAGE_DELETE / 8] |= (1 << (DP_ID_LINKAGE_DELETE % 8));
hasChange = 1;
}
/* DP6 条件配置1 */
if (memcmp(last->cond_config1, cur->cond_config1, 7))
/* DP6 联动配置 */
if (memcmp(last->linkage_config, cur->linkage_config, 20))
{
mask[DP_ID_COND_CONFIG1 / 8] |= (1 << (DP_ID_COND_CONFIG1 % 8));
hasChange = 1;
}
/* DP7 条件配置2 */
if (memcmp(last->cond_config2, cur->cond_config2, 7))
{
mask[DP_ID_COND_CONFIG2 / 8] |= (1 << (DP_ID_COND_CONFIG2 % 8));
hasChange = 1;
}
/* DP8 条件配置3 */
if (memcmp(last->cond_config3, cur->cond_config3, 7))
{
mask[DP_ID_COND_CONFIG3 / 8] |= (1 << (DP_ID_COND_CONFIG3 % 8));
hasChange = 1;
}
/* DP9 条件配置4 */
if (memcmp(last->cond_config4, cur->cond_config4, 7))
{
mask[DP_ID_COND_CONFIG4 / 8] |= (1 << (DP_ID_COND_CONFIG4 % 8));
hasChange = 1;
}
/* DP10 条件配置5 */
if (memcmp(last->cond_config5, cur->cond_config5, 7))
{
mask[DP_ID_COND_CONFIG5 / 8] |= (1 << (DP_ID_COND_CONFIG5 % 8));
hasChange = 1;
}
/* DP11 条件配置6 */
if (memcmp(last->cond_config6, cur->cond_config6, 7))
{
mask[DP_ID_COND_CONFIG6 / 8] |= (1 << (DP_ID_COND_CONFIG6 % 8));
hasChange = 1;
}
/* DP12 条件配置7 */
if (memcmp(last->cond_config7, cur->cond_config7, 7))
{
mask[DP_ID_COND_CONFIG7 / 8] |= (1 << (DP_ID_COND_CONFIG7 % 8));
mask[DP_ID_LINKAGE_CONFIG / 8] |= (1 << (DP_ID_LINKAGE_CONFIG % 8));
hasChange = 1;
}
/* DP13 定时使能 */
@@ -817,43 +680,45 @@ static uint8_t jbBuildDiffMask(const jb_data_point_t *last,
mask[DP_ID_TIME_CONFIG7 / 8] |= (1 << (DP_ID_TIME_CONFIG7 % 8));
hasChange = 1;
}
/* DP21 设备故障使能 */
/* DP21 运行记录:每秒都在变,不参与差分上报(避免 2s 防抖推 124B)。
* 读请求与 REPORT_PERIOD 全量仍带当前 gDevData.run_record。 */
/* DP23 设备故障使能 */
if (last->fault_en != cur->fault_en)
{
mask[DP_ID_FAULT_EN / 8] |= (1 << (DP_ID_FAULT_EN % 8));
hasChange = 1;
}
/* DP22 设备故障 */
/* DP24 设备故障 */
if (last->fault_code != cur->fault_code)
{
mask[DP_ID_FAULT_CODE / 8] |= (1 << (DP_ID_FAULT_CODE % 8));
hasChange = 1;
}
/* DP23 设备告警使能 */
/* DP25 设备告警使能 */
if (last->alarm_en != cur->alarm_en)
{
mask[DP_ID_ALARM_EN / 8] |= (1 << (DP_ID_ALARM_EN % 8));
hasChange = 1;
}
/* DP24 设备告警 */
/* DP26 设备告警 */
if (last->alarm_code != cur->alarm_code)
{
mask[DP_ID_ALARM_CODE / 8] |= (1 << (DP_ID_ALARM_CODE % 8));
hasChange = 1;
}
/* DP26 预留DP1 */
/* DP28 预留DP1 */
if (last->reserva_dp1 != cur->reserva_dp1)
{
mask[DP_ID_RESERVA_DP1 / 8] |= (1 << (DP_ID_RESERVA_DP1 % 8));
hasChange = 1;
}
/* DP27 预留DP2 */
/* DP29 预留DP2 */
if (last->reserva_dp2 != cur->reserva_dp2)
{
mask[DP_ID_RESERVA_DP2 / 8] |= (1 << (DP_ID_RESERVA_DP2 % 8));
hasChange = 1;
}
/* DP28 预留DP3 */
/* DP30 预留DP3 */
if (last->reserva_dp3 != cur->reserva_dp3)
{
mask[DP_ID_RESERVA_DP3 / 8] |= (1 << (DP_ID_RESERVA_DP3 % 8));
+34 -43
View File
@@ -1,7 +1,7 @@
/* ================================================================
* jb_protocol.h — 见宝 IOT 协议层(自动生成)
* 设备: 温湿度风扇 | DP 数: 29 | Bitmap: 4B
* 协议版本: V1.0 | 生成时间: 2026-08-29 10:31:50
* 设备: 温湿度风扇 | DP 数: 25 | Bitmap: 4B
* 协议版本: V1.0 | 生成时间: 2026-09-02 16:01:44
*
* 帧格式: [55 AA] [LEN_H LEN_L] [CMD] [SN] [payload...] [CKSUM]
* LEN = CMD(1) + SN(1) + payload + CKSUM(1) = payload + 3
@@ -23,10 +23,13 @@
* ════════════════════════════════════════════════════════════════ */
#define PKT_HEAD_0 0x55
#define PKT_HEAD_1 0xAA
/* ⚠ 生成器给的是 128,必须改回 256DP21 run_record 124B,加 bitmap(4B) 与
* cmd/sn/cksum 开销后 128B 组不出完整帧(规格书第 0 章第 1 条 / 第 19 章)。
* 每次从生成器重新拷贝 jb_protocol.h 后都要重新确认本值。 */
#define MAX_PACKAGE_LEN 256
#define JB_OTA_MAX_PAYLOAD 96 /* OTA 单包 Payload 上限(Byte); 须 <= MAX_PACKAGE_LEN - 11(0x32 帧开销) */
#define DP_COUNT 29
#define DP_COUNT 25
#define DP_BITMAP_SIZE 4
#define SEND_MAX_TIME 2500 /* ACK 重传超时(ms)BLE Indication往返常需数百ms~1s,过短会误重传导致双应答 */
@@ -123,14 +126,8 @@ typedef enum
DP_ID_FAN_GEAR = 2, /* 风速挡位 (enum, RW) */
DP_ID_CURRENT_TEMP = 3, /* 当前温度 (float, RO) */
DP_ID_CURRENT_HUMI = 4, /* 当前湿度 (uint8, RO) */
DP_ID_COND_EN = 5, /* 条件使能 (bool, RW) */
DP_ID_COND_CONFIG1 = 6, /* 条件配置1 (raw, RW) */
DP_ID_COND_CONFIG2 = 7, /* 条件配置2 (raw, RW) */
DP_ID_COND_CONFIG3 = 8, /* 条件配置3 (raw, RW) */
DP_ID_COND_CONFIG4 = 9, /* 条件配置4 (raw, RW) */
DP_ID_COND_CONFIG5 = 10, /* 条件配置5 (raw, RW) */
DP_ID_COND_CONFIG6 = 11, /* 条件配置6 (raw, RW) */
DP_ID_COND_CONFIG7 = 12, /* 条件配置7 (raw, RW) */
DP_ID_LINKAGE_DELETE = 5, /* 联动删除 (bool, RW) */
DP_ID_LINKAGE_CONFIG = 6, /* 联动配置 (raw, RW) */
DP_ID_TIME_EN = 13, /* 定时使能 (bool, RW) */
DP_ID_TIME_CONFIG1 = 14, /* 定时配置1 (raw, RW) */
DP_ID_TIME_CONFIG2 = 15, /* 定时配置2 (raw, RW) */
@@ -139,14 +136,16 @@ typedef enum
DP_ID_TIME_CONFIG5 = 18, /* 定时配置5 (raw, RW) */
DP_ID_TIME_CONFIG6 = 19, /* 定时配置6 (raw, RW) */
DP_ID_TIME_CONFIG7 = 20, /* 定时配置7 (raw, RW) */
DP_ID_FAULT_EN = 21, /* 设备故障使能 (uint8, RW) */
DP_ID_FAULT_CODE = 22, /* 设备故障 (uint8, RO) */
DP_ID_ALARM_EN = 23, /* 设备告警使能 (uint8, RW) */
DP_ID_ALARM_CODE = 24, /* 设备告警 (uint8, RO) */
DP_ID_FACTORY_RESET = 25, /* 恢复出厂设置 (bool, WO) */
DP_ID_RESERVA_DP1 = 26, /* 预留DP1 (uint32, RW) */
DP_ID_RESERVA_DP2 = 27, /* 预留DP2 (uint32, RW) */
DP_ID_RESERVA_DP3 = 28, /* 预留DP3 (uint32, RW) */
DP_ID_RUN_RECORD = 21, /* 运行记录 (raw, RO) */
DP_ID_HEARTBEAT = 22, /* 心跳 (bool, WO) */
DP_ID_FAULT_EN = 23, /* 设备故障使能 (uint8, RW) */
DP_ID_FAULT_CODE = 24, /* 设备故障 (uint8, RO) */
DP_ID_ALARM_EN = 25, /* 设备告警使能 (uint8, RW) */
DP_ID_ALARM_CODE = 26, /* 设备告警 (uint8, RO) */
DP_ID_FACTORY_RESET = 27, /* 恢复出厂设置 (bool, WO) */
DP_ID_RESERVA_DP1 = 28, /* 预留DP1 (uint32, RW) */
DP_ID_RESERVA_DP2 = 29, /* 预留DP2 (uint32, RW) */
DP_ID_RESERVA_DP3 = 30, /* 预留DP3 (uint32, RW) */
DP_ID_MAX
} dp_id_t;
@@ -156,14 +155,8 @@ typedef enum
#define DP_LEN_FAN_GEAR 1
#define DP_LEN_CURRENT_TEMP 2
#define DP_LEN_CURRENT_HUMI 1
#define DP_LEN_COND_EN 1
#define DP_LEN_COND_CONFIG1 7
#define DP_LEN_COND_CONFIG2 7
#define DP_LEN_COND_CONFIG3 7
#define DP_LEN_COND_CONFIG4 7
#define DP_LEN_COND_CONFIG5 7
#define DP_LEN_COND_CONFIG6 7
#define DP_LEN_COND_CONFIG7 7
#define DP_LEN_LINKAGE_DELETE 1
#define DP_LEN_LINKAGE_CONFIG 20
#define DP_LEN_TIME_EN 1
#define DP_LEN_TIME_CONFIG1 8
#define DP_LEN_TIME_CONFIG2 8
@@ -172,6 +165,8 @@ typedef enum
#define DP_LEN_TIME_CONFIG5 8
#define DP_LEN_TIME_CONFIG6 8
#define DP_LEN_TIME_CONFIG7 8
#define DP_LEN_RUN_RECORD 124
#define DP_LEN_HEARTBEAT 1
#define DP_LEN_FAULT_EN 1
#define DP_LEN_FAULT_CODE 1
#define DP_LEN_ALARM_EN 1
@@ -213,14 +208,8 @@ typedef struct
uint8_t fan_gear; /* DP2 风速挡位 */
float current_temp; /* DP3 当前温度 (float, scale=0.1) */
uint8_t current_humi; /* DP4 当前湿度 */
uint8_t cond_en; /* DP5 条件使能 */
uint8_t cond_config1[7];/* DP6 条件配置1 (7B: en/tempH/tempL/humi/dur/action/cond) */
uint8_t cond_config2[7];/* DP7 条件配置2 */
uint8_t cond_config3[7];/* DP8 条件配置3 */
uint8_t cond_config4[7];/* DP9 条件配置4 */
uint8_t cond_config5[7];/* DP10 条件配置5 */
uint8_t cond_config6[7];/* DP11 条件配置6 */
uint8_t cond_config7[7];/* DP12 条件配置7 */
uint8_t linkage_delete;/* DP5 联动删除 */
uint8_t linkage_config[20];/* DP6 联动配置 */
uint8_t time_en; /* DP13 定时使能 */
uint8_t time_config1[8];/* DP14 定时配置1 */
uint8_t time_config2[8];/* DP15 定时配置2 */
@@ -229,14 +218,16 @@ typedef struct
uint8_t time_config5[8];/* DP18 定时配置5 */
uint8_t time_config6[8];/* DP19 定时配置6 */
uint8_t time_config7[8];/* DP20 定时配置7 */
uint8_t fault_en; /* DP21 设备故障使能 */
uint8_t fault_code; /* DP22 设备故障 */
uint8_t alarm_en; /* DP23 设备告警使能 */
uint8_t alarm_code; /* DP24 设备告警 */
uint8_t factory_reset;/* DP25 恢复出厂设置 */
uint32_t reserva_dp1; /* DP26 预留DP1 */
uint32_t reserva_dp2; /* DP27 预留DP2 */
uint32_t reserva_dp3; /* DP28 预留DP3 */
uint8_t run_record[124];/* DP21 运行记录 */
uint8_t heartbeat; /* DP22 心跳 */
uint8_t fault_en; /* DP23 设备故障使能 */
uint8_t fault_code; /* DP24 设备故障 */
uint8_t alarm_en; /* DP25 设备告警使能 */
uint8_t alarm_code; /* DP26 设备告警 */
uint8_t factory_reset;/* DP27 恢复出厂设置 */
uint32_t reserva_dp1; /* DP28 预留DP1 */
uint32_t reserva_dp2; /* DP29 预留DP2 */
uint32_t reserva_dp3; /* DP30 预留DP3 */
} jb_data_point_t;
/* 控制事件信息 */