Skip to content

loryanstrant/ha-jokes

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

44 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Home Assistant Jokes Integration

hacs_badge GitHub release

A custom Home Assistant integration that fetches random jokes from multiple sources and provides them as a sensor entity.

icon

Features

  • 🎭 Fetches random jokes from multiple joke APIs
  • πŸ”€ Random provider selection for variety
  • πŸ›‘οΈ Fault tolerance - automatically tries alternative providers if one fails
  • πŸ“Š Creates a sensor entity with state "OK" when successful
  • 🏷️ Stores joke text, ID, and source as attributes (no 255 character state limitation)
  • ⏰ Configurable refresh interval (1-1440 minutes, default: 5 minutes)
  • πŸ€– AI-powered joke explanations using Home Assistant's AI integration
  • βš™οΈ Easy configuration through Home Assistant UI
  • πŸ”„ Supports options flow for changing settings
  • πŸ›‘οΈ Robust error handling and logging
  • πŸ“± HACS compliant for easy installation

Installation

HACS (Recommended)

  1. Open HACS in your Home Assistant instance
  2. Find "Jokes" in the integration list and install it
  3. Restart Home Assistant
  4. Go to Configuration > Integrations
  5. Click "+ Add Integration" and search for "Jokes"

Or open it directly from here:

Open your Home Assistant instance and open a repository inside the Home Assistant Community Store.

Manual Installation

  1. Download the latest release from the releases page
  2. Extract the contents
  3. Copy the custom_components/ha_jokes folder to your Home Assistant custom_components directory
  4. Restart Home Assistant
  5. Go to Configuration > Integrations
  6. Click "+ Add Integration" and search for "Jokes"

Configuration

Initial Setup

  1. Go to Settings β†’ Devices & Services
  2. Click "+ Add Integration"
  3. Search for "Jokes"
  4. Set your desired refresh interval (1-1440 minutes, default: 5)
  5. Click "Submit"

Changing Options

  1. Go to Settings β†’ Devices & Services
  2. Find the Jokes integration
  3. Click "Configure"
  4. Adjust the refresh interval as needed
  5. Select/de-select joke providers
  6. Click "Submit"
image

Usage

After installation, the integration creates a sensor entity:

  • Entity ID: sensor.joke
  • State: "OK" when successful, "Error" when failed
  • Icon: πŸ™‚ (mdi:emoticon-happy-outline)

Attributes

The sensor provides the following attributes:

  • joke: The complete joke text
  • joke_id: Unique identifier for the joke
  • source: The joke provider that supplied the joke
  • last_updated: Timestamp of the last successful update
  • refresh_interval: Current refresh interval in minutes

Example Usage in Lovelace

Simple Entity Card

type: entity
entity: sensor.joke
attribute: joke
name: "Joke of the Moment"

Markdown Card with last updated time

type: markdown
content: |
  ## πŸ˜„ Joke
  {{ state_attr('sensor.joke', 'joke') }}
  
  *Last updated @ {{ as_datetime(state_attr('sensor.joke', 'last_updated')).strftime('%H:%M %d %b %Y') }}*
  *Source: {{ state_attr('sensor.joke', 'source') }}*
image

Markdown Card with time since last update

type: markdown
content: |
  ## πŸ˜„ Joke
  {{ state_attr('sensor.joke', 'joke') }}
  
  *Last updated: {{ relative_time(as_datetime(state_attr('sensor.joke', 'last_updated'))) }} ago*
  *Source: {{ state_attr('sensor.joke', 'source') }}*
image

Custom Card with Conditional Display

type: conditional
conditions:
  - entity: sensor.joke
    state: "OK"
card:
  type: markdown
  content: |
    ## 🎭 Today's Joke
    {{ state_attr('sensor.joke', 'joke') }}
    
    **Joke ID**: {{ state_attr('sensor.joke', 'joke_id') }}
    **Source**: {{ state_attr('sensor.joke', 'source') }}
    **Updated**: {{ state_attr('sensor.joke', 'last_updated') }}

Button Card Example (requires button-card from HACS)

type: custom:button-card
entity: sensor.joke
name: Daily Joke
show_state: false
styles:
  card:
    - background-color: var(--primary-background-color)
    - padding: 20px
    - border-radius: 15px
  name:
    - font-size: 20px
    - font-weight: bold
    - color: var(--primary-text-color)
custom_fields:
  joke: |
    [[[
      return `<div style="font-size: 16px; line-height: 1.5; margin-top: 10px;">
        ${states['sensor.joke'].attributes.joke}
      </div>`
    ]]]
  source: |
    [[[
      return `<div style="font-size: 12px; color: var(--secondary-text-color); margin-top: 10px;">
        Source: ${states['sensor.joke'].attributes.source}
      </div>`
    ]]]

Entities Card

type: entities
title: Joke
entities:
  - entity: sensor.joke
    type: attribute
    attribute: joke
    name: Current Joke
  - entity: sensor.joke
    type: attribute
    attribute: source
    name: Source
    icon: mdi:information-outline
  - entity: sensor.joke
    type: attribute
    attribute: last_updated
    name: Last Updated
    icon: mdi:clock-outline

Automations

You can use the sensor in automations:

automation:
  - alias: "Announce Joke"
    trigger:
      - platform: state
        entity_id: sensor.joke
        attribute: joke
    action:
      - service: notify.mobile_app_your_phone
        data:
          title: "New Joke!"
          message: "{{ state_attr('sensor.joke', 'joke') }}"

AI-Powered Joke Explanations

The integration provides an ha_jokes.explain_joke service that uses Home Assistant's AI integration to explain the current joke in plain language. This is perfect for jokes that might have wordplay, cultural references, or puns that need clarification.

image

Requirements

  • Home Assistant AI integration must be configured (e.g., OpenAI, Google Generative AI, or Azure AI)
  • A default AI conversation agent must be set up

Usage

From the Developer Tools:

  1. Go to Developer Tools β†’ Actions
  2. Select the ha_jokes.explain_joke action
  3. Click "Perform Action"

In Automations:

automation:
  - alias: "Explain Joke on Request"
    trigger:
      - platform: state
        entity_id: input_boolean.explain_joke_trigger
        to: "on"
    action:
      - service: ha_jokes.explain_joke
      - service: notify.mobile_app_your_phone
        data:
          title: "Joke Explanation"
          message: "{{ state_attr('sensor.joke_explanation', 'explanation') }}"

In Scripts:

script:
  get_joke_explanation:
    sequence:
      - service: ha_jokes.explain_joke
      - delay:
          seconds: 5
      - service: notify.persistent_notification
        data:
          title: "Joke Explanation"
          message: "{{ state_attr('sensor.joke_explanation', 'explanation') }}"

Explanation Sensor

After calling the explain_joke service, the explanation is stored in the sensor.joke_explanation entity:

  • Entity ID: sensor.joke_explanation
  • State: "Explained" when an explanation is available, "Not Explained" otherwise
  • Attribute: explanation contains the AI-generated explanation

Example Lovelace Card:

type: vertical-stack
cards:
  - type: markdown
    content: |
      ## πŸ˜„ Joke
      {{ state_attr('sensor.joke', 'joke') }}
  - type: button
    name: Explain This Joke
    icon: mdi:comment-question-outline
    tap_action:
      action: call-service
      service: ha_jokes.explain_joke
  - type: conditional
    conditions:
      - entity: sensor.joke_explanation
        state: "Explained"
    card:
      type: markdown
      content: |
        ### πŸ’‘ Explanation
        {{ state_attr('sensor.joke_explanation', 'explanation') }}

API Information

This integration fetches jokes from three different sources, automatically selecting them in random order and providing fault tolerance if one source is unavailable:

Joke Sources

  1. icanhazdadjoke.com - A curated collection of dad jokes

    • Provides free access to dad jokes
    • Returns jokes in JSON format with unique IDs
    • No API key required
  2. JokeAPI v2 - A RESTful API serving jokes

    • Configured in safe mode (no explicit content)
    • Returns single-line jokes only
    • Free and open source
    • No API key required
  3. Official Joke API - A simple joke API

    • Community-maintained joke collection
    • Returns setup/punchline format jokes
    • Free and open source
    • No API key required

The integration randomly selects which provider to use for each joke request. If a provider fails to respond, it automatically tries the next provider, ensuring you always get a joke as long as at least one service is available.

Troubleshooting

Common Issues

  1. Sensor shows "Error" state

    • Check your internet connection
    • Verify that at least one joke API is accessible
    • Check Home Assistant logs for detailed error messages
    • The integration will automatically try alternative providers
  2. Integration not appearing

    • Ensure you've restarted Home Assistant after installation
    • Check that the custom_components/ha_jokes folder is in the correct location
    • Verify all required files are present
  3. Jokes not updating

    • Check the refresh interval setting
    • Verify the sensor state is "OK"
    • Check logs for any error messages

Logs

To enable debug logging for this integration, add the following to your configuration.yaml:

logger:
  logs:
    custom_components.ha_jokes: debug

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Development Approach

Vibe Coding with GitHub Copilot 256x256

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

Credits

Contributors

Languages