mirror of
https://github.com/ajnart/homarr.git
synced 2026-01-26 09:19:18 +01:00
feat: home assistant entity generic toggle (#2015)
Added support for generic toggle on Home Assistant entities that support it. For entities that does not support toggle the feature will silently fail. This way matches how Home Assistant handles it.
This commit is contained in:
committed by
GitHub
parent
6a5836f096
commit
18cd1f961f
@@ -22,8 +22,13 @@
|
||||
},
|
||||
"displayFriendlyName": {
|
||||
"label": "Display friendly name",
|
||||
"info": "Display friendly name from Home Assistant instead instead of display name"
|
||||
"info": "Display friendly name from Home Assistant instead instead of display name."
|
||||
},
|
||||
"genericToggle": {
|
||||
"label": "Entity toggle",
|
||||
"info": "Perform a generic Home Assistant toggle action on entity when clicked."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -88,6 +88,36 @@ export const smartHomeEntityStateRouter = createTRPCRouter({
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}),
|
||||
triggerToggle: protectedProcedure
|
||||
.input(z.object({
|
||||
widgetId: z.string(),
|
||||
configName: z.string()
|
||||
})).mutation(async ({ input }) => {
|
||||
const config = getConfig(input.configName);
|
||||
const widget = config.widgets.find(widget => widget.id === input.widgetId) as ISmartHomeEntityStateWidget | null;
|
||||
|
||||
if (!widget) {
|
||||
Consola.error(`Referenced widget ${input.widgetId} does not exist on backend.`);
|
||||
throw new TRPCError({
|
||||
code: 'CONFLICT',
|
||||
message: 'Referenced widget does not exist on backend',
|
||||
});
|
||||
}
|
||||
|
||||
const instances = config.apps.filter((app) => app.integration?.type == 'homeAssistant');
|
||||
|
||||
for (const instance of instances) {
|
||||
const url = new URL(instance.url);
|
||||
const client = HomeAssistantSingleton.getOrSet(url, findAppProperty(instance, 'apiKey'));
|
||||
const state = await client.triggerToggle(widget.properties.entityId);
|
||||
|
||||
if (state) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -56,4 +56,28 @@ export class HomeAssistant {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers a toggle action for a specific entity.
|
||||
*
|
||||
* @param entityId - The ID of the entity to toggle.
|
||||
* @returns A boolean indicating whether the toggle action was successful.
|
||||
*/
|
||||
async triggerToggle(entityId: string) {
|
||||
try {
|
||||
const response = await fetch(appendPath(this.basePath, `/services/homeassistant/toggle`), {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${this.token}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
'entity_id': entityId,
|
||||
}),
|
||||
method: 'POST'
|
||||
});
|
||||
return response.ok;
|
||||
} catch (err) {
|
||||
Consola.error(`Failed to fetch from '${this.basePath}': ${err}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,11 @@ const definition = defineWidget({
|
||||
defaultValue: false,
|
||||
info: true,
|
||||
},
|
||||
genericToggle: {
|
||||
type: 'switch',
|
||||
defaultValue: false,
|
||||
info: true,
|
||||
},
|
||||
automationId: {
|
||||
type: 'text',
|
||||
info: true,
|
||||
@@ -82,15 +87,26 @@ function EntityStateTile({ widget }: SmartHomeEntityStateWidgetProps) {
|
||||
},
|
||||
});
|
||||
|
||||
const handleClick = async () => {
|
||||
if (!widget.properties.automationId) {
|
||||
return;
|
||||
}
|
||||
const { mutateAsync: mutateTriggerToggleSync } = api.smartHomeEntityState.triggerToggle.useMutation({
|
||||
onSuccess: () => {
|
||||
void utils.smartHomeEntityState.invalidate();
|
||||
},
|
||||
});
|
||||
|
||||
await mutateTriggerAutomationAsync({
|
||||
configName: configName as string,
|
||||
widgetId: widget.id,
|
||||
});
|
||||
const handleClick = async () => {
|
||||
if (widget.properties.genericToggle) {
|
||||
await mutateTriggerToggleSync({
|
||||
configName: configName as string,
|
||||
widgetId: widget.id,
|
||||
});
|
||||
}
|
||||
|
||||
if (widget.properties.automationId) {
|
||||
await mutateTriggerAutomationAsync({
|
||||
configName: configName as string,
|
||||
widgetId: widget.id,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
let dataComponent = null;
|
||||
|
||||
Reference in New Issue
Block a user