aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--docs/customservices.md17
-rw-r--r--dummy-data/openHAB/rest/systeminfo18
-rw-r--r--src/components/services/OpenHAB.vue144
3 files changed, 179 insertions, 0 deletions
diff --git a/docs/customservices.md b/docs/customservices.md
index 910f401..64ed416 100644
--- a/docs/customservices.md
+++ b/docs/customservices.md
@@ -35,6 +35,7 @@ within Homer:
35 - [Tdarr](#tdarr) 35 - [Tdarr](#tdarr)
36 - [PiAlert](#pialert) 36 - [PiAlert](#pialert)
37 - [Immich](#immich) 37 - [Immich](#immich)
38 - [OpenHAB](#openhab)
38 39
39If you experiencing any issue, please have a look to the [troubleshooting](troubleshooting.md) page. 40If you experiencing any issue, please have a look to the [troubleshooting](troubleshooting.md) page.
40 41
@@ -446,3 +447,19 @@ The Immich server must be running at least version 1.85.0 for the correct api en
446 apikey: "<--- Your api key --->" # administrator user 447 apikey: "<--- Your api key --->" # administrator user
447 updateInterval: 5000 # (Optional) Interval (in ms) for updating the stats 448 updateInterval: 5000 # (Optional) Interval (in ms) for updating the stats
448``` 449```
450
451## OpenHAB
452
453You need to set the type to OpenHAB, provide an api key and enable cors on OpenHAB.
454
455```yaml
456- name: "OpenHAB"
457 logo: "assets/tools/sample.png"
458 url: "http://192.168.0.151/"
459 type: "OpenHAB"
460 apikey: "<---insert-api-key-here--->"
461 things: true # true will query the things API and report total and online things count. false will skip the call
462 items: true # true will query the items API and report total items count. false will skip the call
463```
464To create an API token on OpenHAB, follow the [official documentation here](https://www.openhab.org/docs/configuration/apitokens.html).
465To enable cors on OpenHAB, edit your services/runtime.cfg and uncomment or add this line: `org.openhab.cors:enable=true` \ No newline at end of file
diff --git a/dummy-data/openHAB/rest/systeminfo b/dummy-data/openHAB/rest/systeminfo
new file mode 100644
index 0000000..e692cea
--- /dev/null
+++ b/dummy-data/openHAB/rest/systeminfo
@@ -0,0 +1,18 @@
1{
2 "systemInfo": {
3 "configFolder": "/etc/openhab",
4 "userdataFolder": "/var/lib/openhab",
5 "logFolder": "/var/log/openhab",
6 "javaVersion": "17.0.9",
7 "javaVendor": "Azul Systems, Inc.",
8 "javaVendorVersion": "Zulu17.46+19-CA",
9 "osName": "Linux",
10 "osVersion": "6.5.11-4-pve",
11 "osArchitecture": "amd64",
12 "availableProcessors": 2,
13 "freeMemory": 75885968,
14 "totalMemory": 494927872,
15 "uptime": 2150186,
16 "startLevel": 100
17 }
18} \ No newline at end of file
diff --git a/src/components/services/OpenHAB.vue b/src/components/services/OpenHAB.vue
new file mode 100644
index 0000000..03b50b2
--- /dev/null
+++ b/src/components/services/OpenHAB.vue
@@ -0,0 +1,144 @@
1<template>
2 <Generic :item="item">
3 <template #content>
4 <p class="title is-4">{{ item.name }}</p>
5 <p class="subtitle is-6">
6 <template v-if="item.subtitle">
7 {{ item.subtitle }}
8 </template>
9 <template v-else>
10 {{ details }}
11 </template>
12 </p>
13 </template>
14 <template #indicator>
15 <div v-if="status" class="status" :class="status">
16 {{ status }}
17 </div>
18 </template>
19 </Generic>
20</template>
21
22<script>
23import service from "@/mixins/service.js";
24import Generic from "./Generic.vue";
25
26export default {
27 name: "OpenHAB",
28 mixins: [service],
29 props: {
30 item: Object,
31 },
32 components: {
33 Generic,
34 },
35 data: () => ({
36 status: "",
37 things: {
38 count: 0,
39 online: 0,
40 },
41 items: {
42 count: 0,
43 },
44 }),
45 computed: {
46 headers: function () {
47 const basicAuth = `${this.item.apikey}:`;
48
49 return {
50 Authorization: `Basic ${btoa(basicAuth)}`,
51 };
52 },
53 details: function () {
54 const details = [];
55
56 if (this.item.things) {
57 details.push(
58 `${this.things.count} things (${this.things.online} Online)`,
59 );
60 }
61
62 if (this.item.items) {
63 details.push(`${this.items.count} items`);
64 }
65
66 return details.join(", ");
67 },
68 },
69 created() {
70 this.fetchServerStatus();
71
72 if (!this.item.subtitle && this.status !== "dead") {
73 this.fetchServerStats();
74 }
75 },
76 methods: {
77 fetchServerStatus: async function () {
78 const headers = this.headers;
79 this.fetch("/rest/systeminfo", { headers })
80 .then((response) => {
81 if (response && response.systemInfo) this.status = "running";
82 else throw new Error();
83 })
84 .catch((e) => {
85 console.log(e);
86 this.status = "dead";
87 });
88 },
89 fetchServerStats: async function () {
90 const headers = this.headers;
91
92 if (this.item.things) {
93 const data = await this.fetch("/rest/things?summary=true", {
94 headers,
95 }).catch((e) => {
96 console.log(e);
97 });
98
99 this.things.count = data.length;
100 this.things.online = data.filter(
101 (e) => e.statusInfo.status === "ONLINE",
102 ).length;
103 }
104
105 if (this.item.items) {
106 const data = await this.fetch("/rest/items", { headers }).catch((e) => {
107 console.log(e);
108 });
109
110 this.items.count = data.length;
111 }
112 },
113 },
114};
115</script>
116
117<style scoped lang="scss">
118.status {
119 font-size: 0.8rem;
120 color: var(--text-title);
121
122 &.running:before {
123 background-color: #94e185;
124 border-color: #78d965;
125 box-shadow: 0 0 5px 1px #94e185;
126 }
127
128 &.dead:before {
129 background-color: #c9404d;
130 border-color: #c42c3b;
131 box-shadow: 0 0 5px 1px #c9404d;
132 }
133
134 &:before {
135 content: " ";
136 display: inline-block;
137 width: 7px;
138 height: 7px;
139 margin-right: 10px;
140 border: 1px solid #000;
141 border-radius: 7px;
142 }
143}
144</style>