MOKOSMART - Lw001 Bg Pro

Sensor

Codec Description

Codec for MOKOSMART - Lw001-Bg-Pro (v1.0.0).

Codec Preview

/* eslint-disable no-plusplus */ /* eslint-disable prettier/prettier */ /* * LW001-BG-PRO */ const packet_type = [ "heart", "fix_success", "fix_false", "sys_close_info", "shake_info", "idle_info", "demolish_alarm", "event", "battery_consume", "config", "store_data", "limit_gps_data", ]; const dev_mode = ["standby", "period", "timing", "motion"]; const dev_fix_type = ["work_mode_fix", "down_request_fix"]; function substringBytes(bytes, start, len) { const char = []; for (let i = 0; i < len; i++) { char.push(`0x${bytes[start + i].toString(16)}` < 0x10 ? `0${bytes[start + i].toString(16)}` : bytes[start + i].toString(16)); } return char.join(""); } function BytestoInt(bytes, start) { const value = (bytes[start] << 24) | (bytes[start + 1] << 16) | (bytes[start + 2] << 8) | bytes[start + 3]; return value; } function Decoder(bytes, port) { const dev_info = {}; dev_info.pack_type = packet_type[port - 1]; // common frame head if (port <= 10) { dev_info.work_mode = dev_mode[bytes[0] & 0x03]; dev_info.low_power_state = (bytes[0] >> 2) & 0x01; dev_info.demolish_state = (bytes[0] >> 3) & 0x01; dev_info.idle_state = (bytes[0] >> 4) & 0x01; dev_info.motion_state = (bytes[0] >> 5) & 0x01; if (port === 2 || port === 3) { dev_info.fix_type = dev_fix_type[(bytes[0] >> 6) & 0x01]; } if (bytes[1] > 0x80) { dev_info.temperature = `${bytes[1] - 0x100}°C`; } else { dev_info.temperature = `${bytes[1]}°C`; } dev_info.lorawan_downlink_count = bytes[2] & 0x0f; dev_info.battery_voltage = `${(22 + ((bytes[2] >> 4) & 0x0f)) / 10}V`; } if (port === 1) { const restart_reason = ["power_restart", "ble_cmd_restart", "lorawan_cmd_restart", "switch_off_mode_restart"]; dev_info.pre_restart_reason = restart_reason[bytes[3]]; const ver_major = (bytes[4] >> 6) & 0x03; const ver_mijor = (bytes[4] >> 4) & 0x03; const ver_patch = bytes[4] & 0x0f; dev_info.ver = `V${ver_major}.${ver_mijor}.${ver_patch}`; dev_info.motion_count = BytestoInt(bytes, 5); } else if (port === 2) { const fix_tech = ["wifi", "ble", "gps"]; let parse_len = 3; // common head is 3 byte const datas = []; const tech = bytes[parse_len++]; dev_info.fix_tech = fix_tech[tech]; const year = bytes[parse_len] * 256 + bytes[parse_len + 1]; parse_len += 2; const mon = bytes[parse_len++]; const days = bytes[parse_len++]; const hour = bytes[parse_len++]; const minute = bytes[parse_len++]; const sec = bytes[parse_len++]; const timezone = bytes[parse_len++]; if (timezone > 0x80) { dev_info.utc_time = `${year}-${mon}-${days} ${hour}:${minute}:${sec} TZ:${timezone - 0x100}`; } else { dev_info.utc_time = `${year}-${mon}-${days} ${hour}:${minute}:${sec} TZ:${timezone}`; } const datalen = bytes[parse_len++]; if (tech === 0 || tech === 1) { for (let i = 0; i < datalen / 7; i++) { const data = {}; data.mac = substringBytes(bytes, parse_len, 6); parse_len += 6; data.rssi = `${bytes[parse_len++] - 256}dBm`; datas.push(data); } dev_info.mac_data = datas; } else { let lat = BytestoInt(bytes, parse_len); parse_len += 4; let lng = BytestoInt(bytes, parse_len); parse_len += 4; if (lat > 0x80000000) lat -= 0x100000000; if (lng > 0x80000000) lng -= 0x100000000; dev_info.lat = lat / 10000000; dev_info.lng = lng / 10000000; lat = dev_info.lat; lng = dev_info.lng; dev_info.location = { variable: "location", value: `${lat},${lng}`, location: { lat, lng } }; dev_info.pdop = bytes[parse_len] / 10; } } else if (port === 3) { const fix_false_reason = [ "wifi_fix_time_timeout", "wifi_fix_tech_timeout", "wifi_module_nofind", "ble_fix_time_timeout", "ble_fix_tech_timeout", "ble_adv", "gps_no_budget", "gps_coarse_acc_timeout", "gps_fine_acc_timeout", "gps_fix_timeout", "gps_assistnow_timeout", "gps_cold_start_timeout", "down_request_fix_interrupt", "motion_start_fix_false_by_motion_end", "motion_end_fix_false_by_motion_start", ]; let parse_len = 3; const datas = []; const reason = bytes[parse_len++]; dev_info.fix_false_reason = fix_false_reason[reason]; const datalen = bytes[parse_len++]; if (reason <= 5) { // wifi and ble reason if (datalen) { for (let i = 0; i < datalen / 7; i++) { const data = {}; data.mac = substringBytes(bytes, parse_len, 6); parse_len += 6; data.rssi = `${bytes[parse_len++] - 256}dBm`; datas.push(data); } dev_info.mac_data = datas; } } else if (reason <= 11) { // gps reason const pdop = bytes[parse_len++]; if (pdop !== 0xff) dev_info.pdop = pdop / 10; else dev_info.pdop = "unknow"; dev_info.gps_satellite_cn = `${bytes[parse_len]}-${bytes[parse_len + 1]}-${bytes[parse_len + 2]}-${bytes[parse_len + 3]}`; } } else if (port === 4) { const sys_close_reason = ["ble_cmd_close", "lorawan_cmd_close", "reed_switch_close"]; dev_info.sys_close_reason = sys_close_reason[bytes[3]]; } else if (port === 5) { dev_info.shake_num = bytes[3] * 256 + bytes[4]; } else if (port === 6) { dev_info.idle_time = bytes[3] * 256 + bytes[4]; } else if (port === 7) { let parse_len = 3; // common head is 3 byte const year = bytes[parse_len] * 256 + bytes[parse_len + 1]; parse_len += 2; const mon = bytes[parse_len++]; const days = bytes[parse_len++]; const hour = bytes[parse_len++]; const minute = bytes[parse_len++]; const sec = bytes[parse_len++]; const timezone = bytes[parse_len++]; if (timezone > 0x80) { dev_info.alarm_time = `${year}-${mon}-${days} ${hour}:${minute}:${sec} TZ:${timezone - 0x100}`; } else { dev_info.alarm_time = `${year}-${mon}-${days} ${hour}:${minute}:${sec} TZ:${timezone}`; } } else if (port === 8) { const event = ["motion start", "moving fix start", "motion end", "lorawan downlink trigger uplink"]; dev_info.event_info = event[bytes[3]]; } else if (port === 9) { let parse_len = 3; dev_info.gps_work_time = BytestoInt(bytes, parse_len); parse_len += 4; dev_info.wifi_work_time = BytestoInt(bytes, parse_len); parse_len += 4; dev_info.ble_scan_work_time = BytestoInt(bytes, parse_len); parse_len += 4; dev_info.ble_adv_work_time = BytestoInt(bytes, parse_len); parse_len += 4; dev_info.lorawan_work_time = BytestoInt(bytes, parse_len); parse_len += 4; } else if (port === 10) { // } else if (port === 11) { // } else if (port === 12) { dev_info.work_mode = dev_mode[bytes[0] & 0x03]; dev_info.low_power_state = bytes[0] & 0x04; dev_info.demolish_state = bytes[0] & 0x08; dev_info.idle_state = bytes[0] & 0x10; dev_info.motion_state = bytes[0] & 0x20; dev_info.fix_type = dev_fix_type[(bytes[0] >> 6) & 0x01]; dev_info.lorawan_downlink_count = bytes[1] & 0x0f; dev_info.battery_voltage = `${(22 + ((bytes[2] >> 4) & 0x0f)) / 10}V`; let parse_len = 2; let lat = BytestoInt(bytes, parse_len); parse_len += 4; let lng = BytestoInt(bytes, parse_len); parse_len += 4; if (lat > 0x80000000) lat -= 0x100000000; if (lng > 0x80000000) lng -= 0x100000000; dev_info.lat = lat / 10000000; dev_info.lng = lng / 10000000; lat = dev_info.lat; lng = dev_info.lng; dev_info.location = { variable: "location", value: `${lat},${lng}`, location: { lat, lng } }; dev_info.pdop = bytes[parse_len] / 10; } return dev_info; } function ToTagoFormat(object_item, serie, prefix = "") { const result = []; for (const key in object_item) { if (typeof object_item[key] === "object") { result.push({ variable: (object_item[key].MessageType || `${prefix}${key}`).toLowerCase(), value: object_item[key].value || object_item[key].Value, serie: object_item[key].serie || serie, metadata: object_item[key].metadata, unit: object_item[key].unit, location: object_item[key].location, }); } else { result.push({ variable: `${prefix}${key}`.toLowerCase(), value: object_item[key], serie, }); } } return result; } const payload_raw = payload.find((x) => x.variable === "payload_raw" || x.variable === "payload" || x.variable === "data"); // Get the port variable. const port = payload.find((x) => x.variable === "port" || x.variable === "fport").value; if (payload_raw) { try { // Convert the data from Hex to Javascript Buffer. const buffer = Buffer.from(payload_raw.value, "hex"); const serie = new Date().getTime(); const payload_aux = ToTagoFormat(Decoder(buffer, port), serie); payload = payload.concat(payload_aux.map((x) => ({ ...x, serie }))); } catch (e) { // Print the error to the Live Inspector. console.error(e); // Return the variable parse_error for debugging. payload = [{ variable: "parse_error", value: e.message }]; } } 

This codec is sourced from TagoIO Github. All rights belong to TagoIO Github.

This codec is licensed under the GNU General Public License v3 (GPL v3). Modifications, if any, are clearly marked. You are free to use, modify, and distribute the codec under the terms of GPL v3.

Community Feedback