mirror of
https://github.com/Koenkk/zigbee2mqtt.git
synced 2026-08-28 05:24:29 +00:00
feat: New health extension & extras in bridge/info (#27164)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
This commit is contained in:
@@ -41,6 +41,19 @@ const mocksClear = [
|
||||
|
||||
const deviceIconsDir = path.join(data.mockDir, "device_icons");
|
||||
|
||||
vi.mock("node:os", async (importOriginal) => ({
|
||||
...(await importOriginal()),
|
||||
version: vi.fn(() => "Linux"),
|
||||
release: vi.fn(() => "0.0.1"),
|
||||
arch: vi.fn(() => "x64"),
|
||||
cpus: vi.fn(() => [{model: "Intel Core i7-9999"}]),
|
||||
totalmem: vi.fn(() => 10485760),
|
||||
}));
|
||||
vi.mock("node:process", async (importOriginal) => ({
|
||||
...(await importOriginal()),
|
||||
version: "v1.2.3",
|
||||
}));
|
||||
|
||||
describe("Extension: Bridge", () => {
|
||||
let controller: Controller;
|
||||
let mockRestart: Mock;
|
||||
@@ -94,12 +107,16 @@ describe("Extension: Bridge", () => {
|
||||
const zhVersion = await utils.getDependencyVersion("zigbee-herdsman");
|
||||
const zhcVersion = await utils.getDependencyVersion("zigbee-herdsman-converters");
|
||||
const directory = settings.get().advanced.log_directory;
|
||||
// console.log(mockMQTTPublishAsync.mock.calls.find((c) => c[0] === 'zigbee2mqtt/bridge/info')![1]);
|
||||
// console.log(mockMQTTPublishAsync.mock.calls.find((c) => c[0] === "zigbee2mqtt/bridge/info")![1]);
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith(
|
||||
"zigbee2mqtt/bridge/info",
|
||||
stringify({
|
||||
commit: version.commitHash,
|
||||
config: {
|
||||
health: {
|
||||
interval: 10,
|
||||
reset_on_check: false,
|
||||
},
|
||||
advanced: {
|
||||
adapter_concurrent: undefined,
|
||||
adapter_delay: undefined,
|
||||
@@ -315,6 +332,16 @@ describe("Extension: Bridge", () => {
|
||||
version: version.version,
|
||||
zigbee_herdsman: zhVersion,
|
||||
zigbee_herdsman_converters: zhcVersion,
|
||||
os: {
|
||||
version: "Linux - 0.0.1 - x64",
|
||||
node_version: "v1.2.3",
|
||||
cpus: "Intel Core i7-9999 (x1)",
|
||||
memory_mb: 10,
|
||||
},
|
||||
mqtt: {
|
||||
server: "mqtt://localhost:1883",
|
||||
version: 5,
|
||||
},
|
||||
}),
|
||||
{retain: true},
|
||||
);
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
import * as data from "../mocks/data";
|
||||
import {mockLogger} from "../mocks/logger";
|
||||
import {events as mockMQTTEvents, mockMQTTPublishAsync} from "../mocks/mqtt";
|
||||
import {flushPromises} from "../mocks/utils";
|
||||
import {devices, events as mockZHEvents, returnDevices} from "../mocks/zigbeeHerdsman";
|
||||
|
||||
import {Controller} from "../../lib/controller";
|
||||
import Health from "../../lib/extension/health";
|
||||
import * as settings from "../../lib/util/settings";
|
||||
import {minutes, seconds} from "../../lib/util/utils";
|
||||
|
||||
const mocksClear = [mockMQTTPublishAsync, mockLogger.warning, mockLogger.info];
|
||||
|
||||
returnDevices.push(devices.bulb_color.ieeeAddr, devices.bulb_color_2.ieeeAddr, devices.coordinator.ieeeAddr);
|
||||
|
||||
describe("Extension: Health", () => {
|
||||
let controller: Controller;
|
||||
|
||||
const getExtension = (): Health => controller.getExtension("Health") as Health;
|
||||
|
||||
const resetExtension = async (): Promise<void> => {
|
||||
await controller.removeExtension(getExtension());
|
||||
await controller.addExtension(new Health(...controller.extensionArgs));
|
||||
};
|
||||
|
||||
beforeAll(async () => {
|
||||
vi.useFakeTimers();
|
||||
settings.reRead();
|
||||
|
||||
controller = new Controller(vi.fn(), vi.fn());
|
||||
|
||||
await controller.start();
|
||||
await flushPromises();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
data.writeDefaultConfiguration();
|
||||
settings.reRead();
|
||||
settings.set(["devices", devices.bulb_color_2.ieeeAddr, "health"], false);
|
||||
|
||||
for (const mock of mocksClear) {
|
||||
mock.mockClear();
|
||||
}
|
||||
|
||||
getExtension().clearStats();
|
||||
});
|
||||
|
||||
afterEach(async () => {});
|
||||
|
||||
afterAll(async () => {
|
||||
await controller?.stop();
|
||||
await flushPromises();
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it("checks health at default interval", async () => {
|
||||
await resetExtension();
|
||||
await mockZHEvents.lastSeenChanged({device: devices.bulb_color});
|
||||
await mockZHEvents.lastSeenChanged({device: devices.bulb_color_2});
|
||||
await mockZHEvents.deviceLeave({ieeeAddr: devices.bulb_color.ieeeAddr});
|
||||
await mockZHEvents.deviceJoined({device: devices.bulb_color});
|
||||
await mockZHEvents.deviceNetworkAddressChanged({device: devices.bulb_color});
|
||||
await vi.advanceTimersByTimeAsync(seconds(1));
|
||||
await mockZHEvents.lastSeenChanged({device: devices.bulb_color});
|
||||
await vi.advanceTimersByTimeAsync(seconds(1));
|
||||
await mockZHEvents.lastSeenChanged({device: devices.bulb_color});
|
||||
await vi.advanceTimersByTimeAsync(seconds(1));
|
||||
await mockZHEvents.lastSeenChanged({device: devices.bulb_color});
|
||||
await mockMQTTEvents.message("zigbee2mqtt/mock", "mocked");
|
||||
await vi.advanceTimersByTimeAsync(minutes(11));
|
||||
|
||||
let calls = mockMQTTPublishAsync.mock.calls.filter((call) => call[0] === "zigbee2mqtt/bridge/health");
|
||||
|
||||
expect(calls.length).toStrictEqual(1);
|
||||
expect(JSON.parse(calls[0][1])).toStrictEqual({
|
||||
response_time: expect.any(Number),
|
||||
os: {
|
||||
load_average: [expect.any(Number), expect.any(Number), expect.any(Number)],
|
||||
memory_used_mb: expect.any(Number),
|
||||
memory_percent: expect.any(Number),
|
||||
},
|
||||
process: {uptime_sec: expect.any(Number), memory_used_mb: expect.any(Number), memory_percent: expect.any(Number)},
|
||||
mqtt: {
|
||||
connected: true,
|
||||
queued: 0,
|
||||
published: expect.any(Number),
|
||||
received: 1,
|
||||
},
|
||||
devices: {
|
||||
[devices.bulb_color.ieeeAddr]: {
|
||||
leave_count: 1,
|
||||
messages: 4,
|
||||
messages_per_sec: 0.0067,
|
||||
network_address_changes: 1,
|
||||
},
|
||||
[devices.bulb_color_2.ieeeAddr]: {
|
||||
leave_count: 0,
|
||||
messages: 1,
|
||||
messages_per_sec: 0.0017,
|
||||
network_address_changes: 0,
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(calls[0][2]).toStrictEqual({retain: true, qos: 1});
|
||||
|
||||
mockMQTTPublishAsync.mockClear();
|
||||
await mockMQTTEvents.message("zigbee2mqtt/mock2", "mocked2");
|
||||
await vi.advanceTimersByTimeAsync(minutes(11));
|
||||
|
||||
calls = mockMQTTPublishAsync.mock.calls.filter((call) => call[0] === "zigbee2mqtt/bridge/health");
|
||||
|
||||
expect(calls.length).toStrictEqual(1);
|
||||
expect(JSON.parse(calls[0][1])).toStrictEqual({
|
||||
response_time: expect.any(Number),
|
||||
os: {
|
||||
load_average: [expect.any(Number), expect.any(Number), expect.any(Number)],
|
||||
memory_used_mb: expect.any(Number),
|
||||
memory_percent: expect.any(Number),
|
||||
},
|
||||
process: {uptime_sec: expect.any(Number), memory_used_mb: expect.any(Number), memory_percent: expect.any(Number)},
|
||||
mqtt: {
|
||||
connected: true,
|
||||
queued: 0,
|
||||
published: expect.any(Number),
|
||||
received: 2,
|
||||
},
|
||||
devices: {
|
||||
[devices.bulb_color.ieeeAddr]: {
|
||||
leave_count: 1,
|
||||
messages: 4,
|
||||
messages_per_sec: 0.0033,
|
||||
network_address_changes: 1,
|
||||
},
|
||||
[devices.bulb_color_2.ieeeAddr]: {
|
||||
leave_count: 0,
|
||||
messages: 1,
|
||||
messages_per_sec: 0.0008,
|
||||
network_address_changes: 0,
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(calls[0][2]).toStrictEqual({retain: true, qos: 1});
|
||||
});
|
||||
|
||||
it("checks health at given interval", async () => {
|
||||
settings.set(["health", "interval"], 20);
|
||||
await resetExtension();
|
||||
await vi.advanceTimersByTimeAsync(minutes(11));
|
||||
|
||||
let calls = mockMQTTPublishAsync.mock.calls.filter((call) => call[0] === "zigbee2mqtt/bridge/health");
|
||||
|
||||
expect(calls.length).toStrictEqual(0);
|
||||
|
||||
await vi.advanceTimersByTimeAsync(minutes(10));
|
||||
|
||||
calls = mockMQTTPublishAsync.mock.calls.filter((call) => call[0] === "zigbee2mqtt/bridge/health");
|
||||
|
||||
expect(calls.length).toStrictEqual(1);
|
||||
expect(JSON.parse(calls[0][1])).toStrictEqual({
|
||||
response_time: expect.any(Number),
|
||||
os: {
|
||||
load_average: [expect.any(Number), expect.any(Number), expect.any(Number)],
|
||||
memory_used_mb: expect.any(Number),
|
||||
memory_percent: expect.any(Number),
|
||||
},
|
||||
process: {uptime_sec: expect.any(Number), memory_used_mb: expect.any(Number), memory_percent: expect.any(Number)},
|
||||
mqtt: {
|
||||
connected: true,
|
||||
queued: 0,
|
||||
published: expect.any(Number),
|
||||
received: 0,
|
||||
},
|
||||
devices: {},
|
||||
});
|
||||
expect(calls[0][2]).toStrictEqual({retain: true, qos: 1});
|
||||
});
|
||||
|
||||
it("init device health from leave", async () => {
|
||||
await resetExtension();
|
||||
await mockZHEvents.deviceLeave({ieeeAddr: devices.bulb_color.ieeeAddr});
|
||||
await mockZHEvents.deviceJoined({device: devices.bulb_color});
|
||||
await vi.advanceTimersByTimeAsync(minutes(11));
|
||||
|
||||
const calls = mockMQTTPublishAsync.mock.calls.filter((call) => call[0] === "zigbee2mqtt/bridge/health");
|
||||
|
||||
expect(calls.length).toStrictEqual(1);
|
||||
expect(JSON.parse(calls[0][1])).toStrictEqual({
|
||||
response_time: expect.any(Number),
|
||||
os: {
|
||||
load_average: [expect.any(Number), expect.any(Number), expect.any(Number)],
|
||||
memory_used_mb: expect.any(Number),
|
||||
memory_percent: expect.any(Number),
|
||||
},
|
||||
process: {uptime_sec: expect.any(Number), memory_used_mb: expect.any(Number), memory_percent: expect.any(Number)},
|
||||
mqtt: {
|
||||
connected: true,
|
||||
queued: 0,
|
||||
published: expect.any(Number),
|
||||
received: 0,
|
||||
},
|
||||
devices: {
|
||||
[devices.bulb_color.ieeeAddr]: {
|
||||
leave_count: 1,
|
||||
messages: 0,
|
||||
messages_per_sec: 0,
|
||||
network_address_changes: 0,
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(calls[0][2]).toStrictEqual({retain: true, qos: 1});
|
||||
});
|
||||
|
||||
it("init device health from network address change", async () => {
|
||||
await resetExtension();
|
||||
await mockZHEvents.deviceNetworkAddressChanged({device: devices.bulb_color});
|
||||
await vi.advanceTimersByTimeAsync(minutes(11));
|
||||
|
||||
const calls = mockMQTTPublishAsync.mock.calls.filter((call) => call[0] === "zigbee2mqtt/bridge/health");
|
||||
|
||||
expect(calls.length).toStrictEqual(1);
|
||||
expect(JSON.parse(calls[0][1])).toStrictEqual({
|
||||
response_time: expect.any(Number),
|
||||
os: {
|
||||
load_average: [expect.any(Number), expect.any(Number), expect.any(Number)],
|
||||
memory_used_mb: expect.any(Number),
|
||||
memory_percent: expect.any(Number),
|
||||
},
|
||||
process: {uptime_sec: expect.any(Number), memory_used_mb: expect.any(Number), memory_percent: expect.any(Number)},
|
||||
mqtt: {
|
||||
connected: true,
|
||||
queued: 0,
|
||||
published: expect.any(Number),
|
||||
received: 0,
|
||||
},
|
||||
devices: {
|
||||
[devices.bulb_color.ieeeAddr]: {
|
||||
leave_count: 0,
|
||||
messages: 0,
|
||||
messages_per_sec: 0,
|
||||
network_address_changes: 1,
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(calls[0][2]).toStrictEqual({retain: true, qos: 1});
|
||||
});
|
||||
|
||||
it("checks health then resets possible stats", async () => {
|
||||
settings.set(["health", "reset_on_check"], true);
|
||||
await resetExtension();
|
||||
await mockZHEvents.lastSeenChanged({device: devices.bulb_color});
|
||||
await mockZHEvents.lastSeenChanged({device: devices.bulb_color}); // coverage no time diff first/last
|
||||
await mockZHEvents.lastSeenChanged({device: devices.bulb_color_2});
|
||||
await vi.advanceTimersByTimeAsync(minutes(11));
|
||||
|
||||
let calls = mockMQTTPublishAsync.mock.calls.filter((call) => call[0] === "zigbee2mqtt/bridge/health");
|
||||
|
||||
expect(calls.length).toStrictEqual(1);
|
||||
expect(JSON.parse(calls[0][1])).toStrictEqual({
|
||||
response_time: expect.any(Number),
|
||||
os: {
|
||||
load_average: [expect.any(Number), expect.any(Number), expect.any(Number)],
|
||||
memory_used_mb: expect.any(Number),
|
||||
memory_percent: expect.any(Number),
|
||||
},
|
||||
process: {uptime_sec: expect.any(Number), memory_used_mb: expect.any(Number), memory_percent: expect.any(Number)},
|
||||
mqtt: {
|
||||
connected: true,
|
||||
queued: 0,
|
||||
published: expect.any(Number),
|
||||
received: 0,
|
||||
},
|
||||
devices: {
|
||||
[devices.bulb_color.ieeeAddr]: {
|
||||
leave_count: 0,
|
||||
messages: 2,
|
||||
messages_per_sec: 0.0033,
|
||||
network_address_changes: 0,
|
||||
},
|
||||
[devices.bulb_color_2.ieeeAddr]: {
|
||||
leave_count: 0,
|
||||
messages: 1,
|
||||
messages_per_sec: 0.0017,
|
||||
network_address_changes: 0,
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(calls[0][2]).toStrictEqual({retain: true, qos: 1});
|
||||
|
||||
mockMQTTPublishAsync.mockClear();
|
||||
await vi.advanceTimersByTimeAsync(minutes(11));
|
||||
|
||||
calls = mockMQTTPublishAsync.mock.calls.filter((call) => call[0] === "zigbee2mqtt/bridge/health");
|
||||
|
||||
expect(calls.length).toStrictEqual(1);
|
||||
expect(JSON.parse(calls[0][1])).toStrictEqual({
|
||||
response_time: expect.any(Number),
|
||||
os: {
|
||||
load_average: [expect.any(Number), expect.any(Number), expect.any(Number)],
|
||||
memory_used_mb: expect.any(Number),
|
||||
memory_percent: expect.any(Number),
|
||||
},
|
||||
process: {uptime_sec: expect.any(Number), memory_used_mb: expect.any(Number), memory_percent: expect.any(Number)},
|
||||
mqtt: {
|
||||
connected: true,
|
||||
queued: 0,
|
||||
published: expect.any(Number),
|
||||
received: 0,
|
||||
},
|
||||
devices: {},
|
||||
});
|
||||
expect(calls[0][2]).toStrictEqual({retain: true, qos: 1});
|
||||
});
|
||||
});
|
||||
@@ -1564,7 +1564,8 @@ describe("Extension: HomeAssistant", () => {
|
||||
await flushPromises();
|
||||
await vi.runOnlyPendingTimersAsync();
|
||||
await flushPromises();
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(0);
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(1);
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith("zigbee2mqtt/bridge/health", expect.any(String), expect.any(Object));
|
||||
});
|
||||
|
||||
it("Shouldnt send all status when home assistant comes online with different topic", async () => {
|
||||
@@ -1577,7 +1578,8 @@ describe("Extension: HomeAssistant", () => {
|
||||
await flushPromises();
|
||||
await vi.runOnlyPendingTimersAsync();
|
||||
await flushPromises();
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(0);
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(1);
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith("zigbee2mqtt/bridge/health", expect.any(String), expect.any(Object));
|
||||
});
|
||||
|
||||
it("Should discover devices with availability", async () => {
|
||||
@@ -2456,7 +2458,8 @@ describe("Extension: HomeAssistant", () => {
|
||||
stringify(payload),
|
||||
{retain: true, qos: 1},
|
||||
);
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(6);
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(7);
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith("zigbee2mqtt/bridge/health", expect.any(String), expect.any(Object));
|
||||
});
|
||||
|
||||
it("Should not clear bridge entities unnecessarily", async () => {
|
||||
|
||||
@@ -183,10 +183,11 @@ describe("Extension: Receive", () => {
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(0);
|
||||
vi.runOnlyPendingTimers();
|
||||
await flushPromises();
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(1);
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(2);
|
||||
expect(mockMQTTPublishAsync.mock.calls[0][0]).toStrictEqual("zigbee2mqtt/weather_sensor");
|
||||
expect(JSON.parse(mockMQTTPublishAsync.mock.calls[0][1])).toStrictEqual({temperature: 0.08, humidity: 0.01, pressure: 2});
|
||||
expect(mockMQTTPublishAsync.mock.calls[0][2]).toStrictEqual({qos: 1, retain: false});
|
||||
expect(mockMQTTPublishAsync.mock.calls[1][0]).toStrictEqual("zigbee2mqtt/bridge/health");
|
||||
});
|
||||
|
||||
it("Should debounce and retain messages when set via device_options", async () => {
|
||||
@@ -229,10 +230,11 @@ describe("Extension: Receive", () => {
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(0);
|
||||
vi.runOnlyPendingTimers();
|
||||
await flushPromises();
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(1);
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(2);
|
||||
expect(mockMQTTPublishAsync.mock.calls[0][0]).toStrictEqual("zigbee2mqtt/weather_sensor");
|
||||
expect(JSON.parse(mockMQTTPublishAsync.mock.calls[0][1])).toStrictEqual({temperature: 0.08, humidity: 0.01, pressure: 2});
|
||||
expect(mockMQTTPublishAsync.mock.calls[0][2]).toStrictEqual({qos: 1, retain: true});
|
||||
expect(mockMQTTPublishAsync.mock.calls[1][0]).toStrictEqual("zigbee2mqtt/bridge/health");
|
||||
});
|
||||
|
||||
it("Should debounce messages only with the same payload values for provided debounce_ignore keys", async () => {
|
||||
@@ -281,8 +283,9 @@ describe("Extension: Receive", () => {
|
||||
expect(JSON.parse(mockMQTTPublishAsync.mock.calls[0][1])).toStrictEqual({temperature: 0.08, pressure: 2});
|
||||
vi.runOnlyPendingTimers();
|
||||
await flushPromises();
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(2);
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(3);
|
||||
expect(JSON.parse(mockMQTTPublishAsync.mock.calls[1][1])).toStrictEqual({temperature: 0.07, pressure: 2, humidity: 0.03});
|
||||
expect(mockMQTTPublishAsync.mock.calls[2][0]).toStrictEqual("zigbee2mqtt/bridge/health");
|
||||
});
|
||||
|
||||
it("Should NOT publish old messages from State cache during debouncing", async () => {
|
||||
@@ -322,9 +325,10 @@ describe("Extension: Receive", () => {
|
||||
vi.runOnlyPendingTimers();
|
||||
|
||||
// Test that only one MQTT is sent out and test its values.
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(1);
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(1 + 1 /* "bridge/health" */);
|
||||
expect(mockMQTTPublishAsync.mock.calls[0][0]).toStrictEqual("zigbee2mqtt/weather_sensor");
|
||||
expect(JSON.parse(mockMQTTPublishAsync.mock.calls[0][1])).toStrictEqual({temperature: 0.08, humidity: 0.01, pressure: 2});
|
||||
expect(mockMQTTPublishAsync.mock.calls[1][0]).toStrictEqual("zigbee2mqtt/bridge/health");
|
||||
|
||||
// Send another Zigbee message...
|
||||
await mockZHEvents.message({
|
||||
@@ -343,12 +347,14 @@ describe("Extension: Receive", () => {
|
||||
vi.runOnlyPendingTimers();
|
||||
|
||||
// Total of 3 messages should have triggered.
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(3);
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(5);
|
||||
|
||||
expect(mockMQTTPublishAsync.mock.calls[1][0]).toStrictEqual("zigbee2mqtt/bridge/health");
|
||||
// Test that message pushed by asynchronous message contains NEW measurement and not old.
|
||||
expect(JSON.parse(mockMQTTPublishAsync.mock.calls[1][1])).toStrictEqual({temperature: 0.09, humidity: 0.01, pressure: 2});
|
||||
// Test that messages after debouncing contains NEW measurement and not old.
|
||||
expect(JSON.parse(mockMQTTPublishAsync.mock.calls[2][1])).toStrictEqual({temperature: 0.09, humidity: 0.01, pressure: 2});
|
||||
// Test that messages after debouncing contains NEW measurement and not old.
|
||||
expect(JSON.parse(mockMQTTPublishAsync.mock.calls[3][1])).toStrictEqual({temperature: 0.09, humidity: 0.01, pressure: 2});
|
||||
expect(mockMQTTPublishAsync.mock.calls[4][0]).toStrictEqual("zigbee2mqtt/bridge/health");
|
||||
});
|
||||
|
||||
it("Should throttle multiple messages from spamming devices", async () => {
|
||||
@@ -439,9 +445,10 @@ describe("Extension: Receive", () => {
|
||||
await mockMQTTEvents.message("zigbee2mqtt/bulb/set", stringify({state: "ON"}));
|
||||
await flushPromises();
|
||||
vi.runOnlyPendingTimers();
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(2);
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledTimes(2 + 1);
|
||||
expect(JSON.parse(mockMQTTPublishAsync.mock.calls[0][1])).toStrictEqual({state: "ON"});
|
||||
expect(JSON.parse(mockMQTTPublishAsync.mock.calls[1][1])).toStrictEqual({state: "ON"});
|
||||
expect(mockMQTTPublishAsync.mock.calls[2][0]).toStrictEqual("zigbee2mqtt/bridge/health");
|
||||
});
|
||||
|
||||
it("Should handle a zigbee message with 1 precision", async () => {
|
||||
|
||||
@@ -25,6 +25,13 @@ export const mockMQTTConnectAsync = vi.fn(() => ({
|
||||
events[type] = handler;
|
||||
}),
|
||||
stream: {setMaxListeners: vi.fn()},
|
||||
options: {
|
||||
protocolVersion: 5,
|
||||
protocol: "mqtt",
|
||||
host: "localhost",
|
||||
port: 1883,
|
||||
},
|
||||
queue: [],
|
||||
}));
|
||||
|
||||
vi.mock("mqtt", () => ({
|
||||
|
||||
Reference in New Issue
Block a user