Движок правил wb-rules 1.7: различия между версиями

Материал из Wiren Board
 
(не показано 13 промежуточных версий 4 участников)
Строка 1: Строка 1:
В обновлённом движке правил wb-rules присутствует ряд важных нововведений, касающихся логики написания сценариев.
<languages/>
<translate>


= Сценарии =
== Изоляция сценариев == <!--T:3-->


== Изоляция сценариев ==
<!--T:4-->
Начиная с версии wb-rules 1.7, локальные переменные и функции, обьявленные в файле сценария не видны в других сценариях.
Таким образом, каждый сценарий может определять свои функции и переменные без риска изменить поведение других сценариев.


Начиная с версии wb-rules 1.7, каждый файл сценария запускается в своём отдельном пространстве имён - '''контексте'''. Таким образом, каждый сценарий может определять
=== Пример === <!--T:5-->
свои функции и глобальные переменные без риска изменить поведение других сценариев.


=== Пример ===
<!--T:6-->
В качестве примера приведём два сценария, одновременно запускаемых в движке правил.
В качестве примера приведём два сценария, одновременно запускаемых в движке правил.
Каждый сценарий определяет глобальные переменные и функции.
Каждый сценарий определяет переменные и функции.


В предыдущих версиях wb-rules обращение к глобальной переменной, изменяемой в нескольких
<!--T:7-->
В предыдущих версиях wb-rules обращение к переменной, изменяемой в нескольких
файлах сценариев, может привести к неопределённому поведению. В версиях, начиная с 1.7,
файлах сценариев, может привести к неопределённому поведению. В версиях, начиная с 1.7,
поведение строго определено и такое же, как будто сценарий единственный в системе.
поведение строго определено и такое же, как будто сценарий единственный в системе.


В комментариях указан вывод команд log для ранних версий и для актуальной версии.
<!--T:8-->
В комментариях указан вывод команд log для ранних версий и для актуальной версии. Обратите внимание на var перед переменными.


<!--T:9-->
'''Сценарий 1 (rules1.js)'''
'''Сценарий 1 (rules1.js)'''
<syntaxhighlight lang="js">
<syntaxhighlight lang="js">
test1 = 42;
var test1 = 42;


setTimeout(function myFuncOne() {
<!--T:10-->
setInterval(function myFuncOne() {
     log("myFuncOne called");
     log("myFuncOne called");
     log("test1: {}, test2: {}", test1, test2);
     log("test1: {}", test1);
     // раньше: test1: [либо 42, либо 84], test2: Hello
     log("test2: {}", test2);
    // теперь: test1: 42, test2: (undefined)
}, 5000);
    // (будет выведена ошибка выполнения: ReferenceError: identifier 'test2' undefined)
}, 1000);
</syntaxhighlight>
</syntaxhighlight>


<!--T:11-->
'''Сценарий 2 (rules2.js)'''
'''Сценарий 2 (rules2.js)'''
<syntaxhighlight lang="js">
<syntaxhighlight lang="js">
test1 = 84;
var test1 = 84;
test2 = "Hello";
var test2 = "Hello";


setTimeout(function myFuncTwo() {
<!--T:12-->
setInterval(function myFuncTwo() {
     log("myFuncTwo called");
     log("myFuncTwo called");
     log("test1: {}, test2: {}", test1, test2);
     log("test1: {}, test2: {}", test1, test2);
    // раньше: test1: [либо 42, либо 84], test2: Hello
}, 5000);
    // теперь: test1: 84, test2: Hello
}, 1000);
</syntaxhighlight>
</syntaxhighlight>


=== Примечание ===
<!--T:13-->
Было:
<pre>
2019-01-05 17:29:50myFuncTwo called
2019-01-05 17:29:50test1: 84, test2: Hello
2019-01-05 17:29:50myFuncOne called
2019-01-05 17:29:50test1: 84
2019-01-05 17:29:50test2: Hello
 
<!--T:14-->
</pre>
 
<!--T:15-->
Стало:
<pre>
2019-01-05 17:28:42myFuncTwo called
2019-01-05 17:28:42test1: 84, test2: Hello
2019-01-05 17:28:42myFuncOne called
2019-01-05 17:28:42test1: 42
2019-01-05 17:28:42ECMAScript error: ReferenceError: identifier 'test2' undefined
duk_js_var.c:1232
myFuncOne /etc/wb-rules/rules1.js:6 preventsyield
</pre>


=== Примечание === <!--T:16-->
<!--T:17-->
В предыдущих версиях wb-rules для изоляции правил рекомендовалось использовать замыкание, т.е.  
В предыдущих версиях wb-rules для изоляции правил рекомендовалось использовать замыкание, т.е.  
оборачивание кода сценария в конструкцию:
оборачивание кода сценария в конструкцию:
Строка 54: Строка 83:
</syntaxhighlight>
</syntaxhighlight>


Начиная с версии 1.7, в подобной конструкции нет необходимости. Тем не менее, старые сценарии,
<!--T:18-->
Начиная с версии 1.7, в подобной конструкции обычно нет необходимости. Тем не менее, старые сценарии,
использующие эту конструкцию, продолжат работу без изменений в поведении.
использующие эту конструкцию, продолжат работу без изменений в поведении.


=== Обходные пути ===
=== Обходные пути === <!--T:19-->


<!--T:20-->
Если в вашей системе использовалось общее глобальное пространство для хранения общих данных и функций,
Если в вашей системе использовалось общее глобальное пространство для хранения общих данных и функций,
есть несколько способов реализации такого поведения:
есть несколько способов реализации такого поведения:


==== Виртуальные устройства ====
==== Постоянное хранилище ==== <!--T:21-->
 
В простых случаях удобно использовать виртуальные устройства для обмена данными. Такие механизмы
просто отлаживаются (состояние виртуального устройства всегда можно посмотреть в web-интерфейсе), а
также легко создаётся реакция на изменения параметров (с помощью правил). (Подробнее - см. Виртуальные устройства).
 
==== Использование модулей ====
 
Можно написать модуль для организации взаимодействия. У модулей есть статическое хранилище,
общее для всех файлов, импортировавших модуль. (см. [[#Модули|Модули]])
 
==== Постоянное хранилище ====


<!--T:22-->
Для обмена данными также можно использовать глобальные постоянные хранилища (PersistentStorage).
Для обмена данными также можно использовать глобальные постоянные хранилища (PersistentStorage).


<!--T:23-->
'''Внимание:''' при использовании глобальных постоянных хранилищ может произойти совпадение имён, в  
'''Внимание:''' при использовании глобальных постоянных хранилищ может произойти совпадение имён, в  
этом случае возможно труднообнаруживаемое нарушение поведения.
этом случае возможно труднообнаруживаемое нарушение поведения.


<!--T:24-->
<syntaxhighlight lang="js">
<syntaxhighlight lang="js">
var ps = new PersistentStorage("my-global-storage", {global: true});
var ps = new PersistentStorage("my-global-storage", {global: true});


<!--T:25-->
/// ...
/// ...


<!--T:26-->
ps.myvar = "value"; // это значение доступно для всех пользователей хранилища с именем "my-global-storage"
ps.myvar = "value"; // это значение доступно для всех пользователей хранилища с именем "my-global-storage"
</syntaxhighlight>
</syntaxhighlight>


==== Прототип глобального объекта ====
==== Прототип глобального объекта ==== <!--T:27-->


<!--T:28-->
'''ВНИМАНИЕ:''' метод считается "грязным", т.к. все переменные и функции, опубликованные таким образом,
'''ВНИМАНИЕ:''' метод считается "грязным", т.к. все переменные и функции, опубликованные таким образом,
становятся доступными всем сценариям в системе. Старайтесь избегать этого способа. За неопределённое
становятся доступными всем сценариям в системе. Старайтесь избегать этого способа. За неопределённое
поведение при использовании этого метода несёт ответственность сам программист.
поведение при использовании этого метода несёт ответственность сам программист.


<!--T:29-->
Глобальные объекты всех сценариев имеют общий объект-''прототип'', в котором определены стандартные функции
Глобальные объекты всех сценариев имеют общий объект-''прототип'', в котором определены стандартные функции
wb-rules (такие, как defineRule, setTimeout и т.д.). Через него можно передавать переменные или функции
wb-rules (такие, как defineRule, setTimeout и т.д.). Через него можно передавать переменные или функции
в общую область видимости.
в общую область видимости.


<!--T:30-->
<syntaxhighlight lang="js">
<syntaxhighlight lang="js">
global.__proto__.myVar = 42; // теперь myVar - общая переменная для всех сценариев
global.__proto__.myVar = 42; // теперь myVar - общая переменная для всех сценариев


<!--T:31-->
// из других сценариев к переменной можно обращаться так
// из других сценариев к переменной можно обращаться так
log("shared myVar: {}", myVar);
log("shared myVar: {}", myVar);


<!--T:32-->
// или вот так, что чуть более аккуратно, т.к. однозначно показывает, где определена переменная
// или вот так, что чуть более аккуратно, т.к. однозначно показывает, где определена переменная
log("shared myVar: {}", global.__proto__.myVar);
log("shared myVar: {}", global.__proto__.myVar);
</syntaxhighlight>
</syntaxhighlight>


<!--T:33-->
Правило поиска переменной в первом случае будет выглядеть так:
Правило поиска переменной в первом случае будет выглядеть так:


<!--T:34-->
# Проверяем, есть ли myVar среди локальных переменных (определённой как var myVar = ...).
# Проверяем, есть ли myVar среди локальных переменных (определённой как var myVar = ...).
# Если нет, проверяем, есть ли myVar в глобальном объекте (определённой как myVar = ...).
# Если нет, проверяем, есть ли myVar в глобальном объекте (определённой как myVar = ...).
# Если нет, проверяем, есть ли myVar в ''прототипе'' глобального объекта (определённой как global.__proto__.myVar).
# Если нет, проверяем, есть ли myVar в ''прототипе'' глобального объекта (определённой как global.__proto__.myVar).


<!--T:35-->
Поиск останавливается, как только переменная найдена.
Поиск останавливается, как только переменная найдена.


<!--T:36-->
Таким образом, первый способ обращения будет работать только в том случае, если myVar не определена в верхних областях видимости.
Таким образом, первый способ обращения будет работать только в том случае, если myVar не определена в верхних областях видимости.


== Анонимные правила ==
== Постоянное хранилище данных == <!--T:37-->
 
Теперь правила можно объявлять анонимно (без задания специального имени). Это позволит уменьшить путаницу и неочевидное
поведение системы при дублировании имён правил в одном скрипте.
 
Уникальные имена для анонимных правил генерируются автоматически.
 
Старый синтаксис (с явным заданием имени правила) продолжит работу без изменений.
 
'''ВНИМАНИЕ:''' начиная с версии 1.7, при объявлении правил с одинаковыми
именами в одном файле теперь будет возвращаться ошибка.
 
=== Пример ===
 
<syntaxhighlight lang="js">
defineRule({
    whenChanged: "mydev/test",
    then: function() {
        log("mydev/test changed");
    }
});
</syntaxhighlight>
 
== Управление правилами ==
 
В wb-rules 1.7 также появляется возможность управлять выполнением правил. Теперь функция defineRule() возвращает идентификатор
созданного правила (аналогично setTimeout()/setInterval() ), который можно использовать позже для:
 
* выключения/включения отработки правила;
* принудительного запуска тела правила.
 
По умолчанию, все правила включены.
 
=== Пример ===
 
<syntaxhighlight lang="js">
var myRule = defineRule({
    whenChanged: "mydev/test",
    then: function() {
        log("mydev/test changed");
    }
});
 
// ...
 
disableRule(myRule); // отключить проверку и выполнение правила
enableRule(myRule); // разрешить выполнение правила
 
runRule(myRule); // принудительно запустить тело правила (функцию then)
// на текущий момент не поддерживается передача аргументов в then
</syntaxhighlight>
 
== Постоянное хранилище данных ==


<!--T:38-->
В wb-rules 1.7 добавлена поддержка постоянных хранилищ. По сути, это объекты, значения в которых будут сохраняться
В wb-rules 1.7 добавлена поддержка постоянных хранилищ. По сути, это объекты, значения в которых будут сохраняться
даже при потере питания контроллера. Такие хранилища удобно использовать для хранения состояний или конфигурации.
даже при потере питания контроллера. Такие хранилища удобно использовать для хранения состояний или конфигурации.


<!--T:39-->
<syntaxhighlight lang="js">
<syntaxhighlight lang="js">
var ps = new PersistentStorage("my-storage");
var ps = new PersistentStorage("my-storage", { global: true });


<!--T:40-->
ps.key = "Hello World";
ps.key = "Hello World";
log(ps.key);
log(ps.key);
</syntaxhighlight>
</syntaxhighlight>


По умолчанию, хранилища создаются локальными для данного файла сценария. Таким образом, при создании хранилищ с
<!--T:41-->
одинаковыми именами в разных файлах сценариев, создастся два разных хранилища (и сценарий не получит
Поддерживаются только глобальные хранилища, т.е. видимые по одному и тому же имени из всех файлов сценариев.
доступа к "чужим" данным).
 
Однако, есть возможность создавать глобальные хранилища. Для этого нужно добавить аргумент { global: true } в
вызов конструктора:
 
<syntaxhighlight lang="js">
var ps = new PersistentStorage("my-storage", { global: true });
</syntaxhighlight>
 
Если такое хранилище уже было создано когда-либо ранее, сценарий получит к нему доступ.
 
= Модули =
Начиная с версии 1.7, в движке правил wb-rules появилась поддержка подключаемых JS-модулей (похожая по поведению на
аналогичную в Node.js, но с некоторыми особенностями).
 
== Расположение ==
Поиск модулей происходит по следующим путям (в заданном порядке):
 
* /etc/wb-rules/modules
* /usr/share/wb-rules/modules
 
Таким образом, пользовательские модули удобно складывать в /etc/wb-rules.
 
Добавить свои пути можно редактированием /etc/default/wb-rules добавлением путей
к переменной WB_RULES_MODULES через разделитель (:):
 
<syntaxhighlight lang="bash">
...
WB_RULES_MODULES="/etc/wb-rules/modules:/usr/share/wb-rules/modules"
...
</syntaxhighlight>
 
== Подключение модуля к сценарию ==
 
Подключение модуля происходит с помощью функции require(). Она возвращает объект, экспортированный
модулем (exports).
 
<syntaxhighlight lang="js">
...
var myModule = require("myModule");
...
</syntaxhighlight>
 
При этом движок правил будет искать файл myModule.js по очереди в директориях поиска (см. Расположение).
 
Также допустим поиск файла модуля по поддиректориям в директориях поиска, тогда вызов будет выглядеть так:
 
 
<syntaxhighlight lang="js">
...
var myModule = require("path/to/myModule");
...
</syntaxhighlight>
 
После того, как файл будет найден, его содержимое будет выполнено, и из файла будет передан объект exports.
 
'''Примечание 1:''' если модуль был подключен в одном сценарии несколько раз (несколько вызовов require("myModule")),
содержимое файла модуля будет выполнено только в первый раз, а при повторных вызовах будет возвращаться сохранённый
объект exports.
 
'''Примечание 2:''' если модуль подключается в разных сценариях, для каждого сценария будет создан свой объект модуля
и заново выполнен весь код модуля. Если модулю требуется использовать данные, общие для всех файлов сценариев,
для хранения данных следует использовать объект module.static.
 
== Создание модуля ==
 
Для создания модуля достаточно создать файл с именем, соответсвующим имени модуля (с расширением .js) в директории
/etc/wb-rules/modules.
 
В этом файле будут доступны все стандартные функции wb-rules, а также набор специальных объектов, с помощью
которого можно реализовать необходимый функционал модуля.
 
=== Объект exports ===
 
С помощью объекта exports можно передавать пользовательскому сценарию параметры и методы.


==== Пример ====
== Виртуальные устройства == <!--T:42-->


Файл модуля /etc/wb-rules/modules/myModule.js
<!--T:43-->
<syntaxhighlight lang="js">
В предыдущих версиях wb-rules значения контролов виртуальных устройств хранились только в MQTT retained, что не очень надёжно (в случае
exports.hello = function(text) {
потери питания данные могли быть легко утеряны). Начиная с версии 2.0, эти значения сохраняются также в специальное хранилище в постоянной
    log("Hello from module, {}", text);
памяти и восстанавливаются при загрузке сценария.
};


exports.answer = 42;
<!--T:44-->
</syntaxhighlight>
Если необходимо каждый раз при перезагрузке скрипта восстанавливать строго определённое значение (т.е. не восстанавливать предыдущее сохранённое),
можно добавить в описание контрола поле forceDefault:


Файл сценария scenario.js
<!--T:45-->
<syntaxhighlight lang="js">
<syntaxhighlight lang="js">
var m = require("myModule");
defineVirtualDevice("vdev", {
m.hello("world"); // выведет в лог "Hello from module, world"
    ...
log("The answer is {}", m.answer); // выведет в лог "The answer is 42"
     cells: {
</syntaxhighlight>
        ...
 
        mycell: {
'''Будьте внимательны:''' объект exports можно '''только дополнять значениями''', но не переопределять.
            type: "value",
Иначе значения экспортированы не будут!
            value: "10",
 
            forceDefault: true // при каждой загрузке сценария поле mycell будет получать значение 10
<syntaxhighlight lang="js">
         }
exports = function(text) {
     log("Hello from module, {}", text);
};
 
// Ожидание:
var m = require("my-module");
m("world"); // не работает
 
// На практике m будет пустым объектом.
// Та же проблема произойдёт при использовании такой конструкции:
exports = {
    hello: function(text) {
        log("Hello from module, {}", world);
    },
    answer: 42
};
</syntaxhighlight>
 
=== Объект module ===
 
Объект module содержит параметры, относящиеся непосредственно к файлу модуля.
 
==== module.filename ====
Содержит полный путь до файла ''модуля''. Например, для модуля, сохранённого в /etc/wb-rules/modules/myModule.js:
 
<syntaxhighlight lang="js">
log(module.filename); // выведет /etc/wb-rules/modules/myModule.js
</syntaxhighlight>
 
==== module.static ====
Объект, хранящий данные, общие для всех экземпляров данного модуля. Его следует использовать для тех данных,
которые должны быть доступны сразу во всех сценариях, использующих данный модуль.
 
Файл /etc/wb-rules/modules/myModule.js
<syntaxhighlight lang="js">
exports.counter = function() {
    if (module.static.count === undefined) {
         module.static.count = 1;
     }
     }
    log("Number of calls: {}", module.static.count);
});
    module.static.count++;
};
</syntaxhighlight>
 
Файл сценария scenario1.js
<syntaxhighlight lang="js">
var m = require("myModule");
m.counter();
m.counter();
</syntaxhighlight>
 
Файл сценария scenario2.js
<syntaxhighlight lang="js">
var m = require("myModule");
m.counter();
m.counter();
m.counter();
</syntaxhighlight>
 
В результате работы двух скриптов в логе окажется 5 сообщений:
 
<syntaxhighlight>
Number of calls: 1
Number of calls: 2
Number of calls: 3
Number of calls: 4
Number of calls: 5
</syntaxhighlight>
 
=== __filename ===
 
Переменная __filename берётся из глобального объекта сценария, к которому подключается модуль, и содержит путь до файла
сценария.
 
В случае, если модуль подключается в другом модуле, переменная __filename, тем не менее, будет содержать именно
путь до файла сценария - вершины дерева зависимостей.
 
Файл /etc/wb-rules/modules/myModule.js
<syntaxhighlight lang="js">
exports.hello = function() {
    log(__filename);
};
</syntaxhighlight>
 
Файл сценария scenario1.js
<syntaxhighlight lang="js">
var m = require("myModule");
m.hello(); // выведет /etc/wb-rules/scenario1.js
</syntaxhighlight>
</syntaxhighlight>
</translate>

Текущая версия на 12:28, 17 марта 2021

Другие языки:

Изоляция сценариев

Начиная с версии wb-rules 1.7, локальные переменные и функции, обьявленные в файле сценария не видны в других сценариях. Таким образом, каждый сценарий может определять свои функции и переменные без риска изменить поведение других сценариев.

Пример

В качестве примера приведём два сценария, одновременно запускаемых в движке правил. Каждый сценарий определяет переменные и функции.

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

В комментариях указан вывод команд log для ранних версий и для актуальной версии. Обратите внимание на var перед переменными.

Сценарий 1 (rules1.js)

var test1 = 42;

setInterval(function myFuncOne() {
    log("myFuncOne called");
    log("test1: {}", test1);
    log("test2: {}", test2);
}, 5000);

Сценарий 2 (rules2.js)

var test1 = 84;
var test2 = "Hello";

setInterval(function myFuncTwo() {
    log("myFuncTwo called");
    log("test1: {}, test2: {}", test1, test2);
}, 5000);

Было:

2019-01-05 17:29:50myFuncTwo called
2019-01-05 17:29:50test1: 84, test2: Hello
2019-01-05 17:29:50myFuncOne called
2019-01-05 17:29:50test1: 84
2019-01-05 17:29:50test2: Hello

Стало:

2019-01-05 17:28:42myFuncTwo called
2019-01-05 17:28:42test1: 84, test2: Hello
2019-01-05 17:28:42myFuncOne called
2019-01-05 17:28:42test1: 42
2019-01-05 17:28:42ECMAScript error: ReferenceError: identifier 'test2' undefined
duk_js_var.c:1232
myFuncOne /etc/wb-rules/rules1.js:6 preventsyield

Примечание

В предыдущих версиях wb-rules для изоляции правил рекомендовалось использовать замыкание, т.е. оборачивание кода сценария в конструкцию:

(function() {
    // код сценария идёт здесь
})();

Начиная с версии 1.7, в подобной конструкции обычно нет необходимости. Тем не менее, старые сценарии, использующие эту конструкцию, продолжат работу без изменений в поведении.

Обходные пути

Если в вашей системе использовалось общее глобальное пространство для хранения общих данных и функций, есть несколько способов реализации такого поведения:

Постоянное хранилище

Для обмена данными также можно использовать глобальные постоянные хранилища (PersistentStorage).

Внимание: при использовании глобальных постоянных хранилищ может произойти совпадение имён, в этом случае возможно труднообнаруживаемое нарушение поведения.

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

/// ...

ps.myvar = "value"; // это значение доступно для всех пользователей хранилища с именем "my-global-storage"

Прототип глобального объекта

ВНИМАНИЕ: метод считается "грязным", т.к. все переменные и функции, опубликованные таким образом, становятся доступными всем сценариям в системе. Старайтесь избегать этого способа. За неопределённое поведение при использовании этого метода несёт ответственность сам программист.

Глобальные объекты всех сценариев имеют общий объект-прототип, в котором определены стандартные функции wb-rules (такие, как defineRule, setTimeout и т.д.). Через него можно передавать переменные или функции в общую область видимости.

global.__proto__.myVar = 42; // теперь myVar - общая переменная для всех сценариев

// из других сценариев к переменной можно обращаться так
log("shared myVar: {}", myVar);

// или вот так, что чуть более аккуратно, т.к. однозначно показывает, где определена переменная
log("shared myVar: {}", global.__proto__.myVar);

Правило поиска переменной в первом случае будет выглядеть так:

  1. Проверяем, есть ли myVar среди локальных переменных (определённой как var myVar = ...).
  2. Если нет, проверяем, есть ли myVar в глобальном объекте (определённой как myVar = ...).
  3. Если нет, проверяем, есть ли myVar в прототипе глобального объекта (определённой как global.__proto__.myVar).

Поиск останавливается, как только переменная найдена.

Таким образом, первый способ обращения будет работать только в том случае, если myVar не определена в верхних областях видимости.

Постоянное хранилище данных

В wb-rules 1.7 добавлена поддержка постоянных хранилищ. По сути, это объекты, значения в которых будут сохраняться даже при потере питания контроллера. Такие хранилища удобно использовать для хранения состояний или конфигурации.

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

ps.key = "Hello World";
log(ps.key);

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

Виртуальные устройства

В предыдущих версиях wb-rules значения контролов виртуальных устройств хранились только в MQTT retained, что не очень надёжно (в случае потери питания данные могли быть легко утеряны). Начиная с версии 2.0, эти значения сохраняются также в специальное хранилище в постоянной памяти и восстанавливаются при загрузке сценария.

Если необходимо каждый раз при перезагрузке скрипта восстанавливать строго определённое значение (т.е. не восстанавливать предыдущее сохранённое), можно добавить в описание контрола поле forceDefault:

defineVirtualDevice("vdev", {
    ...
    cells: {
        ...
        mycell: {
            type: "value",
            value: "10",
            forceDefault: true // при каждой загрузке сценария поле mycell будет получать значение 10
        }
    }
});