fix this thing

- add PM10 + PM2.5 sensors
- rebrand / translate texts to german
- make it work with current API

TODO:
- proper translation service?
- load sensors from API instead of hardcode
- make box an URL param
- make it work with current node
- sync scroll between charts
master
Norwin 6 years ago
parent fcbe8f53f8
commit c4aec1ce04
Signed by: norwin
GPG Key ID: 24BC059DE24C43A3

@ -1 +0,0 @@
sense.devseed.com

@ -31,14 +31,20 @@ export function fetchSensorData (sensor, toDate) {
}
return response.json();
})
.then(json => {
return json.sort((a, b) => {
return new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime();
});
})
.then(json => {
dispatch(receiveSensorData(sensor, json));
// setTimeout(() => {
// dispatch(receiveSensorData(sensor, json));
// }, Math.ceil(Math.random() * 5000));
}, e => {
// }, Math.ceil(Math.random() * 2000));
})
.catch(e => {
console.log('e', e);
return dispatch(receiveSensorData(null, null, 'Data not available'));
return dispatch(receiveSensorData(sensor, null, 'Data not available'));
});
};
}

@ -13,3 +13,9 @@ export const RECEIVE_SENSOR_DATA_UV = 'RECEIVE_SENSOR_DATA_UV';
export const REQUEST_SENSOR_DATA_HUMIDITY = 'REQUEST_SENSOR_DATA_HUMIDITY';
export const RECEIVE_SENSOR_DATA_HUMIDITY = 'RECEIVE_SENSOR_DATA_HUMIDITY';
export const REQUEST_SENSOR_DATA_PM10 = 'REQUEST_SENSOR_DATA_PM10';
export const RECEIVE_SENSOR_DATA_PM10 = 'RECEIVE_SENSOR_DATA_PM10';
export const REQUEST_SENSOR_DATA_PM25 = 'REQUEST_SENSOR_DATA_PM25';
export const RECEIVE_SENSOR_DATA_PM25 = 'RECEIVE_SENSOR_DATA_PM25';

@ -23,7 +23,6 @@ var LineChart = React.createClass({
},
componentDidMount: function () {
// console.log('LineChart componentDidMount');
// Debounce event.
this.onWindowResize = _.debounce(this.onWindowResize, 200);
@ -38,13 +37,11 @@ var LineChart = React.createClass({
},
componentWillUnmount: function () {
// console.log('LineChart componentWillUnmount');
window.removeEventListener('resize', this.onWindowResize);
this.chart.destroy();
},
componentDidUpdate: function (prevProps/* prevState */) {
console.log('LineChart componentDidUpdate');
componentDidUpdate: function (prevProps) {
this.chart.pauseUpdate();
if (prevProps.data !== this.props.data) {
this.chart.data(this.props.data);

@ -60,12 +60,14 @@ var SensorWidget = React.createClass({
data={plotData} />
</div>
) : null}
{!plotData.length && fetching ? <p className='card__loading'>Loading Data...</p> : null}
{!plotData.length ? <p className='card__loading'>
{fetching ? 'Lade Daten...' : 'Keine Daten verfügbar'}
</p> : null}
</div>
<div className='metrics'>
<ul className='metrics__list'>
<li><strong>{avgs !== null ? numDisplay(avgs.today, 1, unit) : '--'}</strong> avg today</li>
<li><strong>{avgs !== null ? numDisplay(avgs.yesterday, 1, unit) : '--'}</strong> avg yesterday</li>
<li><strong>{avgs !== null ? numDisplay(avgs.today, 1, unit) : '--'}</strong> heute</li>
<li><strong>{avgs !== null ? numDisplay(avgs.yesterday, 1, unit) : '--'}</strong> gestern</li>
</ul>
</div>
</div>

@ -4,14 +4,17 @@
*/
module.exports = {
environment: 'production',
api: 'http://opensensemap.org:8000',
api: 'https://api.opensensemap.org',
title: 'Begga Weer',
senseBox: {
id: '570629b945fd40c8197462fb',
'sensorId--uv': '570629b945fd40c8197462fd',
'sensorId--luminosity': '570629b945fd40c8197462fe',
'sensorId--pressure': '570629b945fd40c8197462ff',
'sensorId--humidity': '570629b945fd40c819746300',
'sensorId--temperature': '570629b945fd40c819746301'
id: '5b26181b1fef04001b69093c',
'sensorId--pm25': '5b26181b1fef04001b69093d',
'sensorId--pm10': '5b26181b1fef04001b69093e',
'sensorId--uv': '5b26181b1fef04001b69093f',
'sensorId--luminosity': '5b26181b1fef04001b690940',
'sensorId--pressure': '5b26181b1fef04001b690941',
'sensorId--humidity': '5b26181b1fef04001b690942',
'sensorId--temperature': '5b26181b1fef04001b690943'
}
};

@ -29,6 +29,8 @@ const sensorLuminosity = sensorReducerFactory('luminosity');
const sensorPressure = sensorReducerFactory('pressure');
const sensorHumidity = sensorReducerFactory('humidity');
const sensorTemperature = sensorReducerFactory('temperature');
const sensorPm10 = sensorReducerFactory('pm10');
const sensorPm25 = sensorReducerFactory('pm25');
export default combineReducers({
routing: routeReducer,
@ -36,5 +38,7 @@ export default combineReducers({
sensorLuminosity,
sensorPressure,
sensorHumidity,
sensorTemperature
sensorTemperature,
sensorPm10,
sensorPm25,
});

@ -9,7 +9,7 @@ module.exports.numDisplay = function (n, dec = 2, suffix = '', nan = '--') {
};
module.exports.formatDate = function (date) {
let months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
let months = ['Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'];
let hour = date.getHours();
hour = hour < 10 ? `0${hour}` : hour;
let minute = date.getMinutes();

@ -1,5 +1,6 @@
'use strict';
import React from 'react';
import config from '../config';
var App = React.createClass({
displayName: 'App',
@ -15,8 +16,8 @@ var App = React.createClass({
<header className='site-header' role='banner'>
<div className='inner'>
<div className='site-headline'>
<h1 className='site-title'>Devseed Sense Lisbon
{/* <a href='/' title='Visit homepage'>Glacial Inferno</a> */}
<h1 className='site-title'>
<a href={'https://opensensemap.org/explore/' + config.senseBox.id}>{config.title}</a>
</h1>
</div>
</div>
@ -26,7 +27,7 @@ var App = React.createClass({
{this.props.children}
</main>
<footer className='site-footer' role='footer'>
<p>Made with love by <a href='https://developmentseed.org' title='Visit Development Seed website'>Development Seed</a> using <a href='http://opensensemap.org' title='Visit OpenSenseMap website'>OpenSenseMap</a> data</p>
<p> Made with love by <a href='https://developmentseed.org' title='Visit Development Seed website' target="_blank">Development Seed</a> using <a href={'https://opensensemap.org/explore/' + config.senseBox.id} title='Visit openSenseMap website' target="_blank">openSenseMap</a> data </p>
</footer>
</div>
);

@ -26,7 +26,9 @@ var Home = React.createClass({
sensorLuminosity: sensorProps,
sensorPressure: sensorProps,
sensorHumidity: sensorProps,
sensorTemperature: sensorProps
sensorTemperature: sensorProps,
sensorPm10: sensorProps,
sensorPm25: sensorProps,
},
// Having measurements every minute is too much. Group them.
@ -42,7 +44,7 @@ var Home = React.createClass({
prepareData: function (rawData) {
var data = null;
if (rawData) {
if (rawData && rawData.length) {
data = [];
rawData[0].value = +rawData[0].value;
let bucket = [rawData[0]];
@ -127,6 +129,8 @@ var Home = React.createClass({
this.props._requestSensorData('uv', daysAgo3);
this.props._requestSensorData('luminosity', daysAgo3);
this.props._requestSensorData('pressure', daysAgo3);
this.props._requestSensorData('pm10', daysAgo3);
this.props._requestSensorData('pm25', daysAgo3);
},
componentDidMount: function () {
@ -148,6 +152,8 @@ var Home = React.createClass({
let sensorUvData = this.prepareData(this.props.sensorUv.data);
let sensorLuminosityData = this.prepareData(this.props.sensorLuminosity.data);
let sensorPressureData = this.prepareData(this.props.sensorPressure.data);
let sensorPm10Data = this.prepareData(this.props.sensorPm10.data);
let sensorPm25Data = this.prepareData(this.props.sensorPm25.data);
return (
<section className='page'>
@ -167,7 +173,7 @@ var Home = React.createClass({
className='card--temp'
fetching={this.props.sensorTemperature.fetching}
fetched={this.props.sensorTemperature.fetched}
title='Temperature'
title='Temperatur'
lastReading={sensorTemperatureData.last}
avgs={sensorTemperatureData.avgs}
plotData={sensorTemperatureData.data}
@ -181,7 +187,7 @@ var Home = React.createClass({
className='card--hum'
fetching={this.props.sensorHumidity.fetching}
fetched={this.props.sensorHumidity.fetched}
title='Humidity'
title='rel. Luftfeuchte'
lastReading={sensorHumidityData.last}
avgs={sensorHumidityData.avgs}
plotData={sensorHumidityData.data}
@ -195,7 +201,7 @@ var Home = React.createClass({
className='card--uv'
fetching={this.props.sensorUv.fetching}
fetched={this.props.sensorUv.fetched}
title='Uv light'
title='Uv Licht'
lastReading={sensorUvData.last}
avgs={sensorUvData.avgs}
plotData={sensorUvData.data}
@ -209,7 +215,7 @@ var Home = React.createClass({
className='card--lux'
fetching={this.props.sensorLuminosity.fetching}
fetched={this.props.sensorLuminosity.fetched}
title='Luminosity'
title='Helligkeit'
lastReading={sensorLuminosityData.last}
avgs={sensorLuminosityData.avgs}
plotData={sensorLuminosityData.data}
@ -223,7 +229,7 @@ var Home = React.createClass({
className='card--press'
fetching={this.props.sensorPressure.fetching}
fetched={this.props.sensorPressure.fetched}
title='Air Pressure'
title='Luftdruck'
lastReading={sensorPressureData.last}
avgs={sensorPressureData.avgs}
plotData={sensorPressureData.data}
@ -233,6 +239,34 @@ var Home = React.createClass({
unit=' hPa'
/>
<SensorWidget
className='card--pm'
fetching={this.props.sensorPm10.fetching}
fetched={this.props.sensorPm10.fetched}
title='Feinstaub 10 μm'
lastReading={sensorPm10Data.last}
avgs={sensorPm10Data.avgs}
plotData={sensorPm10Data.data}
axisLineMax={30}
axisLineVal={10}
axisLineMin={0}
unit=' μg/m³'
/>
<SensorWidget
className='card--pm'
fetching={this.props.sensorPm25.fetching}
fetched={this.props.sensorPm25.fetched}
title='Feinstaub 2.5 μm'
lastReading={sensorPm25Data.last}
avgs={sensorPm25Data.avgs}
plotData={sensorPm25Data.data}
axisLineMax={30}
axisLineVal={10}
axisLineMin={0}
unit=' μg/m³'
/>
</div>
</section>
</div>
@ -250,7 +284,9 @@ function selector (state) {
sensorLuminosity: state.sensorLuminosity,
sensorPressure: state.sensorPressure,
sensorHumidity: state.sensorHumidity,
sensorTemperature: state.sensorTemperature
sensorTemperature: state.sensorTemperature,
sensorPm10: state.sensorPm10,
sensorPm25: state.sensorPm25,
};
}

@ -277,6 +277,12 @@ a:active {
}
&.card--press {
.infographic {
background: linear-gradient(#0d60dd, rgb(52, 122, 196));
}
}
&.card--pm {
.infographic {
background: linear-gradient(#616161, #607D8B);
}
@ -298,4 +304,4 @@ a:active {
p {
opacity: 0.64;
}
}
}

@ -7,15 +7,15 @@
<meta name="description" content="Devseed sense dashboards" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<title>Devseed Sense - Lisbon</title>
<title>Begga Weer</title>
<!-- Twitter -->
<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="@developmentseed" />
<meta name="twitter:title" content="Devseed Sense - Lisbon">
<meta name="twitter:description" content="Devseed sense dashboards." />
<meta name="twitter:image:src" content="assets/graphics/meta/default-meta-image.png" /
<!--/ Twitter -->
<!-- <meta name="twitter:card" content="summary" /> -->
<!-- <meta name="twitter:site" content="@developmentseed" /> -->
<!-- <meta name="twitter:title" content="Devseed Sense - Lisbon"> -->
<!-- <meta name="twitter:description" content="Devseed sense dashboards." /> -->
<!-- <meta name="twitter:image:src" content="assets/graphics/meta/default-meta-image.png" / -->
<!--/ Twitter -->
<!-- OG -->
<meta property="og:site_name" content="Devseed Sense - Lisbon" />

Loading…
Cancel
Save