KNX demo-stand: различия между версиями

6994 байта добавлено ,  3 года назад
Строка 131: Строка 131:


== Правила wb-rules ==
== Правила wb-rules ==
Зайдите в веб интерфейс контроллера и создайте новое правило во вкладке "Scripts".
=== Вспомогательное правило для KNX ===
Вспомогательное правило помогает избежать лишних действий при работе с KNX. При получении посылки в топик "knx/data" данные парсятся и раскладываются по топикам. Для каждого группового адреса создается отдельный контрол. При изменении этого контрола данные так же отправляются обратно в топик "knx/data" для отправки на шину KNX. В объекте knx_vdev_obj мы можем явно указать заранее известные групповые адреса и задать им необходимый тип.
<syntaxhighlight lang="ecmascript">
(function() {
    var knx_vdev_obj = {
        title: "KNX Group Addresses",
        cells: {
          "1-1-1": {
                type: "value",
                value: "0"
            },
          "1-1-2": {
                type: "switch",
                value: false
            },
          "1-1-3": {
                type: "range",
                max: 255,
                value: 0,
                knx_type: "wide"
            },
            "1-1-6": {
                type: "switch",
                value: false
            },
          "1-1-7": {
                type: "value",
                value: "0"
            },
          "1-1-8": {
                type: "value",
                value: "0"
            },
          "1-1-9": {
                type: "value",
                value: "0"
            },
            "1-1-10": {
                type: "switch",
                value: false
            },
            "1-1-11": {
                type: "switch",
                value: false
            },
          "1-1-12": {
                type: "value",
                value: "0"
            },
            "1-1-13": {
                type: "value",
                value: 0,
                knx_type: "wide"
            }
        }
    };
    var vdev_when_changed = [];
    var vdev_devid = "knx_group_addrs";
    for (var control_id in knx_vdev_obj.cells) {
        if (knx_vdev_obj.cells.hasOwnProperty(control_id)) {
            vdev_when_changed.push("knx_group_addrs/" + control_id);
        }
    }
    defineVirtualDevice(vdev_devid, knx_vdev_obj);
    defineRule("knx_vdev_feedback", {
        whenChanged: vdev_when_changed,
        then: function(newValue, devName, cellName) {
            var group_address = cellName.split("-").join("/");
            var value = +newValue;
            var write_str = "";
            if (knx_vdev_obj.cells[cellName].knx_type == "wide") {
                while (value > 0) {
                    var rem = value % 256;
                    value = Math.floor(value / 256);
                    write_str = rem + " " + write_str;
                }
                write_str = "0 " + write_str;
            } else {
                write_str = "" + value;
            }
            if (write_str) {
                dev["knx/data"] = "g:{} GroupValueWrite {}".format(group_address, write_str);
            }
        }
    });
    defineRule("knx_vdev_incoming", {
        whenChanged: "knx/data",
        then: function(newValue, devName, cellName) {
            var arr = newValue.split(/\s/);
            var sourceAddr = arr[0].split(/i\:|\,/);
            var groupAddr = arr[1].split(/g\:|\,/);
            var arr1 = newValue.split(/GroupValueWrite/);
            var value = arr1[1];
            if ((sourceAddr[1] == "0/0/0") || (sourceAddr[1] == "1/1/255")) { // skip local echo
                return;
            }
            dev[vdev_devid][groupAddr[1].split("/").join("-")] = parseInt(value, 16);
        }
    });
 
})()
function knxConvertToFloat16(value) {
    var sign = 0;
    var exp = 0;
    if (value < 0) {
        sign = 1;
    }
    var mant = Math.floor(value * 100);
    while ((mant < -2048) || (mant > 2047)) {
        mant = mant >> 1;
        exp += 1
    }
    var data = (sign << 15) | (exp << 11) | (mant & 0x07ff);
    return data;
};
</syntaxhighlight>
=== Основное правило ===
<syntaxhighlight lang="ecmascript">
(function() {
    var channel_pairs = [
        ["knx_group_addrs/1-1-10", "wb-gpio/EXT1_R3A1"],
        ["knx_group_addrs/1-1-11", "wb-mr3_139/K1"]
    ];
    function makePairRules(chan1, chan2) {
        defineRule("channel_pair_follow_" + chan1 + "_" + chan2, {
            whenChanged: chan1,
            then: function(newValue, devName, cellName) {
                dev[chan2] = newValue;
            }
        });
    };
    for (var i = 0; i < channel_pairs.length; ++i) {
        var chan1 = channel_pairs[i][0];
        var chan2 = channel_pairs[i][1];
        makePairRules(chan1, chan2);
        makePairRules(chan2, chan1);
    }
    defineRule("hdl_panel_set_temp", {
        whenChanged: "wb-w1/28-041643cee6ff",
        then: function(newValue, devName, cellName) {
            dev["knx_group_addrs/1-1-13"] = knxConvertToFloat16(newValue + 2);
        }
    });
    defineRule("dimmer_chan1", {
        whenChanged: "knx_group_addrs/1-1-7",
        then: function(newValue, devName, cellName) {
          if(newValue == 11){
            dev["wb-mdm2_1/Channel 1"] = Math.min(dev["wb-mdm2_1/Channel 1"] + 10, 100);
          } else if(newValue == 3) {
            dev["wb-mdm2_1/Channel 1"] = Math.max(dev["wb-mdm2_1/Channel 1"] - 10, 0);
          }
        }
    });
    defineRule("hdl_dimmer_chan1_on_off", {
        whenChanged: "wb-gpio/EXT2_DR1",
        then: function(newValue, devName, cellName) {
            if (newValue) {
                dev["knx_group_addrs/1-1-2"] = !dev["knx_group_addrs/1-1-2"];
            }
        }
    });
    defineRule("dimmer_chan1_on_off", {
        whenChanged: "wb-gpio/EXT2_DR2",
        then: function(newValue, devName, cellName) {
            if (newValue) {
              dev["knx_group_addrs/1-1-6"] = !dev["knx_group_addrs/1-1-6"]
            }
        }
    });
  defineRule("dimmer_chan1_on_off_knx", {
        whenChanged: "knx_group_addrs/1-1-6",
        then: function(newValue, devName, cellName) {
            if(newValue){
              dev["wb-mdm2_1/Channel 1"] = 70;
            } else {
              dev["wb-mdm2_1/Channel 1"] = 0;
            }
        }
    });
})();
function knxConvertToFloat16(value) {
    var sign = 0;
    var exp = 0;
    if (value < 0) {
        sign = 1;
    }
    var mant = Math.floor(value * 100);
    while ((mant < -2048) || (mant > 2047)) {
        mant = mant >> 1;
        exp += 1
    }
    var data = (sign << 15) | (exp << 11) | (mant & 0x07ff);
    return data;
};
</syntaxhighlight>
547

правок