tempestas

A REST API for processing sensor.community data
git clone https://git.bracken.jp/tempestas.git
Log | Files | Refs | README | LICENSE

tempestas.js (2984B)


      1 /* Warning: I am not a web developer and have absolutely zero idea what I'm
      2    doing. This is almost certainly composed entirely of Very Bad Ideas. */
      3 
      4 // The JSON API server base URL.
      5 const API_SERVER = 'http://minerva'
      6 
      7 // TODO: automate colour generation.
      8 var colors = ['rgb(255, 99, 132)', 'rgb(255, 159, 64)', 'rgb(75, 192, 192)'];
      9 var sensors = [];
     10 var charts = [
     11   {
     12     id:          'chart-temperature',
     13     title:       'Temperature (°C)',
     14     readingType: 'BME280_temperature'
     15   },
     16   {
     17     id:          'chart-humidity',
     18     title:       'Humidity (%)',
     19     readingType: 'BME280_humidity'},
     20   {
     21     id:          'chart-pressure',
     22     title:       'Pressure (Pa)',
     23     readingType: 'BME280_pressure'
     24   },
     25   {
     26     id:          'chart-pm25',
     27     title:       'Particulate Matter 2.5 μm (μg/m³)',
     28     readingType: 'SDS_P1'
     29   },
     30   {
     31     id:          'chart-pm10',
     32     title:       'Particulate Matter 10 μm (μg/m³)',
     33     readingType: 'SDS_P2'
     34   },
     35   {
     36     id:          'chart-pressure',
     37     title:       'Pressure (Pa)',
     38     readingType: 'BME280_pressure'
     39   },
     40 ];
     41 var sensorReadings = {};
     42 
     43 var sensorUrl = API_SERVER + '/sensor/sensors/';
     44 fetch(sensorUrl)
     45   .then((response) => { return response.json(); })
     46   .then((data) => {
     47     data.forEach((sensor, i) => {
     48       sensor.color = colors[i];
     49       sensors.push(sensor);
     50     });
     51     charts.forEach((chart, i) => {
     52       sensorReadings[chart.id] = {};
     53       sensors.forEach((sensor, i) => fetchSensorData(sensor.id, chart));
     54     });
     55 });
     56 
     57 function fetchSensorData(sensorId, chart) {
     58   var url = API_SERVER + '/sensor/reading/' + sensorId + '/' + chart.readingType;
     59   fetch(url).then((response) => {
     60     return response.json();
     61   }).then((data) => {
     62     if (data != null && data.length > 0) {
     63       sensorId = data[0].sensor_id;
     64       sensorReadings[chart.id][sensorId] = data;
     65     }
     66     updateChart(chart);
     67   });
     68 }
     69 
     70 function updateChart(chart) {
     71   for (let i = 0; i < sensors.length; i++) {
     72     var sensorId = sensors[i].id;
     73     if (sensorReadings[chart.id][sensorId] == null) {
     74       return;
     75     }
     76   }
     77 
     78   data = {
     79     labels: sensorReadings[chart.id][sensors[0].id].map(e => Date.parse(e.time)),
     80     datasets: [],
     81   };
     82   for (let i = 0; i < sensors.length; i++) {
     83     var sensorId = sensors[i].id;
     84     data.datasets.push({
     85       data: sensorReadings[chart.id][sensorId].map(e => { return {x: Date.parse(e.time), y: e.value}; }),
     86       label: sensors[i].name,
     87       radius: 0,
     88       borderWidth: 1,
     89       borderColor: sensors[i].color,
     90       fill: false,
     91     });
     92   }
     93 
     94   var ctx = document.getElementById(chart.id).getContext('2d');
     95   var chart = new Chart(ctx, {
     96     type: 'line',
     97     data: data,
     98     options: {
     99       plugins: {
    100         title: {
    101           display: true,
    102           text: chart.title,
    103         },
    104         legend: {
    105           position: 'bottom',
    106         },
    107       },
    108       scales: {
    109         x: {
    110           type: 'time',
    111           time: {
    112             unit: 'hour',
    113           },
    114         },
    115       },
    116     },
    117   });
    118 }