Compare commits
4
Commits
3171433770
...
cf8839db6a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf8839db6a | ||
|
|
1d14219b93 | ||
|
|
d8756928a5 | ||
|
|
caf9051864 |
No files matched your search
+2
-2
@@ -114,10 +114,10 @@ class SmartObject(hass.Hass,LoggerInterface):
|
||||
if state_class is not None: attributes['state_class'] = state_class
|
||||
|
||||
if state is not None:
|
||||
entity.set_state(state=state, attributes=attributes)
|
||||
entity.set_state(state=state, attributes=attributes, check_existence=False)
|
||||
else:
|
||||
if not entity.exists():
|
||||
entity.set_state(state='unknown')
|
||||
entity.set_state(state='unknown', check_existence=False)
|
||||
entity.set_state(attributes=attributes)
|
||||
|
||||
return entity
|
||||
|
||||
+6
-1
@@ -46,6 +46,11 @@ class VirtualSensorBase:
|
||||
if super_entity_id != None:
|
||||
self.constants['super'] = super_entity_id
|
||||
|
||||
self.entity_existed = self.ad_api.entity_exists(self.sensor_name)
|
||||
if not self.entity_existed:
|
||||
self.ad_api.set_state(self.sensor_name, state='unknown',attributes=self.attributes, check_existence=False)
|
||||
self.entity = self.ad_api.get_entity(self.sensor_name)
|
||||
|
||||
if self_initialize:
|
||||
self._initialize()
|
||||
|
||||
@@ -657,7 +662,7 @@ class VirtualSensors():
|
||||
for sensor_name,default_value in default_values.items():
|
||||
if not self.ad_api.entity_exists(sensor_name):
|
||||
self.logger_interface.log_info(f"Creating sensor {sensor_name} = {default_value}")
|
||||
self.ad_api.set_state(sensor_name, state = str(default_value))
|
||||
self.ad_api.set_state(sensor_name, state = str(default_value),check_existence=False)
|
||||
|
||||
averagers = parser.parse_args('averagers',{})
|
||||
for averager in averagers:
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
.block-title{font-weight:600;margin-bottom:6px;color:var(--fg);overflow-wrap:anywhere}
|
||||
|
||||
#error-count{font-weight:700;font-size:14px}#error-count.has-errors{color:var(--vscode-editorError-foreground,#ffacac);border-color:currentColor;background:var(--vscode-inputValidation-errorBackground,#5b3039)}
|
||||
#error-count,#warning-count{font-weight:700;font-size:14px}#error-count.has-errors{color:var(--vscode-editorError-foreground,#ffacac);border-color:currentColor;background:var(--vscode-inputValidation-errorBackground,#5b3039)}#warning-count.has-warnings{color:var(--vscode-editorWarning-foreground,#f3cd80);border-color:currentColor;background:var(--vscode-inputValidation-warningBackground,#594925)}
|
||||
|
||||
.last-log{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||||
summary{display:grid;grid-template-columns:auto minmax(0,1fr) repeat(3,max-content);align-items:center;column-gap:10px;row-gap:5px}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<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>
|
||||
<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="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" 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>
|
||||
<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>
|
||||
<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>
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
const appFlashTokens = new Map();
|
||||
let receivedInitialData = false;
|
||||
let pointerSelecting = false;
|
||||
let errorView;
|
||||
let countView;
|
||||
let activeCountLevel;
|
||||
const $ = id => document.getElementById(id);
|
||||
const node = (tag, text, cls) => { const e = document.createElement(tag); if (text !== undefined) e.textContent = text; if (cls) e.className = cls; return e; };
|
||||
const normalLevel = e => e.level === 'CRITICAL' ? 'ERROR' : e.level;
|
||||
@@ -149,6 +150,7 @@
|
||||
});
|
||||
const timeOf = (app, logs) => (lastLogs.get(app) || logs[logs.length - 1]).time;
|
||||
$('error-count').setAttribute('aria-pressed', String($('level').value === 'ERROR'));
|
||||
$('warning-count').setAttribute('aria-pressed', String($('level').value === 'WARNING'));
|
||||
[...groups].sort(([a, al], [b, bl]) => {
|
||||
const order = $('sort').value;
|
||||
if (order === 'name') return a.localeCompare(b);
|
||||
@@ -363,6 +365,10 @@
|
||||
$('error-count').textContent = `${errorCount} error${errorCount === 1 ? '' : 's'}`;
|
||||
$('error-count').classList.toggle('has-errors', errorCount > 0);
|
||||
$('error-count').title = 'Errors and critical logs across all apps in loaded history. Click to show them.';
|
||||
const warningCount = entries.filter(e => (e.kind === 'log' || e.kind.startsWith('initialization_')) && normalLevel(e) === 'WARNING').length;
|
||||
$('warning-count').textContent = `${warningCount} warning${warningCount === 1 ? '' : 's'}`;
|
||||
$('warning-count').classList.toggle('has-warnings', warningCount > 0);
|
||||
$('warning-count').title = 'Warnings across all apps in loaded history. Click to show them.';
|
||||
$('warnings').textContent = (message.warnings || []).join(' · '); renderApps(); renderDetail();
|
||||
}
|
||||
function refreshLastLogAges() {
|
||||
@@ -387,21 +393,22 @@
|
||||
document.addEventListener('pointerup', () => { pointerSelecting = false; });
|
||||
document.addEventListener('selectionchange', () => { if (!selectionActive() && latest && latest !== appliedMessage) setTimeout(() => { if (!selectionActive() && latest !== appliedMessage) apply(latest); }, 0); });
|
||||
['search', 'period', 'level', 'sort'].forEach(id => $(id).addEventListener('input', () => {
|
||||
errorView = undefined; selected = undefined; origin = undefined;
|
||||
countView = undefined; activeCountLevel = undefined; selected = undefined; origin = undefined;
|
||||
save(); renderApps(); renderDetail();
|
||||
}));
|
||||
$('error-count').onclick = () => {
|
||||
const leaving = $('level').value === 'ERROR';
|
||||
function toggleCountView(level) {
|
||||
const leaving = activeCountLevel === level;
|
||||
if (leaving) {
|
||||
$('search').value = errorView?.search || '';
|
||||
$('period').value = errorView?.period || '0';
|
||||
$('level').value = errorView?.level || 'all';
|
||||
if (errorView) { expanded.clear(); errorView.expanded.forEach(app => expanded.add(app)); }
|
||||
errorView = undefined;
|
||||
$('search').value = countView?.search || '';
|
||||
$('period').value = countView?.period || '0';
|
||||
$('level').value = countView?.level || 'all';
|
||||
if (countView) { expanded.clear(); countView.expanded.forEach(app => expanded.add(app)); }
|
||||
countView = undefined; activeCountLevel = undefined;
|
||||
} else {
|
||||
errorView = { search: $('search').value, period: $('period').value, level: $('level').value, expanded: [...expanded] };
|
||||
$('search').value = ''; $('period').value = '0'; $('level').value = 'ERROR';
|
||||
entries.filter(e => normalLevel(e) === 'ERROR').forEach(e => expanded.add(e.app));
|
||||
if (!activeCountLevel) countView = { search: $('search').value, period: $('period').value, level: $('level').value, expanded: [...expanded] };
|
||||
activeCountLevel = level;
|
||||
$('search').value = ''; $('period').value = '0'; $('level').value = level;
|
||||
entries.filter(e => normalLevel(e) === level).forEach(e => expanded.add(e.app));
|
||||
}
|
||||
selected = undefined; origin = undefined;
|
||||
save(); renderApps(); renderDetail();
|
||||
@@ -409,7 +416,9 @@
|
||||
const first = document.querySelector('#apps .row');
|
||||
if (first) { first.click(); first.closest('.rows').scrollTop = 0; first.focus({ preventScroll: true }); }
|
||||
}
|
||||
};
|
||||
}
|
||||
$('error-count').onclick = () => toggleCountView('ERROR');
|
||||
$('warning-count').onclick = () => toggleCountView('WARNING');
|
||||
$('clear').onclick = () => { selected = undefined; origin = undefined; save(); $('clear').disabled = true; $('clear').textContent = 'Clearing…'; vscode.postMessage({ type: 'clear' }); };
|
||||
$('graph-mode').onclick = () => { mode = 'graph'; save(); renderDetail(); };
|
||||
$('tree-mode').onclick = () => { mode = 'tree'; save(); renderDetail(); };
|
||||
|
||||
Binary file not shown.
Reference in new issue
Block a user