Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support for Home Assistant #783

Merged
merged 8 commits into from
May 22, 2024
19 changes: 18 additions & 1 deletion docs/customservices.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ within Homer:
- [PiAlert](#pialert)
- [Immich](#immich)
- [OpenHAB](#openhab)
- [Home Assistant](#home-assistant)

If you experiencing any issue, please have a look to the [troubleshooting](troubleshooting.md) page.

Expand Down Expand Up @@ -462,4 +463,20 @@ You need to set the type to OpenHAB, provide an api key and enable cors on OpenH
items: true # true will query the items API and report total items count. false will skip the call
```
To create an API token on OpenHAB, follow the [official documentation here](https://www.openhab.org/docs/configuration/apitokens.html).
To enable cors on OpenHAB, edit your services/runtime.cfg and uncomment or add this line: `org.openhab.cors:enable=true`
To enable cors on OpenHAB, edit your services/runtime.cfg and uncomment or add this line: `org.openhab.cors:enable=true`

## Home Assistant

You need to set the type to HomeAssistant, provide an api key and enable cors on Home Assistant.

```yaml
- name: "HomeAssistant"
logo: "assets/tools/sample.png" # optional, if none provided logo is taken from the home assistant instance
url: "http://192.168.0.151/"
type: "HomeAssistant"
apikey: "<---insert-api-key-here--->"
items: [] # optional, which items to show (and in which order) in the subtitle. Possible values are "name", "version", "entities"
separator: " " # optional, how to separate items
```
To create an API token on HomeAssistant, follow the [official documentation here](https://developers.home-assistant.io/docs/auth_api/#long-lived-access-token).
To enable cors on HomeAssistant, edit your `configuration.yml` and add the IP of Homer to `https: cors_allowed_origins`
165 changes: 165 additions & 0 deletions src/components/services/HomeAssistant.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
<template>
<Generic :item="item">
<template #content>
<p class="title is-4">{{ item.name }}</p>
<p class="subtitle is-6">
<template v-if="item.subtitle">
{{ item.subtitle }}
</template>
<template v-else>
{{ details }}
</template>
</p>
</template>
<template #indicator>
<div v-if="status" class="status" :class="status">
{{ status }}
</div>
</template>
</Generic>
</template>

<script>
import service from "@/mixins/service.js";
import Generic from "./Generic.vue";

export default {
name: "HomeAssistant",
mixins: [service],
props: {
item: Object,
},
components: {
Generic,
},
data: () => ({
status: "",
msg: "",
version: "",
entities: 0,
}),
computed: {
headers: function () {
return {
'Authorization': `Bearer ${this.item.apikey}`,
'Content-Type': 'application/json',
};
},
details: function () {
const details = [];
const items = this.item.items;
const separator = this.item.separator;

for (const i in items) {
const key = items[i];

switch (key) {
case "version":
details.push(
`v${this.version}`,
);
break;
case "name":
details.push(
`${this.location_name}`,
);
break;
case "entities":
details.push(
`Entities: ${this.entities}`,
);
break;
default:
details.push(
`undefined key ${key} `,
);
}
}

Check failure on line 77 in src/components/services/HomeAssistant.vue

View workflow job for this annotation

GitHub Actions / build (20.x)

Unexpected mutation of "item" prop

Check failure on line 78 in src/components/services/HomeAssistant.vue

View workflow job for this annotation

GitHub Actions / build (20.x)

Unexpected mutation of "item" prop
return details.join(separator);
},

Check failure on line 80 in src/components/services/HomeAssistant.vue

View workflow job for this annotation

GitHub Actions / build (20.x)

Unexpected mutation of "item" prop
},
created() {
this.fetchServerStatus().then(() => {
if (!this.item.subtitle && this.status !== "dead") {
if (!this.item.items) this.item.items = ["name", "version"];
if (!this.item.separator) this.item.separator = " ";
if (!this.item.logo) this.item.logo = `${this.item.url}/static/icons/favicon-192x192.png`;
this.fetchServerStats();
}
});
},
methods: {
fetchServerStatus: async function () {
const headers = this.headers;

return this.fetch("/api/", { headers })
.then((response) => {
if (response && response.message) this.status = "running";
else throw new Error();
})
.catch((e) => {
console.log(e);
this.status = "dead";
});
},
fetchServerStats: async function () {
const headers = this.headers;

this.fetch("/api/config", { headers })
.then((response) => {
if (response) {
if (response.version) this.version = response.version;
if (response.location_name) this.location_name = response.location_name;
}
else throw new Error();
})
.catch((e) => {
console.log(e);
this.status = "dead";
});

this.fetch("/api/states", { headers })
.then((response) => {
if (response) {
this.entities = response.length;
}
else throw new Error();
})
.catch((e) => {
console.log(e);
this.status = "dead";
});
},
},
};
</script>

<style scoped lang="scss">
.status {
font-size: 0.8rem;
color: var(--text-title);

&.running:before {
background-color: #94e185;
border-color: #78d965;
box-shadow: 0 0 5px 1px #94e185;
}

&.dead:before {
background-color: #c9404d;
border-color: #c42c3b;
box-shadow: 0 0 5px 1px #c9404d;
}

&:before {
content: " ";
display: inline-block;
width: 7px;
height: 7px;
margin-right: 10px;
border: 1px solid #000;
border-radius: 7px;
}
}
</style>
Loading