Skip to content

Commit

Permalink
Add home assistant 1.1.0 (#30)
Browse files Browse the repository at this point in the history
* add Home Assistant 1.1.0

* move state component

* add Search Entity Attributes root command

* add heat_cool mode support

* rename command

* update states after action
  • Loading branch information
tonka3000 authored Oct 15, 2021
1 parent 5bec629 commit 50fa586
Show file tree
Hide file tree
Showing 16 changed files with 246 additions and 51 deletions.
18 changes: 9 additions & 9 deletions extensions/homeassistant/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 9 additions & 2 deletions extensions/homeassistant/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "homeassistant",
"title": "Home Assistant",
"version": "1.0.0",
"version": "1.1.0",
"author": "tonka3000",
"license": "MIT",
"description": "Home Assistant remote control. Control your house with Raycast 🚀",
Expand Down Expand Up @@ -76,6 +76,13 @@
"subtitle" : "Home Assistant",
"description": "Get/Set states of Home Assistant climate entities",
"mode": "view"
},
{
"name": "attributes",
"title": "All Entity Attributes",
"subtitle" : "Home Assistant",
"description": "Query Home Assistant entity attributes",
"mode": "view"
}
],
"preferences": [
Expand All @@ -97,7 +104,7 @@
}
],
"dependencies": {
"@raycast/api": "^1.24.5",
"@raycast/api": "^1.25.0",
"node-fetch": "^2.6.1",
"url-join": "^4.0.1"
},
Expand Down
5 changes: 5 additions & 0 deletions extensions/homeassistant/src/attributes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { StatesAttributesList } from "./components/attributes_all";

export default function main() {
return <StatesAttributesList domain="" />;
}
2 changes: 1 addition & 1 deletion extensions/homeassistant/src/automations.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { StatesList } from "./components";
import { StatesList } from "./components/states";

export default function main() {
return <StatesList domain="automation" />;
Expand Down
2 changes: 1 addition & 1 deletion extensions/homeassistant/src/binarysensors.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { StatesList } from "./components";
import { StatesList } from "./components/states";

export default function main() {
return <StatesList domain="binary_sensor" />;
Expand Down
2 changes: 1 addition & 1 deletion extensions/homeassistant/src/climate.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { StatesList } from "./components";
import { StatesList } from "./components/states";

export default function main() {
return <StatesList domain="climate" />;
Expand Down
27 changes: 27 additions & 0 deletions extensions/homeassistant/src/components/attributes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ActionPanel, CopyToClipboardAction, List } from "@raycast/api";
import { State } from "../haapi";

export function EntityAttributesList(props: { state: State }) {
const state = props.state;
const title = state.attributes.friendly_name
? `${state.attributes.friendly_name} (${state.entity_id})`
: `${state.entity_id}`;
return (
<List searchBarPlaceholder="Search entity attributes">
<List.Section title={`Attributes of ${title}`}>
{Object.entries(state.attributes).map(([k, v]) => (
<List.Item
key={state.entity_id + k}
title={k}
accessoryTitle={`${v}`}
actions={
<ActionPanel>
<CopyToClipboardAction content={`${v}`} />
</ActionPanel>
}
/>
))}
</List.Section>
</List>
);
}
104 changes: 104 additions & 0 deletions extensions/homeassistant/src/components/attributes_all.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { ActionPanel, CopyToClipboardAction, List, showToast, ToastStyle } from "@raycast/api";
import { useState, useEffect } from "react";
import { createHomeAssistantClient } from "../common";

export const ha = createHomeAssistantClient();

class Attribute {
public name = "";
public value: any;
}

export function StatesAttributesList(props: { domain: string }) {
const [searchText, setSearchText] = useState<string>();
const { attributes, error, isLoading } = useSearch(searchText, props.domain);

if (error) {
showToast(ToastStyle.Failure, "Cannot search Home Assistant states", error);
}

if (!attributes) {
return <List isLoading={true} searchBarPlaceholder="Loading" />;
}

return (
<List
searchBarPlaceholder="Filter by entity ID or attribute name"
isLoading={isLoading}
onSearchTextChange={setSearchText}
>
{attributes?.map((attr) => (
<List.Item
key={attr.name}
title={attr.name}
accessoryTitle={`${attr.value}`.substring(0, 50)}
actions={
<ActionPanel>
<CopyToClipboardAction content={`${attr.value}`} />
</ActionPanel>
}
/>
))}
</List>
);
}

export function useSearch(
query: string | undefined,
domain: string
): {
attributes?: Attribute[];
error?: string;
isLoading: boolean;
} {
const [attributes, setAttributes] = useState<Attribute[]>();
const [error, setError] = useState<string>();
const [isLoading, setIsLoading] = useState<boolean>(false);

let cancel = false;

useEffect(() => {
async function fetchData() {
if (query === null || cancel) {
return;
}

setIsLoading(true);
setError(undefined);

try {
const haStates = await ha.getStates({ domain: domain, query: "" });
let attributesData: Attribute[] = [];
haStates.forEach((e) =>
Object.entries(e.attributes).forEach(([k, v]) =>
attributesData.push({ name: `${e.entity_id}.${k}`, value: v })
)
);
if (query) {
const lquery = query.toLocaleLowerCase().trim();
attributesData = attributesData.filter((v) => v.name.toLocaleLowerCase().includes(lquery));
}
attributesData = attributesData.slice(0, 100);
if (!cancel) {
setAttributes(attributesData);
}
} catch (e: any) {
if (!cancel) {
setError(e.toString());
}
} finally {
if (!cancel) {
setIsLoading(false);
}
}
}

fetchData();

return () => {
cancel = true;
};
}, [query]);

return { attributes, error, isLoading };
}
Loading

0 comments on commit 50fa586

Please sign in to comment.