mirror of
https://github.com/beestat/app.git
synced 2025-05-24 02:14:03 -04:00
Added 3D viewer to Visualize
Added 3D viewer to Visualize
This commit is contained in:
parent
7464630fb5
commit
c3891ffff8
@ -417,7 +417,9 @@ input[type=radio] {
|
||||
.icon.alarm_snooze:before { content: "\F068E"; }
|
||||
.icon.alpha_b:before { content: "\F0AEF"; }
|
||||
.icon.alpha_b_box:before { content: "\F0B09"; }
|
||||
.icon.arrow_expand_horizontal:before { content: "\F084E"; }
|
||||
.icon.arrow_expand_vertical:before { content: "\F084F"; }
|
||||
.icon.arrow_horizontal_lock:before { content: "\F115B"; }
|
||||
.icon.arrow_left:before { content: "\F004D"; }
|
||||
.icon.basket_fill:before { content: "\F0077"; }
|
||||
.icon.basket_unfill:before { content: "\F0078"; }
|
||||
@ -429,7 +431,8 @@ input[type=radio] {
|
||||
.icon.calendar:before { content: "\F00ED"; }
|
||||
.icon.calendar_alert:before { content: "\F0A31"; }
|
||||
.icon.calendar_edit:before { content: "\F08A7"; }
|
||||
.icon.calendar_range:before { content: "\F0679"; }
|
||||
.icon.calendar_month:before { content: "\F0E17"; }
|
||||
.icon.calendar_week:before { content: "\F0A33"; }
|
||||
.icon.cancel:before { content: "\F073A"; }
|
||||
.icon.card_plus_outline:before { content: "\F1200"; }
|
||||
.icon.card_remove_outline:before { content: "\F1605"; }
|
||||
@ -453,6 +456,7 @@ input[type=radio] {
|
||||
.icon.eye_circle:before { content: "\F0B94"; }
|
||||
.icon.eye_off:before { content: "\F0209"; }
|
||||
.icon.fan:before { content: "\F0210"; }
|
||||
.icon.fast_forward:before { content: "\F0211"; }
|
||||
.icon.fire:before { content: "\F0238"; }
|
||||
.icon.floor_plan:before { content: "\F0821"; }
|
||||
.icon.google_play:before { content: "\F02BC"; }
|
||||
@ -501,7 +505,9 @@ input[type=radio] {
|
||||
.icon.numeric_9_box:before { content: "\F03BC"; }
|
||||
.icon.open_in_new:before { content: "\F03CC"; }
|
||||
.icon.patreon:before { content: "\F0882"; }
|
||||
.icon.pause:before { content: "\F03E4"; }
|
||||
.icon.pencil:before { content: "\F03EB"; }
|
||||
.icon.play:before { content: "\F040A"; }
|
||||
.icon.plus:before { content: "\F0415"; }
|
||||
.icon.pound:before { content: "\F0423"; }
|
||||
.icon.redo:before { content: "\F044E"; }
|
||||
@ -509,6 +515,7 @@ input[type=radio] {
|
||||
.icon.resistor:before { content: "\F0B44"; }
|
||||
.icon.snowflake:before { content: "\F0717"; }
|
||||
.icon.swap_horizontal:before { content: "\F04E1"; }
|
||||
.icon.thermometer:before { content: "\F050F"; }
|
||||
.icon.thermostat:before { content: "\F0393"; }
|
||||
.icon.thumb_up:before { content: "\F0513"; }
|
||||
.icon.tune:before { content: "\F062E"; }
|
||||
|
@ -87,6 +87,7 @@ window.addEventListener('resize', rocket.throttle(100, function() {
|
||||
// First run
|
||||
var $ = rocket.extend(rocket.$, rocket);
|
||||
$.ready(function() {
|
||||
moment.suppressDeprecationWarnings = true;
|
||||
if (window.environment === 'live') {
|
||||
Sentry.init({
|
||||
'dsn': 'https://af9fd2cf6cda49dcb93dcaf02fe39fc6@sentry.io/3736982',
|
||||
|
@ -57,3 +57,84 @@ beestat.floor_plan.get_area_room = function(room, round = true) {
|
||||
|
||||
return area;
|
||||
};
|
||||
|
||||
beestat.floor_plan.get_bounding_box = function(floor_plan_id) {
|
||||
const floor_plan = beestat.cache.floor_plan[floor_plan_id];
|
||||
|
||||
let min_x = Infinity;
|
||||
let max_x = -Infinity;
|
||||
let min_y = Infinity;
|
||||
let max_y = -Infinity;
|
||||
|
||||
floor_plan.data.groups.forEach(function(group) {
|
||||
const bounding_box = beestat.floor_plan.get_bounding_box_group(group);
|
||||
|
||||
min_x = Math.min(bounding_box.left, min_x);
|
||||
max_x = Math.max(bounding_box.right, max_x);
|
||||
min_y = Math.min(bounding_box.top, min_y);
|
||||
max_y = Math.max(bounding_box.bottom, max_y);
|
||||
});
|
||||
|
||||
return {
|
||||
'width': max_x - min_x,
|
||||
'height': max_y - min_y,
|
||||
'left': min_x,
|
||||
'top': min_y,
|
||||
'right': max_x,
|
||||
'bottom': max_y,
|
||||
'x': min_x,
|
||||
'y': min_y
|
||||
};
|
||||
};
|
||||
|
||||
beestat.floor_plan.get_bounding_box_group = function(group) {
|
||||
let min_x = Infinity;
|
||||
let max_x = -Infinity;
|
||||
let min_y = Infinity;
|
||||
let max_y = -Infinity;
|
||||
|
||||
group.rooms.forEach(function(room) {
|
||||
const bounding_box = beestat.floor_plan.get_bounding_box_room(room);
|
||||
|
||||
min_x = Math.min(bounding_box.left, min_x);
|
||||
max_x = Math.max(bounding_box.right, max_x);
|
||||
min_y = Math.min(bounding_box.top, min_y);
|
||||
max_y = Math.max(bounding_box.bottom, max_y);
|
||||
});
|
||||
|
||||
return {
|
||||
'width': max_x - min_x,
|
||||
'height': max_y - min_y,
|
||||
'left': min_x,
|
||||
'top': min_y,
|
||||
'right': max_x,
|
||||
'bottom': max_y,
|
||||
'x': min_x,
|
||||
'y': min_y
|
||||
};
|
||||
};
|
||||
|
||||
beestat.floor_plan.get_bounding_box_room = function(room) {
|
||||
let min_x = Infinity;
|
||||
let max_x = -Infinity;
|
||||
let min_y = Infinity;
|
||||
let max_y = -Infinity;
|
||||
|
||||
room.points.forEach(function(point) {
|
||||
min_x = Math.min(room.x + point.x, min_x);
|
||||
max_x = Math.max(room.x + point.x, max_x);
|
||||
min_y = Math.min(room.y + point.y, min_y);
|
||||
max_y = Math.max(room.y + point.y, max_y);
|
||||
});
|
||||
|
||||
return {
|
||||
'width': max_x - min_x,
|
||||
'height': max_y - min_y,
|
||||
'left': min_x,
|
||||
'top': min_y,
|
||||
'right': max_x,
|
||||
'bottom': max_y,
|
||||
'x': min_x,
|
||||
'y': min_y
|
||||
};
|
||||
};
|
||||
|
@ -4,7 +4,7 @@ beestat.runtime_sensor = {};
|
||||
* Get a bunch of data for the current runtime_sensor rows. Includes basically
|
||||
* everything you need to make a cool chart.
|
||||
*
|
||||
* @param {number} thermostat_id The thermostat_id to get data for.
|
||||
* @param {number} sensor_ids The sensor_ids to get data for.
|
||||
* @param {object} range Range settings.
|
||||
* @param {string} key The key to pull the data from inside
|
||||
* beestat.cache.data. This exists because runtime_sensor data exists in
|
||||
@ -12,7 +12,7 @@ beestat.runtime_sensor = {};
|
||||
*
|
||||
* @return {object} The data.
|
||||
*/
|
||||
beestat.runtime_sensor.get_data = function(thermostat_id, range, key) {
|
||||
beestat.runtime_sensor.get_data = function(sensor_ids, range, key) {
|
||||
var data = {
|
||||
'x': [],
|
||||
'series': {},
|
||||
@ -51,30 +51,28 @@ beestat.runtime_sensor.get_data = function(thermostat_id, range, key) {
|
||||
beestat.style.color.lightblue.dark
|
||||
];
|
||||
|
||||
// Duration objects. These are passed by reference into the metadata.
|
||||
var durations = {};
|
||||
|
||||
var series_codes = [];
|
||||
|
||||
// Get and sort all the sensors.
|
||||
var sensors = beestat.sensor.get_sorted();
|
||||
data.metadata.sensors = sensors;
|
||||
data.metadata.sensors = [];
|
||||
|
||||
// Set up the series_codes.
|
||||
const sensor_series_colors = {};
|
||||
sensors.forEach(function(sensor, i) {
|
||||
if (sensor.thermostat_id === thermostat_id) {
|
||||
series_codes.push('temperature_' + sensor.sensor_id);
|
||||
series_codes.push('occupancy_' + sensor.sensor_id);
|
||||
sensor_ids.forEach(function(sensor_id, i) {
|
||||
const sensor = beestat.cache.sensor[sensor_id];
|
||||
|
||||
sensor_series_colors[sensor.sensor_id] = colors[i];
|
||||
series_codes.push('temperature_' + sensor.sensor_id);
|
||||
series_codes.push('occupancy_' + sensor.sensor_id);
|
||||
|
||||
if (sensor.type === 'thermostat') {
|
||||
series_codes.push('air_quality_' + sensor.sensor_id);
|
||||
series_codes.push('voc_concentration_' + sensor.sensor_id);
|
||||
series_codes.push('co2_concentration_' + sensor.sensor_id);
|
||||
}
|
||||
sensor_series_colors[sensor.sensor_id] = colors[i];
|
||||
|
||||
if (sensor.type === 'thermostat') {
|
||||
series_codes.push('air_quality_' + sensor.sensor_id);
|
||||
series_codes.push('voc_concentration_' + sensor.sensor_id);
|
||||
series_codes.push('co2_concentration_' + sensor.sensor_id);
|
||||
}
|
||||
|
||||
data.metadata.sensors.push(sensor);
|
||||
});
|
||||
|
||||
series_codes.push('dummy');
|
||||
@ -87,7 +85,6 @@ beestat.runtime_sensor.get_data = function(thermostat_id, range, key) {
|
||||
data.series[series_code] = [];
|
||||
data.metadata.series[series_code] = {
|
||||
'active': false,
|
||||
'durations': {},
|
||||
'data': {}
|
||||
};
|
||||
if (series_code === 'dummy') {
|
||||
@ -103,8 +100,6 @@ beestat.runtime_sensor.get_data = function(thermostat_id, range, key) {
|
||||
data.metadata.series[series_code].name = beestat.cache.sensor[sensor_id].name;
|
||||
data.metadata.series[series_code].color = sensor_series_colors[sensor_id];
|
||||
}
|
||||
|
||||
durations[series_code] = {'seconds': 0};
|
||||
});
|
||||
|
||||
var begin_m;
|
||||
@ -141,7 +136,7 @@ beestat.runtime_sensor.get_data = function(thermostat_id, range, key) {
|
||||
data.metadata.series.dummy.active = true;
|
||||
|
||||
if (runtime_sensors[current_m.valueOf()] !== undefined) {
|
||||
sensors.forEach(function(sensor, j) {
|
||||
data.metadata.sensors.forEach(function(sensor, j) {
|
||||
var runtime_sensor = runtime_sensors[current_m.valueOf()][sensor.sensor_id];
|
||||
if (runtime_sensor === undefined) {
|
||||
data.series['temperature_' + sensor.sensor_id].push(null);
|
||||
@ -177,7 +172,7 @@ beestat.runtime_sensor.get_data = function(thermostat_id, range, key) {
|
||||
if (runtime_sensor.occupancy === true) {
|
||||
let swimlane_properties =
|
||||
beestat.component.chart.runtime_sensor_detail_occupancy.get_swimlane_properties(
|
||||
sensors.length,
|
||||
data.metadata.sensors.length,
|
||||
j
|
||||
);
|
||||
|
||||
@ -188,7 +183,7 @@ beestat.runtime_sensor.get_data = function(thermostat_id, range, key) {
|
||||
if (sequential['occupancy_' + runtime_sensor.sensor_id] > 0) {
|
||||
let swimlane_properties =
|
||||
beestat.component.chart.runtime_sensor_detail_occupancy.get_swimlane_properties(
|
||||
sensors.length,
|
||||
data.metadata.sensors.length,
|
||||
j
|
||||
);
|
||||
|
||||
@ -201,16 +196,14 @@ beestat.runtime_sensor.get_data = function(thermostat_id, range, key) {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
sensors.forEach(function(sensor) {
|
||||
if (sensor.thermostat_id === thermostat_id) {
|
||||
data.series['temperature_' + sensor.sensor_id].push(null);
|
||||
data.series['occupancy_' + sensor.sensor_id].push(null);
|
||||
data.metadata.sensors.forEach(function(sensor) {
|
||||
data.series['temperature_' + sensor.sensor_id].push(null);
|
||||
data.series['occupancy_' + sensor.sensor_id].push(null);
|
||||
|
||||
if (sensor.type === 'thermostat') {
|
||||
data.series['air_quality_' + sensor.sensor_id].push(null);
|
||||
data.series['voc_concentration_' + sensor.sensor_id].push(null);
|
||||
data.series['co2_concentration_' + sensor.sensor_id].push(null);
|
||||
}
|
||||
if (sensor.type === 'thermostat') {
|
||||
data.series['air_quality_' + sensor.sensor_id].push(null);
|
||||
data.series['voc_concentration_' + sensor.sensor_id].push(null);
|
||||
data.series['co2_concentration_' + sensor.sensor_id].push(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
beestat.sensor = {};
|
||||
|
||||
/**
|
||||
* Get a sorted list of all sensors attached to the current thermostat.
|
||||
*
|
||||
* @param {number} thermostat_id Thermostat to get this list for.
|
||||
*
|
||||
* @return {array} The sensors.
|
||||
*/
|
||||
beestat.sensor.get_sorted = function(thermostat_id) {
|
||||
// Get and sort all the sensors.
|
||||
const sensors = [];
|
||||
Object.values(beestat.cache.sensor).forEach(function(sensor) {
|
||||
if (sensor.thermostat_id === (thermostat_id || beestat.setting('thermostat_id'))) {
|
||||
sensors.push(sensor);
|
||||
}
|
||||
});
|
||||
|
||||
sensors.sort(function(a, b) {
|
||||
return a.name.localeCompare(b.name, 'en', {'sensitivity': 'base'});
|
||||
});
|
||||
|
||||
return sensors;
|
||||
};
|
@ -68,7 +68,21 @@ beestat.setting = function(argument_1, opt_value, opt_callback) {
|
||||
|
||||
'thermostat.#.profile.ignore_solar_gain': false,
|
||||
|
||||
'floor_plan_id': null
|
||||
'visualize.data_type': 'temperature',
|
||||
'visualize.range_type': 'dynamic',
|
||||
'visualize.range_dynamic': 7,
|
||||
'visualize.range_static.begin': moment()
|
||||
.subtract(3, 'day')
|
||||
.format('MM/DD/YYYY'),
|
||||
'visualize.range_static.end': moment()
|
||||
.format('MM/DD/YYYY'),
|
||||
'visualize.floor_plan_id': null,
|
||||
'visualize.heat_map_type': 'relative',
|
||||
'visualize.heat_map_absolute.temperature.min': 70,
|
||||
'visualize.heat_map_absolute.temperature.max': 80,
|
||||
'visualize.heat_map_absolute.occupancy.min': 0,
|
||||
'visualize.heat_map_absolute.occupancy.max': 100
|
||||
|
||||
};
|
||||
|
||||
// Figure out what we're trying to do.
|
||||
|
@ -339,3 +339,61 @@ beestat.series.co2_concentration = {
|
||||
'name': 'CO₂',
|
||||
'color': beestat.style.color.blue.base
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a number of colors between two points.
|
||||
*
|
||||
* @param {Object} colors Array of colors in RGB.
|
||||
* @param {number} steps Number of colors to generate.
|
||||
*
|
||||
* @see http://forums.codeguru.com/showthread.php?259953-Code-to-create-Color-Gradient-programatically&s=4710043a327ee6059da1f8433ad1e5d2&p=795289#post795289
|
||||
*
|
||||
* @return {Array.<Object>} RGB color array
|
||||
*/
|
||||
beestat.style.generate_gradient = function(colors, steps) {
|
||||
const gradient_count = colors.length - 1;
|
||||
|
||||
let gradient = [];
|
||||
for (let j = 0; j < gradient_count; j++) {
|
||||
gradient = gradient.concat(this.generate_gradient_(
|
||||
colors[j],
|
||||
colors[j + 1],
|
||||
steps
|
||||
));
|
||||
}
|
||||
|
||||
return gradient;
|
||||
};
|
||||
|
||||
beestat.style.generate_gradient_ = function(begin, end, steps) {
|
||||
var gradient = [];
|
||||
for (var i = 0; i < steps; i++) {
|
||||
var n = i / (steps - 1);
|
||||
gradient.push({
|
||||
'r': Math.round(begin.r * (1 - n) + end.r * n),
|
||||
'g': Math.round(begin.g * (1 - n) + end.g * n),
|
||||
'b': Math.round(begin.b * (1 - n) + end.b * n)
|
||||
});
|
||||
}
|
||||
return gradient;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert a hex string to RGB components.
|
||||
*
|
||||
* @param {string} hex
|
||||
*
|
||||
* @return {object} RGB
|
||||
*/
|
||||
beestat.style.hex_to_rgb = function(hex) {
|
||||
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
return result ? {
|
||||
'r': parseInt(result[1], 16),
|
||||
'g': parseInt(result[2], 16),
|
||||
'b': parseInt(result[3], 16)
|
||||
} : null;
|
||||
};
|
||||
|
||||
beestat.style.rgb_to_hex = function(rgb) {
|
||||
return "#" + ((1 << 24) + (rgb.r << 16) + (rgb.g << 8) + rgb.b).toString(16).slice(1);
|
||||
}
|
||||
|
@ -9,33 +9,10 @@ beestat.extend(beestat.component.card, beestat.component);
|
||||
beestat.component.card.prototype.box_shadow_ = true;
|
||||
|
||||
/**
|
||||
* [get_class_name_recursive_ description]
|
||||
* Decorate
|
||||
*
|
||||
* @param {[type]} parent [description]
|
||||
* @param {[type]} opt_prefix [description]
|
||||
*
|
||||
* @return {[type]} [description]
|
||||
* @param {rocket.Elements} parent
|
||||
*/
|
||||
beestat.component.card.prototype.get_class_name_recursive_ = function(parent, opt_prefix) {
|
||||
for (var i in parent) {
|
||||
if (
|
||||
(parent[i]) &&
|
||||
(parent[i].prototype) &&
|
||||
(this instanceof parent[i])
|
||||
) {
|
||||
var name = opt_prefix ? rocket.clone(opt_prefix) : [];
|
||||
name.push(i);
|
||||
if (parent[i] === this.constructor) {
|
||||
return name;
|
||||
}
|
||||
name = this.get_class_name_recursive_(parent[i], name);
|
||||
if (name) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
beestat.component.card.prototype.decorate_ = function(parent) {
|
||||
this.hide_loading_();
|
||||
|
||||
|
@ -25,8 +25,6 @@ beestat.component.card.air_quality_detail = function(thermostat_id) {
|
||||
|
||||
beestat.dispatcher.addEventListener(
|
||||
[
|
||||
'setting.air_quality_detail_range_type',
|
||||
'setting.air_quality_detail_range_dynamic',
|
||||
'cache.data.air_quality_detail__runtime_thermostat',
|
||||
'cache.data.air_quality_detail__runtime_sensor'
|
||||
],
|
||||
@ -79,8 +77,6 @@ beestat.component.card.air_quality_detail.prototype.decorate_contents_ = functio
|
||||
chart_container.appendChild($.createElement('p').innerText('CO₂ Concentration (ppm)'));
|
||||
this.charts_.co2_concentration.render(chart_container);
|
||||
|
||||
// this.charts_.x_axis.render(chart_container);
|
||||
|
||||
// Sync extremes and crosshair.
|
||||
Object.values(this.charts_).forEach(function(source_chart) {
|
||||
Object.values(self.charts_).forEach(function(target_chart) {
|
||||
@ -149,7 +145,7 @@ beestat.component.card.air_quality_detail.prototype.decorate_contents_ = functio
|
||||
}
|
||||
|
||||
var api_call = new beestat.api();
|
||||
beestat.sensor.get_sorted().forEach(function(sensor) {
|
||||
Object.values(beestat.cache.sensor).forEach(function(sensor) {
|
||||
if (sensor.thermostat_id === self.thermostat_id_) {
|
||||
api_call.add_call(
|
||||
'runtime_sensor',
|
||||
@ -347,6 +343,8 @@ beestat.component.card.air_quality_detail.prototype.has_data_ = function() {
|
||||
* @return {object} The data.
|
||||
*/
|
||||
beestat.component.card.air_quality_detail.prototype.get_data_ = function(force) {
|
||||
const self = this;
|
||||
|
||||
if (this.data_ === undefined || force === true) {
|
||||
var range = {
|
||||
'type': beestat.setting('air_quality_detail_range_type'),
|
||||
@ -356,7 +354,10 @@ beestat.component.card.air_quality_detail.prototype.get_data_ = function(force)
|
||||
};
|
||||
|
||||
var sensor_data = beestat.runtime_sensor.get_data(
|
||||
this.thermostat_id_,
|
||||
Object.values(beestat.cache.sensor).filter(function(sensor) {
|
||||
return sensor.thermostat_id === self.thermostat_id_;
|
||||
})
|
||||
.map(sensor => sensor.sensor_id),
|
||||
range,
|
||||
'air_quality_detail__runtime_sensor'
|
||||
);
|
||||
|
@ -115,7 +115,7 @@ beestat.component.card.air_quality_summary.prototype.decorate_contents_ = functi
|
||||
}
|
||||
|
||||
var api_call = new beestat.api();
|
||||
beestat.sensor.get_sorted().forEach(function(sensor) {
|
||||
Object.values(beestat.cache.sensor).forEach(function(sensor) {
|
||||
if (
|
||||
sensor.thermostat_id === self.thermostat_id_ &&
|
||||
sensor.type === 'thermostat'
|
||||
|
@ -151,7 +151,7 @@ beestat.component.card.comparison_settings.prototype.decorate_region_ = function
|
||||
|
||||
var color = beestat.style.color.green.base;
|
||||
|
||||
var button_group = new beestat.component.tile_group();
|
||||
var tile_group = new beestat.component.tile_group();
|
||||
regions.forEach(function(region) {
|
||||
var button = new beestat.component.tile()
|
||||
.set_background_hover_color(color)
|
||||
@ -192,9 +192,9 @@ beestat.component.card.comparison_settings.prototype.decorate_region_ = function
|
||||
});
|
||||
}
|
||||
|
||||
button_group.add_button(button);
|
||||
tile_group.add_tile(button);
|
||||
});
|
||||
button_group.render(parent);
|
||||
tile_group.render(parent);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -233,7 +233,7 @@ beestat.component.card.comparison_settings.prototype.decorate_property_ = functi
|
||||
|
||||
var color = beestat.style.color.purple.base;
|
||||
|
||||
var button_group = new beestat.component.tile_group();
|
||||
var tile_group = new beestat.component.tile_group();
|
||||
property_types.forEach(function(property_type) {
|
||||
var button = new beestat.component.tile()
|
||||
.set_background_hover_color(color)
|
||||
@ -274,9 +274,9 @@ beestat.component.card.comparison_settings.prototype.decorate_property_ = functi
|
||||
});
|
||||
}
|
||||
|
||||
button_group.add_button(button);
|
||||
tile_group.add_tile(button);
|
||||
});
|
||||
button_group.render(parent);
|
||||
tile_group.render(parent);
|
||||
};
|
||||
|
||||
beestat.component.card.comparison_settings.prototype.decorate_detail_ = function(parent) {
|
||||
|
@ -8,7 +8,7 @@ beestat.component.card.floor_plan_editor = function(thermostat_id) {
|
||||
|
||||
this.thermostat_id_ = thermostat_id;
|
||||
|
||||
var change_function = beestat.debounce(function() {
|
||||
const change_function = beestat.debounce(function() {
|
||||
// todo replace these with (if entity set active false?)
|
||||
delete self.state_.active_group;
|
||||
|
||||
@ -21,10 +21,7 @@ beestat.component.card.floor_plan_editor = function(thermostat_id) {
|
||||
}, 10);
|
||||
|
||||
beestat.dispatcher.addEventListener(
|
||||
[
|
||||
'setting.floor_plan_id',
|
||||
'cache.floor_plan'
|
||||
],
|
||||
'setting.visualize.floor_plan_id',
|
||||
change_function
|
||||
);
|
||||
|
||||
@ -71,7 +68,7 @@ beestat.component.card.floor_plan_editor.prototype.decorate_contents_ = function
|
||||
});
|
||||
center_container.appendChild(get_started_button);
|
||||
} else {
|
||||
const floor_plan = beestat.cache.floor_plan[beestat.setting('floor_plan_id')];
|
||||
const floor_plan = beestat.cache.floor_plan[beestat.setting('visualize.floor_plan_id')];
|
||||
|
||||
// Set group ids if they are not set.
|
||||
floor_plan.data.groups.forEach(function(group) {
|
||||
@ -138,7 +135,7 @@ beestat.component.card.floor_plan_editor.prototype.decorate_drawing_pane_ = func
|
||||
|
||||
// Create and render a new SVG component.
|
||||
this.floor_plan_ = new beestat.component.floor_plan(
|
||||
beestat.setting('floor_plan_id'),
|
||||
beestat.setting('visualize.floor_plan_id'),
|
||||
this.state_
|
||||
);
|
||||
|
||||
@ -467,9 +464,13 @@ beestat.component.card.floor_plan_editor.prototype.decorate_info_pane_room_ = fu
|
||||
|
||||
const sensors = {};
|
||||
Object.values(beestat.cache.thermostat).forEach(function(thermostat) {
|
||||
const thermostat_sensors = beestat.sensor.get_sorted(
|
||||
thermostat.thermostat_id
|
||||
);
|
||||
const thermostat_sensors = Object.values(beestat.cache.sensor).filter(function(sensor) {
|
||||
return sensor.thermostat_id === self.thermostat_id_;
|
||||
})
|
||||
.sort(function(a, b) {
|
||||
return a.name.localeCompare(b.name, 'en', {'sensitivity': 'base'});
|
||||
});
|
||||
|
||||
sensors[thermostat.thermostat_id] = thermostat_sensors;
|
||||
});
|
||||
|
||||
@ -526,20 +527,6 @@ beestat.component.card.floor_plan_editor.prototype.get_title_ = function() {
|
||||
return 'Floor Plan';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the subtitle of the card.
|
||||
*
|
||||
* @return {string} Subtitle
|
||||
*/
|
||||
beestat.component.card.floor_plan_editor.prototype.get_subtitle_ = function() {
|
||||
if (beestat.setting('floor_plan_id') !== null) {
|
||||
const floor_plan = beestat.cache.floor_plan[beestat.setting('floor_plan_id')];
|
||||
return floor_plan.name;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the floor plan in the database. This is throttled so the update can
|
||||
* only run so fast.
|
||||
@ -547,6 +534,9 @@ beestat.component.card.floor_plan_editor.prototype.get_subtitle_ = function() {
|
||||
beestat.component.card.floor_plan_editor.prototype.update_floor_plan_ = function() {
|
||||
const self = this;
|
||||
|
||||
// Fake this event since the cache is being directly modified.
|
||||
beestat.dispatcher.dispatchEvent('cache.floor_plan');
|
||||
|
||||
window.clearTimeout(this.update_timeout_);
|
||||
this.update_timeout_ = window.setTimeout(function() {
|
||||
new beestat.api()
|
||||
@ -555,8 +545,8 @@ beestat.component.card.floor_plan_editor.prototype.update_floor_plan_ = function
|
||||
'update',
|
||||
{
|
||||
'attributes': {
|
||||
'floor_plan_id': beestat.setting('floor_plan_id'),
|
||||
'data': self.get_floor_plan_data_(beestat.setting('floor_plan_id'))
|
||||
'floor_plan_id': beestat.setting('visualize.floor_plan_id'),
|
||||
'data': self.get_floor_plan_data_(beestat.setting('visualize.floor_plan_id'))
|
||||
}
|
||||
},
|
||||
'update_floor_plan'
|
||||
@ -566,22 +556,14 @@ beestat.component.card.floor_plan_editor.prototype.update_floor_plan_ = function
|
||||
};
|
||||
|
||||
/**
|
||||
* Get floor plan data with UUIDs stripped.
|
||||
* Get cloned floor plan data.
|
||||
*
|
||||
* @param {number} floor_plan_id Floor plan ID
|
||||
*
|
||||
* @return {object} The modified floor plan data.
|
||||
*/
|
||||
beestat.component.card.floor_plan_editor.prototype.get_floor_plan_data_ = function(floor_plan_id) {
|
||||
const floor_plan = beestat.cache.floor_plan[floor_plan_id];
|
||||
const data = beestat.clone(floor_plan.data);
|
||||
data.groups.forEach(function(group) {
|
||||
delete group.group_id;
|
||||
group.rooms.forEach(function(room) {
|
||||
delete room.room_id;
|
||||
});
|
||||
});
|
||||
return data;
|
||||
return beestat.clone(beestat.cache.floor_plan[floor_plan_id].data);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -592,7 +574,7 @@ beestat.component.card.floor_plan_editor.prototype.get_floor_plan_data_ = functi
|
||||
beestat.component.card.floor_plan_editor.prototype.decorate_top_right_ = function(parent) {
|
||||
const self = this;
|
||||
|
||||
var menu = (new beestat.component.menu()).render(parent);
|
||||
const menu = (new beestat.component.menu()).render(parent);
|
||||
|
||||
if (window.is_demo === false) {
|
||||
menu.add_menu_item(new beestat.component.menu_item()
|
||||
@ -604,33 +586,24 @@ beestat.component.card.floor_plan_editor.prototype.decorate_top_right_ = functio
|
||||
).render();
|
||||
}));
|
||||
|
||||
if (Object.keys(beestat.cache.floor_plan).length > 1) {
|
||||
menu.add_menu_item(new beestat.component.menu_item()
|
||||
.set_text('Switch')
|
||||
.set_icon('swap_horizontal')
|
||||
.set_callback(function() {
|
||||
(new beestat.component.modal.change_floor_plan()).render();
|
||||
}));
|
||||
}
|
||||
|
||||
if (beestat.setting('floor_plan_id') !== null) {
|
||||
if (beestat.setting('visualize.floor_plan_id') !== null) {
|
||||
menu.add_menu_item(new beestat.component.menu_item()
|
||||
.set_text('Edit')
|
||||
.set_icon('pencil')
|
||||
.set_callback(function() {
|
||||
new beestat.component.modal.update_floor_plan(
|
||||
beestat.setting('floor_plan_id')
|
||||
beestat.setting('visualize.floor_plan_id')
|
||||
).render();
|
||||
}));
|
||||
}
|
||||
|
||||
if (beestat.setting('floor_plan_id') !== null) {
|
||||
if (beestat.setting('visualize.floor_plan_id') !== null) {
|
||||
menu.add_menu_item(new beestat.component.menu_item()
|
||||
.set_text('Delete')
|
||||
.set_icon('delete')
|
||||
.set_callback(function() {
|
||||
new beestat.component.modal.delete_floor_plan(
|
||||
beestat.setting('floor_plan_id')
|
||||
beestat.setting('visualize.floor_plan_id')
|
||||
).render();
|
||||
}));
|
||||
}
|
||||
|
@ -67,27 +67,27 @@ beestat.component.card.my_home.prototype.decorate_system_type_ = function(parent
|
||||
);
|
||||
const cool_stages_string = cool_stages > 1 ? ' (2 Stage)' : '';
|
||||
|
||||
var button_group = new beestat.component.tile_group();
|
||||
button_group.add_button(new beestat.component.tile()
|
||||
var tile_group = new beestat.component.tile_group();
|
||||
tile_group.add_tile(new beestat.component.tile()
|
||||
.set_type('pill')
|
||||
.set_background_color(beestat.series.compressor_heat_1.color)
|
||||
.set_text_color('#fff')
|
||||
.set_icon('fire')
|
||||
.set_text(heat.charAt(0).toUpperCase() + heat.slice(1) + heat_stages_string));
|
||||
button_group.add_button(new beestat.component.tile()
|
||||
tile_group.add_tile(new beestat.component.tile()
|
||||
.set_type('pill')
|
||||
.set_background_color(beestat.series.auxiliary_heat_1.color)
|
||||
.set_text_color('#fff')
|
||||
.set_icon('fire')
|
||||
.set_text(auxiliary_heat.charAt(0).toUpperCase() + auxiliary_heat.slice(1)));
|
||||
button_group.add_button(new beestat.component.tile()
|
||||
tile_group.add_tile(new beestat.component.tile()
|
||||
.set_type('pill')
|
||||
.set_background_color(beestat.series.compressor_cool_1.color)
|
||||
.set_text_color('#fff')
|
||||
.set_icon('snowflake')
|
||||
.set_text(cool.charAt(0).toUpperCase() + cool.slice(1) + cool_stages_string));
|
||||
|
||||
button_group.render(parent);
|
||||
tile_group.render(parent);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -117,7 +117,7 @@ beestat.component.card.my_home.prototype.decorate_region_ = function(parent) {
|
||||
region = null;
|
||||
}
|
||||
|
||||
var button_group = new beestat.component.tile_group();
|
||||
var tile_group = new beestat.component.tile_group();
|
||||
if (region !== null) {
|
||||
var button = new beestat.component.tile()
|
||||
.set_type('pill')
|
||||
@ -125,16 +125,16 @@ beestat.component.card.my_home.prototype.decorate_region_ = function(parent) {
|
||||
.set_text_color('#fff')
|
||||
.set_icon('map_marker')
|
||||
.set_text(region);
|
||||
button_group.add_button(button);
|
||||
tile_group.add_tile(button);
|
||||
} else {
|
||||
button_group.add_button(new beestat.component.tile()
|
||||
tile_group.add_tile(new beestat.component.tile()
|
||||
.set_type('pill')
|
||||
.set_background_color(beestat.style.color.gray.dark)
|
||||
.set_text_color('#fff')
|
||||
.set_icon('border_none_variant')
|
||||
.set_text('No Data'));
|
||||
}
|
||||
button_group.render(parent);
|
||||
tile_group.render(parent);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -147,10 +147,12 @@ beestat.component.card.my_home.prototype.decorate_property_ = function(parent) {
|
||||
|
||||
(new beestat.component.title('Property')).render(parent);
|
||||
|
||||
var button_group = new beestat.component.tile_group();
|
||||
var tile_group = new beestat.component.tile_group();
|
||||
let has_data = false;
|
||||
|
||||
if (thermostat.property.structure_type !== null) {
|
||||
button_group.add_button(new beestat.component.tile()
|
||||
has_data = true;
|
||||
tile_group.add_tile(new beestat.component.tile()
|
||||
.set_type('pill')
|
||||
.set_background_color(beestat.style.color.purple.base)
|
||||
.set_text_color('#fff')
|
||||
@ -167,7 +169,8 @@ beestat.component.card.my_home.prototype.decorate_property_ = function(parent) {
|
||||
thermostat.property.structure_type === 'semi-detached'
|
||||
)
|
||||
) {
|
||||
button_group.add_button(new beestat.component.tile()
|
||||
has_data = true;
|
||||
tile_group.add_tile(new beestat.component.tile()
|
||||
.set_type('pill')
|
||||
.set_background_color(beestat.style.color.purple.base)
|
||||
.set_text_color('#fff')
|
||||
@ -177,7 +180,8 @@ beestat.component.card.my_home.prototype.decorate_property_ = function(parent) {
|
||||
}
|
||||
|
||||
if (thermostat.property.square_feet !== null) {
|
||||
button_group.add_button(new beestat.component.tile()
|
||||
has_data = true;
|
||||
tile_group.add_tile(new beestat.component.tile()
|
||||
.set_type('pill')
|
||||
.set_background_color(beestat.style.color.purple.base)
|
||||
.set_text_color('#fff')
|
||||
@ -186,7 +190,8 @@ beestat.component.card.my_home.prototype.decorate_property_ = function(parent) {
|
||||
}
|
||||
|
||||
if (thermostat.property.age !== null) {
|
||||
button_group.add_button(new beestat.component.tile()
|
||||
has_data = true;
|
||||
tile_group.add_tile(new beestat.component.tile()
|
||||
.set_type('pill')
|
||||
.set_background_color(beestat.style.color.purple.base)
|
||||
.set_text_color('#fff')
|
||||
@ -194,8 +199,8 @@ beestat.component.card.my_home.prototype.decorate_property_ = function(parent) {
|
||||
.set_text(thermostat.property.age + ' Years'));
|
||||
}
|
||||
|
||||
if (button_group.get_buttons().length === 0) {
|
||||
button_group.add_button(new beestat.component.tile()
|
||||
if (has_data === false) {
|
||||
tile_group.add_tile(new beestat.component.tile()
|
||||
.set_type('pill')
|
||||
.set_background_color(beestat.style.color.gray.dark)
|
||||
.set_text_color('#fff')
|
||||
@ -203,7 +208,7 @@ beestat.component.card.my_home.prototype.decorate_property_ = function(parent) {
|
||||
.set_text('No Data'));
|
||||
}
|
||||
|
||||
button_group.render(parent);
|
||||
tile_group.render(parent);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -60,6 +60,7 @@ beestat.component.card.patreon.prototype.get_title_ = function() {
|
||||
beestat.component.card.patreon.prototype.decorate_top_right_ = function(parent) {
|
||||
new beestat.component.tile()
|
||||
.set_type('pill')
|
||||
.set_shadow(false)
|
||||
.set_icon('close')
|
||||
.set_text_color('#fff')
|
||||
.set_background_hover_color(beestat.style.color.green.light)
|
||||
|
@ -25,8 +25,6 @@ beestat.component.card.runtime_sensor_detail = function(thermostat_id) {
|
||||
|
||||
beestat.dispatcher.addEventListener(
|
||||
[
|
||||
'setting.runtime_sensor_detail_range_type',
|
||||
'setting.runtime_sensor_detail_range_dynamic',
|
||||
'cache.data.runtime_sensor_detail__runtime_thermostat',
|
||||
'cache.data.runtime_sensor_detail__runtime_sensor'
|
||||
],
|
||||
@ -149,7 +147,7 @@ beestat.component.card.runtime_sensor_detail.prototype.decorate_contents_ = func
|
||||
}
|
||||
|
||||
var api_call = new beestat.api();
|
||||
beestat.sensor.get_sorted().forEach(function(sensor) {
|
||||
Object.values(beestat.cache.sensor).forEach(function(sensor) {
|
||||
if (sensor.thermostat_id === self.thermostat_id_) {
|
||||
api_call.add_call(
|
||||
'runtime_sensor',
|
||||
@ -354,6 +352,8 @@ beestat.component.card.runtime_sensor_detail.prototype.has_data_ = function() {
|
||||
* @return {object} The data.
|
||||
*/
|
||||
beestat.component.card.runtime_sensor_detail.prototype.get_data_ = function(force) {
|
||||
const self = this;
|
||||
|
||||
if (this.data_ === undefined || force === true) {
|
||||
var range = {
|
||||
'type': beestat.setting('runtime_sensor_detail_range_type'),
|
||||
@ -363,7 +363,10 @@ beestat.component.card.runtime_sensor_detail.prototype.get_data_ = function(forc
|
||||
};
|
||||
|
||||
var sensor_data = beestat.runtime_sensor.get_data(
|
||||
this.thermostat_id_,
|
||||
Object.values(beestat.cache.sensor).filter(function(sensor) {
|
||||
return sensor.thermostat_id === self.thermostat_id_;
|
||||
})
|
||||
.map(sensor => sensor.sensor_id),
|
||||
range,
|
||||
'runtime_sensor_detail__runtime_sensor'
|
||||
);
|
||||
|
@ -25,8 +25,6 @@ beestat.component.card.runtime_thermostat_detail = function(thermostat_id) {
|
||||
|
||||
beestat.dispatcher.addEventListener(
|
||||
[
|
||||
'setting.runtime_thermostat_detail_range_type',
|
||||
'setting.runtime_thermostat_detail_range_dynamic',
|
||||
'cache.data.runtime_thermostat_detail__runtime_thermostat',
|
||||
'cache.thermostat'
|
||||
],
|
||||
|
@ -509,7 +509,7 @@ beestat.component.card.runtime_thermostat_summary.prototype.decorate_top_right_
|
||||
if (beestat.thermostat.get_sync_progress(this.thermostat_id_) !== null) {
|
||||
menu.add_menu_item(new beestat.component.menu_item()
|
||||
.set_text('Past 3 Months')
|
||||
.set_icon('calendar_range')
|
||||
.set_icon('calendar_month')
|
||||
.set_callback(function() {
|
||||
if (
|
||||
beestat.setting('runtime_thermostat_summary_time_count') !== 3 ||
|
||||
@ -526,7 +526,7 @@ beestat.component.card.runtime_thermostat_summary.prototype.decorate_top_right_
|
||||
|
||||
menu.add_menu_item(new beestat.component.menu_item()
|
||||
.set_text('Past 12 Months')
|
||||
.set_icon('calendar_range')
|
||||
.set_icon('calendar_month')
|
||||
.set_callback(function() {
|
||||
if (
|
||||
beestat.setting('runtime_thermostat_summary_time_count') !== 12 ||
|
||||
@ -543,7 +543,7 @@ beestat.component.card.runtime_thermostat_summary.prototype.decorate_top_right_
|
||||
|
||||
menu.add_menu_item(new beestat.component.menu_item()
|
||||
.set_text('All Time')
|
||||
.set_icon('calendar_range')
|
||||
.set_icon('calendar_month')
|
||||
.set_callback(function() {
|
||||
if (
|
||||
beestat.setting('runtime_thermostat_summary_time_count') !== 0 ||
|
||||
|
@ -25,13 +25,19 @@ beestat.component.card.sensors.prototype.decorate_contents_ = function(parent) {
|
||||
|
||||
var sensors = [];
|
||||
var internal_sensor;
|
||||
beestat.sensor.get_sorted().forEach(function(sensor) {
|
||||
if (sensor.thermostat_id === beestat.setting('thermostat_id')) {
|
||||
if (sensor.type === 'thermostat') {
|
||||
internal_sensor = sensor;
|
||||
} else {
|
||||
sensors.push(sensor);
|
||||
}
|
||||
|
||||
const thermostat_sensors = Object.values(beestat.cache.sensor).filter(function(sensor) {
|
||||
return sensor.thermostat_id === beestat.setting('thermostat_id');
|
||||
})
|
||||
.sort(function(a, b) {
|
||||
return a.name.localeCompare(b.name, 'en', {'sensitivity': 'base'});
|
||||
});
|
||||
|
||||
thermostat_sensors.forEach(function(sensor) {
|
||||
if (sensor.type === 'thermostat') {
|
||||
internal_sensor = sensor;
|
||||
} else {
|
||||
sensors.push(sensor);
|
||||
}
|
||||
});
|
||||
|
||||
|
595
js/component/card/three_d.js
Normal file
595
js/component/card/three_d.js
Normal file
@ -0,0 +1,595 @@
|
||||
/**
|
||||
* 3D View
|
||||
*/
|
||||
beestat.component.card.three_d = function() {
|
||||
const self = this;
|
||||
|
||||
// Things that update the scene that don't require a rerender.
|
||||
// TODO these probably need moved to the layer instead of here
|
||||
beestat.dispatcher.addEventListener(
|
||||
[
|
||||
'setting.visualize.data_type',
|
||||
'setting.visualize.heat_map_type',
|
||||
'setting.visualize.heat_map_absolute.temperature.min',
|
||||
'setting.visualize.heat_map_absolute.temperature.max',
|
||||
'setting.visualize.heat_map_absolute.occupancy.min',
|
||||
'setting.visualize.heat_map_absolute.occupancy.max'
|
||||
], self.update_scene_.bind(this));
|
||||
|
||||
beestat.dispatcher.addEventListener('cache.floor_plan', function() {
|
||||
self.scene_.rerender();
|
||||
});
|
||||
|
||||
/*
|
||||
* When a setting is changed clear all of the data. Then rerender which will
|
||||
* trigger the loading state. Also do this when the cache changes.
|
||||
*
|
||||
* Debounce so that multiple setting changes don't re-trigger the same
|
||||
* event. This fires on the trailing edge so that all changes are accounted
|
||||
* for when rerendering.
|
||||
*/
|
||||
const change_function = beestat.debounce(function() {
|
||||
self.get_data_(true);
|
||||
self.rerender();
|
||||
}, 10);
|
||||
|
||||
beestat.dispatcher.addEventListener(
|
||||
[
|
||||
'cache.data.three_d__runtime_sensor'
|
||||
],
|
||||
change_function
|
||||
);
|
||||
|
||||
beestat.component.card.apply(this, arguments);
|
||||
};
|
||||
beestat.extend(beestat.component.card.three_d, beestat.component.card);
|
||||
|
||||
/**
|
||||
* Decorate
|
||||
*
|
||||
* @param {rocket.Elements} parent
|
||||
*/
|
||||
beestat.component.card.three_d.prototype.decorate_ = function(parent) {
|
||||
this.hide_loading_();
|
||||
|
||||
this.parent_ = parent;
|
||||
|
||||
/*
|
||||
* Unfortunate but necessary to get the card to fill the height of the flex
|
||||
* container. Everything leading up to the card has to be 100% height.
|
||||
*/
|
||||
parent.style('height', '100%');
|
||||
|
||||
this.contents_ = $.createElement('div')
|
||||
.style({
|
||||
'height': '100%',
|
||||
'background': beestat.style.color.bluegray.base,
|
||||
'border-radius': beestat.style.size.border_radius
|
||||
});
|
||||
|
||||
if (this.box_shadow_ === true) {
|
||||
this.contents_.style('box-shadow', '0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)');
|
||||
}
|
||||
|
||||
parent.appendChild(this.contents_);
|
||||
|
||||
this.decorate_contents_(this.contents_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Decorate
|
||||
*
|
||||
* @param {rocket.Elements} parent
|
||||
*/
|
||||
beestat.component.card.three_d.prototype.decorate_contents_ = function(parent) {
|
||||
const drawing_pane_container = document.createElement('div');
|
||||
|
||||
parent.appendChild(drawing_pane_container);
|
||||
this.decorate_drawing_pane_(drawing_pane_container);
|
||||
|
||||
// Decorate everything.
|
||||
const controls_container = document.createElement('div');
|
||||
Object.assign(controls_container.style, {
|
||||
'position': 'absolute',
|
||||
// 'margin': 'auto',
|
||||
'top': `${beestat.style.size.gutter}px`,
|
||||
'left': '50%',
|
||||
'width': '300px',
|
||||
'margin-left': '-150px',
|
||||
'background': beestat.style.color.bluegray.base,
|
||||
'padding': `${beestat.style.size.gutter / 2}px`,
|
||||
'border-radius': `${beestat.style.size.border_radius}px`
|
||||
});
|
||||
parent.appendChild(controls_container);
|
||||
this.decorate_controls_(controls_container);
|
||||
|
||||
|
||||
// var thermostat = beestat.cache.thermostat[this.thermostat_id_];
|
||||
|
||||
let required_begin;
|
||||
let required_end;
|
||||
if (beestat.setting('visualize.range_type') === 'dynamic') {
|
||||
required_begin = moment()
|
||||
.subtract(
|
||||
beestat.setting('visualize.range_dynamic'),
|
||||
'day'
|
||||
)
|
||||
.hour(0)
|
||||
.minute(0)
|
||||
.second(0);
|
||||
|
||||
required_end = required_begin
|
||||
.clone()
|
||||
.hour(23)
|
||||
.minute(59)
|
||||
.second(59);
|
||||
} else {
|
||||
required_begin = moment(
|
||||
beestat.setting('visualize.range_static_begin') + ' 00:00:00'
|
||||
);
|
||||
required_end = moment(
|
||||
beestat.setting('visualize.range_static_end') + ' 23:59:59'
|
||||
);
|
||||
}
|
||||
|
||||
// Don't go before there's data.
|
||||
/* required_begin = moment.max(
|
||||
required_begin,
|
||||
moment.utc(thermostat.data_begin)
|
||||
);*/
|
||||
|
||||
// Don't go after now.
|
||||
/* required_end = moment.min(
|
||||
required_end,
|
||||
moment().subtract(1, 'hour')
|
||||
);*/
|
||||
|
||||
/**
|
||||
* If the needed data exists in the database and the runtime_sensor
|
||||
* cache is empty, then query the data. If the needed data does not exist in
|
||||
* the database, check every 2 seconds until it does.
|
||||
*/
|
||||
// TODO somewhat problematic because I need to check if data is synced from multiple thermostats now
|
||||
// if (beestat.thermostat.data_synced(this.thermostat_id_, required_begin, required_end) === true) {
|
||||
const sensor_ids = Object.keys(this.get_sensor_ids_map_());
|
||||
if (sensor_ids.length > 0) {
|
||||
if (true) {
|
||||
if (beestat.cache.data.three_d__runtime_sensor === undefined) {
|
||||
// console.log('data is undefined need to load it');
|
||||
this.show_loading_('Fetching');
|
||||
|
||||
var value;
|
||||
var operator;
|
||||
// var value = [
|
||||
// required_begin.format(),
|
||||
// required_end.format()
|
||||
// ];
|
||||
// var operator = 'between';
|
||||
|
||||
if (beestat.setting('visualize.range_type') === 'dynamic') {
|
||||
value = required_begin.format();
|
||||
operator = '>=';
|
||||
} else {
|
||||
value = [
|
||||
required_begin.format(),
|
||||
required_end.format()
|
||||
];
|
||||
operator = 'between';
|
||||
}
|
||||
|
||||
const sensor_ids = Object.keys(this.get_sensor_ids_map_());
|
||||
// if (sensor_ids.length > 0) {
|
||||
const api_call = new beestat.api();
|
||||
sensor_ids.forEach(function(sensor_id) {
|
||||
api_call.add_call(
|
||||
'runtime_sensor',
|
||||
'read',
|
||||
{
|
||||
'attributes': {
|
||||
'sensor_id': sensor_id,
|
||||
'timestamp': {
|
||||
'value': value,
|
||||
'operator': operator
|
||||
}
|
||||
}
|
||||
},
|
||||
'runtime_sensor_' + sensor_id
|
||||
);
|
||||
});
|
||||
|
||||
api_call.set_callback(function(response) {
|
||||
var runtime_sensors = [];
|
||||
for (var alias in response) {
|
||||
var r = response[alias];
|
||||
runtime_sensors = runtime_sensors.concat(r);
|
||||
}
|
||||
beestat.cache.set('data.three_d__runtime_sensor', runtime_sensors);
|
||||
});
|
||||
|
||||
api_call.send();
|
||||
|
||||
// }
|
||||
} else if (this.has_data_() === false) {
|
||||
console.info('has data false');
|
||||
/*chart_container.style('filter', 'blur(3px)');
|
||||
var no_data = $.createElement('div');
|
||||
no_data.style({
|
||||
'position': 'absolute',
|
||||
'top': 0,
|
||||
'left': 0,
|
||||
'width': '100%',
|
||||
'height': '100%',
|
||||
'display': 'flex',
|
||||
'flex-direction': 'column',
|
||||
'justify-content': 'center',
|
||||
'text-align': 'center'
|
||||
});
|
||||
no_data.innerText('No data to display');
|
||||
container.appendChild(no_data);*/
|
||||
}
|
||||
} else {
|
||||
this.show_loading_('Syncing');
|
||||
window.setTimeout(function() {
|
||||
new beestat.api()
|
||||
.add_call(
|
||||
'thermostat',
|
||||
'read_id',
|
||||
{
|
||||
'attributes': {
|
||||
'inactive': 0
|
||||
}
|
||||
},
|
||||
'thermostat'
|
||||
)
|
||||
.set_callback(function(response) {
|
||||
beestat.cache.set('thermostat', response);
|
||||
self.rerender();
|
||||
})
|
||||
.send();
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Decorate the drawing pane.
|
||||
*
|
||||
* @param {HTMLDivElement} parent
|
||||
*/
|
||||
beestat.component.card.three_d.prototype.decorate_drawing_pane_ = function(parent) {
|
||||
const self = this;
|
||||
|
||||
// Create the scene
|
||||
this.scene_ = new beestat.component.scene(
|
||||
beestat.setting('visualize.floor_plan_id'),
|
||||
this.get_data_()
|
||||
);
|
||||
|
||||
// Set the initial date.
|
||||
if (this.has_data_() === true) {
|
||||
this.update_scene_();
|
||||
this.scene_.render($(parent));
|
||||
|
||||
if (beestat.setting('visualize.range_type') === 'dynamic') {
|
||||
this.date_m_ = moment()
|
||||
.subtract(
|
||||
beestat.setting('visualize.range_dynamic'),
|
||||
'day'
|
||||
)
|
||||
.hour(0)
|
||||
.minute(0)
|
||||
.second(0);
|
||||
} else {
|
||||
this.date_m_ = moment(
|
||||
beestat.setting('visualize.range_static_begin') + ' 00:00:00'
|
||||
);
|
||||
}
|
||||
|
||||
this.scene_.set_date(this.date_m_);
|
||||
} else {
|
||||
this.scene_.render($(parent));
|
||||
}
|
||||
|
||||
// Manage width of the scene.
|
||||
setTimeout(function() {
|
||||
if (parent.getBoundingClientRect().width > 0) {
|
||||
self.scene_.set_width(parent.getBoundingClientRect().width);
|
||||
}
|
||||
}, 0);
|
||||
|
||||
beestat.dispatcher.removeEventListener('resize.three_d');
|
||||
beestat.dispatcher.addEventListener('resize.three_d', function() {
|
||||
self.scene_.set_width(parent.getBoundingClientRect().width);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Decorate the playback controls.
|
||||
*
|
||||
* @param {HTMLDivElement} parent
|
||||
*/
|
||||
beestat.component.card.three_d.prototype.decorate_controls_ = function(parent) {
|
||||
const self = this;
|
||||
|
||||
window.clearInterval(self.interval_);
|
||||
|
||||
// Hoisting
|
||||
const range = new beestat.component.input.range();
|
||||
const right_container = document.createElement('div');
|
||||
|
||||
const container = document.createElement('div');
|
||||
Object.assign(container.style, {
|
||||
'display': 'flex',
|
||||
'align-items': 'center'
|
||||
});
|
||||
parent.appendChild(container);
|
||||
|
||||
const left_container = document.createElement('div');
|
||||
container.appendChild(left_container);
|
||||
|
||||
const play_tile = new beestat.component.tile()
|
||||
.set_icon('play')
|
||||
.set_shadow(false)
|
||||
.set_text_hover_color(beestat.style.color.green.base)
|
||||
.render($(left_container));
|
||||
play_tile.addEventListener('click', function() {
|
||||
if (self.interval_ === undefined) {
|
||||
play_tile
|
||||
.set_icon('pause')
|
||||
.set_text_hover_color(beestat.style.color.red.base);
|
||||
|
||||
self.interval_ = window.setInterval(function() {
|
||||
self.date_m_.add(5, 'minutes');
|
||||
self.scene_.set_date(self.date_m_);
|
||||
range.set_value(
|
||||
((self.date_m_.hours() * 60) + self.date_m_.minutes()) / 1440 * 288
|
||||
);
|
||||
right_container.innerText = self.date_m_.format('h:mm a');
|
||||
}, 100);
|
||||
} else {
|
||||
play_tile
|
||||
.set_icon('play')
|
||||
.set_text_hover_color(beestat.style.color.green.base);
|
||||
window.clearInterval(self.interval_);
|
||||
delete self.interval_;
|
||||
}
|
||||
});
|
||||
|
||||
const center_container = document.createElement('div');
|
||||
Object.assign(center_container.style, {
|
||||
'flex-grow': '1'
|
||||
});
|
||||
container.appendChild(center_container);
|
||||
|
||||
range
|
||||
.set_min(0)
|
||||
.set_max(287)
|
||||
.set_value(0)
|
||||
.render($(center_container));
|
||||
|
||||
right_container.innerText = '12:00 am';
|
||||
Object.assign(right_container.style, {
|
||||
'width': '70px',
|
||||
'text-align': 'right'
|
||||
});
|
||||
container.appendChild(right_container);
|
||||
|
||||
range.addEventListener('input', function() {
|
||||
play_tile
|
||||
.set_icon('play')
|
||||
.set_text_hover_color(beestat.style.color.green.base);
|
||||
window.clearInterval(self.interval_);
|
||||
delete self.interval_;
|
||||
|
||||
const minute_of_day = range.get_value() * 5;
|
||||
self.date_m_.hours(Math.floor(minute_of_day / 60));
|
||||
self.date_m_.minutes(Math.floor(minute_of_day % 60));
|
||||
right_container.innerText = self.date_m_.format('h:mm a');
|
||||
self.scene_.set_date(self.date_m_);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get data. This doesn't directly or indirectly make any API calls, but it
|
||||
* caches the data so it doesn't have to loop over everything more than once.
|
||||
*
|
||||
* @param {boolean} force Force get the data?
|
||||
*
|
||||
* @return {object} The data.
|
||||
*/
|
||||
beestat.component.card.three_d.prototype.get_data_ = function(force) {
|
||||
const self = this;
|
||||
if (this.data_ === undefined || force === true) {
|
||||
const sensor_ids_map = this.get_sensor_ids_map_();
|
||||
|
||||
this.data_ = {
|
||||
'metadata': {
|
||||
'series': {
|
||||
'temperature': {
|
||||
'min': Infinity,
|
||||
'max': -Infinity
|
||||
},
|
||||
'occupancy': {
|
||||
'min': Infinity,
|
||||
'max': -Infinity
|
||||
}
|
||||
}
|
||||
},
|
||||
'series': {
|
||||
'temperature': {},
|
||||
'occupancy': {}
|
||||
}
|
||||
};
|
||||
|
||||
if (beestat.cache.data.three_d__runtime_sensor !== undefined) {
|
||||
// Add to data
|
||||
beestat.cache.data.three_d__runtime_sensor.forEach(function(runtime_sensor) {
|
||||
if (
|
||||
sensor_ids_map[runtime_sensor.sensor_id] !== undefined &&
|
||||
runtime_sensor.temperature !== null &&
|
||||
runtime_sensor.occupancy !== null
|
||||
) {
|
||||
const timestamp_m = moment(runtime_sensor.timestamp);
|
||||
const time = timestamp_m.format('HH:mm');
|
||||
|
||||
// Temperature
|
||||
if (self.data_.series.temperature[runtime_sensor.sensor_id] === undefined) {
|
||||
self.data_.series.temperature[runtime_sensor.sensor_id] = {};
|
||||
}
|
||||
if (self.data_.series.temperature[runtime_sensor.sensor_id][time] === undefined) {
|
||||
self.data_.series.temperature[runtime_sensor.sensor_id][time] = [];
|
||||
}
|
||||
self.data_.series.temperature[runtime_sensor.sensor_id][time].push(runtime_sensor.temperature);
|
||||
|
||||
// Occupancy
|
||||
if (self.data_.series.occupancy[runtime_sensor.sensor_id] === undefined) {
|
||||
self.data_.series.occupancy[runtime_sensor.sensor_id] = {};
|
||||
}
|
||||
if (self.data_.series.occupancy[runtime_sensor.sensor_id][time] === undefined) {
|
||||
self.data_.series.occupancy[runtime_sensor.sensor_id][time] = [];
|
||||
}
|
||||
self.data_.series.occupancy[runtime_sensor.sensor_id][time].push(runtime_sensor.occupancy === true ? 1 : 0);
|
||||
}
|
||||
});
|
||||
|
||||
// Average data
|
||||
for (let key in this.data_.series) {
|
||||
for (let sensor_id in this.data_.series[key]) {
|
||||
for (let time in this.data_.series[key][sensor_id]) {
|
||||
this.data_.series[key][sensor_id][time] = this.data_.series[key][sensor_id][time].reduce(function(a, b) {
|
||||
return a + b;
|
||||
}) / this.data_.series[key][sensor_id][time].length;
|
||||
|
||||
// Set min/max
|
||||
this.data_.metadata.series[key].min = Math.min(
|
||||
this.data_.series[key][sensor_id][time],
|
||||
this.data_.metadata.series[key].min
|
||||
);
|
||||
this.data_.metadata.series[key].max = Math.max(
|
||||
this.data_.series[key][sensor_id][time],
|
||||
this.data_.metadata.series[key].max
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// console.log(this.data_);
|
||||
return this.data_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether or not there is data to display on the chart.
|
||||
*
|
||||
* @return {boolean} Whether or not there is data to display on the chart.
|
||||
*/
|
||||
beestat.component.card.three_d.prototype.has_data_ = function() {
|
||||
const data = this.get_data_();
|
||||
for (let key in data.series) {
|
||||
for (let sensor_id in data.series[key]) {
|
||||
if (Object.keys(data.series[key][sensor_id]).length > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the title of the card.
|
||||
*
|
||||
* @return {string} The title.
|
||||
*/
|
||||
beestat.component.card.three_d.prototype.get_title_ = function() {
|
||||
return '3D View';
|
||||
};
|
||||
|
||||
/**
|
||||
* Decorate the menu.
|
||||
*
|
||||
* @param {rocket.Elements} parent
|
||||
*/
|
||||
beestat.component.card.three_d.prototype.decorate_top_right_ = function(parent) {
|
||||
const menu = (new beestat.component.menu()).render(parent);
|
||||
|
||||
menu.add_menu_item(new beestat.component.menu_item()
|
||||
.set_text('Help')
|
||||
.set_icon('help_circle')
|
||||
.set_callback(function() {
|
||||
// TODO
|
||||
// window.open('https://doc.beestat.io/???');
|
||||
}));
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the scene with current settings. Anything that doesn't require
|
||||
* re-rendering can go here.
|
||||
*/
|
||||
beestat.component.card.three_d.prototype.update_scene_ = function() {
|
||||
this.scene_.set_data_type(beestat.setting('visualize.data_type'));
|
||||
|
||||
switch (beestat.setting('visualize.heat_map_type')) {
|
||||
case 'relative':
|
||||
this.scene_.set_heat_map_min(
|
||||
this.data_.metadata.series[beestat.setting('visualize.data_type')].min
|
||||
);
|
||||
this.scene_.set_heat_map_max(
|
||||
this.data_.metadata.series[beestat.setting('visualize.data_type')].max
|
||||
);
|
||||
break;
|
||||
case 'absolute':
|
||||
this.scene_.set_heat_map_min(
|
||||
beestat.setting(
|
||||
'visualize.heat_map_absolute.' +
|
||||
beestat.setting('visualize.data_type') +
|
||||
'.min'
|
||||
) / (beestat.setting('visualize.data_type') === 'occupancy' ? 100 : 1)
|
||||
);
|
||||
this.scene_.set_heat_map_max(
|
||||
beestat.setting(
|
||||
'visualize.heat_map_absolute.' +
|
||||
beestat.setting('visualize.data_type') +
|
||||
'.max'
|
||||
) / (beestat.setting('visualize.data_type') === 'occupancy' ? 100 : 1)
|
||||
);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the floor_plan_id.
|
||||
*
|
||||
* @param {number} floor_plan_id
|
||||
*
|
||||
* @return {beestat.component.card.three_d}
|
||||
*/
|
||||
beestat.component.card.three_d.prototype.set_floor_plan_id = function(floor_plan_id) {
|
||||
this.floor_plan_id_ = floor_plan_id;
|
||||
|
||||
if (this.rendered_ === true) {
|
||||
this.rerender();
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an object of all the sensor_ids included in the current floor plan. Key
|
||||
* is sensor_id, value is true.
|
||||
*
|
||||
* @return {object}
|
||||
*/
|
||||
beestat.component.card.three_d.prototype.get_sensor_ids_map_ = function() {
|
||||
const floor_plan = beestat.cache.floor_plan[this.floor_plan_id_];
|
||||
const sensor_ids_map = [];
|
||||
floor_plan.data.groups.forEach(function(group) {
|
||||
group.rooms.forEach(function(room) {
|
||||
if (room.sensor_id !== undefined) {
|
||||
sensor_ids_map[room.sensor_id] = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return sensor_ids_map;
|
||||
};
|
@ -1,42 +0,0 @@
|
||||
/**
|
||||
* Visualize
|
||||
*
|
||||
* @param {number} thermostat_id The thermostat_id this card is displaying
|
||||
* data for.
|
||||
*/
|
||||
beestat.component.card.visualize = function(thermostat_id) {
|
||||
this.thermostat_id_ = thermostat_id;
|
||||
|
||||
beestat.component.card.apply(this, arguments);
|
||||
};
|
||||
beestat.extend(beestat.component.card.visualize, beestat.component.card);
|
||||
|
||||
beestat.component.card.visualize.prototype.decorate_contents_ = function(parent) {
|
||||
const scene = new beestat.component.scene(this.thermostat_id_);
|
||||
scene.render(parent);
|
||||
|
||||
let date = new Date('2022-06-27 11:30:00');
|
||||
scene.set_date(date);
|
||||
// let date = new Date('2024-04-08 08:00:00'); // Total solar eclipse
|
||||
// scene.set_date(date);
|
||||
// setInterval(function() {
|
||||
// date = new Date(date.getTime() + (60000 * 1));
|
||||
// scene.set_date(date);
|
||||
// }, 100);
|
||||
//
|
||||
|
||||
beestat.dispatcher.addEventListener('cache.floor_plan', function() {
|
||||
scene.rerender();
|
||||
// todo get scene to remember date, camera position, etc on rerender
|
||||
scene.set_date(date);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the title of the card.
|
||||
*
|
||||
* @return {string} The title.
|
||||
*/
|
||||
beestat.component.card.visualize.prototype.get_title_ = function() {
|
||||
return 'Visualize';
|
||||
};
|
359
js/component/card/visualize_settings.js
Normal file
359
js/component/card/visualize_settings.js
Normal file
@ -0,0 +1,359 @@
|
||||
/**
|
||||
* Visualize settings.
|
||||
*/
|
||||
beestat.component.card.visualize_settings = function() {
|
||||
const self = this;
|
||||
beestat.dispatcher.addEventListener('cache.floor_plan', function() {
|
||||
self.rerender();
|
||||
});
|
||||
|
||||
beestat.component.card.apply(this, arguments);
|
||||
};
|
||||
beestat.extend(beestat.component.card.visualize_settings, beestat.component.card);
|
||||
|
||||
/**
|
||||
* Decorate
|
||||
*
|
||||
* @param {rocket.Elements} parent
|
||||
*/
|
||||
beestat.component.card.visualize_settings.prototype.decorate_contents_ = function(parent) {
|
||||
const grid_1 = document.createElement('div');
|
||||
Object.assign(grid_1.style, {
|
||||
'display': 'grid',
|
||||
'grid-template-columns': 'repeat(auto-fit, minmax(min(350px, 100%), 1fr))',
|
||||
'grid-gap': `${beestat.style.size.gutter}px`,
|
||||
'margin-bottom': `${beestat.style.size.gutter}px`
|
||||
});
|
||||
parent.appendChild(grid_1);
|
||||
|
||||
const type_container = document.createElement('div');
|
||||
this.decorate_data_type_(type_container);
|
||||
grid_1.appendChild(type_container);
|
||||
|
||||
const time_period_container = document.createElement('div');
|
||||
this.decorate_time_period_(time_period_container);
|
||||
grid_1.appendChild(time_period_container);
|
||||
|
||||
const grid_2 = document.createElement('div');
|
||||
Object.assign(grid_2.style, {
|
||||
'display': 'grid',
|
||||
'grid-template-columns': 'repeat(auto-fit, minmax(min(350px, 100%), 1fr))',
|
||||
'grid-gap': `${beestat.style.size.gutter}px`
|
||||
});
|
||||
parent.appendChild(grid_2);
|
||||
|
||||
const heat_map_type_container = document.createElement('div');
|
||||
this.decorate_heat_map_type_(heat_map_type_container);
|
||||
grid_2.appendChild(heat_map_type_container);
|
||||
|
||||
const floor_plan_container = document.createElement('div');
|
||||
this.decorate_floor_plan_(floor_plan_container);
|
||||
grid_2.appendChild(floor_plan_container);
|
||||
};
|
||||
|
||||
/**
|
||||
* Decorate the type options.
|
||||
*
|
||||
* @param {HTMLDivElement} parent
|
||||
*/
|
||||
beestat.component.card.visualize_settings.prototype.decorate_data_type_ = function(parent) {
|
||||
const self = this;
|
||||
|
||||
(new beestat.component.title('Data Type')).render($(parent));
|
||||
|
||||
const types = [
|
||||
{
|
||||
'code': 'temperature',
|
||||
'name': 'Temperature',
|
||||
'icon': 'thermometer'
|
||||
},
|
||||
{
|
||||
'code': 'occupancy',
|
||||
'name': 'Occupancy',
|
||||
'icon': 'eye'
|
||||
}
|
||||
];
|
||||
|
||||
const color = beestat.style.color.green.base;
|
||||
const tile_group = new beestat.component.tile_group();
|
||||
types.forEach(function(type) {
|
||||
const tile = new beestat.component.tile()
|
||||
.set_background_hover_color(color)
|
||||
.set_text_color('#fff')
|
||||
.set_icon(type.icon)
|
||||
.set_text(type.name);
|
||||
|
||||
if (beestat.setting('visualize.data_type') === type.code) {
|
||||
tile.set_background_color(color);
|
||||
} else {
|
||||
tile
|
||||
.set_background_color(beestat.style.color.bluegray.light)
|
||||
.addEventListener('click', function() {
|
||||
beestat.setting('visualize.data_type', type.code);
|
||||
self.rerender();
|
||||
});
|
||||
}
|
||||
tile_group.add_tile(tile);
|
||||
});
|
||||
|
||||
tile_group.render($(parent));
|
||||
};
|
||||
/**
|
||||
* Decorate the type options.
|
||||
*
|
||||
* @param {HTMLDivElement} parent
|
||||
*/
|
||||
beestat.component.card.visualize_settings.prototype.decorate_heat_map_type_ = function(parent) {
|
||||
const self = this;
|
||||
|
||||
(new beestat.component.title('Heat Map Type')).render($(parent));
|
||||
|
||||
const types = [
|
||||
{
|
||||
'code': 'relative',
|
||||
'name': 'Relative',
|
||||
'icon': 'arrow_expand_horizontal'
|
||||
},
|
||||
{
|
||||
'code': 'absolute',
|
||||
'name': 'Absolute',
|
||||
'icon': 'arrow_horizontal_lock'
|
||||
}
|
||||
];
|
||||
|
||||
const color = beestat.style.color.orange.base;
|
||||
const tile_group = new beestat.component.tile_group();
|
||||
types.forEach(function(type) {
|
||||
const tile = new beestat.component.tile()
|
||||
.set_background_hover_color(color)
|
||||
.set_text_color('#fff')
|
||||
.set_icon(type.icon)
|
||||
.set_text(type.name);
|
||||
|
||||
if (beestat.setting('visualize.heat_map_type') === type.code) {
|
||||
tile.set_background_color(color);
|
||||
} else {
|
||||
tile
|
||||
.set_background_color(beestat.style.color.bluegray.light)
|
||||
.addEventListener('click', function() {
|
||||
beestat.setting('visualize.heat_map_type', type.code);
|
||||
self.rerender();
|
||||
});
|
||||
}
|
||||
tile_group.add_tile(tile);
|
||||
});
|
||||
tile_group.render($(parent));
|
||||
|
||||
if (beestat.setting('visualize.heat_map_type') === 'absolute') {
|
||||
const min_max_container = document.createElement('div');
|
||||
min_max_container.style.marginTop = `${beestat.style.size.gutter}px`;
|
||||
parent.appendChild(min_max_container);
|
||||
|
||||
const min = new beestat.component.input.text()
|
||||
.set_value(beestat.setting(
|
||||
'visualize.heat_map_absolute.' + beestat.setting('visualize.data_type') + '.min')
|
||||
)
|
||||
.set_width(50);
|
||||
min.addEventListener('change', function() {
|
||||
beestat.setting('visualize.heat_map_absolute.' + beestat.setting('visualize.data_type') + '.min', min.get_value());
|
||||
});
|
||||
|
||||
const max = new beestat.component.input.text()
|
||||
.set_value(beestat.setting(
|
||||
'visualize.heat_map_absolute.' + beestat.setting('visualize.data_type') + '.max')
|
||||
)
|
||||
.set_width(50);
|
||||
max.addEventListener('change', function() {
|
||||
beestat.setting('visualize.heat_map_absolute.' + beestat.setting('visualize.data_type') + '.max', max.get_value());
|
||||
});
|
||||
|
||||
let span;
|
||||
|
||||
span = document.createElement('span');
|
||||
span.style.display = 'inline-block';
|
||||
min.render($(span));
|
||||
parent.appendChild(span);
|
||||
|
||||
span = document.createElement('span');
|
||||
span.innerText = 'to';
|
||||
Object.assign(span.style, {
|
||||
'display': 'inline-block',
|
||||
'margin-left': `${beestat.style.size.gutter}px`,
|
||||
'margin-right': `${beestat.style.size.gutter}px`
|
||||
});
|
||||
parent.appendChild(span);
|
||||
|
||||
span = document.createElement('span');
|
||||
span.style.display = 'inline-block';
|
||||
max.render($(span));
|
||||
parent.appendChild(span);
|
||||
|
||||
span = document.createElement('span');
|
||||
switch (beestat.setting('visualize.data_type')) {
|
||||
case 'temperature':
|
||||
span.innerText = beestat.setting('temperature_unit');
|
||||
break;
|
||||
case 'occupancy':
|
||||
span.innerText = '%';
|
||||
break;
|
||||
}
|
||||
|
||||
Object.assign(span.style, {
|
||||
'display': 'inline-block',
|
||||
'margin-left': `${beestat.style.size.gutter}px`
|
||||
});
|
||||
parent.appendChild(span);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Decorate the type options.
|
||||
*
|
||||
* @param {HTMLDivElement} parent
|
||||
*/
|
||||
beestat.component.card.visualize_settings.prototype.decorate_time_period_ = function(parent) {
|
||||
const self = this;
|
||||
|
||||
(new beestat.component.title('Time Period')).render($(parent));
|
||||
|
||||
const color = beestat.style.color.purple.base;
|
||||
|
||||
const tile_group = new beestat.component.tile_group();
|
||||
|
||||
// Current Day
|
||||
const day_tile = new beestat.component.tile()
|
||||
.set_background_hover_color(color)
|
||||
.set_text_color('#fff')
|
||||
.set_icon('calendar')
|
||||
.set_text('Today');
|
||||
|
||||
if (
|
||||
beestat.setting('visualize.range_type') === 'dynamic' &&
|
||||
beestat.setting('visualize.range_dynamic') === 0
|
||||
) {
|
||||
day_tile.set_background_color(color);
|
||||
} else {
|
||||
day_tile
|
||||
.set_background_color(beestat.style.color.bluegray.light)
|
||||
.addEventListener('click', function() {
|
||||
beestat.cache.delete('data.three_d__runtime_sensor');
|
||||
beestat.setting('visualize.range_type', 'dynamic');
|
||||
beestat.setting('visualize.range_dynamic', 0);
|
||||
self.rerender();
|
||||
});
|
||||
}
|
||||
tile_group.add_tile(day_tile);
|
||||
|
||||
// Current Week
|
||||
const week_tile = new beestat.component.tile()
|
||||
.set_background_hover_color(color)
|
||||
.set_text_color('#fff')
|
||||
.set_icon('calendar_week')
|
||||
.set_text('Last 7 Days');
|
||||
|
||||
if (
|
||||
beestat.setting('visualize.range_type') === 'dynamic' &&
|
||||
beestat.setting('visualize.range_dynamic') === 7
|
||||
) {
|
||||
week_tile.set_background_color(color);
|
||||
} else {
|
||||
week_tile
|
||||
.set_background_color(beestat.style.color.bluegray.light)
|
||||
.addEventListener('click', function() {
|
||||
beestat.cache.delete('data.three_d__runtime_sensor');
|
||||
beestat.setting('visualize.range_type', 'dynamic');
|
||||
beestat.setting('visualize.range_dynamic', 7);
|
||||
self.rerender();
|
||||
});
|
||||
}
|
||||
tile_group.add_tile(week_tile);
|
||||
|
||||
// Custom
|
||||
/* const custom_tile = new beestat.component.tile()
|
||||
.set_background_hover_color(color)
|
||||
.set_text_color('#fff')
|
||||
.set_icon('calendar_edit')
|
||||
.set_text('Custom');
|
||||
|
||||
if (
|
||||
beestat.setting('visualize.range_type') === 'static'
|
||||
) {
|
||||
custom_tile.set_background_color(color);
|
||||
} else {
|
||||
custom_tile
|
||||
.set_background_color(beestat.style.color.bluegray.light)
|
||||
.addEventListener('click', function() {
|
||||
// TODO MODAL
|
||||
beestat.setting('visualize.range_type', 'static');
|
||||
self.rerender();
|
||||
});
|
||||
}
|
||||
tile_group.add_tile(custom_tile);*/
|
||||
|
||||
tile_group.render($(parent));
|
||||
};
|
||||
|
||||
/**
|
||||
* Decorate the floor plan options.
|
||||
*
|
||||
* @param {HTMLDivElement} parent
|
||||
*/
|
||||
beestat.component.card.visualize_settings.prototype.decorate_floor_plan_ = function(parent) {
|
||||
const self = this;
|
||||
|
||||
(new beestat.component.title('Floor Plan')).render($(parent));
|
||||
|
||||
var sorted_floor_plans = $.values(beestat.cache.floor_plan)
|
||||
.sort(function(a, b) {
|
||||
return a.name > b.name;
|
||||
});
|
||||
|
||||
const tile_group = new beestat.component.tile_group();
|
||||
sorted_floor_plans.forEach(function(floor_plan) {
|
||||
const tile = new beestat.component.tile.floor_plan(floor_plan.floor_plan_id)
|
||||
.set_text_color('#fff')
|
||||
.set_display('block');
|
||||
|
||||
if (floor_plan.floor_plan_id === beestat.setting('visualize.floor_plan_id')) {
|
||||
tile.set_background_color(beestat.style.color.lightblue.base);
|
||||
} else {
|
||||
tile
|
||||
.set_background_color(beestat.style.color.bluegray.light)
|
||||
.set_background_hover_color(beestat.style.color.lightblue.base)
|
||||
.addEventListener('click', function() {
|
||||
beestat.setting('visualize.floor_plan_id', floor_plan.floor_plan_id);
|
||||
self.rerender();
|
||||
});
|
||||
}
|
||||
|
||||
tile_group.add_tile(tile);
|
||||
});
|
||||
|
||||
tile_group.render($(parent));
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the title of the card.
|
||||
*
|
||||
* @return {string} The title of the card.
|
||||
*/
|
||||
beestat.component.card.visualize_settings.prototype.get_title_ = function() {
|
||||
return 'Visualize Settings';
|
||||
};
|
||||
|
||||
/**
|
||||
* Decorate the menu.
|
||||
*
|
||||
* @param {rocket.Elements} parent
|
||||
*/
|
||||
beestat.component.card.visualize_settings.prototype.decorate_top_right_ = function(parent) {
|
||||
var menu = (new beestat.component.menu()).render(parent);
|
||||
|
||||
menu.add_menu_item(new beestat.component.menu_item()
|
||||
.set_text('Help')
|
||||
.set_icon('help_circle')
|
||||
.set_callback(function() {
|
||||
// TODO
|
||||
// window.open('https://doc.beestat.io/596040eadd014928830b4d1d54692761');
|
||||
}));
|
||||
};
|
@ -404,24 +404,25 @@ beestat.component.floor_plan.prototype.dispose = function() {
|
||||
beestat.component.floor_plan.prototype.update_toolbar = function() {
|
||||
const self = this;
|
||||
|
||||
if (this.button_group_ !== undefined) {
|
||||
this.button_group_.dispose();
|
||||
if (this.tile_group_ !== undefined) {
|
||||
this.tile_group_.dispose();
|
||||
}
|
||||
|
||||
if (this.button_group_floors_ !== undefined) {
|
||||
this.button_group_floors_.dispose();
|
||||
if (this.tile_group_floors_ !== undefined) {
|
||||
this.tile_group_floors_.dispose();
|
||||
}
|
||||
|
||||
this.button_group_ = new beestat.component.tile_group();
|
||||
this.tile_group_ = new beestat.component.tile_group();
|
||||
|
||||
// Add floor
|
||||
this.button_group_.add_button(new beestat.component.tile()
|
||||
this.tile_group_.add_tile(new beestat.component.tile()
|
||||
.set_icon('layers')
|
||||
.set_shadow(false)
|
||||
.set_text_color(beestat.style.color.lightblue.base)
|
||||
);
|
||||
|
||||
// Add room
|
||||
this.button_group_.add_button(new beestat.component.tile()
|
||||
this.tile_group_.add_tile(new beestat.component.tile()
|
||||
.set_icon('card_plus_outline')
|
||||
.set_title('Add Room [R]')
|
||||
.set_text_color(beestat.style.color.gray.light)
|
||||
@ -437,7 +438,7 @@ beestat.component.floor_plan.prototype.update_toolbar = function() {
|
||||
.set_icon('card_remove_outline')
|
||||
.set_title('Remove Room [Delete]')
|
||||
.set_background_color(beestat.style.color.bluegray.base);
|
||||
this.button_group_.add_button(remove_room_button);
|
||||
this.tile_group_.add_tile(remove_room_button);
|
||||
|
||||
if (this.state_.active_room_entity !== undefined) {
|
||||
remove_room_button
|
||||
@ -454,7 +455,7 @@ beestat.component.floor_plan.prototype.update_toolbar = function() {
|
||||
.set_icon('vector_square_plus')
|
||||
.set_title('Add Point [Double click]')
|
||||
.set_background_color(beestat.style.color.bluegray.base);
|
||||
this.button_group_.add_button(add_point_button);
|
||||
this.tile_group_.add_tile(add_point_button);
|
||||
|
||||
if (this.state_.active_wall_entity !== undefined) {
|
||||
add_point_button
|
||||
@ -471,7 +472,7 @@ beestat.component.floor_plan.prototype.update_toolbar = function() {
|
||||
.set_background_color(beestat.style.color.bluegray.base)
|
||||
.set_title('Remove Point [Delete]')
|
||||
.set_icon('vector_square_remove');
|
||||
this.button_group_.add_button(remove_point_button);
|
||||
this.tile_group_.add_tile(remove_point_button);
|
||||
|
||||
if (
|
||||
this.state_.active_point_entity !== undefined &&
|
||||
@ -497,7 +498,7 @@ beestat.component.floor_plan.prototype.update_toolbar = function() {
|
||||
snapping_title = 'Enable Snapping [S]';
|
||||
}
|
||||
|
||||
this.button_group_.add_button(new beestat.component.tile()
|
||||
this.tile_group_.add_tile(new beestat.component.tile()
|
||||
.set_icon(snapping_icon)
|
||||
.set_title(snapping_title)
|
||||
.set_text_color(beestat.style.color.gray.light)
|
||||
@ -511,7 +512,7 @@ beestat.component.floor_plan.prototype.update_toolbar = function() {
|
||||
.set_icon('undo')
|
||||
.set_title('Undo [Ctrl+Z]')
|
||||
.set_background_color(beestat.style.color.bluegray.base);
|
||||
this.button_group_.add_button(undo_button);
|
||||
this.tile_group_.add_tile(undo_button);
|
||||
|
||||
if (
|
||||
this.can_undo_() === true
|
||||
@ -532,7 +533,7 @@ beestat.component.floor_plan.prototype.update_toolbar = function() {
|
||||
.set_icon('redo')
|
||||
.set_title('redo [Ctrl+Y]')
|
||||
.set_background_color(beestat.style.color.bluegray.base);
|
||||
this.button_group_.add_button(redo_button);
|
||||
this.tile_group_.add_tile(redo_button);
|
||||
|
||||
if (
|
||||
this.can_redo_() === true
|
||||
@ -553,7 +554,7 @@ beestat.component.floor_plan.prototype.update_toolbar = function() {
|
||||
.set_icon('magnify_plus_outline')
|
||||
.set_title('Zoom In')
|
||||
.set_background_color(beestat.style.color.bluegray.base);
|
||||
this.button_group_.add_button(zoom_in_button);
|
||||
this.tile_group_.add_tile(zoom_in_button);
|
||||
|
||||
if (
|
||||
this.can_zoom_in_() === true
|
||||
@ -574,7 +575,7 @@ beestat.component.floor_plan.prototype.update_toolbar = function() {
|
||||
.set_icon('magnify_minus_outline')
|
||||
.set_title('Zoom out')
|
||||
.set_background_color(beestat.style.color.bluegray.base);
|
||||
this.button_group_.add_button(zoom_out_button);
|
||||
this.tile_group_.add_tile(zoom_out_button);
|
||||
|
||||
if (
|
||||
this.can_zoom_out_() === true
|
||||
@ -591,10 +592,10 @@ beestat.component.floor_plan.prototype.update_toolbar = function() {
|
||||
}
|
||||
|
||||
// Render
|
||||
this.button_group_.render(this.toolbar_container_);
|
||||
this.tile_group_.render(this.toolbar_container_);
|
||||
|
||||
// FLOORS
|
||||
this.button_group_floors_ = new beestat.component.tile_group();
|
||||
this.tile_group_floors_ = new beestat.component.tile_group();
|
||||
|
||||
const floor_plan = beestat.cache.floor_plan[this.floor_plan_id_];
|
||||
|
||||
@ -607,6 +608,7 @@ beestat.component.floor_plan.prototype.update_toolbar = function() {
|
||||
sorted_groups.forEach(function(group) {
|
||||
const button = new beestat.component.tile()
|
||||
.set_title(group.name)
|
||||
.set_shadow(false)
|
||||
.set_text_hover_color(beestat.style.color.lightblue.light)
|
||||
.set_text_color(beestat.style.color.lightblue.base);
|
||||
|
||||
@ -639,10 +641,10 @@ beestat.component.floor_plan.prototype.update_toolbar = function() {
|
||||
});
|
||||
}
|
||||
|
||||
self.button_group_floors_.add_button(button);
|
||||
self.tile_group_floors_.add_tile(button);
|
||||
});
|
||||
|
||||
this.button_group_floors_.render(this.floors_container_);
|
||||
this.tile_group_floors_.render(this.floors_container_);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -952,30 +954,33 @@ beestat.component.floor_plan.prototype.get_group_below = function(group) {
|
||||
* Center the view box on the content. Sets zoom and pan.
|
||||
*/
|
||||
beestat.component.floor_plan.prototype.center_content = function() {
|
||||
const floor_plan = beestat.cache.floor_plan[this.floor_plan_id_];
|
||||
// const floor_plan = beestat.cache.floor_plan[this.floor_plan_id_];
|
||||
|
||||
let min_x = Infinity;
|
||||
let max_x = -Infinity;
|
||||
let min_y = Infinity;
|
||||
let max_y = -Infinity;
|
||||
// let min_x = Infinity;
|
||||
// let max_x = -Infinity;
|
||||
// let min_y = Infinity;
|
||||
// let max_y = -Infinity;
|
||||
|
||||
let has_content = false;
|
||||
floor_plan.data.groups.forEach(function(group) {
|
||||
group.rooms.forEach(function(room) {
|
||||
room.points.forEach(function(point) {
|
||||
has_content = true;
|
||||
min_x = Math.min(room.x + point.x, min_x);
|
||||
max_x = Math.max(room.x + point.x, max_x);
|
||||
min_y = Math.min(room.y + point.y, min_y);
|
||||
max_y = Math.max(room.y + point.y, max_y);
|
||||
});
|
||||
});
|
||||
});
|
||||
// let has_content = false;
|
||||
// floor_plan.data.groups.forEach(function(group) {
|
||||
// group.rooms.forEach(function(room) {
|
||||
// room.points.forEach(function(point) {
|
||||
// has_content = true;
|
||||
// min_x = Math.min(room.x + point.x, min_x);
|
||||
// max_x = Math.max(room.x + point.x, max_x);
|
||||
// min_y = Math.min(room.y + point.y, min_y);
|
||||
// max_y = Math.max(room.y + point.y, max_y);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
const bounding_box = beestat.floor_plan.get_bounding_box(this.floor_plan_id_);
|
||||
|
||||
this.reset_view_box_();
|
||||
if (has_content === true) {
|
||||
const width = (max_x - min_x) + 50;
|
||||
const height = (max_y - min_y) + 50;
|
||||
// TODO ADD THIS BACK IN
|
||||
// if (has_content === true) {
|
||||
const width = (bounding_box.width) + 50;
|
||||
const height = (bounding_box.height) + 50;
|
||||
while (
|
||||
(
|
||||
this.view_box_.width < width ||
|
||||
@ -986,14 +991,14 @@ beestat.component.floor_plan.prototype.center_content = function() {
|
||||
this.zoom_out_();
|
||||
}
|
||||
|
||||
const center_x = (max_x + min_x) / 2;
|
||||
const center_y = (max_y + min_y) / 2;
|
||||
const center_x = (bounding_box.right + bounding_box.left) / 2;
|
||||
const center_y = (bounding_box.bottom + bounding_box.top) / 2;
|
||||
|
||||
this.view_box_.x = center_x - (this.view_box_.width / 2);
|
||||
this.view_box_.y = center_y - (this.view_box_.height / 2);
|
||||
|
||||
this.update_view_box_();
|
||||
}
|
||||
// }
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1019,7 +1024,7 @@ beestat.component.floor_plan.prototype.save_buffer = function(clear = true) {
|
||||
}
|
||||
|
||||
this.state_.buffer.push({
|
||||
'floor_plan': beestat.clone(beestat.cache.floor_plan[beestat.setting('floor_plan_id')]),
|
||||
'floor_plan': beestat.clone(beestat.cache.floor_plan[beestat.setting('visualize.floor_plan_id')]),
|
||||
'active_room_entity': this.state_.active_room_entity,
|
||||
'active_group_id': this.state_.active_group.group_id
|
||||
});
|
||||
|
@ -90,10 +90,11 @@ beestat.component.header.prototype.decorate_ = function(parent) {
|
||||
});
|
||||
row.appendChild(column_navigation);
|
||||
|
||||
var button_group = new beestat.component.tile_group();
|
||||
var tile_group = new beestat.component.tile_group();
|
||||
pages.forEach(function(page) {
|
||||
var button = new beestat.component.tile()
|
||||
.set_icon(page.icon)
|
||||
.set_shadow(false)
|
||||
.set_text_color(beestat.style.color.bluegray.dark);
|
||||
|
||||
if (beestat.width > 800) {
|
||||
@ -115,10 +116,10 @@ beestat.component.header.prototype.decorate_ = function(parent) {
|
||||
});
|
||||
}
|
||||
|
||||
button_group.add_button(button);
|
||||
tile_group.add_tile(button);
|
||||
});
|
||||
|
||||
button_group.render(column_navigation);
|
||||
tile_group.render(column_navigation);
|
||||
|
||||
// Menu
|
||||
|
||||
|
81
js/component/input/range.js
Normal file
81
js/component/input/range.js
Normal file
@ -0,0 +1,81 @@
|
||||
/**
|
||||
* Range input.
|
||||
*/
|
||||
beestat.component.input.range = function() {
|
||||
const self = this;
|
||||
|
||||
this.input_ = document.createElement('input');
|
||||
this.input_.setAttribute('type', 'range');
|
||||
|
||||
this.input_.addEventListener('change', function() {
|
||||
self.dispatchEvent('change');
|
||||
});
|
||||
|
||||
this.input_.addEventListener('input', function() {
|
||||
self.dispatchEvent('input');
|
||||
});
|
||||
|
||||
beestat.component.input.apply(this, arguments);
|
||||
};
|
||||
beestat.extend(beestat.component.input.range, beestat.component.input);
|
||||
|
||||
/**
|
||||
* Decorate
|
||||
*
|
||||
* @param {rocket.Elements} parent
|
||||
*/
|
||||
beestat.component.input.range.prototype.decorate_ = function(parent) {
|
||||
this.input_.style.width = '100%';
|
||||
|
||||
parent.appendChild(this.input_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the value in the range field. Do not rerender; it's unnecessary.
|
||||
*
|
||||
* @param {string} value
|
||||
*
|
||||
* @return {beestat.component.input.range} This.
|
||||
*/
|
||||
beestat.component.input.range.prototype.set_value = function(value) {
|
||||
this.input_.value = value;
|
||||
|
||||
this.dispatchEvent('change');
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the value of the input.
|
||||
*
|
||||
* @return {string}
|
||||
*/
|
||||
beestat.component.input.range.prototype.get_value = function() {
|
||||
return this.input_.value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the min value of the range input.
|
||||
*
|
||||
* @param {string} min
|
||||
*
|
||||
* @return {beestat.component.input.range} This.
|
||||
*/
|
||||
beestat.component.input.range.prototype.set_min = function(min) {
|
||||
this.input_.setAttribute('min', min);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the max value of the range input.
|
||||
*
|
||||
* @param {string} max
|
||||
*
|
||||
* @return {beestat.component.input.range} This.
|
||||
*/
|
||||
beestat.component.input.range.prototype.set_max = function(max) {
|
||||
this.input_.setAttribute('max', max);
|
||||
|
||||
return this;
|
||||
};
|
@ -13,6 +13,7 @@ beestat.component.menu.prototype.decorate_ = function(parent) {
|
||||
|
||||
this.icon_ = new beestat.component.tile()
|
||||
.set_type('pill')
|
||||
.set_shadow(false)
|
||||
.set_icon('dots_vertical')
|
||||
.set_bubble_text(this.bubble_text_)
|
||||
.set_bubble_color(this.bubble_color_)
|
||||
|
@ -208,6 +208,7 @@ beestat.component.modal.prototype.decorate_close_ = function(parent) {
|
||||
|
||||
var close = new beestat.component.tile()
|
||||
.set_type('pill')
|
||||
.set_shadow(false)
|
||||
.set_icon('close')
|
||||
.set_text_color(beestat.style.color.gray.dark)
|
||||
.set_background_hover_color(beestat.style.color.gray.light)
|
||||
@ -248,11 +249,11 @@ beestat.component.modal.prototype.decorate_buttons_ = function(parent) {
|
||||
});
|
||||
parent.appendChild(container);
|
||||
|
||||
var button_group = new beestat.component.tile_group();
|
||||
var tile_group = new beestat.component.tile_group();
|
||||
buttons.forEach(function(button) {
|
||||
button_group.add_button(button);
|
||||
tile_group.add_tile(button);
|
||||
});
|
||||
button_group.render(container);
|
||||
tile_group.render(container);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -43,9 +43,9 @@ beestat.component.modal.air_quality_detail_custom.prototype.decorate_contents_ =
|
||||
beestat.component.modal.air_quality_detail_custom.prototype.decorate_range_type_ = function(parent) {
|
||||
var self = this;
|
||||
|
||||
var button_group = new beestat.component.tile_group();
|
||||
var tile_group = new beestat.component.tile_group();
|
||||
|
||||
button_group.add_button(new beestat.component.tile()
|
||||
tile_group.add_tile(new beestat.component.tile()
|
||||
.set_background_hover_color(beestat.style.color.lightblue.base)
|
||||
.set_text_color('#fff')
|
||||
.set_background_color(
|
||||
@ -59,7 +59,7 @@ beestat.component.modal.air_quality_detail_custom.prototype.decorate_range_type_
|
||||
self.rerender();
|
||||
}));
|
||||
|
||||
button_group.add_button(new beestat.component.tile()
|
||||
tile_group.add_tile(new beestat.component.tile()
|
||||
.set_background_hover_color(beestat.style.color.lightblue.base)
|
||||
.set_text_color('#fff')
|
||||
.set_background_color(
|
||||
@ -78,7 +78,7 @@ beestat.component.modal.air_quality_detail_custom.prototype.decorate_range_type_
|
||||
parent.appendChild(row);
|
||||
var column = $.createElement('div').addClass(['column column_12']);
|
||||
row.appendChild(column);
|
||||
button_group.render(column);
|
||||
tile_group.render(column);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -298,6 +298,7 @@ beestat.component.modal.air_quality_detail_custom.prototype.get_buttons_ = funct
|
||||
.set_background_color('#fff')
|
||||
.set_text_color(beestat.style.color.gray.base)
|
||||
.set_text_hover_color(beestat.style.color.red.base)
|
||||
.set_shadow(false)
|
||||
.set_text('Cancel')
|
||||
.addEventListener('click', function() {
|
||||
self.dispose();
|
||||
@ -332,8 +333,8 @@ beestat.component.modal.air_quality_detail_custom.prototype.get_buttons_ = funct
|
||||
self.state_.air_quality_detail_range_static_end = temp;
|
||||
}
|
||||
|
||||
beestat.cache.delete('runtime_thermostat');
|
||||
beestat.cache.delete('runtime_sensor');
|
||||
beestat.cache.delete('data.air_quality_detail__runtime_thermostat');
|
||||
beestat.cache.delete('data.air_quality_detail__runtime_sensor');
|
||||
beestat.setting(
|
||||
{
|
||||
'air_quality_detail_range_type': self.state_.air_quality_detail_range_type,
|
||||
|
@ -1,66 +0,0 @@
|
||||
/**
|
||||
* Change floor plan
|
||||
*/
|
||||
beestat.component.modal.change_floor_plan = function() {
|
||||
beestat.component.modal.apply(this, arguments);
|
||||
};
|
||||
beestat.extend(beestat.component.modal.change_floor_plan, beestat.component.modal);
|
||||
|
||||
/**
|
||||
* Decorate
|
||||
*
|
||||
* @param {rocket.Elements} parent
|
||||
*/
|
||||
beestat.component.modal.change_floor_plan.prototype.decorate_contents_ = function(parent) {
|
||||
const self = this;
|
||||
|
||||
const p = document.createElement('p');
|
||||
p.innerText = 'You have multiple floor plans; which one would you like to view?';
|
||||
parent.appendChild(p);
|
||||
|
||||
const grid = document.createElement('div');
|
||||
grid.style.display = 'grid';
|
||||
grid.style.gridTemplateColumns = 'repeat(auto-fit, minmax(150px, 1fr))';
|
||||
grid.style.columnGap = beestat.style.size.gutter + 'px';
|
||||
grid.style.rowGap = beestat.style.size.gutter + 'px';
|
||||
parent.appendChild(grid);
|
||||
|
||||
var sorted_floor_plans = $.values(beestat.cache.floor_plan)
|
||||
.sort(function(a, b) {
|
||||
return a.name > b.name;
|
||||
});
|
||||
|
||||
let div;
|
||||
sorted_floor_plans.forEach(function(floor_plan) {
|
||||
div = document.createElement('div');
|
||||
grid.appendChild(div);
|
||||
|
||||
const tile = new beestat.component.tile.floor_plan(floor_plan.floor_plan_id)
|
||||
.set_text_color('#fff')
|
||||
.set_display('block');
|
||||
|
||||
if (floor_plan.floor_plan_id === beestat.setting('floor_plan_id')) {
|
||||
tile.set_background_color(beestat.style.color.lightblue.base);
|
||||
} else {
|
||||
tile
|
||||
.set_background_color(beestat.style.color.bluegray.base)
|
||||
.set_background_hover_color(beestat.style.color.lightblue.base)
|
||||
.addEventListener('click', function() {
|
||||
beestat.setting('floor_plan_id', floor_plan.floor_plan_id);
|
||||
self.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
tile.render($(div));
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get title.
|
||||
*
|
||||
* @return {string} Title.
|
||||
*/
|
||||
beestat.component.modal.change_floor_plan.prototype.get_title_ = function() {
|
||||
return 'Change Floor Plan';
|
||||
};
|
||||
|
@ -62,7 +62,7 @@ beestat.component.modal.change_system_type.prototype.decorate_contents_ = functi
|
||||
key
|
||||
);
|
||||
|
||||
let button_group = new beestat.component.tile_group();
|
||||
let tile_group = new beestat.component.tile_group();
|
||||
options[key].forEach(function(system_type) {
|
||||
let text = system_type.charAt(0).toUpperCase() + system_type.slice(1);
|
||||
if (thermostat.system_type.detected[key].equipment === system_type) {
|
||||
@ -93,9 +93,9 @@ beestat.component.modal.change_system_type.prototype.decorate_contents_ = functi
|
||||
button.set_background_color(beestat.style.color.bluegray.base);
|
||||
}
|
||||
|
||||
button_group.add_button(button);
|
||||
tile_group.add_tile(button);
|
||||
});
|
||||
button_group.render(parent);
|
||||
tile_group.render(parent);
|
||||
}
|
||||
};
|
||||
|
||||
@ -117,6 +117,7 @@ beestat.component.modal.change_system_type.prototype.get_buttons_ = function() {
|
||||
.set_background_color('#fff')
|
||||
.set_text_color(beestat.style.color.gray.base)
|
||||
.set_text_hover_color(beestat.style.color.red.base)
|
||||
.set_shadow(false)
|
||||
.set_text('Cancel')
|
||||
.addEventListener('click', function() {
|
||||
self.dispose();
|
||||
|
@ -176,6 +176,7 @@ beestat.component.modal.create_floor_plan.prototype.get_buttons_ = function() {
|
||||
.set_background_color('#fff')
|
||||
.set_text_color(beestat.style.color.gray.base)
|
||||
.set_text_hover_color(beestat.style.color.red.base)
|
||||
.set_shadow(false)
|
||||
.set_text('Cancel')
|
||||
.addEventListener('click', function() {
|
||||
self.dispose();
|
||||
@ -248,7 +249,7 @@ beestat.component.modal.create_floor_plan.prototype.get_buttons_ = function() {
|
||||
'floor_plan'
|
||||
)
|
||||
.set_callback(function(response) {
|
||||
beestat.setting('floor_plan_id', response.new_floor_plan.floor_plan_id);
|
||||
beestat.setting('visualize.floor_plan_id', response.new_floor_plan.floor_plan_id);
|
||||
beestat.cache.set('floor_plan', response.floor_plan);
|
||||
})
|
||||
.send();
|
||||
|
@ -47,6 +47,7 @@ beestat.component.modal.delete_floor_plan.prototype.get_buttons_ = function() {
|
||||
.set_background_color('#fff')
|
||||
.set_text_color(beestat.style.color.gray.base)
|
||||
.set_text_hover_color(beestat.style.color.red.base)
|
||||
.set_shadow(false)
|
||||
.set_text('Cancel')
|
||||
.addEventListener('click', function() {
|
||||
self.dispose();
|
||||
@ -78,9 +79,9 @@ beestat.component.modal.delete_floor_plan.prototype.get_buttons_ = function() {
|
||||
console.log('deleted fp');
|
||||
console.log(response);
|
||||
if (Object.keys(response.floor_plan).length > 0) {
|
||||
beestat.setting('floor_plan_id', Object.values(response.floor_plan)[0].floor_plan_id);
|
||||
beestat.setting('visualize.floor_plan_id', Object.values(response.floor_plan)[0].floor_plan_id);
|
||||
} else {
|
||||
beestat.setting('floor_plan_id', null);
|
||||
beestat.setting('visualize.floor_plan_id', null);
|
||||
}
|
||||
beestat.cache.set('floor_plan', response.floor_plan);
|
||||
})
|
||||
|
@ -169,7 +169,7 @@ beestat.component.modal.download_data.prototype.decorate_presets_ = function(par
|
||||
}
|
||||
];
|
||||
|
||||
var button_group = new beestat.component.tile_group();
|
||||
var tile_group = new beestat.component.tile_group();
|
||||
presets.forEach(function(preset) {
|
||||
preset.button
|
||||
.set_background_color(beestat.style.color.bluegray.base)
|
||||
@ -181,7 +181,7 @@ beestat.component.modal.download_data.prototype.decorate_presets_ = function(par
|
||||
self.state_.range_end = preset.range_end;
|
||||
self.dispatchEvent('range_change');
|
||||
});
|
||||
button_group.add_button(preset.button);
|
||||
tile_group.add_tile(preset.button);
|
||||
});
|
||||
|
||||
// Highlight the preset if the current date range matches.
|
||||
@ -198,7 +198,7 @@ beestat.component.modal.download_data.prototype.decorate_presets_ = function(par
|
||||
});
|
||||
});
|
||||
|
||||
button_group.render(column);
|
||||
tile_group.render(column);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -246,6 +246,7 @@ beestat.component.modal.download_data.prototype.get_buttons_ = function() {
|
||||
.set_background_color('#fff')
|
||||
.set_text_color(beestat.style.color.gray.base)
|
||||
.set_text_hover_color(beestat.style.color.red.base)
|
||||
.set_shadow(false)
|
||||
.set_text('Cancel')
|
||||
.addEventListener('click', function() {
|
||||
self.dispose();
|
||||
|
@ -57,6 +57,7 @@ beestat.component.modal.enjoy_beestat.prototype.get_buttons_ = function() {
|
||||
|
||||
var hide = new beestat.component.tile()
|
||||
.set_background_color('#fff')
|
||||
.set_shadow(false)
|
||||
.set_text_color(beestat.style.color.gray.base)
|
||||
.set_text_hover_color(beestat.style.color.bluegray.base)
|
||||
.set_text('Hide for one month')
|
||||
|
@ -43,9 +43,9 @@ beestat.component.modal.runtime_sensor_detail_custom.prototype.decorate_contents
|
||||
beestat.component.modal.runtime_sensor_detail_custom.prototype.decorate_range_type_ = function(parent) {
|
||||
var self = this;
|
||||
|
||||
var button_group = new beestat.component.tile_group();
|
||||
var tile_group = new beestat.component.tile_group();
|
||||
|
||||
button_group.add_button(new beestat.component.tile()
|
||||
tile_group.add_tile(new beestat.component.tile()
|
||||
.set_background_hover_color(beestat.style.color.lightblue.base)
|
||||
.set_text_color('#fff')
|
||||
.set_background_color(
|
||||
@ -59,7 +59,7 @@ beestat.component.modal.runtime_sensor_detail_custom.prototype.decorate_range_ty
|
||||
self.rerender();
|
||||
}));
|
||||
|
||||
button_group.add_button(new beestat.component.tile()
|
||||
tile_group.add_tile(new beestat.component.tile()
|
||||
.set_background_hover_color(beestat.style.color.lightblue.base)
|
||||
.set_text_color('#fff')
|
||||
.set_background_color(
|
||||
@ -78,7 +78,7 @@ beestat.component.modal.runtime_sensor_detail_custom.prototype.decorate_range_ty
|
||||
parent.appendChild(row);
|
||||
var column = $.createElement('div').addClass(['column column_12']);
|
||||
row.appendChild(column);
|
||||
button_group.render(column);
|
||||
tile_group.render(column);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -298,6 +298,7 @@ beestat.component.modal.runtime_sensor_detail_custom.prototype.get_buttons_ = fu
|
||||
.set_background_color('#fff')
|
||||
.set_text_color(beestat.style.color.gray.base)
|
||||
.set_text_hover_color(beestat.style.color.red.base)
|
||||
.set_shadow(false)
|
||||
.set_text('Cancel')
|
||||
.addEventListener('click', function() {
|
||||
self.dispose();
|
||||
@ -332,8 +333,8 @@ beestat.component.modal.runtime_sensor_detail_custom.prototype.get_buttons_ = fu
|
||||
self.state_.runtime_sensor_detail_range_static_end = temp;
|
||||
}
|
||||
|
||||
beestat.cache.delete('runtime_thermostat');
|
||||
beestat.cache.delete('runtime_sensor');
|
||||
beestat.cache.delete('data.runtime_sensor_detail__runtime_thermostat');
|
||||
beestat.cache.delete('data.runtime_sensor_detail__runtime_sensor');
|
||||
beestat.setting(
|
||||
{
|
||||
'runtime_sensor_detail_range_type': self.state_.runtime_sensor_detail_range_type,
|
||||
|
@ -43,9 +43,9 @@ beestat.component.modal.runtime_thermostat_detail_custom.prototype.decorate_cont
|
||||
beestat.component.modal.runtime_thermostat_detail_custom.prototype.decorate_range_type_ = function(parent) {
|
||||
var self = this;
|
||||
|
||||
var button_group = new beestat.component.tile_group();
|
||||
var tile_group = new beestat.component.tile_group();
|
||||
|
||||
button_group.add_button(new beestat.component.tile()
|
||||
tile_group.add_tile(new beestat.component.tile()
|
||||
.set_background_hover_color(beestat.style.color.lightblue.base)
|
||||
.set_text_color('#fff')
|
||||
.set_background_color(
|
||||
@ -59,7 +59,7 @@ beestat.component.modal.runtime_thermostat_detail_custom.prototype.decorate_rang
|
||||
self.rerender();
|
||||
}));
|
||||
|
||||
button_group.add_button(new beestat.component.tile()
|
||||
tile_group.add_tile(new beestat.component.tile()
|
||||
.set_background_hover_color(beestat.style.color.lightblue.base)
|
||||
.set_text_color('#fff')
|
||||
.set_background_color(
|
||||
@ -78,7 +78,7 @@ beestat.component.modal.runtime_thermostat_detail_custom.prototype.decorate_rang
|
||||
parent.appendChild(row);
|
||||
var column = $.createElement('div').addClass(['column column_12']);
|
||||
row.appendChild(column);
|
||||
button_group.render(column);
|
||||
tile_group.render(column);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -298,6 +298,7 @@ beestat.component.modal.runtime_thermostat_detail_custom.prototype.get_buttons_
|
||||
.set_background_color('#fff')
|
||||
.set_text_color(beestat.style.color.gray.base)
|
||||
.set_text_hover_color(beestat.style.color.red.base)
|
||||
.set_shadow(false)
|
||||
.set_text('Cancel')
|
||||
.addEventListener('click', function() {
|
||||
self.dispose();
|
||||
@ -332,7 +333,7 @@ beestat.component.modal.runtime_thermostat_detail_custom.prototype.get_buttons_
|
||||
self.state_.runtime_thermostat_detail_range_static_end = temp;
|
||||
}
|
||||
|
||||
beestat.cache.delete('runtime_thermostat');
|
||||
beestat.cache.delete('data.runtime_thermostat_detail__runtime_thermostat');
|
||||
beestat.setting(
|
||||
{
|
||||
'runtime_thermostat_detail_range_type': self.state_.runtime_thermostat_detail_range_type,
|
||||
|
@ -43,13 +43,13 @@ beestat.component.modal.runtime_thermostat_summary_custom.prototype.decorate_con
|
||||
]
|
||||
};
|
||||
|
||||
var button_groups = {};
|
||||
var tile_groups = {};
|
||||
|
||||
this.selected_buttons_ = {};
|
||||
for (let key in options) {
|
||||
let current_type = beestat.setting(key);
|
||||
|
||||
let button_group = new beestat.component.tile_group();
|
||||
let tile_group = new beestat.component.tile_group();
|
||||
options[key].forEach(function(value) {
|
||||
let text = value.replace('runtime_thermostat_summary_', '')
|
||||
.charAt(0)
|
||||
@ -105,9 +105,9 @@ beestat.component.modal.runtime_thermostat_summary_custom.prototype.decorate_con
|
||||
button.set_background_color(beestat.style.color.bluegray.base);
|
||||
}
|
||||
|
||||
button_group.add_button(button);
|
||||
tile_group.add_tile(button);
|
||||
});
|
||||
button_groups[key] = button_group;
|
||||
tile_groups[key] = tile_group;
|
||||
}
|
||||
|
||||
// Display it all
|
||||
@ -122,13 +122,13 @@ beestat.component.modal.runtime_thermostat_summary_custom.prototype.decorate_con
|
||||
time_count.render(column);
|
||||
column = $.createElement('div').addClass(['column column_10']);
|
||||
row.appendChild(column);
|
||||
button_groups.runtime_thermostat_summary_time_period.render(column);
|
||||
tile_groups.runtime_thermostat_summary_time_period.render(column);
|
||||
(new beestat.component.title('Group By')).render(parent);
|
||||
row = $.createElement('div').addClass('row');
|
||||
parent.appendChild(row);
|
||||
column = $.createElement('div').addClass(['column column_12']);
|
||||
row.appendChild(column);
|
||||
button_groups.runtime_thermostat_summary_group_by.render(column);
|
||||
tile_groups.runtime_thermostat_summary_group_by.render(column);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -152,6 +152,7 @@ beestat.component.modal.runtime_thermostat_summary_custom.prototype.get_buttons_
|
||||
.set_background_color('#fff')
|
||||
.set_text_color(beestat.style.color.gray.base)
|
||||
.set_text_hover_color(beestat.style.color.red.base)
|
||||
.set_shadow(false)
|
||||
.set_text('Cancel')
|
||||
.addEventListener('click', function() {
|
||||
self.dispose();
|
||||
|
@ -69,8 +69,8 @@ beestat.component.modal.update_floor_plan.prototype.decorate_contents_ = functio
|
||||
|
||||
sorted_groups.forEach(function(group) {
|
||||
new beestat.component.tile.floor_plan_group(group)
|
||||
.set_background_color(beestat.style.color.bluegray.base)
|
||||
.set_text_color('#fff')
|
||||
.set_background_color(beestat.style.color.gray.dark)
|
||||
.set_shadow(false)
|
||||
.set_display('block')
|
||||
.render($(grid));
|
||||
});
|
||||
@ -136,6 +136,7 @@ beestat.component.modal.update_floor_plan.prototype.get_buttons_ = function() {
|
||||
.set_background_color('#fff')
|
||||
.set_text_color(beestat.style.color.gray.base)
|
||||
.set_text_hover_color(beestat.style.color.red.base)
|
||||
.set_shadow(false)
|
||||
.set_text('Cancel')
|
||||
.addEventListener('click', function() {
|
||||
self.dispose();
|
||||
|
@ -1,8 +1,12 @@
|
||||
/**
|
||||
* Home Scene
|
||||
*
|
||||
* @param {number} floor_plan_id The floor plan to render.
|
||||
* @param {object} data Sensor data.
|
||||
*/
|
||||
beestat.component.scene = function(thermostat_id) {
|
||||
this.thermostat_id_ = thermostat_id;
|
||||
beestat.component.scene = function(floor_plan_id, data) {
|
||||
this.floor_plan_id_ = floor_plan_id;
|
||||
this.data_ = data;
|
||||
|
||||
beestat.component.apply(this, arguments);
|
||||
};
|
||||
@ -11,13 +15,19 @@ beestat.extend(beestat.component.scene, beestat.component);
|
||||
beestat.component.scene.sun_light_intensity = 1;
|
||||
beestat.component.scene.moon_light_intensity = 0.3;
|
||||
|
||||
beestat.component.scene.ambient_light_intensity_base = 0.3;
|
||||
beestat.component.scene.ambient_light_intensity_base = 1.5;
|
||||
beestat.component.scene.ambient_light_intensity_sky = 0.4;
|
||||
beestat.component.scene.moon_opacity = 0.9;
|
||||
|
||||
beestat.component.scene.turbidity = 10;
|
||||
beestat.component.scene.rayleigh = 0.5;
|
||||
beestat.component.scene.mie_coefficient = 0.001;
|
||||
beestat.component.scene.mie_directional_g = 0.95;
|
||||
beestat.component.scene.moon_opacity = 0.9;
|
||||
|
||||
// beestat.component.scene.turbidity = 14;
|
||||
// beestat.component.scene.rayleigh = 0.7;
|
||||
// beestat.component.scene.mie_coefficient = 0.008;
|
||||
// beestat.component.scene.mie_directional_g = 0.9;
|
||||
|
||||
beestat.component.scene.shadow_map_size = 4096;
|
||||
|
||||
@ -32,6 +42,20 @@ beestat.component.scene.prototype.rerender = function() {
|
||||
this.add_floor_plan_();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the width of this component.
|
||||
*
|
||||
* @param {number} width
|
||||
*/
|
||||
beestat.component.scene.prototype.set_width = function(width) {
|
||||
this.width_ = width;
|
||||
|
||||
this.camera_.aspect = this.width_ / this.height_;
|
||||
this.camera_.updateProjectionMatrix();
|
||||
|
||||
this.renderer_.setSize(this.width_, this.height_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Decorate
|
||||
*
|
||||
@ -48,17 +72,21 @@ beestat.component.scene.prototype.decorate_ = function(parent) {
|
||||
'watcher': false
|
||||
};
|
||||
|
||||
this.width_ = this.state_.scene_width || 800;
|
||||
this.height_ = 500;
|
||||
|
||||
this.add_scene_(parent);
|
||||
this.add_background_(parent);
|
||||
this.add_renderer_(parent);
|
||||
this.add_camera_();
|
||||
this.add_controls_(parent);
|
||||
this.add_sky_();
|
||||
this.add_moon_();
|
||||
this.add_moon_light_();
|
||||
// this.add_sky_();
|
||||
// this.add_moon_();
|
||||
// this.add_moon_light_();
|
||||
this.add_sun_light_();
|
||||
this.add_ambient_light_();
|
||||
this.add_ground_();
|
||||
// this.add_ground_();
|
||||
// this.add_ground_limited_();
|
||||
|
||||
this.add_group_();
|
||||
this.add_floor_plan_();
|
||||
@ -85,6 +113,7 @@ beestat.component.scene.prototype.decorate_ = function(parent) {
|
||||
|
||||
const animate = function() {
|
||||
requestAnimationFrame(animate);
|
||||
self.controls_.update();
|
||||
self.renderer_.render(self.scene_, self.camera_);
|
||||
};
|
||||
animate();
|
||||
@ -134,7 +163,7 @@ beestat.component.scene.prototype.add_renderer_ = function(parent) {
|
||||
this.renderer_ = new THREE.WebGLRenderer({
|
||||
'antialias': true
|
||||
});
|
||||
this.renderer_.setSize(window.innerWidth / 2.2, window.innerHeight / 2.2);
|
||||
this.renderer_.setSize(window.innerWidth /1.1, window.innerHeight / 1.1);
|
||||
this.renderer_.shadowMap.enabled = true;
|
||||
this.renderer_.shadowMap.autoUpdate = false;
|
||||
|
||||
@ -143,7 +172,8 @@ beestat.component.scene.prototype.add_renderer_ = function(parent) {
|
||||
* https://threejs.org/examples/webgl_shaders_sky.html
|
||||
*/
|
||||
this.renderer_.toneMapping = THREE.ACESFilmicToneMapping;
|
||||
this.renderer_.toneMappingExposure = 0.5;
|
||||
// this.renderer_.toneMappingExposure = 0.5;
|
||||
this.renderer_.toneMappingExposure = 0.2;
|
||||
|
||||
parent[0].appendChild(this.renderer_.domElement);
|
||||
};
|
||||
@ -175,7 +205,11 @@ beestat.component.scene.prototype.add_camera_ = function() {
|
||||
* @param {rocket.Elements} parent
|
||||
*/
|
||||
beestat.component.scene.prototype.add_controls_ = function(parent) {
|
||||
new THREE.OrbitControls(this.camera_, parent[0]); // eslint-disable-line no-new
|
||||
this.controls_ = new THREE.OrbitControls(this.camera_, parent[0]);
|
||||
this.controls_.enableDamping = true;
|
||||
this.controls_.enablePan = false;
|
||||
this.controls_.maxDistance = 1000;
|
||||
this.controls_.minDistance = 400;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -262,7 +296,8 @@ beestat.component.scene.prototype.add_sun_light_ = function() {
|
||||
beestat.component.scene.sun_light_intensity
|
||||
);
|
||||
this.directional_light_sun_.castShadow = true;
|
||||
this.directional_light_sun_.shadow.bias = -0.00009;
|
||||
// this.directional_light_sun_.shadow.bias = -0.00009;
|
||||
// this.directional_light_sun_.shadow.radius = 32;
|
||||
this.directional_light_sun_.shadow.mapSize.width = beestat.component.scene.shadow_map_size;
|
||||
this.directional_light_sun_.shadow.mapSize.height = beestat.component.scene.shadow_map_size;
|
||||
this.directional_light_sun_.shadow.camera.left = -1000;
|
||||
@ -311,15 +346,88 @@ beestat.component.scene.prototype.add_ambient_light_ = function() {
|
||||
|
||||
/**
|
||||
* Set the date and thus the position of the sun/moon.
|
||||
*
|
||||
* @param {Date} date
|
||||
*/
|
||||
beestat.component.scene.prototype.set_date = function(date) {
|
||||
const thermostat = beestat.cache.thermostat[this.thermostat_id_];
|
||||
const address = beestat.cache.address[thermostat.address_id];
|
||||
beestat.component.scene.prototype.update_ = function() {
|
||||
const self = this;
|
||||
|
||||
const floor_plan = beestat.cache.floor_plan[this.floor_plan_id_];
|
||||
|
||||
const time = this.date_.format('HH:mm');
|
||||
|
||||
// TODO Memoize this
|
||||
let gradient;
|
||||
if (self.data_type_ === 'temperature') {
|
||||
gradient = beestat.style.generate_gradient(
|
||||
[
|
||||
beestat.style.hex_to_rgb(beestat.style.color.blue.dark),
|
||||
beestat.style.hex_to_rgb(beestat.style.color.gray.base),
|
||||
beestat.style.hex_to_rgb(beestat.style.color.red.dark)
|
||||
],
|
||||
100
|
||||
);
|
||||
} else if (self.data_type_ === 'occupancy') {
|
||||
gradient = beestat.style.generate_gradient(
|
||||
[
|
||||
beestat.style.hex_to_rgb(beestat.style.color.gray.base),
|
||||
beestat.style.hex_to_rgb(beestat.style.color.orange.dark)
|
||||
],
|
||||
200
|
||||
);
|
||||
}
|
||||
|
||||
// Set the color of each room
|
||||
floor_plan.data.groups.forEach(function(group) {
|
||||
group.rooms.forEach(function(room) {
|
||||
let color;
|
||||
if (
|
||||
room.sensor_id !== undefined &&
|
||||
self.data_.series[self.data_type_][room.sensor_id] !== undefined &&
|
||||
self.data_.series[self.data_type_][room.sensor_id][time] !== undefined
|
||||
) {
|
||||
const value = self.data_.series[self.data_type_][room.sensor_id][time];
|
||||
|
||||
const percentage = Math.min(
|
||||
1,
|
||||
Math.max(
|
||||
0,
|
||||
(value - self.heat_map_min_) / (self.heat_map_max_ - self.heat_map_min_)
|
||||
)
|
||||
);
|
||||
color = beestat.style.rgb_to_hex(gradient[Math.floor((gradient.length - 1) * percentage)]);
|
||||
} else {
|
||||
color = beestat.style.color.gray.dark;
|
||||
}
|
||||
|
||||
self.rooms_[room.room_id].material.color.setHex(color.replace('#', '0x'));
|
||||
});
|
||||
});
|
||||
|
||||
let address;
|
||||
if (floor_plan.address_id !== null) { // todo should be undefined?
|
||||
address = beestat.cache.address[floor_plan.address_id];
|
||||
} else {
|
||||
address = {
|
||||
'normalized': {
|
||||
'metadata': {
|
||||
'latitude': 0,
|
||||
'longitude': 0
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// After sunset may need to hide the sun light source...or maybe wean it's brightness off or something.
|
||||
|
||||
// TODO TEMP TO KEEP LIGHTING CONSISTENT
|
||||
// const date = new Date('2022-08-16 12:00:00');
|
||||
// const date = this.date_.toDate();
|
||||
const date = moment()
|
||||
.hour(12)
|
||||
.minute(0)
|
||||
.second(0)
|
||||
.toDate();
|
||||
|
||||
const sun_object_vector = new THREE.Vector3();
|
||||
const moon_object_vector = new THREE.Vector3();
|
||||
|
||||
@ -386,29 +494,33 @@ beestat.component.scene.prototype.set_date = function(date) {
|
||||
beestat.component.scene.ambient_light_intensity_sky * Math.sin(sun_position.altitude) * (1 - eclipse_percentage)
|
||||
);
|
||||
|
||||
this.moon_.material.opacity = 0.2;
|
||||
// this.moon_.material.opacity = 0.2;
|
||||
|
||||
/**
|
||||
* Mess up the sky during an eclipse
|
||||
*/
|
||||
|
||||
// Turn down to 0
|
||||
this.sky_.material.uniforms.rayleigh.value =
|
||||
beestat.component.scene.rayleigh * (1 - eclipse_percentage);
|
||||
if (this.sky_ !== undefined) {
|
||||
this.sky_.material.uniforms.rayleigh.value =
|
||||
beestat.component.scene.rayleigh * (1 - eclipse_percentage);
|
||||
|
||||
// Turn down to almost 0
|
||||
this.sky_.material.uniforms.mieCoefficient.value =
|
||||
Math.max(
|
||||
0.00001,
|
||||
beestat.component.scene.mie_coefficient * (1 - eclipse_percentage)
|
||||
);
|
||||
// Turn down to almost 0
|
||||
this.sky_.material.uniforms.mieCoefficient.value =
|
||||
Math.max(
|
||||
0.00001,
|
||||
beestat.component.scene.mie_coefficient * (1 - eclipse_percentage)
|
||||
);
|
||||
|
||||
// Increase to almost 1
|
||||
this.sky_.material.uniforms.mieDirectionalG.value =
|
||||
Math.max(
|
||||
beestat.component.scene.mie_directional_g,
|
||||
0.9999 * eclipse_percentage
|
||||
);
|
||||
// Increase to almost 1
|
||||
this.sky_.material.uniforms.mieDirectionalG.value =
|
||||
Math.max(
|
||||
beestat.component.scene.mie_directional_g,
|
||||
0.9999 * eclipse_percentage
|
||||
);
|
||||
|
||||
this.sky_.material.uniforms.sunPosition.value.copy(sun_object_vector);
|
||||
}
|
||||
|
||||
/*
|
||||
* this.renderer_.toneMappingExposure = Math.max(
|
||||
@ -418,12 +530,23 @@ beestat.component.scene.prototype.set_date = function(date) {
|
||||
*/
|
||||
|
||||
// Set the brightness of the sun
|
||||
this.directional_light_sun_.intensity =
|
||||
beestat.component.scene.sun_light_intensity * Math.sin(sun_position.altitude) * (1 - eclipse_percentage);
|
||||
if (this.directional_light_sun_ !== undefined) {
|
||||
this.directional_light_sun_.intensity =
|
||||
beestat.component.scene.sun_light_intensity * Math.sin(sun_position.altitude) * (1 - eclipse_percentage);
|
||||
this.directional_light_sun_.position.copy(sun_light_vector);
|
||||
|
||||
}
|
||||
|
||||
// Set the brightness of the moon
|
||||
this.directional_light_moon_.intensity =
|
||||
beestat.component.scene.moon_light_intensity * moon_illumination.fraction;
|
||||
if (this.directional_light_moon_ !== undefined) {
|
||||
this.directional_light_moon_.intensity =
|
||||
beestat.component.scene.moon_light_intensity * moon_illumination.fraction;
|
||||
this.directional_light_moon_.position.copy(moon_light_vector);
|
||||
}
|
||||
|
||||
if (this.moon_ !== undefined) {
|
||||
this.moon_.position.copy(moon_object_vector);
|
||||
}
|
||||
|
||||
// TODO size of moon based on distance? Might not be worth it haha.
|
||||
|
||||
@ -433,12 +556,8 @@ beestat.component.scene.prototype.set_date = function(date) {
|
||||
*/
|
||||
|
||||
// Update the directional light positions
|
||||
this.directional_light_sun_.position.copy(sun_light_vector);
|
||||
this.directional_light_moon_.position.copy(moon_light_vector);
|
||||
|
||||
// Update the position of the sun and moon in the sky
|
||||
this.sky_.material.uniforms.sunPosition.value.copy(sun_object_vector);
|
||||
this.moon_.position.copy(moon_object_vector);
|
||||
// this.sky2_.material.uniforms.sunPosition.value.copy(moon_object_vector);
|
||||
|
||||
// Update shadows
|
||||
@ -484,8 +603,6 @@ beestat.component.scene.prototype.add_ground_ = function() {
|
||||
plane.rotation.x += Math.PI / 2;
|
||||
plane.receiveShadow = true;
|
||||
|
||||
|
||||
|
||||
this.scene_.add(plane);
|
||||
|
||||
if (this.debug_.grid === true) {
|
||||
@ -502,6 +619,45 @@ beestat.component.scene.prototype.add_ground_ = function() {
|
||||
this.scene_.add(grid_helper);
|
||||
}
|
||||
};
|
||||
beestat.component.scene.prototype.add_ground_limited_ = function() {
|
||||
const height = 24;
|
||||
|
||||
const bounding_box = beestat.floor_plan.get_bounding_box(this.floor_plan_id_);
|
||||
|
||||
const size = Math.max(bounding_box.width, bounding_box.height) + 120;
|
||||
|
||||
// const texture = new THREE.TextureLoader().load('img/grass.jpg');
|
||||
// texture.wrapS = THREE.RepeatWrapping;
|
||||
// texture.wrapT = THREE.RepeatWrapping;
|
||||
// texture.repeat.set(1000, 1000);
|
||||
|
||||
const geometry = new THREE.BoxGeometry(size, size, height);
|
||||
const material = new THREE.MeshLambertMaterial({
|
||||
// 'map': texture,
|
||||
'color': new THREE.Color(beestat.style.color.green.dark),
|
||||
'side': THREE.DoubleSide
|
||||
});
|
||||
const box = new THREE.Mesh(geometry, material);
|
||||
box.translateY(height / -2);
|
||||
box.rotation.x += Math.PI / 2;
|
||||
// box.receiveShadow = true;
|
||||
|
||||
this.scene_.add(box);
|
||||
|
||||
if (this.debug_.grid === true) {
|
||||
const grid_size = 100;
|
||||
const grid_divisions = grid_size;
|
||||
const grid_color_center_line = new THREE.Color(beestat.style.color.lightblue.base);
|
||||
const grid_color_grid = new THREE.Color(beestat.style.color.green.base);
|
||||
const grid_helper = new THREE.GridHelper(
|
||||
grid_size,
|
||||
grid_divisions,
|
||||
grid_color_center_line,
|
||||
grid_color_grid
|
||||
);
|
||||
this.scene_.add(grid_helper);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -512,11 +668,10 @@ beestat.component.scene.prototype.add_ground_ = function() {
|
||||
/**
|
||||
* Add a background.
|
||||
*/
|
||||
/*
|
||||
* beestat.component.scene.prototype.add_background_ = function() {
|
||||
* this.scene_.background = new THREE.Color(beestat.style.color.bluegray.dark);
|
||||
* }
|
||||
*/
|
||||
beestat.component.scene.prototype.add_background_ = function() {
|
||||
this.scene_.background = new THREE.Color(beestat.style.color.bluegray.dark);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -529,97 +684,58 @@ beestat.component.scene.prototype.add_ground_ = function() {
|
||||
* @param {object} room The room to add.
|
||||
*/
|
||||
beestat.component.scene.prototype.add_room_ = function(group, room) {
|
||||
const color = new THREE.Color(beestat.style.color.blue.base);
|
||||
const color = beestat.style.color.gray.base;
|
||||
|
||||
var clipper_offset = new ClipperLib.ClipperOffset();
|
||||
|
||||
clipper_offset.AddPath(room.points, ClipperLib.JoinType.jtMiter, ClipperLib.EndType.etClosedPolygon);
|
||||
clipper_offset.AddPath(
|
||||
room.points,
|
||||
ClipperLib.JoinType.jtSquare,
|
||||
ClipperLib.EndType.etClosedPolygon
|
||||
);
|
||||
var clipper_hole = new ClipperLib.Path();
|
||||
// var offsetted_paths = new ClipperLib.Path();
|
||||
clipper_offset.Execute(clipper_hole, -5);
|
||||
clipper_offset.Execute(clipper_hole, -3);
|
||||
|
||||
// Full height
|
||||
// const extrude_height = (room.height || group.height) - 3;
|
||||
|
||||
// Just the floor plan
|
||||
const extrude_height = 6;
|
||||
|
||||
|
||||
|
||||
room.height = 12 * 1;
|
||||
|
||||
// Create a shape using the points of the room.
|
||||
const shape = new THREE.Shape();
|
||||
const first_point = room.points[0];
|
||||
const first_point = clipper_hole[0].shift();
|
||||
shape.moveTo(first_point.x, first_point.y);
|
||||
room.points.forEach(function(point) {
|
||||
clipper_hole[0].forEach(function(point) {
|
||||
shape.lineTo(point.x, point.y);
|
||||
});
|
||||
|
||||
|
||||
// FLOOR
|
||||
const floor = shape.clone();
|
||||
const floor_geometry = new THREE.ShapeGeometry(floor);
|
||||
const floor_material = new THREE.MeshLambertMaterial({
|
||||
'color': color,
|
||||
'side': THREE.DoubleSide
|
||||
});
|
||||
const floor_mesh = new THREE.Mesh(floor_geometry, floor_material);
|
||||
floor_mesh.position.z = ((room.elevation || group.elevation) + room.height) * -1;
|
||||
|
||||
// Translate the floor_mesh to the room x/y position.
|
||||
floor_mesh.translateX(room.x);
|
||||
floor_mesh.translateY(room.y);
|
||||
floor_mesh.translateZ(room.height - 1);
|
||||
|
||||
// floor.rotation.x += Math.PI/2;
|
||||
|
||||
// Shadows are neat.
|
||||
floor_mesh.castShadow = true;
|
||||
floor_mesh.receiveShadow = true;
|
||||
|
||||
// Add the mesh to the group.
|
||||
this.group_.add(floor_mesh);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Create a hole
|
||||
const hole = new THREE.Shape();
|
||||
const hole_first_point = clipper_hole[0].shift();
|
||||
hole.moveTo(hole_first_point.x, hole_first_point.y);
|
||||
clipper_hole[0].forEach(function(point) {
|
||||
hole.lineTo(point.x, point.y);
|
||||
});
|
||||
|
||||
// Hole
|
||||
// const hole = shape.clone();
|
||||
shape.holes.push(hole);
|
||||
|
||||
/* var paths = [[{x:30,y:30},{x:130,y:30},{x:130,y:130},{x:30,y:130}],
|
||||
[{x:60,y:60},{x:60,y:100},{x:100,y:100},{x:100,y:60}]];
|
||||
var scale = 100;
|
||||
ClipperLib.JS.ScaleUpPaths(paths, scale);
|
||||
// Possibly ClipperLib.Clipper.SimplifyPolygons() here
|
||||
// Possibly ClipperLib.Clipper.CleanPolygons() here
|
||||
var co = new ClipperLib.ClipperOffset(2, 0.25);
|
||||
|
||||
// ClipperLib.EndType = {etOpenSquare: 0, etOpenRound: 1, etOpenButt: 2, etClosedPolygon: 3, etClosedLine : 4 };
|
||||
co.AddPaths(paths, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etClosedPolygon);
|
||||
var offsetted_paths = new ClipperLib.Paths();
|
||||
co.Execute(offsetted_paths, -10 * scale);*/
|
||||
|
||||
|
||||
|
||||
// Extrude the shape and create the mesh.
|
||||
const extrude_settings = {
|
||||
'depth': room.height,
|
||||
'bevelEnabled': false
|
||||
'depth': extrude_height,
|
||||
'bevelEnabled': true,
|
||||
'bevelThickness': 1,
|
||||
'bevelSize': 1,
|
||||
'bevelOffset': 1,
|
||||
'bevelSegments': 5
|
||||
};
|
||||
|
||||
const geometry = new THREE.ExtrudeGeometry(
|
||||
shape,
|
||||
extrude_settings
|
||||
);
|
||||
// const material = new THREE.MeshBasicMaterial({
|
||||
const material = new THREE.MeshPhongMaterial({
|
||||
// 'color': new THREE.Color(beestat.style.color.red.base)
|
||||
'color': color
|
||||
'color': color,
|
||||
// 'transparent': true,
|
||||
// 'opacity': 0.5
|
||||
});
|
||||
// material.opacity = 0.5;
|
||||
const mesh = new THREE.Mesh(geometry, material);
|
||||
mesh.position.z = ((room.elevation || group.elevation) + room.height) * -1;
|
||||
mesh.position.z = -extrude_height - (room.elevation || group.elevation);
|
||||
|
||||
// Translate the mesh to the room x/y position.
|
||||
mesh.translateX(room.x);
|
||||
@ -627,10 +743,16 @@ beestat.component.scene.prototype.add_room_ = function(group, room) {
|
||||
|
||||
// Shadows are neat.
|
||||
mesh.castShadow = true;
|
||||
mesh.receiveShadow = true;
|
||||
// mesh.receiveShadow = true;
|
||||
|
||||
// Add the mesh to the group.
|
||||
this.group_.add(mesh);
|
||||
|
||||
// Store a reference to the mesh representing each room.
|
||||
if (this.rooms_ === undefined) {
|
||||
this.rooms_ = {};
|
||||
}
|
||||
this.rooms_[room.room_id] = mesh;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -671,7 +793,16 @@ beestat.component.scene.prototype.update_debug_ = function() {
|
||||
* Add a group containing all of the extruded geometry.
|
||||
*/
|
||||
beestat.component.scene.prototype.add_group_ = function() {
|
||||
const bounding_box = beestat.floor_plan.get_bounding_box(this.floor_plan_id_);
|
||||
// this.floor_plan_center_x_ = ;
|
||||
// this.floor_plan_center_y_ = (bounding_box.bottom + bounding_box.top) / 2;
|
||||
|
||||
// this.view_box_.x = center_x - (this.view_box_.width / 2);
|
||||
// this.view_box_.y = center_y - (this.view_box_.height / 2);
|
||||
|
||||
this.group_ = new THREE.Group();
|
||||
this.group_.translateX((bounding_box.right + bounding_box.left) / -2);
|
||||
this.group_.translateZ((bounding_box.bottom + bounding_box.top) / -2);
|
||||
// this.group_.rotation.x = -Math.PI / 2;
|
||||
//
|
||||
this.group_.rotation.x = Math.PI / 2;
|
||||
@ -683,10 +814,79 @@ beestat.component.scene.prototype.add_group_ = function() {
|
||||
*/
|
||||
beestat.component.scene.prototype.add_floor_plan_ = function() {
|
||||
const self = this;
|
||||
const floor_plan = beestat.cache.floor_plan[1];
|
||||
const floor_plan = beestat.cache.floor_plan[this.floor_plan_id_];
|
||||
|
||||
floor_plan.data.groups.forEach(function(group) {
|
||||
group.rooms.forEach(function(room) {
|
||||
self.add_room_(group, room);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the current date.
|
||||
*
|
||||
* @param {moment} date
|
||||
*
|
||||
* @return {beestat.component.scene}
|
||||
*/
|
||||
beestat.component.scene.prototype.set_date = function(date) {
|
||||
this.date_ = date;
|
||||
|
||||
if (this.rendered_ === true) {
|
||||
this.update_();
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the type of data this scene is visualizing.
|
||||
*
|
||||
* @param {string} data_type temperature|occupancy
|
||||
*
|
||||
* @return {beestat.component.scene}
|
||||
*/
|
||||
beestat.component.scene.prototype.set_data_type = function(data_type) {
|
||||
this.data_type_ = data_type;
|
||||
|
||||
if (this.rendered_ === true) {
|
||||
this.update_();
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the min value of the heat map.
|
||||
*
|
||||
* @param {string} heat_map_min
|
||||
*
|
||||
* @return {beestat.component.scene}
|
||||
*/
|
||||
beestat.component.scene.prototype.set_heat_map_min = function(heat_map_min) {
|
||||
this.heat_map_min_ = heat_map_min;
|
||||
|
||||
if (this.rendered_ === true) {
|
||||
this.update_();
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the max value of the heat map.
|
||||
*
|
||||
* @param {string} heat_map_max
|
||||
*
|
||||
* @return {beestat.component.scene}
|
||||
*/
|
||||
beestat.component.scene.prototype.set_heat_map_max = function(heat_map_max) {
|
||||
this.heat_map_max_ = heat_map_max;
|
||||
|
||||
if (this.rendered_ === true) {
|
||||
this.update_();
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
@ -17,10 +17,11 @@ beestat.component.tile.prototype.decorate_ = function(parent) {
|
||||
const background_color = this.background_color_ || 'none';
|
||||
const text_color = this.text_color_ || '#fff';
|
||||
const tabbable = this.tabbable_ || false;
|
||||
const shadow = this.shadow_ === undefined ? true : this.shadow_;
|
||||
const display = this.display_ === 'block' ? 'flex' : 'inline-flex';
|
||||
let border_radius;
|
||||
if (this.type_ === 'pill') {
|
||||
border_radius = (this.get_size_() === 'large' ? 48 : 32);
|
||||
border_radius = (this.get_size_() === 'large' ? 48 : 36);
|
||||
} else {
|
||||
border_radius = beestat.style.size.border_radius;
|
||||
}
|
||||
@ -30,7 +31,7 @@ beestat.component.tile.prototype.decorate_ = function(parent) {
|
||||
Object.assign(this.container_.style, {
|
||||
'background': background_color,
|
||||
'border-radius': `${border_radius}px`,
|
||||
'height': `${(this.get_size_() === 'large' ? 48 : 32)}px`,
|
||||
'height': `${(this.get_size_() === 'large' ? 48 : 36)}px`,
|
||||
'display': display,
|
||||
'align-items': 'center',
|
||||
'color': text_color,
|
||||
@ -40,12 +41,18 @@ beestat.component.tile.prototype.decorate_ = function(parent) {
|
||||
'text-align': 'left'
|
||||
});
|
||||
|
||||
if (shadow === true) {
|
||||
Object.assign(this.container_.style, {
|
||||
'box-shadow': '0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)'
|
||||
});
|
||||
}
|
||||
|
||||
parent.appendChild(this.container_);
|
||||
|
||||
// Padding. Basically for icon only make it a nice square button.
|
||||
if (this.get_text_() === undefined) {
|
||||
Object.assign(this.container_.style, {
|
||||
'width': `${(this.get_size_() === 'large' ? 48 : 32)}px`,
|
||||
'width': `${(this.get_size_() === 'large' ? 48 : 36)}px`,
|
||||
'justify-content': 'center'
|
||||
});
|
||||
} else {
|
||||
@ -230,7 +237,8 @@ beestat.component.tile.prototype.get_icon_ = function() {
|
||||
/**
|
||||
* Set the text of the button.
|
||||
*
|
||||
* @param {string|array} text A single string or array of strings. If an array is passed multiple lines of text will be shown.
|
||||
* @param {string|array} text A single string or array of strings. If an array
|
||||
* is passed multiple lines of text will be shown.
|
||||
*
|
||||
* @return {beestat.component.tile} This.
|
||||
*/
|
||||
@ -268,6 +276,21 @@ beestat.component.tile.prototype.set_background_color = function(background_colo
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set whether or not there is a shadow. Default true.
|
||||
*
|
||||
* @param {boolean} shadow
|
||||
*
|
||||
* @return {beestat.component.tile} This.
|
||||
*/
|
||||
beestat.component.tile.prototype.set_shadow = function(shadow) {
|
||||
this.shadow_ = shadow;
|
||||
if (this.rendered_ === true) {
|
||||
this.rerender();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the text color.
|
||||
*
|
||||
|
@ -2,7 +2,7 @@
|
||||
* A group of tiles.
|
||||
*/
|
||||
beestat.component.tile_group = function() {
|
||||
this.buttons_ = [];
|
||||
this.tiles_ = [];
|
||||
beestat.component.apply(this, arguments);
|
||||
};
|
||||
beestat.extend(beestat.component.tile_group, beestat.component);
|
||||
@ -13,53 +13,37 @@ beestat.extend(beestat.component.tile_group, beestat.component);
|
||||
* @param {rocket.Elements} parent
|
||||
*/
|
||||
beestat.component.tile_group.prototype.decorate_ = function(parent) {
|
||||
var self = this;
|
||||
const flex = document.createElement('div');
|
||||
Object.assign(flex.style, {
|
||||
'display': 'inline-flex',
|
||||
'flex-wrap': 'wrap',
|
||||
'grid-gap': `${beestat.style.size.gutter / 2}px`
|
||||
});
|
||||
parent.appendChild(flex);
|
||||
|
||||
// Only exists so that there can be spacing between wrapped elements.
|
||||
var outer_container = $.createElement('div')
|
||||
.style({
|
||||
'margin-top': (beestat.style.size.gutter / -2)
|
||||
});
|
||||
parent.appendChild(outer_container);
|
||||
|
||||
this.buttons_.forEach(function(button, i) {
|
||||
var container = $.createElement('div').style({
|
||||
'display': 'inline-block',
|
||||
'margin-right': (i < self.buttons_.length) ? (beestat.style.size.gutter / 2) : 0,
|
||||
'margin-top': (beestat.style.size.gutter / 2)
|
||||
});
|
||||
button.render(container);
|
||||
outer_container.appendChild(container);
|
||||
this.tiles_.forEach(function(tile) {
|
||||
tile.render($(flex));
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a button to this group.
|
||||
* Add a tile to this group.
|
||||
*
|
||||
* @param {beestat.component.button} button The button to add.
|
||||
* @param {beestat.component.tile} tile The tile to add.
|
||||
*/
|
||||
beestat.component.tile_group.prototype.add_button = function(button) {
|
||||
this.buttons_.push(button);
|
||||
beestat.component.tile_group.prototype.add_tile = function(tile) {
|
||||
this.tiles_.push(tile);
|
||||
if (this.rendered_ === true) {
|
||||
this.rerender();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get all of the buttons in this button group.
|
||||
*
|
||||
* @return {[beestat.component.button]} The buttons in this group.
|
||||
*/
|
||||
beestat.component.tile_group.prototype.get_buttons = function() {
|
||||
return this.buttons_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove this component from the page. Disposes the buttons first.
|
||||
* Remove this component from the page. Disposes the tiles first.
|
||||
*/
|
||||
beestat.component.tile_group.prototype.dispose = function() {
|
||||
this.buttons_.forEach(function(button) {
|
||||
button.dispose();
|
||||
this.tiles_.forEach(function(tile) {
|
||||
tile.dispose();
|
||||
});
|
||||
beestat.component.prototype.dispose.apply(this, arguments);
|
||||
};
|
||||
|
@ -38,7 +38,6 @@ if($setting->get('environment') === 'dev' || $setting->get('environment') === 'd
|
||||
echo '<script src="/js/beestat/ecobee.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/beestat/runtime_thermostat.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/beestat/runtime_sensor.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/beestat/sensor.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/beestat/requestor.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/beestat/touch.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/beestat/crypto.js"></script>' . PHP_EOL;
|
||||
@ -77,7 +76,8 @@ if($setting->get('environment') === 'dev' || $setting->get('environment') === 'd
|
||||
echo '<script src="/js/component/card/settings.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/card/air_quality_detail.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/card/air_quality_summary.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/card/visualize.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/card/three_d.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/card/visualize_settings.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/card/air_quality_not_supported.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/card/floor_plan_editor.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/chart.js"></script>' . PHP_EOL;
|
||||
@ -119,12 +119,12 @@ if($setting->get('environment') === 'dev' || $setting->get('environment') === 'd
|
||||
echo '<script src="/js/component/modal/create_floor_plan.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/modal/update_floor_plan.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/modal/delete_floor_plan.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/modal/change_floor_plan.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/input.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/input/text.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/input/checkbox.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/input/radio.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/input/select.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/input/range.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/tile_group.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/tile.js"></script>' . PHP_EOL;
|
||||
echo '<script src="/js/component/tile/floor_plan.js"></script>' . PHP_EOL;
|
||||
|
@ -33,7 +33,21 @@ beestat.layer.visualize.prototype.decorate_ = function(parent) {
|
||||
|
||||
cards.push([
|
||||
{
|
||||
'card': new beestat.component.card.early_access(),
|
||||
'card': new beestat.component.card.visualize_settings(),
|
||||
'size': 12
|
||||
}
|
||||
]);
|
||||
|
||||
const three_d = new beestat.component.card.three_d()
|
||||
.set_floor_plan_id(beestat.setting('visualize.floor_plan_id'));
|
||||
|
||||
beestat.dispatcher.addEventListener('setting.visualize.floor_plan_id', function() {
|
||||
three_d.set_floor_plan_id(beestat.setting('visualize.floor_plan_id'));
|
||||
});
|
||||
|
||||
cards.push([
|
||||
{
|
||||
'card': three_d,
|
||||
'size': 12
|
||||
}
|
||||
]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user