├── README.md ├── uc11-t1.js ├── EM500-LGT ├── EM500-PT100.js ├── EM300-TH.js ├── EM500-SWL.js ├── EM500-UDL.js ├── EM500-SMT.js ├── EM500-CO2.js ├── ug8x_uplink.js ├── AM100.js └── uc11-n1.js /README.md: -------------------------------------------------------------------------------- 1 | # Decoder 2 | Example decoder functions to Ursalink end-devices 3 | -------------------------------------------------------------------------------- /uc11-t1.js: -------------------------------------------------------------------------------- 1 | // T1: Payload Decoder 2 | function Decoder(bytes, port) { 3 | var decoded={}; 4 | for(i=0;i< bytes.length;){ 5 | //BATTERY 6 | if(bytes[i]==0x03){ 7 | decoded.battery=bytes[i+2]; 8 | i+=3; 9 | continue; 10 | } 11 | //TEMPERATURE 12 | if(bytes[i]==0x01){ 13 | decoded.temperature=(readInt16LE(bytes.slice(i+2, i+4)))/10; 14 | i+=4; 15 | continue; 16 | } 17 | //HUMIDITY 18 | if(bytes[i]==0x02){ 19 | decoded.humidity=readUInt8LE(bytes[i+2]) / 2; 20 | i+=3; 21 | continue; 22 | } 23 | } 24 | return decoded; 25 | } 26 | 27 | function readUInt8LE(bytes) { 28 | return (bytes & 0xFF); 29 | } 30 | 31 | function readInt8LE(bytes) { 32 | var ref = readUInt8LE(bytes); 33 | return (ref > 0x7F) ? ref - 0x100 : ref; 34 | } 35 | 36 | function readUInt16LE(bytes) { 37 | var value = (bytes[1] << 8) + bytes[0]; 38 | return (value & 0xFFFF); 39 | } 40 | 41 | function readInt16LE(bytes) { 42 | var ref = readUInt16LE(bytes); 43 | return (ref > 0x7FFF) ? ref - 0x10000 : ref; 44 | } 45 | -------------------------------------------------------------------------------- /EM500-LGT: -------------------------------------------------------------------------------- 1 | /** 2 | * Ursalink Sensor Payload Decoder 3 | * 4 | * definition [channel-id] [channel-type] [channel-data] 5 | * 6 | * 01: battery -> 0x01 0x75 [1byte] Unit: % 7 | * 03: light -> 0x03 0x94 [4bytes] Unit: lux 8 | * ------------------------------------------ EM500-LGT 9 | */ 10 | function Decoder(bytes, port) { 11 | var decoded = {}; 12 | 13 | for (var i = 0; i < bytes.length;) { 14 | var channel_id = bytes[i++]; 15 | var channel_type = bytes[i++]; 16 | // BATTERY 17 | if (channel_id === 0x01 && channel_type === 0x75) { 18 | decoded.battery = bytes[i]; 19 | i += 1; 20 | } 21 | // LIGHT 22 | else if (channel_id === 0x03 && channel_type === 0x94) { 23 | decoded.light = readInt16LE(bytes.slice(i, i + 4)) ; 24 | i += 4; 25 | } else { 26 | break; 27 | } 28 | } 29 | return decoded; 30 | } 31 | 32 | /* ****************************************** 33 | * bytes to number 34 | ********************************************/ 35 | function readUInt16LE(bytes) { 36 | var value = (bytes[1] << 8) + bytes[0]; 37 | return value & 0xffff; 38 | } 39 | function readInt16LE(bytes) { 40 | var ref = readUInt16LE(bytes); 41 | return ref > 0x7fff ? ref - 0x10000 : ref; 42 | } 43 | -------------------------------------------------------------------------------- /EM500-PT100.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Ursalink Sensor Payload Decoder 3 | * 4 | * definition [channel-id] [channel-type] [channel-data] 5 | * 6 | * 01: battery -> 0x01 0x75 [1byte] Unit: % 7 | * 03: temperature -> 0x03 0x67 [2bytes] Unit: °C 8 | * ------------------------------------------ EM500-PT100 9 | */ 10 | function Decoder(bytes, port) { 11 | var decoded = {}; 12 | 13 | for (var i = 0; i < bytes.length;) { 14 | var channel_id = bytes[i++]; 15 | var channel_type = bytes[i++]; 16 | // BATTERY 17 | if (channel_id === 0x01 && channel_type === 0x75) { 18 | decoded.battery = bytes[i]; 19 | i += 1; 20 | } 21 | // TEMPERATURE 22 | else if (channel_id === 0x03 && channel_type === 0x67) { 23 | decoded.temperature = readInt16LE(bytes.slice(i, i + 2)) / 10; 24 | i += 2; 25 | } else { 26 | break; 27 | } 28 | } 29 | return decoded; 30 | } 31 | 32 | /* ****************************************** 33 | * bytes to number 34 | ********************************************/ 35 | function readUInt16LE(bytes) { 36 | var value = (bytes[1] << 8) + bytes[0]; 37 | return value & 0xffff; 38 | } 39 | function readInt16LE(bytes) { 40 | var ref = readUInt16LE(bytes); 41 | return ref > 0x7fff ? ref - 0x10000 : ref; 42 | } 43 | -------------------------------------------------------------------------------- /EM300-TH.js: -------------------------------------------------------------------------------- 1 | 2 | function Decoder(bytes, port) { 3 | var decoded = {}; 4 | 5 | for (var i = 0; i < bytes.length;) { 6 | 7 | var channel_id = bytes[i++]; 8 | 9 | var channel_type = bytes[i++]; 10 | 11 | // BATTERY 12 | 13 | if (channel_id === 0x01 && channel_type === 0x75) { 14 | 15 | decoded.battery = bytes[i]; 16 | 17 | i += 1; 18 | 19 | } 20 | 21 | // TEMPERATURE 22 | 23 | else if (channel_id === 0x03 && channel_type === 0x67) { 24 | 25 | decoded.temperature = readInt16LE(bytes.slice(i, i + 2)) / 10; 26 | 27 | i += 2; 28 | 29 | } 30 | 31 | // HUMIDITY 32 | 33 | else if (channel_id === 0x04 && channel_type === 0x68) { 34 | 35 | decoded.humidity = bytes[i] / 2; 36 | 37 | i += 1; 38 | 39 | } 40 | 41 | 42 | 43 | else { 44 | 45 | break; 46 | 47 | } 48 | 49 | } 50 | 51 | return decoded; 52 | 53 | } 54 | 55 | 56 | 57 | /* ****************************************** 58 | 59 | * bytes to number 60 | 61 | ********************************************/ 62 | 63 | function readUInt16LE(bytes) { 64 | 65 | var value = (bytes[1] << 8) + bytes[0]; 66 | 67 | return value & 0xffff; 68 | 69 | } 70 | 71 | 72 | 73 | function readInt16LE(bytes) { 74 | 75 | var ref = readUInt16LE(bytes); 76 | 77 | return ref > 0x7fff ? ref - 0x10000 : ref; 78 | 79 | } 80 | -------------------------------------------------------------------------------- /EM500-SWL.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Ursalink EM500-SWL Payload Decoder 3 | * 4 | * definition [channel-id] [channel-type] [channel-data] 5 | * 6 | * 01: battery -> 0x01 0x75 [1 byte] Unit: % 7 | * 03: water level -> 0x03 0x77 [2 bytes] Unit: cm 8 | * ------------------------------------------ EM500 9 | * 10 | * Example: 11 | * base64: AXVkA3cCAA== 12 | * bytes: 01 75 64 03 77 02 00 13 | * 14 | * After decode: 15 | * { 16 | * "battery": 100, 17 | * "water_level": 2 18 | * } 19 | */ 20 | function Decoder(bytes, port) { 21 | var decoded = {}; 22 | 23 | for (var i = 0; i < bytes.length; ) { 24 | var channel_id = bytes[i++]; 25 | var channel_type = bytes[i++]; 26 | // BATTERY 27 | if (channel_id === 0x01 && channel_type === 0x75) { 28 | decoded.battery = bytes[i]; 29 | i += 1; 30 | } 31 | // WATER LEVEL 32 | else if (channel_id === 0x03 && channel_type === 0x77) { 33 | decoded.water_level = readInt16LE(bytes.slice(i, i + 2)); 34 | i += 2; 35 | } else { 36 | break; 37 | } 38 | } 39 | 40 | return decoded; 41 | } 42 | 43 | /* ****************************************** 44 | * bytes to number 45 | ********************************************/ 46 | function readUInt16LE(bytes) { 47 | var value = (bytes[1] << 8) + bytes[0]; 48 | return value & 0xffff; 49 | } 50 | 51 | function readInt16LE(bytes) { 52 | var ref = readUInt16LE(bytes); 53 | return ref > 0x7fff ? ref - 0x10000 : ref; 54 | } 55 | -------------------------------------------------------------------------------- /EM500-UDL.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Ursalink EM500-UDL Payload Decoder 3 | * 4 | * definition [channel-id] [channel-type] [channel-data] 5 | * 6 | * 01: battery -> 0x01 0x75 [1 byte] Unit: % 7 | * 03: distance -> 0x03 0x82 [2 bytes] Unit: m 8 | * ------------------------------------------ EM500 9 | * 10 | * Example: 11 | * base64: AXVaA4IeAA== 12 | * bytes: 01 75 5A 03 82 1E 00 13 | * 14 | * After decode: 15 | * { 16 | * "battery": 90, 17 | * "distance": 30 18 | * } 19 | */ 20 | function Decoder(bytes, port) { 21 | var decoded = {}; 22 | 23 | for (var i = 0; i < bytes.length; ) { 24 | var channel_id = bytes[i++]; 25 | var channel_type = bytes[i++]; 26 | // BATTERY 27 | if (channel_id === 0x01 && channel_type === 0x75) { 28 | decoded.battery = bytes[i]; 29 | i += 1; 30 | } 31 | // DISTANCE 32 | else if (channel_id === 0x03 && channel_type === 0x82) { 33 | decoded.distance = readInt16LE(bytes.slice(i, i + 2))/1000; 34 | i += 2; 35 | } else { 36 | break; 37 | } 38 | } 39 | 40 | return decoded; 41 | } 42 | 43 | /******************************************* 44 | * bytes to number 45 | ********************************************/ 46 | function readUInt16LE(bytes) { 47 | var value = (bytes[1] << 8) + bytes[0]; 48 | return value & 0xffff; 49 | } 50 | 51 | function readInt16LE(bytes) { 52 | var ref = readUInt16LE(bytes); 53 | return ref > 0x7fff ? ref - 0x10000 : ref; 54 | } 55 | -------------------------------------------------------------------------------- /EM500-SMT.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Ursalink Sensor Payload Decoder 3 | * 4 | * definition [channel-id] [channel-type] [channel-data] 5 | * 6 | * 01: battery -> 0x01 0x75 [1byte] Unit:% 7 | * 03: Temperature -> 0x03 0x67 [2bytes] Unit:°C 8 | * 04: Moisture -> 0x04 0x68 [1byte] Unit:%RH 9 | * 05: Conductivity -> 0x05 0x7f [2bytes] Unit:µs/cm 10 | * ------------------------------------------ EM500-SMT 11 | */ 12 | function Decoder(bytes, port) { 13 | var decoded = {}; 14 | 15 | for (var i = 0; i < bytes.length;) { 16 | var channel_id = bytes[i++]; 17 | var channel_type = bytes[i++]; 18 | // BATTERY 19 | if (channel_id === 0x01 && channel_type === 0x75) { 20 | decoded.battery = bytes[i]; 21 | i += 1; 22 | } 23 | // TEMPERATURE 24 | else if (channel_id === 0x03 && channel_type === 0x67) { 25 | decoded.temperature = readInt16LE(bytes.slice(i, i + 2)) / 10; 26 | i += 2; 27 | } 28 | // MOISTURE 29 | else if (channel_id === 0x04 && channel_type === 0x68) { 30 | decoded.humidity = bytes[i] / 2; 31 | i += 1; 32 | } 33 | // Electrical Conductivity 34 | else if (channel_id === 0x05 && channel_type === 0x7f) { 35 | decoded.conductivity= readInt16LE(bytes.slice(i, i + 2)) ; 36 | i += 2; 37 | } else { 38 | break; 39 | } 40 | } 41 | return decoded; 42 | } 43 | /* ****************************************** 44 | * bytes to number 45 | ********************************************/ 46 | function readUInt16LE(bytes) { 47 | var value = (bytes[1] << 8) + bytes[0]; 48 | return value & 0xffff; 49 | } 50 | 51 | function readInt16LE(bytes) { 52 | var ref = readUInt16LE(bytes); 53 | return ref > 0x7fff ? ref - 0x10000 : ref; 54 | } 55 | -------------------------------------------------------------------------------- /EM500-CO2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Ursalink Sensor Payload Decoder 3 | * 4 | * definition [channel-id] [channel-type] [channel-data] 5 | * 6 | * 01: battery -> 0x01 0x75 [1byte] Unit:% 7 | * 03: temperature -> 0x03 0x67 [2bytes] Unit:°C 8 | * 04: humidity -> 0x04 0x68 [1byte] Unit:%RH 9 | * 05: CO2 -> 0x05 0x7D [2bytes] Unit:ppm 10 | * 06: Pressure -> 0x09 0x73 [2bytes] Unit: hPa 11 | ------------------------------------------ EM500-CO2 12 | */ 13 | function Decoder(bytes, port) { 14 | var decoded = {}; 15 | 16 | for (var i = 0; i < bytes.length;) { 17 | var channel_id = bytes[i++]; 18 | var channel_type = bytes[i++]; 19 | // BATTERY 20 | if (channel_id === 0x01 && channel_type === 0x75) { 21 | decoded.battery = bytes[i]; 22 | i += 1; 23 | } 24 | // TEMPERATURE 25 | else if (channel_id === 0x03 && channel_type === 0x67) { 26 | decoded.temperature = readInt16LE(bytes.slice(i, i + 2)) / 10; 27 | i += 2; 28 | } 29 | // HUMIDITY 30 | else if (channel_id === 0x04 && channel_type === 0x68) { 31 | decoded.humidity = bytes[i] / 2; 32 | i += 1; 33 | } 34 | // CO2 35 | else if (channel_id === 0x05 && channel_type === 0x7D) { 36 | decoded.co2 = readInt16LE(bytes.slice(i, i + 2)); 37 | i += 2; 38 | } 39 | 40 | // PRESSURE 41 | else if (channel_id === 0x06 && channel_type === 0x73) { 42 | decoded.pressure = readInt16LE(bytes.slice(i, i + 2))/10; 43 | i += 2; 44 | } else { 45 | break; 46 | } 47 | } 48 | return decoded; 49 | } 50 | 51 | /* ****************************************** 52 | * bytes to number 53 | ********************************************/ 54 | function readUInt16LE(bytes) { 55 | var value = (bytes[1] << 8) + bytes[0]; 56 | return value & 0xffff; 57 | } 58 | 59 | function readInt16LE(bytes) { 60 | var ref = readUInt16LE(bytes); 61 | return ref > 0x7fff ? ref - 0x10000 : ref; 62 | } 63 | -------------------------------------------------------------------------------- /ug8x_uplink.js: -------------------------------------------------------------------------------- 1 | // LoRaObject is global variable in javascript 2 | 3 | // ”applicationID" :1 //application ID 4 | // "applicationName":"cloud", //application name 5 | // "deviceName":"24e1641092176759", // lorawan node device name 6 | // "devEUI":"24e1641092176759", // rx lorawan node deveui 7 | // "time": 2020-0327T12:39:05.547336Z // uplink receive time 8 | // rxInfo": // lorawan gateway information related to lora 9 | // [{ 10 | // "mac":"24e124fffef021be", // ID of the receiving gateway 11 | // "rssi":-57, // signal strength (dBm) 12 | // "loRaSNR":10, // signal to noise ratio 13 | // "name":"local_gateway", // name of the receiving gateway 14 | // "latitude":0, // latitude of the receiving gateway 15 | // "longitude":0, // longitude of the receiving gateway 16 | // "altitude":0 // altitude of the receiving gateway 17 | // }], 18 | 19 | // "txInfo": //lorawan node tx info 20 | // { 21 | // "frequency":868300000, //frequency used for transmission 22 | // “dataRate": 23 | // { 24 | // "modulation":"LORA", //LORA 25 | // "bandwidth":125, //bandwidth used for transmission 26 | // "spreadFactor":7 //spreadFactor used for transmission 27 | // } 28 | // ,"adr":false, // device ADR status 29 | // "codeRate":"4/5" //codeRate 30 | // }, 31 | 32 | // "fCnt":0, // frame-counter 33 | // "fPort":85, // FPort 34 | // "data":"AWcAAAJoAA==", // base64 encoded payload (decrypted) 35 | 36 | 37 | //example Decode function : 38 | function Decode(fPort, bytes) { 39 | var decoder = {}; 40 | if (fPort == 85) { 41 | decoder.sensorsId = LoRaObject.devEUI 42 | decoder.flag = "A" 43 | decoder.addTime = LoRaObject.time 44 | decoder.value = bytes[0]; 45 | } 46 | 47 | return decoder; 48 | } 49 | 50 | //Encoded json : 51 | { 52 | "sensorsId":"24e1242191336951", 53 | "addTime":"2020-0327T12:39:05.547336Z", 54 | "flag":"A", 55 | "value":255 56 | } 57 | -------------------------------------------------------------------------------- /AM100.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Ursalink AM100 / AM102 Payload Decoder 3 | * 4 | * definition [channel-id] [channel-type] [channel-data] 5 | * 6 | * 01: battery -> 0x01 0x75 [1byte] Unit: % 7 | * 03: temperature -> 0x03 0x67 [2bytes] Unit: °C 8 | * 04: humidity -> 0x04 0x68 [1byte] Unit: % 9 | * 05: PIR -> 0x05 0x6A [2bytes] 10 | * 06: illumination -> 0x06 0x65 [6bytes] Unit: lux 11 | * ------------------------------------------ AM100 12 | * 07: CO2 -> 0x07 0x7D [2bytes] Unit: ppm 13 | * 08: TVOC -> 0x08 0x7D [2bytes] Unit: ppb 14 | * 09: Pressure -> 0x09 0x73 [2bytes] Unit: hPa 15 | * ------------------------------------------ AM102 16 | */ 17 | function Decoder(bytes, port) { 18 | var decoded = {}; 19 | 20 | for (var i = 0; i < bytes.length;) { 21 | var channel_id = bytes[i++]; 22 | var channel_type = bytes[i++]; 23 | // BATTERY 24 | if (channel_id === 0x01 && channel_type === 0x75) { 25 | decoded.battery = bytes[i]; 26 | i += 1; 27 | } 28 | // TEMPERATURE 29 | else if (channel_id === 0x03 && channel_type === 0x67) { 30 | decoded.temperature = readInt16LE(bytes.slice(i, i + 2)) / 10; 31 | i += 2; 32 | } 33 | // HUMIDITY 34 | else if (channel_id === 0x04 && channel_type === 0x68) { 35 | decoded.humidity = bytes[i] / 2; 36 | i += 1; 37 | } 38 | // PIR 39 | else if (channel_id === 0x05 && channel_type === 0x6A) { 40 | decoded.activity = readInt16LE(bytes.slice(i, i + 2)); 41 | i += 2; 42 | } 43 | // LIGHT 44 | else if (channel_id === 0x06 && channel_type === 0x65) { 45 | decoded.illumination = readInt16LE(bytes.slice(i, i+2)); 46 | // decoded.infrared_and_visible = readInt16LE(bytes.slice(i + 2, i + 4)); 47 | // decoded.infrared = readInt16LE(bytes.slice(i + 4, i + 6)); 48 | i += 6; 49 | } 50 | // CO2 51 | else if (channel_id === 0x07 && channel_type === 0x7D) { 52 | decoded.co2 = readInt16LE(bytes.slice(i, i + 2)); 53 | i += 2; 54 | } 55 | // TVOC 56 | else if (channel_id === 0x08 && channel_type === 0x7D) { 57 | decoded.tvoc = readInt16LE(bytes.slice(i, i + 2)); 58 | i += 2; 59 | } 60 | // PRESSURE 61 | else if (channel_id === 0x09 && channel_type === 0x73) { 62 | decoded.pressure = readInt16LE(bytes.slice(i, i + 2))/10; 63 | i += 2; 64 | } else { 65 | break; 66 | } 67 | } 68 | return decoded; 69 | } 70 | 71 | /* ****************************************** 72 | * bytes to number 73 | ********************************************/ 74 | function readUInt16LE(bytes) { 75 | var value = (bytes[1] << 8) + bytes[0]; 76 | return value & 0xffff; 77 | } 78 | 79 | function readInt16LE(bytes) { 80 | var ref = readUInt16LE(bytes); 81 | return ref > 0x7fff ? ref - 0x10000 : ref; 82 | } 83 | -------------------------------------------------------------------------------- /uc11-n1.js: -------------------------------------------------------------------------------- 1 | // N1: Payload Decoder 2 | function Decoder(bytes, port) { 3 | var decoded = {}; 4 | 5 | for (i = 0; i < bytes.length;) { 6 | // BATTERY 7 | if (bytes[i] == 0x01) { 8 | decoded.battery = bytes[i + 2]; 9 | i += 3; 10 | continue; 11 | } 12 | 13 | // GPIO 14 | if (bytes[i] == 0x03) { 15 | decoded.gpio1 = bytes[i + 2] === 0 ? "off" : "on"; 16 | i += 3; 17 | continue; 18 | } 19 | 20 | if (bytes[i] == 0x04 && bytes[i + 1] !== 0xc8) { 21 | decoded.gpio2 = bytes[i + 2] === 0 ? "off" : "on"; 22 | i += 3; 23 | continue; 24 | } 25 | if (bytes[i] == 0x04 && bytes [i + 1] == 0xc8){ 26 | //Pulse Counter 27 | decoded.counter = readUInt32LE(bytes.slice(i + 2, i + 6)) ; 28 | i += 6; 29 | continue; 30 | } 31 | 32 | // ADC 33 | if (bytes[i] == 0x05) { 34 | decoded.adc1 = {}; 35 | decoded.adc1.cur = readInt16LE(bytes.slice(i + 2, i + 4)) / 100; 36 | decoded.adc1.min = readInt16LE(bytes.slice(i + 4, i + 6)) / 100; 37 | decoded.adc1.max = readInt16LE(bytes.slice(i + 6, i + 8)) / 100; 38 | decoded.adc1.avg = readInt16LE(bytes.slice(i + 8, i + 10)) / 100; 39 | i += 10; 40 | continue; 41 | } 42 | 43 | if (bytes[i] == 0x06) { 44 | decoded.adc2 = {}; 45 | decoded.adc2.cur = readInt16LE(bytes.slice(i + 2, i + 4)) / 100; 46 | decoded.adc2.min = readInt16LE(bytes.slice(i + 4, i + 6)) / 100; 47 | decoded.adc2.max = readInt16LE(bytes.slice(i + 6, i + 8)) / 100; 48 | decoded.adc2.avg = readInt16LE(bytes.slice(i + 8, i + 10)) / 100; 49 | i += 10; 50 | continue; 51 | } 52 | 53 | // MODBUS 54 | if (bytes[i] == 0xFF && bytes[i + 1] == 0x0E) { 55 | var chnId = bytes[i + 2]; 56 | var packageType = bytes[i + 3]; 57 | var dataType = packageType & 7; 58 | var dataLength = packageType >> 3; 59 | var chn = 'chn' + chnId; 60 | switch (dataType) { 61 | case 0: 62 | decoded[chn] = bytes[i + 4] ? "on" : "off"; 63 | i += 5; 64 | break; 65 | case 1: 66 | decoded[chn] = bytes[i + 4]; 67 | i += 5; 68 | break; 69 | case 2: 70 | case 3: 71 | decoded[chn] = readUInt16LE(bytes.slice(i + 4, i + 6)); 72 | i += 6; 73 | break; 74 | case 4: 75 | case 6: 76 | decoded[chn] = readUInt32LE(bytes.slice(i + 4, i + 8)); 77 | i += 8; 78 | break; 79 | case 5: 80 | case 7: 81 | decoded[chn] = readFloatLE(bytes.slice(i + 4, i + 8)); 82 | i += 8; 83 | break; 84 | } 85 | } 86 | } 87 | 88 | return decoded; 89 | } 90 | 91 | /* ****************************************** 92 | * bytes to number 93 | ********************************************/ 94 | function readUInt8LE(bytes) { 95 | return (bytes & 0xFF); 96 | } 97 | 98 | function readInt8LE(bytes) { 99 | var ref = readUInt8LE(bytes); 100 | return (ref > 0x7F) ? ref - 0x100 : ref; 101 | } 102 | 103 | function readUInt16LE(bytes) { 104 | var value = (bytes[1] << 8) + bytes[0]; 105 | return (value & 0xFFFF); 106 | } 107 | 108 | function readInt16LE(bytes) { 109 | var ref = readUInt16LE(bytes); 110 | return (ref > 0x7FFF) ? ref - 0x10000 : ref; 111 | } 112 | 113 | function readUInt32LE(bytes) { 114 | var value = (bytes[3] << 24) + (bytes[2] << 16) + (bytes[1] << 8) + bytes[0]; 115 | return (value & 0xFFFFFFFF); 116 | } 117 | 118 | function readInt32LE(bytes) { 119 | var ref = readUInt32LE(bytes); 120 | return (ref > 0x7FFFFFFF) ? ref - 0x100000000 : ref; 121 | } 122 | 123 | function readFloatLE(bytes) { 124 | // JavaScript bitwise operators yield a 32 bits integer, not a float. 125 | // Assume LSB (least significant byte first). 126 | var bits = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0]; 127 | var sign = (bits >>> 31 === 0) ? 1.0 : -1.0; 128 | var e = bits >>> 23 & 0xff; 129 | var m = (e === 0) ? (bits & 0x7fffff) << 1 : (bits & 0x7fffff) | 0x800000; 130 | var f = sign * m * Math.pow(2, e - 150); 131 | return f; 132 | } 133 | --------------------------------------------------------------------------------