Knx dpt

Подскажите где и как можно подробнее понять по преобразование типов данных для knx. Сейчас беру данные например вольтажа с счетчика и засылаю в knx. Но что то приходит в knx не понятное. Завтра приложу больше данных.

Добрый день. Ну да, как минимум неплохо посмотреть отправляется ли что-то (что) подписавшись на топик

mosquitto_sub -v -t /devices/knx/#

а как эту подписку сделать? (с Wirenboard только знакомлюсь) и не вся терминология пока понятна.

Сейчас у меня работают 2 скрипта:

(function() {
    var knx_vdev_obj = {
        title: "KNX Group Addresses",
        cells: {
             "15-1-1": {
                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;
};

function convertfromKnx(value) {
var byte1 = "0x" + value[3] + value[4];
var byte2 = "0x" + value[8] + value[9];
var data = parseInt(byte1, 16) * 256 + parseInt(byte2, 16);
var sign = data >> 15;
var exponent = (data >> 11) & 0x0f;
var mantisse = data & 0x7ff;
if (sign) {
mantisse = -2048 + mantisse;
}
output = (mantisse * (Math.pow(2, exponent)) / 100);
return output;
};

и вот 2й:

var urms_L1 = "wb-map12e_67/Urms L1"; //Сохраним в переменной имя входа.
var urms_setMax = "230";
var k1 = "wb-mwac_15/K1";


defineRule("urms_to_KNX", { //название правила 
whenChanged: urms_L1, //при изменении указанного значения
  then: function (newValue, devName, cellName) { //выполняй следующие действия
    log.info("Напряжение", newValue, "В"); //Это лог.
    if (newValue) {
      dev ["knx_group_addrs/15-1-1"] = knxConvertToFloat16(newValue); // Передаем на KNX
      log.info("в KNX ", newValue);
    }
    if (newValue > urms_setMax) {  
  		log.info("Напряжение", newValue, "БОЛЬШЕ уставки", urms_setMax);
      	dev [k1] = true;
    }
      else  {  
  		log.info("Напряжение", newValue, "Меньше уставки", urms_setMax);
        dev [k1] = false;
      }
    
    }
});

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;
};

в логе “newValue” = 218.361

в шину KNX по мониторингу с ETS летит:

Вот тут:

надо исключать свой локальный адрес, в вашем случае это 5.10.Х

А тут неверно:

Надо в виртуальное устройство knx_group_addrs/15-1-1 передавать просто значение, оно сконвертится уже во втором скрипте.

dev ["knx_group_addrs/15-1-1"] = newValue; // Передаем на KNX

данные сразу перестали идти…

P.S. основной скрипт где параметры KNX первый а вот тот после него, из за этого? вот не хватает на странице скриптов: отключение скриптов, изменение очередности, копировать…

if ((sourceAddr[1] == "0/0/0") || (sourceAddr[1] == "5/10/250")) { // skip local echo

правильно понял?

есть кто ни будь))))

накопились вопросы:

  1. добавил в скрипте новые групповые адреса KNX:
        cells: {
            "15-1-2": {
                type: "switch",
                value: false
            },
            "15-1-1": {
                type: "voltage",
                value: 250.333,
                //knx_type: "voltage",
              	//readonly : true
            },
          	"15-1-3": {
                type: "voltage",
                value: 250.333,
                //knx_type: "voltage",
              	//readonly : true
            },
          	"15-1-15": {
                type: "temperature",
                scale: 0.1,
                value: 0
            }
        }

далее в другом скрипте:

    defineRule("hdl_panel_set_temp", {
        whenChanged: "hwmon/CPU Temperature",
        then: function(newValue, devName, cellName) {
            dev["knx_group_addrs/15-1-15"] = knxConvertToFloat16(newValue + 2); // Передаем в KNX температуру
          	log.info("Температура", newValue);
        }
    });

и в шине опять вижу неправильный тип…

проще говоря что бы не пытался передавать тип всегда битовый вкл/выкл…

2й момент.

всегда отправка идет с разных адресов устройства. на скриншоте выше это видно. что за?

Перестали идти куда? В топик knx пишется? Или не доходит до него в проверке условия? Подпишитесь на топик, посмотрите.

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

Тут надо исключить свои, клентские адреса knxd, которые принадлежат контроллеру.
Какие они?

А что именно передаете, какой тип значение? Ну если строку, например пытаться сконвертировать - да, будет на выходе булев.

Как и писал выше - с клиентских адресов контроллера.

Я предлагаю для начала просто создать тестовый скрипт, с одним правилом и проверить на нем.

В шине KNX перестали идти телеграммы. в топике данные меняются, вот тут на скрине:

что значит “подписаться на топик” как это сделать?

image

Передавал напряжение с счетчика, передавал температуру проца самого WB.

Почему всегда с разных? не встречал в KNX что одна физ. железка с разных адресов швыряла. Взять тот же LM есть один ее физ. адрес она по нему с шиной и работает…

ок. Создаю первый скрипт knx-main.js

(function() {
    var knx_vdev_obj = {
        title: "KNX Group Addresses",
        cells: {
                "15-1-1": {
                type: "voltage",
                value: 250.333
            }
        }
    };


    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] == "5/10/")) { // 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;
};

function convertfromKnx(value) {
var byte1 = "0x" + value[3] + value[4];
var byte2 = "0x" + value[8] + value[9];
var data = parseInt(byte1, 16) * 256 + parseInt(byte2, 16);
var sign = data >> 15;
var exponent = (data >> 11) & 0x0f;
var mantisse = data & 0x7ff;
if (sign) {
mantisse = -2048 + mantisse;
}
output = (mantisse * (Math.pow(2, exponent)) / 100);
return output;
};

и второй knx-test.js

(function() {

    defineRule("hdl_panel_set_temp", {
        whenChanged: "wb-map12e_67/Urms L1",
        then: function(newValue, devName, cellName) {
            dev["knx_group_addrs/15-1-1"] = knxConvertToFloat16(newValue + 2); // Передаем на KNX панельку температуру с датчика DS18B20
          	log.info("Температура", newValue);
        }
    });



})();

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;
};

то в “топике” вот:

в шине вот:

https://wirenboard.com/wiki/MQTT#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80_.D0.BF.D0.BE.D0.B4.D0.BF.D0.B8.D1.81.D0.BA.D0.B8

Посмотртте (выведите в лог) тип переменной. Если строка - ее нельзя конвертировать наприямую в функции предназначенной для работы с числами.
Ну и для float надо указать knx_type: “wide” в описании поля.

я запутался… как в логе вывести тип данных не нагуглил.
Но зачем вы пишите “если так” - вы же писали инструкцию, и наверняка знаете каким типом передаются данные и если по моим сообщениям видно что проблема в типах данных, то помогите плиз как преобразовать или правильно передать данные. knx_type: “wide” я пробовал изменений нет…

Вот так
Движок правил wb-rules — Wiren Board.

Покажите что приходит у вас в функцию преобразования и что отправляется в телеграмме knx, из топика. Ну или давате отладим один скрипт.

тип number

в топике значение приходит: вида 224.58

в KNX определяется как 2-byte… хотелось бы что бы по DPT 14.27

может anydesk? завтра что бы разом закрыть вопросы по SNMP и KNX это решающие факторы по которым мы определимся для себя в использовании ваших контроллеров на наших объектах.

P.S. у Евгения Б. есть мои контакты.

У нас кстати скоро (через неделю или две) выйдет бета-версия совершенно нового драйвера для KNX, в котором работа с типами данных будет сильно удобнее. Я бы дождался её.

Это хорошая новость! Но хотя бы в аспекте некоторых задач которые сейчас есть, хотелось бы достигнуть результатов.

Если резюмировать моменты которые сейчас есть то это: назначение правильного типа данных (нужного) для передачи в knx из knx. И решить вопрос по SNMP можно ли и какие использовать oid для того что бы были другие типы данных.