Skip to content

Instantly share code, notes, and snippets.

@mbernson
Forked from Nizzle/shabadge.yaml
Last active January 28, 2026 10:14
Show Gist options
  • Select an option

  • Save mbernson/29514bf4a5e8067aa362c22f2dd5d0be to your computer and use it in GitHub Desktop.

Select an option

Save mbernson/29514bf4a5e8067aa362c22f2dd5d0be to your computer and use it in GitHub Desktop.
ESPhome config for SHA2017 badge (https://wiki.sha2017.org/w/Projects:Badge)
esphome:
name: sha2017-badge
friendly_name: SHA2017 Badge
esp32:
board: esp32-pro
framework:
type: esp-idf
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: !secret api_key
# Enable over the air updates
ota:
- platform: esphome
password: !secret ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Sha2017-Badge Fallback Hotspot"
password: !secret wifi_fallback_password
captive_portal:
i2c:
sda: 26
scl: 27
scan: True
mpr121:
id: mpr121_component
address: 0x5A
touch_debounce: 1
release_debounce: 1
touch_threshold: 12
release_threshold: 6
binary_sensor:
- platform: mpr121
id: touch_buttonA
channel: 0
name: "Touch Button A"
- platform: mpr121
id: touch_buttonB
channel: 1
name: "Touch Button B"
- platform: mpr121
id: touch_buttonStart
channel: 2
name: "Touch Button Start"
- platform: mpr121
id: touch_buttonSelect
channel: 3
name: "Touch Button Select"
- platform: mpr121
id: touch_buttonDown
channel: 4
name: "Touch Button Down"
- platform: mpr121
id: touch_buttonRight
channel: 5
name: "Touch Button Right"
- platform: mpr121
id: touch_buttonUp
channel: 6
name: "Touch Button Up"
- platform: mpr121
id: touch_buttonLeft
channel: 7
name: "Touch Button Left"
# - platform: mpr121
# id: charging_status
# channel: 9
# name: "Charging Status"
- platform: gpio
name: "Flash Button"
pin: 0
filters:
- invert:
sensor:
- platform: adc
pin: 34
attenuation: 6db
filters:
- multiply: 2.91
name: "USB Voltage"
update_interval: 20s
accuracy_decimals: 1
- platform: adc
pin: 35
attenuation: 6db
#attenuation: 2.5db
filters:
- multiply: 2.91
#- multiply: 1.95
name: "Battery Voltage"
update_interval: 20s
accuracy_decimals: 1
# Weather forecast: max and min temperature for each day (0 = today, 6 = 6 days ahead)
- platform: homeassistant
id: weather_temperature_0
entity_id: weather.home
attribute: forecast.0.temperature
- platform: homeassistant
id: weather_temperature_1
entity_id: weather.home
attribute: forecast.1.temperature
- platform: homeassistant
id: weather_temperature_2
entity_id: weather.home
attribute: forecast.2.temperature
- platform: homeassistant
id: weather_temperature_3
entity_id: weather.home
attribute: forecast.3.temperature
- platform: homeassistant
id: weather_temperature_4
entity_id: weather.home
attribute: forecast.4.temperature
- platform: homeassistant
id: weather_temperature_5
entity_id: weather.home
attribute: forecast.5.temperature
- platform: homeassistant
id: weather_temperature_6
entity_id: weather.home
attribute: forecast.6.temperature
- platform: homeassistant
id: weather_temperature_min_0
entity_id: weather.home
attribute: forecast.0.templow
- platform: homeassistant
id: weather_temperature_min_1
entity_id: weather.home
attribute: forecast.1.templow
- platform: homeassistant
id: weather_temperature_min_2
entity_id: weather.home
attribute: forecast.2.templow
- platform: homeassistant
id: weather_temperature_min_3
entity_id: weather.home
attribute: forecast.3.templow
- platform: homeassistant
id: weather_temperature_min_4
entity_id: weather.home
attribute: forecast.4.templow
- platform: homeassistant
id: weather_temperature_min_5
entity_id: weather.home
attribute: forecast.5.templow
- platform: homeassistant
id: weather_temperature_min_6
entity_id: weather.home
attribute: forecast.6.templow
spi:
clk_pin: 18
mosi_pin: 5
text_sensor:
- platform: version
id: ver
hide_timestamp: true
# Weather condition for each day (0 = today, 6 = 6 days ahead)
- platform: homeassistant
id: weather_condition_0
entity_id: weather.home
attribute: forecast.0.condition
- platform: homeassistant
id: weather_condition_1
entity_id: weather.home
attribute: forecast.1.condition
- platform: homeassistant
id: weather_condition_2
entity_id: weather.home
attribute: forecast.2.condition
- platform: homeassistant
id: weather_condition_3
entity_id: weather.home
attribute: forecast.3.condition
- platform: homeassistant
id: weather_condition_4
entity_id: weather.home
attribute: forecast.4.condition
- platform: homeassistant
id: weather_condition_5
entity_id: weather.home
attribute: forecast.5.condition
- platform: homeassistant
id: weather_condition_6
entity_id: weather.home
attribute: forecast.6.condition
# - platform: template
# name: Uptime Human Readable
# id: uptime_human
# icon: mdi:clock-start
display:
- platform: waveshare_epaper
cs_pin: 19
dc_pin: 21
busy_pin: 22
reset_pin: 23
model: 2.90in-dke
full_update_every: 30
update_interval: 60s
lambda: |-
// --- Weather Forecast Display for 2.9" e-ink (296x128) ---
// Layout: 7 days, icons, min/max temps
// Assumes Home Assistant sensors for weather data are available as text_sensors and sensors
// You may need to adjust entity IDs to match your HA setup
// --- CONFIG ---
const int days = 7;
const int icon_size = 24;
const int col_width = 42; // 296/7 β‰ˆ 42px per day
const int top_margin = 8;
const int icon_y = top_margin;
const int temp_y = icon_y + icon_size + 2;
const int minmax_y = temp_y + 18;
const int font_size = 18;
// --- ICON MAPPING ---
// Map Home Assistant weather states to Unicode icons (Weather Icons font or fallback)
auto get_icon = [](std::string condition) -> const char* {
if (condition == "sunny") return "β˜€";
if (condition == "clear-night") return "πŸŒ™";
if (condition == "cloudy") return "☁";
if (condition == "partlycloudy" || condition == "partly-cloudy") return "β›…";
if (condition == "rainy" || condition == "rain") return "🌧";
if (condition == "pouring") return "🌧";
if (condition == "snowy" || condition == "snow") return "❄";
if (condition == "windy") return "🌬";
if (condition == "fog" || condition == "foggy") return "🌫";
if (condition == "hail") return "🌨";
if (condition == "lightning") return "⚑";
if (condition == "lightning-rainy") return "β›ˆ";
return "?";
};
// --- DAY LABELS ---
const char* day_labels[7] = {"Zo", "Ma", "Di", "Wo", "Do", "Vr", "Za"};
// --- FETCH DATA FROM HA SENSORS ---
// You must define these sensors/text_sensors in your ESPHome config, e.g.:
// text_sensor.weather_condition_0 ... weather_condition_6
// sensor.weather_temperature_0 ... weather_temperature_6 (max)
// sensor.weather_temperature_min_0 ... weather_temperature_min_6 (min)
// Use static references for each day
std::string conditions[7];
float temp_max[7];
float temp_min[7];
conditions[0] = id(weather_condition_0).has_state() ? id(weather_condition_0).state : "cloudy";
conditions[1] = id(weather_condition_1).has_state() ? id(weather_condition_1).state : "cloudy";
conditions[2] = id(weather_condition_2).has_state() ? id(weather_condition_2).state : "cloudy";
conditions[3] = id(weather_condition_3).has_state() ? id(weather_condition_3).state : "cloudy";
conditions[4] = id(weather_condition_4).has_state() ? id(weather_condition_4).state : "cloudy";
conditions[5] = id(weather_condition_5).has_state() ? id(weather_condition_5).state : "cloudy";
conditions[6] = id(weather_condition_6).has_state() ? id(weather_condition_6).state : "cloudy";
temp_max[0] = id(weather_temperature_0).has_state() ? id(weather_temperature_0).state : 20;
temp_max[1] = id(weather_temperature_1).has_state() ? id(weather_temperature_1).state : 21;
temp_max[2] = id(weather_temperature_2).has_state() ? id(weather_temperature_2).state : 22;
temp_max[3] = id(weather_temperature_3).has_state() ? id(weather_temperature_3).state : 23;
temp_max[4] = id(weather_temperature_4).has_state() ? id(weather_temperature_4).state : 24;
temp_max[5] = id(weather_temperature_5).has_state() ? id(weather_temperature_5).state : 25;
temp_max[6] = id(weather_temperature_6).has_state() ? id(weather_temperature_6).state : 26;
temp_min[0] = id(weather_temperature_min_0).has_state() ? id(weather_temperature_min_0).state : 12;
temp_min[1] = id(weather_temperature_min_1).has_state() ? id(weather_temperature_min_1).state : 13;
temp_min[2] = id(weather_temperature_min_2).has_state() ? id(weather_temperature_min_2).state : 14;
temp_min[3] = id(weather_temperature_min_3).has_state() ? id(weather_temperature_min_3).state : 15;
temp_min[4] = id(weather_temperature_min_4).has_state() ? id(weather_temperature_min_4).state : 16;
temp_min[5] = id(weather_temperature_min_5).has_state() ? id(weather_temperature_min_5).state : 17;
temp_min[6] = id(weather_temperature_min_6).has_state() ? id(weather_temperature_min_6).state : 18;
// --- DRAW ---
for (int i = 0; i < days; i++) {
int x = i * col_width + 2;
// Day label
it.printf(x + col_width/2, 0, id(defaultfont), TextAlign::TOP_CENTER, "%s", day_labels[i]);
// Icon
it.printf(x + col_width/2, icon_y, id(defaultfont), TextAlign::TOP_CENTER, "%s", get_icon(conditions[i]));
// Max temp
it.printf(x + col_width/2, temp_y, id(defaultfont), TextAlign::TOP_CENTER, "%.0fΒ°", temp_max[i]);
// Min temp (smaller font or below max)
it.printf(x + col_width/2, minmax_y, id(defaultfont), TextAlign::TOP_CENTER, "%.0fΒ°", temp_min[i]);
}
// Optionally, add a title or current temp at the top
// it.printf(148, 120, id(defaultfont), TextAlign::BOTTOM_CENTER, "Weer");
rotation: 270
font:
- file: "gfonts://Roboto"
id: defaultfont
size: 24
output:
- id: led_and_ext_power
platform: gpio
pin:
mpr121: mpr121_component
number: 10
mode: OUTPUT
inverted: true
- id: buzzer_power
platform: gpio
pin:
mpr121: mpr121_component
number: 8
mode: OUTPUT
button:
- platform: output
name: "Buzzer"
output: buzzer_power
duration: 4000ms
icon: mdi:vibrate
light:
- platform: esp32_rmt_led_strip
is_rgbw: true
rgb_order: GRB
pin: 32
num_leds: 6
chipset: sk6812
name: "Badge LEDs"
bluetooth_proxy:
active: true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment