Examples
June 22, 2026 · View on GitHub
Fetch current weather from Open-Meteo
Open-Meteo is free, no API key required. Publish the result to MQTT so other scripts can react to it.
async function updateWeather() {
const lat = she.config.latitude;
const lon = she.config.longitude;
try {
const { body: data } = await she.http.fetch(
`https://api.open-meteo.com/v1/forecast` +
`?latitude=${lat}&longitude=${lon}` +
`¤t=temperature_2m,precipitation,wind_speed_10m,weather_code`
);
const c = data.current;
she.mqtt.pub('home/weather/temperature', c.temperature_2m);
she.mqtt.pub('home/weather/precipitation', c.precipitation);
she.mqtt.pub('home/weather/wind_speed', c.wind_speed_10m);
she.mqtt.pub('home/weather/code', c.weather_code);
} catch (err) {
she.warn('weather fetch failed:', err.message);
}
}
// Update every 15 minutes
updateWeather();
she.schedule('*/15 * * * *', updateWeather);
Expose a sensor reading via HTTP GET
// GET /api/sensors/temperature?room=living → { room: "living", temp: 21.5 }
she.api.get('/temperature', (req) => {
const room = req.query.room || 'living';
return {
room,
temp: she.mqtt.get(`home/sensor/${room}/temp`),
};
});
Trigger a scene via HTTP POST
she.api.post('/scene', (req, body) => {
if (!body.scene) throw new Error('scene is required');
she.mqtt.pub('home/scene/activate', body.scene);
she.info('scene activated via HTTP:', body.scene);
return { ok: true, scene: body.scene };
});
curl -X POST http://she-host:8080/api/myscript/scene \
-H "Content-Type: application/json" \
-d '{"scene":"movie"}'
Receive a webhook from an external service
// POST /api/myscript/webhook/doorbell ← called by a cloud doorbell service
she.http.sub('/webhook/doorbell', (body, { headers }) => {
she.log('doorbell webhook received:', body);
she.mqtt.pub('home/doorbell', 1);
// Auto-clear after 2 s
setTimeout(() => she.mqtt.pub('home/doorbell', 0), 2000);
});
Webhook with a shared secret
Validate an Authorization header to prevent unauthorized callers.
const SECRET = 'my-webhook-secret'; // store this in a lib script or sheDB, not inline
she.http.sub('/webhook/sensor', (body, { headers }) => {
if (headers['authorization'] !== `Bearer ${SECRET}`) {
throw new Error('unauthorized');
}
she.mqtt.pub('home/sensor/external/value', body.value);
});
Send a Pushover push notification
Uses she.http.fetch — no npm package needed.
// Store credentials in sheDB under 'config/pushover'
// { "appToken": "...", "userKey": "..." }
const cfg = she.db.get('config/pushover') || {};
async function notify(title, message, opts = {}) {
if (!cfg.appToken || !cfg.userKey) {
she.warn('pushover not configured — skipping notification');
return;
}
try {
await she.http.fetch('https://api.pushover.net/1/messages.json', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
token: cfg.appToken,
user: cfg.userKey,
title,
message,
priority: opts.priority ?? 0,
}),
});
} catch (err) {
she.warn('pushover send failed:', err.message);
}
}
// Use from this script or share via she.global.notify (see cross-script examples)
she.global.notify = notify;
// Alert on flood
she.mqtt.sub('home/sensor/basement/flood', { change: true, retain: true }, async (topic, val) => {
try {
if (val) await notify('⚠️ FLOOD', 'Basement flood sensor triggered', { priority: 1 });
} catch (err) {
she.error('flood alert failed:', err.message);
}
});
Fetch and cache an external API, expose via MQTT and HTTP
Avoid hammering a rate-limited API by caching the result and serving it from MQTT state.
let lastFetch = 0;
const CACHE_TTL = 10 * 60 * 1000; // 10 minutes
async function fetchPrice() {
if (Date.now() - lastFetch < CACHE_TTL) return;
try {
const { body: data } = await she.http.fetch('https://api.example.com/electricity/price');
she.mqtt.pub('home/energy/price_ct', data.price_cents);
lastFetch = Date.now();
} catch (err) {
she.warn('price fetch failed:', err.message);
}
}
she.schedule('*/10 * * * *', fetchPrice);
fetchPrice();
she.api.get('/price', () => ({
price_ct: she.mqtt.get('home/energy/price_ct'),
last_update: she.mqtt.getProp('home/energy/price_ct', 'ts'),
}));
Dynamic route parameter
// GET /api/myscript/devices/hall/pir → document from sheDB
she.api.get('/devices/:path(*)', (req) => {
const doc = she.db.get('devices/' + req.params.path);
if (!doc) throw new Error('not found');
return doc;
});