Смена значений у контролов виртуального устройства при перезагрузке

Не могу понять, подскажите что не так с моим скриптом или как правильно сделать скрипт для решения задачи учета воды.
В целом все работает, но стоит только перезапустить правило или контроллер, то контролам присваимваются какие-то непонятно откуда взятые значения.

изображение

defineVirtualDevice("WaterCount", {
    title: "WaterCount",
    cells: {
      "HW99": {//ГВС кв99
	    type: "value",
	    value: 4700,
        format: "u32",
        readonly: false,
        forceDefault: false,
	    },
      "CW99": {//ХВС кв99
	    type: "value",
	    value: 3110,
        format: "u32",
        readonly: false,
        forceDefault: false,        
	    },
      "HW100": {//ГВС кв100
	    type: "value",
	    value: 220,
        format: "u32",
        readonly: false,
        forceDefault: false,        
	    },
      "CW100": {//ХВС кв100
        type: "value",
        value: 660,
        format: "u8",
        readonly: false,
        forceDefault: false,        
	    },
      "HW99start": {//ГВС кв99 начало месяца
	    type: "value",
	    value: 4700,
        format: "u32",
        readonly: false,
        forceDefault: false,        
	    },
      "CW99start": {//ХВС кв99 начало месяца
	    type: "value",
	    value: 3110,
        format: "u32",
        readonly: false,
        forceDefault: false,        
	    },
      "HW100start": {//ГВС кв100 начало месяца
	    type: "value",
	    value: 220,
        format: "u32",
        readonly: false,
        forceDefault: false,        
	    },
      "CW100start": {//ХВС кв100 начало месяца
	    type: "value",
	    value: 660,
        format: "u32",
        readonly: false,
        forceDefault: false,        
	    }
	}
});

function WaterCount(name, control, virt, count) {
defineRule(name, { 
  whenChanged: control, //при новом импульсе
  then: function (newValue, devName, cellName) { //выполняй следующие действия
    if (newValue) {
    	dev[virt][count] += 10; // прибавляем +10 т.к. импульс это десятки, а не единица у счетчика
	    log.info("WaterCount.js : " + name + "   count = " + dev[virt][count]);
    }
  }
});
}

WaterCount("CW99Count", "wb-gpio/EXT2_IN6","WaterCount", "CW99");
WaterCount("HW99Count", "wb-gpio/EXT2_IN7", "WaterCount","HW99");
WaterCount("CW100Count","wb-gpio/EXT2_IN9","WaterCount","CW100");
WaterCount("HW100Count","wb-gpio/EXT2_IN8","WaterCount","HW100");


// проверка смены месяца и фиксация показаний на начало месяца
function resetStartMonth(name) {
var timer = 70*1000; // таймер на 70 секунд
var timer_id = null;
  
defineRule(name, {
  when: cron ("0 59 23 * *"), //запускаем таймер в 23-59, время согласно date формат 0 ММ ЧЧ * *
  then: function (){
		var date1 = new Date ();
      	if (timer_id) {
          clearTimeout(timer_id); //сброс таймера
        }
    
        timer_id = setTimeout(function () { //запускаем таймер на 70 секунд чтобы посмотреть дату позже
		var date2 = new Date ();
        if (date1.getMonth() != date2.getMonth()) // если месяцы в датах разные, т.е. наступил новый месяц
        {
            log.info("WaterCount.js : Установка начало отсчета месяца, текущие значения HW99start = " + dev["WaterCount/HW99"] + "  CW99start =  " + dev["WaterCount/CW99"] + "  HW100start =  " + dev["WaterCount/HW100"] + "  CW100start = " + dev["WaterCount/CW100"]);
          	dev["WaterCount/HW99start"] = dev["WaterCount/HW99"]; // значение счетчика на начало месяца
            dev["WaterCount/CW99start"] = dev["WaterCount/CW99"]; // значение счетчика на начало месяца
            dev["WaterCount/HW100start"] = dev["WaterCount/HW100"]; // значение счетчика на начало месяца
            dev["WaterCount/CW100start"] = dev["WaterCount/CW100"]; // значение счетчика на начало месяца
        }
          timer_id = null;   
       	}, timer);
  }
});
}

Добрый день.
Советую использовать https://wirenboard.com/wiki/Wb-rules_2.0#.D0.9F.D0.BE.D1.81.D1.82.D0.BE.D1.8F.D0.BD.D0.BD.D0.BE.D0.B5_.D1.85.D1.80.D0.B0.D0.BD.D0.B8.D0.BB.D0.B8.D1.89.D0.B5_.D0.B4.D0.B0.D0.BD.D0.BD.D1.8B.D1.85

Взаимообмен с иридиум нужен, просто переменные не подойдут

Имею в виду - хранить (и обновлять при изменении) в PersistentStorage значения контролов.

Не понимаю.

defineVirtualDevice("WaterCount", {
    title: "WaterCount",
    cells: {
      "HW99": {//ГВС кв99
	    type: "value",
	    value: 4700,
        format: "u32",
        readonly: false,
        forceDefault: false,
	    },
      "CW99": {//ХВС кв99
	    type: "value",
	    value: 3110,
        format: "u32",
        readonly: false,
        forceDefault: false,        
	    },
      "HW100": {//ГВС кв100
	    type: "value",
	    value: 220,
        format: "u32",
        readonly: false,
        forceDefault: false,        
	    },
      "CW100": {//ХВС кв100
        type: "value",
        value: 660,
        format: "u8",
        readonly: false,
        forceDefault: false,        
	    },
      "HW99start": {//ГВС кв99 начало месяца
	    type: "value",
	    value: 4700,
        format: "u32",
        readonly: false,
        forceDefault: false,        
	    },
      "CW99start": {//ХВС кв99 начало месяца
	    type: "value",
	    value: 3110,
        format: "u32",
        readonly: false,
        forceDefault: false,        
	    },
      "HW100start": {//ГВС кв100 начало месяца
	    type: "value",
	    value: 220,
        format: "u32",
        readonly: false,
        forceDefault: false,        
	    },
      "CW100start": {//ХВС кв100 начало месяца
	    type: "value",
	    value: 660,
        format: "u32",
        readonly: false,
        forceDefault: false,        
	    }
	}
});

var ps = new PersistentStorage("my-storage");

// инициализация показания счетчиков по состоянию 11.08.2021
ps["HW99"] = 3110;
ps["CW99"] = 4700;
ps["HW100"] = 210;
ps["CW100"] = 610;

function WaterCount(name, control, virt, count) {
defineRule(name, { 
  whenChanged: control, //при новом импульсе
  then: function (newValue, devName, cellName) { //выполняй следующие действия
    if (newValue) {
    	ps[count] += 10;
      	dev[virt][count] = ps[cont]; // прибавляем +10 т.к. импульс это десятки, а не единица у счетчика
	    log.info("WaterCount.js : " + name + "   count = " + dev[virt][count]);
    }
  }
});
}

WaterCount("CW99Count", "wb-gpio/EXT2_IN6","WaterCount", "CW99");
WaterCount("HW99Count", "wb-gpio/EXT2_IN7", "WaterCount","HW99");
WaterCount("CW100Count","wb-gpio/EXT2_IN9","WaterCount","CW100");
WaterCount("HW100Count","wb-gpio/EXT2_IN8","WaterCount","HW100");

// проверка смены месяца и фиксация показаний на начало месяца
function resetStartMonth(name) {
var timer = 70*1000; // таймер на 70 секунд
var timer_id = null;
  
defineRule(name, {
  when: cron ("0 59 23 * *"), //запускаем таймер в 23-59, время согласно date формат 0 ММ ЧЧ * *
  then: function (){
		var date1 = new Date ();
      	if (timer_id) {
          clearTimeout(timer_id); //сброс таймера
        }
    
        timer_id = setTimeout(function () { //запускаем таймер на 70 секунд чтобы посмотреть дату позже
		var date2 = new Date ();
        if (date1.getMonth() != date2.getMonth()) // если месяцы в датах разные, т.е. наступил новый месяц
        {
            log.info("WaterCount.js : Установка начало отсчета месяца, текущие значения HW99start = " + dev["WaterCount/HW99"] + "  CW99start =  " + dev["WaterCount/CW99"] + "  HW100start =  " + dev["WaterCount/HW100"] + "  CW100start = " + dev["WaterCount/CW100"]);
          	dev["WaterCount/HW99start"] = ps["HW99"]; // значение счетчика на начало месяца
            dev["WaterCount/CW99start"] = ps["CW99"]; // значение счетчика на начало месяца
            dev["WaterCount/HW100start"] = ps["HW100"]; // значение счетчика на начало месяца
            dev["WaterCount/CW100start"] = ps["CW100"]; // значение счетчика на начало месяца
        }
          timer_id = null;   
       	}, timer);
  }
});
}

После сохранения скрипта мне присваиваются какие-то левые цифры отличающиеся от тех что я наблюдаю в WUI. Завтра проверю, по идее после инкремента текущие показания должны стать корректными, но вот показаний на начало месяца будут постоянно сбиваться при перезагрузке контроллера и расход месячный будет явно кривой.

Все таки хотелось бы разобраться почему при перезагрузки скрипта/WB сбрасываются значения у контролов виртуального устройства и как это победить.

Возможно я вас не понял - поправьте меня.

Вот тут значения уже в хранилище.
При объявлении виртуального устройства ( а объявлять его надо после инициализации хранилища) надо сразу указывать значения так:

 "HW99": {//ГВС кв99
	    type: "value",
	    value: ps["HW99"],
        format: "u32",
        readonly: false
	    },

Все равно не понимаю, сделал следующий скрипт

var ps = new PersistentStorage("my-storage", { global: true });

ps["HW99"]; // ГВС 99
ps["CW99"]; // ХВС 99
ps["HW100"]; // ГВС 100
ps["CW100"]; // ХВС 100

log.info("HW99 = " + ps["HW99"]);
log.info("CW99 = " + ps["HW99"]);
log.info("HW100 = " + ps["HW100"]);
log.info("CW100 = " + ps["CW100"]);

defineVirtualDevice("WaterCount", {
    title: "WaterCount",
    cells: {
      "HW99": {//ГВС кв99
	    type: "value",
	    value: ps["HW99"],
        format: "u32",
        readonly: false
	    },
      "CW99": {//ХВС кв99
	    type: "value",
	    value: ps["CW99"],
        format: "u32",
        readonly: false       
	    },
      "HW100": {//ГВС кв100
	    type: "value",
	    value: ps["HW100"],
        format: "u32",
        readonly: false,
        forceDefault: false,        
	    },
      "CW100": {//ХВС кв100
        type: "value",
        value: ps["CW100"],
        format: "u8",
        readonly: false        
	    },
      "HW99start": {//ГВС кв99 начало месяца
	    type: "value",
	    value: 4700,
        format: "u32",
        readonly: false        
	    },
      "CW99start": {//ХВС кв99 начало месяца
	    type: "value",
	    value: 3110,
        format: "u32",
        readonly: false       
	    },
      "HW100start": {//ГВС кв100 начало месяца
	    type: "value",
	    value: 220,
        format: "u32",
        readonly: false       
	    },
      "CW100start": {//ХВС кв100 начало месяца
	    type: "value",
	    value: 660,
        format: "u32",
        readonly: false      
	    }
	}
});

function WaterCount(name, control, virt, count) {
defineRule(name, { 
  whenChanged: control, //при новом импульсе
  then: function (newValue, devName, cellName) { //выполняй следующие действия
    if (newValue) {
    	ps[count] += 10;
      	//dev[virt][count] = ps[cont]; // прибавляем +10 т.к. импульс это десятки, а не единица у счетчика
	    log.info("WaterCount.js : " + name + "   count = " + dev[virt][count]);
    }
  }
});
}

WaterCount("CW99Count", "wb-gpio/EXT2_IN6","WaterCount", "CW99");
WaterCount("HW99Count", "wb-gpio/EXT2_IN7", "WaterCount","HW99");
WaterCount("CW100Count","wb-gpio/EXT2_IN9","WaterCount","CW100");
WaterCount("HW100Count","wb-gpio/EXT2_IN8","WaterCount","HW100");

// проверка смены месяца и фиксация показаний на начало месяца
function resetStartMonth(name) {
var timer = 70*1000; // таймер на 70 секунд
var timer_id = null;
  
defineRule(name, {
  when: cron ("0 59 23 * *"), //запускаем таймер в 23-59, время согласно date формат 0 ММ ЧЧ * *
  then: function (){
		var date1 = new Date ();
      	if (timer_id) {
          clearTimeout(timer_id); //сброс таймера
        }
    
        timer_id = setTimeout(function () { //запускаем таймер на 70 секунд чтобы посмотреть дату позже
		var date2 = new Date ();
        if (date1.getMonth() != date2.getMonth()) // если месяцы в датах разные, т.е. наступил новый месяц
        {
            log.info("WaterCount.js : Установка начало отсчета месяца, текущие значения HW99start = " + dev["WaterCount/HW99"] + "  CW99start =  " + dev["WaterCount/CW99"] + "  HW100start =  " + dev["WaterCount/HW100"] + "  CW100start = " + dev["WaterCount/CW100"]);
          	dev["WaterCount/HW99start"] = ps["HW99"]; // значение счетчика на начало месяца
            dev["WaterCount/CW99start"] = ps["CW99"]; // значение счетчика на начало месяца
            dev["WaterCount/HW100start"] = ps["HW100"]; // значение счетчика на начало месяца
            dev["WaterCount/CW100start"] = ps["CW100"]; // значение счетчика на начало месяца
        }
          timer_id = null;   
       	}, timer);
  }
});
}

Причем пришлось в этом же скрипте объявлять хранилище, т.к. в другом файле глобальное объявление не помогало и скрипт в котором я присваиваю значения виртуальному контролу выдавал ошибку.

И так если запускаю этот скрипт, в девайсах и mqtt топиках вижу следующее:

изображение , другие контролы в топиках mqtt не появились. Удалял виртуальное устройство в том числе с очисткой retained - не помогает.

Но! Если завести новое устройство например Water_Count все работает как следует.
Где что нужно почистить чтобы скрипт работал? И еще вопрос - а как удалить/почистить/ понять содержимое хранилища?

В другом - объявляем, в следующем используем.
Проверил, работает.

Хранилище расположено тут:
/var/lib/wirenboard/wbrules-persistent.db
Можно просто удалить файл и перезапустить wb-rules

Здравствуйте!

Объявлять хранилище нужно в каждом файле. Но если оно уже было создано ранее, то к нему будет просто получен доступ.

var ps = new PersistentStorage(“my-storage”, { global: true });`

Не забывайте инициализировать переменные до первого использования.

Вот тут, наверное, ошибка. HW99 нужно заменить на CW99.