### Initialize Mock Home Assistant and Theme
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/demo/index.html
Sets up a mock Home Assistant environment and initializes the theme for the demo. This code is essential for running the interactive examples.
```typescript
import { MockHass } from "../test/mocks/index.ts";
let theme = "dark";
const mockHass = new MockHass({
darkMode: theme === "dark",
currentCondition: "partlycloudy",
});
let hass = mockHass.getHass();
const demoMode = "toggle_and_scroll"; // 'condition_effects' | 'toggle_and_scroll' | 'none'
const updateTheme = () => {
const card = document.querySelector(".demo-card");
if (theme === "light") {
card.classList.add("light-theme");
document.body.classList.add("light-theme");
} else {
card.classList.remove("light-theme");
document.body.classList.remove("light-theme");
}
mockHass.setDarkMode(theme === "dark");
hass = mockHass.getHass();
card.hass = hass;
};
updateTheme();
document.getElementById("theme-toggle").addEventListener("click", () => {
theme = theme === "dark" ? "light" : "dark";
updateTheme();
});
```
--------------------------------
### Example Configuration with Current Attributes and Chart Mode
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/README.md
This configuration displays specific current weather attributes (humidity, pressure, wind speed) and enables chart mode with an extra attribute for wind direction.
```yaml
type: custom:weather-forecast-card
entity: weather.home
current:
show_attributes:
- humidity
- pressure
- wind_speed
forecast:
mode: chart
extra_attribute: wind_direction
```
--------------------------------
### Weather Forecast Card Full Configuration
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
This example shows a comprehensive configuration for the weather-forecast-card, including options for current conditions, forecast display modes, and custom actions. It demonstrates how to override default sensors and display additional attributes.
```yaml
type: custom:weather-forecast-card
entity: weather.home
name: "My Weather"
show_current: true
show_forecast: true
default_forecast: hourly # "hourly" | "daily"
icons_path: /local/img/weather # custom SVG icons directory
show_condition_effects: # true | false | array of effects
- rain
- snow
- lightning
- sky
- sun
- moon
current:
temperature_entity: sensor.outdoor_temperature # override temp sensor
temperature_precision: 1 # 0–2 decimal places
secondary_info_attribute: humidity # shown below temp
show_attributes: # true | false | string | array
- humidity
- pressure
- name: wind_speed # use custom entity
entity: sensor.my_wind_sensor
- uv_index
forecast:
mode: chart # "simple" | "chart"
default_chart_attribute: humidity # which attribute charts by default
extra_attribute: wind_direction # shown below each forecast slot
show_sun_times: true
use_color_thresholds: true
scroll_to_selected: true
show_attribute_selector: true
hourly_group_size: 3 # aggregate 3 hours into one slot
hourly_slots: 24 # cap hourly entries
daily_slots: 7 # cap daily entries
temperature_precision: 0
forecast_action:
tap_action:
action: toggle-forecast # custom action to switch hourly/daily
hold_action:
action: select-forecast-attribute # open chart attribute selector
double_tap_action:
action: none
tap_action:
action: more-info
hold_action:
action: navigate
navigation_path: /lovelace/weather
```
--------------------------------
### Theme Example: Adjust Font Sizes Globally
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/README.md
Customize font sizes globally by defining Home Assistant theme variables. This affects all cards using these variables.
```yaml
my-custom-theme:
# Adjust font sizes globally for all cards
ha-font-size-3xl: 32px
ha-font-size-l: 18px
```
--------------------------------
### Card-mod Example: Granular Control Over Font Sizes
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/README.md
Apply specific font size and width adjustments to different sections of the weather forecast card using card-mod. This example targets current weather and forecast sections independently.
```yaml
type: custom:weather-forecast-card
entity: weather.home
card_mod:
style: |
ha-card {
/* Make simple forecast items wider to avoid text overflow */
--forecast-item-width: 70px;
}
/* Affects only font sizes in the current weather section */
.wfc-current-weather {
/* Larger current conditions and temperature */
--ha-font-size-3xl: 38px;
--ha-font-size-xl: 30px;
}
/* Affects only forecast section */
.wfc-forecast {
/* Forecast header and temperatures font (simple mode) */
--ha-font-size-m: 20px;
}
```
--------------------------------
### Minimal Weather Forecast Card Configuration
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
This is the most basic configuration for the weather-forecast-card, requiring only the card type and a weather entity. It's useful for a quick setup with default settings.
```yaml
type: custom:weather-forecast-card
entity: weather.home
```
--------------------------------
### Card-mod Example: Configure Font Sizes for All Elements
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/README.md
Use card-mod to apply custom font sizes and element widths to all elements within a specific weather forecast card. This allows for granular control over the card's appearance.
```yaml
type: custom:weather-forecast-card
entity: weather.home
card_mod:
style: |
ha-card {
/* Larger current conditions and temperature */
--ha-font-size-3xl: 38px;
--ha-font-size-xl: 30px;
/* Larger forecast temperatures (simple mode) */
--ha-font-size-m: 16px;
/* Make simple forecast items wider to avoid text overflow */
--forecast-item-width: 75px;
}
```
--------------------------------
### Test Card Initialization with Default Configuration
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Tests initializing the weather forecast card with a basic entity configuration.
```javascript
initializeCard("test-card-1", { entity: "weather.demo" }, hass);
```
--------------------------------
### Test Card Initialization for Twice Daily Simple Mode
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Tests initializing the weather forecast card in 'simple' forecast mode, simulating a device that only supports twice-daily forecasts.
```javascript
initializeCard("test-card-twice-daily-simple", {
entity: "weather.demo",
forecast: {
mode: "simple",
},
}, new MockHass({ supportedFeatures: 6 }).getHass());
```
--------------------------------
### Test Card Initialization with Color Thresholds in Chart Mode
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Tests initializing the weather forecast card in 'chart' mode with 'use_color_thresholds' enabled.
```javascript
initializeCard("test-card-color-thresholds", {
entity: "weather.demo",
forecast: {
mode: "chart",
use_color_thresholds: true,
},
}, hass);
```
--------------------------------
### Test Card Initialization for Twice Daily Chart Mode
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Tests initializing the weather forecast card in 'chart' mode with 'wind_direction', simulating a device that only supports twice-daily forecasts.
```javascript
initializeCard("test-card-twice-daily-chart", {
entity: "weather.demo",
forecast: {
mode: "chart",
extra_attribute: "wind_direction",
},
}, new MockHass({ supportedFeatures: 6 }).getHass());
```
--------------------------------
### Initialize Weather Forecast Card
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Initializes the weather forecast card with a given ID, configuration, and Home Assistant object. Logs an error if the card element is not found.
```javascript
const initializeCard = (cardId, config, hass) => {
const card = document.getElementById(cardId);
if (card) {
card.setConfig(config);
card.hass = hass;
} else {
console.error(`Card element with id ${cardId} not found`);
const errorMessage = document.getElementById("error-message");
if (errorMessage) {
errorMessage.textContent += `Card element with id ${cardId} not found\n`;
}
}
};
```
--------------------------------
### Test Card Initialization with Hourly Chart Mode
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Tests initializing the weather forecast card in 'hourly' default forecast and 'chart' mode, displaying 'wind_direction'.
```javascript
initializeCard("test-card-5", {
entity: "weather.demo",
default_forecast: "hourly",
forecast: {
mode: "chart",
extra_attribute: "wind_direction",
},
}, hass);
```
--------------------------------
### Test Card Initialization with Color Thresholds in Fahrenheit
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Tests initializing the weather forecast card in 'chart' mode with 'use_color_thresholds' enabled, using Fahrenheit units.
```javascript
initializeCard("test-card-color-thresholds-fahrenheit", {
entity: "weather.demo",
forecast: {
mode: "chart",
use_color_thresholds: true,
},
}, hassFahrenheit.getHass());
```
--------------------------------
### Test Card Initialization with Cardinal Wind Bearing Data
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Tests initializing the weather forecast card with mock data for cardinal wind bearings in both hourly and daily forecasts.
```javascript
initializeCard("test-card-cardinal-wind", {
entity: "weather.demo",
forecast: {
mode: "chart",
extra_attribute: "wind_direction",
},
}, hassCardinalWind.getHass());
```
--------------------------------
### Test Card Initialization Showing Current Attributes
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Tests initializing the weather forecast card with options to show attributes for the current weather conditions.
```javascript
initializeCard("test-card-9", {
entity: "weather.demo",
current: {
show_attributes: true,
},
}, hass);
```
--------------------------------
### Test Card Initialization with 12-Hour Clock
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Tests initializing the weather forecast card with a mock Home Assistant object configured for a 12-hour clock display.
```javascript
initializeCard("test-card-12-hour-clock", {
entity: "weather.demo",
}, hass12HourClock.getHass());
```
--------------------------------
### Test Card Initialization for Bug Fix 14 (Second Case)
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Tests initializing the weather forecast card with alternative mock daily forecast data related to issue #14.
```javascript
initializeCard("test-card-bug-14-2", {
entity: "weather.demo",
forecast: {
mode: "chart",
extra_attribute: "wind_direction",
},
}, hassIssue14_2.getHass());
```
--------------------------------
### Add Resource to Lovelace Configuration
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/README.md
Add this resource to your Lovelace configuration to use the custom card. Ensure Home Assistant is restarted after adding.
```yaml
resources:
- url: /local/weather-forecast-card.js
type: module
```
--------------------------------
### Test Card Initialization with Hourly Chart Mode and Group Size
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Tests initializing the weather forecast card in 'hourly' default forecast and 'chart' mode with a specified 'hourly_group_size' of 3.
```javascript
initializeCard("test-card-6", {
entity: "weather.demo",
default_forecast: "hourly",
forecast: {
mode: "chart",
extra_attribute: "wind_direction",
hourly_group_size: 3,
},
}, hass);
```
--------------------------------
### Generate Default Card Configuration
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
The static `getStubConfig` method is used by Home Assistant's card picker to provide a default configuration when adding the card. It automatically detects the best weather entity.
```typescript
// Called internally by HA card picker — result pre-fills the editor
const stub = WeatherForecastCard.getStubConfig(hass);
// Returns:
// {
// type: "custom:weather-forecast-card",
// entity: "weather.home", // or first weather.* entity found
// show_current: true,
// show_forecast: true,
// default_forecast: "daily",
// forecast: { mode: "simple", show_sun_times: true, ... }
// }
```
--------------------------------
### Test Card Initialization with 12-Hour Clock and Chart Mode
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Tests initializing the weather forecast card in 'chart' mode with 'wind_direction' as an extra attribute, using a 12-hour clock.
```javascript
initializeCard("test-card-12-hour-clock-chart-mode", {
entity: "weather.demo",
forecast: {
mode: "chart",
extra_attribute: "wind_direction",
},
}, hass12HourClock.getHass());
```
--------------------------------
### WeatherForecastCardEditor getConfigElement Method
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
This static method is automatically invoked by Home Assistant's UI when editing the card. It returns an instance of the card's editor element, enabling visual configuration.
```typescript
// Accessed automatically by HA when user clicks "Edit" on the card
public static async getConfigElement() {
return document.createElement("weather-forecast-card-editor");
}
// The editor handles:
// - Entity selector (domain: "weather")
// - Forecast mode toggle (show_both / show_current / show_forecast)
// - Attribute multi-select with per-attribute custom sensor entity pickers
// - Action configuration for tap/hold/double-tap on card and forecast area
// - Automatic migration of legacy temperature_entity on save
// - Normalization of show_condition_effects: true when all effects are selected
// Config change event fired on any editor change:
// CustomEvent("config-changed", { detail: { config: WeatherForecastCardConfig } })
```
--------------------------------
### setConfig(config: WeatherForecastCardConfig)
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
Validates and initializes the card's configuration. It checks for required fields, validates constraints, migrates deprecated configuration options like `temperature_entity`, and merges user-provided settings with default values.
```APIDOC
## `setConfig(config: WeatherForecastCardConfig)` — Configuration Validation & Initialization
Called by Home Assistant when the card is first rendered or the config changes. Validates required fields, validates constraints, migrates the deprecated root-level `temperature_entity`, and deep-merges with defaults.
```typescript
// Errors thrown by setConfig — catch these when writing config programmatically
try {
card.setConfig({
type: "custom:weather-forecast-card",
entity: "weather.home",
forecast: {
daily_slots: 0, // ❌ throws: "daily_slots must be greater than 0"
},
});
} catch (e) {
console.error(e.message);
}
// Automatic migration of deprecated temperature_entity
card.setConfig({
type: "custom:weather-forecast-card",
entity: "weather.home",
temperature_entity: "sensor.my_temp", // deprecated root-level field
// ↑ automatically migrated to current.temperature_entity
});
// After setConfig, access the merged+validated config:
console.log(card.config);
// {
// type: "custom:weather-forecast-card",
// entity: "weather.home",
// show_current: true,
// show_forecast: true,
// default_forecast: "daily",
// current: { temperature_entity: "sensor.my_temp" },
// forecast: { mode: "simple", show_sun_times: true, use_color_thresholds: true, scroll_to_selected: true },
// forecast_action: { tap_action: { action: "toggle-forecast" }, hold_action: { action: "select-forecast-attribute" } },
// tap_action: { action: "more-info" }
// }
```
```
--------------------------------
### Test Card Initialization with Secondary Info Attribute
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Tests initializing the weather forecast card to display a 'secondary_info_attribute', specifically 'humidity'.
```javascript
initializeCard("test-card-secondary-info-attribute", {
entity: "weather.demo",
current: {
secondary_info_attribute: "humidity",
},
}, hass);
```
--------------------------------
### Toggle and Scroll Demo Sequence
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/demo/index.html
Orchestrates a demo sequence for the 'toggle_and_scroll' mode, simulating user interactions like tapping and scrolling to demonstrate card functionality. This includes helper functions for visual indicators.
```javascript
const toggleAndScrollDemo = () => {
const scrollContainer = card.shadowRoot?.querySelector(
".wfc-scroll-container"
);
if (scrollContainer) {
console.log("Starting demo sequence");
const tapIndicator = document.getElementById("tap-indicator");
const scrollIndicator = document.getElementById("scroll-indicator");
// Function to show tap indicator at element center
const showTapIndicator = (element) => {
const rect = element.getBoundingClientRect();
const x = rect.left + rect.width / 2;
const y = rect.top + rect.height / 2;
tapIndicator.style.left = `${x}px`;
tapIndicator.style.top = `${y}px`;
tapIndicator.classList.remove("active", "hold");
// Trigger reflow to restart animation
void tapIndicator.offsetWidth;
tapIndicator.classList.add("active");
};
// Function to show hold indicator at element center
const showHoldIndicator = (element) => {
const rect = element.getBoundingClientRect();
const x = rect.left + rect.width / 2;
const y = rect.top + rect.height / 2;
tapIndicator.style.left = `${x}px`;
tapIndicator.style.top = `${y}px`;
tapIndicator.classList.remove("active", "hold");
// Trigger reflow to restart animation
void tapIndicator.offsetWidth;
tapIndicator.classList.add("hold");
};
// Function to show scroll indicator
const showScrollIndicator = (element, reverse = false) => {
const rect = element.getBoundingClientRect();
const indicatorWidth = 50; // Width of the indicator
const edgeOffset = 30; // Distance from edge
// Position symmetrically from edges
const x = reverse ? rect.left + edgeOffset : rect.right - edgeOffset - indicatorWidth;
const y = rect.top + rect.height / 3;
scrollIndicator.style.left = `${x}px`;
scrollIndicator.style.top = `${y}px`;
scrollIndicator.classList.remove("active", "reverse");
if (reverse) {
scrollIndicator.classList.add("reverse");
}
// Trigger reflow to restart animation
void scrollIndicator.offsetWidth;
scrollIndicator.classList.add("active");
};
const getChartComponent = () => {
return card.shadowRoot?.querySelector("wfc-forecast-chart");
};
const getAttributeSelector = () => {
const chart = getChartComponent();
return chart?.querySelector("wfc-chart-attribute-selector");
};
const selectAttribute = (attributeValue) => {
const selector = getAttributeSelector();
if (!selector) return false;
const dropdown = selector.shadowRoot?.querySelector(".dropdown");
if (!dropdown) return false;
const items = dropdown.querySelectorAll(".menu-item");
for (const item of items) {
const itemContent = item.querySelector(".item-content span");
if (
attributeValue === "humidity" &&
itemContent?.textContent?.toLowerCase().includes("humidity")
) {
showTapIndicator(item);
item.click();
return true;
} else if (attributeValue === "temperature_and_precipitation") {
showTapIndicator(items[0]);
items[0].click();
return true;
}
}
return false;
};
const holdForecast = () => {
const forecastComponent = getChartComponent();
if (!forecastComponent) return;
const scrollContainer = forecastComponent.querySelector(
".wfc-scroll-container"
);
if (!scrollConta
```
--------------------------------
### Test Card Initialization with Wind Direction Forecast
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Tests initializing the weather forecast card to display 'wind_direction' as an extra attribute in the forecast.
```javascript
initializeCard("test-card-4", {
entity: "weather.demo",
temperature_entity: "sensor.temperature_outdoor",
forecast: {
extra_attribute: "wind_direction",
},
}, hass);
```
--------------------------------
### getWindBearing() / getWind()
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
Provides utilities for formatting wind data. `getWindBearing()` converts numeric degrees into a 16-point cardinal direction string, while `getWind()` generates a localized string combining wind speed and direction.
```APIDOC
## getWindBearing(degrees: number | string): string | undefined
### Description
Converts a numeric wind bearing in degrees to a 16-point cardinal direction string (e.g., 'N', 'NNE', 'NE', etc.). Handles non-numeric input by returning undefined.
### Parameters
#### Path Parameters
- **degrees** (number | string) - Required - The wind direction in degrees or a non-numeric string.
### Response
#### Success Response (200)
- **cardinalDirection** (string | undefined) - The 16-point cardinal direction string, or undefined if the input was non-numeric.
### Request Example
```typescript
import { getWindBearing } from "./data/weather";
getWindBearing(270); // → "W"
getWindBearing(22.5); // → "NNE"
getWindBearing(135); // → "SE"
getWindBearing("N/A"); // → undefined
```
## getWind(hass: Hass, weatherEntity: WeatherEntity): string | undefined
### Description
Builds a complete, localized wind string by combining wind speed and direction, using Home Assistant's localization. Returns undefined if the `wind_speed` attribute is missing.
### Parameters
#### Path Parameters
- **hass** (Hass) - Required - The Home Assistant core object.
- **weatherEntity** (WeatherEntity) - Required - The weather entity object.
### Response
#### Success Response (200)
- **windString** (string | undefined) - A localized string representing the wind, e.g., "15 km/h (West)", or undefined if wind speed is not available.
### Request Example
```typescript
import { getWind } from "./data/weather";
const windString = getWind(hass, weatherEntity);
// Example: "15 km/h (West)" or "9.3 mph (SW)"
```
```
--------------------------------
### Test Card Initialization Showing Condition Effects
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Tests initializing the weather forecast card with the 'show_condition_effects' option enabled.
```javascript
initializeCard("test-card-7", { entity: "weather.demo", show_condition_effects: true, }, hass);
```
```javascript
initializeCard("test-card-8", { entity: "weather.demo", show_condition_effects: true, }, hass);
```
--------------------------------
### Configure Custom Weather Icons
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/README.md
Specify the `icons_path` option to load custom SVG weather icons from a specified directory. Ensure icons are named according to Home Assistant weather conditions.
```yaml
type: custom:weather-forecast-card
entity: weather.home
icons_path: /local/img/weather-icons
```
--------------------------------
### getSuntimesInfo()
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
Computes sunrise, sunset, and current night/day status using the Home Assistant instance's configured geographic coordinates and the `suncalc` library.
```APIDOC
## `getSuntimesInfo()` — Sunrise / Sunset Calculation
Computes sunrise, sunset, and current night/day status using the Home Assistant instance's configured geographic coordinates and the `suncalc` library.
```typescript
import { getSuntimesInfo } from "./helpers";
const info = getSuntimesInfo(hass, new Date());
// Returns null if hass.config.latitude/longitude are not set.
// Otherwise:
// {
// sunrise: Date, // today's sunrise time
// sunset: Date, // today's sunset time
// isNightTime: boolean // true if current time is before sunrise or after sunset
// }
// Used for conditional icon variants and sky animation
if (info?.isNightTime) {
// show moon icon instead of sunny icon
// render moon + stars animation instead of sun animation
}
// Check for a past or future datetime
const tomorrowNoon = new Date();
tomorrowNoon.setDate(tomorrowNoon.getDate() + 1);
tomorrowNoon.setHours(12);
const tomorrowInfo = getSuntimesInfo(hass, tomorrowNoon);
```
```
--------------------------------
### Test Card Initialization for Bug Fix 14
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Tests initializing the weather forecast card with specific mock daily forecast data related to issue #14.
```javascript
initializeCard("test-card-bug-14", {
entity: "weather.demo",
forecast: {
mode: "chart",
extra_attribute: "wind_direction",
},
}, hassIssue14.getHass());
```
--------------------------------
### subscribeForecast()
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
Establishes a real-time subscription to Home Assistant's `weather/subscribe_forecast` WebSocket message for live forecast updates. This method returns a function to unsubscribe from the updates and is typically called internally by the card when its configuration or weather units change.
```APIDOC
## `subscribeForecast()` — Real-time Forecast WebSocket Subscription
Subscribes to Home Assistant's `weather/subscribe_forecast` WebSocket message for live forecast updates. Returns an unsubscribe function. Called internally by the card whenever config or weather units change.
```typescript
import { subscribeForecast } from "./data/weather";
// Subscribe to hourly forecast events
const unsubscribe = await subscribeForecast(
hass,
"weather.home",
"hourly", // "hourly" | "daily" | "twice_daily"
(event: ForecastEvent) => {
console.log(event.type); // "hourly"
console.log(event.forecast); // ForecastAttribute[] | null
// event.forecast[0] example:
// {
// datetime: "2024-06-15T14:00:00+00:00",
// temperature: 22.5,
// templow: 18.0,
// condition: "sunny",
// precipitation: 0,
// precipitation_probability: 5,
// humidity: 55,
// wind_speed: 12.5,
// wind_bearing: 270,
// uv_index: 6,
// apparent_temperature: 23.1,
// pressure: 1013
// }
}
);
// Later, clean up the subscription
unsubscribe();
```
```
--------------------------------
### Validate and Initialize Card Configuration
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
Use `setConfig` to validate required fields, constraints, and migrate deprecated configuration options. Errors during validation can be caught programmatically.
```typescript
try {
card.setConfig({
type: "custom:weather-forecast-card",
entity: "weather.home",
forecast: {
daily_slots: 0, // ❌ throws: "daily_slots must be greater than 0"
},
});
} catch (e) {
console.error(e.message);
}
```
```typescript
// Automatic migration of deprecated temperature_entity
card.setConfig({
type: "custom:weather-forecast-card",
entity: "weather.home",
temperature_entity: "sensor.my_temp", // deprecated root-level field
// ↑ automatically migrated to current.temperature_entity
});
```
```typescript
// After setConfig, access the merged+validated config:
console.log(card.config);
```
--------------------------------
### Test Card Initialization with Extra Forecast Attribute
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Tests initializing the weather forecast card with a custom 'extra_attribute' for forecast data, specifically 'precipitation_probability'.
```javascript
initializeCard("test-card-3", {
entity: "weather.demo",
icons_path: "./resources/img",
forecast: {
extra_attribute: "precipitation_probability",
},
}, hass);
```
--------------------------------
### Test Card Initialization Hiding Current Weather
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/test/app/index.html
Tests initializing the weather forecast card with the 'show_current' option set to false.
```javascript
initializeCard("test-card-2", { entity: "weather.demo", show_current: false, }, hass);
```
--------------------------------
### Enable All Weather Condition Effects
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/README.md
Activate all available animated visual effects that respond to current weather conditions by setting 'show_condition_effects' to true. Be mindful of potential performance impacts on low-powered devices.
```yaml
type: custom:weather-forecast-card
entity: weather.home
show_condition_effects: true
```
--------------------------------
### show_condition_effects
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
Enables CSS-driven particle animations that respond to the current weather entity state and wind data. Configure globally (`true`/`false`) or selectively as an array.
```APIDOC
## `show_condition_effects` — Animated Weather Effects
Enables CSS-driven particle animations that respond to the current weather entity state and wind data. Configure globally (`true`/`false`) or selectively as an array.
```yaml
# Enable all effects
type: custom:weather-forecast-card
entity: weather.home
show_condition_effects: true
# Enable specific effects only
show_condition_effects:
- rain # animated drops for: rainy, pouring, lightning-rainy
- snow # sinusoidal snowflakes for: snowy, snowy-rainy
- lightning # flash sequence for: lightning, lightning-rainy
- sky # gradient sky background for: sunny, clear-night
- sun # rotating sun rays for: sunny (daytime)
- moon # crescent moon + twinkling stars for: clear-night, sunny (nighttime with sun times)
```
```typescript
// Internal effect resolution (wfc-animation-provider.ts)
// Effects are computed from weatherEntity.state:
// "rainy" | "pouring" → rain
// "snowy" | "snowy-rainy" → snow
// "lightning" | "lightning-rainy" → lightning
// "sunny" | "clear-night" → sky + (sun or moon based on time)
// Rain & snow particle counts scale with current forecast precipitation:
// intensity = (forecast.precipitation / maxPrecipForUnit) * 10
// particleCount = Math.round((intensity / 10) * MAX_PARTICLES) // capped at 75
// Rain/snow falling angle is driven by wind data:
// angleDeg = sin(wind_bearing_radians) * speedFactor * MAX_TILT
// MAX_TILT = 15° (rain) or 35° (snow)
```
```
--------------------------------
### Simulate Weather Forecast Card Interactions
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/demo/index.html
This JavaScript code simulates user interactions with the weather forecast card. It includes functions to click on forecast elements and hold to open attribute dropdowns, automating a sequence of actions to demonstrate the card's dynamic behavior. Use this for automated testing or live demos.
```javascript
const showHoldIndicator = (element) => {
// Placeholder for showing a hold indicator
console.log('Showing hold indicator on:', element);
};
const showTapIndicator = (element) => {
// Placeholder for showing a tap indicator
console.log('Showing tap indicator on:', element);
};
const holdForecast = () => {
const scrollContainer = document.querySelector('ha-card'); // Assuming ha-card is the scroll container
if (!scrollContainer) return;
showHoldIndicator(scrollContainer);
// Dispatch hold action event
const holdEvent = new CustomEvent("action", {
bubbles: true,
composed: true,
detail: { action: "hold" },
});
scrollContainer.dispatchEvent(holdEvent);
};
const clickForecast = () => {
const forecastComponent = document.querySelector('ha-card')?.shadowRoot?.querySelector("wfc-forecast-chart");
if (forecastComponent) {
const header = forecastComponent.querySelector(".wfc-forecast-chart-header");
const slots = header?.querySelectorAll(".wfc-forecast-slot");
const canvas = forecastComponent.querySelector("#forecast-canvas");
if (slots && slots.length >= 5 && canvas) {
const slotToClick = slots[4];
showTapIndicator(slotToClick);
const slotIndex = parseInt(slotToClick.dataset.index, 10);
const slotRect = slotToClick.getBoundingClientRect();
const canvasRect = canvas.getBoundingClientRect();
const slotCenterX = slotRect.left + slotRect.width / 2;
const offsetX = slotCenterX - canvasRect.left;
const offsetY = canvasRect.height / 2;
const pointerEvent = new PointerEvent("pointerdown", {
bubbles: true,
cancelable: true,
view: window,
clientX: slotCenterX,
clientY: canvasRect.top + offsetY,
isPrimary: true,
});
// Override offsetX/offsetY since synthetic events don't calculate them
Object.defineProperty(pointerEvent, "offsetX", {
value: offsetX,
});
Object.defineProperty(pointerEvent, "offsetY", {
value: offsetY,
});
canvas.dispatchEvent(pointerEvent);
const eventInit = {
bubbles: true,
cancelable: true,
view: window,
clientX: slotCenterX,
clientY: canvasRect.top + offsetY,
};
slotToClick.dispatchEvent( new MouseEvent("mousedown", eventInit) );
slotToClick.dispatchEvent( new MouseEvent("mouseup", eventInit) );
slotToClick.dispatchEvent(new MouseEvent("click", eventInit));
}
}
};
let step = 0;
setInterval(() => {
switch (step) {
case 0:
// Click forecast
clickForecast();
step = 1;
break;
case 1:
// Hold to open attribute dropdown
holdForecast();
step = 2;
break;
case 2:
// Select humidity
selectAttribute("humidity");
step = 3;
break;
case 3:
// Hold again to open dropdown
holdForecast();
step = 4;
break;
case 4:
// Select temperature and precipitation
selectAttribute("temperature_and_precipitation");
step = 5;
break;
case 5:
// Click forecast to reset/close
clickForecast();
step = 0;
break;
}
}, 2500);
```
--------------------------------
### CSS Theme Variables for Customization
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
The card supports extensive visual customization through CSS custom properties, which can be set via Home Assistant themes or the `card-mod` integration.
```yaml
```
--------------------------------
### Home Assistant Theme Configuration for Weather Forecast Card
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
Define custom theme variables for temperature gradients, chart lines, UV index bars, and animation effects. These settings are applied globally via your Home Assistant `configuration.yaml` or `themes/` directory.
```yaml
my-weather-theme:
# Temperature gradient in chart mode
weather-forecast-card-temp-cold-color: "#2196f3"
weather-forecast-card-temp-freezing-color: "#4fb3ff"
weather-forecast-card-temp-chilly-color: "#ffeb3b"
weather-forecast-card-temp-mild-color: "#4caf50"
weather-forecast-card-temp-warm-color: "#ff9800"
weather-forecast-card-temp-hot-color: "#f44336"
# Chart lines
weather-forecast-card-chart-temp-high-line-color: "#ff5722"
weather-forecast-card-chart-temp-low-line-color: "#2196f3"
weather-forecast-card-chart-humidity-line-color: "#1976d2"
weather-forecast-card-chart-pressure-line-color: "#0097a7"
weather-forecast-card-chart-font-size: "13px"
# UV index risk level bars
weather-forecast-card-uv-low-color: "#289500" # 0–2
weather-forecast-card-uv-moderate-color: "#f7e400" # 3–5
weather-forecast-card-uv-high-color: "#f85900" # 6–7
weather-forecast-card-uv-very-high-color: "#d8001d" # 8–10
weather-forecast-card-uv-extreme-color: "#6b49c8" # 11+
# Animation effects
weather-forecast-card-effects-sun-color: "#facc15"
weather-forecast-card-effects-rain-color: "#2563eb"
weather-forecast-card-effects-snow-color: "#cbd5e1"
```
--------------------------------
### CSS Theme Variables
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
The card exposes CSS custom properties for all visual aspects, settable via Home Assistant themes or `card-mod`.
```APIDOC
## CSS Theme Variables — Appearance Customization
The card exposes CSS custom properties for all visual aspects, settable via Home Assistant themes or `card-mod`.
```yaml
```
--------------------------------
### Configure Weather Forecast Card
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/demo/index.html
Configures the weather forecast card with various options, including entity, name, and specific display settings for current conditions and forecasts. This is used to set up the card for different demo modes.
```javascript
customElements.whenDefined("weather-forecast-card").then(() => {
const card = document.querySelector(".demo-card");
card.setConfig({
type: "custom:weather-forecast-card",
entity: "weather.demo",
name: "Home",
show_condition_effects: false,
current: {
show_attributes: ["visibility", "apparent_temperature"],
},
forecast: {
mode: "chart",
extra_attribute: "wind_direction",
hourly_group_size: 2,
show_sun_times: demoMode !== "condition_effects",
use_color_thresholds: true,
},
});
card.hass = hass;
```
--------------------------------
### Subscribe to Real-time Forecast Updates
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
Use `subscribeForecast` to receive live weather forecast updates via WebSocket. This function returns an unsubscribe callback to clean up the subscription.
```typescript
import { subscribeForecast } from "./data/weather";
// Subscribe to hourly forecast events
const unsubscribe = await subscribeForecast(
hass,
"weather.home",
"hourly", // "hourly" | "daily" | "twice_daily"
(event: ForecastEvent) => {
console.log(event.type); // "hourly"
console.log(event.forecast); // ForecastAttribute[] | null
// event.forecast[0] example:
// {
// datetime: "2024-06-15T14:00:00+00:00",
// temperature: 22.5,
// templow: 18.0,
// condition: "sunny",
// precipitation: 0,
// precipitation_probability: 5,
// humidity: 55,
// wind_speed: 12.5,
// wind_bearing: 270,
// uv_index: 6,
// apparent_temperature: 23.1,
// pressure: 1013
// }
}
);
// Later, clean up the subscription
unsubscribe();
```
--------------------------------
### Enable Animated Weather Effects
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
Configure `show_condition_effects` in your card to enable CSS-driven particle animations that visually represent weather conditions like rain, snow, and lightning, as well as sky backgrounds.
```yaml
# Enable all effects
type: custom:weather-forecast-card
entity: weather.home
show_condition_effects: true
# Enable specific effects only
show_condition_effects:
- rain # animated drops for: rainy, pouring, lightning-rainy
- snow # sinusoidal snowflakes for: snowy, snowy-rainy
- lightning # flash sequence for: lightning, lightning-rainy
- sky # gradient sky background for: sunny, clear-night
- sun # rotating sun rays for: sunny (daytime)
- moon # crescent moon + twinkling stars for: clear-night, sunny (nighttime with sun times)
```
--------------------------------
### getStubConfig(hass)
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
A static method used by the Home Assistant UI to provide a default configuration when a user adds the card from the card picker. It attempts to automatically detect the most suitable weather entity, prioritizing `weather.home`.
```APIDOC
## `getStubConfig(hass)` — Default Config for Card Picker
Static method used by the Home Assistant UI when a user adds the card from the picker. Automatically finds the best weather entity, preferring `weather.home`.
```typescript
// Called internally by HA card picker — result pre-fills the editor
const stub = WeatherForecastCard.getStubConfig(hass);
// Returns:
// {
// type: "custom:weather-forecast-card",
// entity: "weather.home", // or first weather.* entity found
// show_current: true,
// show_forecast: true,
// default_forecast: "daily",
// forecast: { mode: "simple", show_sun_times: true, ... }
// }
```
```
--------------------------------
### Format Temperature with Locale and Unit
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
Use `formatTemperature` to display temperature values localized to the user's Home Assistant locale and the entity's configured unit. It supports optional precision overrides and can exclude the unit symbol.
```typescript
import { formatTemperature } from "./data/weather";
// Basic usage — uses entity's temperature_unit attribute
formatTemperature(hass, weatherEntity, 22.567);
// → "23°C" (locale-formatted, default precision)
// With explicit precision
formatTemperature(hass, weatherEntity, 22.567, 1);
// → "22.6°C"
// Exclude unit (for chart labels)
formatTemperature(hass, weatherEntity, 22.567, 0, true);
// → "23"
// String input from sensor state (auto-parsed)
formatTemperature(hass, weatherEntity, "21.3", 2);
// → "21.30°C"
```
--------------------------------
### formatPrecipitation()
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
Formats a precipitation amount for display, respecting the unit and suppressing near-zero values.
```APIDOC
## `formatPrecipitation()` — Precipitation Display
Formats a precipitation amount for display, respecting the unit and suppressing near-zero values.
```typescript
import { formatPrecipitation } from "./data/weather";
formatPrecipitation(1.5, "mm"); // → "1.5 mm"
formatPrecipitation(0.08, "in"); // → "0.08 in"
formatPrecipitation(0.03, "mm"); // → "" (below 0.05 mm threshold — not shown)
formatPrecipitation(0, "mm"); // → "" (zero — not shown)
```
```
--------------------------------
### Enable Specific Weather Condition Effects
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/README.md
Conditionally enable specific weather condition effects like rain, snow, or lightning by providing a list of desired effects to 'show_condition_effects'.
```yaml
type: custom:weather-forecast-card
entity: weather.home
show_condition_effects:
- rain
- snow
- lightning
```
--------------------------------
### Rotate Conditions Demo
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/demo/index.html
Implements a demo that cycles through different weather conditions to showcase visual effects. This function is intended to be called after the card is configured.
```javascript
const rotateConditionsDemo = () => {
const conditions = [
"sunny",
"snowy",
"rainy",
"lightning-rainy",
"clear-night",
];
let index = 0;
setInterval(() => {
mockHass.setCurrentConditions(conditions[index]);
card.hass = mockHass.getHass();
index = (index + 1) % conditions.length;
}, 5000);
};
```
--------------------------------
### formatTemperature()
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
Formats a raw numeric or string temperature value using the Home Assistant locale and the entity's configured temperature unit, with optional decimal precision override.
```APIDOC
## `formatTemperature()` — Localized Temperature Formatting
Formats a raw numeric or string temperature value using the Home Assistant locale and the entity's configured temperature unit, with optional decimal precision override.
```typescript
import { formatTemperature } from "./data/weather";
// Basic usage — uses entity's temperature_unit attribute
formatTemperature(hass, weatherEntity, 22.567);
// → "23°C" (locale-formatted, default precision)
// With explicit precision
formatTemperature(hass, weatherEntity, 22.567, 1);
// → "22.6°C"
// Exclude unit (for chart labels)
formatTemperature(hass, weatherEntity, 22.567, 0, true);
// → "23"
// String input from sensor state (auto-parsed)
formatTemperature(hass, weatherEntity, "21.3", 2);
// → "21.30°C"
```
```
--------------------------------
### Configure Display of Current Weather Attributes
Source: https://github.com/troinine/ha-weather-forecast-card/blob/main/README.md
Use a simple array of attribute names to display specific weather attributes below the current conditions. Ensure the attribute data is available from your weather entity.
```yaml
current:
show_attributes:
- humidity
- pressure
- wind_speed
```
--------------------------------
### formatHourParts() / formatTimeParts()
Source: https://context7.com/troinine/ha-weather-forecast-card/llms.txt
Splits a datetime into numeric and suffix parts (for AM/PM or localized time suffixes) using `Intl.DateTimeFormat`, with a fallback for environments where it's unavailable.
```APIDOC
## `formatHourParts()` / `formatTimeParts()` — Locale-aware Time Formatting
Splits a datetime into numeric and suffix parts (for AM/PM or localized time suffixes) using `Intl.DateTimeFormat`, with a fallback for environments where it's unavailable.
```typescript
import { formatHourParts, formatTimeParts } from "./helpers";
// 12-hour locale (en-US)
formatHourParts(hass, "2024-06-15T14:30:00Z");
// → { hour: "2", suffix: "PM" }
// 24-hour locale (de-DE)
formatHourParts(hass, "2024-06-15T14:30:00Z");
// → { hour: "14" }
// Full time with minutes
formatTimeParts(hass, "2024-06-15T07:05:00Z");
// 12-hour: → { time: "7:05", suffix: "AM" }
// 24-hour: → { time: "07:05" }
// Used in forecast slot headers to render stacked hour + AM/PM suffix
const { hour, suffix } = formatHourParts(hass, forecast.datetime);
// Renders: 7AM
```
```