Skip to content

Instantly share code, notes, and snippets.

@hex128
Last active October 31, 2025 14:24
Show Gist options
  • Save hex128/0308e82f75620d7f123e57ccd7462c88 to your computer and use it in GitHub Desktop.
Save hex128/0308e82f75620d7f123e57ccd7462c88 to your computer and use it in GitHub Desktop.
type: custom:yasno-card
city: "Київ"
dso: "ПРАТ «ДТЕК КИЇВСЬКІ ЕЛЕКТРОМЕРЕЖІ»"
group: "1.1"
class YasnoCard extends HTMLElement {
constructor() {
super();
this.attachShadow({
mode: 'open'
});
this.city = "Київ"; // Default city
this.dso = "ПРАТ «ДТЕК КИЇВСЬКІ ЕЛЕКТРОМЕРЕЖІ»"; // Default DSO
this.group = "1.1"; // Default group
this.refreshInterval = null; // To store the interval ID
}
setConfig(config) {
if (!config.city || !config.group || !config.dso) {
throw new Error("You need to define 'city', 'dso', 'group' in the card configuration.");
}
this.city = config.city;
this.dso = config.dso;
this.group = config.group;
// Render the card whenever the config changes
this.render();
// Set up auto-refresh if not already running
if (!this.refreshInterval) {
this.refreshInterval = setInterval(() => this.render(), 300000); // Refresh every 5 minutes
}
}
render() {
const convertTime = t => `${String(t/60|0).padStart(2,'0')}:${String(t%60).padStart(2,'0')}`;;
let formattedPeriodsToday = ['<div><ha-icon icon="mdi:emoticon-happy-outline"></ha-icon> Відключень не заплановано!</div>'];
let periodsTomorrowHeading = "";
let formattedPeriodsTomorrow = [];
fetch('https://d2df36r8szehn1.cloudfront.net/')
.then((response) => response.json())
.then((data) => {
if (data[this.city][this.dso]?.today) {
const periodsToday = data[this.city][this.dso].today[this.group];
if (periodsToday.length > 0) {
formattedPeriodsToday = periodsToday.map(
(range) => `<div><ha-icon icon="mdi:transmission-tower-off"></ha-icon> ${convertTime(range[0])} - ${convertTime(range[1])}</div>`
);
}
}
if (data[this.city][this.dso]?.tomorrow) {
const periodsTomorrow = data[this.city][this.dso].tomorrow[this.group];
if (periodsTomorrow.length > 0) {
periodsTomorrowHeading = '<div><h3><ha-icon icon="mdi:calendar-arrow-right"></ha-icon> Завтра</h3></div>';
formattedPeriodsTomorrow = periodsTomorrow.map(
(range) => `<div><ha-icon icon="mdi:transmission-tower-off"></ha-icon> ${convertTime(range[0])} - ${convertTime(range[1])}</div>`
);
}
}
})
.catch((error) => {
console.error('Failed to fetch time periods:', error);
formattedPeriodsToday = ['<div><ha-icon icon="mdi:emoticon-sad-outline"></ha-icon> Не вдалося отримати графік відключень.</div>'];
})
.then(() => {
const content = `
<ha-card>
<h1 class="card-header">Графік відключень групи ${this.group}</h1>
<div class="card-content">
${formattedPeriodsToday.join("\n")}
${periodsTomorrowHeading}
${formattedPeriodsTomorrow}
</div>
</ha-card>
`;
this.shadowRoot.innerHTML = content;
});
}
disconnectedCallback() {
// Clean up interval when the card is removed from the DOM
if (this.refreshInterval) {
clearInterval(this.refreshInterval);
this.refreshInterval = null;
}
}
set hass(hass) {
// The `hass` object is not used here, but it could be used for future integration
}
getCardSize() {
return 3;
}
}
customElements.define('yasno-card', YasnoCard);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment