├── LICENSE
├── README.md
├── display-28.yaml
├── fonts
    ├── Arial-Black.ttf
    ├── BebasNeue-Regular.ttf
    ├── Helvetica.ttf
    ├── arial.ttf
    ├── lexis.ttf
    ├── materialdesignicons-webfont.ttf
    ├── slkscr.ttf
    └── times-new-roman.ttf
├── images
    ├── 0-default.png
    ├── 1-clear-night.png
    ├── 10-snowy.png
    ├── 11-snowy-rainy.png
    ├── 12-sunny.png
    ├── 13-windy.png
    ├── 14-windy-variant.png
    ├── 15-exceptional.png
    ├── 16-rosa-dei-venti originale.png
    ├── 16-rosa-dei-venti.png
    ├── 2-cloudy.png
    ├── 3-fog.png
    ├── 4-hail.png
    ├── 5-lightning.png
    ├── 6-lightning-rainy.png
    ├── 7-partlycloudy.png
    ├── 8-pouring.png
    ├── 9-rainy.png
    ├── power-off-button.png
    ├── radio-station.png
    └── rosadeiventi.png
├── readme_img
    ├── 1703942900-de997d983c0182a35cf30cceca23220db6154e67.jpeg
    ├── 1703943134-Screenshot-2023-12-30-at-14-31-18-733E-Esp-wroom-32-Esp32-For-Arduino-Lvgl-Wifi-28-28inch-Lcd-Tft-Module-With-Touch-Wroom-240-.png
    ├── 1703943240-Screenshot-2023-12-30-at-14-32-26-733E-Esp-wroom-32-Esp32-For-Arduino-Lvgl-Wifi-28-28inch-Lcd-Tft-Module-With-Touch-Wroom-240-320-.png
    ├── esp32_2432s028_i2c.jpg
    ├── example.jpg
    ├── grafico.jpg
    ├── status.jpg
    └── vento.jpg
└── secrets.yaml
/LICENSE:
--------------------------------------------------------------------------------
  1 |                     GNU GENERAL PUBLIC LICENSE
  2 |                        Version 3, 29 June 2007
  3 | 
  4 |  Copyright (C) 2007 Free Software Foundation, Inc. 
  5 |  Everyone is permitted to copy and distribute verbatim copies
  6 |  of this license document, but changing it is not allowed.
  7 | 
  8 |                             Preamble
  9 | 
 10 |   The GNU General Public License is a free, copyleft license for
 11 | software and other kinds of works.
 12 | 
 13 |   The licenses for most software and other practical works are designed
 14 | to take away your freedom to share and change the works.  By contrast,
 15 | the GNU General Public License is intended to guarantee your freedom to
 16 | share and change all versions of a program--to make sure it remains free
 17 | software for all its users.  We, the Free Software Foundation, use the
 18 | GNU General Public License for most of our software; it applies also to
 19 | any other work released this way by its authors.  You can apply it to
 20 | your programs, too.
 21 | 
 22 |   When we speak of free software, we are referring to freedom, not
 23 | price.  Our General Public Licenses are designed to make sure that you
 24 | have the freedom to distribute copies of free software (and charge for
 25 | them if you wish), that you receive source code or can get it if you
 26 | want it, that you can change the software or use pieces of it in new
 27 | free programs, and that you know you can do these things.
 28 | 
 29 |   To protect your rights, we need to prevent others from denying you
 30 | these rights or asking you to surrender the rights.  Therefore, you have
 31 | certain responsibilities if you distribute copies of the software, or if
 32 | you modify it: responsibilities to respect the freedom of others.
 33 | 
 34 |   For example, if you distribute copies of such a program, whether
 35 | gratis or for a fee, you must pass on to the recipients the same
 36 | freedoms that you received.  You must make sure that they, too, receive
 37 | or can get the source code.  And you must show them these terms so they
 38 | know their rights.
 39 | 
 40 |   Developers that use the GNU GPL protect your rights with two steps:
 41 | (1) assert copyright on the software, and (2) offer you this License
 42 | giving you legal permission to copy, distribute and/or modify it.
 43 | 
 44 |   For the developers' and authors' protection, the GPL clearly explains
 45 | that there is no warranty for this free software.  For both users' and
 46 | authors' sake, the GPL requires that modified versions be marked as
 47 | changed, so that their problems will not be attributed erroneously to
 48 | authors of previous versions.
 49 | 
 50 |   Some devices are designed to deny users access to install or run
 51 | modified versions of the software inside them, although the manufacturer
 52 | can do so.  This is fundamentally incompatible with the aim of
 53 | protecting users' freedom to change the software.  The systematic
 54 | pattern of such abuse occurs in the area of products for individuals to
 55 | use, which is precisely where it is most unacceptable.  Therefore, we
 56 | have designed this version of the GPL to prohibit the practice for those
 57 | products.  If such problems arise substantially in other domains, we
 58 | stand ready to extend this provision to those domains in future versions
 59 | of the GPL, as needed to protect the freedom of users.
 60 | 
 61 |   Finally, every program is threatened constantly by software patents.
 62 | States should not allow patents to restrict development and use of
 63 | software on general-purpose computers, but in those that do, we wish to
 64 | avoid the special danger that patents applied to a free program could
 65 | make it effectively proprietary.  To prevent this, the GPL assures that
 66 | patents cannot be used to render the program non-free.
 67 | 
 68 |   The precise terms and conditions for copying, distribution and
 69 | modification follow.
 70 | 
 71 |                        TERMS AND CONDITIONS
 72 | 
 73 |   0. Definitions.
 74 | 
 75 |   "This License" refers to version 3 of the GNU General Public License.
 76 | 
 77 |   "Copyright" also means copyright-like laws that apply to other kinds of
 78 | works, such as semiconductor masks.
 79 | 
 80 |   "The Program" refers to any copyrightable work licensed under this
 81 | License.  Each licensee is addressed as "you".  "Licensees" and
 82 | "recipients" may be individuals or organizations.
 83 | 
 84 |   To "modify" a work means to copy from or adapt all or part of the work
 85 | in a fashion requiring copyright permission, other than the making of an
 86 | exact copy.  The resulting work is called a "modified version" of the
 87 | earlier work or a work "based on" the earlier work.
 88 | 
 89 |   A "covered work" means either the unmodified Program or a work based
 90 | on the Program.
 91 | 
 92 |   To "propagate" a work means to do anything with it that, without
 93 | permission, would make you directly or secondarily liable for
 94 | infringement under applicable copyright law, except executing it on a
 95 | computer or modifying a private copy.  Propagation includes copying,
 96 | distribution (with or without modification), making available to the
 97 | public, and in some countries other activities as well.
 98 | 
 99 |   To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies.  Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 | 
103 |   An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License.  If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 | 
112 |   1. Source Code.
113 | 
114 |   The "source code" for a work means the preferred form of the work
115 | for making modifications to it.  "Object code" means any non-source
116 | form of a work.
117 | 
118 |   A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 | 
123 |   The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form.  A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 | 
134 |   The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities.  However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work.  For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 | 
147 |   The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 | 
151 |   The Corresponding Source for a work in source code form is that
152 | same work.
153 | 
154 |   2. Basic Permissions.
155 | 
156 |   All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met.  This License explicitly affirms your unlimited
159 | permission to run the unmodified Program.  The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work.  This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 | 
164 |   You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force.  You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright.  Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 | 
175 |   Conveying under any other circumstances is permitted solely under
176 | the conditions stated below.  Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 | 
179 |   3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 | 
181 |   No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 | 
187 |   When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 | 
195 |   4. Conveying Verbatim Copies.
196 | 
197 |   You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 | 
205 |   You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 | 
208 |   5. Conveying Modified Source Versions.
209 | 
210 |   You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 | 
214 |     a) The work must carry prominent notices stating that you modified
215 |     it, and giving a relevant date.
216 | 
217 |     b) The work must carry prominent notices stating that it is
218 |     released under this License and any conditions added under section
219 |     7.  This requirement modifies the requirement in section 4 to
220 |     "keep intact all notices".
221 | 
222 |     c) You must license the entire work, as a whole, under this
223 |     License to anyone who comes into possession of a copy.  This
224 |     License will therefore apply, along with any applicable section 7
225 |     additional terms, to the whole of the work, and all its parts,
226 |     regardless of how they are packaged.  This License gives no
227 |     permission to license the work in any other way, but it does not
228 |     invalidate such permission if you have separately received it.
229 | 
230 |     d) If the work has interactive user interfaces, each must display
231 |     Appropriate Legal Notices; however, if the Program has interactive
232 |     interfaces that do not display Appropriate Legal Notices, your
233 |     work need not make them do so.
234 | 
235 |   A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit.  Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 | 
245 |   6. Conveying Non-Source Forms.
246 | 
247 |   You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 | 
252 |     a) Convey the object code in, or embodied in, a physical product
253 |     (including a physical distribution medium), accompanied by the
254 |     Corresponding Source fixed on a durable physical medium
255 |     customarily used for software interchange.
256 | 
257 |     b) Convey the object code in, or embodied in, a physical product
258 |     (including a physical distribution medium), accompanied by a
259 |     written offer, valid for at least three years and valid for as
260 |     long as you offer spare parts or customer support for that product
261 |     model, to give anyone who possesses the object code either (1) a
262 |     copy of the Corresponding Source for all the software in the
263 |     product that is covered by this License, on a durable physical
264 |     medium customarily used for software interchange, for a price no
265 |     more than your reasonable cost of physically performing this
266 |     conveying of source, or (2) access to copy the
267 |     Corresponding Source from a network server at no charge.
268 | 
269 |     c) Convey individual copies of the object code with a copy of the
270 |     written offer to provide the Corresponding Source.  This
271 |     alternative is allowed only occasionally and noncommercially, and
272 |     only if you received the object code with such an offer, in accord
273 |     with subsection 6b.
274 | 
275 |     d) Convey the object code by offering access from a designated
276 |     place (gratis or for a charge), and offer equivalent access to the
277 |     Corresponding Source in the same way through the same place at no
278 |     further charge.  You need not require recipients to copy the
279 |     Corresponding Source along with the object code.  If the place to
280 |     copy the object code is a network server, the Corresponding Source
281 |     may be on a different server (operated by you or a third party)
282 |     that supports equivalent copying facilities, provided you maintain
283 |     clear directions next to the object code saying where to find the
284 |     Corresponding Source.  Regardless of what server hosts the
285 |     Corresponding Source, you remain obligated to ensure that it is
286 |     available for as long as needed to satisfy these requirements.
287 | 
288 |     e) Convey the object code using peer-to-peer transmission, provided
289 |     you inform other peers where the object code and Corresponding
290 |     Source of the work are being offered to the general public at no
291 |     charge under subsection 6d.
292 | 
293 |   A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 | 
297 |   A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling.  In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage.  For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product.  A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 | 
310 |   "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source.  The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 | 
318 |   If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information.  But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 | 
329 |   The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed.  Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 | 
337 |   Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 | 
343 |   7. Additional Terms.
344 | 
345 |   "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law.  If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 | 
354 |   When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it.  (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.)  You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 | 
361 |   Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 | 
365 |     a) Disclaiming warranty or limiting liability differently from the
366 |     terms of sections 15 and 16 of this License; or
367 | 
368 |     b) Requiring preservation of specified reasonable legal notices or
369 |     author attributions in that material or in the Appropriate Legal
370 |     Notices displayed by works containing it; or
371 | 
372 |     c) Prohibiting misrepresentation of the origin of that material, or
373 |     requiring that modified versions of such material be marked in
374 |     reasonable ways as different from the original version; or
375 | 
376 |     d) Limiting the use for publicity purposes of names of licensors or
377 |     authors of the material; or
378 | 
379 |     e) Declining to grant rights under trademark law for use of some
380 |     trade names, trademarks, or service marks; or
381 | 
382 |     f) Requiring indemnification of licensors and authors of that
383 |     material by anyone who conveys the material (or modified versions of
384 |     it) with contractual assumptions of liability to the recipient, for
385 |     any liability that these contractual assumptions directly impose on
386 |     those licensors and authors.
387 | 
388 |   All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10.  If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term.  If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 | 
398 |   If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 | 
403 |   Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 | 
407 |   8. Termination.
408 | 
409 |   You may not propagate or modify a covered work except as expressly
410 | provided under this License.  Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 | 
415 |   However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 | 
422 |   Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 | 
429 |   Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License.  If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 | 
435 |   9. Acceptance Not Required for Having Copies.
436 | 
437 |   You are not required to accept this License in order to receive or
438 | run a copy of the Program.  Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance.  However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work.  These actions infringe copyright if you do
443 | not accept this License.  Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 | 
446 |   10. Automatic Licensing of Downstream Recipients.
447 | 
448 |   Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License.  You are not responsible
451 | for enforcing compliance by third parties with this License.
452 | 
453 |   An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations.  If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 | 
463 |   You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License.  For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 | 
471 |   11. Patents.
472 | 
473 |   A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based.  The
475 | work thus licensed is called the contributor's "contributor version".
476 | 
477 |   A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version.  For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 | 
487 |   Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 | 
492 |   In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement).  To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 | 
499 |   If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients.  "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 | 
513 |   If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 | 
521 |   A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License.  You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 | 
536 |   Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 | 
540 |   12. No Surrender of Others' Freedom.
541 | 
542 |   If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License.  If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all.  For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 | 
552 |   13. Use with the GNU Affero General Public License.
553 | 
554 |   Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work.  The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 | 
563 |   14. Revised Versions of this License.
564 | 
565 |   The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time.  Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 | 
570 |   Each version is given a distinguishing version number.  If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation.  If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 | 
579 |   If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 | 
584 |   Later license versions may give you additional or different
585 | permissions.  However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 | 
589 |   15. Disclaimer of Warranty.
590 | 
591 |   THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 | 
600 |   16. Limitation of Liability.
601 | 
602 |   IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 | 
612 |   17. Interpretation of Sections 15 and 16.
613 | 
614 |   If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 | 
621 |                      END OF TERMS AND CONDITIONS
622 | 
623 |             How to Apply These Terms to Your New Programs
624 | 
625 |   If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 | 
629 |   To do so, attach the following notices to the program.  It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 | 
634 |     
635 |     Copyright (C)   
636 | 
637 |     This program is free software: you can redistribute it and/or modify
638 |     it under the terms of the GNU General Public License as published by
639 |     the Free Software Foundation, either version 3 of the License, or
640 |     (at your option) any later version.
641 | 
642 |     This program is distributed in the hope that it will be useful,
643 |     but WITHOUT ANY WARRANTY; without even the implied warranty of
644 |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
645 |     GNU General Public License for more details.
646 | 
647 |     You should have received a copy of the GNU General Public License
648 |     along with this program.  If not, see .
649 | 
650 | Also add information on how to contact you by electronic and paper mail.
651 | 
652 |   If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 | 
655 |       Copyright (C)   
656 |     This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 |     This is free software, and you are welcome to redistribute it
658 |     under certain conditions; type `show c' for details.
659 | 
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License.  Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 | 
664 |   You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 | 
669 |   The GNU General Public License does not permit incorporating your program
670 | into proprietary programs.  If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library.  If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License.  But first, please read
674 | .
675 | 
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
 1 | # ESPHOME esp32-2432s028r 
 2 | 
 3 | 
 4 | This start to project of https://github.com/niahane/meteo-thermostat
 5 | 
 6 | 
 7 | 
 8 | This is the program I wrote with esphome for my esp32-2432s028r very cheap board with esp32 + lcd ILI9341 2.8"
 9 | 
10 | ## Hardware
11 | ### Specifics
12 | 2.8″ 240×320 SPI ILI9341V with Touch Panel
13 | 
14 | ### Configuration:
15 | 1. ESP32 with TELEC(211-161007): Internal 4MB (32Bit) Flash
16 | 2. External 4MB (32Mbit) Flash memory, winbond 25Q32JVSlQ rev 1.  2022.09.13: U3 4MB, U4 4MB. It is now Parallel SPI.
17 | 3. LCD ( ILI9341V  ) with Touch ( U3 :  XPT2046 resistive film method)
18 | 4. Expanded IO x 2
19 |   - P3 ( GND, GPIO_35, GPIO_22, GPIO_21)
20 |   - CN1 ( GND, NC, GPIO_27, 3V3)
21 | 5. SD SLOT ( Micro SD )
22 | 6. RGB LED ( MHP5050RGBDT  )
23 |   - BLUE : GPIO_16, RED : GPIO_4, GREEN : GPIO_17
24 | 7. CDS ( GT36516  ) : GPIO_34
25 | 8. EXT Power Conn : P1 ( VIN, TX, RX, GND )
26 | 9. Audio OUT( Audio amp SC8002B ) : P4 SPEAK(2=VO2,1=VO1)
27 | 10. P1: Power Supply Base Conector
28 | 11. Included: Touch pen, 4pin External connector cable, USB Cable.
29 | 
30 | 
31 | 
32 | 
33 | 
34 | 
35 | Weather : 3 button on all page -/+ scroll page and central for active heater
36 | 
37 | Wind
38 | 
39 | This monitoring tempetarure int and externale and more 2 button +/- fore heater regulation
40 | 
41 | Status
42 | 
43 | 
44 | 
45 | Feature plus:
46 | 
47 | - touch bottom for scroll page
48 | - touch bottom dedicated some page
49 | - 4 page at moment wather - wind - homeassisant - status
50 | 
51 | 
52 | 
53 | 
54 | 
55 | 
56 | 
57 | 
58 | 
59 | 
60 | 
61 | ## Hardware
62 | ### Wiring esp32-2432s028 + BME280 sensor
63 | All credits for extended pinout explanation go to macsbug, see more on: https://macsbug.wordpress.com/2022/08/17/esp32-2432s028/
64 | 
65 |  66 | 
67 | Flashing instructions: keep the boot button pressed when you plug in the USB cable/flasher, this will allow to flash the firmware.
68 | 
69 | ## Enclosure options
70 | - https://www.thingiverse.com/thing:5680106
71 | - https://www.thingiverse.com/thing:5905855
72 | 
73 | ## Next steps
74 | 1) Improve format page
75 | 2) Add Air monitor quality page
76 | 3) Add Security page alarm
77 | 4) LVGL Library implemetation start on :
78 |    -  https://github.com/1achy/ha_deck_-ILI9341_2.8
79 |    -  https://github.com/rzeldent/esp32-smartdisplay
80 | 
81 | 
82 | 
83 | 
84 | 
85 | Greetings from Achy
86 | 
--------------------------------------------------------------------------------
/display-28.yaml:
--------------------------------------------------------------------------------
   1 | 
   2 | #Substitutions do un nome fisso a delle entita
   3 | substitutions:
   4 | #Set here your entities
   5 |   devicename: "display-28"
   6 |   ssid: Esp32-2432S028 Fallback Hotspot
   7 |   static_ip: 192.168.0.119
   8 |   gateway: 192.168.0.1
   9 |   subnet: 255.255.255.0
  10 | #Set here your entities
  11 | # Heater entity from home assistant, in my case i used a Shelly 1v3 for open/close contact of my house gas heater.
  12 | #You can also use a relay connected to a gpio but I do not recommend it especially if the load is alternating current the absorption peaks could glue the contacts of the cheap relays.
  13 | #I also noticed that the electromagnetic peak sometimes crashes the esp32. Since we are talking about a delicated system like a gas heater, it is better to opt for a certified device.
  14 |   heater: climate.cronotermostato
  15 | # Weather entity from home assistant
  16 |   weather_entity: weather.casa
  17 | # Total consumption sensor to import from home assistant i have a Shelly em with 2 amperomeric sensor, this is the first and grab the phase exiting from my energy grid
  18 |   tc: sensor.potenza_energia_elettrica_power
  19 | # Partial consumtion entity like washing machine etc to import from home assistant this is my second amperometric sensor and grab the phase of my garage
  20 |   pc: sensor.consumo_lavastoviglie_power
  21 | #Weather now icon size
  22 |   icon_xy: '65x65'
  23 | #temperatura purificatore config
  24 |   temperatura_purificatore : sensor.zhimi_airpurifier_mb3_temperature
  25 | 
  26 | globals:
  27 |   - id: menu_pos
  28 |     restore_value: no
  29 |     type: int
  30 |     initial_value: "0"
  31 | #definisco coordinate icona pagina succesiva
  32 |   - id: x_page
  33 |     type: int
  34 |     restore_value: no
  35 |     initial_value: '300'
  36 |   - id: y_page
  37 |     type: int
  38 |     restore_value: no
  39 |     initial_value: '220'
  40 | 
  41 | 
  42 | 
  43 | 
  44 | # display 320x240
  45 | 
  46 | esphome:
  47 |   name: $devicename
  48 |   friendly_name: Display 2.8
  49 | 
  50 | esp32:
  51 |   board: esp32dev
  52 |   framework:
  53 |     type: arduino
  54 | 
  55 | # Enable logging
  56 | logger:
  57 | 
  58 | # Enable Home Assistant API
  59 | api:
  60 |   encryption:
  61 |     key: "qFyyPu4U4WWJw9iV9+WlCO/aYmtA+DrovMJqmH2PHpg="
  62 |   services:
  63 |   # Receive sound from homeassistant as service (only buzzer rtttl)
  64 |     - service: play_rtttl
  65 |       variables:
  66 |         song_str: string
  67 |       then:
  68 |         - rtttl.play:
  69 |             rtttl: !lambda 'return song_str;'
  70 | 
  71 | #Buzzer
  72 | rtttl:
  73 |   output: rtttl_out
  74 | ota:
  75 |   password: "b3c2948c5c1aa9c51f9e7b8e6ff9556a"
  76 | 
  77 | wifi:
  78 |   ssid: !secret wifi_ssid
  79 |   password: !secret wifi_password
  80 | 
  81 |   # Enable fallback hotspot (captive portal) in case wifi connection fails
  82 |   ap:
  83 |     ssid: $ssid
  84 |     password: "TuMHWpSUedAq"
  85 | 
  86 | captive_portal:
  87 |  #page successiva riferimenti definita come variabile globale
  88 | 
  89 | 
  90 | spi:
  91 |   - id: lcd
  92 |     clk_pin: GPIO14
  93 |     mosi_pin: GPIO13
  94 |     miso_pin: GPIO12
  95 |   - id: touch
  96 |     clk_pin: GPIO25
  97 |     mosi_pin: GPIO32
  98 |     miso_pin: GPIO39
  99 | 
 100 | i2c:
 101 |   sda: GPIO27
 102 |   scl: GPIO22
 103 |   scan: true
 104 |   id: bus_a
 105 | 
 106 | 
 107 | #This import arduinojson library for extract weather forecasts
 108 | json:
 109 | 
 110 | #Definisco imagini
 111 | #Weather now images
 112 | image:
 113 | #0-default.png
 114 |   - file: "images/0-default.png"
 115 |     id: wpng_0
 116 |     type: RGB24
 117 |     resize: ${icon_xy}
 118 | #1-clear-night.png
 119 |   - file: "images/1-clear-night.png"
 120 |     id: wpng_1
 121 |     type: RGB24
 122 |     resize: ${icon_xy}
 123 | #2-cloudy.png
 124 |   - file: "images/2-cloudy.png"
 125 |     id: wpng_2
 126 |     type: RGB24
 127 |     resize: ${icon_xy}
 128 | #3-fog.png
 129 |   - file: "images/3-fog.png"
 130 |     id: wpng_3
 131 |     type: RGB24
 132 |     resize: ${icon_xy}
 133 | #4-hail.png
 134 |   - file: "images/4-hail.png"
 135 |     id: wpng_4
 136 |     type: RGB24
 137 |     resize: ${icon_xy}
 138 | #5-lightning.png
 139 |   - file: "images/5-lightning.png"
 140 |     id: wpng_5
 141 |     type: RGB24
 142 |     resize: ${icon_xy}
 143 | #6-lightning-rainy.png
 144 |   - file: "images/6-lightning-rainy.png"
 145 |     id: wpng_6
 146 |     type: RGB24
 147 |     resize: ${icon_xy}
 148 | #7-partlycloudy.png
 149 |   - file: "images/7-partlycloudy.png"
 150 |     id: wpng_7
 151 |     type: RGB24
 152 |     resize: ${icon_xy}
 153 | #8-pouring.png // rgb565
 154 |   - file: "images/8-pouring.png"
 155 |     id: wpng_8
 156 |     type: RGB24
 157 |     resize: ${icon_xy}
 158 | #9-rainy.png
 159 |   - file: "images/9-rainy.png"
 160 |     id: wpng_9
 161 |     type: RGB24
 162 |     resize: ${icon_xy}
 163 | #10-snowy.png
 164 |   - file: "images/10-snowy.png"
 165 |     id: wpng_10
 166 |     type: RGB24
 167 |     resize: ${icon_xy}
 168 | #11-snowy-rainy.png
 169 |   - file: "images/11-snowy-rainy.png"
 170 |     id: wpng_11
 171 |     type: RGB24
 172 |     resize: ${icon_xy}
 173 | #12-sunny.png
 174 |   - file: "images/12-sunny.png"
 175 |     id: wpng_12
 176 |     type: RGB24
 177 |     resize: ${icon_xy}
 178 | #13-windy.png
 179 |   - file: "images/13-windy.png"
 180 |     id: wpng_13
 181 |     type: RGB24
 182 |     resize: ${icon_xy}
 183 | #14-windy-variant.png
 184 |   - file: "images/14-windy-variant.png"
 185 |     id: wpng_14
 186 |     type: RGB24
 187 |     resize: ${icon_xy}
 188 | #15-exceptional.png
 189 |   - file: "images/15-exceptional.png"
 190 |     id: wpng_15
 191 |     type: RGB24
 192 |     resize: ${icon_xy}
 193 | #16-radio e power
 194 |   - file: "images/power-off-button.png"
 195 |     id: on_off_button
 196 |   - file: "images/radio-station.png"
 197 |     id: radio
 198 | 
 199 | ### CUSTOM!!
 200 | # menu spunto https://github.com/anton-semeniak/Esphome-TTGO-T-Display-Remote/blob/master/ttgo_menu.yaml
 201 | 
 202 | 
 203 | font:
 204 |   - file: "fonts/Helvetica.ttf"
 205 |     id: helvetica_48
 206 |     size: 48
 207 |   - file: "fonts/Helvetica.ttf"
 208 |     id: helvetica_36
 209 |     size: 36
 210 |   - file: "fonts/Helvetica.ttf"
 211 |     id: helvetica_24
 212 |     size: 24
 213 |   - file: "fonts/Helvetica.ttf"
 214 |     id: helvetica_12
 215 |     size: 12
 216 |   - file: "fonts/arial.ttf"
 217 |     id: font11
 218 |     size: 12
 219 |   - file: "fonts/materialdesignicons-webfont.ttf"
 220 |     id: icon_font_20
 221 |     size: 20
 222 |     glyphs: [
 223 |       "", # mdi-thermometer
 224 |       "", # mdi-water-percent
 225 |       "ﴟ", # mdi-air-filter
 226 |       "", # mdi-lightbulb-outline
 227 |       "", # mdi-lightbulb-on
 228 |        ] 
 229 | 
 230 | 
 231 | #Font declaration
 232 | #font date
 233 |   - file: 'fonts/arial-black.ttf'
 234 |     id: font1
 235 |     size: 16
 236 | #Time orologio dx
 237 |   - file: 'fonts/BebasNeue-Regular.ttf'
 238 |     id: font_clock
 239 |     size: 30
 240 | #Temperature blu  outside
 241 |   - file: 'fonts/BebasNeue-Regular.ttf'
 242 |     id: font2
 243 |     size: 35
 244 | #Location sensors
 245 |   - file: 'fonts/arial.ttf'
 246 |     id: font8
 247 |     size: 18
 248 | # Day name in forecast
 249 |   - file: 'fonts/arial-black.ttf'
 250 |     id: font_small
 251 |     size: 12
 252 | #Forecast fonts
 253 |   - file: 'fonts/arial.ttf'
 254 |     id: font_small_1
 255 |     size: 10
 256 | #Font icon various sensor
 257 |   - file: 'fonts/materialdesignicons-webfont.ttf'
 258 |     id: sensor_font
 259 |     size: 18
 260 |     glyphs:
 261 |       - "\U000F059D" # Wind
 262 |       - "\U000F050F" # Temperature
 263 |       - "\U000F04C5" # Pression
 264 |       - "\U000F058E" # Humidity
 265 |       - "\U000F0238" # Fire
 266 |       - "\U000F0F55" # Home thermometer
 267 |       - "\U000F0BB1" # next page               
 268 | 
 269 | #Big icons other home stuff
 270 |   - file: 'fonts/materialdesignicons-webfont.ttf'
 271 |     id: home_font
 272 |     size: 52
 273 |     glyphs:
 274 |       - "\U000F02DC" # At home
 275 |       - "\U000F0F9B" # Outside home
 276 |       - "\U000F0238" # Fire
 277 |       - "\U000F072A" # Washing machine on
 278 |       - "\U000F11BD" # Washing machine off
 279 |       - "\U000F0100" # Camera on
 280 |       - "\U000F05DF" # Camera off
 281 |       - "\U000F0241" # Flash
 282 |       - "\U000F0EF7" # Flash alert
 283 |       - "\U000F06D0" # Diocane
 284 |       - "\U000F0425" # OFF
 285 |       - "\U000F0415" # Plus
 286 |       - "\U000F0374" # Minus
 287 |       - "\U000F0335" # lightbulb pieno
 288 |       - "\U000F0336" # lightbulb vuoto
 289 | 
 290 | #Forecast icons
 291 |   - file: 'fonts/materialdesignicons-webfont.ttf'
 292 |     id: weather_font
 293 |     size: 50
 294 |     glyphs:
 295 |       - "\U000F0590" # weather-cloudy
 296 |       - "\U000F0F2F" # weather-cloudy-alert
 297 |       - "\U000F0E6E" # weather-cloudy-arrow-right
 298 |       - "\U000F0591" # weather-fog
 299 |       - "\U000F0592" # weather-hail
 300 |       - "\U000F0F30" # weather-hazy
 301 |       - "\U000F0898" # weather-hurricane
 302 |       - "\U000F0593" # weather-lightning
 303 |       - "\U000F067E" # weather-lightning-rainy
 304 |       - "\U000F0594" # weather-night
 305 |       - "\U000F0F31" # weather-night-partly-cloudy
 306 |       - "\U000F0595" # weather-partly-cloudy
 307 |       - "\U000F0F32" # weather-partly-lightning
 308 |       - "\U000F0F33" # weather-partly-rainy
 309 |       - "\U000F0F34" # weather-partly-snowy
 310 |       - "\U000F0F35" # weather-partly-snowy-rainy
 311 |       - "\U000F0596" # weather-pouring
 312 |       - "\U000F0597" # weather-rainy
 313 |       - "\U000F0598" # weather-snowy
 314 |       - "\U000F0F36" # weather-snowy-heavy
 315 |       - "\U000F067F" # weather-snowy-rainy
 316 |       - "\U000F0599" # weather-sunny
 317 |       - "\U000F0F37" # weather-sunny-alert
 318 |       - "\U000F14E4" # weather-sunny-off
 319 |       - "\U000F059A" # weather-sunset
 320 |       - "\U000F059B" # weather-sunset-down
 321 |       - "\U000F059C" # weather-sunset-up
 322 |       - "\U000F0F38" # weather-tornado
 323 |       - "\U000F059D" # weather-windy
 324 |       - "\U000F059E" # weather-windy-variant
 325 | 
 326 | 
 327 | 
 328 | color:
 329 |   - id: my_red
 330 |     red: 100%
 331 |     green: 0%
 332 |     blue: 0%
 333 |   - id: my_yellow
 334 |     red: 100%
 335 |     green: 100%
 336 |     blue: 0%
 337 |   - id: my_green
 338 |     red: 0%
 339 |     green: 100%
 340 |     blue: 0%
 341 |   - id: my_blue
 342 |     red: 0%
 343 |     green: 0%
 344 |     blue: 100%
 345 |   - id: my_gray
 346 |     red: 50%
 347 |     green: 50%
 348 |     blue: 50%
 349 |   - id: my_orange
 350 |     red: 100%
 351 |     green: 50%
 352 |     blue: 0%
 353 |   - id: my_teal
 354 |     red: 0%
 355 |     green: 100%
 356 |     blue: 100%
 357 |   - id: my_white
 358 |     red: 100%
 359 |     green: 100%
 360 |     blue: 100%
 361 | 
 362 | 
 363 | 
 364 | #This create the climate entity
 365 | climate:
 366 |   - platform: thermostat
 367 |     visual:
 368 |       min_temperature: 16 °C
 369 |       max_temperature: 30 °C
 370 |     name: Termostato
 371 |     id: termostato1
 372 |     sensor: temp_int
 373 |     min_heating_off_time: 30s
 374 |     min_heating_run_time: 30s
 375 |     min_idle_time: 30s
 376 |     #This is the service to call on off of the Shelly 1v3 actuator.
 377 |     heat_action:
 378 |       homeassistant.service:
 379 |         service: switch.turn_on
 380 |         data: {entity_id: $heater}
 381 |     idle_action:
 382 |       homeassistant.service:
 383 |         service: switch.turn_off
 384 |         data: {entity_id: $heater}
 385 | 
 386 | 
 387 | 
 388 | # Pulsanti touchSCREEN
 389 | 
 390 | binary_sensor:
 391 |   - platform: status
 392 |     name: "Node Status"
 393 |     id: system_status
 394 | 
 395 | #Virtual touch buttons on display 320x240
 396 | #Touch key plus pagina avanti
 397 |   - platform: touchscreen
 398 |     id: touch_key_plus
 399 |     x_min: 260
 400 |     x_max: 320
 401 |     y_min: 180
 402 |     y_max: 240
 403 |     on_press:
 404 |       - display.page.show_next: schermo  
 405 | #Touch key meno
 406 |   - platform: touchscreen
 407 |     id: touch_key_minus
 408 |     x_min: 260
 409 |     x_max: 320
 410 |     y_min: 0
 411 |     y_max: 60
 412 |     on_press:
 413 |       - display.page.show_previous: schermo  
 414 | #Touch key climate on/off
 415 |   - platform: touchscreen
 416 |     id: touch_key_climate
 417 |     x_min: 260
 418 |     x_max: 320
 419 |     y_min: 100
 420 |     y_max: 160
 421 |     # page_id: page1
 422 |     on_click:
 423 |     #Thermostat on
 424 |     - min_length: 50ms
 425 |       max_length: 500ms
 426 |       then:
 427 |         - climate.control:
 428 |             id: termostato1
 429 |             mode: "HEAT"
 430 |         - rtttl.play: 'one short:d=4,o=5,b=100:16e6'
 431 |     #Thermostat off
 432 |     - min_length: 1000ms
 433 |       max_length: 5000ms
 434 |       then:
 435 |         - climate.control:
 436 |             id: termostato1
 437 |             mode: "OFF"
 438 |         - rtttl.play: 'one short:d=4,o=5,b=100:16e6'
 439 | 
 440 | #Touch key aumenta temperatura
 441 |   - platform: touchscreen
 442 |     id: touch_key_aumenta_temp
 443 |     x_min: 160
 444 |     x_max: 240
 445 |     y_min: 180
 446 |     y_max: 240
 447 |     page_id: page3
 448 |     on_press:
 449 |       - climate.control:
 450 |           id: termostato1
 451 |           target_temperature: !lambda return (id(termostato1).target_temperature + 0.5);
 452 |       - rtttl.play: 'one short:d=4,o=5,b=100:16e6'
 453 | #Touch key mdiminuisci temperatira
 454 |   - platform: touchscreen
 455 |     id: touch_key_diminuisce_temp
 456 |     x_min: 160
 457 |     x_max: 240
 458 |     y_min: 0
 459 |     y_max: 60
 460 |     page_id: page3
 461 |     on_press:
 462 |       - climate.control:
 463 |           id: termostato1
 464 |           target_temperature: !lambda return (id(termostato1).target_temperature - 0.5);
 465 |       - rtttl.play: 'one short:d=4,o=5,b=100:16e6'      
 466 | 
 467 | 
 468 | 
 469 | 
 470 | 
 471 | 
 472 | 
 473 | 
 474 | time:
 475 |   - platform: homeassistant
 476 |     id: esptime
 477 | 
 478 | 
 479 | 
 480 | sensor:
 481 |   - platform: uptime
 482 |     # name: Uptime Sensor
 483 |     internal: True
 484 |     id: uptime_sensor
 485 |     update_interval: 1s
 486 |     on_raw_value:
 487 |       then:
 488 |         - text_sensor.template.publish:
 489 |             id: uptime_human
 490 |             state: !lambda |-
 491 |               int seconds = round(id(uptime_sensor).raw_state);
 492 |               int days = seconds / (24 * 3600);
 493 |               seconds = seconds % (24 * 3600);
 494 |               int hours = seconds / 3600;
 495 |               seconds = seconds % 3600;
 496 |               int minutes = seconds /  60;
 497 |               seconds = seconds % 60;
 498 |               return (
 499 |                 ("Uptime ") +
 500 |                 (days ? to_string(days) + "d " : "") +
 501 |                 (hours ? to_string(hours) + "h " : "") +
 502 |                 (minutes ? to_string(minutes) + "m " : "") +
 503 |                 (to_string(seconds) + "s")
 504 |               ).c_str();
 505 | 
 506 |   - platform: wifi_signal
 507 |     # name: "WiFi Signal Sensor"
 508 |     internal: True
 509 |     id: wifi_signal_sensor
 510 |     update_interval: 5s
 511 | 
 512 | #Import external temperature
 513 |   - platform: homeassistant
 514 |     id: weather_temperature
 515 |     entity_id: $weather_entity
 516 |     attribute: temperature
 517 |     internal: true
 518 | #Import Wind speed
 519 |   - platform: homeassistant
 520 |     id: vento
 521 |     entity_id: $weather_entity
 522 |     attribute: wind_speed
 523 |     internal: true
 524 | #Import Wind dir
 525 |   - platform: homeassistant
 526 |     id: wind_bearing
 527 |     entity_id: $weather_entity
 528 |     attribute: wind_bearing
 529 |     internal: true
 530 | #Import external Humidity
 531 |   - platform: homeassistant
 532 |     id: umidita_ext
 533 |     entity_id: $weather_entity
 534 |     attribute: humidity
 535 |     internal: true
 536 | #Import external pressure
 537 |   - platform: homeassistant
 538 |     id: pressure_ext
 539 |     entity_id: $weather_entity
 540 |     attribute: pressure
 541 |     internal: true
 542 | 
 543 | #Total energy in kw/h
 544 |   - platform: homeassistant
 545 |     id: consumo_t
 546 |     entity_id: $tc
 547 |     internal: true
 548 | #Lavastoviglie energy in kw/h
 549 |   - platform: homeassistant
 550 |     id: consumo_c
 551 |     entity_id: $pc
 552 |     internal: true
 553 | 
 554 | 
 555 | 
 556 | #Bme280 internal sensor su co2 BOX prendo tramite hA
 557 |   - platform: homeassistant
 558 |     id: temp_int
 559 |     entity_id: sensor.co2box_bmp280_temperature
 560 |     internal: true
 561 |   - platform: homeassistant
 562 |     id: pressione_int
 563 |     entity_id: sensor.co2box_bmp280_pressure
 564 |     internal: true
 565 |   - platform: homeassistant
 566 |     id: co2_int
 567 |     entity_id: sensor.co2box_mhz19b_carbondioxide
 568 |     internal: true
 569 | #temperatura umidita purificatore    
 570 |   - platform: homeassistant
 571 |     id: temperatura_pur
 572 |     entity_id: $temperatura_purificatore 
 573 |     internal: true
 574 |   - platform: homeassistant
 575 |     id: umidita_int
 576 |     entity_id: sensor.zhimi_airpurifier_mb3_humidity
 577 |     internal: true
 578 | #This import heater entity from home assistant (it is a shelly 1v3 that open or close the heater contact)
 579 |   - platform: homeassistant
 580 |     name: "Caldaia"
 581 |     entity_id: $heater
 582 |     id: sensor_caldaia
 583 |     internal: true
 584 | 
 585 | 
 586 | text_sensor:
 587 |   - platform: template
 588 |     # name: Uptime Human Readable
 589 |     id: uptime_human
 590 |     icon: mdi:clock-start
 591 |     internal: True
 592 | 
 593 |   - platform: wifi_info
 594 |     ip_address:
 595 |       # name: ESP IP Address
 596 |       id: ip_address
 597 |   # Sensore luci
 598 |   - platform: homeassistant
 599 |     id: luci
 600 |     entity_id: group.all_light
 601 |     name: "Luci Casa"
 602 | #Import Location
 603 |   - platform: homeassistant
 604 |     id: weather_location
 605 |     entity_id: $weather_entity
 606 |     attribute: friendly_name
 607 |     internal: true
 608 | #Import weather condition now
 609 |   - platform: homeassistant
 610 |     id: weather_condition
 611 |     entity_id: $weather_entity
 612 |     internal: true
 613 | #Import 5 day forecast
 614 |   - platform: homeassistant
 615 |     id: forecast_5
 616 |     entity_id: $weather_entity
 617 |     attribute: forecast
 618 |     internal: yes
 619 | #Import Sun state
 620 |   - platform: homeassistant
 621 |     id: sun_state
 622 |     entity_id: sun.sun
 623 |     internal: true
 624 | 
 625 | #imposto grafico pagina 4
 626 | graph:
 627 |   # Show multi-trace graph
 628 |   - id: multi_temperature_graph
 629 |     duration: 1h
 630 |     x_grid: 10min
 631 |     y_grid: 1.0     # degC/div
 632 |     width: 200
 633 |     height: 80
 634 |     max_value: 40
 635 | 
 636 |     traces:
 637 |       - sensor: temperatura_pur
 638 |         line_type: DASHED
 639 |         line_thickness: 2
 640 |         color: my_red
 641 |       - sensor: weather_temperature
 642 |         line_type: SOLID
 643 |         line_thickness: 3
 644 |         color: my_blue
 645 | 
 646 | display:
 647 |   - platform: ili9xxx
 648 |     model: ILI9341
 649 |     spi_id: lcd
 650 |     cs_pin: 15
 651 |     dc_pin: 2
 652 |     rotation: 90
 653 |     id: schermo
 654 |     pages:
 655 | 
 656 | 
 657 | # https://github.com/niahane/meteo-thermostat
 658 |     - id: page1    # pagina 1
 659 |       lambda: |-
 660 |          //Map icons//
 661 |          std::map imgDict;
 662 |          imgDict["clear-night"] = id(wpng_1);
 663 |          imgDict["cloudy"] = id(wpng_2);
 664 |          imgDict["fog"] = id(wpng_3);
 665 |          imgDict["hail"] = id(wpng_4);
 666 |          imgDict["lightning"] = id(wpng_5);
 667 |          imgDict["lightning-rainy"] = id(wpng_6);
 668 |          imgDict["partlycloudy"] = id(wpng_7);
 669 |          imgDict["pouring"] = id(wpng_8);
 670 |          imgDict["rainy"] = id(wpng_9);
 671 |          imgDict["snowy"] = id(wpng_10);
 672 |          imgDict["snowy-rainy"] = id(wpng_11);
 673 |          imgDict["sunny"] = id(wpng_12);
 674 |          imgDict["windy"] = id(wpng_13);
 675 |          imgDict["windy-variant"] = id(wpng_14);
 676 |          imgDict["exceptional"] = id(wpng_15);
 677 |          imgDict[""] = id(wpng_0);
 678 |          
 679 |          //Map conditions//
 680 |          std::map conDict;
 681 |          conDict["clear-night"] = "Notte serena";
 682 |          conDict["cloudy"] = "Nuvoloso";
 683 |          conDict["fog"] = "Nebbia";
 684 |          conDict["hail"] = "Nevischio";
 685 |          conDict["lightning"] = "Fulmini";
 686 |          conDict["lightning-rainy"] = "Fulmini/pioggia";
 687 |          conDict["partlycloudy"] = "Parz. Nuv.";
 688 |          conDict["pouring"] = "Rovescio";
 689 |          conDict["rainy"] = "Pioggia";
 690 |          conDict["snowy"] = "Neve";
 691 |          conDict["snowy-rainy"] = "Neve/pioggia";
 692 |          conDict["sunny"] = "Sereno";
 693 |          conDict["windy"] = "Vento";
 694 |          conDict["windy-variant"] = "Vento forte";
 695 |          conDict["exceptional"] = "Eccezionale";
 696 |          conDict[""] = "Sconosciuto";
 697 |          
 698 |          //Map weather fonts//
 699 |          std::map fonDict;
 700 |          fonDict["clear-night"] = "\U000F0594";
 701 |          fonDict["cloudy"] = "\U000F0590";
 702 |          fonDict["fog"] = "\U000F0591";
 703 |          fonDict["hail"] = "\U000F0592";
 704 |          fonDict["lightning"] = "\U000F0593";
 705 |          fonDict["lightning-rainy"] = "\U000F067E";
 706 |          fonDict["partlycloudy"] = "\U000F0595";
 707 |          fonDict["pouring"] = "\U000F0596";
 708 |          fonDict["rainy"] = "\U000F0597";
 709 |          fonDict["snowy"] = "\U000F0598";
 710 |          fonDict["snowy-rainy"] = "\U000F067F";
 711 |          fonDict["sunny"] = "\U000F0599";
 712 |          fonDict["windy"] = "\U000F059D";
 713 |          fonDict["windy-variant"] = "\U000F059E";
 714 |          fonDict["exceptional"] = "";
 715 |          
 716 |          //Map days of week//
 717 |          std::map dayDict;
 718 |          dayDict[1] = "Dom";
 719 |          dayDict[2] = "Lun";
 720 |          dayDict[3] = "Mar";
 721 |          dayDict[4] = "Mer";
 722 |          dayDict[5] = "Gio";
 723 |          dayDict[6] = "Ven";
 724 |          dayDict[7] = "Sab";
 725 |          
 726 |          //Map days of week extended//
 727 |          std::map dayDict_ext;
 728 |          dayDict_ext[1] = "Domenica";
 729 |          dayDict_ext[2] = "Lunedi";
 730 |          dayDict_ext[3] = "Martedi";
 731 |          dayDict_ext[4] = "Mercoledi";
 732 |          dayDict_ext[5] = "Giovedi";
 733 |          dayDict_ext[6] = "Venerdi";
 734 |          dayDict_ext[7] = "Sabato";
 735 |          
 736 |          //Map month//
 737 |          std::map monDict;
 738 |          monDict[1] = "Gennaio";
 739 |          monDict[2] = "Febbraio";
 740 |          monDict[3] = "Marzo";
 741 |          monDict[4] = "Aprile";
 742 |          monDict[5] = "Maggio";
 743 |          monDict[6] = "Giugno";
 744 |          monDict[7] = "Luglio";
 745 |          monDict[8] = "Agosto";
 746 |          monDict[9] = "Settembre";
 747 |          monDict[10] = "Ottobre";
 748 |          monDict[11] = "Novembre";
 749 |          monDict[12] = "Dicembre";
 750 |          
 751 |          //Today weekday as number
 752 |          int day = id(esptime).now().day_of_week;
 753 |          //Month as number
 754 |          auto month = id(esptime).now().month;
 755 |          //Day of month as number
 756 |          auto dom = id(esptime).now().day_of_month;
 757 |          
 758 |          //Position Y 1 day of week, day of month, month
 759 |          int h1 = 0;
 760 |          //Position Y 2 time
 761 |          int h2 = 5;
 762 |          //Position Y 3 weather icons, location, home name
 763 |          int h3 = 18;
 764 |          //Position Y 4 temperature ext, int, 
 765 |          int h4 = 30;
 766 |          //Position Y 6 humidity ext, int
 767 |          int h6 = 50;
 768 |          //Position Y 7 wind, Pressure int
 769 |          int h7 = 65;
 770 |          //Position Y wy forecast
 771 |          int wy = 85;
 772 |          //Position X wx forecast
 773 |          int wx = 32;
 774 |          //Position X 1 Weather location name, outside temp
 775 |          int w1 = 70;
 776 |          //Position Y 2 Outside sensor icon
 777 |          int w2 = 115;  
 778 |          //Position X 3 Home name, home temperature
 779 |          int w3 = 200;
 780 |          //Position X 4 Home sensor icon
 781 |          int w4 = 250;
 782 |          
 783 |          //Begin print to screen
 784 |          // Time
 785 |          it.printf((it.get_width() / 2), h1, id(font1), id(my_gray), TextAlign::TOP_CENTER, "%s %i %s", dayDict[day], dom, monDict[month]);
 786 |          it.strftime(it.get_width(), h2, id(font_clock), TextAlign::TOP_RIGHT, "%H:%M", id(esptime).now());
 787 | 
 788 |          // Weather now if it's night and sunny for display night icon
 789 |          if (id(sun_state).state == "below_horizon" && id(weather_condition).state == "sunny") {
 790 |             // Icon of weather condition night
 791 |             it.image(0, h3, imgDict["clear-night"]);
 792 |             // Translated weather condition state as text
 793 |             it.printf(0, h1, id(font_small), id(my_gray), "%s", conDict["clear-night"]);
 794 |          } else {
 795 |             // Check if weather_condition has a known state in the dictionary to prevent a crash
 796 |             if (conDict.count(id(weather_condition).state) > 0) {
 797 |                // Weather now for other cases
 798 |                // Icon of weather condition now
 799 |                it.image(0, h3, imgDict[id(weather_condition).state]);
 800 |                // Translated weather condition state as text
 801 |                it.printf(0, h1, id(font_small), id(my_gray), "%s", conDict[id(weather_condition).state]);
 802 |             } else {
 803 |                // This is printed in case weather_condition has another or unknown state
 804 |                it.image(0, h3, imgDict["exceptional"]);
 805 |                // Translated weather condition state as text
 806 |                it.printf(0, h1, id(font_small), id(my_gray), "%s", conDict["exceptional"]);
 807 |             }
 808 |          }
 809 | 
 810 |          // Outside temp
 811 |          if (id(weather_temperature).has_state()) {
 812 |             it.printf(w1, h4, id(font2), id(my_blue), "%.0f°", id(weather_temperature).state);
 813 |          }
 814 | 
 815 |          // Location
 816 |          if (id(weather_location).has_state()) {
 817 |             it.printf(w1, h3, id(font8), id(my_blue), "%s", id(weather_location).state.c_str());
 818 |          }
 819 | 
 820 |          // Inside temp
 821 |          if (id(temp_int).has_state()) {
 822 |             it.printf(w3, h3, id(font8), id(my_red), "Casa");
 823 |             it.printf(w3, h4, id(font2), id(my_red), "%.0f°", id(temp_int).state);
 824 |          }
 825 | 
 826 |          // Today wind
 827 |          if (id(vento).has_state()) {
 828 |             it.printf(w2, h7, id(sensor_font), "\U000F059D");
 829 |             it.printf(w2 + 20, h7, id(font8), id(my_gray), "%.0f km/h", id(vento).state);
 830 |          }
 831 | 
 832 |          // External humidity
 833 |          if (id(umidita_ext).has_state()) {
 834 |             it.printf(w2, h6, id(sensor_font), "\U000F058E");
 835 |             it.printf(w2 + 20, h6, id(font8), id(my_gray), "%.0f%%", id(umidita_ext).state);
 836 |          }
 837 | 
 838 |          // Internal humidity
 839 |          if (id(umidita_int).has_state()) {
 840 |             it.printf(w4, h6, id(sensor_font), "\U000F058E");
 841 |             it.printf(it.get_width(), h6, id(font8), id(my_gray), TextAlign::TOP_RIGHT, "%.0f%%", id(umidita_int).state);
 842 |          }
 843 | 
 844 |          // Atmospheric pressure
 845 |          if (id(pressione_int).has_state()) {
 846 |             it.printf(w4, h7, id(sensor_font), "\U000F04C5");
 847 |             it.printf(it.get_width(), h7, id(font8), id(my_gray), TextAlign::TOP_RIGHT, "%.0fb", id(pressione_int).state);
 848 |          }
 849 | 
 850 |          // Imported forecast json deserialization
 851 |          if (id(forecast_5).has_state()) {
 852 |             int wxx = 0;
 853 |             int wyy = 0;
 854 |             int forday = 1;
 855 |             DynamicJsonDocument doc(2048);
 856 |             deserializeJson(doc, (id(forecast_5).state.c_str()));
 857 |             JsonArray root = doc.as();
 858 |             for (int i = 0; i <= 3; ++i) {
 859 |                JsonObject root_x = root[i];
 860 |                if (i == 0) {
 861 |                      wxx = wx;
 862 |                      wyy = wy;
 863 |                      forday = (id(esptime).now().day_of_week + 1);
 864 |                }
 865 |                if (forday == 8) {
 866 |                      forday = 1;
 867 |                }
 868 |                // Day 3-4 go down
 869 |                // if (i == 2) {wyy += 38;}
 870 |                // if (i == 2) {wxx = 0;}
 871 |                std::string root_0_condition = root_x["condition"];
 872 |                float root_0_precipitation = root_x["precipitation"];
 873 |                float root_0_temperature = root_x["temperature"];
 874 |                float root_0_templow = root_x["templow"];
 875 | 
 876 |                // Print to screen
 877 |                // Translated day
 878 |                it.printf(wxx, wyy, id(font_small), id(my_green), TextAlign::TOP_CENTER, "%s", dayDict_ext[forday]);
 879 |                // Icon condition
 880 |                if (fonDict.count(root_0_condition) > 0) {
 881 |                      it.printf(wxx, wyy + 12, id(weather_font), TextAlign::TOP_CENTER, "%s", fonDict[root_0_condition.c_str()]);
 882 |                }
 883 |                // Temp max
 884 |                it.printf(wxx, wyy + 60, id(font_small_1), TextAlign::TOP_CENTER, "max %.0f°", root_0_temperature);
 885 |                // Temp min
 886 |                it.printf(wxx, wyy + 70, id(font_small_1), TextAlign::TOP_CENTER, "min %.0f°", root_0_templow);
 887 |                // Rain in mm
 888 |                it.printf(wxx, wyy + 80, id(font_small_1), TextAlign::TOP_CENTER, "%.0f mm", root_0_precipitation);
 889 |                // lines
 890 |                it.line(0, wy, it.get_width(), wy);
 891 |                it.line(0, wy + 95, it.get_width(), wy + 95);
 892 |                wxx += 85;
 893 |                forday += 1;
 894 |             }
 895 |          }
 896 |          // Heater icon
 897 |          if ((id(termostato1).mode) == 0) {
 898 |             it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0425");
 899 |           } else {
 900 |             if (id(sensor_caldaia).state) {
 901 |                it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_red), TextAlign::BASELINE_CENTER, "\U000F0238");
 902 |             } else {
 903 |                it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0238");
 904 |             }
 905 |          }
 906 | 
 907 |          // Display thermostat desired temperature
 908 |           it.printf((it.get_width() / 2), it.get_height(), id(font8), id(my_red), TextAlign::BASELINE_CENTER, "%.1f°", id(termostato1).target_temperature);
 909 | 
 910 |          // When the motion sensor sees something, draw 2 eyes
 911 |          // if (id(movimento).state) {
 912 |          //   it.printf(it.get_width(), it.get_height(), id(home_font), id(my_red), TextAlign::BASELINE_RIGHT, "\U000F06D0");
 913 |          //   it.printf(0, it.get_height(), id(home_font), id(my_red), TextAlign::BASELINE_LEFT, "\U000F06D0");
 914 |          // } else {
 915 |             // Plus Key
 916 |             it.printf(it.get_width(), it.get_height(), id(home_font), id(my_gray), TextAlign::BASELINE_RIGHT, "\U000F0415");
 917 |             // Minus key
 918 |             it.printf(0, it.get_height(), id(home_font), id(my_gray), TextAlign::BASELINE_LEFT, "\U000F0374");
 919 |          // }
 920 | 
 921 |          // Total absorption icon and value
 922 |          if (id(consumo_t).has_state()) {
 923 |             if (id(consumo_t).state < 2800) {
 924 |                it.printf((it.get_width() / 2 - 65), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0241");
 925 |                it.printf((it.get_width() / 2 - 65), it.get_height(), id(font8), id(my_blue), TextAlign::BASELINE_CENTER, "%.0f W", id(consumo_t).state);
 926 |             } else {
 927 |                it.printf((it.get_width() / 2 - 65), (it.get_height() - 15), id(home_font), id(my_red), TextAlign::BASELINE_CENTER, "\U000F0241");
 928 |                it.printf((it.get_width() / 2 - 65), it.get_height(), id(font8), id(my_red), TextAlign::BASELINE_CENTER, "%.0f W", id(consumo_t).state);
 929 |             }
 930 |          }
 931 | 
 932 |          // Washing machine status and absorption value
 933 |          if (id(consumo_c).has_state()) {
 934 |             if (id(consumo_c).state > 20) {
 935 |                it.printf((it.get_width() / 2 + 65), (it.get_height() - 15), id(home_font), id(my_red), TextAlign::BASELINE_CENTER, "\U000F072A");
 936 |                it.printf((it.get_width() / 2 + 65), it.get_height(), id(font8), id(my_red), TextAlign::BASELINE_CENTER, "%.0f W", id(consumo_c).state);
 937 |             } else {
 938 |                it.printf((it.get_width() / 2 + 65), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F11BD");
 939 |                it.printf((it.get_width() / 2 + 65), it.get_height(), id(font8), id(my_blue), TextAlign::BASELINE_CENTER, "%.0f W", id(consumo_c).state);
 940 |             }
 941 |          }
 942 | 
 943 | 
 944 | 
 945 |     - id: page2   # pagina 2
 946 |       lambda: |-
 947 | 
 948 |           // cordinate scritta direzione  vento
 949 |           int DIRx = 110;
 950 |           int DIRy = 50;
 951 |           // cordinate centro rosa venti
 952 |           int cerchio_x = 120;
 953 |           int cerchio_y = 70;
 954 |           int raggio = 50;
 955 | 
 956 | 
 957 |           // Convert wind direction da int a float con nome DIR per fare IF
 958 |           float dir = id(wind_bearing).state;
 959 | 
 960 |           // Wind DIREZIONE NANE (do il nome)
 961 |           
 962 |             std::string  name_dir;  // definisco variabile locale stringa di nome name_dir dove assegno la direzione del vento in NSEW
 963 |             std::string  name_vento;  // definisco variabile locale stringa di nome vento
 964 | 
 965 |             if (dir>0 && dir<=11) { name_dir = "N"; name_vento = "Tramontana"; }
 966 |              else {
 967 |             if (dir>11 && dir<=33) { name_dir = "NEE"; name_vento = "Tramontana"; } 
 968 |              else {
 969 |             if (dir>33 && dir<=55) { name_dir = "NE"; name_vento = "Greco"; } 
 970 |              else {
 971 |             if (dir>55 && dir<=77) { name_dir = "ENE"; name_vento = "Greco"; } 
 972 |              else {
 973 |             if (dir>77 && dir<=99) { name_dir = "E"; name_vento = "Levante"; } 
 974 |              else {
 975 |             if (dir>99 && dir<=121) { name_dir = "ESE"; name_vento = "Levante"; } 
 976 |              else {
 977 |             if (dir>121 && dir<=143) { name_dir = "SE"; name_vento = "Scirocco"; } 
 978 |              else { 
 979 |             if (dir>143 && dir<=165) { name_dir = "SSE"; name_vento = "Scirocco"; } 
 980 |              else { 
 981 |             if (dir>165 && dir<=190) { name_dir = "S"; name_vento = "Mezzogiorno"; } 
 982 |              else {   
 983 |             if (dir>190 && dir<=212) { name_dir = "SSW"; name_vento = "Mezzogiorno"; } 
 984 |              else {   
 985 |             if (dir>212 && dir<=234) { name_dir = "SW"; name_vento = "Libeccio"; } 
 986 |              else {   
 987 |             if (dir>234 && dir<=256) { name_dir = "WSW"; name_vento = "Libeccio"; } 
 988 |              else {   
 989 |             if (dir>256 && dir<=278) { name_dir = "W"; name_vento = "Ponente"; } 
 990 |              else {   
 991 |             if (dir>278 && dir<=300) { name_dir = "WNW"; name_vento = "Ponente"; } 
 992 |              else {   
 993 |             if (dir>300 && dir<=322) { name_dir = "NW"; name_vento = "Maestrale"; } 
 994 |              else {   
 995 |             if (dir>322 && dir<=344) { name_dir = "NNW"; name_vento = "Maestrale"; } 
 996 |              else {   
 997 |             if (dir>344 && dir<=360) { name_dir = "N"; name_vento = "Tramontana"; } 
 998 |              else {                   
 999 |            } } } } } } } } } } } } } } } } }
1000 | 
1001 | 
1002 |  
1003 |           // Colours - used for visiual indication of wind strength
1004 |           auto red = Color(255, 0, 0);
1005 |           auto green = Color(0, 255, 0);
1006 |           auto light_blue = Color(135, 237, 232);
1007 |           auto orange = Color(255, 170, 43);
1008 |           auto white = Color(255, 255, 255);
1009 |           auto purple = Color(97, 15, 219);
1010 |           auto grey = Color(100, 135, 135);
1011 | 
1012 |           // history arrays for trend display
1013 |           static float hist_wind[30];
1014 |           static int hist_dir[30];
1015 |           static int index=0;
1016 |           static int prev_index=29;
1017 | 
1018 | 
1019 | 
1020 | 
1021 |           // Store in array
1022 |           if ((hist_wind[prev_index]!=id(vento).state || hist_dir[prev_index]!=dir) && id(vento).state!=0) {
1023 |             hist_wind[index] = id(vento).state;
1024 |             hist_dir[index] = dir;
1025 |             index += 1;
1026 |             prev_index += 1;
1027 |             if (index==30) { index = 0; }
1028 |             if (prev_index==30) { prev_index = 0; }
1029 |           }
1030 |           // Trend maximum for last 30
1031 |           float max = hist_wind[0];
1032 |           for (size_t i = 0; i < 30; ++i) {
1033 |             if (hist_wind[i] > max) {
1034 |               max = hist_wind[i];
1035 |             }
1036 |           }
1037 | 
1038 |           // Weather data
1039 |           
1040 |           //it.strftime(5, 20, idfont11), TextAlign::TOP_LEFT, "%H:%M", id(esptime).now());
1041 |          
1042 |           it.printf(50, 20, id(font11), TextAlign::TOP_RIGHT, "%.1f°C", id(weather_temperature).state);
1043 |           it.printf(230, 20, id(font11), TextAlign::TOP_RIGHT, "%.1f hPa", id(pressure_ext).state);
1044 | 
1045 |           // it.printf(55, 20, id(font11), TextAlign::BOTTOM_RIGHT, "%s mm", conDict[id(weather_condition).state]);
1046 | 
1047 |           // Wind details
1048 |           it.printf(DIRx, DIRy, id(font8), id(my_blue), "%s", name_dir.c_str());
1049 |           it.printf(100, 95, id(font11), TextAlign::BOTTOM_LEFT, "%.1f km/h", id(vento).state);
1050 |           it.printf(100, 80, id(font11), TextAlign::BOTTOM_LEFT, "%.1f°", id(wind_bearing).state);
1051 |           it.printf(230, 120, id(font11), TextAlign::TOP_RIGHT, "TM %2.1f km/h", max);
1052 |           it.printf(50, 120, id(font11), TextAlign::TOP_RIGHT, "%s", name_vento.c_str());
1053 | 
1054 | 
1055 |       
1056 | 
1057 |           // Display trend data linea direzione vento
1058 |           for (size_t i = 0; i < 30; ++i) {
1059 |             if (hist_wind[i]>0) {
1060 |               int a = cerchio_x + ((90-(70*hist_wind[i]/max)) * (cos((hist_dir[i]-90)*PI/180)));
1061 |               int b = cerchio_y + ((90-(70*hist_wind[i]/max)) * (sin((hist_dir[i]-90)*PI/180)));
1062 |               int c = cerchio_x + (raggio * (cos((hist_dir[i]-90)*PI/180)));
1063 |               int d = cerchio_y + (raggio * (sin((hist_dir[i]-90)*PI/180)));
1064 |               it.line(a, b, c, d, grey);
1065 |             }
1066 |           }
1067 | 
1068 | 
1069 | 
1070 |           // Compass rose
1071 |           it.circle(cerchio_x, cerchio_y, raggio); //raggio 50
1072 |           it.print(cerchio_x, 20, id(font11), red, TextAlign::BOTTOM_CENTER, "N");
1073 |           it.print(cerchio_x, 120, id(font11), red, TextAlign::TOP_CENTER, "S");
1074 |           it.print(60, cerchio_y, id(font11), red, TextAlign::CENTER_RIGHT, "W");
1075 |           it.print(180, cerchio_y, id(font11), red, TextAlign::CENTER_LEFT, "E");
1076 | 
1077 | 
1078 |           // Calculate xy position to plot wind indicator
1079 |           int x = cerchio_x + (raggio * (cos((dir-90)*PI/180)));
1080 |           int y = cerchio_y + (raggio * (sin((dir-90)*PI/180)));
1081 | 
1082 |           // Wind pointerpuntatore colorato velocita
1083 |           if (id(vento).state<=11) { it.filled_circle(x, y, 7, light_blue); }
1084 |             else {
1085 |           if (id(vento).state>11 && id(vento).state<=30) { it.filled_circle(x, y, 7, green); } 
1086 |             else {
1087 |           if (id(vento).state>30 && id(vento).state<=60) { it.filled_circle(x, y, 7, orange); } 
1088 |             else {
1089 |           if (id(vento).state>60) { it.filled_circle(x, y, 7, red); } 
1090 |             } } }
1091 | 
1092 | 
1093 |           // PARTE COMUNE IN FONDO DEI PULSANTI TOUCH
1094 |           // Heater icon
1095 |           if ((id(termostato1).mode) == 0) {
1096 |              it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0425");
1097 |            } else {
1098 |              if (id(sensor_caldaia).state) {
1099 |                 it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_red), TextAlign::BASELINE_CENTER, "\U000F0238");
1100 |              } else {
1101 |                 it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0238");
1102 |              }
1103 |           }
1104 |           // Display thermostat desired temperature
1105 |            it.printf((it.get_width() / 2), it.get_height(), id(font8), id(my_red), TextAlign::BASELINE_CENTER, "%.1f°", id(termostato1).target_temperature);
1106 | 
1107 |             // Plus Key
1108 |             it.printf(it.get_width(), it.get_height(), id(home_font), id(my_gray), TextAlign::BASELINE_RIGHT, "\U000F0415");
1109 |             // Minus key
1110 |             it.printf(0, it.get_height(), id(home_font), id(my_gray), TextAlign::BASELINE_LEFT, "\U000F0374");
1111 |           // PARTE COMUNE IN FONDO DEI PULSANTI TOUCH
1112 | 
1113 |     - id: page3    # pagina 3
1114 |       lambda: |-
1115 | 
1116 |           // Draw the graph at position [x=10,y=20]
1117 |           it.graph(30, 40, id(multi_temperature_graph), my_gray);
1118 |           it.printf(20, 10, id(font8), id(my_red), TextAlign::TOP_LEFT, "Casa: %.0f°C", id(temperatura_pur).state);
1119 |           it.printf(120, 10, id(font8), id(my_blue), TextAlign::TOP_LEFT, "Esterno: %.0f°C", id(weather_temperature).state);
1120 |           // simbolo + per aumenta temperatura
1121 |           it.printf(it.get_width(), (it.get_height() - 50), id(home_font), id(my_gray), TextAlign::BASELINE_RIGHT, "\U000F0415");
1122 |           // simbolo meno per diminuisci temperatura
1123 |           it.printf(0, (it.get_height() - 50), id(home_font), id(my_gray), TextAlign::BASELINE_LEFT, "\U000F0374");
1124 | 
1125 |           // PARTE COMUNE IN FONDO DEI PULSANTI TOUCH
1126 |           // Heater icon
1127 |           if ((id(termostato1).mode) == 0) {
1128 |              it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0425");
1129 |            } else {
1130 |              if (id(sensor_caldaia).state) {
1131 |                 it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_red), TextAlign::BASELINE_CENTER, "\U000F0238");
1132 |              } else {
1133 |                 it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0238");
1134 |              }
1135 |           }
1136 |           // Display thermostat desired temperature
1137 |            it.printf((it.get_width() / 2), it.get_height(), id(font8), id(my_red), TextAlign::BASELINE_CENTER, "%.1f°", id(termostato1).target_temperature);
1138 | 
1139 |             // Plus Key
1140 |             it.printf(it.get_width(), it.get_height(), id(home_font), id(my_gray), TextAlign::BASELINE_RIGHT, "\U000F0415");
1141 |             // Minus key
1142 |             it.printf(0, it.get_height(), id(home_font), id(my_gray), TextAlign::BASELINE_LEFT, "\U000F0374");
1143 |           // PARTE COMUNE IN FONDO DEI PULSANTI TOUCH
1144 | 
1145 | 
1146 |     - id: page4    # pagina 4 
1147 |       lambda: |-
1148 |         int hs = it.get_width() / 2; // Horizontal Spacing = text data horizontal center point
1149 |         int hq = it.get_width() / 4; // text data horizontal center for two vertical lines
1150 |         int vs = it.get_height() / 8; // Vertical Center = text data vertical center point = how many lines
1151 |         int line_gap = 21; // distance of line from center of data text
1152 |         it.rectangle(0,  0, it.get_width(), it.get_height(), id(my_blue));
1153 |          it.rectangle(0, 20, it.get_width(), it.get_height(), id(my_blue));
1154 |       
1155 |         it.strftime(5, 5, id(helvetica_12), id(my_white), TextAlign::TOP_LEFT, "%H:%M:%S", id(esptime).now());
1156 |         it.print(hs, 5, id(helvetica_12), id(my_blue), TextAlign::TOP_CENTER, "${devicename}"); //print title  
1157 |       
1158 |         if (id(system_status).state) {
1159 |           it.print(it.get_width()-5, 5, id(helvetica_12), id(my_green), TextAlign::TOP_RIGHT, "Online");
1160 |         }
1161 |         else {
1162 |           it.print(it.get_width()-5, 5, id(helvetica_12), id(my_red), TextAlign::TOP_RIGHT, "Offline");
1163 |         }
1164 |         it.line(0, it.get_height()-60, it.get_width(), it.get_height()-60, id(my_blue)); // line orizzontale bottom above footer text
1165 |         it.printf(5, it.get_height()-63, id(helvetica_12), id(my_gray), TextAlign::BOTTOM_LEFT, "%s", id(uptime_human).state.c_str());
1166 |         it.printf(hs, it.get_height()-63, id(helvetica_12), id(my_gray), TextAlign::BOTTOM_CENTER, "%.0fdBm", id(wifi_signal_sensor).state);
1167 |         it.printf(it.get_width()-5, it.get_height()-63, id(helvetica_12), id(my_gray), TextAlign::BOTTOM_RIGHT, "%s", id(ip_address).state.c_str());
1168 | 
1169 | 
1170 |         it.line(0, vs * 3, it.get_width(), vs * 3, id(my_blue));
1171 |         it.line(0, vs * 4, it.get_width(), vs * 4, id(my_blue));
1172 | 
1173 | 
1174 |         // prova luci
1175 |         it.print(4, 25, id(font11), "Entita:");
1176 |         it.printf(4, 40, id(font11), id(my_yellow), "Luci: %s", id(luci).state.c_str());
1177 |         it.printf(4, 55, id(font11), id(my_yellow), "Consumo: %.0f Watt", id(consumo_t).state);
1178 |         it.print(4, 75, id(icon_font_20), "");
1179 | 
1180 | 
1181 |           // PARTE COMUNE IN FONDO DEI PULSANTI TOUCH
1182 |           // Heater icon
1183 |           if ((id(termostato1).mode) == 0) {
1184 |              it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0425");
1185 |            } else {
1186 |              if (id(sensor_caldaia).state) {
1187 |                 it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_red), TextAlign::BASELINE_CENTER, "\U000F0238");
1188 |              } else {
1189 |                 it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0238");
1190 |              }
1191 |           }
1192 |           // Display thermostat desired temperature
1193 |            it.printf((it.get_width() / 2), it.get_height(), id(font8), id(my_red), TextAlign::BASELINE_CENTER, "%.1f°", id(termostato1).target_temperature);
1194 | 
1195 |             // Plus Key
1196 |             it.printf(it.get_width(), it.get_height(), id(home_font), id(my_gray), TextAlign::BASELINE_RIGHT, "\U000F0415");
1197 |             // Minus key
1198 |             it.printf(0, it.get_height(), id(home_font), id(my_gray), TextAlign::BASELINE_LEFT, "\U000F0374");
1199 |           // PARTE COMUNE IN FONDO DEI PULSANTI TOUCH
1200 | 
1201 | 
1202 | 
1203 | 
1204 | 
1205 | 
1206 | 
1207 | 
1208 | # Define pins for backlight display and back LED1
1209 | output:
1210 |   - platform: ledc
1211 |     pin: GPIO21
1212 |     id: former_led_pin
1213 |   - platform: ledc
1214 |     id: output_red
1215 |     pin: GPIO4
1216 |     inverted: true
1217 |   - platform: ledc
1218 |     id: output_green
1219 |     pin: GPIO16
1220 |     inverted: true
1221 |   - platform: ledc
1222 |     id: output_blue
1223 |     pin: GPIO17
1224 |     inverted: true
1225 |   # speaker P4
1226 |   - platform: ledc
1227 |     pin: GPIO26
1228 |     id: rtttl_out
1229 | 
1230 | # Define a monochromatic, dimmable light for the backlight
1231 | light:
1232 |   - platform: monochromatic
1233 |     output: former_led_pin
1234 |     name: "Display Backlight"
1235 |     id: back_light
1236 |     restore_mode: ALWAYS_ON
1237 |   - platform: rgb
1238 |     name: LED
1239 |     red: output_red
1240 |     id: led
1241 |     green: output_green
1242 |     blue: output_blue
1243 |     restore_mode: ALWAYS_OFF
1244 | 
1245 | touchscreen:
1246 |   platform: xpt2046
1247 |   spi_id: touch
1248 |   cs_pin: 33
1249 |   interrupt_pin: 36
1250 |   update_interval: 50ms
1251 |   # report_interval: 1s
1252 |   threshold: 400
1253 |   calibration_x_min: 273
1254 |   calibration_x_max: 3771
1255 |   calibration_y_min: 192
1256 |   calibration_y_max: 3631
1257 |   on_touch:
1258 |     - script.stop: backlight_timer
1259 |     - script.execute: backlight_timer
1260 |   #Uncomment for calibrations
1261 |   #  - lambda: |-
1262 |   #        ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
1263 |   #            touch.x,
1264 |   #            touch.y,
1265 |   #            touch.x_raw,
1266 |   #            touch.y_raw
1267 |   #            );
1268 |   #Uncomment for calibrations
1269 | 
1270 | #This is the script for turn off the backlight after some seconds of inactivity
1271 | script:
1272 |   id: backlight_timer
1273 |   then:
1274 |   - light.turn_on:
1275 |       id: back_light
1276 |       brightness: 100%
1277 |   - delay: 20s
1278 |   - light.turn_on:
1279 |       id: back_light
1280 |       brightness: 50%
1281 |   - delay: 40s
1282 |   - light.turn_off: back_light
1283 | 
1284 | # Exposed switches.
1285 | switch:
1286 |   - platform: restart
1287 |     name: ESP32-2432S028 Restart
--------------------------------------------------------------------------------
/fonts/Arial-Black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/fonts/Arial-Black.ttf
--------------------------------------------------------------------------------
/fonts/BebasNeue-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/fonts/BebasNeue-Regular.ttf
--------------------------------------------------------------------------------
/fonts/Helvetica.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/fonts/Helvetica.ttf
--------------------------------------------------------------------------------
/fonts/arial.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/fonts/arial.ttf
--------------------------------------------------------------------------------
/fonts/lexis.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/fonts/lexis.ttf
--------------------------------------------------------------------------------
/fonts/materialdesignicons-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/fonts/materialdesignicons-webfont.ttf
--------------------------------------------------------------------------------
/fonts/slkscr.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/fonts/slkscr.ttf
--------------------------------------------------------------------------------
/fonts/times-new-roman.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/fonts/times-new-roman.ttf
--------------------------------------------------------------------------------
/images/0-default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/0-default.png
--------------------------------------------------------------------------------
/images/1-clear-night.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/1-clear-night.png
--------------------------------------------------------------------------------
/images/10-snowy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/10-snowy.png
--------------------------------------------------------------------------------
/images/11-snowy-rainy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/11-snowy-rainy.png
--------------------------------------------------------------------------------
/images/12-sunny.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/12-sunny.png
--------------------------------------------------------------------------------
/images/13-windy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/13-windy.png
--------------------------------------------------------------------------------
/images/14-windy-variant.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/14-windy-variant.png
--------------------------------------------------------------------------------
/images/15-exceptional.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/15-exceptional.png
--------------------------------------------------------------------------------
/images/16-rosa-dei-venti originale.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/16-rosa-dei-venti originale.png
--------------------------------------------------------------------------------
/images/16-rosa-dei-venti.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/16-rosa-dei-venti.png
--------------------------------------------------------------------------------
/images/2-cloudy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/2-cloudy.png
--------------------------------------------------------------------------------
/images/3-fog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/3-fog.png
--------------------------------------------------------------------------------
/images/4-hail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/4-hail.png
--------------------------------------------------------------------------------
/images/5-lightning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/5-lightning.png
--------------------------------------------------------------------------------
/images/6-lightning-rainy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/6-lightning-rainy.png
--------------------------------------------------------------------------------
/images/7-partlycloudy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/7-partlycloudy.png
--------------------------------------------------------------------------------
/images/8-pouring.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/8-pouring.png
--------------------------------------------------------------------------------
/images/9-rainy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/9-rainy.png
--------------------------------------------------------------------------------
/images/power-off-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/power-off-button.png
--------------------------------------------------------------------------------
/images/radio-station.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/radio-station.png
--------------------------------------------------------------------------------
/images/rosadeiventi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/rosadeiventi.png
--------------------------------------------------------------------------------
/readme_img/1703942900-de997d983c0182a35cf30cceca23220db6154e67.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/readme_img/1703942900-de997d983c0182a35cf30cceca23220db6154e67.jpeg
--------------------------------------------------------------------------------
/readme_img/1703943134-Screenshot-2023-12-30-at-14-31-18-733E-Esp-wroom-32-Esp32-For-Arduino-Lvgl-Wifi-28-28inch-Lcd-Tft-Module-With-Touch-Wroom-240-.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/readme_img/1703943134-Screenshot-2023-12-30-at-14-31-18-733E-Esp-wroom-32-Esp32-For-Arduino-Lvgl-Wifi-28-28inch-Lcd-Tft-Module-With-Touch-Wroom-240-.png
--------------------------------------------------------------------------------
/readme_img/1703943240-Screenshot-2023-12-30-at-14-32-26-733E-Esp-wroom-32-Esp32-For-Arduino-Lvgl-Wifi-28-28inch-Lcd-Tft-Module-With-Touch-Wroom-240-320-.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/readme_img/1703943240-Screenshot-2023-12-30-at-14-32-26-733E-Esp-wroom-32-Esp32-For-Arduino-Lvgl-Wifi-28-28inch-Lcd-Tft-Module-With-Touch-Wroom-240-320-.png
--------------------------------------------------------------------------------
/readme_img/esp32_2432s028_i2c.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/readme_img/esp32_2432s028_i2c.jpg
--------------------------------------------------------------------------------
/readme_img/example.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/readme_img/example.jpg
--------------------------------------------------------------------------------
/readme_img/grafico.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/readme_img/grafico.jpg
--------------------------------------------------------------------------------
/readme_img/status.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/readme_img/status.jpg
--------------------------------------------------------------------------------
/readme_img/vento.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/readme_img/vento.jpg
--------------------------------------------------------------------------------
/secrets.yaml:
--------------------------------------------------------------------------------
1 | wifi_ssid: "your ssid"
2 | wifi_password: "your wifi wpa psk"
3 | fallpass: "your fallback password"
4 | 
--------------------------------------------------------------------------------
66 | 
67 | Flashing instructions: keep the boot button pressed when you plug in the USB cable/flasher, this will allow to flash the firmware.
68 | 
69 | ## Enclosure options
70 | - https://www.thingiverse.com/thing:5680106
71 | - https://www.thingiverse.com/thing:5905855
72 | 
73 | ## Next steps
74 | 1) Improve format page
75 | 2) Add Air monitor quality page
76 | 3) Add Security page alarm
77 | 4) LVGL Library implemetation start on :
78 |    -  https://github.com/1achy/ha_deck_-ILI9341_2.8
79 |    -  https://github.com/rzeldent/esp32-smartdisplay
80 | 
81 | 
82 | 
83 | 
84 | 
85 | Greetings from Achy
86 | 
--------------------------------------------------------------------------------
/display-28.yaml:
--------------------------------------------------------------------------------
   1 | 
   2 | #Substitutions do un nome fisso a delle entita
   3 | substitutions:
   4 | #Set here your entities
   5 |   devicename: "display-28"
   6 |   ssid: Esp32-2432S028 Fallback Hotspot
   7 |   static_ip: 192.168.0.119
   8 |   gateway: 192.168.0.1
   9 |   subnet: 255.255.255.0
  10 | #Set here your entities
  11 | # Heater entity from home assistant, in my case i used a Shelly 1v3 for open/close contact of my house gas heater.
  12 | #You can also use a relay connected to a gpio but I do not recommend it especially if the load is alternating current the absorption peaks could glue the contacts of the cheap relays.
  13 | #I also noticed that the electromagnetic peak sometimes crashes the esp32. Since we are talking about a delicated system like a gas heater, it is better to opt for a certified device.
  14 |   heater: climate.cronotermostato
  15 | # Weather entity from home assistant
  16 |   weather_entity: weather.casa
  17 | # Total consumption sensor to import from home assistant i have a Shelly em with 2 amperomeric sensor, this is the first and grab the phase exiting from my energy grid
  18 |   tc: sensor.potenza_energia_elettrica_power
  19 | # Partial consumtion entity like washing machine etc to import from home assistant this is my second amperometric sensor and grab the phase of my garage
  20 |   pc: sensor.consumo_lavastoviglie_power
  21 | #Weather now icon size
  22 |   icon_xy: '65x65'
  23 | #temperatura purificatore config
  24 |   temperatura_purificatore : sensor.zhimi_airpurifier_mb3_temperature
  25 | 
  26 | globals:
  27 |   - id: menu_pos
  28 |     restore_value: no
  29 |     type: int
  30 |     initial_value: "0"
  31 | #definisco coordinate icona pagina succesiva
  32 |   - id: x_page
  33 |     type: int
  34 |     restore_value: no
  35 |     initial_value: '300'
  36 |   - id: y_page
  37 |     type: int
  38 |     restore_value: no
  39 |     initial_value: '220'
  40 | 
  41 | 
  42 | 
  43 | 
  44 | # display 320x240
  45 | 
  46 | esphome:
  47 |   name: $devicename
  48 |   friendly_name: Display 2.8
  49 | 
  50 | esp32:
  51 |   board: esp32dev
  52 |   framework:
  53 |     type: arduino
  54 | 
  55 | # Enable logging
  56 | logger:
  57 | 
  58 | # Enable Home Assistant API
  59 | api:
  60 |   encryption:
  61 |     key: "qFyyPu4U4WWJw9iV9+WlCO/aYmtA+DrovMJqmH2PHpg="
  62 |   services:
  63 |   # Receive sound from homeassistant as service (only buzzer rtttl)
  64 |     - service: play_rtttl
  65 |       variables:
  66 |         song_str: string
  67 |       then:
  68 |         - rtttl.play:
  69 |             rtttl: !lambda 'return song_str;'
  70 | 
  71 | #Buzzer
  72 | rtttl:
  73 |   output: rtttl_out
  74 | ota:
  75 |   password: "b3c2948c5c1aa9c51f9e7b8e6ff9556a"
  76 | 
  77 | wifi:
  78 |   ssid: !secret wifi_ssid
  79 |   password: !secret wifi_password
  80 | 
  81 |   # Enable fallback hotspot (captive portal) in case wifi connection fails
  82 |   ap:
  83 |     ssid: $ssid
  84 |     password: "TuMHWpSUedAq"
  85 | 
  86 | captive_portal:
  87 |  #page successiva riferimenti definita come variabile globale
  88 | 
  89 | 
  90 | spi:
  91 |   - id: lcd
  92 |     clk_pin: GPIO14
  93 |     mosi_pin: GPIO13
  94 |     miso_pin: GPIO12
  95 |   - id: touch
  96 |     clk_pin: GPIO25
  97 |     mosi_pin: GPIO32
  98 |     miso_pin: GPIO39
  99 | 
 100 | i2c:
 101 |   sda: GPIO27
 102 |   scl: GPIO22
 103 |   scan: true
 104 |   id: bus_a
 105 | 
 106 | 
 107 | #This import arduinojson library for extract weather forecasts
 108 | json:
 109 | 
 110 | #Definisco imagini
 111 | #Weather now images
 112 | image:
 113 | #0-default.png
 114 |   - file: "images/0-default.png"
 115 |     id: wpng_0
 116 |     type: RGB24
 117 |     resize: ${icon_xy}
 118 | #1-clear-night.png
 119 |   - file: "images/1-clear-night.png"
 120 |     id: wpng_1
 121 |     type: RGB24
 122 |     resize: ${icon_xy}
 123 | #2-cloudy.png
 124 |   - file: "images/2-cloudy.png"
 125 |     id: wpng_2
 126 |     type: RGB24
 127 |     resize: ${icon_xy}
 128 | #3-fog.png
 129 |   - file: "images/3-fog.png"
 130 |     id: wpng_3
 131 |     type: RGB24
 132 |     resize: ${icon_xy}
 133 | #4-hail.png
 134 |   - file: "images/4-hail.png"
 135 |     id: wpng_4
 136 |     type: RGB24
 137 |     resize: ${icon_xy}
 138 | #5-lightning.png
 139 |   - file: "images/5-lightning.png"
 140 |     id: wpng_5
 141 |     type: RGB24
 142 |     resize: ${icon_xy}
 143 | #6-lightning-rainy.png
 144 |   - file: "images/6-lightning-rainy.png"
 145 |     id: wpng_6
 146 |     type: RGB24
 147 |     resize: ${icon_xy}
 148 | #7-partlycloudy.png
 149 |   - file: "images/7-partlycloudy.png"
 150 |     id: wpng_7
 151 |     type: RGB24
 152 |     resize: ${icon_xy}
 153 | #8-pouring.png // rgb565
 154 |   - file: "images/8-pouring.png"
 155 |     id: wpng_8
 156 |     type: RGB24
 157 |     resize: ${icon_xy}
 158 | #9-rainy.png
 159 |   - file: "images/9-rainy.png"
 160 |     id: wpng_9
 161 |     type: RGB24
 162 |     resize: ${icon_xy}
 163 | #10-snowy.png
 164 |   - file: "images/10-snowy.png"
 165 |     id: wpng_10
 166 |     type: RGB24
 167 |     resize: ${icon_xy}
 168 | #11-snowy-rainy.png
 169 |   - file: "images/11-snowy-rainy.png"
 170 |     id: wpng_11
 171 |     type: RGB24
 172 |     resize: ${icon_xy}
 173 | #12-sunny.png
 174 |   - file: "images/12-sunny.png"
 175 |     id: wpng_12
 176 |     type: RGB24
 177 |     resize: ${icon_xy}
 178 | #13-windy.png
 179 |   - file: "images/13-windy.png"
 180 |     id: wpng_13
 181 |     type: RGB24
 182 |     resize: ${icon_xy}
 183 | #14-windy-variant.png
 184 |   - file: "images/14-windy-variant.png"
 185 |     id: wpng_14
 186 |     type: RGB24
 187 |     resize: ${icon_xy}
 188 | #15-exceptional.png
 189 |   - file: "images/15-exceptional.png"
 190 |     id: wpng_15
 191 |     type: RGB24
 192 |     resize: ${icon_xy}
 193 | #16-radio e power
 194 |   - file: "images/power-off-button.png"
 195 |     id: on_off_button
 196 |   - file: "images/radio-station.png"
 197 |     id: radio
 198 | 
 199 | ### CUSTOM!!
 200 | # menu spunto https://github.com/anton-semeniak/Esphome-TTGO-T-Display-Remote/blob/master/ttgo_menu.yaml
 201 | 
 202 | 
 203 | font:
 204 |   - file: "fonts/Helvetica.ttf"
 205 |     id: helvetica_48
 206 |     size: 48
 207 |   - file: "fonts/Helvetica.ttf"
 208 |     id: helvetica_36
 209 |     size: 36
 210 |   - file: "fonts/Helvetica.ttf"
 211 |     id: helvetica_24
 212 |     size: 24
 213 |   - file: "fonts/Helvetica.ttf"
 214 |     id: helvetica_12
 215 |     size: 12
 216 |   - file: "fonts/arial.ttf"
 217 |     id: font11
 218 |     size: 12
 219 |   - file: "fonts/materialdesignicons-webfont.ttf"
 220 |     id: icon_font_20
 221 |     size: 20
 222 |     glyphs: [
 223 |       "", # mdi-thermometer
 224 |       "", # mdi-water-percent
 225 |       "ﴟ", # mdi-air-filter
 226 |       "", # mdi-lightbulb-outline
 227 |       "", # mdi-lightbulb-on
 228 |        ] 
 229 | 
 230 | 
 231 | #Font declaration
 232 | #font date
 233 |   - file: 'fonts/arial-black.ttf'
 234 |     id: font1
 235 |     size: 16
 236 | #Time orologio dx
 237 |   - file: 'fonts/BebasNeue-Regular.ttf'
 238 |     id: font_clock
 239 |     size: 30
 240 | #Temperature blu  outside
 241 |   - file: 'fonts/BebasNeue-Regular.ttf'
 242 |     id: font2
 243 |     size: 35
 244 | #Location sensors
 245 |   - file: 'fonts/arial.ttf'
 246 |     id: font8
 247 |     size: 18
 248 | # Day name in forecast
 249 |   - file: 'fonts/arial-black.ttf'
 250 |     id: font_small
 251 |     size: 12
 252 | #Forecast fonts
 253 |   - file: 'fonts/arial.ttf'
 254 |     id: font_small_1
 255 |     size: 10
 256 | #Font icon various sensor
 257 |   - file: 'fonts/materialdesignicons-webfont.ttf'
 258 |     id: sensor_font
 259 |     size: 18
 260 |     glyphs:
 261 |       - "\U000F059D" # Wind
 262 |       - "\U000F050F" # Temperature
 263 |       - "\U000F04C5" # Pression
 264 |       - "\U000F058E" # Humidity
 265 |       - "\U000F0238" # Fire
 266 |       - "\U000F0F55" # Home thermometer
 267 |       - "\U000F0BB1" # next page               
 268 | 
 269 | #Big icons other home stuff
 270 |   - file: 'fonts/materialdesignicons-webfont.ttf'
 271 |     id: home_font
 272 |     size: 52
 273 |     glyphs:
 274 |       - "\U000F02DC" # At home
 275 |       - "\U000F0F9B" # Outside home
 276 |       - "\U000F0238" # Fire
 277 |       - "\U000F072A" # Washing machine on
 278 |       - "\U000F11BD" # Washing machine off
 279 |       - "\U000F0100" # Camera on
 280 |       - "\U000F05DF" # Camera off
 281 |       - "\U000F0241" # Flash
 282 |       - "\U000F0EF7" # Flash alert
 283 |       - "\U000F06D0" # Diocane
 284 |       - "\U000F0425" # OFF
 285 |       - "\U000F0415" # Plus
 286 |       - "\U000F0374" # Minus
 287 |       - "\U000F0335" # lightbulb pieno
 288 |       - "\U000F0336" # lightbulb vuoto
 289 | 
 290 | #Forecast icons
 291 |   - file: 'fonts/materialdesignicons-webfont.ttf'
 292 |     id: weather_font
 293 |     size: 50
 294 |     glyphs:
 295 |       - "\U000F0590" # weather-cloudy
 296 |       - "\U000F0F2F" # weather-cloudy-alert
 297 |       - "\U000F0E6E" # weather-cloudy-arrow-right
 298 |       - "\U000F0591" # weather-fog
 299 |       - "\U000F0592" # weather-hail
 300 |       - "\U000F0F30" # weather-hazy
 301 |       - "\U000F0898" # weather-hurricane
 302 |       - "\U000F0593" # weather-lightning
 303 |       - "\U000F067E" # weather-lightning-rainy
 304 |       - "\U000F0594" # weather-night
 305 |       - "\U000F0F31" # weather-night-partly-cloudy
 306 |       - "\U000F0595" # weather-partly-cloudy
 307 |       - "\U000F0F32" # weather-partly-lightning
 308 |       - "\U000F0F33" # weather-partly-rainy
 309 |       - "\U000F0F34" # weather-partly-snowy
 310 |       - "\U000F0F35" # weather-partly-snowy-rainy
 311 |       - "\U000F0596" # weather-pouring
 312 |       - "\U000F0597" # weather-rainy
 313 |       - "\U000F0598" # weather-snowy
 314 |       - "\U000F0F36" # weather-snowy-heavy
 315 |       - "\U000F067F" # weather-snowy-rainy
 316 |       - "\U000F0599" # weather-sunny
 317 |       - "\U000F0F37" # weather-sunny-alert
 318 |       - "\U000F14E4" # weather-sunny-off
 319 |       - "\U000F059A" # weather-sunset
 320 |       - "\U000F059B" # weather-sunset-down
 321 |       - "\U000F059C" # weather-sunset-up
 322 |       - "\U000F0F38" # weather-tornado
 323 |       - "\U000F059D" # weather-windy
 324 |       - "\U000F059E" # weather-windy-variant
 325 | 
 326 | 
 327 | 
 328 | color:
 329 |   - id: my_red
 330 |     red: 100%
 331 |     green: 0%
 332 |     blue: 0%
 333 |   - id: my_yellow
 334 |     red: 100%
 335 |     green: 100%
 336 |     blue: 0%
 337 |   - id: my_green
 338 |     red: 0%
 339 |     green: 100%
 340 |     blue: 0%
 341 |   - id: my_blue
 342 |     red: 0%
 343 |     green: 0%
 344 |     blue: 100%
 345 |   - id: my_gray
 346 |     red: 50%
 347 |     green: 50%
 348 |     blue: 50%
 349 |   - id: my_orange
 350 |     red: 100%
 351 |     green: 50%
 352 |     blue: 0%
 353 |   - id: my_teal
 354 |     red: 0%
 355 |     green: 100%
 356 |     blue: 100%
 357 |   - id: my_white
 358 |     red: 100%
 359 |     green: 100%
 360 |     blue: 100%
 361 | 
 362 | 
 363 | 
 364 | #This create the climate entity
 365 | climate:
 366 |   - platform: thermostat
 367 |     visual:
 368 |       min_temperature: 16 °C
 369 |       max_temperature: 30 °C
 370 |     name: Termostato
 371 |     id: termostato1
 372 |     sensor: temp_int
 373 |     min_heating_off_time: 30s
 374 |     min_heating_run_time: 30s
 375 |     min_idle_time: 30s
 376 |     #This is the service to call on off of the Shelly 1v3 actuator.
 377 |     heat_action:
 378 |       homeassistant.service:
 379 |         service: switch.turn_on
 380 |         data: {entity_id: $heater}
 381 |     idle_action:
 382 |       homeassistant.service:
 383 |         service: switch.turn_off
 384 |         data: {entity_id: $heater}
 385 | 
 386 | 
 387 | 
 388 | # Pulsanti touchSCREEN
 389 | 
 390 | binary_sensor:
 391 |   - platform: status
 392 |     name: "Node Status"
 393 |     id: system_status
 394 | 
 395 | #Virtual touch buttons on display 320x240
 396 | #Touch key plus pagina avanti
 397 |   - platform: touchscreen
 398 |     id: touch_key_plus
 399 |     x_min: 260
 400 |     x_max: 320
 401 |     y_min: 180
 402 |     y_max: 240
 403 |     on_press:
 404 |       - display.page.show_next: schermo  
 405 | #Touch key meno
 406 |   - platform: touchscreen
 407 |     id: touch_key_minus
 408 |     x_min: 260
 409 |     x_max: 320
 410 |     y_min: 0
 411 |     y_max: 60
 412 |     on_press:
 413 |       - display.page.show_previous: schermo  
 414 | #Touch key climate on/off
 415 |   - platform: touchscreen
 416 |     id: touch_key_climate
 417 |     x_min: 260
 418 |     x_max: 320
 419 |     y_min: 100
 420 |     y_max: 160
 421 |     # page_id: page1
 422 |     on_click:
 423 |     #Thermostat on
 424 |     - min_length: 50ms
 425 |       max_length: 500ms
 426 |       then:
 427 |         - climate.control:
 428 |             id: termostato1
 429 |             mode: "HEAT"
 430 |         - rtttl.play: 'one short:d=4,o=5,b=100:16e6'
 431 |     #Thermostat off
 432 |     - min_length: 1000ms
 433 |       max_length: 5000ms
 434 |       then:
 435 |         - climate.control:
 436 |             id: termostato1
 437 |             mode: "OFF"
 438 |         - rtttl.play: 'one short:d=4,o=5,b=100:16e6'
 439 | 
 440 | #Touch key aumenta temperatura
 441 |   - platform: touchscreen
 442 |     id: touch_key_aumenta_temp
 443 |     x_min: 160
 444 |     x_max: 240
 445 |     y_min: 180
 446 |     y_max: 240
 447 |     page_id: page3
 448 |     on_press:
 449 |       - climate.control:
 450 |           id: termostato1
 451 |           target_temperature: !lambda return (id(termostato1).target_temperature + 0.5);
 452 |       - rtttl.play: 'one short:d=4,o=5,b=100:16e6'
 453 | #Touch key mdiminuisci temperatira
 454 |   - platform: touchscreen
 455 |     id: touch_key_diminuisce_temp
 456 |     x_min: 160
 457 |     x_max: 240
 458 |     y_min: 0
 459 |     y_max: 60
 460 |     page_id: page3
 461 |     on_press:
 462 |       - climate.control:
 463 |           id: termostato1
 464 |           target_temperature: !lambda return (id(termostato1).target_temperature - 0.5);
 465 |       - rtttl.play: 'one short:d=4,o=5,b=100:16e6'      
 466 | 
 467 | 
 468 | 
 469 | 
 470 | 
 471 | 
 472 | 
 473 | 
 474 | time:
 475 |   - platform: homeassistant
 476 |     id: esptime
 477 | 
 478 | 
 479 | 
 480 | sensor:
 481 |   - platform: uptime
 482 |     # name: Uptime Sensor
 483 |     internal: True
 484 |     id: uptime_sensor
 485 |     update_interval: 1s
 486 |     on_raw_value:
 487 |       then:
 488 |         - text_sensor.template.publish:
 489 |             id: uptime_human
 490 |             state: !lambda |-
 491 |               int seconds = round(id(uptime_sensor).raw_state);
 492 |               int days = seconds / (24 * 3600);
 493 |               seconds = seconds % (24 * 3600);
 494 |               int hours = seconds / 3600;
 495 |               seconds = seconds % 3600;
 496 |               int minutes = seconds /  60;
 497 |               seconds = seconds % 60;
 498 |               return (
 499 |                 ("Uptime ") +
 500 |                 (days ? to_string(days) + "d " : "") +
 501 |                 (hours ? to_string(hours) + "h " : "") +
 502 |                 (minutes ? to_string(minutes) + "m " : "") +
 503 |                 (to_string(seconds) + "s")
 504 |               ).c_str();
 505 | 
 506 |   - platform: wifi_signal
 507 |     # name: "WiFi Signal Sensor"
 508 |     internal: True
 509 |     id: wifi_signal_sensor
 510 |     update_interval: 5s
 511 | 
 512 | #Import external temperature
 513 |   - platform: homeassistant
 514 |     id: weather_temperature
 515 |     entity_id: $weather_entity
 516 |     attribute: temperature
 517 |     internal: true
 518 | #Import Wind speed
 519 |   - platform: homeassistant
 520 |     id: vento
 521 |     entity_id: $weather_entity
 522 |     attribute: wind_speed
 523 |     internal: true
 524 | #Import Wind dir
 525 |   - platform: homeassistant
 526 |     id: wind_bearing
 527 |     entity_id: $weather_entity
 528 |     attribute: wind_bearing
 529 |     internal: true
 530 | #Import external Humidity
 531 |   - platform: homeassistant
 532 |     id: umidita_ext
 533 |     entity_id: $weather_entity
 534 |     attribute: humidity
 535 |     internal: true
 536 | #Import external pressure
 537 |   - platform: homeassistant
 538 |     id: pressure_ext
 539 |     entity_id: $weather_entity
 540 |     attribute: pressure
 541 |     internal: true
 542 | 
 543 | #Total energy in kw/h
 544 |   - platform: homeassistant
 545 |     id: consumo_t
 546 |     entity_id: $tc
 547 |     internal: true
 548 | #Lavastoviglie energy in kw/h
 549 |   - platform: homeassistant
 550 |     id: consumo_c
 551 |     entity_id: $pc
 552 |     internal: true
 553 | 
 554 | 
 555 | 
 556 | #Bme280 internal sensor su co2 BOX prendo tramite hA
 557 |   - platform: homeassistant
 558 |     id: temp_int
 559 |     entity_id: sensor.co2box_bmp280_temperature
 560 |     internal: true
 561 |   - platform: homeassistant
 562 |     id: pressione_int
 563 |     entity_id: sensor.co2box_bmp280_pressure
 564 |     internal: true
 565 |   - platform: homeassistant
 566 |     id: co2_int
 567 |     entity_id: sensor.co2box_mhz19b_carbondioxide
 568 |     internal: true
 569 | #temperatura umidita purificatore    
 570 |   - platform: homeassistant
 571 |     id: temperatura_pur
 572 |     entity_id: $temperatura_purificatore 
 573 |     internal: true
 574 |   - platform: homeassistant
 575 |     id: umidita_int
 576 |     entity_id: sensor.zhimi_airpurifier_mb3_humidity
 577 |     internal: true
 578 | #This import heater entity from home assistant (it is a shelly 1v3 that open or close the heater contact)
 579 |   - platform: homeassistant
 580 |     name: "Caldaia"
 581 |     entity_id: $heater
 582 |     id: sensor_caldaia
 583 |     internal: true
 584 | 
 585 | 
 586 | text_sensor:
 587 |   - platform: template
 588 |     # name: Uptime Human Readable
 589 |     id: uptime_human
 590 |     icon: mdi:clock-start
 591 |     internal: True
 592 | 
 593 |   - platform: wifi_info
 594 |     ip_address:
 595 |       # name: ESP IP Address
 596 |       id: ip_address
 597 |   # Sensore luci
 598 |   - platform: homeassistant
 599 |     id: luci
 600 |     entity_id: group.all_light
 601 |     name: "Luci Casa"
 602 | #Import Location
 603 |   - platform: homeassistant
 604 |     id: weather_location
 605 |     entity_id: $weather_entity
 606 |     attribute: friendly_name
 607 |     internal: true
 608 | #Import weather condition now
 609 |   - platform: homeassistant
 610 |     id: weather_condition
 611 |     entity_id: $weather_entity
 612 |     internal: true
 613 | #Import 5 day forecast
 614 |   - platform: homeassistant
 615 |     id: forecast_5
 616 |     entity_id: $weather_entity
 617 |     attribute: forecast
 618 |     internal: yes
 619 | #Import Sun state
 620 |   - platform: homeassistant
 621 |     id: sun_state
 622 |     entity_id: sun.sun
 623 |     internal: true
 624 | 
 625 | #imposto grafico pagina 4
 626 | graph:
 627 |   # Show multi-trace graph
 628 |   - id: multi_temperature_graph
 629 |     duration: 1h
 630 |     x_grid: 10min
 631 |     y_grid: 1.0     # degC/div
 632 |     width: 200
 633 |     height: 80
 634 |     max_value: 40
 635 | 
 636 |     traces:
 637 |       - sensor: temperatura_pur
 638 |         line_type: DASHED
 639 |         line_thickness: 2
 640 |         color: my_red
 641 |       - sensor: weather_temperature
 642 |         line_type: SOLID
 643 |         line_thickness: 3
 644 |         color: my_blue
 645 | 
 646 | display:
 647 |   - platform: ili9xxx
 648 |     model: ILI9341
 649 |     spi_id: lcd
 650 |     cs_pin: 15
 651 |     dc_pin: 2
 652 |     rotation: 90
 653 |     id: schermo
 654 |     pages:
 655 | 
 656 | 
 657 | # https://github.com/niahane/meteo-thermostat
 658 |     - id: page1    # pagina 1
 659 |       lambda: |-
 660 |          //Map icons//
 661 |          std::map imgDict;
 662 |          imgDict["clear-night"] = id(wpng_1);
 663 |          imgDict["cloudy"] = id(wpng_2);
 664 |          imgDict["fog"] = id(wpng_3);
 665 |          imgDict["hail"] = id(wpng_4);
 666 |          imgDict["lightning"] = id(wpng_5);
 667 |          imgDict["lightning-rainy"] = id(wpng_6);
 668 |          imgDict["partlycloudy"] = id(wpng_7);
 669 |          imgDict["pouring"] = id(wpng_8);
 670 |          imgDict["rainy"] = id(wpng_9);
 671 |          imgDict["snowy"] = id(wpng_10);
 672 |          imgDict["snowy-rainy"] = id(wpng_11);
 673 |          imgDict["sunny"] = id(wpng_12);
 674 |          imgDict["windy"] = id(wpng_13);
 675 |          imgDict["windy-variant"] = id(wpng_14);
 676 |          imgDict["exceptional"] = id(wpng_15);
 677 |          imgDict[""] = id(wpng_0);
 678 |          
 679 |          //Map conditions//
 680 |          std::map conDict;
 681 |          conDict["clear-night"] = "Notte serena";
 682 |          conDict["cloudy"] = "Nuvoloso";
 683 |          conDict["fog"] = "Nebbia";
 684 |          conDict["hail"] = "Nevischio";
 685 |          conDict["lightning"] = "Fulmini";
 686 |          conDict["lightning-rainy"] = "Fulmini/pioggia";
 687 |          conDict["partlycloudy"] = "Parz. Nuv.";
 688 |          conDict["pouring"] = "Rovescio";
 689 |          conDict["rainy"] = "Pioggia";
 690 |          conDict["snowy"] = "Neve";
 691 |          conDict["snowy-rainy"] = "Neve/pioggia";
 692 |          conDict["sunny"] = "Sereno";
 693 |          conDict["windy"] = "Vento";
 694 |          conDict["windy-variant"] = "Vento forte";
 695 |          conDict["exceptional"] = "Eccezionale";
 696 |          conDict[""] = "Sconosciuto";
 697 |          
 698 |          //Map weather fonts//
 699 |          std::map fonDict;
 700 |          fonDict["clear-night"] = "\U000F0594";
 701 |          fonDict["cloudy"] = "\U000F0590";
 702 |          fonDict["fog"] = "\U000F0591";
 703 |          fonDict["hail"] = "\U000F0592";
 704 |          fonDict["lightning"] = "\U000F0593";
 705 |          fonDict["lightning-rainy"] = "\U000F067E";
 706 |          fonDict["partlycloudy"] = "\U000F0595";
 707 |          fonDict["pouring"] = "\U000F0596";
 708 |          fonDict["rainy"] = "\U000F0597";
 709 |          fonDict["snowy"] = "\U000F0598";
 710 |          fonDict["snowy-rainy"] = "\U000F067F";
 711 |          fonDict["sunny"] = "\U000F0599";
 712 |          fonDict["windy"] = "\U000F059D";
 713 |          fonDict["windy-variant"] = "\U000F059E";
 714 |          fonDict["exceptional"] = "";
 715 |          
 716 |          //Map days of week//
 717 |          std::map dayDict;
 718 |          dayDict[1] = "Dom";
 719 |          dayDict[2] = "Lun";
 720 |          dayDict[3] = "Mar";
 721 |          dayDict[4] = "Mer";
 722 |          dayDict[5] = "Gio";
 723 |          dayDict[6] = "Ven";
 724 |          dayDict[7] = "Sab";
 725 |          
 726 |          //Map days of week extended//
 727 |          std::map dayDict_ext;
 728 |          dayDict_ext[1] = "Domenica";
 729 |          dayDict_ext[2] = "Lunedi";
 730 |          dayDict_ext[3] = "Martedi";
 731 |          dayDict_ext[4] = "Mercoledi";
 732 |          dayDict_ext[5] = "Giovedi";
 733 |          dayDict_ext[6] = "Venerdi";
 734 |          dayDict_ext[7] = "Sabato";
 735 |          
 736 |          //Map month//
 737 |          std::map monDict;
 738 |          monDict[1] = "Gennaio";
 739 |          monDict[2] = "Febbraio";
 740 |          monDict[3] = "Marzo";
 741 |          monDict[4] = "Aprile";
 742 |          monDict[5] = "Maggio";
 743 |          monDict[6] = "Giugno";
 744 |          monDict[7] = "Luglio";
 745 |          monDict[8] = "Agosto";
 746 |          monDict[9] = "Settembre";
 747 |          monDict[10] = "Ottobre";
 748 |          monDict[11] = "Novembre";
 749 |          monDict[12] = "Dicembre";
 750 |          
 751 |          //Today weekday as number
 752 |          int day = id(esptime).now().day_of_week;
 753 |          //Month as number
 754 |          auto month = id(esptime).now().month;
 755 |          //Day of month as number
 756 |          auto dom = id(esptime).now().day_of_month;
 757 |          
 758 |          //Position Y 1 day of week, day of month, month
 759 |          int h1 = 0;
 760 |          //Position Y 2 time
 761 |          int h2 = 5;
 762 |          //Position Y 3 weather icons, location, home name
 763 |          int h3 = 18;
 764 |          //Position Y 4 temperature ext, int, 
 765 |          int h4 = 30;
 766 |          //Position Y 6 humidity ext, int
 767 |          int h6 = 50;
 768 |          //Position Y 7 wind, Pressure int
 769 |          int h7 = 65;
 770 |          //Position Y wy forecast
 771 |          int wy = 85;
 772 |          //Position X wx forecast
 773 |          int wx = 32;
 774 |          //Position X 1 Weather location name, outside temp
 775 |          int w1 = 70;
 776 |          //Position Y 2 Outside sensor icon
 777 |          int w2 = 115;  
 778 |          //Position X 3 Home name, home temperature
 779 |          int w3 = 200;
 780 |          //Position X 4 Home sensor icon
 781 |          int w4 = 250;
 782 |          
 783 |          //Begin print to screen
 784 |          // Time
 785 |          it.printf((it.get_width() / 2), h1, id(font1), id(my_gray), TextAlign::TOP_CENTER, "%s %i %s", dayDict[day], dom, monDict[month]);
 786 |          it.strftime(it.get_width(), h2, id(font_clock), TextAlign::TOP_RIGHT, "%H:%M", id(esptime).now());
 787 | 
 788 |          // Weather now if it's night and sunny for display night icon
 789 |          if (id(sun_state).state == "below_horizon" && id(weather_condition).state == "sunny") {
 790 |             // Icon of weather condition night
 791 |             it.image(0, h3, imgDict["clear-night"]);
 792 |             // Translated weather condition state as text
 793 |             it.printf(0, h1, id(font_small), id(my_gray), "%s", conDict["clear-night"]);
 794 |          } else {
 795 |             // Check if weather_condition has a known state in the dictionary to prevent a crash
 796 |             if (conDict.count(id(weather_condition).state) > 0) {
 797 |                // Weather now for other cases
 798 |                // Icon of weather condition now
 799 |                it.image(0, h3, imgDict[id(weather_condition).state]);
 800 |                // Translated weather condition state as text
 801 |                it.printf(0, h1, id(font_small), id(my_gray), "%s", conDict[id(weather_condition).state]);
 802 |             } else {
 803 |                // This is printed in case weather_condition has another or unknown state
 804 |                it.image(0, h3, imgDict["exceptional"]);
 805 |                // Translated weather condition state as text
 806 |                it.printf(0, h1, id(font_small), id(my_gray), "%s", conDict["exceptional"]);
 807 |             }
 808 |          }
 809 | 
 810 |          // Outside temp
 811 |          if (id(weather_temperature).has_state()) {
 812 |             it.printf(w1, h4, id(font2), id(my_blue), "%.0f°", id(weather_temperature).state);
 813 |          }
 814 | 
 815 |          // Location
 816 |          if (id(weather_location).has_state()) {
 817 |             it.printf(w1, h3, id(font8), id(my_blue), "%s", id(weather_location).state.c_str());
 818 |          }
 819 | 
 820 |          // Inside temp
 821 |          if (id(temp_int).has_state()) {
 822 |             it.printf(w3, h3, id(font8), id(my_red), "Casa");
 823 |             it.printf(w3, h4, id(font2), id(my_red), "%.0f°", id(temp_int).state);
 824 |          }
 825 | 
 826 |          // Today wind
 827 |          if (id(vento).has_state()) {
 828 |             it.printf(w2, h7, id(sensor_font), "\U000F059D");
 829 |             it.printf(w2 + 20, h7, id(font8), id(my_gray), "%.0f km/h", id(vento).state);
 830 |          }
 831 | 
 832 |          // External humidity
 833 |          if (id(umidita_ext).has_state()) {
 834 |             it.printf(w2, h6, id(sensor_font), "\U000F058E");
 835 |             it.printf(w2 + 20, h6, id(font8), id(my_gray), "%.0f%%", id(umidita_ext).state);
 836 |          }
 837 | 
 838 |          // Internal humidity
 839 |          if (id(umidita_int).has_state()) {
 840 |             it.printf(w4, h6, id(sensor_font), "\U000F058E");
 841 |             it.printf(it.get_width(), h6, id(font8), id(my_gray), TextAlign::TOP_RIGHT, "%.0f%%", id(umidita_int).state);
 842 |          }
 843 | 
 844 |          // Atmospheric pressure
 845 |          if (id(pressione_int).has_state()) {
 846 |             it.printf(w4, h7, id(sensor_font), "\U000F04C5");
 847 |             it.printf(it.get_width(), h7, id(font8), id(my_gray), TextAlign::TOP_RIGHT, "%.0fb", id(pressione_int).state);
 848 |          }
 849 | 
 850 |          // Imported forecast json deserialization
 851 |          if (id(forecast_5).has_state()) {
 852 |             int wxx = 0;
 853 |             int wyy = 0;
 854 |             int forday = 1;
 855 |             DynamicJsonDocument doc(2048);
 856 |             deserializeJson(doc, (id(forecast_5).state.c_str()));
 857 |             JsonArray root = doc.as();
 858 |             for (int i = 0; i <= 3; ++i) {
 859 |                JsonObject root_x = root[i];
 860 |                if (i == 0) {
 861 |                      wxx = wx;
 862 |                      wyy = wy;
 863 |                      forday = (id(esptime).now().day_of_week + 1);
 864 |                }
 865 |                if (forday == 8) {
 866 |                      forday = 1;
 867 |                }
 868 |                // Day 3-4 go down
 869 |                // if (i == 2) {wyy += 38;}
 870 |                // if (i == 2) {wxx = 0;}
 871 |                std::string root_0_condition = root_x["condition"];
 872 |                float root_0_precipitation = root_x["precipitation"];
 873 |                float root_0_temperature = root_x["temperature"];
 874 |                float root_0_templow = root_x["templow"];
 875 | 
 876 |                // Print to screen
 877 |                // Translated day
 878 |                it.printf(wxx, wyy, id(font_small), id(my_green), TextAlign::TOP_CENTER, "%s", dayDict_ext[forday]);
 879 |                // Icon condition
 880 |                if (fonDict.count(root_0_condition) > 0) {
 881 |                      it.printf(wxx, wyy + 12, id(weather_font), TextAlign::TOP_CENTER, "%s", fonDict[root_0_condition.c_str()]);
 882 |                }
 883 |                // Temp max
 884 |                it.printf(wxx, wyy + 60, id(font_small_1), TextAlign::TOP_CENTER, "max %.0f°", root_0_temperature);
 885 |                // Temp min
 886 |                it.printf(wxx, wyy + 70, id(font_small_1), TextAlign::TOP_CENTER, "min %.0f°", root_0_templow);
 887 |                // Rain in mm
 888 |                it.printf(wxx, wyy + 80, id(font_small_1), TextAlign::TOP_CENTER, "%.0f mm", root_0_precipitation);
 889 |                // lines
 890 |                it.line(0, wy, it.get_width(), wy);
 891 |                it.line(0, wy + 95, it.get_width(), wy + 95);
 892 |                wxx += 85;
 893 |                forday += 1;
 894 |             }
 895 |          }
 896 |          // Heater icon
 897 |          if ((id(termostato1).mode) == 0) {
 898 |             it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0425");
 899 |           } else {
 900 |             if (id(sensor_caldaia).state) {
 901 |                it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_red), TextAlign::BASELINE_CENTER, "\U000F0238");
 902 |             } else {
 903 |                it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0238");
 904 |             }
 905 |          }
 906 | 
 907 |          // Display thermostat desired temperature
 908 |           it.printf((it.get_width() / 2), it.get_height(), id(font8), id(my_red), TextAlign::BASELINE_CENTER, "%.1f°", id(termostato1).target_temperature);
 909 | 
 910 |          // When the motion sensor sees something, draw 2 eyes
 911 |          // if (id(movimento).state) {
 912 |          //   it.printf(it.get_width(), it.get_height(), id(home_font), id(my_red), TextAlign::BASELINE_RIGHT, "\U000F06D0");
 913 |          //   it.printf(0, it.get_height(), id(home_font), id(my_red), TextAlign::BASELINE_LEFT, "\U000F06D0");
 914 |          // } else {
 915 |             // Plus Key
 916 |             it.printf(it.get_width(), it.get_height(), id(home_font), id(my_gray), TextAlign::BASELINE_RIGHT, "\U000F0415");
 917 |             // Minus key
 918 |             it.printf(0, it.get_height(), id(home_font), id(my_gray), TextAlign::BASELINE_LEFT, "\U000F0374");
 919 |          // }
 920 | 
 921 |          // Total absorption icon and value
 922 |          if (id(consumo_t).has_state()) {
 923 |             if (id(consumo_t).state < 2800) {
 924 |                it.printf((it.get_width() / 2 - 65), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0241");
 925 |                it.printf((it.get_width() / 2 - 65), it.get_height(), id(font8), id(my_blue), TextAlign::BASELINE_CENTER, "%.0f W", id(consumo_t).state);
 926 |             } else {
 927 |                it.printf((it.get_width() / 2 - 65), (it.get_height() - 15), id(home_font), id(my_red), TextAlign::BASELINE_CENTER, "\U000F0241");
 928 |                it.printf((it.get_width() / 2 - 65), it.get_height(), id(font8), id(my_red), TextAlign::BASELINE_CENTER, "%.0f W", id(consumo_t).state);
 929 |             }
 930 |          }
 931 | 
 932 |          // Washing machine status and absorption value
 933 |          if (id(consumo_c).has_state()) {
 934 |             if (id(consumo_c).state > 20) {
 935 |                it.printf((it.get_width() / 2 + 65), (it.get_height() - 15), id(home_font), id(my_red), TextAlign::BASELINE_CENTER, "\U000F072A");
 936 |                it.printf((it.get_width() / 2 + 65), it.get_height(), id(font8), id(my_red), TextAlign::BASELINE_CENTER, "%.0f W", id(consumo_c).state);
 937 |             } else {
 938 |                it.printf((it.get_width() / 2 + 65), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F11BD");
 939 |                it.printf((it.get_width() / 2 + 65), it.get_height(), id(font8), id(my_blue), TextAlign::BASELINE_CENTER, "%.0f W", id(consumo_c).state);
 940 |             }
 941 |          }
 942 | 
 943 | 
 944 | 
 945 |     - id: page2   # pagina 2
 946 |       lambda: |-
 947 | 
 948 |           // cordinate scritta direzione  vento
 949 |           int DIRx = 110;
 950 |           int DIRy = 50;
 951 |           // cordinate centro rosa venti
 952 |           int cerchio_x = 120;
 953 |           int cerchio_y = 70;
 954 |           int raggio = 50;
 955 | 
 956 | 
 957 |           // Convert wind direction da int a float con nome DIR per fare IF
 958 |           float dir = id(wind_bearing).state;
 959 | 
 960 |           // Wind DIREZIONE NANE (do il nome)
 961 |           
 962 |             std::string  name_dir;  // definisco variabile locale stringa di nome name_dir dove assegno la direzione del vento in NSEW
 963 |             std::string  name_vento;  // definisco variabile locale stringa di nome vento
 964 | 
 965 |             if (dir>0 && dir<=11) { name_dir = "N"; name_vento = "Tramontana"; }
 966 |              else {
 967 |             if (dir>11 && dir<=33) { name_dir = "NEE"; name_vento = "Tramontana"; } 
 968 |              else {
 969 |             if (dir>33 && dir<=55) { name_dir = "NE"; name_vento = "Greco"; } 
 970 |              else {
 971 |             if (dir>55 && dir<=77) { name_dir = "ENE"; name_vento = "Greco"; } 
 972 |              else {
 973 |             if (dir>77 && dir<=99) { name_dir = "E"; name_vento = "Levante"; } 
 974 |              else {
 975 |             if (dir>99 && dir<=121) { name_dir = "ESE"; name_vento = "Levante"; } 
 976 |              else {
 977 |             if (dir>121 && dir<=143) { name_dir = "SE"; name_vento = "Scirocco"; } 
 978 |              else { 
 979 |             if (dir>143 && dir<=165) { name_dir = "SSE"; name_vento = "Scirocco"; } 
 980 |              else { 
 981 |             if (dir>165 && dir<=190) { name_dir = "S"; name_vento = "Mezzogiorno"; } 
 982 |              else {   
 983 |             if (dir>190 && dir<=212) { name_dir = "SSW"; name_vento = "Mezzogiorno"; } 
 984 |              else {   
 985 |             if (dir>212 && dir<=234) { name_dir = "SW"; name_vento = "Libeccio"; } 
 986 |              else {   
 987 |             if (dir>234 && dir<=256) { name_dir = "WSW"; name_vento = "Libeccio"; } 
 988 |              else {   
 989 |             if (dir>256 && dir<=278) { name_dir = "W"; name_vento = "Ponente"; } 
 990 |              else {   
 991 |             if (dir>278 && dir<=300) { name_dir = "WNW"; name_vento = "Ponente"; } 
 992 |              else {   
 993 |             if (dir>300 && dir<=322) { name_dir = "NW"; name_vento = "Maestrale"; } 
 994 |              else {   
 995 |             if (dir>322 && dir<=344) { name_dir = "NNW"; name_vento = "Maestrale"; } 
 996 |              else {   
 997 |             if (dir>344 && dir<=360) { name_dir = "N"; name_vento = "Tramontana"; } 
 998 |              else {                   
 999 |            } } } } } } } } } } } } } } } } }
1000 | 
1001 | 
1002 |  
1003 |           // Colours - used for visiual indication of wind strength
1004 |           auto red = Color(255, 0, 0);
1005 |           auto green = Color(0, 255, 0);
1006 |           auto light_blue = Color(135, 237, 232);
1007 |           auto orange = Color(255, 170, 43);
1008 |           auto white = Color(255, 255, 255);
1009 |           auto purple = Color(97, 15, 219);
1010 |           auto grey = Color(100, 135, 135);
1011 | 
1012 |           // history arrays for trend display
1013 |           static float hist_wind[30];
1014 |           static int hist_dir[30];
1015 |           static int index=0;
1016 |           static int prev_index=29;
1017 | 
1018 | 
1019 | 
1020 | 
1021 |           // Store in array
1022 |           if ((hist_wind[prev_index]!=id(vento).state || hist_dir[prev_index]!=dir) && id(vento).state!=0) {
1023 |             hist_wind[index] = id(vento).state;
1024 |             hist_dir[index] = dir;
1025 |             index += 1;
1026 |             prev_index += 1;
1027 |             if (index==30) { index = 0; }
1028 |             if (prev_index==30) { prev_index = 0; }
1029 |           }
1030 |           // Trend maximum for last 30
1031 |           float max = hist_wind[0];
1032 |           for (size_t i = 0; i < 30; ++i) {
1033 |             if (hist_wind[i] > max) {
1034 |               max = hist_wind[i];
1035 |             }
1036 |           }
1037 | 
1038 |           // Weather data
1039 |           
1040 |           //it.strftime(5, 20, idfont11), TextAlign::TOP_LEFT, "%H:%M", id(esptime).now());
1041 |          
1042 |           it.printf(50, 20, id(font11), TextAlign::TOP_RIGHT, "%.1f°C", id(weather_temperature).state);
1043 |           it.printf(230, 20, id(font11), TextAlign::TOP_RIGHT, "%.1f hPa", id(pressure_ext).state);
1044 | 
1045 |           // it.printf(55, 20, id(font11), TextAlign::BOTTOM_RIGHT, "%s mm", conDict[id(weather_condition).state]);
1046 | 
1047 |           // Wind details
1048 |           it.printf(DIRx, DIRy, id(font8), id(my_blue), "%s", name_dir.c_str());
1049 |           it.printf(100, 95, id(font11), TextAlign::BOTTOM_LEFT, "%.1f km/h", id(vento).state);
1050 |           it.printf(100, 80, id(font11), TextAlign::BOTTOM_LEFT, "%.1f°", id(wind_bearing).state);
1051 |           it.printf(230, 120, id(font11), TextAlign::TOP_RIGHT, "TM %2.1f km/h", max);
1052 |           it.printf(50, 120, id(font11), TextAlign::TOP_RIGHT, "%s", name_vento.c_str());
1053 | 
1054 | 
1055 |       
1056 | 
1057 |           // Display trend data linea direzione vento
1058 |           for (size_t i = 0; i < 30; ++i) {
1059 |             if (hist_wind[i]>0) {
1060 |               int a = cerchio_x + ((90-(70*hist_wind[i]/max)) * (cos((hist_dir[i]-90)*PI/180)));
1061 |               int b = cerchio_y + ((90-(70*hist_wind[i]/max)) * (sin((hist_dir[i]-90)*PI/180)));
1062 |               int c = cerchio_x + (raggio * (cos((hist_dir[i]-90)*PI/180)));
1063 |               int d = cerchio_y + (raggio * (sin((hist_dir[i]-90)*PI/180)));
1064 |               it.line(a, b, c, d, grey);
1065 |             }
1066 |           }
1067 | 
1068 | 
1069 | 
1070 |           // Compass rose
1071 |           it.circle(cerchio_x, cerchio_y, raggio); //raggio 50
1072 |           it.print(cerchio_x, 20, id(font11), red, TextAlign::BOTTOM_CENTER, "N");
1073 |           it.print(cerchio_x, 120, id(font11), red, TextAlign::TOP_CENTER, "S");
1074 |           it.print(60, cerchio_y, id(font11), red, TextAlign::CENTER_RIGHT, "W");
1075 |           it.print(180, cerchio_y, id(font11), red, TextAlign::CENTER_LEFT, "E");
1076 | 
1077 | 
1078 |           // Calculate xy position to plot wind indicator
1079 |           int x = cerchio_x + (raggio * (cos((dir-90)*PI/180)));
1080 |           int y = cerchio_y + (raggio * (sin((dir-90)*PI/180)));
1081 | 
1082 |           // Wind pointerpuntatore colorato velocita
1083 |           if (id(vento).state<=11) { it.filled_circle(x, y, 7, light_blue); }
1084 |             else {
1085 |           if (id(vento).state>11 && id(vento).state<=30) { it.filled_circle(x, y, 7, green); } 
1086 |             else {
1087 |           if (id(vento).state>30 && id(vento).state<=60) { it.filled_circle(x, y, 7, orange); } 
1088 |             else {
1089 |           if (id(vento).state>60) { it.filled_circle(x, y, 7, red); } 
1090 |             } } }
1091 | 
1092 | 
1093 |           // PARTE COMUNE IN FONDO DEI PULSANTI TOUCH
1094 |           // Heater icon
1095 |           if ((id(termostato1).mode) == 0) {
1096 |              it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0425");
1097 |            } else {
1098 |              if (id(sensor_caldaia).state) {
1099 |                 it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_red), TextAlign::BASELINE_CENTER, "\U000F0238");
1100 |              } else {
1101 |                 it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0238");
1102 |              }
1103 |           }
1104 |           // Display thermostat desired temperature
1105 |            it.printf((it.get_width() / 2), it.get_height(), id(font8), id(my_red), TextAlign::BASELINE_CENTER, "%.1f°", id(termostato1).target_temperature);
1106 | 
1107 |             // Plus Key
1108 |             it.printf(it.get_width(), it.get_height(), id(home_font), id(my_gray), TextAlign::BASELINE_RIGHT, "\U000F0415");
1109 |             // Minus key
1110 |             it.printf(0, it.get_height(), id(home_font), id(my_gray), TextAlign::BASELINE_LEFT, "\U000F0374");
1111 |           // PARTE COMUNE IN FONDO DEI PULSANTI TOUCH
1112 | 
1113 |     - id: page3    # pagina 3
1114 |       lambda: |-
1115 | 
1116 |           // Draw the graph at position [x=10,y=20]
1117 |           it.graph(30, 40, id(multi_temperature_graph), my_gray);
1118 |           it.printf(20, 10, id(font8), id(my_red), TextAlign::TOP_LEFT, "Casa: %.0f°C", id(temperatura_pur).state);
1119 |           it.printf(120, 10, id(font8), id(my_blue), TextAlign::TOP_LEFT, "Esterno: %.0f°C", id(weather_temperature).state);
1120 |           // simbolo + per aumenta temperatura
1121 |           it.printf(it.get_width(), (it.get_height() - 50), id(home_font), id(my_gray), TextAlign::BASELINE_RIGHT, "\U000F0415");
1122 |           // simbolo meno per diminuisci temperatura
1123 |           it.printf(0, (it.get_height() - 50), id(home_font), id(my_gray), TextAlign::BASELINE_LEFT, "\U000F0374");
1124 | 
1125 |           // PARTE COMUNE IN FONDO DEI PULSANTI TOUCH
1126 |           // Heater icon
1127 |           if ((id(termostato1).mode) == 0) {
1128 |              it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0425");
1129 |            } else {
1130 |              if (id(sensor_caldaia).state) {
1131 |                 it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_red), TextAlign::BASELINE_CENTER, "\U000F0238");
1132 |              } else {
1133 |                 it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0238");
1134 |              }
1135 |           }
1136 |           // Display thermostat desired temperature
1137 |            it.printf((it.get_width() / 2), it.get_height(), id(font8), id(my_red), TextAlign::BASELINE_CENTER, "%.1f°", id(termostato1).target_temperature);
1138 | 
1139 |             // Plus Key
1140 |             it.printf(it.get_width(), it.get_height(), id(home_font), id(my_gray), TextAlign::BASELINE_RIGHT, "\U000F0415");
1141 |             // Minus key
1142 |             it.printf(0, it.get_height(), id(home_font), id(my_gray), TextAlign::BASELINE_LEFT, "\U000F0374");
1143 |           // PARTE COMUNE IN FONDO DEI PULSANTI TOUCH
1144 | 
1145 | 
1146 |     - id: page4    # pagina 4 
1147 |       lambda: |-
1148 |         int hs = it.get_width() / 2; // Horizontal Spacing = text data horizontal center point
1149 |         int hq = it.get_width() / 4; // text data horizontal center for two vertical lines
1150 |         int vs = it.get_height() / 8; // Vertical Center = text data vertical center point = how many lines
1151 |         int line_gap = 21; // distance of line from center of data text
1152 |         it.rectangle(0,  0, it.get_width(), it.get_height(), id(my_blue));
1153 |          it.rectangle(0, 20, it.get_width(), it.get_height(), id(my_blue));
1154 |       
1155 |         it.strftime(5, 5, id(helvetica_12), id(my_white), TextAlign::TOP_LEFT, "%H:%M:%S", id(esptime).now());
1156 |         it.print(hs, 5, id(helvetica_12), id(my_blue), TextAlign::TOP_CENTER, "${devicename}"); //print title  
1157 |       
1158 |         if (id(system_status).state) {
1159 |           it.print(it.get_width()-5, 5, id(helvetica_12), id(my_green), TextAlign::TOP_RIGHT, "Online");
1160 |         }
1161 |         else {
1162 |           it.print(it.get_width()-5, 5, id(helvetica_12), id(my_red), TextAlign::TOP_RIGHT, "Offline");
1163 |         }
1164 |         it.line(0, it.get_height()-60, it.get_width(), it.get_height()-60, id(my_blue)); // line orizzontale bottom above footer text
1165 |         it.printf(5, it.get_height()-63, id(helvetica_12), id(my_gray), TextAlign::BOTTOM_LEFT, "%s", id(uptime_human).state.c_str());
1166 |         it.printf(hs, it.get_height()-63, id(helvetica_12), id(my_gray), TextAlign::BOTTOM_CENTER, "%.0fdBm", id(wifi_signal_sensor).state);
1167 |         it.printf(it.get_width()-5, it.get_height()-63, id(helvetica_12), id(my_gray), TextAlign::BOTTOM_RIGHT, "%s", id(ip_address).state.c_str());
1168 | 
1169 | 
1170 |         it.line(0, vs * 3, it.get_width(), vs * 3, id(my_blue));
1171 |         it.line(0, vs * 4, it.get_width(), vs * 4, id(my_blue));
1172 | 
1173 | 
1174 |         // prova luci
1175 |         it.print(4, 25, id(font11), "Entita:");
1176 |         it.printf(4, 40, id(font11), id(my_yellow), "Luci: %s", id(luci).state.c_str());
1177 |         it.printf(4, 55, id(font11), id(my_yellow), "Consumo: %.0f Watt", id(consumo_t).state);
1178 |         it.print(4, 75, id(icon_font_20), "");
1179 | 
1180 | 
1181 |           // PARTE COMUNE IN FONDO DEI PULSANTI TOUCH
1182 |           // Heater icon
1183 |           if ((id(termostato1).mode) == 0) {
1184 |              it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0425");
1185 |            } else {
1186 |              if (id(sensor_caldaia).state) {
1187 |                 it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_red), TextAlign::BASELINE_CENTER, "\U000F0238");
1188 |              } else {
1189 |                 it.printf((it.get_width() / 2), (it.get_height() - 15), id(home_font), id(my_gray), TextAlign::BASELINE_CENTER, "\U000F0238");
1190 |              }
1191 |           }
1192 |           // Display thermostat desired temperature
1193 |            it.printf((it.get_width() / 2), it.get_height(), id(font8), id(my_red), TextAlign::BASELINE_CENTER, "%.1f°", id(termostato1).target_temperature);
1194 | 
1195 |             // Plus Key
1196 |             it.printf(it.get_width(), it.get_height(), id(home_font), id(my_gray), TextAlign::BASELINE_RIGHT, "\U000F0415");
1197 |             // Minus key
1198 |             it.printf(0, it.get_height(), id(home_font), id(my_gray), TextAlign::BASELINE_LEFT, "\U000F0374");
1199 |           // PARTE COMUNE IN FONDO DEI PULSANTI TOUCH
1200 | 
1201 | 
1202 | 
1203 | 
1204 | 
1205 | 
1206 | 
1207 | 
1208 | # Define pins for backlight display and back LED1
1209 | output:
1210 |   - platform: ledc
1211 |     pin: GPIO21
1212 |     id: former_led_pin
1213 |   - platform: ledc
1214 |     id: output_red
1215 |     pin: GPIO4
1216 |     inverted: true
1217 |   - platform: ledc
1218 |     id: output_green
1219 |     pin: GPIO16
1220 |     inverted: true
1221 |   - platform: ledc
1222 |     id: output_blue
1223 |     pin: GPIO17
1224 |     inverted: true
1225 |   # speaker P4
1226 |   - platform: ledc
1227 |     pin: GPIO26
1228 |     id: rtttl_out
1229 | 
1230 | # Define a monochromatic, dimmable light for the backlight
1231 | light:
1232 |   - platform: monochromatic
1233 |     output: former_led_pin
1234 |     name: "Display Backlight"
1235 |     id: back_light
1236 |     restore_mode: ALWAYS_ON
1237 |   - platform: rgb
1238 |     name: LED
1239 |     red: output_red
1240 |     id: led
1241 |     green: output_green
1242 |     blue: output_blue
1243 |     restore_mode: ALWAYS_OFF
1244 | 
1245 | touchscreen:
1246 |   platform: xpt2046
1247 |   spi_id: touch
1248 |   cs_pin: 33
1249 |   interrupt_pin: 36
1250 |   update_interval: 50ms
1251 |   # report_interval: 1s
1252 |   threshold: 400
1253 |   calibration_x_min: 273
1254 |   calibration_x_max: 3771
1255 |   calibration_y_min: 192
1256 |   calibration_y_max: 3631
1257 |   on_touch:
1258 |     - script.stop: backlight_timer
1259 |     - script.execute: backlight_timer
1260 |   #Uncomment for calibrations
1261 |   #  - lambda: |-
1262 |   #        ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
1263 |   #            touch.x,
1264 |   #            touch.y,
1265 |   #            touch.x_raw,
1266 |   #            touch.y_raw
1267 |   #            );
1268 |   #Uncomment for calibrations
1269 | 
1270 | #This is the script for turn off the backlight after some seconds of inactivity
1271 | script:
1272 |   id: backlight_timer
1273 |   then:
1274 |   - light.turn_on:
1275 |       id: back_light
1276 |       brightness: 100%
1277 |   - delay: 20s
1278 |   - light.turn_on:
1279 |       id: back_light
1280 |       brightness: 50%
1281 |   - delay: 40s
1282 |   - light.turn_off: back_light
1283 | 
1284 | # Exposed switches.
1285 | switch:
1286 |   - platform: restart
1287 |     name: ESP32-2432S028 Restart
--------------------------------------------------------------------------------
/fonts/Arial-Black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/fonts/Arial-Black.ttf
--------------------------------------------------------------------------------
/fonts/BebasNeue-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/fonts/BebasNeue-Regular.ttf
--------------------------------------------------------------------------------
/fonts/Helvetica.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/fonts/Helvetica.ttf
--------------------------------------------------------------------------------
/fonts/arial.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/fonts/arial.ttf
--------------------------------------------------------------------------------
/fonts/lexis.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/fonts/lexis.ttf
--------------------------------------------------------------------------------
/fonts/materialdesignicons-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/fonts/materialdesignicons-webfont.ttf
--------------------------------------------------------------------------------
/fonts/slkscr.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/fonts/slkscr.ttf
--------------------------------------------------------------------------------
/fonts/times-new-roman.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/fonts/times-new-roman.ttf
--------------------------------------------------------------------------------
/images/0-default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/0-default.png
--------------------------------------------------------------------------------
/images/1-clear-night.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/1-clear-night.png
--------------------------------------------------------------------------------
/images/10-snowy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/10-snowy.png
--------------------------------------------------------------------------------
/images/11-snowy-rainy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/11-snowy-rainy.png
--------------------------------------------------------------------------------
/images/12-sunny.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/12-sunny.png
--------------------------------------------------------------------------------
/images/13-windy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/13-windy.png
--------------------------------------------------------------------------------
/images/14-windy-variant.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/14-windy-variant.png
--------------------------------------------------------------------------------
/images/15-exceptional.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/15-exceptional.png
--------------------------------------------------------------------------------
/images/16-rosa-dei-venti originale.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/16-rosa-dei-venti originale.png
--------------------------------------------------------------------------------
/images/16-rosa-dei-venti.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/16-rosa-dei-venti.png
--------------------------------------------------------------------------------
/images/2-cloudy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/2-cloudy.png
--------------------------------------------------------------------------------
/images/3-fog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/3-fog.png
--------------------------------------------------------------------------------
/images/4-hail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/4-hail.png
--------------------------------------------------------------------------------
/images/5-lightning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/5-lightning.png
--------------------------------------------------------------------------------
/images/6-lightning-rainy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/6-lightning-rainy.png
--------------------------------------------------------------------------------
/images/7-partlycloudy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/7-partlycloudy.png
--------------------------------------------------------------------------------
/images/8-pouring.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/8-pouring.png
--------------------------------------------------------------------------------
/images/9-rainy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/9-rainy.png
--------------------------------------------------------------------------------
/images/power-off-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/power-off-button.png
--------------------------------------------------------------------------------
/images/radio-station.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/radio-station.png
--------------------------------------------------------------------------------
/images/rosadeiventi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/images/rosadeiventi.png
--------------------------------------------------------------------------------
/readme_img/1703942900-de997d983c0182a35cf30cceca23220db6154e67.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/readme_img/1703942900-de997d983c0182a35cf30cceca23220db6154e67.jpeg
--------------------------------------------------------------------------------
/readme_img/1703943134-Screenshot-2023-12-30-at-14-31-18-733E-Esp-wroom-32-Esp32-For-Arduino-Lvgl-Wifi-28-28inch-Lcd-Tft-Module-With-Touch-Wroom-240-.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/readme_img/1703943134-Screenshot-2023-12-30-at-14-31-18-733E-Esp-wroom-32-Esp32-For-Arduino-Lvgl-Wifi-28-28inch-Lcd-Tft-Module-With-Touch-Wroom-240-.png
--------------------------------------------------------------------------------
/readme_img/1703943240-Screenshot-2023-12-30-at-14-32-26-733E-Esp-wroom-32-Esp32-For-Arduino-Lvgl-Wifi-28-28inch-Lcd-Tft-Module-With-Touch-Wroom-240-320-.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/readme_img/1703943240-Screenshot-2023-12-30-at-14-32-26-733E-Esp-wroom-32-Esp32-For-Arduino-Lvgl-Wifi-28-28inch-Lcd-Tft-Module-With-Touch-Wroom-240-320-.png
--------------------------------------------------------------------------------
/readme_img/esp32_2432s028_i2c.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/readme_img/esp32_2432s028_i2c.jpg
--------------------------------------------------------------------------------
/readme_img/example.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/readme_img/example.jpg
--------------------------------------------------------------------------------
/readme_img/grafico.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/readme_img/grafico.jpg
--------------------------------------------------------------------------------
/readme_img/status.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/readme_img/status.jpg
--------------------------------------------------------------------------------
/readme_img/vento.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/1achy/ESPHOME-esp32-2432s028r-LCD/a986983df4af59a8f6a7336829c6bac0c7dd29cf/readme_img/vento.jpg
--------------------------------------------------------------------------------
/secrets.yaml:
--------------------------------------------------------------------------------
1 | wifi_ssid: "your ssid"
2 | wifi_password: "your wifi wpa psk"
3 | fallpass: "your fallback password"
4 | 
--------------------------------------------------------------------------------