{"version":3,"sources":["jsdelivr-header.js","/npm/nodejs-collector@1.1.2/lib/nodejs-collector-module.js"],"names":[],"mappings":"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","file":"/npm/nodejs-collector@1.1.2/lib/nodejs-collector-module.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/nodejs-collector@1.1.2/lib/nodejs-collector-module.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","\n/* required modules */\nvar elitech = require('elitech-reader');\nvar underscore = require('underscore');\nvar fs = require('fs');\nvar request = require('request');\n\n\n/* module code */\nfunction getCollector(attributes) {\n\n  var webservice_url = false; /* POST application/json webservice url. False means that data won't be uploaded */\n  var serial_port = false; /* stores device USB/COM port. If false, we'll try to discover USB ones */\n  var device_info = false; /* stores devise information (acquired every measurement cycle) */\n  var last_timestamp = false; /* last measurement date. It is used to ensure that we'll retrieve just the latest measurements from the datalogger */\n  var upload_interval = 10; /* data upload to server inverval. In seconds. 10 is default */\n  var upload_page_size = 1000; /* max data allowed per webservice request */\n  var __ws_parser_callback = function(device, record) {\n    return {\n      location: device.info,\n      temperature: record.temp,\n      timestamp: record.time.replace('.000Z','')\n    };\n  };\n\n  /* Stores device information into device_info variable. It exits if we're not able to retrieve it. */\n  function store_device_info(info) {\n    if(info.info == '') {\n      console.log('Device identifier(info) is blank. Exiting');\n      process.exit(0);\n    } else {\n      console.log(info.info);\n      device_info=info;\n    }\n  }\n\n  /* Reads last measuremnt date from config file */\n  function read_last_date() {\n    try {\n      var obj = JSON.parse(fs.readFileSync(getConfigFile(), 'utf8'));\n        return obj.lastUpdate;\n      }catch(error) {\n        return false;\n      }\n  }\n\n  /* Stores last measurement date into config file */\n  function write_last_date() {\n    var out = {'lastUpdate': last_timestamp};\n    fs.writeFile(getConfigFile(), JSON.stringify(out), function(err) {\n        if(err) {\n          console.log(err);\n        } else {\n          read_last_date();\n        }\n    });\n  }\n\n  /* Prints all system params */\n  function print_params() {\n    console.log(`Webservice url: <<<${webservice_url}>>>`);\n    if(!webservice_url) {\n      console.log('..... Data upload is <<<DISABLED>>>!');\n    }\n\n    console.log(`Upload interval: <<<${upload_interval}>>>`);\n    console.log(`Upload page size: <<<${upload_page_size}>>>`);\n    console.log(`Elitech RC-4 Serial Port: <<<${serial_port}>>> ('false' means that it'll be retrieved automatically from operating system)`);\n    console.log(`Last upload timestamp: <<<${last_timestamp}>>>`);\n  }\n\n  /* Initializes system params */\n  function setup() {\n    return new Promise((resolve,reject) => {\n      if(attributes.ws) {\n        webservice_url = attributes.ws;\n      }\n\n      if(attributes.upload_interval) {\n        upload_interval = attributes.upload_interval;\n      }\n\n      if(attributes.upload_page_size) {\n        upload_page_size = attributes.upload_page_size;\n      }\n\n      if(attributes.port) {\n        serial_port = attributes.port;\n      }\n\n      if(attributes.data_parser) {\n        __ws_parser_callback = attributes.data_parser;\n      }\n\n      last_timestamp = read_last_date(); /* trying to retrieve it from config file */\n\n      print_params();\n\n      resolve();\n    });\n  }\n\n  /* Returns config file path (user home) */\n  function getConfigFile() {\n    return process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'] + '/config.json';\n  }\n\n  /* Sends data to remote webservice */\n  function send_data_to_server(data) {\n    if(webservice_url) {\n      console.log('Pushing data to server ... ');\n      var pageSize = upload_page_size;\n      var page = 1;\n      while(data.length > 0) {\n        var data_to_send = data.splice(0,pageSize);\n        console.log(`Uploading page ${page} with ${data_to_send.length} measurements.`);\n        page++;\n\n        request.post({url: webservice_url,\n          method: \"POST\",\n          json: true,\n          headers: {\n              \"content-type\": \"application/json\",\n          }, body: data_to_send}, function(err,httpResponse,body){\n            if(err) {\n              console.error('Error uploading data to server: ' + err);\n              console.error(\"Respose: \" + httpResponse);\n              console.error(\"Body: \" + body);\n            } else {\n              console.log(\"Upload successful\");\n            }\n        });\n      }\n    } else {\n      console.log('Data pushing skipped.')\n    }\n  }\n\n  /* Process data acquisition. Transforms data to webservice pattern */\n  function proccess_data_acquisition(data) {\n    if(data.length < 1) {\n      console.log(\"No data available.\");\n      return;\n    }\n\n    console.log(\"Data available: \" + data.length);\n\n    var record = underscore.max(data, record => new Date(record.time).getTime());\n\n    last_timestamp = record.time;\n    write_last_date();\n\n    console.log(`Updating last_timestamp to ${last_timestamp}!`);\n    var data_to_send = [];\n    for(i=0;i<data.length;i++) {\n      data_to_send.push(__ws_parser_callback(device_info, data[i]));\n    }\n\n    send_data_to_server(data_to_send);\n\n  }\n\n  function run_once_internal(port) {\n    console.log('Starting measuremnt process on device: ' + port);\n    return new Promise((resolve, reject) => {\n      var device = elitech.getDevice(port);\n      device.open()\n          .then(() => device.getDeviceInfo(), error=>reject(error))\n          .then(info => store_device_info(info), error=>reject(error))\n          .then(() => device.getData(last_timestamp), error=>reject(error))\n          .then(result => {proccess_data_acquisition(result)}, error => reject(error))\n          .then(() => device.close())\n          .then(() => resolve());\n    });\n  }\n\n  /* start measurement process on port <port> */\n  function run_internal(port) {\n    console.log(\"Starting device on port \" + port);\n    return new Promise((resolve, reject) => {\n      run_once_internal(port)\n        .then(() => setTimeout(run_loop, upload_interval * 1000))\n        .then(() => console.log(`Waiting ${upload_interval} seconds for the next measurement. `))\n        .then(() => resolve());\n    });\n  }\n\n  /* retrieves the serial port from local variable or from operating system */\n  function get_serial_port() {\n    return new Promise((resolve, reject) => {\n      if(serial_port) {\n        resolve(serial_port);\n      } else {\n        elitech.getElitechReader().then(port =>  {serial_port = port.comName; resolve(port.comName);}, error =>  reject(error));\n      }\n    });\n  }\n\n  /* runs just once */\n  function run_once() {\n    return new Promise((resolve, reject) => {\n      get_serial_port()\n        .then(port => run_once_internal(port))\n        .then(a => resolve(a), b=>reject(b));\n    });\n  }\n\n  /* run in loop  */\n  function run_loop() {\n    return new Promise((resolve, reject) => {\n      get_serial_port()\n        .then(port => run_internal(port))\n        .then(a => resolve(a), b=>reject(b));\n    });\n  };\n\n\n  /* visible functions */\n  return {\n    setup: setup,\n    run_loop: run_loop,\n    run_once: run_once,\n    get_config_file: getConfigFile,\n    list_ports: list_ports\n\t};\n}\n\n/* returns all serial ports */\nfunction list_ports() {\n  return new Promise((resolve, reject) => {\n    elitech.getSerialPorts().then(ports=>resolve(ports), error=>reject(error));\n  });\n}\n\n/* registering modules */\nexports.getCollector = getCollector;\nexports.list_ports = list_ports;\n/* end */\n"]}