//взял отсюда https://g...content-available-to-author-only...b.com/patrick--/node-omron-fins
const fins = require('omron-fins');
const furnaceConst = require('./checkOmronConst.js');
const http = require('http');
const port = 6500;
function humanize(x){
return (x ? x.toFixed(3).replace(/\.?0*$/,'') : null);
}
const makeDt = function (dt) { //дату в формате "yyyy-MM-dd hh:mm:ss"
let tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds
let localISOTime = (new Date(dt - tzoffset)).toISOString().slice(0, 19).replace('T', ' ');
let mySqlDT = localISOTime;
return mySqlDT;
}
const bcd2number = function(bcd) {
let d0 = (bcd & 0xF);
let d1 = (bcd & 0xF0) >> 4;
let d2 = (bcd & 0xF00) >> 8;
let d3 = (bcd & 0xF000) >> 12;
return (d3*1000 + d2*100 + d1*10 + d0);
}
const getOmron = function(adr, tags0){
let client = fins.FinsClient(9600, adr);
// Setting up our error listener
client.on('error',function(error) {
console.log('Error: ', error);
});
//подготовка выходного массива
let tags = tags0.map(t => {return { "tagNum": Number(String(t.tag).slice(2)),
"tag": t.tag, "value":null, "lastTime":null, "name": t.name, "units": t.units, "k": t.k}});
//объединение подряд идущих ячеек
let tagsS = []; //сокращенный массив без подряд-идущих значений
for (let pos=tags.length-2, cnt=1; pos>=-1; pos--, cnt++) //с конца в начало
if (pos<0 || tags[pos].tagNum != tags[pos+1].tagNum-1) //pos==-1 чтобы сработало для [0]-элемента
{ tagsS.push({"tagNum": tags[pos+1].tagNum, "cnt": cnt, "index": pos+1}); cnt=0;}
//в цикле ниже с задержкой делаем запросы
var tm = setTimeout(reqOmron, 0);
//вызывается на ответе от ПЛК, ans отсюда идёт ниже в reqOmron
let ans=[];
client.on('reply',function(msg) {
if (msg.values && msg.values.length) //иногда считывается "ничего"(wi-fi плохой)
ans=msg.values.slice(0);
clearTimeout(tm);
tm = setTimeout(reqOmron, 0);//сокращаем ожидание ответа
});
//надо как-то сделать эту функцию с promise, с учетом ожиданий
let st = 0; pos = 0;
function reqOmron(){
//switch-case последовательного опроса с задержкой?
switch(st){
case 0:
st++;
ans.length=0;
client.read('D' +String(tagsS[pos].tagNum), tagsS[pos].cnt); //запрос
//ждём ответа на запрос, или таймаут 2 секунды (таймаут в ответе сбрасывается).
tm = setTimeout(reqOmron, 2000); //таймаут до 2 секунд
break;
case 1:
//заполняем из массива ответов
for (let i=0; i<ans.length; i++)
tags[tagsS[pos].index + i].value=bcd2number(ans[i]);
st++;
if (pos<tagsS.length-1) { //проходим сокращенный массив
pos++;
st=0;
}
tm = setTimeout(reqOmron, 0); //надо немного подождать перед следующей посылкой
break;
default:
let dt = new Date();
console.log (makeDt(dt) +"> "+ (tags.filter(t=> t.value).length)+'/'+tags.length);
//заполняем только успешно считанные ячейки
tags.forEach( function(t){ if (t.value) {t.value *= t.k; t.lastTime = dt;} });
tags.forEach( function(t,i){ if (t.value) {furnace4data[i].value = t.value; furnace4data[i].lastTime = t.lastTime;}});
}
}
return tags;
}
var furnace4data = furnaceConst.furnace4const.map( function(t){ return {"tag": t.tag, "value":null, "lastTime":null, "name": t.name, "units": t.units, "k": t.k}} );
getOmron("192.168.0.69", furnaceConst.furnace4const);
setInterval(function() { getOmron("192.168.0.69", furnaceConst.furnace4const); }, 30000);
//furnace4data - дальше в JSON на http-сервер
let server = new http.Server();
server.listen(port, (err) => {
if (err) { return console.log('server Http error!', err); } }
);
server.on('request', function(req, res){
let s = "<!DOCTYPE html><html><head><meta charset='utf-8' /></head><body><table border=1>";
furnace4data.forEach( function(t){ s+="<tr><td>"+makeDt(t.lastTime)+"</td><td>"+t.tag+"</td><td>"+humanize(t.value)+"</td><td>"+t.units+"</td><td>"+t.name+"</td></tr>"; } );
s+="</table></body></html>";
res.end(s);
});
let serverJSON = new http.Server();
serverJSON.listen(6501, (err) => {
if (err) { return console.log('server JSON error!', err); }
});
serverJSON.on('request', function(req, res){
let t = {"data" : furnace4data.map( (t)=>{return {'tag': t.tag, 'value': humanize(t.value)}})};
res.end( JSON.stringify( t ) );
});