feat(M06-E): 接入智慧插座业务控制

This commit is contained in:
Codex
2026-06-24 15:12:12 +08:00
parent 48638606fe
commit 9144fa8102
5 changed files with 198 additions and 3 deletions
+33 -2
View File
@@ -15,6 +15,12 @@ const issued = [];
const service = new DeviceControlService({
async execute(sql) {
if (sql.includes('FROM qipai_devices')) {
if (sql.includes("device_type = 'SMART_SOCKET'")) {
return [[{
id: 52, deviceId: 'SOCKET_001', storeId: 11, roomId: 31,
deviceType: 'SMART_SOCKET', status: 'ONLINE'
}], []];
}
return [[{
id: 51, deviceId: 'BOX_001', storeId: 11, roomId: 31,
deviceType: 'CONTROL_BOX', status: 'ONLINE'
@@ -56,6 +62,19 @@ await service.controlSubLock(context, {
subID: 'SUB001', order: 'open', delayTime: 4
});
assert.equal(issued.at(-1).payload.action, 'CtrlDevice');
await service.readSmartSocket(context, 'workInfo');
assert.deepEqual(issued.at(-1).payload, { read: 'workInfo' });
await service.switchSmartSocket(context, { on: false, slotNum: 2 });
assert.deepEqual(issued.at(-1).payload, {
action: 'off', id: '1782120000001', slotNum: 2
});
await service.scheduleSmartSocket(context, {
taskNum: 1, action: 'on', mode: 'weekly', time: '18:30', weekdays: [5, 6]
});
assert.equal(issued.at(-1).payload.action, 'localtask');
assert.equal(issued.at(-1).payload.switch, 'on');
await service.clearSmartSocketTask(context, 1);
assert.equal(issued.at(-1).payload.action, 'clearTask');
await assert.rejects(
() => service.controlSubLock(context, {
@@ -114,7 +133,11 @@ const app = await buildApp({
async extendTask() { return {}; },
async cancelTask() { return {}; },
async pairSubLock() { return {}; },
async controlSubLock() { return {}; }
async controlSubLock() { return {}; },
async readSmartSocket() { return {}; },
async switchSmartSocket(_context, input) { routed = input; return { status: 'PUBLISHED' }; },
async scheduleSmartSocket() { return {}; },
async clearSmartSocketTask() { return {}; }
}
}
});
@@ -126,6 +149,14 @@ const response = await app.inject({
});
assert.equal(response.statusCode, 200);
assert.equal(routed.slot1, 'on');
const socketResponse = await app.inject({
method: 'POST',
url: '/admin-api/device-control/socket/switch',
headers: { authorization: `Bearer ${token}` },
payload: { storeId: '11', roomId: '31', on: true, slotNum: 1 }
});
assert.equal(socketResponse.statusCode, 200);
assert.equal(routed.on, true);
const invalid = await app.inject({
method: 'POST',
url: '/admin-api/device-control/door',
@@ -135,4 +166,4 @@ const invalid = await app.inject({
assert.equal(invalid.statusCode, 400);
await app.close();
console.log('PASS: M06-D control-box and Sub-1G command gates and routes work.');
console.log('PASS: M06-E device control commands include control-box, Sub-1G and smart socket.');
+22
View File
@@ -91,6 +91,12 @@ const service = new IotMessageService({
async execute(sql, params) {
calls.push({ sql, params });
if (sql.includes('FROM qipai_devices')) {
if (params[0] === 'SOCKET_001') {
return [[{
id: 52, tenantId: 7, storeId: 11, roomId: 31,
deviceId: 'SOCKET_001', deviceType: 'SMART_SOCKET'
}], []];
}
return [[{
id: 51, tenantId: 7, storeId: 11, roomId: 31,
deviceId: 'BOX_001', deviceType: 'CONTROL_BOX'
@@ -150,6 +156,22 @@ assert.equal(calls.some((item) =>
item.sql.includes('INSERT INTO qipai_device_alerts')
&& item.params.includes('DEVICE_UNCONFIRM')
), true);
await service.handle('/devicesend/SOCKET_001', Buffer.from(JSON.stringify({
DeviceID: 'SOCKET_001', event: 'workInfo', switch: 'on',
powerW: 3601, temperature: 82, overLoad: true
})));
assert.equal(calls.some((item) =>
item.sql.includes('INSERT INTO qipai_device_alerts')
&& item.params.includes('SOCKET_OVERLOAD')
), true);
assert.equal(calls.some((item) =>
item.sql.includes('INSERT INTO qipai_device_alerts')
&& item.params.includes('SOCKET_POWER_LIMIT')
), true);
assert.equal(calls.some((item) =>
item.sql.includes('INSERT INTO qipai_device_alerts')
&& item.params.includes('SOCKET_TEMPERATURE_LIMIT')
), true);
await assert.rejects(
() => service.createCommand({