diff --git a/api/ecobee_runtime_thermostat.php b/api/ecobee_runtime_thermostat.php
index 0c54b59..bcac135 100644
--- a/api/ecobee_runtime_thermostat.php
+++ b/api/ecobee_runtime_thermostat.php
@@ -66,7 +66,7 @@ class ecobee_runtime_thermostat extends cora\crud {
$thermostat = $this->api('thermostat', 'get', $thermostat_id);
- if($thermostat['sync_begin'] === null) {
+ if($thermostat['sync_begin'] !== $thermostat['first_connected']) {
$this->sync_backwards($thermostat_id);
} else {
$this->sync_forwards($thermostat_id);
@@ -87,21 +87,30 @@ class ecobee_runtime_thermostat extends cora\crud {
}
/**
- * Sync backwards from now until thermostat.first_connected. This should
- * only be used when syncing for the first time.
+ * Sync backwards. When running for the first time it will sync from now all
+ * the way back to the first connected date. If it is called again it will
+ * check to see if a full backwards sync has already completed. If it has,
+ * it will throw an exception. If not, it will resume the backwards sync.
*
- * @param int $ecobee_thermostat_id
+ * @param int $thermostat_id
*/
private function sync_backwards($thermostat_id) {
$thermostat = $this->api('thermostat', 'get', $thermostat_id);
- if($thermostat['sync_begin'] !== null) {
+ if($thermostat['sync_begin'] === $thermostat['first_connected']) {
throw new \Exception('Full sync already performed; must call sync_forwards() now.');
}
- // Sync from when the thermostat was first connected until now.
- $sync_begin = strtotime($thermostat['first_connected']);
- $sync_end = time();
+ if($thermostat['sync_begin'] === null) {
+ // Sync from when the thermostat was first connected until now.
+ $sync_begin = strtotime($thermostat['first_connected']);
+ $sync_end = time();
+ }
+ else {
+ // Sync from when the thermostat was first connected until sync_end.
+ $sync_begin = strtotime($thermostat['first_connected']);
+ $sync_end = strtotime($thermostat['sync_begin']);
+ }
$chunk_begin = $sync_end;
$chunk_end = $sync_end;
@@ -125,12 +134,17 @@ class ecobee_runtime_thermostat extends cora\crud {
'attributes' => [
'thermostat_id' => $thermostat['thermostat_id'],
'sync_begin' => date('Y-m-d H:i:s', $chunk_begin),
- 'sync_end' => date('Y-m-d H:i:s', $sync_end),
+ 'sync_end' => date(
+ 'Y-m-d H:i:s',
+ max(
+ $sync_end,
+ strtotime($thermostat['sync_end'])
+ )
+ )
]
]
);
-
// Because I am doing day-level syncing this will end up fetching an
// overlapping day of data every time. But if I properly switch this to
// interval-level syncing this should be correct or at the very least
@@ -458,6 +472,7 @@ class ecobee_runtime_thermostat extends cora\crud {
$query = '
select
`ecobee_thermostat_id`,
+ `ecobee_runtime_thermostat_id`,
`timestamp`,
cast(greatest(0, (cast(`compressor_heat_1` as signed) - cast(`compressor_heat_2` as signed))) as unsigned) `compressor_heat_1`,
diff --git a/api/user.php b/api/user.php
index 18370a4..054cc79 100644
--- a/api/user.php
+++ b/api/user.php
@@ -15,7 +15,7 @@ class user extends cora\crud {
'log_out',
'sync_patreon_status'
],
- 'public' => []
+ 'public' => ['force_log_in']
];
public static $converged = [];
diff --git a/js/component/card/recent_activity.js b/js/component/card/recent_activity.js
index 72060bc..d6f2643 100644
--- a/js/component/card/recent_activity.js
+++ b/js/component/card/recent_activity.js
@@ -61,7 +61,8 @@ beestat.component.card.recent_activity.prototype.decorate_contents_ = function(p
'lineColor': beestat.style.color.bluegray.light,
'min': series.x.chart_data[0],
'max': series.x.chart_data[series.x.chart_data.length - 1],
- 'minRange': 21600000,
+ // 'minRange': 21600000,
+ 'minRange': 21600000/8,
'tickLength': 0,
'gridLineWidth': 0,
'labels': {
@@ -383,33 +384,33 @@ beestat.component.card.recent_activity.prototype.decorate_contents_ = function(p
'data': series.compressor_cool_1.chart_data,
'yAxis': 1,
'marker': {
- 'enabled': false,
- 'states': {'hover': {'enabled': false}}
+ 'enabled': true,
+ // 'states': {'hover': {'enabled': false}}
},
'name': 'Cool',
'type': 'line',
'color': beestat.series.compressor_cool_1.color,
- 'lineWidth': 10,
+ // 'lineWidth': 10,
'linecap': 'square',
- 'states': {'hover': {'lineWidthPlus': 0}}
+ // 'states': {'hover': {'lineWidthPlus': 0}}
});
}
if (series.compressor_cool_2.enabled === true) {
this.chart_.options.series.push({
'data': series.compressor_cool_2.chart_data,
- 'linkedTo': 'compressor_cool_1',
+ // 'linkedTo': 'compressor_cool_1',
'yAxis': 1,
'marker': {
- 'enabled': false,
- 'states': {'hover': {'enabled': false}}
+ 'enabled': true,
+ // 'states': {'hover': {'enabled': false}}
},
'name': beestat.series.compressor_cool_2.name,
'type': 'line',
'color': beestat.series.compressor_cool_2.color,
- 'lineWidth': 10,
+ // 'lineWidth': 10,
'linecap': 'square',
- 'states': {'hover': {'lineWidthPlus': 0}}
+ // 'states': {'hover': {'lineWidthPlus': 0}}
});
}
@@ -851,13 +852,15 @@ beestat.component.card.recent_activity.prototype.get_series_ = function() {
)
.valueOf();
+
/*
* This creates a distinct object for each chunk of runtime so the total on
* time can be computed for any given segment.
*/
var durations = {};
- beestat.cache.ecobee_runtime_thermostat.forEach(function(ecobee_runtime_thermostat, i) {
+ var ecobee_runtime_thermostats = this.get_adjusted_ecobee_runtime_thermostats_();
+ ecobee_runtime_thermostats.forEach(function(ecobee_runtime_thermostat, i) {
if (ecobee_runtime_thermostat.ecobee_thermostat_id !== thermostat.ecobee_thermostat_id) {
return;
}
@@ -877,6 +880,8 @@ beestat.component.card.recent_activity.prototype.get_series_ = function() {
// TODO DO THIS FOR AUX
// TODO DO THIS FOR COOL
+ // ecobee_runtime_thermostat['compressor_cool_1'] += ecobee_runtime_thermostat['compressor_cool_2'];
+
beestat.component.card.recent_activity.optional_series.forEach(function(series_code) {
if (durations[series_code] === undefined) {
durations[series_code] = [{'seconds': 0}];
@@ -906,16 +911,17 @@ beestat.component.card.recent_activity.prototype.get_series_ = function() {
break;
}
+ var duration = original_durations[series_code] !== undefined
+ ? original_durations[series_code]
+ : ecobee_runtime_thermostat[series_code];
+
series[series_code].enabled = true;
series[series_code].chart_data.push([
x,
value
]);
- series[series_code].data[x] = value;
- var duration = original_durations[series_code] !== undefined
- ? original_durations[series_code]
- : ecobee_runtime_thermostat[series_code];
+ series[series_code].data[x] = value;
durations[series_code][durations[series_code].length - 1].seconds += duration;
// durations[series_code][durations[series_code].length - 1].seconds += ecobee_runtime_thermostat[series_code];
@@ -1401,3 +1407,132 @@ beestat.component.card.recent_activity.prototype.get_data_ = function() {
})
.send();
};
+
+/**
+ * [get_adjusted_ecobee_runtime_thermostats_ description]
+ *
+ * @return {[type]} [description]
+ */
+beestat.component.card.recent_activity.prototype.get_adjusted_ecobee_runtime_thermostats_ = function() {
+ var ecobee_runtime_thermostats = [];
+ beestat.cache.ecobee_runtime_thermostat.forEach(function(ecobee_runtime_thermostat, i) {
+ var new_rows = {};
+ var directions = {};
+
+ /**
+ * Skip the first row as I look backwards to it to determine if runtimes
+ * are beginning or ending.
+ *
+ *
+ *
+ * sigh...now the issue is that I have this
+ * 300 fan: 300
+ * 600 fan: 150
+ * 750 fan: 0
+ * 900 fan: 0
+ *
+ * So the 750 fan 0 gets added, but no point is drawn there so the fan still
+ * appears to turn off at 600. I either need to insert a row at 749 with fan:1,
+ * or somehow get highcharts to put a marker on 750 because the previous value was positive.
+ * I think I could do if(off and previous on) value = 1
+ *
+ */
+ if (i > 0 && ecobee_runtime_thermostat.ecobee_runtime_thermostat_id === 752423131) { // test end
+ // if (i > 0 && ecobee_runtime_thermostat.ecobee_runtime_thermostat_id === 724690669) { // test begin
+ // if (i > 0) {
+
+ // beestat.cache.ecobee_runtime_thermostat[i - 1].compressor_heat_1 = 0;
+ // ecobee_runtime_thermostat.compressor_heat_1 = 90;
+
+ // Assign the directions (begin/end) and fill in stubs for new_rows.
+ beestat.component.card.recent_activity.optional_series.forEach(function(series_code) {
+ if (
+ ecobee_runtime_thermostat[series_code] > 0 &&
+ ecobee_runtime_thermostat[series_code] < 300
+ ) {
+ var new_row_timestamp_offset;
+ var previous_row = beestat.cache.ecobee_runtime_thermostat[i - 1];
+ if (previous_row[series_code] === 300) {
+ console.log(series_code + ' is turning off in ' + ecobee_runtime_thermostat[series_code] + 's');
+ directions[series_code] = 'end';
+ new_row_timestamp_offset = ecobee_runtime_thermostat[series_code];
+ } else {
+ console.log(series_code + ' turned on ' + ecobee_runtime_thermostat[series_code] + 's ago');
+ directions[series_code] = 'begin';
+ new_row_timestamp_offset =
+ (300 - ecobee_runtime_thermostat[series_code]);
+ }
+
+ var new_row = JSON.parse(JSON.stringify(ecobee_runtime_thermostat));
+ var new_row_timestamp_m = moment(ecobee_runtime_thermostat.timestamp)
+ .add(new_row_timestamp_offset, 'seconds');
+ new_row.timestamp_m = new_row_timestamp_m;
+ new_row.timestamp = new_row_timestamp_m.format('Y-MM-DD HH:mm:ss');
+ new_rows[new_row_timestamp_m.format('Y-MM-DD HH:mm:ss')] = new_row;
+ }
+ });
+ }
+
+ new_rows = Object.values(new_rows);
+ if (new_rows.length > 0) {
+ // Add the current row as it's easier to pretend it's new.
+ ecobee_runtime_thermostat.timestamp_m =
+ moment(ecobee_runtime_thermostat.timestamp);
+ new_rows.push(ecobee_runtime_thermostat);
+
+ // Sort the new rows so they can be looped over accurately.
+ new_rows.sort(function(a, b) {
+ return moment(a.timestamp).isAfter(moment(b.timestamp)) ? 1 : -1;
+ });
+
+ /**
+ * Go through each column one at a time filling in the appropriate
+ * values.
+ */
+ beestat.component.card.recent_activity.optional_series.forEach(function(series_code) {
+ var j;
+ var diff;
+ var time_left = new_rows[0][series_code];
+ if (directions[series_code] === 'begin') {
+ for (j = new_rows.length - 1; j > 0; j--) {
+ diff = new_rows[j].timestamp_m.diff(
+ new_rows[j - 1].timestamp_m,
+ 'seconds'
+ );
+ new_rows[j][series_code] = Math.min(time_left, diff);
+ time_left = Math.max(0, time_left - diff);
+ }
+
+ // The first new_row will always be set to 0.
+ new_rows[0][series_code] = 0;
+ } else {
+ // var time_left = new_rows[0][series_code];
+ for (j = 0; j < new_rows.length - 1; j++) {
+ diff = new_rows[j + 1].timestamp_m.diff(
+ new_rows[j].timestamp_m,
+ 'seconds'
+ );
+ new_rows[j][series_code] = Math.min(time_left, diff);
+ time_left = Math.max(0, time_left - diff);
+ }
+
+ // The last new_row will always be set to 0.
+ new_rows[j][series_code] = 0;
+ }
+ });
+
+ // Add all of the new rows to the list.
+ new_rows.forEach(function(new_row) {
+ ecobee_runtime_thermostats.push(new_row);
+ });
+
+ console.log(ecobee_runtime_thermostat);
+ console.log(new_rows);
+ } else {
+ // No new rows, so just add the original row to the list.
+ ecobee_runtime_thermostats.push(ecobee_runtime_thermostat);
+ }
+ });
+
+ return ecobee_runtime_thermostats;
+};
diff --git a/js/js.php b/js/js.php
index ffd171d..8145c3f 100644
--- a/js/js.php
+++ b/js/js.php
@@ -19,6 +19,7 @@ if($setting->get('environment') === 'dev' || $setting->get('environment') === 'd
echo '' . PHP_EOL;
echo '' . PHP_EOL;
echo '' . PHP_EOL;
+ echo '' . PHP_EOL;
echo '' . PHP_EOL;
echo '' . PHP_EOL;
echo '' . PHP_EOL;