feat: add hover provider for virtual sensors to display entity details
This commit is contained in:
@@ -244,7 +244,7 @@ class ADVirtualSensorDefinitionProvider implements vscode.DefinitionProvider {
|
||||
|
||||
invalidate() { this.cache = undefined; }
|
||||
|
||||
private async getSensors(): Promise<VirtualSensorEntry[]> {
|
||||
async getSensors(): Promise<VirtualSensorEntry[]> {
|
||||
const now = Date.now();
|
||||
if (this.cache && now < this.cacheExpiry) { return this.cache; }
|
||||
this.cache = await findAllVirtualSensors();
|
||||
@@ -282,6 +282,46 @@ class ADVirtualSensorDefinitionProvider implements vscode.DefinitionProvider {
|
||||
}
|
||||
}
|
||||
|
||||
class ADVirtualSensorHoverProvider implements vscode.HoverProvider {
|
||||
constructor(
|
||||
private haClient: HAClient,
|
||||
private defProvider: ADVirtualSensorDefinitionProvider
|
||||
) {}
|
||||
|
||||
async provideHover(
|
||||
document: vscode.TextDocument,
|
||||
position: vscode.Position
|
||||
): Promise<vscode.Hover | undefined> {
|
||||
// Find a virtual sensor whose definition is on this exact line
|
||||
const sensors = await this.defProvider.getSensors();
|
||||
const match = sensors.find(
|
||||
s => s.uri.fsPath === document.uri.fsPath && s.line === position.line
|
||||
);
|
||||
if (!match) { return undefined; }
|
||||
|
||||
const entity = this.haClient.getEntity(match.sensorId);
|
||||
if (!entity) { return undefined; }
|
||||
|
||||
const md = new vscode.MarkdownString();
|
||||
md.isTrusted = true;
|
||||
const friendly = entity.attributes?.friendly_name as string | undefined;
|
||||
md.appendMarkdown(`### ${friendly || entity.entity_id}\n\n`);
|
||||
md.appendMarkdown(`| | |\n|---|---|\n`);
|
||||
md.appendMarkdown(`| **Entity** | \`${entity.entity_id}\` |\n`);
|
||||
md.appendMarkdown(`| **State** | **\`${entity.state}\`** |\n`);
|
||||
if (entity.attributes) {
|
||||
const skip = new Set(['friendly_name', 'icon', 'entity_picture', 'supported_features', 'supported_color_modes']);
|
||||
for (const [key, value] of Object.entries(entity.attributes).filter(([k]) => !skip.has(k)).slice(0, 12)) {
|
||||
const display = typeof value === 'object' ? JSON.stringify(value) : String(value);
|
||||
const truncated = display.length > 60 ? display.substring(0, 57) + '...' : display;
|
||||
md.appendMarkdown(`| ${key.replace(/\|/g, '\\|')} | \`${truncated.replace(/\|/g, '\\|')}\` |\n`);
|
||||
}
|
||||
}
|
||||
md.appendMarkdown(`\n*Last changed: ${entity.last_changed}*`);
|
||||
return new vscode.Hover(md);
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
function updateContextualButton(editor: vscode.TextEditor | undefined) {
|
||||
@@ -367,6 +407,10 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
vscode.languages.registerDefinitionProvider(
|
||||
{ scheme: 'file', language: 'yaml' },
|
||||
virtualSensorDefProvider
|
||||
),
|
||||
vscode.languages.registerHoverProvider(
|
||||
{ scheme: 'file', language: 'yaml' },
|
||||
new ADVirtualSensorHoverProvider(haClient, virtualSensorDefProvider)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user