Платформа позволяет осуществлять контроль текущих значений параметров объекта, которые регистрируются его датчиками. Все данные, полученные от устройства, сохраняются на платформе и в любой момент доступны для последующего анализа. Однако зачастую при анализе данных появляется необходимость в дополнительных расчетах на базе полученных значений. Или же наоборот, могут быть случаи, когда получены данные с избыточной или некорректной информацией. В подобных ситуациях необходима дополнительная фильтрация.
Для этого в архитектуре платформы существует отдельный слой - обработчики, которые позволяют обрабатывать входной пакет данных с целью его коррекции или дополнения. Данные могут быть обработаны таким образом, чтобы можно было, например, рассчитывать расстояние, пройденное транспортным средством, оперируя количеством оборотов колеса и длиной его окружности; осуществлять перевод величины одной единицы измерения в другую; фильтровать пакеты данных, отбрасывая избыточную информацию и оставляя наиболее существенную, и многое другое. Подобные действия можно реализовать в обработчике и затем запустить его. Для создания обработчика необходимо написать исходный код на языке программирования JavaScript версии ES6. Таким образом, вы сами реализуете алгоритм, с помощью которого можно учитывать все аспекты обработки данных для ваших пакетов.
Здравствуйте! В обработчике пытаюсь сделать логику, что бы парсить входящее сообщение. А именно хочу сжать передаваемый пакет на сервер, такт как часто некоторые параметры бывыют равны нулю или повторяются. А далее в обработчике вернуть в “нормальный” вид.
Типа:
раньше строка была:
“0#0#0#0#0#0#0#0#0#0#0#14#ea60#3e8#ea60#64#ea60#0#94#0#0#0#0#0#1e#0#0#0#0#1#2#0#0#0#2#0#0#0#1#f#0#1#0#0#3#0#818#0#1429#0#216.06#”
в сжатом варианте "|11#14#ea60#3e8#ea60#64#ea60##94#|5#1e#|4#1#2#|3#2#|3#1#f##1#|2@3##818##1429#@216.06@
"
Пытался сделать в обработчике отдельную функцию, но выдает ошибку:
“TypeError: Cannot read property ‘toString’ of undefined”
Пока не получилось победить…
Подскажите, что не так, пожалуйста
Добрый день. А код самого обработчика можете приложить? Ну или в чат личный скинуть. Скорей всего какое то значение string undefined или null.
// пример прихода и рабора данных
// #region test text
// St#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#20#60000#1000#60000#100#60000#0#147#0#0#0#0#0#30#0#0#0#0#1#2#0#0#0#2#0#0#59#2#23#0#2#0#0#125.00#100#0.13#041140#55.7259#49.1507#0#125.8##SMARTGEN
//Kovali_azimut_20#
//0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@20@60000@1000@60000@100@60000@0@148@
//0@0@0@0@0@30@0@0@0@0@1@2@0@0@0@2@0@0@59@2@23@0@2@0@0@
//#43@1000@41c@0@1429@#
//50.00@9@0.13#
//F@55.623221@49.156243@F@F
//#SMARTGEN
//Kovali_azimut_20#0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@20@60000@1000@60000@100@60000@0@148@0@0@0@0@0@30@0@0@0@0@1@2@0@0@0@2@0@0@59@2@23@0@2@0@0@#43@1000@41c@0@1429@#50.00@9@0.14#F@55.623221@49.156243@F@F#SMARTGEN
//TypeError: Register_array is not a function
//TypeError: Cannot read property ‘fill’ of undefined
//ReferenceError: NONE is not defined
//Kovali_azimut_20#213@0@0@214@0@214@499@0@0@0@0@0@0@0@0@0@0@42@3145@0@96@75@277@0@135@0@0@0@0@0@30@0@0@0@0@1@2@0@0@0@2@0@0@42@52@6@0@156@0@204@#40@0@800@2004@1402@#65.53@41@94@0.13#F@55.623221@49.156243@F@F#SMARTGEN
//#endregion
function Split_string(mes, del, add_del){
var arr = mes.split(del);
var _string = “”;
for (let i = 0; i < arr.length; i++) {
if (arr[i].includes(add_del)){
var cell = arr[i].split(add_del);
if (cell[0] === ‘’) {cell[0] = ‘0’}
for (let c = 0; c < Number(cell[1]); c++){
_string = _string + cell[0] + ‘#’;
}
}
else if (arr[i] === ‘’){
_string = _string + ‘0’ + ‘#’;
}
else {
_string = _string + arr[i] + ‘#’;
}
}
return _string;
}
// переменные сос зачениями coils регистров c
// #region coil smartgen
// data[0]
const _Common_Alarm = 0b0000000000000000;//1
const _Common_Warning_Alarm = 0b0000000000000001;//2
const _Common_Shutdown_Alarm = 0b0000000000000010;//3
const _Remote_Mode = 0b0000000000000100;//4
const _Remote_Lock = 0b0000000000001000;//5
const null1 = 0b0000000000010000;//6
const _Gen_with_Load = 0b0000000000100000;//7
const _Mains_with_Load = 0b0000000001000000;//8
const _Emergency_Stop = 0b0000000010000000;//9
const _Overspeed_Alarm_Shutdown = 0b0000000100000000;//10
const _Underspeed_Alarm_Shutdown = 0b0000001000000000;//11
const _Speed_Signal_Loss_Shutdown = 0b0000010000000000;//12
const _Overfrequency_Shutdown = 0b0000100000000000;//13
const _Underfrequency_Shutdown = 0b0001000000000000;//14
const _Overvoltage_Shutdown = 0b0010000000000000;//15
const _Undervoltage_Shutdow = 0b0100000000000000;//16
// data[1]
const _Gen_Overcurrent_Shutdown = 0b0000000000000001;//17
const _Crank_Failure = 0b0000000000000010;//18
const _High_Temperature_Shutdown = 0b0000000000000100;//19
const _Low_Oil_Pressure_Shutdown = 0b0000000000001000;//20
const _Frequency_Loss_Alarm = 0b0000000000010000;//21
const _Input_Port_Shutdown_Alarm = 0b0000000000100000;//22
const _Low_Fuel_Level_Shutdown_Alarm = 0b0000000001000000;//23
const _Low_Coolant_Level_Shutdown_Alarm = 0b0000000010000000;//24
const _High_Water_Temperature_Warn_Alarm = 0b0000000100000000;//25
const _Low_Oil_Pressure_Warn_Alarm = 0b0000001000000000;//26
const _Gen_Overcurrent_Warn_Alarm = 0b0000010000000000;//27
const _Stop_Failure_Warn = 0b0000100000000000;//28
const _Low_Oil_Level_Warn = 0b0001000000000000;//29
const _Charge_Failure_Warn = 0b0010000000000000;//30
const _Battery_Low_Warn_Alarm = 0b0100000000000000;//31
const _Battery_Volt_High_Warn_Alarm = 0b1000000000000000;//32
// data[2]
const _Input_Port_Warn_Alarm = 0b1000000000000001;//33
const _Speed_Signal_Loss_Warn = 0b0000000000000010;//34
const _Low_Coolant_Level_Warn = 0b0000000000000100;//35
const _Temp_Sensor_Open_Warn = 0b0000000000001000;//36
const _Oil_Pressure_Sensor_Open_Warn = 0b0000000000010000;//37
const _Maintenance_Due_Warn = 0b0000000000100000;//38
const _Charger_Fails_to_Charge_Warn = 0b0000000001000000;//39
const _Over_Power_Warn = 0b0000000010000000;//40
const _Test_Mode = 0b0000000100000000;//41
const _Auto_Mode = 0b0000001000000000;//42
const _Manual_Mode = 0b0000010000000000;//43
const _Stop_Mode = 0b0000100000000000;//44
const _Temp_Sensor_Open_Shutdown = 0b0001000000000000;//45
const _Oil_Pressure_Sensor_Open_Shutdown = 0b0010000000000000;//46
const _Maintenance_Due_Shutdown_Alarm = 0b0100000000000000;//47
const _Over_Power_Shutdown_Alarm = 0b1000000000000000;//48
// data[3]
const _Emergency_Stop_Input = 0b1000000000000001;//49
const _Aux_Input_1 = 0b0000000000000010;//50
const _Aux_Input_2 = 0b0000000000000100;//51
const _Aux_Input_3 = 0b0000000000001000;//52
const _Aux_Input_4 = 0b0000000000010000;//53
const _Aux_Input_5 = 0b0000000000100000;//54
const _Gen_Switch_Failure_Warn = 0b0000000001000000;//55
const _Mains_Switch_Failure_Warn = 0b0000000010000000;//56
const _Start_Relay_Output = 0b0000000100000000;//57
const _Fuel_Relay_Output = 0b0000001000000000;//58
const _Aux_Output_1 = 0b0000010000000000;//59
const _Aux_Output_2 = 0b0000100000000000;//60
const _Aux_Output_3 = 0b0001000000000000;//61
const _Aux_Output_4 = 0b0010000000000000;//62
const _null2 = 0b0100000000000000;//63
const _null3 = 0b1000000000000000;//64
// data[4]
const _Mains_Fault = 0b1000000000000001;//65
const _Mains_Normal = 0b0000000000000010;//66
const _Mains_Overvoltage = 0b0000000000000100;//67
const _Mains_Undervoltage = 0b0000000000001000;//68
const _Mains_Loss_of_Phase = 0b0000000000010000;//69
const _Mains_Blackout = 0b0000000000100000;//70
const _null4 = 0b0000000001000000;//71
const _null5 = 0b0000000010000000;//72
const _Gen_Normal = 0b0000000100000000;//73
const _Gen_Overvoltage = 0b0000001000000000;//74
const _Gen_Undervoltage = 0b0000010000000000;//75
const _Gen_Overfrequency = 0b0000100000000000;//76
const _Gen_Underfrequency = 0b0001000000000000;//77
const _Gen_Overcurrent_Warn = 0b0010000000000000;//78
const _In_Scheduled_Not_Run = 0b0100000000000000;//79
const _ECU_Warn = 0b1000000000000000;//80
// #endregion
function process(in_message) {
// var array = in_message.split(‘#’);
var array = in_message.split(‘@’);
// var Register_array = array[0].split(‘@’);
// var registers = array[0].split(‘#’);
// var _string = “”;
// for (let i = 0; i < registers.length; i++) {
// if (registers[i].includes(‘|’)){
// var cell = registers[i].split(‘|’);
// if (cell[0] === ‘’) {cell[0] = ‘0’}
// for (let c = 0; c < Number(cell[1]); c++){
// _string = _string + cell[0] + ‘#’;
// }
// }
// else if (registers[i] === ‘’){
// _string = _string + ‘0’ + ‘#’;
// }
// else {
// _string = _string + registers[i] + ‘#’;
// }
// }
var Register_array = Split_string(array[0], ‘#’, ‘|’).split(‘#’);
var Coils_array = array[1].split(‘@’);
// var Coils_array = Split_string(array[1].split(‘#’));
var System_array = array[2].split(‘@’);
// var System_array = Split_string(array[2].split(‘#’));
var GPS_array = array[1].split(‘@’);
// var GPS_array = Split_string(array[3].split(‘#’));
const Controller = array[1];
// if (Register_array.length < 2){ Register_array = Array(50).fill(“NONE”)}
// if (Coils_array.length < 2){ Coils_array = Array(5).fill(“NONE”)}
// сеть
const MV_L1 = Register_array[0]; // напряжение 1 фазы
const MV_L2 = Register_array[1]; // напряжение 2 фазы
const MV_L3 = Register_array[2]; // напряжение 3 фазы
const MV_L1_L2 = Register_array[3]; // напряжение межазное
const MV_L2_L3 = Register_array[4]; // напряжение межазное
const MV_L3_L1 = Register_array[5]; // напряжение межазное
const MF = Register_array[6]; // частота
// генератор
const GV_L1 = Register_array[7]; // напряжение 1 фазы
const GV_L2 = Register_array[8]; // напряжение 2 фазы
const GV_L3 = Register_array[9]; // напряжение 3 фазы
const GV_L1_L2 = Register_array[10]; // напряжение межазное
const GV_L2_L3 = Register_array[11]; // напряжение межазное
const GV_L3_L1 = Register_array[12]; // напряжение межазное
const GF = Register_array[13]; // частота
const CUR_L1 = Register_array[14]; // ток 1 фазы
const CUR_L2 = Register_array[15]; // ток 2 фазы
const CUR_L3 = Register_array[16]; // ток 3 фазы
const Temp_eng = Register_array[17]; // температура двигателя
//const GC_L2 = array[19]; // ток 2 фазы
const Oil_pres = Register_array[19]; // давление масла
///const GC_L1 = array[21]; // ток 1 фазы
const Fuel_level = Register_array[21]; // уровень топлива
//const GC_L3 = array[23]; // ток 3 фазы
const Speed_rpm = Register_array[23]; // обороты двигателя
const V_bat_gen = Register_array[24]/10; // напряжение АКБ
const V_ch_gen = Register_array[25]/10; // напряжение заряда АКБ
/*
const GC_L1 = array[28]; // ток 1 фазы
const GC_L2 = array[29]; // ток 2 фазы
const GC_L3 = array[30]; // ток 3 фазы
*/
const Last_time = Register_array[30]; // время сервиса
/*
const GC_L2 = array[32]; // ток 2 фазы
const GC_L3 = array[33]; // ток 3 фазы
const GC_L2 = array[34]; // ток 2 фазы
const GC_L3 = array[35]; // ток 3 фазы
const GC_L2 = array[36]; // ток 2 фазы
const GC_L3 = array[37]; // ток 3 фазы
const GC_L2 = array[38]; // ток 2 фазы
const GC_L3 = array[39]; // ток 3 фазы
const GC_L2 = array[40]; // ток 2 фазы
const GC_L3 = array[41]; // ток 3 фазы
const GC_L2 = array[42]; // ток 2 фазы
const GC_L3 = array[43]; // ток 3 фазы
*/
const Time_houre = Register_array[43]; // Моточасы часы
const Time_Min = Register_array[44]; // Моточасы минуты
const Time_Sec = Register_array[45]; // Моточасы секунды
const Time = Time_houre.toString() + ':' + Time_Min.toString() + ':' + Time_Sec.toString();
// const GC_L3 = array[47]; // ток 3 фазы
const Runs = Register_array[47]; // Количество запусков
/*
const GC_L3 = array[49]; // ток 3 фазы
const GC_L2 = array[50]; // ток 2 фазы
*/
//parseInt(num, baseFrom).toString(baseTo);
//const all_coils = array[51]; // значение всех коилс массивом разделителем "@" в HEX
//var array_coils = all_coils.split("@");
const coils_0 = parseInt(Coils_array[0], 16);
const coils_1 = parseInt(Coils_array[1], 16);
const coils_2 = parseInt(Coils_array[2], 16);
const coils_3 = parseInt(Coils_array[3], 16);
const coils_4 = parseInt(Coils_array[4], 16);
const coils_2_str = coils_2.toString(2);
var mode;
if (_Stop_Mode == (_Stop_Mode & coils_2)) {
mode = "STOP";
}
if (_Manual_Mode == (_Manual_Mode & coils_2)) {
mode = "MAN";
}
if (_Auto_Mode == (_Auto_Mode & coils_2)) {
mode = "AUTO";
}
if (_Test_Mode == (_Test_Mode & coils_2)) {
mode = "TEST";
}
var alarm = "";
if (_Emergency_Stop_Input == (_Emergency_Stop_Input & coils_3)) {
alarm += " Em Stop";
}
var gen_act;
if (_Gen_with_Load == (_Gen_with_Load & coils_0)) {
gen_act = "Closed";
}
else{
gen_act = "Open"
}
var mains_act;
if (_Mains_with_Load == (_Mains_with_Load & coils_0)) {
mains_act = "Closed";
}
else{
mains_act = "Open"
}
const ballans = System_array[0];
const CSQ = System_array[1];
const V_bat_sim = System_array[2];
const V_bat_adc = System_array[3];
const Time_GPS = GPS_array[0];
const lat_GPS = Number(GPS_array[1]);
const lon_GPS = Number(GPS_array[2]);
const Sat_GPS = Number(GPS_array[3]);
const Alt_GPS = Number(GPS_array[4]);
//const num_GPS = array[25];
//const alt_GPS = array[26];
// St#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#20#60000#1000#60000#100#60000#0#147#0#0#0#0#0#30#0#0#0#0#1#2#0#0#0#2#0#0#59#2#23#0#2#0#0#0.00#100##090555#55.7188#49.1400#0#149.4##SMARTGEN
return { Controller,
MV_L1, MV_L2, MV_L3,
//MV_L1_L2, MV_L2_L3, MV_L3_L1,
MF,
GV_L1, GV_L2, GV_L3,
//GV_L1_L2, GV_L2_L3, GV_L3_L1,
GF,
CUR_L1, CUR_L2, CUR_L3,
Temp_eng, Oil_pres, Fuel_level, Speed_rpm,
V_bat_gen, V_ch_gen,
Last_time,
Time,
Runs,
ballans, CSQ, V_bat_sim, V_bat_adc,
Time_GPS, lat_GPS, lon_GPS, Sat_GPS, Alt_GPS,
mode, alarm,
gen_act, mains_act
}
}
Обычно можно нажать на плашку с ошибкой на странице состояния, для того чтобы перейти в редактор кода обработчиков в то место, где произошла ошибка.
Курсор будет указазывать на нужную строку и столбец
К сожалению из-за бага в данный момент сбилась нумерация строк, и курсор будет указывать немного не туда.
Баг в ближайшем релизе постараемся исправить.
В данный момент ошибка возникает у вас на 243 строке обработчика
const Time = Time_houre.toString() + ':' + Time_Min.toString() + ':' + Time_Sec.toString();
^
TypeError: Cannot read properties of undefined (reading 'toString')
Так же у вас обработчик имеет довольно внушительный размер, работать с таким в небольшом окне редактора скорее всего неудобно.
Я предложил бы установить себе какой-нибудь JavaScript рантайм:
Сохранить обработчик в файл test.js
(например)
И попробовать позапускать его локально.
> node ./test.js
# или
> deno run ./test.js
Передать в обработчик тестовые данные и вывести результат можно дописав эти строки в конце файла с обработчиком:
const result = process("|11#14#ea60#3e8#ea60#64#ea60##94#|5#1e#|4#1#2#|3#2#|3#1#f##1#|2@3##818##1429#@216.06@");
console.log(result);
Если после этого установить себе ещё VS Code:
То получим полноценный инструмент для отладки
Для вашей изначальной задачи удобно использовать метод Array.flatMap()
Он позволяет пройтись по элементам массива с помощью функции, которая помимо обычных результирующих значений - может возвращать ещё массивы таких значений.
/**
* @param {string} str
* @returns {string[]}
*/
function decompress(str) {
return str.split("#").flatMap((it) => {
// если элемент начинается с `|`
if (it.startsWith("|")) {
// пробуем достать из него кол-во нулей
const zeros = Number(it.replace("|", ""));
if (isFinite(zeros)) {
// возвращаем массив заполненный нулями
return Array(zeros).fill("0");
}
}
// иначе просто берём текущий элемент
return it;
});
}
В результате получится один плоский массив.