NEWS
Скрипт датчика уровня топлива omnicomm.
-
Скрипт для снятия данных с датчика уровня топлива omnicomm lls 30160. Датчик имеет свой протокол, похожий на modbus, но не modbus. Обращаться к датчику можно по RS-485. Подключить датчик можно к шлюзу WI-FI - RS485. Датчик уровня топлива имеет документацию по интеграции, где описан процесс обмена данными с данным датчиком. Ниже скрипт с помощью которого можно получить эти данные. Скрипт ссылается на 3 адрес у датчика, так что если нужно будет повторить - выставляйте адрес у датчика 3, либо рассчитывайте сою команду для отправки buffer.
var PORT = 23; var HOST = '192.168.1.148'; // ip адрес шлюза Wi-Fi-RS-485 var net = require('net'); var client = new net.Socket(); var buffer = Buffer.from([0x31, 0x03, 0x06, 0xFD]);//значения для отправки датчику, где 0x31 - открывающий байт, который говорит датчику слушать дальше, 0x03 - адрес датчика, 0x06 - команда запрос из документации, 0xFD - контрольная сумма, можно проверить на сайте https://crccalc.com/ (CRC-8/MAXIM) в поле ввода вставить "0x31 0x03 0x06" в Input type: выбрать Hex, нажать "Calc CRC-8" в CRC-8/MAXIM вернется 0xFD. Проверка прошла var timer; var arr = []; client.connect(PORT, HOST, function() { clearInterval(timer); log('Connected'); timer = setInterval(function() { parse(); client.write(buffer); }, 5000); }); function parse(){ var buf = Buffer.concat(arr)/*.toJSON().data*/; //log('Received = ' + buf.toString('hex')); var crc = getCRC(buf.slice(0, buf.length-1)); //log('Checksum = ' + crc.toString(16)); if(crc == buf[buf.length-1]){ //log('Чек сумма совпала'); var temp = (buf[3] & 0x7F); if((buf[3] & 0x80) > 0){ temp = temp * -1; } //log('Температура = ' + temp); var litr = ((buf[5] << 8) | buf[4]); // var in_min = ((0x00 << 8) | 0x00); //Значения при тарировке минимум // 0 var in_max = ((0x0F << 8) | 0xFF); //Значения при тарировке максимум // 4095 var fuel = Scaler(litr, in_min, in_max, 0, 18).toFixed(2); //Количество литров в баке //log('in_min = ' + in_min); //log('in_max = ' + in_max); //log('litr = ' + litr); //log('Литраж = ' + Scaler(litr, in_min, in_max, 0, 25).toFixed(2)); createState('GENfuel',0); // Сколько литров в баке createState('GENfueltemp',0); // Температура топлива createState('GENlitr',0); // Температура топлива setState("javascript.0.GENfuel", + fuel); setState("javascript.0.GENfueltemp", + temp); setState("javascript.0.GENlitr", + litr); } arr = []; } //Вставка конвертирования. начало createState('fuel_hk', 100); var hkmin = 0; var hkmax = 100; var iobmin = 0; var iobmax = 4095; var p; on({id: 'GENlitr', change: 'ne', ack: false}, function (obj) { if(obj.state.val >= iobmin && obj.state.val <= iobmax){ p = parseInt(((obj.state.val-iobmin) / (iobmax-iobmin)) * (hkmax-hkmin) + hkmin, 10); setState('fuel_hk', p, true); } }); //Вставка конвертирования. Конец function Scaler (input, in_min, in_max, out_min, out_max){ var out1 = 0; var out2 = 0; var output = 0; var diff = in_max - in_min; if (diff != 0){ if (input > in_max){ out1 = in_max; } else { out1 = input; } if (in_min > out1){ out2 = in_min; } else { out2 = out1; } output = (out_max - out_min) / diff * (out2 - in_min) + out_min; return output; } } client.on('data', function(data) { arr.push(Buffer.from(data, 16)); //log('Received: ' + data); }); client.on('error', function(err) { log("Error: " + err); client.destroy(); }); function getCRC(byte_array) { var c = 0 var table = [0x00, 0x5E, 0xBC, 0xE2, 0x61, 0x3F, 0xDD, 0x83, 0xC2, 0x9C, 0x7E, 0x20, 0xA3, 0xFD, 0x1F, 0x41, 0x9D, 0xC3,0x21, 0x7F, 0xFC, 0xA2, 0x40, 0x1E, 0x5F, 0x01, 0xE3, 0xBD, 0x3E, 0x60,0x82, 0xDC, 0x23, 0x7D, 0x9F, 0xC1, 0x42, 0x1C, 0xFE, 0xA0, 0xE1, 0xBF,0x5D, 0x03, 0x80, 0xDE, 0x3C, 0x62, 0xBE, 0xE0, 0x02, 0x5C, 0xDF, 0x81,0x63, 0x3D, 0x7C, 0x22, 0xC0, 0x9E, 0x1D, 0x43, 0xA1, 0xFF, 0x46, 0x18,0xFA, 0xA4, 0x27, 0x79, 0x9B, 0xC5, 0x84, 0xDA, 0x38, 0x66, 0xE5, 0xBB,0x59, 0x07, 0xDB, 0x85, 0x67, 0x39, 0xBA, 0xE4, 0x06, 0x58, 0x19, 0x47,0xA5, 0xFB, 0x78, 0x26, 0xC4, 0x9A, 0x65, 0x3B, 0xD9, 0x87, 0x04, 0x5A,0xB8, 0xE6, 0xA7, 0xF9, 0x1B, 0x45, 0xC6, 0x98, 0x7A, 0x24, 0xF8, 0xA6,0x44, 0x1A, 0x99, 0xC7, 0x25, 0x7B, 0x3A, 0x64, 0x86, 0xD8, 0x5B, 0x05,0xE7, 0xB9, 0x8C, 0xD2, 0x30, 0x6E, 0xED, 0xB3, 0x51, 0x0F, 0x4E, 0x10,0xF2, 0xAC, 0x2F, 0x71, 0x93, 0xCD, 0x11, 0x4F, 0xAD, 0xF3, 0x70, 0x2E,0xCC, 0x92, 0xD3, 0x8D, 0x6F, 0x31, 0xB2, 0xEC, 0x0E, 0x50, 0xAF, 0xF1,0x13, 0x4D, 0xCE, 0x90, 0x72, 0x2C, 0x6D, 0x33, 0xD1, 0x8F, 0x0C, 0x52,0xB0, 0xEE, 0x32, 0x6C, 0x8E, 0xD0, 0x53, 0x0D, 0xEF, 0xB1, 0xF0, 0xAE,0x4C, 0x12, 0x91, 0xCF, 0x2D, 0x73, 0xCA, 0x94, 0x76, 0x28, 0xAB, 0xF5,0x17, 0x49, 0x08, 0x56, 0xB4, 0xEA, 0x69, 0x37, 0xD5, 0x8B, 0x57, 0x09,0xEB, 0xB5, 0x36, 0x68, 0x8A, 0xD4, 0x95, 0xCB, 0x29, 0x77, 0xF4, 0xAA,0x48, 0x16, 0xE9, 0xB7, 0x55, 0x0B, 0x88, 0xD6, 0x34, 0x6A, 0x2B, 0x75,0x97, 0xC9, 0x4A, 0x14, 0xF6, 0xA8, 0x74, 0x2A, 0xC8, 0x96, 0x15, 0x4B,0xA9, 0xF7, 0xB6, 0xE8, 0x0A, 0x54, 0xD7, 0x89, 0x6B, 0x35]; for (var i = 0; i < byte_array.length; i++ ) c = table[(c ^ byte_array[i]) % 256] return c; }
-
@Anzic Как будет выглядеть код для переходки USB-rs485
-
@Anzic У меня стоит такой на топливо хранилище уже несколько лет. Показания снимал с компа через УНУ (rs 485 - USB) омникомовская переходка и прога. Есть желание снимать показания с iobroker
(с последним подружился год назад) и затем на гаджете наблюдать за процессом. В написании кода не силён. -
@tim4280 Если актуально, то для опроса по USB-rs485 есть адаптер - https://github.com/instalator/ioBroker.omnicomm-lls