From c269c8fd3fa9f765b1926e0f7055342690595d2d Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 25 Mar 2021 02:54:20 -0700 Subject: [PATCH] =?UTF-8?q?Fix=20ordering=20of=20logbook=20entries=20insid?= =?UTF-8?q?e=20choose=20sequence=20with=20multiple=20=E2=80=A6=20(#8715)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gallery/src/data/traces/basic_trace.ts | 192 +++++++++++++++++++------ src/components/trace/hat-trace.ts | 50 ++++--- src/data/script.ts | 16 ++- 3 files changed, 191 insertions(+), 67 deletions(-) diff --git a/gallery/src/data/traces/basic_trace.ts b/gallery/src/data/traces/basic_trace.ts index ca1ef68b3c..6bf8d93f0f 100644 --- a/gallery/src/data/traces/basic_trace.ts +++ b/gallery/src/data/traces/basic_trace.ts @@ -2,13 +2,13 @@ import { DemoTrace } from "./types"; export const basicTrace: DemoTrace = { trace: { - last_action: "action/0/choose/0/sequence/0", + last_action: "action/2", last_condition: "condition/0", run_id: "0", state: "stopped", timestamp: { - start: "2021-03-22T19:17:09.519178+00:00", - finish: "2021-03-22T19:17:09.556129+00:00", + start: "2021-03-25T04:36:51.223693+00:00", + finish: "2021-03-25T04:36:51.266132+00:00", }, trigger: "state of input_boolean.toggle_1", domain: "automation", @@ -17,7 +17,7 @@ export const basicTrace: DemoTrace = { "action/0": [ { path: "action/0", - timestamp: "2021-03-22T19:17:09.526794+00:00", + timestamp: "2021-03-25T04:36:51.243018+00:00", changed_variables: { trigger: { platform: "state", @@ -29,10 +29,10 @@ export const basicTrace: DemoTrace = { editable: true, friendly_name: "Toggle 1", }, - last_changed: "2021-03-22T19:11:24.418709+00:00", - last_updated: "2021-03-22T19:11:24.418709+00:00", + last_changed: "2021-03-24T19:03:59.141440+00:00", + last_updated: "2021-03-24T19:03:59.141440+00:00", context: { - id: "55daa6c47a7613b0800fe0ec81090a84", + id: "5d0918eb379214d07554bdab6a08bcff", parent_id: null, user_id: null, }, @@ -44,10 +44,10 @@ export const basicTrace: DemoTrace = { editable: true, friendly_name: "Toggle 1", }, - last_changed: "2021-03-22T19:17:09.516874+00:00", - last_updated: "2021-03-22T19:17:09.516874+00:00", + last_changed: "2021-03-25T04:36:51.220696+00:00", + last_updated: "2021-03-25T04:36:51.220696+00:00", context: { - id: "116d7a6562d594b114f7efe728619a3f", + id: "664d6d261450a9ecea6738e97269a149", parent_id: null, user_id: "d1b4e89da01445fa8bc98e39fac477ca", }, @@ -57,38 +57,56 @@ export const basicTrace: DemoTrace = { description: "state of input_boolean.toggle_1", }, context: { - id: "54a7371cff31be0f4010c9fde2317322", - parent_id: "116d7a6562d594b114f7efe728619a3f", + id: "6cfcae368e7b3686fad6c59e83ae76c9", + parent_id: "664d6d261450a9ecea6738e97269a149", user_id: null, }, }, + result: { + params: { + domain: "input_boolean", + service: "toggle", + service_data: {}, + target: { + entity_id: ["input_boolean.toggle_4"], + }, + }, + running_script: false, + limit: 10, + }, + }, + ], + "action/1": [ + { + path: "action/1", + timestamp: "2021-03-25T04:36:51.252406+00:00", result: { choice: 0, }, }, ], - "action/0/choose/0": [ + "action/1/choose/0": [ { - path: "action/0/choose/0", - timestamp: "2021-03-22T19:17:09.530176+00:00", + path: "action/1/choose/0", + timestamp: "2021-03-25T04:36:51.254569+00:00", result: { result: true, }, }, ], - "action/0/choose/0/conditions/0": [ + "action/1/choose/0/conditions/0": [ { - path: "action/0/choose/0/conditions/0", - timestamp: "2021-03-22T19:17:09.539155+00:00", + path: "action/1/choose/0/conditions/0", + timestamp: "2021-03-25T04:36:51.254697+00:00", result: { result: true, }, }, ], - "action/0/choose/0/sequence/0": [ + "action/1/choose/0/sequence/0": [ { - path: "action/0/choose/0/sequence/0", - timestamp: "2021-03-22T19:17:09.542769+00:00", + path: "action/1/choose/0/sequence/0", + timestamp: "2021-03-25T04:36:51.257360+00:00", result: { params: { domain: "input_boolean", @@ -103,12 +121,48 @@ export const basicTrace: DemoTrace = { }, }, ], + "action/1/choose/0/sequence/1": [ + { + path: "action/1/choose/0/sequence/1", + timestamp: "2021-03-25T04:36:51.260658+00:00", + result: { + params: { + domain: "input_boolean", + service: "toggle", + service_data: {}, + target: { + entity_id: ["input_boolean.toggle_3"], + }, + }, + running_script: false, + limit: 10, + }, + }, + ], + "action/2": [ + { + path: "action/2", + timestamp: "2021-03-25T04:36:51.264159+00:00", + result: { + params: { + domain: "input_boolean", + service: "toggle", + service_data: {}, + target: { + entity_id: ["input_boolean.toggle_4"], + }, + }, + running_script: false, + limit: 10, + }, + }, + ], }, condition_trace: { "condition/0": [ { path: "condition/0", - timestamp: "2021-03-22T19:17:09.520267+00:00", + timestamp: "2021-03-25T04:36:51.228243+00:00", changed_variables: { trigger: { platform: "state", @@ -120,10 +174,10 @@ export const basicTrace: DemoTrace = { editable: true, friendly_name: "Toggle 1", }, - last_changed: "2021-03-22T19:11:24.418709+00:00", - last_updated: "2021-03-22T19:11:24.418709+00:00", + last_changed: "2021-03-24T19:03:59.141440+00:00", + last_updated: "2021-03-24T19:03:59.141440+00:00", context: { - id: "55daa6c47a7613b0800fe0ec81090a84", + id: "5d0918eb379214d07554bdab6a08bcff", parent_id: null, user_id: null, }, @@ -135,10 +189,10 @@ export const basicTrace: DemoTrace = { editable: true, friendly_name: "Toggle 1", }, - last_changed: "2021-03-22T19:17:09.516874+00:00", - last_updated: "2021-03-22T19:17:09.516874+00:00", + last_changed: "2021-03-25T04:36:51.220696+00:00", + last_updated: "2021-03-25T04:36:51.220696+00:00", context: { - id: "116d7a6562d594b114f7efe728619a3f", + id: "664d6d261450a9ecea6738e97269a149", parent_id: null, user_id: "d1b4e89da01445fa8bc98e39fac477ca", }, @@ -172,11 +226,23 @@ export const basicTrace: DemoTrace = { }, ], action: [ + { + service: "input_boolean.toggle", + target: { + entity_id: "input_boolean.toggle_4", + }, + }, { choose: [ { alias: "If toggle 3 is on", - conditions: "{{ is_state('input_boolean.toggle_3', 'on') }}", + conditions: [ + { + condition: "template", + value_template: + "{{ is_state('input_boolean.toggle_3', 'on') }}", + }, + ], sequence: [ { service: "input_boolean.toggle", @@ -185,6 +251,13 @@ export const basicTrace: DemoTrace = { entity_id: "input_boolean.toggle_2", }, }, + { + service: "input_boolean.toggle", + alias: "Toggle 3", + target: { + entity_id: "input_boolean.toggle_3", + }, + }, ], }, ], @@ -198,12 +271,18 @@ export const basicTrace: DemoTrace = { }, ], }, + { + service: "input_boolean.toggle", + target: { + entity_id: "input_boolean.toggle_4", + }, + }, ], mode: "single", }, context: { - id: "54a7371cff31be0f4010c9fde2317322", - parent_id: "116d7a6562d594b114f7efe728619a3f", + id: "6cfcae368e7b3686fad6c59e83ae76c9", + parent_id: "664d6d261450a9ecea6738e97269a149", user_id: null, }, variables: { @@ -217,10 +296,10 @@ export const basicTrace: DemoTrace = { editable: true, friendly_name: "Toggle 1", }, - last_changed: "2021-03-22T19:11:24.418709+00:00", - last_updated: "2021-03-22T19:11:24.418709+00:00", + last_changed: "2021-03-24T19:03:59.141440+00:00", + last_updated: "2021-03-24T19:03:59.141440+00:00", context: { - id: "55daa6c47a7613b0800fe0ec81090a84", + id: "5d0918eb379214d07554bdab6a08bcff", parent_id: null, user_id: null, }, @@ -232,10 +311,10 @@ export const basicTrace: DemoTrace = { editable: true, friendly_name: "Toggle 1", }, - last_changed: "2021-03-22T19:17:09.516874+00:00", - last_updated: "2021-03-22T19:17:09.516874+00:00", + last_changed: "2021-03-25T04:36:51.220696+00:00", + last_updated: "2021-03-25T04:36:51.220696+00:00", context: { - id: "116d7a6562d594b114f7efe728619a3f", + id: "664d6d261450a9ecea6738e97269a149", parent_id: null, user_id: "d1b4e89da01445fa8bc98e39fac477ca", }, @@ -252,12 +331,23 @@ export const basicTrace: DemoTrace = { message: "has been triggered by state of input_boolean.toggle_1", source: "state of input_boolean.toggle_1", entity_id: "automation.toggle_toggles", - context_id: "54a7371cff31be0f4010c9fde2317322", - when: "2021-03-22T19:17:09.523041+00:00", + context_id: "6cfcae368e7b3686fad6c59e83ae76c9", + when: "2021-03-25T04:36:51.240832+00:00", domain: "automation", }, { - when: "2021-03-22T19:17:09.549346+00:00", + when: "2021-03-25T04:36:51.249828+00:00", + name: "Toggle 4", + state: "on", + entity_id: "input_boolean.toggle_4", + context_entity_id: "automation.toggle_toggles", + context_entity_id_name: "Ensure Party mode", + context_event_type: "automation_triggered", + context_domain: "automation", + context_name: "Ensure Party mode", + }, + { + when: "2021-03-25T04:36:51.258947+00:00", name: "Toggle 2", state: "on", entity_id: "input_boolean.toggle_2", @@ -267,5 +357,27 @@ export const basicTrace: DemoTrace = { context_domain: "automation", context_name: "Ensure Party mode", }, + { + when: "2021-03-25T04:36:51.261806+00:00", + name: "Toggle 3", + state: "off", + entity_id: "input_boolean.toggle_3", + context_entity_id: "automation.toggle_toggles", + context_entity_id_name: "Ensure Party mode", + context_event_type: "automation_triggered", + context_domain: "automation", + context_name: "Ensure Party mode", + }, + { + when: "2021-03-25T04:36:51.265246+00:00", + name: "Toggle 4", + state: "off", + entity_id: "input_boolean.toggle_4", + context_entity_id: "automation.toggle_toggles", + context_entity_id_name: "Ensure Party mode", + context_event_type: "automation_triggered", + context_domain: "automation", + context_name: "Ensure Party mode", + }, ], }; diff --git a/src/components/trace/hat-trace.ts b/src/components/trace/hat-trace.ts index e4c2378d6e..213526d8cf 100644 --- a/src/components/trace/hat-trace.ts +++ b/src/components/trace/hat-trace.ts @@ -24,7 +24,11 @@ import { mdiStopCircleOutline, } from "@mdi/js"; import { LogbookEntry } from "../../data/logbook"; -import { getActionType } from "../../data/script"; +import { + ChooseAction, + ChooseActionChoice, + getActionType, +} from "../../data/script"; import relativeTime from "../../common/datetime/relative_time"; const LOGBOOK_ENTRIES_BEFORE_FOLD = 2; @@ -34,7 +38,7 @@ const pathToName = (path: string) => path.split("/").join(" "); /* eslint max-classes-per-file: "off" */ // Report time entry when more than this time has passed -const SIGNIFICANT_TIME_CHANGE = 5000; // 5 seconds +const SIGNIFICANT_TIME_CHANGE = 1000; // 1 seconds const isSignificantTimeChange = (a: Date, b: Date) => Math.abs(b.getTime() - a.getTime()) > SIGNIFICANT_TIME_CHANGE; @@ -184,6 +188,7 @@ class ActionRenderer { constructor( private entries: TemplateResult[], private trace: AutomationTraceExtended, + private logbookRenderer: LogbookRenderer, private timeTracker: RenderedTimeTracker ) { this.keys = Object.keys(trace.action_trace); @@ -212,6 +217,15 @@ class ActionRenderer { const value = this._getItem(index); const timestamp = new Date(value[0].timestamp); + // Render all logbook items that are in front of this item. + while ( + this.logbookRenderer.hasNext && + new Date(this.logbookRenderer.curItem.when) < timestamp + ) { + this.logbookRenderer.maybeRenderItem(); + } + + this.logbookRenderer.flush(); this.timeTracker.maybeRenderTime(timestamp); const path = value[0].path; @@ -263,11 +277,20 @@ class ActionRenderer { const chooseTrace = this._getItem(index)[0] as ChooseActionTrace; const defaultExecuted = chooseTrace.result.choice === "default"; + const chooseConfig = this._getDataFromPath( + this.keys[index] + ) as ChooseAction; + const name = chooseConfig.alias || "Choose"; if (defaultExecuted) { - this._renderEntry(`Choose: Default action executed`); + this._renderEntry(`${name}: Default action executed`); } else { - this._renderEntry(`Choose: Choice ${chooseTrace.result.choice} executed`); + const choiceConfig = this._getDataFromPath( + `${this.keys[index]}/choose/${chooseTrace.result.choice}` + ) as ChooseActionChoice; + const choiceName = + choiceConfig.alias || `Choice ${chooseTrace.result.choice}`; + this._renderEntry(`${name}: ${choiceName} executed`); } let i; @@ -374,21 +397,12 @@ export class HaAutomationTracer extends LitElement { const actionRenderer = new ActionRenderer( entries, this.trace, + logbookRenderer, timeTracker ); - while (logbookRenderer.hasNext && actionRenderer.hasNext) { - // Find next item time-wise. - const logbookItem = logbookRenderer.curItem; - const actionTrace = actionRenderer.curItem; - const actionTimestamp = new Date(actionTrace[0].timestamp); - - if (new Date(logbookItem.when) > actionTimestamp) { - logbookRenderer.flush(); - actionRenderer.renderItem(); - } else { - logbookRenderer.maybeRenderItem(); - } + while (actionRenderer.hasNext) { + actionRenderer.renderItem(); } while (logbookRenderer.hasNext) { @@ -396,10 +410,6 @@ export class HaAutomationTracer extends LitElement { } logbookRenderer.flush(); - - while (actionRenderer.hasNext) { - actionRenderer.renderItem(); - } } // null means it was stopped by a condition diff --git a/src/data/script.ts b/src/data/script.ts index da1b8f525f..5bc023b161 100644 --- a/src/data/script.ts +++ b/src/data/script.ts @@ -87,6 +87,7 @@ export interface RepeatAction { } interface BaseRepeat { + alias?: string; sequence: Action[]; } @@ -102,14 +103,15 @@ export interface UntilRepeat extends BaseRepeat { until: Condition[]; } +export interface ChooseActionChoice { + alias?: string; + conditions: string | Condition[]; + sequence: Action[]; +} + export interface ChooseAction { - choose: [ - { - alias?: string; - conditions: string | Condition[]; - sequence: Action[]; - } - ]; + alias?: string; + choose: ChooseActionChoice[]; default?: Action[]; }