|
6 | 6 | <template v-if="item.subtitle"> |
7 | 7 | {{ item.subtitle }} |
8 | 8 | </template> |
| 9 | + <template v-else-if="item.sensors && sensors.length > 0"> |
| 10 | + <span class="sensors"> |
| 11 | + <span |
| 12 | + v-for="(sensor, index) in sensors" |
| 13 | + :key="index" |
| 14 | + class="sensor" |
| 15 | + > |
| 16 | + <i :class="sensor.icon"></i> |
| 17 | + <span class="sensor-value">{{ sensor.value }}</span> |
| 18 | + </span> |
| 19 | + </span> |
| 20 | + </template> |
9 | 21 | <template v-else> |
10 | 22 | {{ details }} |
11 | 23 | </template> |
@@ -35,6 +47,7 @@ export default { |
35 | 47 | location_name: "", |
36 | 48 | separator: " ", |
37 | 49 | items: ["name", "version"], |
| 50 | + sensors: [], |
38 | 51 | }), |
39 | 52 | computed: { |
40 | 53 | headers: function () { |
@@ -70,16 +83,54 @@ export default { |
70 | 83 | }, |
71 | 84 | }, |
72 | 85 | created() { |
73 | | - this.fetchServerStatus().then(() => { |
74 | | - if (!this.item.subtitle && this.status !== "dead") { |
75 | | - if (this.item.items) this.items = this.item.items; |
76 | | - if (this.item.separator) this.separator = this.item.separator; |
| 86 | + if (this.item.sensors) { |
| 87 | + // If sensors are configured, fetch sensor data |
| 88 | + this.fetchSensors(); |
| 89 | + |
| 90 | + // Set up configurable refresh interval (default 30 seconds) |
| 91 | + const updateInterval = parseInt(this.item.updateInterval, 10) || 30000; |
| 92 | + setInterval(() => this.fetchSensors(), updateInterval); |
| 93 | + } else { |
| 94 | + // Original behavior for status/stats |
| 95 | + this.fetchServerStatus().then(() => { |
| 96 | + if (!this.item.subtitle && this.status !== "dead") { |
| 97 | + if (this.item.items) this.items = this.item.items; |
| 98 | + if (this.item.separator) this.separator = this.item.separator; |
77 | 99 |
|
78 | | - this.fetchServerStats(); |
79 | | - } |
80 | | - }); |
| 100 | + this.fetchServerStats(); |
| 101 | + } |
| 102 | + }); |
| 103 | + } |
81 | 104 | }, |
82 | 105 | methods: { |
| 106 | + fetchSensors: async function () { |
| 107 | + const headers = this.headers; |
| 108 | +
|
| 109 | + try { |
| 110 | + const response = await this.fetch("/api/states", { headers }); |
| 111 | +
|
| 112 | + // Use configurable sensors from item.sensors |
| 113 | + this.sensors = this.item.sensors |
| 114 | + .map((sensorConfig) => { |
| 115 | + const match = response.find((s) => s.entity_id === sensorConfig.id); |
| 116 | + if (match && !isNaN(parseFloat(match.state))) { |
| 117 | + const value = parseFloat(match.state).toFixed(1); |
| 118 | + const unit = match.attributes?.unit_of_measurement || ""; |
| 119 | + const showUnits = this.item.showUnits !== false; // Default to true |
| 120 | + return { |
| 121 | + icon: sensorConfig.icon, |
| 122 | + value: (showUnits && unit) ? `${value}${unit}` : value, |
| 123 | + }; |
| 124 | + } else { |
| 125 | + return null; |
| 126 | + } |
| 127 | + }) |
| 128 | + .filter(Boolean); // Remove null entries |
| 129 | + } catch (error) { |
| 130 | + console.error("Failed to fetch sensors:", error); |
| 131 | + this.sensors = []; |
| 132 | + } |
| 133 | + }, |
83 | 134 | fetchServerStatus: async function () { |
84 | 135 | const headers = this.headers; |
85 | 136 |
|
@@ -151,4 +202,21 @@ export default { |
151 | 202 | border-radius: 7px; |
152 | 203 | } |
153 | 204 | } |
| 205 | +
|
| 206 | +.sensors { |
| 207 | + display: flex; |
| 208 | + flex-wrap: wrap; |
| 209 | + gap: 8px; |
| 210 | +} |
| 211 | +
|
| 212 | +.sensor { |
| 213 | + display: inline-flex; |
| 214 | + align-items: center; |
| 215 | + gap: 4px; |
| 216 | +
|
| 217 | + .sensor-value { |
| 218 | + font-weight: 500; |
| 219 | + color: var(--text-title); |
| 220 | + } |
| 221 | +} |
154 | 222 | </style> |
0 commit comments