New SenseCraft HMI release v1.2.0 (=screen designer for Seeed e-paper displays) and firmware v1.0.8: release notes.
Short: More templates, more third-party data integrations, more out-of-the-box logic, inproved api connections (not every Homey field has to be defined with a separate api connection, but still room for improvements).
In the meantime, there are several new template integrations (which I haven’t tried myself), such as Google Calendar:
List with more templates/integrations.
New article about these e-paper displays on Dutch tech site Tweakers.
The latest version of the SenseCraft HMI screen designer allows you to send data from Homey to the e-paper screen. This version also includes many new features (release notes here) for creating screens.
I created a Homey script that collects all data needed from various devices. With a single POST command, all the data is available as fields in the screen designer.
It’s even possible to generate a chart (I use the free and fast Quickchart generator in Homey script) and send the resulting URL to the screen. The chart below isn’t a Power-by-the-Hour energy prices chart (that didn’t look nice on the screen), but was generated with Quickchart.
Hi Amersfoort, good work! Can you share your posting homey script?
This Homey script gets all data needed for the 2 Seeed SenseCraft HMI screens below (except the graph).
const url = 'https://sensecraft-hmi-api.seeed.cc/api/v1/user/device/push_data';
const apiKey = 'xxxxxxxxxx'; //fill Seeed api key
//function: get capability from device
const getVal = (dev, cap, unit = "", decimals = 1) => {
try {
if (!dev) return "N/B";
const val = dev.makeCapabilityInstance(cap).value;
if (val === null || val === undefined) return "N/B";
if (typeof val === 'number') {
return val.toFixed(decimals).replace('.', ',') + (unit ? ` ${unit}` : "");
}
return val + (unit ? ` ${unit}` : "");
} catch (e) {
return "N/B";
}
};
// 1. Get base data Homey
const devices = await Homey.devices.getDevices({ $skipCache: true });
const rawVariables = await Homey.logic.getVariables();
const variablesArray = Object.values(rawVariables);
const allDevs = Object.values(devices);
// 2. Helper for variables (Logic)
const getVar = (name) => {
const v = variablesArray.find(v => v.name === name);
return v ? v.value : null;
};
// 3. Get devices based on name
const d = {
hw: allDevs.find(i => i.name === 'Elektra en Gas'),
water: allDevs.find(i => i.name === 'Water'),
enphase: allDevs.find(i => i.name === 'Enphase VD'),
zonneplan: allDevs.find(i => i.name === 'Zonneplan p1'),
shelly: allDevs.find(i => i.name === 'Shelly HT Gen3'),
knmi: allDevs.find(i => i.name === 'KNMI'),
weer: allDevs.find(i => i.name === 'Weerstation'),
regen: allDevs.find(i => i.name === 'Regenmeter'),
prijzen: allDevs.find(i => i.name === 'Elektra dagprijzen')
};
// 4. Build data object for Seeed HMI
const data = {
// --- ELEKTRA ---
ElektraVermogenNu: getVal(d.hw, 'measure_power', 'W', 0),
ElektraVerbruikVandaag: getVal(d.hw, 'meter_power.daily', 'kWh', 1),
ElektraSolarNu: getVal(d.enphase, 'measure_power', 'W', 0),
ElektraSolarVandaag: getVal(d.enphase, 'meter_power', 'kWh', 1),
ElektraTerugleveringVandaag: getVal(d.zonneplan, 'meter_power.daily_production', 'kWh', 1),
ElektraKostenVandaag: "€ " + getVal(d.zonneplan, 'meter_power.daily_cost', '', 2),
// --- GAS & WATER ---
GasVerbruikNu: getVal(d.hw, 'measure_gas', 'm3', 1),
GasVandaag: getVal(d.zonneplan, 'meter_gas.daily', 'm3', 1),
GasKostenVandaag: "€ " + getVal(d.zonneplan, 'meter_gas.daily_price', '', 2),
// Water convert m3 to liter
WaterVandaag: (() => {
try {
const m3 = d.water.makeCapabilityInstance('meter_water.daily').value;
return (m3 * 1000).toFixed(0).replace('.', ',') + " L";
} catch (e) { return "0 L"; }
})(),
// --- WEER BINNEN ---
WeerTempHuiskamer: getVal(d.shelly, 'measure_temperature', '°C', 1),
WeerLuchtvochtigheidHuiskamer: getVal(d.shelly, 'measure_humidity', '%', 1),
// --- WEER BUITEN ---
WeerTempBuiten: getVal(d.weer, 'measure_temperature', '°C', 1),
WeerGevoelstemp: getVal(d.weer, 'measure_temperature.feelsLike', '°C', 1),
WeerstationTempMin: (getVar("Minimum temperatuur") || 0).toFixed(1).replace('.', ',') + " °C",
WeerstationTempMax: (getVar("Maximum temperatuur") || 0).toFixed(1).replace('.', ',') + " °C",
// KNMI & Omgevingssensoren
WeerZonOp: getVal(d.knmi, 'sun_up'),
WeerZonOnder: getVal(d.knmi, 'sun_down'),
WeerNuOmschrijving: getVal(d.knmi, 'recap'),
WeerVerwachting: getVal(d.knmi, 'expected'),
WeerRegenNu: "nu: " + getVal(d.regen, 'measure_rain.rate', 'mm/u', 1),
WeerRegenVandaag: getVal(d.regen, 'measure_rain.daily', 'mm', 1),
WeerLuchtvochtigheid: getVal(d.weer, 'measure_humidity', '%', 0),
WeerKNMIVerwachtingMinTemp: getVal(d.knmi, 'expected_today_min_temp', '°C', 0),
WeerKNMIVerwachtingMaxTemp: getVal(d.knmi, 'expected_today_max_temp', '°C', 0),
WeerWindSnelheid: getVal(d.weer, 'measure_wind_strength', 'km/u', 0),
WeerWindRichting: getVal(d.weer, 'measure_wind_direction'),
WeerLuchtdruk: getVal(d.weer, 'measure_pressure', 'hPa', 0),
WeerZonKans: getVal(d.knmi, 'expected_today_sunshine', '%', 0),
WeerZonUV: getVal(d.weer, 'measure_ultraviolet', 'UVI', 0),
WeerZonLux: getVal(d.weer, 'measure_luminance', 'lx', 0),
// URLs
ElektraprijzenUrl: getVar("StroomGrafiekURL") || ""
};
// 5. Get energy prices per hour (8 hours)
const huidigeTijd = new Date();
const startUur = huidigeTijd.getHours();
for (let i = 0; i <= 7; i++) {
const uur = (startUur + i) % 24;
const prijs = getVal(d.prijzen, 'meter_price_h' + i, '', 3);
data[`ElektraPrijsTijd${i}`] = `${uur} uur: € ${prijs}`;
}
// 6. Generate update time
data.DatumTijd = "weerupdate: " + huidigeTijd.toLocaleDateString('nl-NL', {
weekday: 'long', day: 'numeric', month: 'long', hour: '2-digit', minute: '2-digit'
}).replace(',', '') + " uur";
// 7. Send data to Seeed API
try {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'api-key': apiKey
},
body: JSON.stringify({
device_id: xxxxxxx, //fill in Seeed device id
data: data
})
});
if (!response.ok) {
const errText = await response.text();
throw new Error(`HTTP ${response.status}: ${errText}`);
}
log('Succes: Data verzonden naar Seeed HMI');
return true;
} catch (err) {
console.error('Script error:', err.message);
return false;
}



