create irradiance composite graph

This commit is contained in:
Eric Hulburd
2016-03-11 17:38:03 -06:00
parent 2dd9389694
commit 782f5cbf91
32 changed files with 824 additions and 379 deletions

View File

@@ -1,5 +1,7 @@
import query_string from 'query-string';
import moment from 'moment-timezone';
import EnergyDatum from './../models/energy_datum';
import ObjectUtil from './../../shared/utils/object';
import ArrayUtil from './../../shared/utils/array';
@@ -13,6 +15,9 @@ const ROUTES = [
}, {
path: /houses\/(\d+)\/(power)\/([^\/]+)\/(\d+)\/([^\/]+)\/?$/,
parameters: { 1: 'house_id', 2: 'dataset', 3: 'month', 4: 'year', 5: 'view' }
}, {
path: /(irradiance)\/([^\/]+)\/(\d+)\/([^\/]+)\/?$/,
parameters: { 1: 'dataset', 2: 'month', 3: 'year', 4: 'view' }
}
];
@@ -24,8 +29,7 @@ class StateManager {
state_manager.houses = houses;
state_manager.state = {
loading_energy_data: false,
loading_power_data: false,
loading_data: false,
graph_attr: 'consumption',
view: 'graph',
dataset: 'power',
@@ -33,55 +37,94 @@ class StateManager {
house: null,
month: null,
year: null,
power_range: null };
date_interval: null };
state_manager.history = createHistory();
state_manager.update_in_progress = false;
}
get month_i(){
return moment.monthsShort().indexOf(this.state.month);
}
get date_params(){
return ObjectUtil.filterKeys(this.state, ['year', 'month', 'power_range']);
return ObjectUtil.filterKeys(this.state, ['year', 'month', 'date_interval']);
}
get month_range(){
var state_manager = this,
house = state_manager.state.house,
start_time = house.parseMoment(`${state_manager.state.year}-${state_manager.month_i + 1}-01`, 'YYYY-M-DD'),
end_time = start_time.clone().endOf('month').unix();
start_time = start_time.unix();
if (start_time < house.data.data_from) start_time = house.data.data_from;
if (end_time > house.data.data_until) end_time = house.data.data_until;
return [start_time, end_time];
}
get year_range(){
var state_manager = this,
house = state_manager.state.house,
start_time = house.parseMoment(`${state_manager.state.year}-01-01`, 'YYYY-MM-DD'),
end_time = start_time.clone().endOf('year').unix();
start_time = start_time.unix();
if (start_time < house.data.data_from) start_time = house.data.data_from;
if (end_time > house.data.data_until) end_time = house.data.data_until;
return [start_time, end_time];
}
matchesEnergyState(){
var state_manager = this,
house = state_manager.state.house,
energy_range = state_manager.state.graph_attr === 'irradiance' ? state_manager.state.date_interval : state_manager.year_range;
if (!house.state.energy_range) return false;
return energy_range[0] === house.state.energy_range[0] && energy_range[1] === house.state.energy_range[1];
}
matchesPowerState(){
var state_manager = this,
house = state_manager.state.house,
month_range = state_manager.month_range;
if (!house.state.power_range) return false;
return month_range[0] === house.state.power_range[0] && month_range[1] === house.state.power_range[1];
}
// This will update the house state acccording to passed update parameters.
updateHouseFromState(component, fnResolve){
updateHouseFromState(component){
var state_manager = this,
house = state_manager.state.house,
promise;
if (!house) {
promise = Promise.resolve();
} else if (state_manager.state.dataset === 'energy' && (!house.energy_data || !house.matchesEnergyState(state_manager.state))){
house.setMonthState(state_manager.state);
} else if (state_manager.state.dataset === 'energy' && !state_manager.matchesEnergyState()){
promise = state_manager.setHouseEnergyFromState(component);
} else if (state_manager.state.dataset === 'power' && !house.power_data || !house.matchesPowerState(state_manager.state)){
house.setMonthState(state_manager.state);
} else if (state_manager.state.dataset === 'power' && !state_manager.matchesPowerState()){
promise = state_manager.setHousePowerFromState(component);
} else if (state_manager.state.dataset === 'irradiance'){
promise = state_manager.setIrradianceData(component);
} else {
promise = new Promise((fnResolve, fnReject)=>{
component.syncFromStateManager(fnResolve);
});
promise = Promise.resolve();
}
return promise.then(()=>{ state_manager.update_in_progress = false; })
}
setHouseEnergyFromState(component){
var state_manager = this;
state_manager.power_data_updated = true;
return new Promise((fnResolve, fnReject)=>{
component.setState({
loading_energy_data: true
}, ()=>{
state_manager.state.house.setEnergyData()
.then(()=>{
component.syncFromStateManager(fnResolve);
});
return promise.then(()=>{
state_manager.update_in_progress = false;
return new Promise((fnResolve, fnReject)=>{
component.syncFromStateManager(fnResolve);
});
});
}
powerDataRendered(){
setHouseEnergyFromState(component){
var state_manager = this;
state_manager.power_data_updated = false;
return new Promise((fnResolve, fnReject)=>{
component.setState({
loading_data: 'power'
}, ()=>{
state_manager.state.house.setEnergyData(state_manager.year_range)
.then(fnResolve);
});
});
}
setHousePowerFromState(component){
@@ -89,11 +132,49 @@ class StateManager {
house = state_manager.state.house;
return new Promise((fnResolve, fnReject)=>{
component.setState({
loading_power_data: true
loading_data: 'energy'
}, ()=>{
house.setPowerData()
.then(()=>{
component.syncFromStateManager(fnResolve);
house.setPowerData(state_manager.state.date_interval)
.then(fnResolve);
});
});
}
setIrradianceData(component){
var state_manager = this,
houses = state_manager.houses,
date_interval = state_manager.state.date_interval;
return new Promise((fnResolve, fnReject)=>{
component.setState({
loading_data: 'irradiance'
}, ()=>{
EnergyDatum.ensureEnergyDataForHouses(houses, date_interval)
.then((res)=>{
if (res instanceof Promise){
throw new Error('promise returned promise')
}
var promises = [],
data = {};
houses.forEach((house)=>{
var promise = house.setEnergyData(date_interval)
.then(()=>{
house.energy_data.forEach((energy_datum)=>{
var date_data = data[energy_datum.day_to_s];
if (!date_data){
date_data = [];
data[energy_datum.day_to_s] = date_data;
}
date_data.push(energy_datum);
});
house.closeDb();
});
promises.push(promise);
});
Promise.all(promises)
.then(()=>{
state_manager.irradiance_data = data;
fnResolve();
});
});
});
});
@@ -105,25 +186,29 @@ class StateManager {
setParams(params){
var state_manager = this,
url;
url, house, params;
if (state_manager.update_in_progress) return false;
state_manager.update_in_progress = true;
params = Object.assign({}, state_manager.state, params);
if (!params.house_id){
url = '/';
} else {
var house = state_manager.houses.find((h)=>{ return h.data.id == params.house_id; })
house.verifyMonthState(params);
if (params.dataset === 'energy'){
url = `/houses/${params.house_id}/energy/${params.year}/${params.graph_attr}/${params.view}`;
} else if (params.dataset === 'power'){
house.verifyPowerRange(params);
url = `/houses/${params.house_id}/power/${params.month}/${params.year}/${params.view}?${query_string.stringify({dates: params.power_range})}`;
} else {
url = `/houses/${house.house_id}`;
}
params = Object.assign({}, state_manager.state, params);
if (params.house_id){
house = state_manager.houses.find((h)=>{ return h.data.id == params.house_id; });
} else {
house = state_manager.state.house || state_manager.houses[0];
params.house_id = house.data.id;
}
house.verifyMonthState(params);
if (params.dataset === 'irradiance'){
params.date_interval = house.verifyPowerRange(params.date_interval || [], params);
url = `/irradiance/${params.month}/${params.year}/${params.view}?${query_string.stringify({dates: params.date_interval})}`;
} else if (params.dataset === 'energy'){
url = `/houses/${params.house_id}/energy/${params.year}/${params.graph_attr}/${params.view}`;
} else {
params.date_interval = house.verifyPowerRange(params.date_interval || [], params);
url = `/houses/${params.house_id}/power/${params.month}/${params.year}/${params.view}?${query_string.stringify({dates: params.date_interval})}`;
}
state_manager.history.push(url);
}
@@ -132,16 +217,28 @@ class StateManager {
*/
updateStateFromUrl(location, component){
var state_manager = this;
var params = state_manager.parseUrl(location.pathname),
var state_manager = this,
params = state_manager.parseUrl(location.pathname),
house = null;
if (params.dataset === 'power' && location.query.dates) {
params.power_range = [+location.query.dates[0], +location.query.dates[1]];
}
if (params.house_id || params.house_id != state_manager.state.house_id){
if (params.house_id){
house = state_manager.houses.find((h)=>{ return h.data.id == params.house_id; });
} else if (params.dataset === 'irradiance'){
// Irradiance needs a house to verify params and
house = state_manager.state.house || state_manager.houses[0];
}
state_manager.state.house = house;
if (house){
// params should already be verified if set through StateManager#setParams, but
// verify here again before setting state in case URL manually loaded.
house.verifyMonthState(params);
if (params.dataset === 'power' || params.dataset === 'irradiance') {
var date_interval = location.query.dates || [];
params.date_interval = house.verifyPowerRange([+date_interval[0], +date_interval[1]], params);
}
state_manager.state.house = house;
state_manager.state.house_id = house.data.id;
}
Object.assign(state_manager.state, params);
if (state_manager.state.house_id) {
state_manager.updateHouseFromState(component);