compare_electricity_tariffs
Compare Swiss electricity tariffs across municipalities to find the cheapest options for relocation or cost analysis.
Instructions
Compare Swiss electricity tariffs across multiple municipalities side-by-side. Returns prices sorted from cheapest to most expensive. Useful for relocation decisions or cost analysis.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| municipalities | Yes | Array of municipality BFS numbers to compare (e.g. ['261', '351', '6621']). Max 20. Use search_municipality_energy to find IDs. | |
| category | No | Electricity category (H1–H8, C1–C7). Default: H4. | |
| year | No | Tariff year (2011–2026). Default: 2026. |
Implementation Reference
- src/modules/energy.ts:255-363 (handler)Implementation of the compare_electricity_tariffs tool handler in src/modules/energy.ts.
case "compare_electricity_tariffs": { const municipalities = args.municipalities as string[]; const category = (args.category as string | undefined) ?? "H4"; const year = (args.year as string | undefined) ?? CURRENT_YEAR; if (!Array.isArray(municipalities) || municipalities.length < 2) { throw new Error("At least 2 municipality IDs are required for comparison."); } if (municipalities.length > 20) { throw new Error("Maximum 20 municipalities can be compared at once."); } const query = ` query Observations($locale: String!, $priceComponent: PriceComponent!, $filters: ObservationFilters!) { observations(locale: $locale, filters: $filters) { period municipality municipalityLabel operator operatorLabel canton cantonLabel category value(priceComponent: $priceComponent) coverageRatio } } `; const data = await gql<{ observations: Observation[] }>(query, { locale: "de", priceComponent: "total", filters: { period: [year], municipality: municipalities, category: [category], }, }); const observations = data.observations ?? []; if (!observations.length) { return JSON.stringify({ error: "No tariff data found for the given municipalities", municipalities, category, year, hint: "Use search_municipality_energy to verify BFS numbers.", source: "https://www.strompreis.elcom.admin.ch", }, null, 2); } // Deduplicate by municipality (keep first/cheapest operator if multiple) const byMunicipality = new Map<string, Observation>(); for (const obs of observations) { const existing = byMunicipality.get(obs.municipality); if (!existing || (obs.value !== null && (existing.value === null || obs.value < existing.value))) { byMunicipality.set(obs.municipality, obs); } } // Sort by total price ascending const sorted = [...byMunicipality.values()].sort((a, b) => { if (a.value === null) return 1; if (b.value === null) return -1; return a.value - b.value; }); const results = sorted.map((obs, idx) => ({ rank: idx + 1, municipality: obs.municipalityLabel, municipalityId: obs.municipality, canton: obs.cantonLabel, operator: obs.operatorLabel, total_rp_per_kwh: obs.value, year, category, })); // Find municipalities not found in results const foundIds = new Set(observations.map((o) => o.municipality)); const notFound = municipalities.filter((m) => !foundIds.has(m)); const cheapest = results[0]; const mostExpensive = results[results.length - 1]; const spread = cheapest && mostExpensive && cheapest.total_rp_per_kwh !== null && mostExpensive.total_rp_per_kwh !== null ? +(mostExpensive.total_rp_per_kwh - cheapest.total_rp_per_kwh).toFixed(3) : null; return JSON.stringify( { comparison: results, summary: { cheapest: cheapest.municipality, most_expensive: mostExpensive.municipality, spread_rp_per_kwh: spread, category, categoryDescription: CATEGORY_DESCRIPTIONS[category] ?? category, year, note: "Prices in Rappen per kWh. Multiple operators per municipality: cheapest shown.", }, notFound: notFound.length ? notFound : undefined, source: "https://www.strompreis.elcom.admin.ch", }, null, 2 ); }