class PetrolAction extends ActionBase { constructor($UD, context) { super($UD, context); this.config = { url: '', stationUuid: '', fuelType: '', refreshRate: '1', }; this.previousPrice = null; this.lastRised = null; this.prevLastRised = null; this.$UD.onDidReceiveSettings(jsn => { if (jsn.context !== this.context) return; const s = jsn.settings || {}; this.config = Object.assign(this.config, s); if (s.previousPrice != null) this.previousPrice = s.previousPrice; if (s.lastRised > 0) this.lastRised = s.lastRised; if (s.prevLastRised > 0) this.prevLastRised = s.prevLastRised; }); } setActive() {} setParams(jsn) { this.config = Object.assign(this.config, (jsn && jsn.param) || {}); this.$UD.getSettings(this.context); this.startTimer(() => this.fetchPrice(), this.config.refreshRate); } onRun() { this.fetchPrice(); } fetchPrice() { this.debounce(async () => { if (!this.config.url || !this.config.stationUuid || !this.config.fuelType) { this.renderButton('?'); return; } try { const response = await fetch(this.config.url); const text = await response.text(); const raw = this.parsePrometheus(text); if (raw) { const current = parseFloat(raw); if (this.previousPrice !== null) { const delta = current - this.previousPrice; if (delta > 0) { this.prevLastRised = this.lastRised; this.lastRised = current; } } this.previousPrice = current; this.renderButton(`${parseFloat(raw).toFixed(3)}€`); this.$UD.setSettings({ ...this.config, previousPrice: this.previousPrice, lastRised: this.lastRised, prevLastRised: this.prevLastRised, }, this.context); } else { this.renderButton('N/A'); } } catch (e) { this.renderButton('ERR'); } }); } parsePrometheus(text) { for (const line of text.split('\n')) { const trimmed = line.trim(); if (!trimmed || trimmed.startsWith('#')) continue; if (trimmed.startsWith('petrol_price_euro') && trimmed.includes(this.config.stationUuid) && trimmed.includes(this.config.fuelType)) { const closingBrace = trimmed.indexOf('}'); if (closingBrace !== -1) return trimmed.slice(closingBrace + 1).trim(); } } return null; } renderButton(priceText) { const { canvas, ctx } = this.createCanvas(); let risedColor = '#888888'; if (this.lastRised > 0 && this.prevLastRised > 0) { risedColor = this.lastRised < this.prevLastRised ? '#6bff6b' : '#ff6b6b'; } if (this.lastRised !== null) { ctx.fillStyle = '#7ec8e3'; ctx.font = 'bold 22px "Source Han Sans SC"'; ctx.fillText(this.config.fuelType, 98, 25); const fSize = priceText.length > 6 ? 36 : 42; ctx.fillStyle = '#f0c040'; ctx.font = `bold ${fSize}px "Source Han Sans SC"`; ctx.fillText(priceText, 98, 82); ctx.fillStyle = '#888888'; ctx.font = '20px "Source Han Sans SC"'; ctx.fillText(this.$UD.t('Last Rised'), 98, 130); ctx.fillStyle = risedColor; ctx.font = 'bold 28px "Source Han Sans SC"'; ctx.fillText(`${this.lastRised.toFixed(3)}€`, 98, 162); } else { ctx.fillStyle = '#7ec8e3'; ctx.font = 'bold 28px "Source Han Sans SC"'; ctx.fillText(this.config.fuelType, 98, 42); const fSize = priceText.length > 6 ? 38 : 46; ctx.fillStyle = '#f0c040'; ctx.font = `bold ${fSize}px "Source Han Sans SC"`; ctx.fillText(priceText, 98, 105); } this.setIcon(canvas); } }