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
This commit is contained in:
parent
fcbe8f53f8
commit
c4aec1ce04
12 changed files with 99 additions and 39 deletions
|
@ -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…
Add table
Reference in a new issue