dk_cheapest_hours
Identify low-cost electricity periods in Denmark to schedule energy-intensive tasks like EV charging or appliance use, optimizing for price areas DK1 or DK2.
Instructions
Find the cheapest hours to use electricity today/tomorrow. Useful for scheduling EV charging, laundry, dishwasher, heat pumps, etc.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| area | Yes | Price area: DK1 or DK2, or a city/region name. | |
| count | No | Number of cheapest hours to return (default: 5) | |
| consecutive | No | If true, find the cheapest consecutive block of 'count' hours (default: false) |
Implementation Reference
- src/servers/danish-energy.js:240-299 (handler)The handler function for 'dk_cheapest_hours' which fetches spot price data and calculates either the cheapest individual hours or the cheapest consecutive block of hours.
async ({ area, count = 5, consecutive = false }) => { const priceArea = resolvePriceArea(area); if (!priceArea) { return { content: [{ type: "text", text: "Could not determine price area. Use DK1 (western Denmark) or DK2 (eastern Denmark), or a city name." }] }; } const data = await fetchDataset("Elspotprices", { limit: 48, sort: "HourDK asc", filter: JSON.stringify({ PriceArea: priceArea }), start: "now-PT1H", }); if (!data.records?.length) { return { content: [{ type: "text", text: "No price data available." }] }; } const records = data.records.filter(r => r.SpotPriceDKK != null); let output = `# Cheapest Hours — ${priceArea} (${PRICE_AREAS[priceArea]})\n\n`; if (consecutive && count > 1) { // Find cheapest consecutive block let bestStart = 0; let bestAvg = Infinity; for (let i = 0; i <= records.length - count; i++) { const block = records.slice(i, i + count); const avg = block.reduce((s, r) => s + r.SpotPriceDKK, 0) / count; if (avg < bestAvg) { bestAvg = avg; bestStart = i; } } const block = records.slice(bestStart, bestStart + count); output += `**Best ${count}-hour block:**\n`; output += `**Start:** ${block[0].HourDK?.replace("T", " ").slice(0, 16)}\n`; output += `**End:** ${block[block.length - 1].HourDK?.replace("T", " ").slice(0, 16)} + 1h\n`; output += `**Average price:** ${formatPrice(bestAvg)}\n\n`; output += "| Hour | Price |\n|---|---|\n"; for (const r of block) { output += `| ${r.HourDK?.replace("T", " ").slice(0, 16)} | ${formatPrice(r.SpotPriceDKK)} |\n`; } } else { // Find N cheapest individual hours const sorted = [...records].sort((a, b) => a.SpotPriceDKK - b.SpotPriceDKK); const cheapest = sorted.slice(0, count); output += `**${count} cheapest hours:**\n\n`; output += "| Rank | Hour | Price |\n|---|---|---|\n"; for (let i = 0; i < cheapest.length; i++) { const r = cheapest[i]; output += `| ${i + 1} | ${r.HourDK?.replace("T", " ").slice(0, 16)} | ${formatPrice(r.SpotPriceDKK)} |\n`; } } output += "\n*Prices are spot prices excl. taxes, tariffs, and VAT. Source: Energi Data Service.*\n"; return { content: [{ type: "text", text: output }] }; } - src/servers/danish-energy.js:232-239 (registration)The registration of the 'dk_cheapest_hours' tool, including its schema definition for input parameters (area, count, consecutive).
server.tool( "dk_cheapest_hours", "Find the cheapest hours to use electricity today/tomorrow. Useful for scheduling EV charging, laundry, dishwasher, heat pumps, etc.", { area: z.string().describe("Price area: DK1 or DK2, or a city/region name."), count: z.number().optional().describe("Number of cheapest hours to return (default: 5)"), consecutive: z.boolean().optional().describe("If true, find the cheapest consecutive block of 'count' hours (default: false)"), },