Skip to content

Instantly share code, notes, and snippets.

@josegomezr
Last active April 25, 2019 17:10
Show Gist options
  • Save josegomezr/24bfa2e47050b8f4eec30c28708d9077 to your computer and use it in GitHub Desktop.
Save josegomezr/24bfa2e47050b8f4eec30c28708d9077 to your computer and use it in GitHub Desktop.
DataLogger Parser for termoDaQ

DataLogger parser for TermoDaQ

Parsed the raw data gathered by TermoDaQ into js objects.

Test it

> node main.js 
[ { rawLine:
     '91.458364,123.178515,9/25/2019,09:0:16.00,80.3375,80.1000,80.1000,0.9687,0.1365',
    rawFields:
     { latitude: '91.458364',
       longitude: '123.178515',
       date: '9/25/2019',
       time: '09:0:16.00',
       tempInternal: '80.3375',
       tempWater: '80.1000',
       tempAir: '80.1000',
       pressure: '0.9687',
       uv: '0.1365' },
    latitude: 91.458364,
    longitude: 123.178515,
    date: 2019-09-25T00:00:00.000Z,
    time: '09:0:16.00',
    tempInternal: 80.3375,
    tempWater: 80.1,
    tempAir: 80.1,
    pressure: 125.695858,
    uv: 0,
    datetime: 2019-09-25T09:00:16.000Z },
  { rawLine:
     '11.458364,-65.178515,10/25/2019,14:46:34.00,28.6875,27.5000,27.5000,0.2963,0.8440',
    rawFields:
     { latitude: '11.458364',
       longitude: '-65.178515',
       date: '10/25/2019',
       time: '14:46:34.00',
       tempInternal: '28.6875',
       tempWater: '27.5000',
       tempAir: '27.5000',
       pressure: '0.2963',
       uv: '0.8440' },
    latitude: 11.458364,
    longitude: -65.178515,
    date: 2019-10-25T00:00:00.000Z,
    time: '14:46:34.00',
    tempInternal: 28.6875,
    tempWater: 27.5,
    tempAir: 27.5,
    pressure: 15.74673,
    uv: 7,
    datetime: 2019-10-25T14:46:34.000Z } ]
// CommonJS
const DatalogParser = require('./parser');
var rawData = "";
rawData += "91.458364,123.178515,9/25/2019,09:0:16.00,80.3375,80.1000,80.1000,0.9687,0.1365\r\n"
rawData += "11.458364,-65.178515,10/25/2019,14:46:34.00,28.6875,27.5000,27.5000,0.2963,0.8440\r\n"
let parser = new DatalogParser();
var results = parser.parse(rawData);
console.log(results)
const utils = require('./utils');
/**
* DataloggerParser
*
* Process the data gathered by datalogger.
*/
class DataloggerParser {
constructor(){
this.fields = [
'latitude', 'longitude', 'date', 'time', 'tempInternal',
'tempWater', 'tempAir', 'pressure', 'uv'
]
this.lineEnding = '\r\n'
}
/**
* parseLine
*
* Process a line of data
* @param {string} line - The raw data line from the data stream.
* @returns {object} the data processed.
*/
parseLine(line){
const defaultParser = (i) => i
return line.split(',').reduce((curr, next, i) => {
const key = this.fields[i]
const parserName = 'parse' + key[0].toUpperCase() + key.substring(1)
const parser = this[parserName] ? this[parserName] : defaultParser
curr.rawFields[key] = next
curr[key] = parser(next)
return curr
}, { rawLine: line, rawFields: {} })
}
/**
* postParseLine
*
* Performs aditional parsing with the whole object.
* @param {object} object - The object with processed data.
* @returns {object} the data processed.
*/
postParseLine(object){
let [hours, mins, seconds] = object.time.split(':').map(parseFloat)
let datetime = new Date(object.date)
datetime.setUTCHours(hours);
datetime.setUTCMinutes(mins);
datetime.setUTCSeconds(seconds);
object.datetime = datetime;
return object
}
/**
* postParseLine
*
* Performs aditional parsing with the whole object.
* @param {string} rawString - The whole input stream of data (usually a string).
* @returns {array} The whole data processed as an array of objects
*/
parse(input){
return input.toString().trim()
.split(this.lineEnding)
.map((line) => this.parseLine(line))
.map((obj) => this.postParseLine(obj))
}
// Custom parsers
// the pattern is parse<FieldNameInCamelCase>
parseLatitude(value){
let parsed = parseFloat(value)
return parsed
}
parseLongitude(value){
let parsed = parseFloat(value)
return parsed
}
parseDate(value){
const [month, day, year] = value.split('/').map((part) => parseFloat(part)); // m/d/y
return new Date(
Date.UTC(
year,
month -1, // monthIndex
day
)
)
}
parseTempInternal(value){
let parsed = parseFloat(value)
return parsed
}
parseTempWater(value){
let parsed = parseFloat(value)
return parsed
}
parseTempAir(value){
let parsed = parseFloat(value)
return parsed
}
/**
* parsePressure
*
* Transforms the Volts reading to kPa applying a linear mapping
* from 0.184 to 4.5
*
*
* @param {string} value - vols reading as a string.
* @returns {int} UV Index
*/
parsePressure(value){
let parsed = parseFloat(value)
let calculated = utils.map(parsed, 0.2, 4.5, 0.0, 703.125)
return utils.sillyRound(calculated, 6)
}
/**
* parseUv
*
* Transforms the Volts reading to UV Index Accoding to the following table:
*
* +--------+-------+
* | mVolts | index |
* +--------+-------+
* | <=50 | -1 | (discarded values)
* | >50 | 0 |
* | >227 | 1 |
* | >318 | 2 |
* | >408 | 3 |
* | >503 | 4 |
* | >606 | 5 |
* | >696 | 6 |
* | >795 | 7 |
* | >881 | 8 |
* | >976 | 9 |
* | >1079 | 10 |
* | >1170 | 11 |
* +----------------+
*
* @param {string} value - vols reading as a string.
* @returns {int} UV Index
*/
parseUv(value){
let parsed = parseFloat(value)*1000
let idx = -1;
if (parsed > 50) {
idx = 0;
}
if (parsed > 227) {
idx = 1;
}
if (parsed > 318) {
idx = 2;
}
if (parsed > 408) {
idx = 3;
}
if (parsed > 503) {
idx = 4;
}
if (parsed > 606) {
idx = 5;
}
if (parsed > 696) {
idx = 6;
}
if (parsed > 795) {
idx = 7;
}
if (parsed > 881) {
idx = 8;
}
if (parsed > 976) {
idx = 9;
}
if (parsed > 1079) {
idx = 10;
}
if (parsed > 1170) {
idx = 11;
}
return idx;
}
}
module.exports = DataloggerParser
function constrain(value, min=0, max=Infinity){
return Math.min(Math.max(min, value), max);
}
function map(value, in_min, in_max, out_min, out_max){
return (value - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
}
function sillyRound(value, places){
places = places || 2;
const exp = Math.pow(10, places);
return Math.round(value *exp ) / exp
}
module.exports = {
constrain: constrain,
map: map,
sillyRound: sillyRound,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment