mirror of
https://github.com/Koenkk/zigbee2mqtt.git
synced 2026-08-27 21:20:03 +00:00
Add cache_state_persistent and cache_state_send_on_startup options. #3496
This commit is contained in:
+1
-1
@@ -154,7 +154,7 @@ class Controller {
|
||||
await this.mqtt.connect();
|
||||
|
||||
// Send all cached states.
|
||||
if (settings.get().advanced.cache_state) {
|
||||
if (settings.get().advanced.cache_state_send_on_startup && settings.get().advanced.cache_state) {
|
||||
for (const device of this.zigbee.getClients()) {
|
||||
if (this.state.exists(device.ieeeAddr)) {
|
||||
this.publishEntityState(device.ieeeAddr, this.state.get(device.ieeeAddr));
|
||||
|
||||
+8
-3
@@ -1,5 +1,6 @@
|
||||
const logger = require('./util/logger');
|
||||
const data = require('./util/data');
|
||||
const settings = require('./util/settings');
|
||||
const fs = require('fs');
|
||||
const objectAssignDeep = require('object-assign-deep');
|
||||
|
||||
@@ -53,9 +54,13 @@ class State {
|
||||
}
|
||||
|
||||
save() {
|
||||
logger.debug(`Saving state to file ${this.file}`);
|
||||
const json = JSON.stringify(this.state, null, 4);
|
||||
fs.writeFileSync(this.file, json, 'utf8');
|
||||
if (settings.get().advanced.cache_state_persistent) {
|
||||
logger.debug(`Saving state to file ${this.file}`);
|
||||
const json = JSON.stringify(this.state, null, 4);
|
||||
fs.writeFileSync(this.file, json, 'utf8');
|
||||
} else {
|
||||
logger.debug(`Not saving state`);
|
||||
}
|
||||
}
|
||||
|
||||
exists(ID) {
|
||||
|
||||
@@ -71,6 +71,8 @@ const defaults = {
|
||||
* https://www.zigbee2mqtt.io/configuration/configuration.html
|
||||
*/
|
||||
cache_state: true,
|
||||
cache_state_persistent: true,
|
||||
cache_state_send_on_startup: true,
|
||||
|
||||
/**
|
||||
* Add a last_seen attribute to mqtt messages, contains date/time of zigbee message arrival
|
||||
@@ -171,6 +173,8 @@ const schema = {
|
||||
ext_pan_id: {type: 'array', items: {type: 'number'}},
|
||||
channel: {type: 'number', minimum: 11, maximum: 26},
|
||||
cache_state: {type: 'boolean'},
|
||||
cache_state_persistent: {type: 'boolean'},
|
||||
cache_state_send_on_startup: {type: 'boolean'},
|
||||
log_rotation: {type: 'boolean'},
|
||||
log_level: {type: 'string', enum: ['info', 'warn', 'error', 'debug']},
|
||||
log_output: {type: 'array', items: {type: 'string'}},
|
||||
|
||||
@@ -108,6 +108,15 @@ describe('Controller', () => {
|
||||
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/remote", `{"brightness":255}`, {"qos": 0, "retain": true}, expect.any(Function));
|
||||
});
|
||||
|
||||
it('Start controller should not publish cached states when disabled', async () => {
|
||||
settings.set(['advanced', 'cache_state_send_on_startup'], false);
|
||||
data.writeDefaultState();
|
||||
await controller.start();
|
||||
await flushPromises();
|
||||
const publishedTopics = MQTT.publish.mock.calls.map(m => m[0]);
|
||||
expect(publishedTopics).toEqual(expect.not.arrayContaining(["zigbee2mqtt/bulb", "zigbee2mqtt/remote"]));
|
||||
});
|
||||
|
||||
it('Start controller should not publish cached states when cache_state is false', async () => {
|
||||
settings.set(['advanced', 'cache_state'], false);
|
||||
data.writeDefaultState();
|
||||
@@ -517,6 +526,21 @@ describe('Controller', () => {
|
||||
expect(MQTT.publish).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('Should allow to disable state persistency', async () => {
|
||||
settings.set(['advanced', 'cache_state_persistent'], false);
|
||||
data.removeState();
|
||||
await controller.start();
|
||||
MQTT.publish.mockClear();
|
||||
await controller.publishEntityState('bulb', {state: 'ON'});
|
||||
await controller.publishEntityState('bulb', {brightness: 200});
|
||||
await flushPromises();
|
||||
expect(MQTT.publish).toHaveBeenCalledTimes(2);
|
||||
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb", JSON.stringify({state: "ON"}), {"qos": 0, "retain": true}, expect.any(Function));
|
||||
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb", JSON.stringify({state: "ON", brightness: 200}), {"qos": 0, "retain": true}, expect.any(Function));
|
||||
await controller.stop();
|
||||
expect(data.stateExists()).toBeFalsy();
|
||||
});
|
||||
|
||||
it('Publish should not cache when set', async () => {
|
||||
settings.set(['advanced', 'cache_state'], false);
|
||||
data.writeEmptyState();
|
||||
|
||||
+13
-5
@@ -5,6 +5,7 @@ const fs = require('fs');
|
||||
|
||||
const mockDir = tmp.dirSync().name;
|
||||
const mockDirStorage = tmp.dirSync().name;
|
||||
const stateFile = path.join(mockDir, 'state.json');
|
||||
|
||||
function writeDefaultConfiguration() {
|
||||
const config = {
|
||||
@@ -182,7 +183,17 @@ function writeDefaultConfiguration() {
|
||||
}
|
||||
|
||||
function writeEmptyState() {
|
||||
fs.writeFileSync(path.join(mockDir, 'state.json'), JSON.stringify({}));
|
||||
fs.writeFileSync(stateFile, JSON.stringify({}));
|
||||
}
|
||||
|
||||
function removeState() {
|
||||
if (stateExists()) {
|
||||
fs.unlinkSync(stateFile);
|
||||
}
|
||||
}
|
||||
|
||||
function stateExists() {
|
||||
return fs.existsSync(stateFile);
|
||||
}
|
||||
|
||||
function writeDefaultState() {
|
||||
@@ -201,10 +212,6 @@ function writeDefaultState() {
|
||||
fs.writeFileSync(path.join(mockDir, 'state.json'), JSON.stringify(state));
|
||||
}
|
||||
|
||||
function removeState() {
|
||||
fs.unlinkSync(path.join(mockDir, 'state.json'))
|
||||
}
|
||||
|
||||
jest.mock('../../lib/util/data', () => ({
|
||||
joinPath: (file) => require('path').join(mockDir, file),
|
||||
getPath: () => mockDir,
|
||||
@@ -220,4 +227,5 @@ module.exports = {
|
||||
writeDefaultState,
|
||||
removeState,
|
||||
writeEmptyState,
|
||||
stateExists,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user