Compare commits
16 Commits
f4ab069600
...
enclosure
| Author | SHA1 | Date | |
|---|---|---|---|
| 49dbff41ae | |||
| 5a4d2300a8 | |||
| 342b243984 | |||
| b36ddcbbc8 | |||
| 1b04be0afe | |||
| cd900cabbd | |||
| dd9048605e | |||
| 7ada8759bd | |||
| 7295048c32 | |||
| 80378b1d95 | |||
| e07666a12b | |||
| a2fbb7ad6a | |||
| c1f0f429b1 | |||
| 7934f83ee2 | |||
| dd9acfe94e | |||
| 15cafb9222 |
@@ -5,3 +5,8 @@ secrets.yaml
|
|||||||
# Python bytecode from custom components
|
# Python bytecode from custom components
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
|
|
||||||
|
# We don't need KiCad backups
|
||||||
|
**/*-backups/*
|
||||||
|
~*
|
||||||
|
\#*\#
|
||||||
|
|||||||
@@ -35,16 +35,26 @@ output (LOW silences it). No impact on UART download mode or OTA flashing.
|
|||||||
- 2-bit grayscale fully working via custom component `waveshare_epaper_2bit`
|
- 2-bit grayscale fully working via custom component `waveshare_epaper_2bit`
|
||||||
- LVGL rendering working, 4-shade colorspace confirmed
|
- LVGL rendering working, 4-shade colorspace confirmed
|
||||||
- Bayer ordered dithering implemented for gradient smoothing
|
- Bayer ordered dithering implemented for gradient smoothing
|
||||||
- Touchscreen working: polling mode, mirror_x + mirror_y transforms confirmed correct
|
- Touchscreen working: polling mode, portrait-orientation transform confirmed correct
|
||||||
- LVGL touch input and button state working end-to-end
|
- LVGL touch input and button state working end-to-end
|
||||||
|
- Panel now mounted vertically (portrait); 4-row layout for light/fan controls
|
||||||
- **Active: LVGL layout work**
|
- **Active: LVGL layout work**
|
||||||
|
|
||||||
## Display Refresh Pattern
|
## Display Refresh Pattern
|
||||||
Two-tier refresh wired to `lvgl.on_draw_end` via two `mode: restart` scripts:
|
Two-tier refresh wired to `lvgl.on_draw_end` via two `mode: restart` scripts:
|
||||||
- **Partial** (`refresh_display`, 60ms): calls `display_partial()` — fast 1-bit, non-blocking, immediate interaction feedback
|
- **Partial** (`refresh_display`, 80ms then a 350ms retry): calls `display_partial()` — fast 1-bit, non-blocking, immediate interaction feedback
|
||||||
- **Full** (`full_refresh_display`, 10s): calls `component.update: display0` → `display()` — full 2-bit grayscale quality restore after idle
|
- **Full** (`full_refresh_display`, 10s): calls `component.update: display0` → `display()` — full 2-bit grayscale quality restore after idle
|
||||||
|
|
||||||
60ms was empirically tuned: 80ms felt sluggish, 40ms intermittently raced. `component.update: display0` only pushes the frame buffer to hardware and does not re-trigger `on_draw_end`.
|
The retry exists because `display_partial()` silently drops calls when the
|
||||||
|
e-paper is still busy from a previous refresh (`waveshare_epaper_2bit.cpp`
|
||||||
|
~line 2003). Without it, HA-triggered widget updates (e.g. fan speed sync
|
||||||
|
arriving 200-500ms after a tap) could land during the busy window of the
|
||||||
|
tap's partial refresh and be lost until the 10s full refresh. The retry
|
||||||
|
fires ~430ms after the last draw, by which point the e-paper's ~300ms
|
||||||
|
partial cycle has cleared. `mode: restart` cancels the retry if a new
|
||||||
|
draw arrives, so it only fires in the quiet period.
|
||||||
|
|
||||||
|
`component.update: display0` only pushes the frame buffer to hardware and does not re-trigger `on_draw_end`.
|
||||||
|
|
||||||
## Grayscale Implementation
|
## Grayscale Implementation
|
||||||
Custom component model name: `2.90inv2-r2-2bpp`
|
Custom component model name: `2.90inv2-r2-2bpp`
|
||||||
@@ -75,7 +85,11 @@ Amplitude chosen to keep 0xAAAAAA and 0x555555 as solid fills.
|
|||||||
- Touch count at register 0x1001, touch data at 0x1002 (7 bytes/point), clear by writing 0x00 to 0x1001
|
- Touch count at register 0x1001, touch data at 0x1002 (7 bytes/point), clear by writing 0x00 to 0x1001
|
||||||
- Waveshare's own driver inverts both axes: X = 295 - raw_x, Y = 127 - raw_y
|
- Waveshare's own driver inverts both axes: X = 295 - raw_x, Y = 127 - raw_y
|
||||||
- INT pulse is very brief (sub-ms); component works in polling mode regardless
|
- INT pulse is very brief (sub-ms); component works in polling mode regardless
|
||||||
- Coordinate transform: mirror_x + mirror_y confirmed correct; swap_xy not needed
|
- Coordinate transform (portrait, display rotation 0°): `swap_xy: true, mirror_x: true`,
|
||||||
|
calibration `x_max: 127, y_max: 295`. Gotcha: ESPHome's base class applies `swap_xy`
|
||||||
|
*before* calibration normalization (see `touchscreen.cpp::add_raw_touch_position_`),
|
||||||
|
so calibration `x_max`/`y_max` must describe the **post-swap** range — i.e., match
|
||||||
|
the display width/height, not the raw sensor's native axes.
|
||||||
|
|
||||||
## Relevant Files
|
## Relevant Files
|
||||||
- Custom component: `custom_components/waveshare_epaper_2bit/`
|
- Custom component: `custom_components/waveshare_epaper_2bit/`
|
||||||
@@ -85,4 +99,5 @@ Amplitude chosen to keep 0xAAAAAA and 0x555555 as solid fills.
|
|||||||
- `waveshare_epaper_2bit.h` — header
|
- `waveshare_epaper_2bit.h` — header
|
||||||
- Main config: `waveshare-test.yaml` (pin table here is source of truth)
|
- Main config: `waveshare-test.yaml` (pin table here is source of truth)
|
||||||
- Build cache: `.esphome/build/waveshare-epaper-test/src/esphome/components/`
|
- Build cache: `.esphome/build/waveshare-epaper-test/src/esphome/components/`
|
||||||
- ESPHome source (venv): ~/Code/esphome-2026.1.0/
|
- ESPHome venv (Windows): `C:\Projects\python_virtual\esphome-2026.1.0` (activate before `esphome` commands)
|
||||||
|
- ESPHome source (WSL venv): ~/Code/esphome-2026.1.0/
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ ESPHome project for the [Waveshare 2.9inch Touch e-Paper HAT](https://www.wavesh
|
|||||||
| Display MOSI | GPIO23 | Pin19/GPIO10/SPI0_MOSI |
|
| Display MOSI | GPIO23 | Pin19/GPIO10/SPI0_MOSI |
|
||||||
| Display CS | GPIO19 | Pin24/GPIO8/SPI0_CE0 |
|
| Display CS | GPIO19 | Pin24/GPIO8/SPI0_CE0 |
|
||||||
| Display DC | GPIO17 | Pin22/GPIO25 |
|
| Display DC | GPIO17 | Pin22/GPIO25 |
|
||||||
| Display BUSY | GPIO4 | Pin24/GPIO24 |
|
| Display BUSY | GPIO4 | Pin18/GPIO24 |
|
||||||
| Display RST | GPIO5 | Pin11/GPIO17/SPI1_CE1 |
|
| Display RST | GPIO5 | Pin11/GPIO17/SPI1_CE1 |
|
||||||
| Touch SDA | GPIO21 | Pin3/GPIO2/I2C1_SDA |
|
| Touch SDA | GPIO21 | Pin3/GPIO2/I2C1_SDA |
|
||||||
| Touch SCL | GPIO22 | Pin5/GPIO3/I2C1_SCL |
|
| Touch SCL | GPIO22 | Pin5/GPIO3/I2C1_SCL |
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
xdim = 23.497 + 1.5;
|
||||||
|
ydim = 18.155;
|
||||||
|
zdim = 13.5;
|
||||||
|
wt = 1;
|
||||||
|
a = 0.897;
|
||||||
|
b = 4.364;
|
||||||
|
c = 10.222;
|
||||||
|
d = 3.168;
|
||||||
|
e = 1.495;
|
||||||
|
f = 3.168;
|
||||||
|
|
||||||
|
//conn_pos = [a, a+b+c, a+b+c+d+e];
|
||||||
|
conn_pos = [a+b+c, a+b+c+d+e];
|
||||||
|
conn_dim = [
|
||||||
|
// [b, 8],
|
||||||
|
[d, 8],
|
||||||
|
[f, 8]
|
||||||
|
];
|
||||||
|
|
||||||
|
div_width = 0.5;
|
||||||
|
div_reach = 2.8;
|
||||||
|
div_pos = a+b+c+d+(e/2)-(div_width/2);
|
||||||
|
|
||||||
|
psu_case();
|
||||||
|
|
||||||
|
module psu_case() {
|
||||||
|
translate([wt + div_pos, wt, 0]) {
|
||||||
|
cube(size=[div_width, div_reach, zdim + wt]);
|
||||||
|
}
|
||||||
|
|
||||||
|
difference() {
|
||||||
|
cube(size=[ xdim + (2 * wt),
|
||||||
|
ydim + (2 * wt),
|
||||||
|
zdim + wt]);
|
||||||
|
translate([wt,wt,wt]) {
|
||||||
|
cube(size=[ xdim,
|
||||||
|
ydim + wt + 1,
|
||||||
|
zdim + wt + 1]);
|
||||||
|
}
|
||||||
|
conn_cuts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module conn_cuts() {
|
||||||
|
translate([wt, -1, 0]) {
|
||||||
|
for(i = [0:1:len(conn_pos) - 1]) {
|
||||||
|
translate([ conn_pos[i], 0, -wt]) {
|
||||||
|
cube([ conn_dim[i][0],
|
||||||
|
wt + 2,
|
||||||
|
conn_dim[i][1] + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//color("red") conn_cuts();
|
||||||
@@ -0,0 +1,208 @@
|
|||||||
|
//*** DIMENSIONS ***//
|
||||||
|
x = 0; y = 1; z = 2; // simplify array references
|
||||||
|
printer_layer_height=0.1313;
|
||||||
|
tol = 0.25; // tolerance
|
||||||
|
$fn = 80; // facet count for curves
|
||||||
|
|
||||||
|
label_text = "2026-05 v3.5";
|
||||||
|
label_size = 5;
|
||||||
|
|
||||||
|
// Include non-printing placeholder compoenents
|
||||||
|
render_placeholders = false;
|
||||||
|
|
||||||
|
// Only render mesh overlap structures
|
||||||
|
render_supports = false;
|
||||||
|
|
||||||
|
// Junction Box
|
||||||
|
jbox_dim = [51,92,82];
|
||||||
|
jbox_screw_distance = 83.5;
|
||||||
|
jbox_screw_dia = 2.1;
|
||||||
|
jbox_ear_width = 18.155 + 2;
|
||||||
|
jbox_ear_thickness = 3;
|
||||||
|
jbox_ear_pleatau = -15;
|
||||||
|
jbox_hole_inset = 4;
|
||||||
|
jbox_mount_dim = [15, 10, jbox_dim.z];
|
||||||
|
|
||||||
|
// Dial
|
||||||
|
dial_pos = [23.63,19.52];
|
||||||
|
dial_r = 18;
|
||||||
|
dial_bezel_r = 3;
|
||||||
|
dial_depth = 10.5;
|
||||||
|
dial_walls = 1.5;
|
||||||
|
dial_shaft_depth = 5;
|
||||||
|
dial_shaft_r = 10 / 2;
|
||||||
|
dial_hole_r = 6.25 / 2;
|
||||||
|
dial_hole_cut = (dial_hole_r * 2) - 4.75;
|
||||||
|
dial_faceplate_tol = 1.0;
|
||||||
|
|
||||||
|
// Faceplate
|
||||||
|
face_pos = [0, -5, 0];
|
||||||
|
thickness = 3;
|
||||||
|
corner_r = 10;
|
||||||
|
// brim_thickness = 13.5;
|
||||||
|
brim_thickness = 19.5 + 5;
|
||||||
|
display_thickness = 8;
|
||||||
|
display_window_layers = 3;
|
||||||
|
display_window_thickness = display_window_layers * printer_layer_height;
|
||||||
|
display_window_depth = 1;
|
||||||
|
display_pos = [[10.93,39.44],[10.93,59.76]];
|
||||||
|
display_dim = [25.4,19,display_thickness];
|
||||||
|
display_tolerance = 0.25;
|
||||||
|
xdim = 75; //placeholder
|
||||||
|
ydim = 115;
|
||||||
|
zdim = display_thickness + display_window_depth;
|
||||||
|
yoff = -10;
|
||||||
|
|
||||||
|
// MAX IC keepout
|
||||||
|
max_pos = [47.20,55.95]; // centered
|
||||||
|
max_dim = [10,34,4];
|
||||||
|
|
||||||
|
// Control PCB
|
||||||
|
pcb_dim = [54.8,82.29,1.6];
|
||||||
|
pcb_pos = [
|
||||||
|
(xdim / 2) - dial_pos.x,
|
||||||
|
(ydim / 2) - (pcb_dim.y / 2) + 5,
|
||||||
|
zdim
|
||||||
|
];
|
||||||
|
diffuse_inter_digit=12.7;
|
||||||
|
diffuse_xoff1 = 1;
|
||||||
|
diffuse_xoff2 = diffuse_xoff1 + diffuse_inter_digit;
|
||||||
|
diffuse_yoff = 2.5;
|
||||||
|
|
||||||
|
mounting_holes = [
|
||||||
|
[3.31,3.08],
|
||||||
|
[49.78,35.05],
|
||||||
|
[51.01,5.08],
|
||||||
|
[3.81,78.81],
|
||||||
|
[51.01,78.81]
|
||||||
|
];
|
||||||
|
|
||||||
|
// ESP Backpack
|
||||||
|
esp_header_dim = [3,38,3];
|
||||||
|
esp_header_offset = 6;
|
||||||
|
esp_pos = [23.43,19.59,pcb_dim.z+esp_header_dim.z];
|
||||||
|
esp_dim = [48,26,4];
|
||||||
|
|
||||||
|
mounting_stem_r = 8.75/2;
|
||||||
|
relay_mounting_stem_r = 7.75/2;
|
||||||
|
mounting_hole_r = 2.75/2; //for M2 screws
|
||||||
|
mounting_hole_depth = 5; //for 6mm long screws
|
||||||
|
mounting_stem_support_height = zdim;
|
||||||
|
mounting_stem_support_base = zdim;
|
||||||
|
mounting_stem_support_thickness = 2;
|
||||||
|
|
||||||
|
hook_dim = [3,20,30];
|
||||||
|
hook_cut_pos = [-1,10,3];
|
||||||
|
hook_cut_dim = [3, 10];
|
||||||
|
hook_cut_height = 20;
|
||||||
|
hook_cut_angle = 2;
|
||||||
|
|
||||||
|
// RELAY BOARD
|
||||||
|
|
||||||
|
relay_dim = [41.58,62.22,1.6];
|
||||||
|
relay_pos = [(jbox_dim.x / 2) - (relay_dim.x / 2),
|
||||||
|
jbox_mount_dim.y + 7,
|
||||||
|
-9.5];
|
||||||
|
relay_mounting_holes = [
|
||||||
|
[3.81,3.81],
|
||||||
|
[38.1,3.81],
|
||||||
|
[3.81,58.65],
|
||||||
|
[38.1,58.65]
|
||||||
|
];
|
||||||
|
relay_cover_height = 15.0;
|
||||||
|
relay_cover_thickness = 1.5;
|
||||||
|
relay_cover_mount_stem_r = 3.75;
|
||||||
|
relay_cover_mount_hole_r = 1.9;
|
||||||
|
relay_cover_mount_thickness = 1;
|
||||||
|
relay_sidewalls = 1.5; //TODO, merge this with thickness
|
||||||
|
relay_pcb_inset = 5.5;
|
||||||
|
relay_threaded_insert_depth = 8; //For M2x8x3.5 inserts
|
||||||
|
// NOTE: the following amount of the threaded brass insert should
|
||||||
|
// be left protruding:
|
||||||
|
// relay_pcb_inset - relay_dim.z = 5.5 - 1.6 = 3.9
|
||||||
|
|
||||||
|
// array of tuples, [pos,length]
|
||||||
|
// relay_conn_openings = [
|
||||||
|
// [8.0,9.0],
|
||||||
|
// [32.0,4],
|
||||||
|
// [42.5,4]
|
||||||
|
// ];
|
||||||
|
relay_actap_pos = [ [relay_dim.x-3.81,34.29],[relay_dim.x-3.81,44.45] ];
|
||||||
|
relay_passthrough_pos = [6.35 - 2,13.7 - 1];
|
||||||
|
relay_passthrough_dim = [4+2,8+2,10];
|
||||||
|
relay_conn_height=relay_pcb_inset - relay_dim.z;
|
||||||
|
|
||||||
|
// DHT SENSOR
|
||||||
|
dht_dim = [20.2,16.4,9.4];
|
||||||
|
dht_pos = [xdim - dht_dim.x - thickness - 11,
|
||||||
|
thickness,
|
||||||
|
thickness - 1];
|
||||||
|
dht_slot_dim = [1.5,dht_dim.y + thickness,dht_dim.z];
|
||||||
|
dht_slot_spacing = 1.5;
|
||||||
|
|
||||||
|
// FACEPLATE HOOKS
|
||||||
|
face_hook_tol = 0.25;
|
||||||
|
face_hook_thickness = 3;
|
||||||
|
face_hook_width = 15;
|
||||||
|
face_hook_jbox_clearance = 2;
|
||||||
|
face_hook_dim_4 = [ 2,15, 10];
|
||||||
|
face_hook_overreach = (xdim / 2) - (jbox_dim.x / 2) - face_hook_dim_4.x - face_hook_tol;
|
||||||
|
face_hook_dim_1 = [12,
|
||||||
|
face_hook_width,
|
||||||
|
thickness];
|
||||||
|
face_hook_dim_2 = [ thickness,
|
||||||
|
face_hook_width,
|
||||||
|
-relay_pos.z];
|
||||||
|
face_hook_dim_3 = [face_hook_overreach + face_hook_jbox_clearance,
|
||||||
|
15,
|
||||||
|
1.5];
|
||||||
|
face_hook_slot_dim = [2 + 2, 15/2 + 1,3];
|
||||||
|
face_hook_slot_pos = [-1,15/2,4];
|
||||||
|
face_hook_pos = [
|
||||||
|
[8, 70], // left side
|
||||||
|
[8, 70] // right side
|
||||||
|
];
|
||||||
|
face_hook_tab_dim = [3,
|
||||||
|
8,
|
||||||
|
face_hook_slot_dim.z - (face_hook_tol * 2)];
|
||||||
|
|
||||||
|
// BEZEL
|
||||||
|
|
||||||
|
bezel_r = 5;
|
||||||
|
|
||||||
|
// MODULES
|
||||||
|
|
||||||
|
module mounting_stem(depth, stem_r = mounting_stem_r, hole_r = mounting_hole_r) {
|
||||||
|
difference() {
|
||||||
|
linear_extrude(depth) {
|
||||||
|
circle(stem_r);
|
||||||
|
}
|
||||||
|
translate([0,0,2]) {
|
||||||
|
linear_extrude(depth + 1) {
|
||||||
|
circle(hole_r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// stem_support(0);
|
||||||
|
// stem_support(90);
|
||||||
|
// stem_support(180);
|
||||||
|
// stem_support(270);
|
||||||
|
}
|
||||||
|
|
||||||
|
//support triangle
|
||||||
|
support_points = [
|
||||||
|
[0,0],
|
||||||
|
[0, mounting_stem_support_height],
|
||||||
|
[mounting_stem_support_base, 0]
|
||||||
|
];
|
||||||
|
support_paths = [[0, 1, 2]];
|
||||||
|
|
||||||
|
module stem_support(rotation) {
|
||||||
|
rotate([90,0,rotation]) {
|
||||||
|
translate([mounting_stem_r - 1,0,-mounting_stem_support_thickness / 2]) {
|
||||||
|
linear_extrude(mounting_stem_support_thickness) {
|
||||||
|
polygon(points=support_points, paths=support_paths);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -0,0 +1,248 @@
|
|||||||
|
include <enclosure.h>
|
||||||
|
use <PSU.scad>
|
||||||
|
|
||||||
|
//*** DIMENSIONS ***//
|
||||||
|
|
||||||
|
//*** ASSEMBLY ***//
|
||||||
|
|
||||||
|
if (render_supports) {
|
||||||
|
supports();
|
||||||
|
} else {
|
||||||
|
difference() {
|
||||||
|
union() {
|
||||||
|
if (render_placeholders) {
|
||||||
|
placeholder_board();
|
||||||
|
*color("grey", 0.5) placeholder_jbox();
|
||||||
|
}
|
||||||
|
color("cyan") jbox_mounting_ears();
|
||||||
|
*color("white") relay_plate();
|
||||||
|
*color("blue") label();
|
||||||
|
*color("pink") sidewalls();
|
||||||
|
*color("cyan") face_hooks();
|
||||||
|
}
|
||||||
|
*color("red") relay_passthrough();
|
||||||
|
translate([0,0,-1])
|
||||||
|
*relay_mounting_stems(0);
|
||||||
|
}
|
||||||
|
*relay_mounting_stems(mounting_hole_r);
|
||||||
|
}
|
||||||
|
|
||||||
|
psu_case_attached();
|
||||||
|
|
||||||
|
*color("grey") placeholder_jbox();
|
||||||
|
|
||||||
|
//*** MODULES ***//
|
||||||
|
|
||||||
|
module psu_case_attached() {
|
||||||
|
translate([18.155/2+1,30,-24.0])
|
||||||
|
rotate([0,0,90])
|
||||||
|
psu_case();
|
||||||
|
}
|
||||||
|
|
||||||
|
module sidewalls() {
|
||||||
|
rotate([0,180,0]) {
|
||||||
|
translate([ -relay_dim.x/2,
|
||||||
|
relay_pos.y,
|
||||||
|
-relay_pos.z]) {
|
||||||
|
difference() {
|
||||||
|
cube(size=[ relay_dim.x,
|
||||||
|
relay_dim.y,
|
||||||
|
mounting_hole_depth]);
|
||||||
|
translate([ relay_sidewalls,
|
||||||
|
relay_sidewalls,
|
||||||
|
-1]) {
|
||||||
|
cube(size=[ relay_dim.x - (2 * relay_sidewalls),
|
||||||
|
relay_dim.y - (2 * relay_sidewalls),
|
||||||
|
mounting_hole_depth + 2]);
|
||||||
|
}
|
||||||
|
for(i = [0:len(relay_mounting_holes)-1]) {
|
||||||
|
translate(relay_mounting_holes[i]) {
|
||||||
|
mounting_stem(mounting_hole_depth + thickness,
|
||||||
|
hole_r = 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module relay_mounting_stems(r) {
|
||||||
|
stem_depth = relay_threaded_insert_depth - relay_pcb_inset + relay_dim.z + 2;
|
||||||
|
translate([jbox_dim.x/2,0,stem_depth]) {
|
||||||
|
rotate([0,0,180]) {
|
||||||
|
translate([relay_pos.x, -relay_pos.y - relay_dim.y, relay_pos.z]) {
|
||||||
|
for(i = [0:len(relay_mounting_holes)-1]) {
|
||||||
|
translate(relay_mounting_holes[i]) {
|
||||||
|
translate([0,0, 0]) {
|
||||||
|
rotate([180,0,0]) {
|
||||||
|
mounting_stem(stem_depth, stem_r = relay_mounting_stem_r, hole_r = r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module supports() {
|
||||||
|
relay_mounting_stems(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
module label() {
|
||||||
|
translate([ relay_pos.x + 0,
|
||||||
|
relay_pos.y + 10,
|
||||||
|
relay_pos.z+thickness])
|
||||||
|
rotate([0,0,90])
|
||||||
|
linear_extrude(0.75)
|
||||||
|
text(label_text, size=label_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
module face_hooks() {
|
||||||
|
for(i = [0:len(face_hook_pos[1])-1]) {
|
||||||
|
translate([0,face_hook_pos[1][i],relay_pos.z]) {
|
||||||
|
face_hook_right();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = [0:len(face_hook_pos[0])-1]) {
|
||||||
|
translate([0,face_hook_pos[0][i],relay_pos.z]) {
|
||||||
|
face_hook_left();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module face_hook_left() {
|
||||||
|
mirror([1,0,0])
|
||||||
|
face_hook_right();
|
||||||
|
}
|
||||||
|
|
||||||
|
module face_hook_right() {
|
||||||
|
//difference() {
|
||||||
|
translate([jbox_dim.x/2 - face_hook_dim_1.x - face_hook_jbox_clearance - thickness,0,0]) {
|
||||||
|
if (!render_supports) {
|
||||||
|
cube(size=face_hook_dim_1);
|
||||||
|
}
|
||||||
|
translate([face_hook_dim_1.x,0,0]) {
|
||||||
|
cube(size=face_hook_dim_2);
|
||||||
|
translate([0,0,face_hook_dim_2.z]) {
|
||||||
|
cube(size=face_hook_dim_3);
|
||||||
|
translate([face_hook_dim_3.x,0,0]) {
|
||||||
|
difference() {
|
||||||
|
cube(size=face_hook_dim_4);
|
||||||
|
translate(face_hook_slot_pos) {
|
||||||
|
cube(size=face_hook_slot_dim);
|
||||||
|
translate([ 0,
|
||||||
|
12,
|
||||||
|
-5.5]) {
|
||||||
|
rotate([45,0,0]) {
|
||||||
|
cube(size=10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module placeholder_jbox() {
|
||||||
|
translate([-jbox_dim.x/2,0,-jbox_dim.z]) {
|
||||||
|
difference() {
|
||||||
|
translate([-3,-3,-3])
|
||||||
|
cube([jbox_dim.x + 6,
|
||||||
|
jbox_dim.y + 6,
|
||||||
|
jbox_dim.z + 3]);
|
||||||
|
cube([jbox_dim.x, jbox_dim.y, jbox_dim.z + 1]);
|
||||||
|
}
|
||||||
|
translate([(jbox_dim.x/2) - (jbox_mount_dim.x/2), 0, 0]) {
|
||||||
|
cube(jbox_mount_dim);
|
||||||
|
translate([0,jbox_dim.y - jbox_mount_dim.y ,0])
|
||||||
|
cube(jbox_mount_dim);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module placeholder_board() {
|
||||||
|
rotate([0,180,0])
|
||||||
|
translate([-jbox_dim.x/2,0,2 * -relay_pos.z + relay_pcb_inset - relay_dim.z])
|
||||||
|
color("green") {
|
||||||
|
translate(relay_pos) {
|
||||||
|
difference() {
|
||||||
|
cube(size=relay_dim);
|
||||||
|
for(i = [0:len(relay_mounting_holes)-1]) {
|
||||||
|
translate([0,0,-1])
|
||||||
|
translate(relay_mounting_holes[i]) {
|
||||||
|
linear_extrude(zdim) {
|
||||||
|
circle(r=2.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module relay_plate() {
|
||||||
|
rotate([0,180,0])
|
||||||
|
translate([0,0,2 * -relay_pos.z - thickness])
|
||||||
|
translate([-jbox_dim.x/2,0,0])
|
||||||
|
translate([relay_pos.x - relay_cover_thickness,relay_pos.y,relay_pos.z]) {
|
||||||
|
cube(size=[relay_dim.x + (2 * relay_cover_thickness), relay_dim.y, thickness]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module relay_passthrough() {
|
||||||
|
rotate([0,180,0])
|
||||||
|
translate([0,0,2 * -relay_pos.z - thickness ])
|
||||||
|
translate([-jbox_dim.x/2,0,0])
|
||||||
|
translate([relay_pos.x - relay_cover_thickness,relay_pos.y,relay_pos.z]) {
|
||||||
|
translate([ relay_dim.x - relay_passthrough_pos.x,
|
||||||
|
relay_dim.y - relay_passthrough_pos.y] ) {
|
||||||
|
cube(size=relay_passthrough_dim, center=true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module jbox_mounting_ears() {
|
||||||
|
translate([0,jbox_hole_inset,0]) {
|
||||||
|
jbox_mounting_ear();
|
||||||
|
translate([0,jbox_screw_distance,0]) {
|
||||||
|
rotate([0,0,180]) {
|
||||||
|
jbox_mounting_ear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
translate([-jbox_ear_width/2, jbox_mount_dim.y, relay_pos.z]) {
|
||||||
|
difference() {
|
||||||
|
cube([jbox_ear_width,
|
||||||
|
jbox_dim.y - (2 * jbox_mount_dim.y) - 2,
|
||||||
|
thickness]);
|
||||||
|
translate([15,21.5,-5])
|
||||||
|
cube([4, 6,10]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module jbox_mounting_ear() {
|
||||||
|
linear_extrude(jbox_ear_thickness) {
|
||||||
|
difference() {
|
||||||
|
intersection() {
|
||||||
|
square([jbox_ear_width, 12], center=true);
|
||||||
|
translate([0, jbox_ear_pleatau, 0]) {
|
||||||
|
rotate([0,0,45]) {
|
||||||
|
square([50,50]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
circle(r=jbox_screw_dia);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
translate([-jbox_ear_width/2, jbox_mount_dim.y - jbox_hole_inset, relay_pos.z]) {
|
||||||
|
cube([jbox_ear_width, thickness, -relay_pos.z + jbox_ear_thickness]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module fplate_mount() {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# PCB Layout
|
||||||
|
|
||||||
|
For connecting [Waveshare 2.9inch Touch e-Paper HAT](https://www.waveshare.com/2.9inch-Touch-e-Paper-HAT.htm) with an ESP32
|
||||||
|
|
||||||
|
## Controller Selection
|
||||||
|
|
||||||
|
12E/12F style module for simplicity, and ICSP with an external serial TTL.
|
||||||
|
|
||||||
|
Will probably be worth running a paste stencil.
|
||||||
|
|
||||||
|
## Enclosure Considerations
|
||||||
|
|
||||||
|
Intent is for this to fit into a junction box, so it can mount to a printed
|
||||||
|
replacement for a switch plate.
|
||||||
|
|
||||||
|
NA Jbox screw spacing:
|
||||||
|
|
||||||
|
* "Box Mount" (Where the switch mounts to the jbox): 3.281"
|
||||||
|
* "Strap Mount" (Where the cover plate mounts to the switch): 3.812"
|
||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,125 @@
|
|||||||
|
{
|
||||||
|
"board": {
|
||||||
|
"active_layer": 0,
|
||||||
|
"active_layer_preset": "",
|
||||||
|
"auto_track_width": true,
|
||||||
|
"hidden_netclasses": [],
|
||||||
|
"hidden_nets": [],
|
||||||
|
"high_contrast_mode": 0,
|
||||||
|
"net_color_mode": 1,
|
||||||
|
"opacity": {
|
||||||
|
"images": 0.6,
|
||||||
|
"pads": 1.0,
|
||||||
|
"shapes": 1.0,
|
||||||
|
"tracks": 1.0,
|
||||||
|
"vias": 1.0,
|
||||||
|
"zones": 0.6
|
||||||
|
},
|
||||||
|
"prototype_zone_fills": false,
|
||||||
|
"selection_filter": {
|
||||||
|
"dimensions": true,
|
||||||
|
"footprints": true,
|
||||||
|
"graphics": true,
|
||||||
|
"keepouts": true,
|
||||||
|
"lockedItems": false,
|
||||||
|
"otherItems": true,
|
||||||
|
"pads": true,
|
||||||
|
"text": true,
|
||||||
|
"tracks": true,
|
||||||
|
"vias": true,
|
||||||
|
"zones": true
|
||||||
|
},
|
||||||
|
"visible_items": [
|
||||||
|
"vias",
|
||||||
|
"footprint_text",
|
||||||
|
"footprint_anchors",
|
||||||
|
"ratsnest",
|
||||||
|
"grid",
|
||||||
|
"footprints_front",
|
||||||
|
"footprints_back",
|
||||||
|
"footprint_values",
|
||||||
|
"footprint_references",
|
||||||
|
"tracks",
|
||||||
|
"drc_errors",
|
||||||
|
"drawing_sheet",
|
||||||
|
"bitmaps",
|
||||||
|
"pads",
|
||||||
|
"zones",
|
||||||
|
"drc_warnings",
|
||||||
|
"drc_exclusions",
|
||||||
|
"locked_item_shadows",
|
||||||
|
"conflict_shadows",
|
||||||
|
"shapes"
|
||||||
|
],
|
||||||
|
"visible_layers": "ffffffff_ffffffff_ffffffff_ffffffff",
|
||||||
|
"zone_display_mode": 0
|
||||||
|
},
|
||||||
|
"git": {
|
||||||
|
"integration_disabled": false,
|
||||||
|
"repo_type": "",
|
||||||
|
"repo_username": "",
|
||||||
|
"ssh_key": ""
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"filename": "waveshare-panel.kicad_prl",
|
||||||
|
"version": 5
|
||||||
|
},
|
||||||
|
"net_inspector_panel": {
|
||||||
|
"col_hidden": [
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
"col_order": [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6,
|
||||||
|
7,
|
||||||
|
8,
|
||||||
|
9
|
||||||
|
],
|
||||||
|
"col_widths": [],
|
||||||
|
"custom_group_rules": [],
|
||||||
|
"expanded_rows": [],
|
||||||
|
"filter_by_net_name": true,
|
||||||
|
"filter_by_netclass": true,
|
||||||
|
"filter_text": "",
|
||||||
|
"group_by_constraint": false,
|
||||||
|
"group_by_netclass": false,
|
||||||
|
"show_time_domain_details": false,
|
||||||
|
"show_unconnected_nets": false,
|
||||||
|
"show_zero_pad_nets": false,
|
||||||
|
"sort_ascending": true,
|
||||||
|
"sorting_column": -1
|
||||||
|
},
|
||||||
|
"open_jobsets": [],
|
||||||
|
"project": {
|
||||||
|
"files": []
|
||||||
|
},
|
||||||
|
"schematic": {
|
||||||
|
"hierarchy_collapsed": [],
|
||||||
|
"selection_filter": {
|
||||||
|
"graphics": true,
|
||||||
|
"images": true,
|
||||||
|
"labels": true,
|
||||||
|
"lockedItems": false,
|
||||||
|
"otherItems": true,
|
||||||
|
"pins": true,
|
||||||
|
"ruleAreas": true,
|
||||||
|
"symbols": true,
|
||||||
|
"text": true,
|
||||||
|
"wires": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,680 @@
|
|||||||
|
{
|
||||||
|
"board": {
|
||||||
|
"3dviewports": [],
|
||||||
|
"design_settings": {
|
||||||
|
"defaults": {
|
||||||
|
"apply_defaults_to_fp_barcodes": false,
|
||||||
|
"apply_defaults_to_fp_dimensions": false,
|
||||||
|
"apply_defaults_to_fp_fields": false,
|
||||||
|
"apply_defaults_to_fp_shapes": false,
|
||||||
|
"apply_defaults_to_fp_text": false,
|
||||||
|
"board_outline_line_width": 0.05,
|
||||||
|
"copper_line_width": 0.2,
|
||||||
|
"copper_text_italic": false,
|
||||||
|
"copper_text_size_h": 1.5,
|
||||||
|
"copper_text_size_v": 1.5,
|
||||||
|
"copper_text_thickness": 0.3,
|
||||||
|
"copper_text_upright": false,
|
||||||
|
"courtyard_line_width": 0.05,
|
||||||
|
"dimension_precision": 4,
|
||||||
|
"dimension_units": 3,
|
||||||
|
"dimensions": {
|
||||||
|
"arrow_length": 1270000,
|
||||||
|
"extension_offset": 500000,
|
||||||
|
"keep_text_aligned": true,
|
||||||
|
"suppress_zeroes": true,
|
||||||
|
"text_position": 0,
|
||||||
|
"units_format": 0
|
||||||
|
},
|
||||||
|
"fab_line_width": 0.1,
|
||||||
|
"fab_text_italic": false,
|
||||||
|
"fab_text_size_h": 1.0,
|
||||||
|
"fab_text_size_v": 1.0,
|
||||||
|
"fab_text_thickness": 0.15,
|
||||||
|
"fab_text_upright": false,
|
||||||
|
"other_line_width": 0.1,
|
||||||
|
"other_text_italic": false,
|
||||||
|
"other_text_size_h": 1.0,
|
||||||
|
"other_text_size_v": 1.0,
|
||||||
|
"other_text_thickness": 0.15,
|
||||||
|
"other_text_upright": false,
|
||||||
|
"pads": {
|
||||||
|
"drill": 0.8,
|
||||||
|
"height": 1.27,
|
||||||
|
"width": 2.54
|
||||||
|
},
|
||||||
|
"silk_line_width": 0.1,
|
||||||
|
"silk_text_italic": false,
|
||||||
|
"silk_text_size_h": 1.0,
|
||||||
|
"silk_text_size_v": 1.0,
|
||||||
|
"silk_text_thickness": 0.1,
|
||||||
|
"silk_text_upright": false,
|
||||||
|
"zones": {
|
||||||
|
"border_display_style": 2,
|
||||||
|
"border_hatch_pitch": 0.5,
|
||||||
|
"corner_radius": 0.0,
|
||||||
|
"corner_smoothing": 0,
|
||||||
|
"fill_mode": 0,
|
||||||
|
"hatch_gap": 1.5,
|
||||||
|
"hatch_orientation": 0.0,
|
||||||
|
"hatch_smoothing_level": 0,
|
||||||
|
"hatch_smoothing_value": 0.1,
|
||||||
|
"hatch_thickness": 1.0,
|
||||||
|
"min_clearance": 0.5,
|
||||||
|
"min_island_area": 10.0,
|
||||||
|
"min_thickness": 0.25,
|
||||||
|
"pad_connection": 1,
|
||||||
|
"remove_islands": 0,
|
||||||
|
"thermal_relief_gap": 0.5,
|
||||||
|
"thermal_relief_spoke_width": 0.5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"diff_pair_dimensions": [],
|
||||||
|
"drc_exclusions": [],
|
||||||
|
"meta": {
|
||||||
|
"version": 2
|
||||||
|
},
|
||||||
|
"rule_severities": {
|
||||||
|
"annular_width": "error",
|
||||||
|
"clearance": "error",
|
||||||
|
"connection_width": "warning",
|
||||||
|
"copper_edge_clearance": "error",
|
||||||
|
"copper_sliver": "warning",
|
||||||
|
"courtyards_overlap": "error",
|
||||||
|
"creepage": "error",
|
||||||
|
"diff_pair_gap_out_of_range": "error",
|
||||||
|
"diff_pair_uncoupled_length_too_long": "error",
|
||||||
|
"drill_out_of_range": "error",
|
||||||
|
"duplicate_footprints": "warning",
|
||||||
|
"extra_footprint": "warning",
|
||||||
|
"footprint": "error",
|
||||||
|
"footprint_filters_mismatch": "ignore",
|
||||||
|
"footprint_symbol_field_mismatch": "warning",
|
||||||
|
"footprint_symbol_mismatch": "warning",
|
||||||
|
"footprint_type_mismatch": "ignore",
|
||||||
|
"hole_clearance": "error",
|
||||||
|
"hole_to_hole": "warning",
|
||||||
|
"holes_co_located": "warning",
|
||||||
|
"invalid_outline": "error",
|
||||||
|
"isolated_copper": "warning",
|
||||||
|
"item_on_disabled_layer": "error",
|
||||||
|
"items_not_allowed": "error",
|
||||||
|
"length_out_of_range": "error",
|
||||||
|
"lib_footprint_issues": "warning",
|
||||||
|
"lib_footprint_mismatch": "warning",
|
||||||
|
"malformed_courtyard": "error",
|
||||||
|
"microvia_drill_out_of_range": "error",
|
||||||
|
"mirrored_text_on_front_layer": "warning",
|
||||||
|
"missing_courtyard": "ignore",
|
||||||
|
"missing_footprint": "warning",
|
||||||
|
"missing_tuning_profile": "warning",
|
||||||
|
"net_conflict": "warning",
|
||||||
|
"nonmirrored_text_on_back_layer": "warning",
|
||||||
|
"npth_inside_courtyard": "error",
|
||||||
|
"padstack": "warning",
|
||||||
|
"pth_inside_courtyard": "error",
|
||||||
|
"shorting_items": "error",
|
||||||
|
"silk_edge_clearance": "warning",
|
||||||
|
"silk_over_copper": "warning",
|
||||||
|
"silk_overlap": "warning",
|
||||||
|
"skew_out_of_range": "error",
|
||||||
|
"solder_mask_bridge": "error",
|
||||||
|
"starved_thermal": "error",
|
||||||
|
"text_height": "warning",
|
||||||
|
"text_on_edge_cuts": "error",
|
||||||
|
"text_thickness": "warning",
|
||||||
|
"through_hole_pad_without_hole": "error",
|
||||||
|
"too_many_vias": "error",
|
||||||
|
"track_angle": "error",
|
||||||
|
"track_dangling": "warning",
|
||||||
|
"track_not_centered_on_via": "ignore",
|
||||||
|
"track_on_post_machined_layer": "error",
|
||||||
|
"track_segment_length": "error",
|
||||||
|
"track_width": "error",
|
||||||
|
"tracks_crossing": "error",
|
||||||
|
"tuning_profile_track_geometries": "ignore",
|
||||||
|
"unconnected_items": "error",
|
||||||
|
"unresolved_variable": "error",
|
||||||
|
"via_dangling": "warning",
|
||||||
|
"zones_intersect": "error"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"max_error": 0.005,
|
||||||
|
"min_clearance": 0.0,
|
||||||
|
"min_connection": 0.0,
|
||||||
|
"min_copper_edge_clearance": 0.5,
|
||||||
|
"min_groove_width": 0.0,
|
||||||
|
"min_hole_clearance": 0.25,
|
||||||
|
"min_hole_to_hole": 0.25,
|
||||||
|
"min_microvia_diameter": 0.2,
|
||||||
|
"min_microvia_drill": 0.1,
|
||||||
|
"min_resolved_spokes": 2,
|
||||||
|
"min_silk_clearance": 0.0,
|
||||||
|
"min_text_height": 0.8,
|
||||||
|
"min_text_thickness": 0.08,
|
||||||
|
"min_through_hole_diameter": 0.3,
|
||||||
|
"min_track_width": 0.2,
|
||||||
|
"min_via_annular_width": 0.1,
|
||||||
|
"min_via_diameter": 0.5,
|
||||||
|
"solder_mask_to_copper_clearance": 0.0,
|
||||||
|
"use_height_for_length_calcs": true
|
||||||
|
},
|
||||||
|
"teardrop_options": [
|
||||||
|
{
|
||||||
|
"td_onpthpad": true,
|
||||||
|
"td_onroundshapesonly": false,
|
||||||
|
"td_onsmdpad": true,
|
||||||
|
"td_ontrackend": false,
|
||||||
|
"td_onvia": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"teardrop_parameters": [
|
||||||
|
{
|
||||||
|
"td_allow_use_two_tracks": true,
|
||||||
|
"td_curve_segcount": 0,
|
||||||
|
"td_height_ratio": 1.0,
|
||||||
|
"td_length_ratio": 0.5,
|
||||||
|
"td_maxheight": 2.0,
|
||||||
|
"td_maxlen": 1.0,
|
||||||
|
"td_on_pad_in_zone": false,
|
||||||
|
"td_target_name": "td_round_shape",
|
||||||
|
"td_width_to_size_filter_ratio": 0.9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"td_allow_use_two_tracks": true,
|
||||||
|
"td_curve_segcount": 0,
|
||||||
|
"td_height_ratio": 1.0,
|
||||||
|
"td_length_ratio": 0.5,
|
||||||
|
"td_maxheight": 2.0,
|
||||||
|
"td_maxlen": 1.0,
|
||||||
|
"td_on_pad_in_zone": false,
|
||||||
|
"td_target_name": "td_rect_shape",
|
||||||
|
"td_width_to_size_filter_ratio": 0.9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"td_allow_use_two_tracks": true,
|
||||||
|
"td_curve_segcount": 0,
|
||||||
|
"td_height_ratio": 1.0,
|
||||||
|
"td_length_ratio": 0.5,
|
||||||
|
"td_maxheight": 2.0,
|
||||||
|
"td_maxlen": 1.0,
|
||||||
|
"td_on_pad_in_zone": false,
|
||||||
|
"td_target_name": "td_track_end",
|
||||||
|
"td_width_to_size_filter_ratio": 0.9
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"track_widths": [],
|
||||||
|
"tuning_pattern_settings": {
|
||||||
|
"diff_pair_defaults": {
|
||||||
|
"corner_radius_percentage": 80,
|
||||||
|
"corner_style": 1,
|
||||||
|
"max_amplitude": 1.0,
|
||||||
|
"min_amplitude": 0.2,
|
||||||
|
"single_sided": false,
|
||||||
|
"spacing": 1.0
|
||||||
|
},
|
||||||
|
"diff_pair_skew_defaults": {
|
||||||
|
"corner_radius_percentage": 80,
|
||||||
|
"corner_style": 1,
|
||||||
|
"max_amplitude": 1.0,
|
||||||
|
"min_amplitude": 0.2,
|
||||||
|
"single_sided": false,
|
||||||
|
"spacing": 0.6
|
||||||
|
},
|
||||||
|
"single_track_defaults": {
|
||||||
|
"corner_radius_percentage": 80,
|
||||||
|
"corner_style": 1,
|
||||||
|
"max_amplitude": 1.0,
|
||||||
|
"min_amplitude": 0.2,
|
||||||
|
"single_sided": false,
|
||||||
|
"spacing": 0.6
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"via_dimensions": [],
|
||||||
|
"zones_allow_external_fillets": false
|
||||||
|
},
|
||||||
|
"ipc2581": {
|
||||||
|
"bom_rev": "",
|
||||||
|
"dist": "",
|
||||||
|
"distpn": "",
|
||||||
|
"internal_id": "",
|
||||||
|
"mfg": "",
|
||||||
|
"mpn": "",
|
||||||
|
"sch_revision": ""
|
||||||
|
},
|
||||||
|
"layer_pairs": [],
|
||||||
|
"layer_presets": [],
|
||||||
|
"viewports": []
|
||||||
|
},
|
||||||
|
"boards": [],
|
||||||
|
"component_class_settings": {
|
||||||
|
"assignments": [],
|
||||||
|
"meta": {
|
||||||
|
"version": 0
|
||||||
|
},
|
||||||
|
"sheet_component_classes": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cvpcb": {
|
||||||
|
"equivalence_files": []
|
||||||
|
},
|
||||||
|
"erc": {
|
||||||
|
"erc_exclusions": [],
|
||||||
|
"meta": {
|
||||||
|
"version": 0
|
||||||
|
},
|
||||||
|
"pin_map": [
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"rule_severities": {
|
||||||
|
"bus_definition_conflict": "error",
|
||||||
|
"bus_entry_needed": "error",
|
||||||
|
"bus_to_bus_conflict": "error",
|
||||||
|
"bus_to_net_conflict": "error",
|
||||||
|
"different_unit_footprint": "error",
|
||||||
|
"different_unit_net": "error",
|
||||||
|
"duplicate_reference": "error",
|
||||||
|
"duplicate_sheet_names": "error",
|
||||||
|
"endpoint_off_grid": "warning",
|
||||||
|
"extra_units": "error",
|
||||||
|
"field_name_whitespace": "warning",
|
||||||
|
"footprint_filter": "ignore",
|
||||||
|
"footprint_link_issues": "warning",
|
||||||
|
"four_way_junction": "ignore",
|
||||||
|
"global_label_dangling": "warning",
|
||||||
|
"ground_pin_not_ground": "warning",
|
||||||
|
"hier_label_mismatch": "error",
|
||||||
|
"isolated_pin_label": "warning",
|
||||||
|
"label_dangling": "error",
|
||||||
|
"label_multiple_wires": "warning",
|
||||||
|
"lib_symbol_issues": "warning",
|
||||||
|
"lib_symbol_mismatch": "warning",
|
||||||
|
"missing_bidi_pin": "warning",
|
||||||
|
"missing_input_pin": "warning",
|
||||||
|
"missing_power_pin": "error",
|
||||||
|
"missing_unit": "warning",
|
||||||
|
"multiple_net_names": "warning",
|
||||||
|
"net_not_bus_member": "warning",
|
||||||
|
"no_connect_connected": "warning",
|
||||||
|
"no_connect_dangling": "warning",
|
||||||
|
"pin_not_connected": "error",
|
||||||
|
"pin_not_driven": "error",
|
||||||
|
"pin_to_pin": "warning",
|
||||||
|
"power_pin_not_driven": "error",
|
||||||
|
"same_local_global_label": "warning",
|
||||||
|
"similar_label_and_power": "warning",
|
||||||
|
"similar_labels": "warning",
|
||||||
|
"similar_power": "warning",
|
||||||
|
"simulation_model_issue": "ignore",
|
||||||
|
"single_global_label": "ignore",
|
||||||
|
"stacked_pin_name": "warning",
|
||||||
|
"unannotated": "error",
|
||||||
|
"unconnected_wire_endpoint": "warning",
|
||||||
|
"undefined_netclass": "error",
|
||||||
|
"unit_value_mismatch": "error",
|
||||||
|
"unresolved_variable": "error",
|
||||||
|
"wire_dangling": "error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"libraries": {
|
||||||
|
"pinned_footprint_libs": [],
|
||||||
|
"pinned_symbol_libs": []
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"filename": "waveshare-panel.kicad_pro",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"net_settings": {
|
||||||
|
"classes": [
|
||||||
|
{
|
||||||
|
"bus_width": 12,
|
||||||
|
"clearance": 0.2,
|
||||||
|
"diff_pair_gap": 0.25,
|
||||||
|
"diff_pair_via_gap": 0.25,
|
||||||
|
"diff_pair_width": 0.2,
|
||||||
|
"line_style": 0,
|
||||||
|
"microvia_diameter": 0.3,
|
||||||
|
"microvia_drill": 0.1,
|
||||||
|
"name": "Default",
|
||||||
|
"pcb_color": "rgba(0, 0, 0, 0.000)",
|
||||||
|
"priority": 2147483647,
|
||||||
|
"schematic_color": "rgba(0, 0, 0, 0.000)",
|
||||||
|
"track_width": 0.2,
|
||||||
|
"tuning_profile": "",
|
||||||
|
"via_diameter": 0.6,
|
||||||
|
"via_drill": 0.3,
|
||||||
|
"wire_width": 6
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"version": 5
|
||||||
|
},
|
||||||
|
"net_colors": null,
|
||||||
|
"netclass_assignments": null,
|
||||||
|
"netclass_patterns": []
|
||||||
|
},
|
||||||
|
"pcbnew": {
|
||||||
|
"last_paths": {
|
||||||
|
"gencad": "",
|
||||||
|
"idf": "",
|
||||||
|
"netlist": "",
|
||||||
|
"plot": "",
|
||||||
|
"pos_files": "",
|
||||||
|
"specctra_dsn": "",
|
||||||
|
"step": "",
|
||||||
|
"svg": "",
|
||||||
|
"vrml": ""
|
||||||
|
},
|
||||||
|
"page_layout_descr_file": ""
|
||||||
|
},
|
||||||
|
"schematic": {
|
||||||
|
"annotate_start_num": 0,
|
||||||
|
"annotation": {
|
||||||
|
"method": 0,
|
||||||
|
"sort_order": 0
|
||||||
|
},
|
||||||
|
"bom_export_filename": "${PROJECTNAME}.csv",
|
||||||
|
"bom_fmt_presets": [],
|
||||||
|
"bom_fmt_settings": {
|
||||||
|
"field_delimiter": ",",
|
||||||
|
"keep_line_breaks": false,
|
||||||
|
"keep_tabs": false,
|
||||||
|
"name": "CSV",
|
||||||
|
"ref_delimiter": ",",
|
||||||
|
"ref_range_delimiter": "",
|
||||||
|
"string_delimiter": "\""
|
||||||
|
},
|
||||||
|
"bom_presets": [],
|
||||||
|
"bom_settings": {
|
||||||
|
"exclude_dnp": false,
|
||||||
|
"fields_ordered": [
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Reference",
|
||||||
|
"name": "Reference",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Qty",
|
||||||
|
"name": "${QUANTITY}",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "Value",
|
||||||
|
"name": "Value",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "DNP",
|
||||||
|
"name": "${DNP}",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "Exclude from BOM",
|
||||||
|
"name": "${EXCLUDE_FROM_BOM}",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "Exclude from Board",
|
||||||
|
"name": "${EXCLUDE_FROM_BOARD}",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "Footprint",
|
||||||
|
"name": "Footprint",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Datasheet",
|
||||||
|
"name": "Datasheet",
|
||||||
|
"show": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"filter_string": "",
|
||||||
|
"group_symbols": true,
|
||||||
|
"include_excluded_from_bom": true,
|
||||||
|
"name": "Default Editing",
|
||||||
|
"sort_asc": true,
|
||||||
|
"sort_field": "Reference"
|
||||||
|
},
|
||||||
|
"bus_aliases": {},
|
||||||
|
"connection_grid_size": 50.0,
|
||||||
|
"drawing": {
|
||||||
|
"dashed_lines_dash_length_ratio": 12.0,
|
||||||
|
"dashed_lines_gap_length_ratio": 3.0,
|
||||||
|
"default_line_thickness": 6.0,
|
||||||
|
"default_text_size": 50.0,
|
||||||
|
"field_names": [],
|
||||||
|
"hop_over_size_choice": 0,
|
||||||
|
"intersheets_ref_own_page": false,
|
||||||
|
"intersheets_ref_prefix": "",
|
||||||
|
"intersheets_ref_short": false,
|
||||||
|
"intersheets_ref_show": false,
|
||||||
|
"intersheets_ref_suffix": "",
|
||||||
|
"junction_size_choice": 3,
|
||||||
|
"label_size_ratio": 0.375,
|
||||||
|
"operating_point_overlay_i_precision": 3,
|
||||||
|
"operating_point_overlay_i_range": "~A",
|
||||||
|
"operating_point_overlay_v_precision": 3,
|
||||||
|
"operating_point_overlay_v_range": "~V",
|
||||||
|
"overbar_offset_ratio": 1.23,
|
||||||
|
"pin_symbol_size": 25.0,
|
||||||
|
"text_offset_ratio": 0.15
|
||||||
|
},
|
||||||
|
"legacy_lib_dir": "",
|
||||||
|
"legacy_lib_list": [],
|
||||||
|
"meta": {
|
||||||
|
"version": 1
|
||||||
|
},
|
||||||
|
"net_format_name": "",
|
||||||
|
"page_layout_descr_file": "",
|
||||||
|
"plot_directory": "",
|
||||||
|
"reuse_designators": true,
|
||||||
|
"space_save_all_events": true,
|
||||||
|
"spice_current_sheet_as_root": false,
|
||||||
|
"spice_external_command": "spice \"%I\"",
|
||||||
|
"spice_model_current_sheet_as_root": true,
|
||||||
|
"spice_save_all_currents": false,
|
||||||
|
"spice_save_all_dissipations": false,
|
||||||
|
"spice_save_all_voltages": false,
|
||||||
|
"subpart_first_id": 65,
|
||||||
|
"subpart_id_separator": 0,
|
||||||
|
"top_level_sheets": [
|
||||||
|
{
|
||||||
|
"filename": "waveshare-panel.kicad_sch",
|
||||||
|
"name": "waveshare-panel",
|
||||||
|
"uuid": "c20e9c1a-dd23-4f44-b3fb-ba3a30ec31ea"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"used_designators": "J4",
|
||||||
|
"variants": []
|
||||||
|
},
|
||||||
|
"sheets": [
|
||||||
|
[
|
||||||
|
"c20e9c1a-dd23-4f44-b3fb-ba3a30ec31ea",
|
||||||
|
"waveshare-panel"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"text_variables": {},
|
||||||
|
"tuning_profiles": {
|
||||||
|
"meta": {
|
||||||
|
"version": 0
|
||||||
|
},
|
||||||
|
"tuning_profiles_impedance_geometric": []
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
+142
-35
@@ -13,13 +13,18 @@
|
|||||||
# |Display MOSI |GPIO23 |Pin19/GPIO10/SPI0_MOSI |Green |
|
# |Display MOSI |GPIO23 |Pin19/GPIO10/SPI0_MOSI |Green |
|
||||||
# |Display CS |GPIO19 |Pin24/GPIO8/SPI0_CE0 |Mgnta |
|
# |Display CS |GPIO19 |Pin24/GPIO8/SPI0_CE0 |Mgnta |
|
||||||
# |Display DC |GPIO17 |Pin22/GPIO25 |White |
|
# |Display DC |GPIO17 |Pin22/GPIO25 |White |
|
||||||
# |Display Busy |GPIO4 |Pin24/GPIO24 |Brown |
|
# |Display Busy |GPIO4 |Pin18/GPIO24 |Brown |
|
||||||
# |Display RST |GPIO5 |Pin11/GPIO17/SPI1_CE1 |Orange |
|
# |Display RST |GPIO5 |Pin11/GPIO17/SPI1_CE1 |Orange |
|
||||||
# |Touch SDA |GPIO21 |Pin3/GPIO2/I2C1_SDA |Gray |
|
# |Touch SDA |GPIO21 |Pin3/GPIO2/I2C1_SDA |Gray |
|
||||||
# |Touch SCL |GPIO22 |Pin5/GPIO3/I2C1_SCL |Purple |
|
# |Touch SCL |GPIO22 |Pin5/GPIO3/I2C1_SCL |Purple |
|
||||||
# |Touch RST |GPIO15 |Pin13/GPIO27 |Blue |
|
# |Touch RST |GPIO15 |Pin13/GPIO27 |Blue |
|
||||||
# |Touch INT |GPIO16 |Pin15/GPIO22 |White |
|
# |Touch INT |GPIO16 |Pin15/GPIO22 |White |
|
||||||
#
|
#
|
||||||
|
# DISP_RST Moves from GPIO5 -> GPIO25 on PCB to avoid potential
|
||||||
|
# strapping issue
|
||||||
|
# TOUCH_IRQ Moves from GPIO16 -> GPIO14 on PCB to avoid potential
|
||||||
|
# strapping issue
|
||||||
|
#
|
||||||
# Exposed Entities
|
# Exposed Entities
|
||||||
# ---
|
# ---
|
||||||
#
|
#
|
||||||
@@ -76,7 +81,7 @@ display:
|
|||||||
model: 2.90inv2-r2-2bpp
|
model: 2.90inv2-r2-2bpp
|
||||||
# model: 2.90inv2-r2
|
# model: 2.90inv2-r2
|
||||||
full_update_every: 30
|
full_update_every: 30
|
||||||
rotation: 270°
|
rotation: 0°
|
||||||
auto_clear_enabled: false
|
auto_clear_enabled: false
|
||||||
update_interval: never
|
update_interval: never
|
||||||
|
|
||||||
@@ -96,12 +101,12 @@ touchscreen:
|
|||||||
update_interval: 50ms
|
update_interval: 50ms
|
||||||
calibration:
|
calibration:
|
||||||
x_min: 0
|
x_min: 0
|
||||||
x_max: 295
|
x_max: 127
|
||||||
y_min: 0
|
y_min: 0
|
||||||
y_max: 127
|
y_max: 295
|
||||||
transform:
|
transform:
|
||||||
|
swap_xy: true
|
||||||
mirror_x: true
|
mirror_x: true
|
||||||
mirror_y: true
|
|
||||||
|
|
||||||
### Okay, now the Good Stuff ###
|
### Okay, now the Good Stuff ###
|
||||||
|
|
||||||
@@ -146,6 +151,8 @@ image:
|
|||||||
id: floor_lamp
|
id: floor_lamp
|
||||||
- file: "mdi:home-off"
|
- file: "mdi:home-off"
|
||||||
id: away_button
|
id: away_button
|
||||||
|
- file: "mdi:thermometer"
|
||||||
|
id: light_temp
|
||||||
|
|
||||||
# When the user taps the screen, introduce a small delay for the LVGL framebuffer
|
# When the user taps the screen, introduce a small delay for the LVGL framebuffer
|
||||||
# to stabilize, then do a quick, 1-bit B/W selective update to visually indicate
|
# to stabilize, then do a quick, 1-bit B/W selective update to visually indicate
|
||||||
@@ -157,7 +164,12 @@ script:
|
|||||||
- id: refresh_display
|
- id: refresh_display
|
||||||
mode: restart
|
mode: restart
|
||||||
then:
|
then:
|
||||||
- delay: 60ms
|
- delay: 80ms
|
||||||
|
- lambda: 'id(display0).display_partial();'
|
||||||
|
# Retry once the e-paper's busy window has cleared, to catch HA-synced
|
||||||
|
# widget updates that landed while the first partial refresh was in flight
|
||||||
|
# (display_partial drops calls when busy).
|
||||||
|
- delay: 350ms
|
||||||
- lambda: 'id(display0).display_partial();'
|
- lambda: 'id(display0).display_partial();'
|
||||||
- id: full_refresh_display
|
- id: full_refresh_display
|
||||||
mode: restart
|
mode: restart
|
||||||
@@ -183,8 +195,8 @@ binary_sensor:
|
|||||||
- component.update: display0
|
- component.update: display0
|
||||||
# List the actual home entitites that we want this panel to control here
|
# List the actual home entitites that we want this panel to control here
|
||||||
- platform: homeassistant
|
- platform: homeassistant
|
||||||
id: goat_summit_light
|
id: alpha_bedroom_light
|
||||||
entity_id: light.goat_summit_light
|
entity_id: light.alpha_bedroom_light
|
||||||
publish_initial_state: true
|
publish_initial_state: true
|
||||||
on_state:
|
on_state:
|
||||||
then:
|
then:
|
||||||
@@ -192,6 +204,38 @@ binary_sensor:
|
|||||||
id: button_ceiling_fan_light
|
id: button_ceiling_fan_light
|
||||||
state:
|
state:
|
||||||
checked: !lambda return x;
|
checked: !lambda return x;
|
||||||
|
- platform: homeassistant
|
||||||
|
id: alpha_bedroom_ceiling_fan
|
||||||
|
entity_id: fan.alpha_bedroom_ceiling_fan
|
||||||
|
publish_initial_state: true
|
||||||
|
on_state:
|
||||||
|
then:
|
||||||
|
- lvgl.widget.update:
|
||||||
|
id: button_ceiling_fan
|
||||||
|
state:
|
||||||
|
checked: !lambda return x;
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
# Track the fan's current percentage so the speed buttons reflect the
|
||||||
|
# actual HA state (including changes made via other controls).
|
||||||
|
- platform: homeassistant
|
||||||
|
id: alpha_bedroom_ceiling_fan_pct
|
||||||
|
entity_id: fan.alpha_bedroom_ceiling_fan
|
||||||
|
attribute: percentage
|
||||||
|
on_value:
|
||||||
|
then:
|
||||||
|
- lvgl.widget.update:
|
||||||
|
id: button_fan_1
|
||||||
|
state:
|
||||||
|
checked: !lambda 'return x >= 1 && x < 50;'
|
||||||
|
- lvgl.widget.update:
|
||||||
|
id: button_fan_2
|
||||||
|
state:
|
||||||
|
checked: !lambda 'return x >= 50 && x < 84;'
|
||||||
|
- lvgl.widget.update:
|
||||||
|
id: button_fan_3
|
||||||
|
state:
|
||||||
|
checked: !lambda 'return x >= 84;'
|
||||||
|
|
||||||
# Here's where we put the actual GUI layout
|
# Here's where we put the actual GUI layout
|
||||||
lvgl:
|
lvgl:
|
||||||
@@ -234,50 +278,74 @@ lvgl:
|
|||||||
bg_color: 0xFFFFFF
|
bg_color: 0xFFFFFF
|
||||||
layout:
|
layout:
|
||||||
type: GRID
|
type: GRID
|
||||||
grid_rows: [fr(1), fr(1)]
|
grid_rows: [fr(1), fr(1), fr(1), fr(1)]
|
||||||
grid_columns: [fr(1), fr(1), fr(1), fr(1)]
|
grid_columns: [fr(1), fr(1)]
|
||||||
widgets:
|
widgets:
|
||||||
- button:
|
# Row 1: Light on/off (full width)
|
||||||
id: button_ceiling_fan
|
|
||||||
grid_cell_row_pos: 0
|
|
||||||
grid_cell_column_pos: 0
|
|
||||||
on_click:
|
|
||||||
- logger.log: "ceiling_fan"
|
|
||||||
widgets:
|
|
||||||
- image:
|
|
||||||
src: ceiling_fan
|
|
||||||
align: CENTER
|
|
||||||
- button:
|
- button:
|
||||||
id: button_ceiling_fan_light
|
id: button_ceiling_fan_light
|
||||||
grid_cell_row_pos: 0
|
grid_cell_row_pos: 0
|
||||||
grid_cell_column_pos: 1
|
grid_cell_column_pos: 0
|
||||||
|
grid_cell_column_span: 2
|
||||||
|
grid_cell_x_align: STRETCH
|
||||||
|
width: 124
|
||||||
on_click:
|
on_click:
|
||||||
- logger.log: "ceiling_fan_light"
|
- logger.log: "ceiling_fan_light"
|
||||||
- homeassistant.action:
|
- homeassistant.action:
|
||||||
action: light.toggle
|
action: light.toggle
|
||||||
data:
|
data:
|
||||||
entity_id: light.goat_summit_light
|
entity_id: light.alpha_bedroom_light
|
||||||
checkable: true
|
checkable: true
|
||||||
widgets:
|
widgets:
|
||||||
- image:
|
- image:
|
||||||
src: ceiling_fan_light
|
src: ceiling_fan_light
|
||||||
|
align: CENTER
|
||||||
|
# Row 2: Fan on/off (full width)
|
||||||
- button:
|
- button:
|
||||||
id: button_fan_off
|
id: button_ceiling_fan
|
||||||
grid_cell_row_pos: 0
|
grid_cell_row_pos: 1
|
||||||
grid_cell_column_pos: 2
|
grid_cell_column_pos: 0
|
||||||
|
grid_cell_column_span: 2
|
||||||
|
grid_cell_x_align: STRETCH
|
||||||
|
width: 124
|
||||||
on_click:
|
on_click:
|
||||||
- logger.log: "fan_off"
|
- logger.log: "ceiling_fan"
|
||||||
|
- homeassistant.action:
|
||||||
|
action: fan.toggle
|
||||||
|
data:
|
||||||
|
entity_id: fan.alpha_bedroom_ceiling_fan
|
||||||
checkable: true
|
checkable: true
|
||||||
widgets:
|
widgets:
|
||||||
- image:
|
- image:
|
||||||
src: fan_off
|
src: ceiling_fan
|
||||||
|
align: CENTER
|
||||||
|
# Row 3: Light temperature | Fan low
|
||||||
|
- button:
|
||||||
|
id: button_light_temp
|
||||||
|
grid_cell_row_pos: 2
|
||||||
|
grid_cell_column_pos: 0
|
||||||
|
on_click:
|
||||||
|
- logger.log: "light_temp"
|
||||||
|
- homeassistant.action:
|
||||||
|
action: button.press
|
||||||
|
data:
|
||||||
|
entity_id: button.alpha_bedroom_color_temp
|
||||||
|
widgets:
|
||||||
|
- image:
|
||||||
|
src: light_temp
|
||||||
|
align: CENTER
|
||||||
- button:
|
- button:
|
||||||
id: button_fan_1
|
id: button_fan_1
|
||||||
grid_cell_row_pos: 0
|
grid_cell_row_pos: 2
|
||||||
grid_cell_column_pos: 3
|
grid_cell_column_pos: 1
|
||||||
checkable: true
|
checkable: true
|
||||||
on_click:
|
on_click:
|
||||||
- logger.log: "fan_speed_1"
|
- logger.log: "fan_speed_1"
|
||||||
|
- homeassistant.action:
|
||||||
|
action: fan.set_percentage
|
||||||
|
data:
|
||||||
|
entity_id: fan.alpha_bedroom_ceiling_fan
|
||||||
|
percentage: '33'
|
||||||
- lvgl.widget.update:
|
- lvgl.widget.update:
|
||||||
id: button_fan_2
|
id: button_fan_2
|
||||||
state:
|
state:
|
||||||
@@ -289,30 +357,71 @@ lvgl:
|
|||||||
widgets:
|
widgets:
|
||||||
- image:
|
- image:
|
||||||
src: fan_speed_1
|
src: fan_speed_1
|
||||||
|
# Row 4: Fan medium | Fan high
|
||||||
- button:
|
- button:
|
||||||
id: button_fan_2
|
id: button_fan_2
|
||||||
grid_cell_row_pos: 1
|
grid_cell_row_pos: 3
|
||||||
grid_cell_column_pos: 0
|
grid_cell_column_pos: 0
|
||||||
on_click:
|
on_click:
|
||||||
- logger.log: "fan_speed_2"
|
- logger.log: "fan_speed_2"
|
||||||
|
- homeassistant.action:
|
||||||
|
action: fan.set_percentage
|
||||||
|
data:
|
||||||
|
entity_id: fan.alpha_bedroom_ceiling_fan
|
||||||
|
percentage: '66'
|
||||||
|
- lvgl.widget.update:
|
||||||
|
id: button_fan_1
|
||||||
|
state:
|
||||||
|
checked: false
|
||||||
|
- lvgl.widget.update:
|
||||||
|
id: button_fan_3
|
||||||
|
state:
|
||||||
|
checked: false
|
||||||
checkable: true
|
checkable: true
|
||||||
widgets:
|
widgets:
|
||||||
- image:
|
- image:
|
||||||
src: fan_speed_2
|
src: fan_speed_2
|
||||||
- button:
|
- button:
|
||||||
id: button_fan_3
|
id: button_fan_3
|
||||||
grid_cell_row_pos: 1
|
grid_cell_row_pos: 3
|
||||||
grid_cell_column_pos: 1
|
grid_cell_column_pos: 1
|
||||||
on_click:
|
on_click:
|
||||||
- logger.log: "fan_speed_3"
|
- logger.log: "fan_speed_3"
|
||||||
|
- homeassistant.action:
|
||||||
|
action: fan.set_percentage
|
||||||
|
data:
|
||||||
|
entity_id: fan.alpha_bedroom_ceiling_fan
|
||||||
|
percentage: '100'
|
||||||
|
- lvgl.widget.update:
|
||||||
|
id: button_fan_1
|
||||||
|
state:
|
||||||
|
checked: false
|
||||||
|
- lvgl.widget.update:
|
||||||
|
id: button_fan_2
|
||||||
|
state:
|
||||||
|
checked: false
|
||||||
checkable: true
|
checkable: true
|
||||||
widgets:
|
widgets:
|
||||||
- image:
|
- image:
|
||||||
src: fan_speed_3
|
src: fan_speed_3
|
||||||
|
# Unused buttons — kept defined but hidden for future use
|
||||||
|
- obj:
|
||||||
|
hidden: true
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
border_width: 0
|
||||||
|
pad_all: 0
|
||||||
|
widgets:
|
||||||
|
- button:
|
||||||
|
id: button_fan_off
|
||||||
|
on_click:
|
||||||
|
- logger.log: "fan_off"
|
||||||
|
checkable: true
|
||||||
|
widgets:
|
||||||
|
- image:
|
||||||
|
src: fan_off
|
||||||
- button:
|
- button:
|
||||||
id: button_floor_lamp
|
id: button_floor_lamp
|
||||||
grid_cell_row_pos: 1
|
|
||||||
grid_cell_column_pos: 2
|
|
||||||
on_click:
|
on_click:
|
||||||
- logger.log: "floor_lamp"
|
- logger.log: "floor_lamp"
|
||||||
checkable: true
|
checkable: true
|
||||||
@@ -321,8 +430,6 @@ lvgl:
|
|||||||
src: floor_lamp
|
src: floor_lamp
|
||||||
- button:
|
- button:
|
||||||
id: button_away
|
id: button_away
|
||||||
grid_cell_row_pos: 1
|
|
||||||
grid_cell_column_pos: 3
|
|
||||||
on_click:
|
on_click:
|
||||||
- logger.log: "away_button"
|
- logger.log: "away_button"
|
||||||
checkable: true
|
checkable: true
|
||||||
|
|||||||
Reference in New Issue
Block a user