Проблема с require и виртуальным устройством

Здравствуйте, возникла задача описать виртуальное устройство как функцию в одном файле, а использовать его в другом. Реализация файла с виртуальном устройством такая:

function floor(in_name, in_titleName, in_deviceName, in_channelSwitch1, in_channelSwitch2) {
  this.name = in_name;
  this.deviceName = in_deviceName;
  this.channelSwitch1 = in_channelSwitch1;
  this.channelSwitch2 = in_channelSwitch2;
  
  defineVirtualDevice (in_name,{

  title: in_titleName, 
  cells: {
      switch: {
          type: "switch",
          value: false,
          enum:{
              0: {"en": "CLOSE", "ru": "Закр"},
              1: {"en": "OPEN", "ru": "Отк"},
          }
      },

      status: {
        type: "switch",
        value: false,
        readonly: true,
      },
    }
  });

    defineRule ({
    whenChanged: in_name + "/switch",
    then: function(newValue, devName, cellName) {
      dev[in_deviceName][in_channelSwitch1] = newValue;
      dev[in_deviceName][in_channelSwitch1] = newValue;
    }
  });

    defineRule ({
    whenChanged: in_deviceName + "/" + in_channelSwitch1,
    then: function(newValue, devName, cellName) {
      dev[in_name]["switch"] = newValue;
      dev[in_name]["status"] = newValue;
    }
  });
}

Реализация вызова:

var implfloor_file = require("floor_valves").floor();

var floor_kid1 = new implfloor_file("floor_kid1", "Клапан коллектора детской 1", "wb-mio-gpio_11:1", "DIR1", "ON1");

Ошибка:
Error: error error (rc -100)
anon native strict preventsyield
require native strict preventsyield
F /etc/wb-rules/test_for_lightning_with_brightness.js:356 preventsyield
На 356 стоке вызов представленный выше.

Добрый день.
Если описываете модуль - то я не вижу где явно определяются его публичные функции.

Ну, нет, конструкция “require(“floor_valves”).floor();” - не будет работать, поскольку в объекте “модуль” нет описанного элемента.
Посмотрите в документацию: GitHub - wirenboard/wb-rules: Rule engine for Wiren Board

Здравствуйте, спасибо за ответ, попробовал сделать как в документации:

var exports.floor = function (in_name, in_titleName, in_deviceName, in_channelSwitch1, in_channelSwitch2) {
  this.name = in_name;
  this.deviceName = in_deviceName;
  this.channelSwitch1 = in_channelSwitch1;
  this.channelSwitch2 = in_channelSwitch2;
...

Тут ошибка и в исполняемом файле тоже. Не совсем понял, про публичные функции, как их правильно объявить?
Вызов:

var  floor_kid1 = require("floor_valves");

floor_kid1.floor = ("floor_kid1", "Клапан коллектора детской 1", "wb-mio-gpio_11:1", "DIR1", "ON1");

Я не понимаю, к сожалению что хотите описать. Объявляете переменной функцию?

Я написал так как написано было в документации:


Цель: описать виртуальный клапан коллектора так, чтобы параметры можно было загружать в него из другого правила. Это другое правило будет главным и из него будет передаваться все ссылки на коллекторы, которые будут потом занесены в виртуальную комнату.

Проверяю пример из документации.
Создаю модуль 10_21_test_01.js с содержимым

exports.testFunction function(inText){
  log.info("Fom module:",inText);
}

Описываю вызов так:

//10_21_test_01.js

var testModule = require("10_21_test_01");

testModule.testFunction("Hello world!")

Получаю ожидаемое:

Проверил Ваш код:


Дело может быть в контролере?

Покажите пожалуйста команды, которыми создаете файл модуля (ну и атрибуты файла заодно).

Файл модуля создаю из веб интерфейса (если я правильно всё понял). А вот как открыть атрибуты файла я не знаю, подскажите пожалуйста.

Да, проверил без exports, ошибок нет.


Если это то

Файлы модуля следует создавать по пути /etc/wb-rules-modules - как описано в документации

1 лайк

Да, пока к сожалению, не сделали возможности создания и редактирования файлов модуля из веб интерфейса, только подключение к контроллеру по ssh, включая облако WB (там есть файловый менеджер)

Спасибо за подсказку, мне удобно WinSCP использовать

Так и сделал, ещё такой вопрос, возможно ли из одного модуля вызвать другой модуль?
При вызове выводит ошибку: SyntaxError: unterminated statement (line 1)
Вызов:

var workspaceLight = require("allLight").namespaceLightgroup();

Да, можно конечно.

Я не понимаю часть после точки, к сожалению.
У require() нет методов и свойств.

Да, можно конечно.

Подскажите пожалуйста как это сделать, попробовал несколько вариантов и получил ошибки.
var workspaceLight = require(“allLight”).namespaceLightgroup();
После точки, это название функции, которую я хочу вызывать из файла allLight

Зачем имено так?
Метод require совершенно стандартный для JS. Как пример: Node.js Modules
Прочитайте пожалуйста документацию к языку.

1 лайк

Во время тестов возник такой вопрос: как получить данные массива в модуле и записать их в модуль? У меня есть модуль комнаты, которая состоит из массивов света, штор, тёплых полов и тд, когда я добавляю свет в массив света абстрактной комнаты:

var workspaceRoom = require("Room");

var svet_test1_1 = workspaceLight.lightGroup("group1-1123123", "group1-1123123", "sdss", "*", "K1");

var room_test = workspaceRoom.Room("250", "garage", 1);
log(workspaceRoom.Room()); // undefined
  rooms.push(room_test);
  workspaceRoom.bindItem({
    device: svet_test1_1,
    type: workspaceRoom.light,
  });

  var scene_test = workspaceScene.Scene("scene_test");
log("это комната " + room_test);  // выводит: это комната undefined
room_test.workspaceRoom.aLightGroups.forEach(function(item){ // тут возникает ошибка unvalid base value
  scene_test.workspaceScene.bindItem(item);
});

Файл модуля комнаты:

function Room(name, tittle, priority){
  var light = 1;
  var blind = 2;
  var thermostat = 3;
  var floorValves = 4;
  var batValves = 5;
  var termometers = 6;
  this.temperatureActual = 0;
  this.temperatureSetpoint = 22;
  this.aLightGroups = new Array();
  this.aBlindGroups = new Array();
  this.aThermostats = new Array();
  this.aFloorValves = new Array();
  this.aBatValves = new Array();
  this.aTermometers = new Array();
  this.name = name || "";
  this.tittle = tittle || "";
};

Room.prototype.bindBatValves = function(item){
  this.aBatValves.push(item); 
  }; 

Room.prototype.openBatValves = function(item){
  this.aBatValves.forEach(item, function(){
    this.aBatValves.channelSwitch1 = false;
  });
};

Room.prototype.closeBatValves = function(item){
  this.aBatValves.forEach(item, function(){
    this.aBatValves.channelSwitch1 = true;
  });
};

Room.prototype.bindFloorValves = function(item){
  this.aFloorValves.push(item); 
  }; 

Room.prototype.openFloorValves = function(item){
  this.aFloorValves.forEach(item, function(){
    this.aFloorValves.channelSwitch1 = true;
  });
};

Room.prototype.closeFloorValves = function(item){
  this.aFloorValves.forEach(item, function(){
    this.aFloorValves.channelSwitch1 = false;
  });
};


Room.prototype.setpoint = function(item){
  var set_point = 22;
  if (this.aThermostats.length == 0)
    {
      return 0;
    };
    this.aThermostats.forEach(item, function()
  {
    set_point = item;
  });
  this.temperatureSetpoint = set_point;
  var climatController = require("climat_controller");
  climatController.control(this, set_point, this.temperatureActual);
};

Room.prototype.calculate = function(item){
  var temp_sum = 0;
  var average_temp = 0;
  if (this.aThermostats.length == 0)
  {
    return 0;
  };
  this.aThermostats.forEach(item, function()
  {
    temp_sum += item;
  });
  this.temperatureActual = temp_sum / this.aThermostats.length;
  var climatController = require("climat_controller");
  climatController.control(this, set_point, this.temperatureActual);

};

Room.prototype.bindItem = function(item){
  switch (item.type){
    case this.light:
      this.aLightGroups.push(item.device);
      break;
    case this.blind:
      aBlindGroups.push(item.device);
      break;
    case this.thermostat:
      this.aThermostats.push(item.device);
      break;
    case this.floorValves:
      this.aFloorValves.push(item.device);
      break;
    case this.batValves:
      this.aBatValves.push(item.device);
    case this.termometers:
      this.aTermometers.push(item.device);
  }
};

exports.Room = Room;
exports.addRoom = Room.prototype.addRoom;
exports.bindBatValves = Room.prototype.bindBatValves;
exports.openBatValves = Room.prototype.openBatValves;
exports.closeBatValves = Room.prototype.closeBatValves;
exports.bindFloorValves = Room.prototype.bindFloorValves;
exports.openFloorValves = Room.prototype.openFloorValves;
exports.closeFloorValves = Room.prototype.closeFloorValves;
exports.setpoint = Room.prototype.setpoint;
exports.calculate = Room.prototype.calculate;
exports.bindItem = Room.prototype.bindItem;

Почему так происходит? Почему не получается в массив света комнаты записать свет?