diff --git a/docs/customservices.md b/docs/customservices.md
index c1f0812..b053056 100644
--- a/docs/customservices.md
+++ b/docs/customservices.md
@@ -226,6 +226,7 @@ The Healthchecks API key can be found in Settings > API Access > API key (read-o
You need to set the type to HomeAssistant, provide an api key and enable cors on Home Assistant.
+**Basic configuration:**
```yaml
- name: "HomeAssistant"
logo: "assets/tools/sample.png"
@@ -236,6 +237,35 @@ You need to set the type to HomeAssistant, provide an api key and enable cors on
separator: " " # optional, how to separate items
```
+**Custom sensors configuration:**
+```yaml
+- name: "Home Assistant"
+ logo: "assets/tools/sample.png"
+ url: "http://192.168.0.151/"
+ type: "HomeAssistant"
+ apikey: "<---insert-api-key-here--->"
+ showUnits: true # Optional: Show units from Home Assistant (default: true)
+ updateInterval: 30000 # Optional: Sensor refresh interval in ms (default: 30000)
+ sensors: # Optional: Display custom sensors instead of default stats
+ - id: "sensor.living_room_temperature"
+ icon: "fas fa-home"
+ - id: "sensor.bedroom_humidity"
+ icon: "fas fa-bed"
+ - id: "sensor.power_consumption"
+ icon: "fas fa-bolt"
+ - id: "sensor.outdoor_air_quality"
+ icon: "fas fa-cloud-sun"
+```
+
+**Configuration Options:**
+
+- When `sensors` is provided, the service displays sensor readings with custom icons instead of the default version/entity information
+- `showUnits`: Controls whether to display units from Home Assistant (default: `true`)
+- `updateInterval`: How often to refresh sensor data in milliseconds (default: `30000`)
+- Sensor values are automatically formatted to 1 decimal place with units (when enabled)
+- Supports any numeric sensor type (temperature, humidity, power, etc.)
+- Falls back to original behavior if `sensors` is not configured
+
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`
diff --git a/src/components/services/HomeAssistant.vue b/src/components/services/HomeAssistant.vue
index 6bedbff..7108e8a 100644
--- a/src/components/services/HomeAssistant.vue
+++ b/src/components/services/HomeAssistant.vue
@@ -6,6 +6,18 @@
{{ item.subtitle }}
+
+
+
+
+ {{ sensor.value }}
+
+
+
{{ details }}
@@ -35,6 +47,7 @@ export default {
location_name: "",
separator: " ",
items: ["name", "version"],
+ sensors: [],
}),
computed: {
headers: function () {
@@ -70,16 +83,54 @@ export default {
},
},
created() {
- this.fetchServerStatus().then(() => {
- if (!this.item.subtitle && this.status !== "dead") {
- if (this.item.items) this.items = this.item.items;
- if (this.item.separator) this.separator = this.item.separator;
+ if (this.item.sensors) {
+ // If sensors are configured, fetch sensor data
+ this.fetchSensors();
- this.fetchServerStats();
- }
- });
+ // Set up configurable refresh interval (default 30 seconds)
+ const updateInterval = parseInt(this.item.updateInterval, 10) || 30000;
+ setInterval(() => this.fetchSensors(), updateInterval);
+ } else {
+ // Original behavior for status/stats
+ this.fetchServerStatus().then(() => {
+ if (!this.item.subtitle && this.status !== "dead") {
+ if (this.item.items) this.items = this.item.items;
+ if (this.item.separator) this.separator = this.item.separator;
+
+ this.fetchServerStats();
+ }
+ });
+ }
},
methods: {
+ fetchSensors: async function () {
+ const headers = this.headers;
+
+ try {
+ const response = await this.fetch("/api/states", { headers });
+
+ // Use configurable sensors from item.sensors
+ this.sensors = this.item.sensors
+ .map((sensorConfig) => {
+ const match = response.find((s) => s.entity_id === sensorConfig.id);
+ if (match && !isNaN(parseFloat(match.state))) {
+ const value = parseFloat(match.state).toFixed(1);
+ const unit = match.attributes?.unit_of_measurement || "";
+ const showUnits = this.item.showUnits !== false; // Default to true
+ return {
+ icon: sensorConfig.icon,
+ value: (showUnits && unit) ? `${value}${unit}` : value,
+ };
+ } else {
+ return null;
+ }
+ })
+ .filter(Boolean); // Remove null entries
+ } catch (error) {
+ console.error("Failed to fetch sensors:", error);
+ this.sensors = [];
+ }
+ },
fetchServerStatus: async function () {
const headers = this.headers;
@@ -151,4 +202,16 @@ export default {
border-radius: 7px;
}
}
+
+.sensors {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+}
+
+.sensor {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+}