Compare commits

..
2 Commits
5 changed files with 47 additions and 10 deletions

No files matched your search

+10 -9
View File
@@ -113,12 +113,11 @@ class SmartObject(hass.Hass,LoggerInterface):
if device_class is not None: attributes['device_class'] = device_class if device_class is not None: attributes['device_class'] = device_class
if state_class is not None: attributes['state_class'] = state_class if state_class is not None: attributes['state_class'] = state_class
if state is not None: if state is None:
state = entity.get_state() if entity.exists() else None
if state is None:
state = 'unknown'
entity.set_state(state=state, attributes=attributes, check_existence=False) entity.set_state(state=state, attributes=attributes, check_existence=False)
else:
if not entity.exists():
entity.set_state(state='unknown', check_existence=False)
entity.set_state(attributes=attributes)
return entity return entity
@@ -219,14 +218,16 @@ class SmartObject(hass.Hass,LoggerInterface):
# entity: <entity_id> → link app to a HA entity # entity: <entity_id> → link app to a HA entity
if "entity" in self.args: if "entity" in self.args:
self.entity_id = self.args["entity"] self.entity_id = self.args["entity"]
self.entity = self.get_entity(self.entity_id) self.entity = self.get_entity(self.entity_id, check_existence=False)
initial_state = None
if self.entity.exists(): if self.entity.exists():
self.log_info(f"Linked to {self.entity_id}") self.log_info(f"Linked to {self.entity_id}")
elif 'default_entity_state' in self.args: elif 'default_entity_state' in self.args:
self.entity.set_state(state = self.args["default_entity_state"]) initial_state = self.args["default_entity_state"]
self.log_info(f"Creating {self.entity_id}, default_state = {self.args['default_entity_state']}") self.log_info(f"Creating {self.entity_id}, default_state = {initial_state}")
else: else:
self.entity.set_state(state = self.get_default_entity_state()) initial_state = self.get_default_entity_state()
self.entity = self.create_entity(self.entity_id, state=initial_state)
self.constants['self'] = self.entity_id self.constants['self'] = self.entity_id
else: else:
+25
View File
@@ -0,0 +1,25 @@
# VS Code extension instructions
## VS Code extension
After every change to this extension, complete the update by compiling,
packaging, and installing the extension in the connected VS Code environment.
This includes changes limited to the Log Explorer HTML, CSS, or JavaScript.
- Keep the current extension version unless the user explicitly requests a
version change. Do not bump `package.json` or `package-lock.json` automatically.
- From this directory, run `npm run compile` and the checks appropriate to
the change. Report any existing test failures separately.
- Package with `vsce package --out vscode-appdaemon-<current-version>.vsix`,
using the installed or cached `@vscode/vsce` CLI when available. Overwrite the
existing VSIX for that version; never pass a version increment to `vsce`.
- Install that exact VSIX using
`code --install-extension ./vscode-appdaemon-<current-version>.vsix --force`.
- Confirm the installed version with `code --list-extensions --show-versions`.
When possible, verify the installed changed files match the packaged files.
- Tell the user to reload the VS Code window to activate the update. If the
connected CLI is unavailable or installation fails, report that limitation
clearly and provide the generated VSIX path; do not claim it was installed.
The user's request authorizes this routine local build and installation after
extension edits. Do not ask for additional conversational confirmation.
+11
View File
@@ -14,3 +14,14 @@ summary{display:grid;grid-template-columns:auto minmax(0,1fr) repeat(3,max-conte
summary .last-log{grid-column:1/-1;min-width:0} summary .last-log{grid-column:1/-1;min-width:0}
.rows{max-height:min(45vh,420px);overflow-y:auto;scrollbar-gutter:stable;overflow-anchor:none} .rows{max-height:min(45vh,420px);overflow-y:auto;scrollbar-gutter:stable;overflow-anchor:none}
.app-label{flex-direction:row;align-items:center;gap:6px}.app-label .name{min-width:0}.app-link{color:var(--accent);font-size:13px;line-height:1;text-decoration:none;white-space:nowrap}.app-link:hover{text-decoration:underline}.app-link:focus-visible{outline:2px solid var(--accent);outline-offset:2px} .app-label{flex-direction:row;align-items:center;gap:6px}.app-label .name{min-width:0}.app-link{color:var(--accent);font-size:13px;line-height:1;text-decoration:none;white-space:nowrap}.app-link:hover{text-decoration:underline}.app-link:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* Keep severity counts distinct from the currently selected filter. */
#error-count::before,#warning-count::before{content:"";display:inline-block;width:1.2em}
#error-count[aria-pressed="true"],#warning-count[aria-pressed="true"]{
color:var(--vscode-button-foreground,#fff);
background:var(--vscode-button-background,#0e639c);
border-color:var(--vscode-contrastActiveBorder,var(--accent));
box-shadow:inset 0 2px 4px rgba(0,0,0,.35);
}
#error-count[aria-pressed="true"]::before,#warning-count[aria-pressed="true"]::before{content:"✓"}
#error-count[aria-pressed="true"]:hover,#warning-count[aria-pressed="true"]:hover{background:var(--vscode-button-hoverBackground,#1177bb)}
+1 -1
View File
@@ -3,7 +3,7 @@
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src {{CSP}}; script-src 'nonce-{{NONCE}}';"> <meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src {{CSP}}; script-src 'nonce-{{NONCE}}';">
<link rel="stylesheet" href="{{CSS}}"><title>AppDaemon · Logs</title></head> <link rel="stylesheet" href="{{CSS}}"><title>AppDaemon · Logs</title></head>
<body> <body>
<header><div><h1>AppDaemon <span>Logs</span></h1><p id="status" role="status">Reading logs…</p></div><div class="actions"><button id="error-count" title="Show errors across all apps in loaded history">0 errors</button><button id="warning-count" title="Show warnings across all apps in loaded history">0 warnings</button><button id="clear" title="Empty configured log files">Clear logs</button></div></header> <header><div><h1>AppDaemon <span>Logs</span></h1><p id="status" role="status">Reading logs…</p></div><div class="actions"><button id="error-count" aria-pressed="false" title="Show errors across all apps in loaded history">0 errors</button><button id="warning-count" aria-pressed="false" title="Show warnings across all apps in loaded history">0 warnings</button><button id="clear" title="Empty configured log files">Clear logs</button></div></header>
<nav aria-label="Filters"><input id="search" type="search" placeholder="Search apps, entities and messages…" aria-label="Search"><select id="period" aria-label="Time range"><option value="15">15 minutes</option><option value="60">1 hour</option><option value="1440">24 hours</option><option value="0" selected>All loaded</option></select><select id="level" aria-label="Level"><option value="all">All levels</option><option value="INFO">INFO</option><option value="WARNING">WARNING</option><option value="ERROR">ERROR</option><option value="DEBUG">DEBUG</option></select></nav> <nav aria-label="Filters"><input id="search" type="search" placeholder="Search apps, entities and messages…" aria-label="Search"><select id="period" aria-label="Time range"><option value="15">15 minutes</option><option value="60">1 hour</option><option value="1440">24 hours</option><option value="0" selected>All loaded</option></select><select id="level" aria-label="Level"><option value="all">All levels</option><option value="INFO">INFO</option><option value="WARNING">WARNING</option><option value="ERROR">ERROR</option><option value="DEBUG">DEBUG</option></select></nav>
<div id="warnings" role="status"></div> <div id="warnings" role="status"></div>
<main><section class="apps" aria-label="Applications"><div class="section-title"><h2>Applications</h2><span id="count"></span><select id="sort" aria-label="Sort apps"><option value="latest" selected>Latest log first</option><option value="oldest">Oldest log first</option><option value="name">App name</option></select></div><div id="apps"></div></section><section class="causes" aria-label="Log details"><div class="section-title"><h2>Log details</h2><div><button id="graph-mode" aria-pressed="true">Graph</button><button id="tree-mode" aria-pressed="false">Tree</button></div></div><div id="detail"><div class="empty">Select a log to view its details.<p>The base AppDaemon log format does not include causal links.</p></div></div></section></main> <main><section class="apps" aria-label="Applications"><div class="section-title"><h2>Applications</h2><span id="count"></span><select id="sort" aria-label="Sort apps"><option value="latest" selected>Latest log first</option><option value="oldest">Oldest log first</option><option value="name">App name</option></select></div><div id="apps"></div></section><section class="causes" aria-label="Log details"><div class="section-title"><h2>Log details</h2><div><button id="graph-mode" aria-pressed="true">Graph</button><button id="tree-mode" aria-pressed="false">Tree</button></div></div><div id="detail"><div class="empty">Select a log to view its details.<p>The base AppDaemon log format does not include causal links.</p></div></div></section></main>
Binary file not shown.