esphome 2025.3.0b2__py3-none-any.whl → 2025.3.0b3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- esphome/components/font/__init__.py +51 -68
- esphome/components/graph/graph.cpp +4 -0
- esphome/components/graph/graph.h +4 -0
- esphome/const.py +1 -1
- {esphome-2025.3.0b2.dist-info → esphome-2025.3.0b3.dist-info}/METADATA +1 -1
- {esphome-2025.3.0b2.dist-info → esphome-2025.3.0b3.dist-info}/RECORD +10 -10
- {esphome-2025.3.0b2.dist-info → esphome-2025.3.0b3.dist-info}/LICENSE +0 -0
- {esphome-2025.3.0b2.dist-info → esphome-2025.3.0b3.dist-info}/WHEEL +0 -0
- {esphome-2025.3.0b2.dist-info → esphome-2025.3.0b3.dist-info}/entry_points.txt +0 -0
- {esphome-2025.3.0b2.dist-info → esphome-2025.3.0b3.dist-info}/top_level.txt +0 -0
@@ -146,6 +146,13 @@ def check_missing_glyphs(file, codepoints, warning: bool = False):
|
|
146
146
|
raise cv.Invalid(message)
|
147
147
|
|
148
148
|
|
149
|
+
def pt_to_px(pt):
|
150
|
+
"""
|
151
|
+
Convert a point size to pixels, rounding up to the nearest pixel
|
152
|
+
"""
|
153
|
+
return (pt + 63) // 64
|
154
|
+
|
155
|
+
|
149
156
|
def validate_font_config(config):
|
150
157
|
"""
|
151
158
|
Check for duplicate codepoints, then check that all requested codepoints actually
|
@@ -172,42 +179,43 @@ def validate_font_config(config):
|
|
172
179
|
)
|
173
180
|
# Make setpoints and glyphspoints disjoint
|
174
181
|
setpoints.difference_update(glyphspoints)
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
check_missing_glyphs(fileconf, glyphspoints)
|
190
|
-
# A missing glyph from a set is a warning.
|
191
|
-
if not config[CONF_IGNORE_MISSING_GLYPHS]:
|
192
|
-
check_missing_glyphs(fileconf, setpoints, warning=True)
|
182
|
+
# check that glyphs are actually present
|
183
|
+
# Check extras against their own font, exclude from parent font codepoints
|
184
|
+
for extra in config[CONF_EXTRAS]:
|
185
|
+
points = {ord(x) for x in flatten(extra[CONF_GLYPHS])}
|
186
|
+
glyphspoints.difference_update(points)
|
187
|
+
setpoints.difference_update(points)
|
188
|
+
check_missing_glyphs(extra[CONF_FILE], points)
|
189
|
+
|
190
|
+
# A named glyph that can't be provided is an error
|
191
|
+
|
192
|
+
check_missing_glyphs(fileconf, glyphspoints)
|
193
|
+
# A missing glyph from a set is a warning.
|
194
|
+
if not config[CONF_IGNORE_MISSING_GLYPHS]:
|
195
|
+
check_missing_glyphs(fileconf, setpoints, warning=True)
|
193
196
|
|
194
197
|
# Populate the default after the above checks so that use of the default doesn't trigger errors
|
198
|
+
font = FONT_CACHE[fileconf]
|
195
199
|
if not config[CONF_GLYPHS] and not config[CONF_GLYPHSETS]:
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
font
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
200
|
+
# set a default glyphset, intersected with what the font actually offers
|
201
|
+
config[CONF_GLYPHS] = [
|
202
|
+
chr(x)
|
203
|
+
for x in glyphsets.unicodes_per_glyphset(DEFAULT_GLYPHSET)
|
204
|
+
if font.get_char_index(x) != 0
|
205
|
+
]
|
206
|
+
|
207
|
+
if font.has_fixed_sizes:
|
208
|
+
sizes = [pt_to_px(x.size) for x in font.available_sizes]
|
209
|
+
if not sizes:
|
210
|
+
raise cv.Invalid(
|
211
|
+
f"Font {FontCache.get_name(fileconf)} has no available sizes"
|
212
|
+
)
|
213
|
+
if CONF_SIZE not in config:
|
214
|
+
config[CONF_SIZE] = sizes[0]
|
215
|
+
elif config[CONF_SIZE] not in sizes:
|
216
|
+
sizes = ", ".join(str(x) for x in sizes)
|
209
217
|
raise cv.Invalid(
|
210
|
-
"
|
218
|
+
f"Font {FontCache.get_name(fileconf)} only has size{'s' if len(sizes) != 1 else ''} {sizes} available"
|
211
219
|
)
|
212
220
|
elif CONF_SIZE not in config:
|
213
221
|
config[CONF_SIZE] = 20
|
@@ -215,14 +223,7 @@ def validate_font_config(config):
|
|
215
223
|
return config
|
216
224
|
|
217
225
|
|
218
|
-
FONT_EXTENSIONS = (".ttf", ".woff", ".otf")
|
219
|
-
BITMAP_EXTENSIONS = (".bdf", ".pcf")
|
220
|
-
|
221
|
-
|
222
|
-
def validate_bitmap_file(value):
|
223
|
-
if not any(map(value.lower().endswith, BITMAP_EXTENSIONS)):
|
224
|
-
raise cv.Invalid(f"Only {', '.join(BITMAP_EXTENSIONS)} files are supported.")
|
225
|
-
return CORE.relative_config_path(cv.file_(value))
|
226
|
+
FONT_EXTENSIONS = (".ttf", ".woff", ".otf", "bdf", ".pcf")
|
226
227
|
|
227
228
|
|
228
229
|
def validate_truetype_file(value):
|
@@ -246,7 +247,6 @@ def add_local_file(value):
|
|
246
247
|
|
247
248
|
|
248
249
|
TYPE_LOCAL = "local"
|
249
|
-
TYPE_LOCAL_BITMAP = "local_bitmap"
|
250
250
|
TYPE_GFONTS = "gfonts"
|
251
251
|
TYPE_WEB = "web"
|
252
252
|
LOCAL_SCHEMA = cv.All(
|
@@ -258,15 +258,6 @@ LOCAL_SCHEMA = cv.All(
|
|
258
258
|
add_local_file,
|
259
259
|
)
|
260
260
|
|
261
|
-
LOCAL_BITMAP_SCHEMA = cv.All(
|
262
|
-
cv.Schema(
|
263
|
-
{
|
264
|
-
cv.Required(CONF_PATH): validate_bitmap_file,
|
265
|
-
}
|
266
|
-
),
|
267
|
-
add_local_file,
|
268
|
-
)
|
269
|
-
|
270
261
|
FULLPATH_SCHEMA = cv.maybe_simple_value(
|
271
262
|
{cv.Required(CONF_PATH): cv.string}, key=CONF_PATH
|
272
263
|
)
|
@@ -403,15 +394,6 @@ def validate_file_shorthand(value):
|
|
403
394
|
}
|
404
395
|
)
|
405
396
|
|
406
|
-
extension = Path(value).suffix
|
407
|
-
if extension in BITMAP_EXTENSIONS:
|
408
|
-
return font_file_schema(
|
409
|
-
{
|
410
|
-
CONF_TYPE: TYPE_LOCAL_BITMAP,
|
411
|
-
CONF_PATH: value,
|
412
|
-
}
|
413
|
-
)
|
414
|
-
|
415
397
|
return font_file_schema(
|
416
398
|
{
|
417
399
|
CONF_TYPE: TYPE_LOCAL,
|
@@ -424,7 +406,6 @@ TYPED_FILE_SCHEMA = cv.typed_schema(
|
|
424
406
|
{
|
425
407
|
TYPE_LOCAL: LOCAL_SCHEMA,
|
426
408
|
TYPE_GFONTS: GFONTS_SCHEMA,
|
427
|
-
TYPE_LOCAL_BITMAP: LOCAL_BITMAP_SCHEMA,
|
428
409
|
TYPE_WEB: WEB_FONT_SCHEMA,
|
429
410
|
}
|
430
411
|
)
|
@@ -522,11 +503,13 @@ async def to_code(config):
|
|
522
503
|
bpp = config[CONF_BPP]
|
523
504
|
mode = ft_pixel_mode_grays
|
524
505
|
scale = 256 // (1 << bpp)
|
506
|
+
size = config[CONF_SIZE]
|
525
507
|
# create the data array for all glyphs
|
526
508
|
for codepoint in codepoints:
|
527
509
|
font = point_font_map[codepoint]
|
528
|
-
|
529
|
-
|
510
|
+
format = font.get_format().decode("utf-8")
|
511
|
+
if format != "PCF":
|
512
|
+
font.set_pixel_sizes(size, 0)
|
530
513
|
font.load_char(codepoint)
|
531
514
|
font.glyph.render(mode)
|
532
515
|
width = font.glyph.bitmap.width
|
@@ -550,17 +533,17 @@ async def to_code(config):
|
|
550
533
|
if pixel & (1 << (bpp - bit_num - 1)):
|
551
534
|
glyph_data[pos // 8] |= 0x80 >> (pos % 8)
|
552
535
|
pos += 1
|
553
|
-
ascender = font.size.ascender
|
536
|
+
ascender = pt_to_px(font.size.ascender)
|
554
537
|
if ascender == 0:
|
555
538
|
if font.has_fixed_sizes:
|
556
|
-
ascender =
|
539
|
+
ascender = size
|
557
540
|
else:
|
558
541
|
_LOGGER.error(
|
559
542
|
"Unable to determine ascender of font %s", config[CONF_FILE]
|
560
543
|
)
|
561
544
|
glyph_args[codepoint] = GlyphInfo(
|
562
545
|
len(data),
|
563
|
-
font.glyph.metrics.horiAdvance
|
546
|
+
pt_to_px(font.glyph.metrics.horiAdvance),
|
564
547
|
font.glyph.bitmap_left,
|
565
548
|
ascender - font.glyph.bitmap_top,
|
566
549
|
width,
|
@@ -599,11 +582,11 @@ async def to_code(config):
|
|
599
582
|
|
600
583
|
glyphs = cg.static_const_array(config[CONF_RAW_GLYPH_ID], glyph_initializer)
|
601
584
|
|
602
|
-
font_height = base_font.size.height
|
603
|
-
ascender = base_font.size.ascender
|
585
|
+
font_height = pt_to_px(base_font.size.height)
|
586
|
+
ascender = pt_to_px(base_font.size.ascender)
|
604
587
|
if font_height == 0:
|
605
588
|
if base_font.has_fixed_sizes:
|
606
|
-
font_height =
|
589
|
+
font_height = size
|
607
590
|
ascender = font_height
|
608
591
|
else:
|
609
592
|
_LOGGER.error("Unable to determine height of font %s", config[CONF_FILE])
|
@@ -132,6 +132,10 @@ void Graph::draw(Display *buff, uint16_t x_offset, uint16_t y_offset, Color colo
|
|
132
132
|
yrange = ymax - ymin;
|
133
133
|
}
|
134
134
|
|
135
|
+
// Store graph limts
|
136
|
+
this->graph_limit_max_ = ymax;
|
137
|
+
this->graph_limit_min_ = ymin;
|
138
|
+
|
135
139
|
/// Draw grid
|
136
140
|
if (!std::isnan(this->gridspacing_y_)) {
|
137
141
|
for (int y = yn; y <= ym; y++) {
|
esphome/components/graph/graph.h
CHANGED
@@ -161,11 +161,15 @@ class Graph : public Component {
|
|
161
161
|
uint32_t get_duration() { return duration_; }
|
162
162
|
uint32_t get_width() { return width_; }
|
163
163
|
uint32_t get_height() { return height_; }
|
164
|
+
float get_graph_limit_min() { return graph_limit_min_; }
|
165
|
+
float get_graph_limit_max() { return graph_limit_max_; }
|
164
166
|
|
165
167
|
protected:
|
166
168
|
uint32_t duration_; /// in seconds
|
167
169
|
uint32_t width_; /// in pixels
|
168
170
|
uint32_t height_; /// in pixels
|
171
|
+
float graph_limit_min_{NAN};
|
172
|
+
float graph_limit_max_{NAN};
|
169
173
|
float min_value_{NAN};
|
170
174
|
float max_value_{NAN};
|
171
175
|
float min_range_{1.0};
|
esphome/const.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: esphome
|
3
|
-
Version: 2025.3.
|
3
|
+
Version: 2025.3.0b3
|
4
4
|
Summary: ESPHome is a system to configure your microcontrollers by simple yet powerful configuration files and control them remotely through Home Automation systems.
|
5
5
|
Author-email: The ESPHome Authors <esphome@nabucasa.com>
|
6
6
|
License: MIT
|
@@ -5,7 +5,7 @@ esphome/codegen.py,sha256=GePHUM7xdXb_Pil59SHVsXg2F4VBPgkH-Fz2PDX8Z54,1873
|
|
5
5
|
esphome/config.py,sha256=fFrDYbhWY1xn_onAl_0jwlg9D8NkK_FdKULTlnjZtxs,39832
|
6
6
|
esphome/config_helpers.py,sha256=MKf_wzO35nn41FvigXE0iYKDslPgL2ruf8R-EPtTT2I,3256
|
7
7
|
esphome/config_validation.py,sha256=9KOhLHQXmDbahg6zHynXfXDfAL2bciu35_SHxHrzZ2M,63705
|
8
|
-
esphome/const.py,sha256=
|
8
|
+
esphome/const.py,sha256=gRnH5u1m9aFv6gSK3arX-BBWulzgNpPYP88e5YWZkRo,40764
|
9
9
|
esphome/coroutine.py,sha256=j_14z8dIIzIBeuNO30D4c1RJvMMt1xZFZ58Evd-EvJA,9344
|
10
10
|
esphome/cpp_generator.py,sha256=1g-y3fxWSrd5Kpbz6DrJXaQajjuwQiTIaTRIz9n7svI,31237
|
11
11
|
esphome/cpp_helpers.py,sha256=6C2vNbOIhZKi43xRVlk5hp9GfshfBn-rc5D_ZFUEYaE,4801
|
@@ -952,7 +952,7 @@ esphome/components/fingerprint_grow/binary_sensor.py,sha256=NeVcqVCpmjGdnfimIIWS
|
|
952
952
|
esphome/components/fingerprint_grow/fingerprint_grow.cpp,sha256=xtHEpnp1Ei_5s5SS5Vfxt8vG_PoPMmeUjbOQHWrn5G0,18675
|
953
953
|
esphome/components/fingerprint_grow/fingerprint_grow.h,sha256=UEkLR4Cqas_XYlTLAwscXCAMRoprWeQZEZ_3vTsI-BM,11206
|
954
954
|
esphome/components/fingerprint_grow/sensor.py,sha256=eazvZvdtt1Rl8o3Aw6eYKn-kb2sNDfZKHegxpFFdQeg,2244
|
955
|
-
esphome/components/font/__init__.py,sha256=
|
955
|
+
esphome/components/font/__init__.py,sha256=r7IpPuAOAJuPyz9tvnb_q9T9QTLuH2-ti-D3iDGOG9A,18893
|
956
956
|
esphome/components/font/font.cpp,sha256=dxZID-p7toxsAe3JZIc6syEdleARl-H3IRWoUIFGUOY,5361
|
957
957
|
esphome/components/font/font.h,sha256=lBUD-bX8qK0Us0tVjq9i38EJVG6p9w4npKnW1L_ILx0,2024
|
958
958
|
esphome/components/fs3000/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -1014,8 +1014,8 @@ esphome/components/gps/time/__init__.py,sha256=iuZWg8qhi8uMoah4B2z4OyAsXndE9z6oH
|
|
1014
1014
|
esphome/components/gps/time/gps_time.cpp,sha256=XEslYAhMq8ZViWF0QfoO95JiISUj0TLeuRcU4CnJq_8,958
|
1015
1015
|
esphome/components/gps/time/gps_time.h,sha256=LTbCT36s68Sjifw0Qv6yxo5aiv2NK6Zreh1Rmtkxsqk,624
|
1016
1016
|
esphome/components/graph/__init__.py,sha256=cxfJJTEGoaQ_3EAo5_cWUvLWAUjeoNyI4mqoxwkm_cc,7819
|
1017
|
-
esphome/components/graph/graph.cpp,sha256=
|
1018
|
-
esphome/components/graph/graph.h,sha256=
|
1017
|
+
esphome/components/graph/graph.cpp,sha256=khFAaKpn7t67RtQFtbp-5GnjxGcTHHQS19hYjj4yJVc,12331
|
1018
|
+
esphome/components/graph/graph.h,sha256=_QYsue2vhTKTLdKW39b_JVcPMwzhlyx5201fIuYJMrw,6201
|
1019
1019
|
esphome/components/graphical_display_menu/__init__.py,sha256=YGbv_JsuWmW3HumvMZq0EwJszFmaXGbNYrrl9OPhNEc,3557
|
1020
1020
|
esphome/components/graphical_display_menu/graphical_display_menu.cpp,sha256=_1xbdf6a_krZS-xD8D4kRW32QPz68zWs-MrXLOYYThU,9146
|
1021
1021
|
esphome/components/graphical_display_menu/graphical_display_menu.h,sha256=wxHyShfCIFDgvppSatvxAYPSnGNjYF9uuh-sloI53MI,2957
|
@@ -3474,9 +3474,9 @@ esphome/dashboard/util/itertools.py,sha256=8eLrWEWmICLtXNxkKdYPQV0c_N4GEz8m9Npnb
|
|
3474
3474
|
esphome/dashboard/util/password.py,sha256=cQz3b9B-ijTe7zS6BeCW0hc3pWv6JjC78jmnycYYAh8,321
|
3475
3475
|
esphome/dashboard/util/subprocess.py,sha256=T8EW6dbU4LPd2DG1dRrdh8li71tt6J1isn411poMhkk,1022
|
3476
3476
|
esphome/dashboard/util/text.py,sha256=ENDnfN4O0NdA3CKVJjQYabFbwbrsIhVKrAMQe53qYu4,534
|
3477
|
-
esphome-2025.3.
|
3478
|
-
esphome-2025.3.
|
3479
|
-
esphome-2025.3.
|
3480
|
-
esphome-2025.3.
|
3481
|
-
esphome-2025.3.
|
3482
|
-
esphome-2025.3.
|
3477
|
+
esphome-2025.3.0b3.dist-info/LICENSE,sha256=HzEjkBInJe44L4WvAOPfhPJJDNj6YbnqFyvGWRzArGM,36664
|
3478
|
+
esphome-2025.3.0b3.dist-info/METADATA,sha256=EpO47tRzjK6pyJGru626GK2LUW_a_Zd9ybDSWxX3xV0,3691
|
3479
|
+
esphome-2025.3.0b3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
3480
|
+
esphome-2025.3.0b3.dist-info/entry_points.txt,sha256=mIxVNuWtbYzeEcaWCl-AQ-97aBOWbnYBAK8nbF6P4M0,50
|
3481
|
+
esphome-2025.3.0b3.dist-info/top_level.txt,sha256=0GSXEW3cnITpgG3qnsSMz0qoqJHAFyfw7Y8MVtEf1Yk,8
|
3482
|
+
esphome-2025.3.0b3.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|