diff --git a/app/public/app.js b/app/public/app.js
index 67bedf5..0558ea5 100644
--- a/app/public/app.js
+++ b/app/public/app.js
@@ -3067,13 +3067,6 @@ function renderAmbientStation(device) {
setEl('st-uv', data.uv != null ? data.uv : '--');
setEl('st-solar', data.solarradiation != null ? Math.round(data.solarradiation) : '--');
- const indoorCard = document.getElementById('st-indoor-card');
- if (data.tempinf != null) {
- setEl('st-tempin', fmtTemp(data.tempinf));
- setEl('st-humin', data.humidityin != null ? `${data.humidityin}% RH` : '');
- if (indoorCard) indoorCard.classList.remove('hidden');
- }
-
if (peekEl && data.tempf != null) {
peekEl.textContent = `· ${fmtTemp(data.tempf)}°${tempUnit} ${data.humidity != null ? data.humidity + '% RH' : ''}`;
}
diff --git a/app/public/dashboard.html b/app/public/dashboard.html
index db41467..ca436b0 100644
--- a/app/public/dashboard.html
+++ b/app/public/dashboard.html
@@ -179,19 +179,6 @@ a { color: var(--cool); text-decoration: none; }
.today-lbl { font-size: 0.75rem; color: var(--ink-light); }
/* ── Ecobee section ── */
-.hvac-badge { display: inline-block; padding: 0.2rem 0.6rem; border-radius: 20px; font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; }
-.hvac-heating { background: rgba(194,90,42,0.18); color: var(--accent); border: 1px solid var(--accent); }
-.hvac-cooling { background: rgba(42,107,138,0.18); color: var(--cool); border: 1px solid var(--cool); }
-.hvac-fan { background: rgba(42,107,138,0.1); color: var(--cool); border: 1px solid var(--border); }
-.hvac-idle { background: var(--paper-darker); color: var(--ink-light); border: 1px solid var(--border); }
-.ecobee-sensors { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.75rem; }
-.sensor-chip { background: var(--paper); border: 1px solid var(--border); border-radius: 8px; padding: 0.35rem 0.7rem; font-size: 0.8rem; display: flex; align-items: center; gap: 0.4rem; }
-.sensor-chip-name { color: var(--ink-light); font-size: 0.72rem; }
-.sensor-chip-val { font-weight: 700; }
-.ecobee-row { display: flex; gap: 1.5rem; align-items: flex-start; flex-wrap: wrap; }
-.ecobee-main { flex: 0 0 auto; min-width: 120px; }
-.ecobee-setpoints { display: flex; gap: 1rem; margin-top: 0.4rem; font-size: 0.85rem; color: var(--ink-light); }
-.ecobee-setpoints strong { color: var(--ink); }
/* ── Tile color tints ── */
.stat-hot { border-color: rgba(220,80,30,0.55) !important; background: rgba(220,80,30,0.07) !important; }
@@ -294,7 +281,7 @@ canvas.sparkline { display: block; width: 100%; height: 22px; margin-top: 0.4rem
💨— mph peak gust
-
+
Wind
@@ -307,10 +294,6 @@ canvas.sparkline { display: block; width: 100%; height: 22px; margin-top: 0.4rem
-
-
-
-
@@ -334,29 +317,6 @@ canvas.sparkline { display: block; width: 100%; height: 22px; margin-top: 0.4rem
-
-
-
- Thermostat
- —
-
-
-
-
-
-
- Heat: —°
- Cool: —°
-
-
Humidity: —%
-
Mode: —
-
-
-
-
History:
@@ -403,43 +363,6 @@ canvas.sparkline { display: block; width: 100%; height: 22px; margin-top: 0.4rem
-
-
- Thermostat (HomeKit Push) Setup
-
-
-
-
iOS Shortcut Push URL
-
Configure your iOS Shortcut to POST thermostat data to this URL:
-
-
-
-
-
-
Auth Token
-
Include this as the x-homekit-token header in your Shortcut's URL request:
-
-
-
-
-
-
-
-
-
-
iOS Shortcut Setup
-
- - Open Shortcuts → tap + to create a new shortcut
- - Add Get my HomeKit value for → select your thermostat → Current Temperature → save as variable temp
- - Repeat for Target Temperature (save as targetTemp) and Current Relative Humidity (save as humidity)
- - Add Get contents of URL → paste the Push URL above → Method: POST
- - Add header:
x-homekit-token = (paste your token)
- - Request Body: JSON → add keys:
temperature=temp, heatSetF=targetTemp, humidity=humidity
- - Go to Automation tab → + → Time of Day → set repeat every 5 min → run this shortcut (no notification)
-
-
-
-
Station API Keys
@@ -810,15 +733,6 @@ function renderCharts(readings, range, yoy = null) {
- ${pts.some(r => r.tempinf != null) ? `
-
-
Indoor Temperature & Dew Point (°F)
-
-
-
-
Indoor Humidity (%)
-
-
` : ''}
`;
@@ -866,23 +780,6 @@ function renderCharts(readings, range, yoy = null) {
[lineDataset('Solar W/m²', field(pts, 'solarradiation'), c.accent)],
lbls, 'W/m²', { scales: { y: { min: 0 } } });
- if (pts.some(r => r.tempinf != null)) {
- const indoorDp = pts.map(r => {
- if (r.tempinf == null || r.humidityin == null) return null;
- const Tc = (r.tempinf - 32) * 5 / 9, RH = r.humidityin;
- const dp = (243.04 * (Math.log(RH / 100) + 17.625 * Tc / (243.04 + Tc))) /
- (17.625 - Math.log(RH / 100) - 17.625 * Tc / (243.04 + Tc));
- return +(dp * 9 / 5 + 32).toFixed(1);
- });
- makeChart('cTempIn', 'line',
- [lineDataset('Temp In °F', field(pts, 'tempinf'), c.accent),
- lineDataset('Dew Point In', indoorDp, c.cool, true)],
- lbls, '°F');
- makeChart('cHumIn', 'line',
- [lineDataset('Humidity In %', field(pts, 'humidityin'), c.cool)],
- lbls, '%', { scales: { y: { min: 0, max: 100 } } });
- }
-
// Today bar + sparklines use full readings (not downsampled pts)
updateTodayBar(readings);
updateSparklines(readings);
@@ -929,24 +826,6 @@ async function updateLatest() {
// Max daily gust
if (d.maxdailygust != null) set('sMaxGust', d.maxdailygust);
- // Indoor sensors
- if (d.tempinf != null) {
- set('sTempIn', d.tempinf);
- document.getElementById('indoorTempTile').style.display = '';
- }
- if (d.feelsLikein != null) {
- set('sFeelsIn', d.feelsLikein, 0);
- document.getElementById('indoorFeelsTile').style.display = '';
- }
- if (d.humidityin != null) {
- set('sHumIn', d.humidityin, 0);
- document.getElementById('indoorHumTile').style.display = '';
- }
- if (d.dewPointin != null) {
- set('sDewIn', d.dewPointin);
- document.getElementById('indoorDewTile').style.display = '';
- }
-
// Ambient rain accumulators
if (d.eventrainin != null && d.eventrainin > 0) {
set('sEventRain', d.eventrainin, 2);
@@ -1618,94 +1497,6 @@ document.getElementById('saveLocBtn')?.addEventListener('click', async () => {
} catch { msg.textContent = 'Error'; msg.className = 'save-msg err'; }
});
-// ── HomeKit thermostat push ───────────────────────────────────────────────────
-function hvacBadge(hvacState) {
- if (!hvacState) return { text: 'Idle', cls: 'hvac-idle' };
- const s = hvacState.toLowerCase();
- if (s.includes('cool')) return { text: 'Cooling', cls: 'hvac-cooling' };
- if (s.includes('heat')) return { text: 'Heating', cls: 'hvac-heating' };
- if (s.includes('fan')) return { text: 'Fan', cls: 'hvac-fan' };
- return { text: 'Idle', cls: 'hvac-idle' };
-}
-
-async function loadHomekitData() {
- const section = document.getElementById('ecobeeSection');
- try {
- const r = await fetch('/api/homekit/data');
- if (!r.ok) return;
- const d = await r.json();
- if (d.tempF == null) return;
-
- section.style.display = '';
- const set = (id, val) => { const el = document.getElementById(id); if (el && val != null) el.textContent = val; };
- set('ecobeeTempF', d.tempF != null ? d.tempF.toFixed(1) : '—');
- set('ecobeeHeatSet', d.heatSetF != null ? d.heatSetF.toFixed(0) : '—');
- set('ecobeeCoolSet', d.coolSetF != null ? d.coolSetF.toFixed(0) : '—');
- set('ecobeeHum', d.humidity ?? '—');
- set('ecobeeMode', d.mode ?? '—');
-
- const badge = document.getElementById('ecobeeBadge');
- if (badge) {
- const { text, cls } = hvacBadge(d.hvacState);
- badge.textContent = text;
- badge.className = `hvac-badge ${cls}`;
- }
-
- const upd = document.getElementById('ecobeeUpdated');
- if (upd && d.receivedAt) {
- upd.textContent = 'Updated ' + new Date(d.receivedAt).toLocaleTimeString();
- }
- } catch {}
-}
-
-async function loadHomekitConfigStatus() {
- try {
- const r = await fetch('/api/homekit/config');
- if (!r.ok) return;
- const d = await r.json();
- const el = document.getElementById('ecobeeConfigStatus');
- if (d.token) {
- el.textContent = '✓ Push endpoint active — configure your iOS Shortcut below';
- el.className = 'keys-status ok';
- } else {
- el.textContent = '⚠ Token not configured';
- el.className = 'keys-status missing';
- }
- const urlInput = document.getElementById('homekitPushUrl');
- if (urlInput) urlInput.value = window.location.origin + '/api/homekit/push';
- const tokenInput = document.getElementById('homekitTokenDisplay');
- if (tokenInput) tokenInput.value = d.token || '';
- } catch {}
-}
-
-document.getElementById('homekitCopyUrlBtn')?.addEventListener('click', () => {
- const val = document.getElementById('homekitPushUrl')?.value;
- if (val) navigator.clipboard.writeText(val).catch(() => {});
-});
-
-document.getElementById('homekitCopyTokenBtn')?.addEventListener('click', () => {
- const val = document.getElementById('homekitTokenDisplay')?.value;
- if (val) navigator.clipboard.writeText(val).catch(() => {});
-});
-
-document.getElementById('homekitRegenBtn')?.addEventListener('click', async () => {
- const msg = document.getElementById('homekitRegenMsg');
- try {
- const r = await fetch('/api/homekit/config/regenerate', { method: 'POST' });
- const d = await r.json();
- if (r.ok && d.token) {
- const tokenInput = document.getElementById('homekitTokenDisplay');
- if (tokenInput) tokenInput.value = d.token;
- msg.textContent = 'Token regenerated — update your Shortcut'; msg.className = 'save-msg';
- } else { msg.textContent = 'Error'; msg.className = 'save-msg err'; }
- setTimeout(() => msg.textContent = '', 4000);
- } catch { msg.textContent = 'Error'; msg.className = 'save-msg err'; }
-});
-
-document.getElementById('ecobeeSettingsPanel')?.addEventListener('toggle', function() {
- if (this.open) loadHomekitConfigStatus();
-});
-
// ── Init all new features ─────────────────────────────────────────────────────
updateLatest();
updatePressureTrend();
@@ -1719,13 +1510,10 @@ loadThresholds();
loadAlerts();
loadStreak();
loadLocation();
-loadHomekitData();
-
setInterval(updatePressureTrend, 120000);
setInterval(updateExtStats, 300000);
setInterval(updateTrends, 120000);
setInterval(loadAlerts, 5 * 60 * 1000);
-setInterval(loadHomekitData, 3 * 60 * 1000);