{"id":481042,"date":"2026-05-26T08:11:27","date_gmt":"2026-05-26T08:11:27","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=481042"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=481042","title":{"rendered":"\u041a\u0430\u043a \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u043e\u0431\u044b\u0447\u043d\u0443\u044e \u043f\u043e\u0441\u0443\u0434\u043e\u043c\u043e\u0435\u0447\u043d\u0443\u044e \u043c\u0430\u0448\u0438\u043d\u0443 \u0443\u043c\u043d\u043e\u0439, \u0441 Home Assistant\/ESPHome"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<blockquote>\n<p>Reverse engineering \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0448\u0438\u043d\u044b \u043f\u0430\u043d\u0435\u043b\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043b\u044f ESPHome \u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0432 Home Assistant.<\/p>\n<\/blockquote>\n<h3>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0421\u0442\u043e\u0438\u0442 \u0443 \u043c\u0435\u043d\u044f \u0441\u0442\u0430\u0440\u0430\u044f \u043f\u043e\u0441\u0443\u0434\u043e\u043c\u043e\u0435\u0447\u043d\u0430\u044f \u043c\u0430\u0448\u0438\u043d\u0430 Gorenje GV 51211. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438\u0441\u043f\u0440\u0430\u0432\u043d\u043e, \u043d\u043e \u0432\u043e\u0437\u0440\u0430\u0441\u0442 \u0443 \u043d\u0435\u0451 \u0443\u0436\u0435 \u0442\u0430\u043a\u043e\u0439, \u0447\u0442\u043e \u043c\u043e\u0440\u0430\u043b\u044c\u043d\u043e \u044f \u0434\u0430\u0432\u043d\u043e \u0433\u043e\u0442\u043e\u0432 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043e\u0434\u043d\u0430\u0436\u0434\u044b \u043e\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043a\u0430\u0436\u0435\u0442: \u00ab\u041d\u0430 \u044d\u0442\u043e\u043c \u0432\u0441\u0451\u00bb.  \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0443\u043c\u043d\u043e\u0433\u043e \u0434\u043e\u043c\u0430 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 Home Assistant \u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043c\u044b\u0441\u043b\u044c: \u0430 \u043f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b \u043d\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043a \u0441\u0438\u0441\u0442\u0435\u043c\u0435  \u0438 \u043f\u043e\u0441\u0443\u0434\u043e\u043c\u043e\u0439\u043a\u0443?  <\/p>\n<p>\u0423\u0434\u0430\u043b\u0451\u043d\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0441\u0443\u0434\u043e\u043c\u043e\u0435\u0447\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u043e\u0439 \u044f \u043d\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0441\u044f. \u041c\u0435\u043d\u044f \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043b \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433:  <\/p>\n<ul>\n<li>\n<p>\u043a\u0430\u043a\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u043b\u0438 \u043e\u0442\u0441\u0440\u043e\u0447\u043a\u0430 \u0441\u0442\u0430\u0440\u0442\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u043d \u043b\u0438 \u0440\u0435\u0436\u0438\u043c \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043b\u0438 \u0441\u043e\u043b\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0438\u0434\u0451\u0442 \u043b\u0438 \u0441\u0435\u0439\u0447\u0430\u0441 \u043c\u043e\u0439\u043a\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0434\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>\u0413\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043c\u043e\u0435\u0439 \u043f\u043e\u0441\u0443\u0434\u043e\u043c\u043e\u0435\u0447\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b Gorenje GV 51211. \u044f \u043d\u0435 \u043d\u0430\u0448\u0451\u043b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0435\u0448\u0438\u043b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u043c \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u043e\u043c \u043f\u0430\u043d\u0435\u043b\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0435\u0451 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e.<\/p>\n<h3>\u0412\u0430\u0436\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435<\/h3>\n<p>\u26a0\ufe0f \u0412\u043d\u0443\u0442\u0440\u0438 \u0431\u044b\u0442\u043e\u0432\u043e\u0439 \u0442\u0435\u0445\u043d\u0438\u043a\u0438 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0435\u0442\u0435\u0432\u043e\u0435 \u043d\u0430\u043f\u0440\u044f\u0436\u0435\u043d\u0438\u0435 230 \u0412.<\/p>\n<p>\u0412\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043d\u0430 \u0432\u0430\u0448 \u0441\u0442\u0440\u0430\u0445 \u0438 \u0440\u0438\u0441\u043a. \u042d\u0442\u043e\u0442 \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043f\u0430\u0441\u0441\u0438\u0432\u043d\u043e\u0433\u043e \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u043d\u0438\u0437\u043a\u043e\u0432\u043e\u043b\u044c\u0442\u043d\u043e\u0439 \u0448\u0438\u043d\u044b \u043f\u0430\u043d\u0435\u043b\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u043d\u0435 \u0432\u043c\u0435\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043c\u0430\u0448\u0438\u043d\u043e\u0439.<\/p>\n<h3>\u0427\u0442\u043e \u0431\u044b\u043b\u043e \u043d\u0443\u0436\u043d\u043e<\/h3>\n<h4>\u0410\u043f\u043f\u0430\u0440\u0430\u0442\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c<\/h4>\n<ul>\n<li>\n<p>Wemos D1 mini (ESP8266)<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0443\u0440\u043e\u0432\u043d\u0435\u0439 5V \u2192 3.3V<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u043d\u0434\u0435\u043d\u0441\u0430\u0442\u043e\u0440 1000 \u043c\u043a\u0424<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0432\u043e\u0434\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>\u041f\u0430\u044f\u043b\u044c\u043d\u0438\u043a<\/p>\n<\/li>\n<\/ul>\n<h4>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c<\/h4>\n<ul>\n<li>\n<p>ESPHome<\/p>\n<\/li>\n<li>\n<p>Home Assistant<\/p>\n<\/li>\n<\/ul>\n<h3>\u0420\u0430\u0437\u0431\u043e\u0440\u043a\u0430 \u0438 \u043f\u043e\u0438\u0441\u043a \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430<\/h3>\n<figure class=\"bordered full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/889\/d6d\/cca\/889d6dccaec3a0a971bacbb89423fbb8.png\" width=\"960\" height=\"1058\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/889\/d6d\/cca\/889d6dccaec3a0a971bacbb89423fbb8.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/889\/d6d\/cca\/889d6dccaec3a0a971bacbb89423fbb8.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0440\u0430\u0437\u0431\u043e\u0440\u043a\u0438 \u043f\u0435\u0440\u0435\u0434\u043d\u0435\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 \u044f \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b \u043f\u043b\u0430\u0442\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430. \u041d\u0430 \u043d\u0435\u0451 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b \u0448\u043b\u0435\u0439\u0444 \u0441 \u043f\u044f\u0442\u044c\u044e \u043a\u043e\u043d\u0442\u0430\u043a\u0442\u0430\u043c\u0438:<\/p>\n<ul>\n<li>\n<p>5V<\/p>\n<\/li>\n<li>\n<p>GND<\/p>\n<\/li>\n<li>\n<p>DIO<\/p>\n<\/li>\n<li>\n<p>CLK<\/p>\n<\/li>\n<li>\n<p>STB<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u043a\u043e\u0439 \u043d\u0430\u0431\u043e\u0440 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u043e\u0432 \u0442\u0438\u043f\u0430 TM1638, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043d\u044b\u043c\u0438 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u0430\u043c\u0438 \u0438 \u0447\u0442\u0435\u043d\u0438\u044f \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b.<\/p>\n<h3>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 Wemos d1 mini<\/h3>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041f\u043b\u0430\u0442\u0430 \u043f\u043e\u0441\u0443\u0434\u043e\u043c\u043e\u0439\u043a\u0438<\/p>\n<\/th>\n<th>\n<p align=\"left\">Wemos D1 mini<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">5V<\/p>\n<\/td>\n<td>\n<p align=\"left\">5V<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">GND<\/p>\n<\/td>\n<td>\n<p align=\"left\">GND<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">DIO<\/p>\n<\/td>\n<td>\n<p align=\"left\">D5<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">CLK<\/p>\n<\/td>\n<td>\n<p align=\"left\">D6<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">STB<\/p>\n<\/td>\n<td>\n<p align=\"left\">D7<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0421\u0438\u0433\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043b\u0438\u043d\u0438\u0438 \u0431\u044b\u043b\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0443\u0440\u043e\u0432\u043d\u0435\u0439 5\u0412-3.3\u0412, \u0430 \u043d\u0430 \u043f\u0438\u0442\u0430\u043d\u0438\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u043a\u043e\u043d\u0434\u0435\u043d\u0441\u0430\u0442\u043e\u0440 6.3\u0412 1000 \u043c\u043a\u0424. \u041f\u0438\u0442\u0430\u043d\u0438\u0435 \u0432\u0437\u044f\u043b \u0441\u043e \u0448\u043b\u0435\u0439\u0444\u0430<\/p>\n<h3>\u041f\u0435\u0440\u0432\u044b\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0438<\/h3>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u044f \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 <code>binary_sensor<\/code> \u0432 ESPHome \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0444\u0440\u043e\u043d\u0442\u043e\u0432 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432.<\/p>\n<p>\u042d\u0442\u043e \u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e: \u043f\u043e\u0442\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0431\u044b\u0441\u0442\u0440\u044b\u043c, \u0447\u0430\u0441\u0442\u044c \u0431\u0438\u0442\u043e\u0432 \u0442\u0435\u0440\u044f\u043b\u0430\u0441\u044c, \u0430 \u043b\u043e\u0433 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u043b\u0441\u044f \u0445\u0430\u043e\u0442\u0438\u0447\u043d\u044b\u043c\u0438 \u043f\u0430\u043a\u0435\u0442\u0430\u043c\u0438.<\/p>\n<p>\u041f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043b\u044f ESPHome \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0430\u043f\u043f\u0430\u0440\u0430\u0442\u043d\u044b\u0445 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 <code>attachInterrupt()<\/code>.<\/p>\n<h3>\u0421\u043d\u0438\u0444\u0444\u0438\u043d\u0433 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430<\/h3>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442:<\/p>\n<ul>\n<li>\n<p><code>washmashine.yaml<\/code><\/p>\n<\/li>\n<li>\n<p><code>components\/tm1638_sniffer\/__init__.py<\/code><\/p>\n<\/li>\n<li>\n<p><code>components\/tm1638_sniffer\/tm1638_sniffer.h<\/code><\/p>\n<\/li>\n<li>\n<p><code>components\/tm1638_sniffer\/tm1638_sniffer.cpp<\/code><\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>__init__.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import esphome.codegen as cgimport esphome.config_validation as cvfrom esphome.components import text_sensor, binary_sensor, sensorfrom esphome.const import CONF_ID, UNIT_MINUTE, ICON_TIMERCONF_PROGRAM = \"program\"CONF_DELAY_TIMER = \"delay_timer\"CONF_POWER = \"power\"CONF_SALT_MISSING = \"salt_missing\"CONF_HALF_LOAD = \"half_load\"CONF_RUNNING = \"running\"CONF_REMAINING_MINUTES = \"remaining_minutes\"AUTO_LOAD = [\"text_sensor\", \"binary_sensor\", \"sensor\"]CODEOWNERS = [\"\"]tm1638_sniffer_ns = cg.esphome_ns.namespace(\"tm1638_sniffer\")TM1638Sniffer = tm1638_sniffer_ns.class_(\"TM1638Sniffer\", cg.Component)CONFIG_SCHEMA = cv.Schema({    cv.GenerateID(): cv.declare_id(TM1638Sniffer),    cv.Optional(CONF_PROGRAM): text_sensor.text_sensor_schema(),    cv.Optional(CONF_DELAY_TIMER): text_sensor.text_sensor_schema(),    cv.Optional(CONF_POWER): binary_sensor.binary_sensor_schema(),    cv.Optional(CONF_SALT_MISSING): binary_sensor.binary_sensor_schema(),    cv.Optional(CONF_HALF_LOAD): binary_sensor.binary_sensor_schema(),    cv.Optional(CONF_RUNNING): binary_sensor.binary_sensor_schema(),    cv.Optional(CONF_REMAINING_MINUTES): sensor.sensor_schema(        unit_of_measurement=UNIT_MINUTE,        icon=ICON_TIMER,        accuracy_decimals=0,    ),}).extend(cv.COMPONENT_SCHEMA)async def to_code(config):    var = cg.new_Pvariable(config[CONF_ID])    await cg.register_component(var, config)    if CONF_PROGRAM in config:        sens = await text_sensor.new_text_sensor(config[CONF_PROGRAM])        cg.add(var.set_program_sensor(sens))    if CONF_DELAY_TIMER in config:        sens = await text_sensor.new_text_sensor(config[CONF_DELAY_TIMER])        cg.add(var.set_delay_timer_sensor(sens))    if CONF_POWER in config:        sens = await binary_sensor.new_binary_sensor(config[CONF_POWER])        cg.add(var.set_power_sensor(sens))    if CONF_SALT_MISSING in config:        sens = await binary_sensor.new_binary_sensor(config[CONF_SALT_MISSING])        cg.add(var.set_salt_missing_sensor(sens))    if CONF_HALF_LOAD in config:        sens = await binary_sensor.new_binary_sensor(config[CONF_HALF_LOAD])        cg.add(var.set_half_load_sensor(sens))    if CONF_RUNNING in config:        sens = await binary_sensor.new_binary_sensor(config[CONF_RUNNING])        cg.add(var.set_running_sensor(sens))    if CONF_REMAINING_MINUTES in config:        sens = await sensor.new_sensor(config[CONF_REMAINING_MINUTES])        cg.add(var.set_remaining_minutes_sensor(sens))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>tm1638_sniffer.cpp<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include \"tm1638_sniffer.h\"#include \"esphome\/core\/log.h\"#include &lt;Arduino.h&gt;namespace esphome {namespace tm1638_sniffer {static const char *const TAG = \"tm1638_sniffer\";#define PIN_DIO D5#define PIN_CLK D6#define PIN_STB D7volatile bool TM1638Sniffer::active_ = false;volatile uint8_t TM1638Sniffer::bit_count_ = 0;volatile uint8_t TM1638Sniffer::cur_byte_ = 0;volatile uint8_t TM1638Sniffer::buf_[128];volatile uint8_t TM1638Sniffer::len_ = 0;volatile bool TM1638Sniffer::ready_ = false;uint8_t TM1638Sniffer::last_buf_[14];uint8_t TM1638Sniffer::last_len_ = 0;void TM1638Sniffer::setup() {  pinMode(PIN_DIO, INPUT_PULLUP);  pinMode(PIN_CLK, INPUT_PULLUP);  pinMode(PIN_STB, INPUT_PULLUP);  attachInterrupt(digitalPinToInterrupt(PIN_STB), TM1638Sniffer::isr_stb, CHANGE);  attachInterrupt(digitalPinToInterrupt(PIN_CLK), TM1638Sniffer::isr_clk, RISING);  ESP_LOGI(TAG, \"TM1638 dishwasher sniffer started\");}void TM1638Sniffer::loop() {  if (!ready_) return;  noInterrupts();  uint8_t local_len = len_;  if (local_len &lt; 4 || local_len &gt; 16) {    ready_ = false;    interrupts();    return;  }  uint8_t local_buf[128];  for (uint8_t i = 0; i &lt; local_len; i++) {    local_buf[i] = buf_[i];  }  ready_ = false;  interrupts();  if (local_buf[0] != 0xC0) return;  if (local_len &lt; 14) return;  local_len = 14;  bool same = last_len_ == local_len;  if (same) {    for (uint8_t i = 0; i &lt; local_len; i++) {      if (local_buf[i] != last_buf_[i]) {        same = false;        break;      }    }  }  if (!same) {    last_len_ = local_len;    for (uint8_t i = 0; i &lt; local_len; i++) {      last_buf_[i] = local_buf[i];    }    std::string out = \"display changed:\";    char tmp[8];    for (uint8_t i = 0; i &lt; local_len; i++) {      snprintf(tmp, sizeof(tmp), \" %02X\", local_buf[i]);      out += tmp;    }    ESP_LOGD(TAG, \"%s\", out.c_str());    decode_packet_(local_buf, local_len);  } else {    \/\/ \u0414\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0434\u0438\u0441\u043f\u043b\u0435\u0439 \u043d\u0435 \u043c\u0435\u043d\u044f\u043b\u0441\u044f, \u0442\u0430\u0439\u043c\u0435\u0440 \u043e\u0441\u0442\u0430\u0442\u043a\u0430 \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0440\u0430\u0437 \u0432 \u043c\u0438\u043d\u0443\u0442\u0443.    static uint32_t last_timer_update_ms = 0;    uint32_t now = millis();    if (was_running_ &amp;&amp; selected_duration_min_ &gt; 0 &amp;&amp; now - last_timer_update_ms &gt; 60000) {      last_timer_update_ms = now;      uint32_t elapsed_min = (now - started_at_ms_) \/ 60000;      int remaining = selected_duration_min_ - elapsed_min;      if (remaining &lt; 0) remaining = 0;      if (remaining_minutes_sensor_ != nullptr) {        remaining_minutes_sensor_-&gt;publish_state(remaining);      }    }  }}int TM1638Sniffer::program_duration_minutes_(const std::string &amp;program) {  if (program == \"\u042d\u043a\u043e\") return 175;  if (program == \"\u0414\u0435\u043b\u0438\u043a\u0430\u0442\u043d\u0430\u044f\") return 110;  if (program == \"90 \u043c\u0438\u043d\") return 90;  if (program == \"\u0411\u044b\u0441\u0442\u0440\u0430\u044f\") return 40;  if (program == \"\u0418\u043d\u0442\u0435\u043d\u0441\u0438\u0432\u043d\u0430\u044f\") return 130;  if (program == \"\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f\") return 155;  return 0;}void TM1638Sniffer::decode_packet_(uint8_t *d, uint8_t len) {  if (len &lt; 14) return;  bool power = d[2] &amp; 0x01;  bool salt_missing = d[6] &amp; 0x01;  bool half_load = d[8] &amp; 0x01;  bool any_program_led =      (d[6] &amp; 0x02) ||      (d[8] &amp; 0x02) ||      (d[10] &amp; 0x02) ||      (d[12] &amp; 0x02) ||      (d[2] &amp; 0x02) ||      (d[4] &amp; 0x02);  std::string program = \"\u041d\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u0430\";  if (d[6] &amp; 0x02) {    program = \"\u042d\u043a\u043e\";  } else if (d[8] &amp; 0x02) {    program = \"\u0414\u0435\u043b\u0438\u043a\u0430\u0442\u043d\u0430\u044f\";  } else if (d[10] &amp; 0x02) {    program = \"90 \u043c\u0438\u043d\";  } else if (d[12] &amp; 0x02) {    program = \"\u0411\u044b\u0441\u0442\u0440\u0430\u044f\";  } else if (d[2] &amp; 0x02) {    program = \"\u0418\u043d\u0442\u0435\u043d\u0441\u0438\u0432\u043d\u0430\u044f\";  } else if (d[4] &amp; 0x02) {    program = \"\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f\";  }  if (any_program_led) {    program_was_selected_ = true;    selected_program_ = program;    selected_duration_min_ = program_duration_minutes_(program);  }  bool running = power &amp;&amp; program_was_selected_ &amp;&amp; !any_program_led;  if (!power) {    program_was_selected_ = false;    was_running_ = false;    started_at_ms_ = 0;    selected_duration_min_ = 0;    selected_program_ = \"\u041d\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u0430\";  }  if (running &amp;&amp; !was_running_) {    was_running_ = true;    started_at_ms_ = millis();    if (selected_duration_min_ == 0) {      selected_duration_min_ = program_duration_minutes_(selected_program_);    }    ESP_LOGI(TAG, \"Dishwasher started: program=%s duration=%d min\",             selected_program_.c_str(), selected_duration_min_);  }  if (!running &amp;&amp; was_running_) {    was_running_ = false;    ESP_LOGI(TAG, \"Dishwasher stopped or finished\");  }  int remaining = 0;  if (running &amp;&amp; selected_duration_min_ &gt; 0) {    uint32_t elapsed_min = (millis() - started_at_ms_) \/ 60000;    remaining = selected_duration_min_ - elapsed_min;    if (remaining &lt; 0) remaining = 0;  }  std::string delay = \"\u0412\u044b\u043a\u043b\u044e\u0447\u0435\u043d\";  if (d[1] &amp; 0x80) {    delay = \"3 \u0447\u0430\u0441\u0430\";  } else if (d[3] &amp; 0x80) {    delay = \"6 \u0447\u0430\u0441\u043e\u0432\";  } else if (d[5] &amp; 0x80) {    delay = \"9 \u0447\u0430\u0441\u043e\u0432\";  } else if (d[7] &amp; 0x80) {    delay = \"12 \u0447\u0430\u0441\u043e\u0432\";  }  if (program_sensor_ != nullptr) {    program_sensor_-&gt;publish_state(any_program_led ? program : selected_program_);  }  if (delay_timer_sensor_ != nullptr) {    delay_timer_sensor_-&gt;publish_state(delay);  }  if (power_sensor_ != nullptr) {    power_sensor_-&gt;publish_state(power);  }  if (salt_missing_sensor_ != nullptr) {    salt_missing_sensor_-&gt;publish_state(salt_missing);  }  if (half_load_sensor_ != nullptr) {    half_load_sensor_-&gt;publish_state(half_load);  }  if (running_sensor_ != nullptr) {    running_sensor_-&gt;publish_state(running);  }  if (remaining_minutes_sensor_ != nullptr) {    remaining_minutes_sensor_-&gt;publish_state(remaining);  }  ESP_LOGD(TAG,           \"program=%s selected_program=%s delay=%s power=%s salt_missing=%s half_load=%s running=%s remaining=%d\",           program.c_str(),           selected_program_.c_str(),           delay.c_str(),           power ? \"ON\" : \"OFF\",           salt_missing ? \"ON\" : \"OFF\",           half_load ? \"ON\" : \"OFF\",           running ? \"ON\" : \"OFF\",           remaining);}void ICACHE_RAM_ATTR TM1638Sniffer::isr_stb() {  bool stb = digitalRead(PIN_STB);  if (!stb) {    active_ = true;    bit_count_ = 0;    cur_byte_ = 0;    len_ = 0;  } else {    active_ = false;    ready_ = true;  }}void ICACHE_RAM_ATTR TM1638Sniffer::isr_clk() {  if (!active_) return;  if (len_ &gt;= sizeof(buf_)) return;  uint8_t bit = digitalRead(PIN_DIO) ? 1 : 0;  cur_byte_ |= bit &lt;&lt; bit_count_;  bit_count_++;  if (bit_count_ == 8) {    buf_[len_++] = cur_byte_;    cur_byte_ = 0;    bit_count_ = 0;  }}}  \/\/ namespace tm1638_sniffer}  \/\/ namespace esphome<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>tm1638_sniffer.h<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#pragma once#include \"esphome\/core\/component.h\"#include \"esphome\/components\/text_sensor\/text_sensor.h\"#include \"esphome\/components\/binary_sensor\/binary_sensor.h\"#include \"esphome\/components\/sensor\/sensor.h\"#include &lt;Arduino.h&gt;namespace esphome {namespace tm1638_sniffer {class TM1638Sniffer : public Component { public:  void setup() override;  void loop() override;  void set_program_sensor(text_sensor::TextSensor *sensor) { program_sensor_ = sensor; }  void set_delay_timer_sensor(text_sensor::TextSensor *sensor) { delay_timer_sensor_ = sensor; }  void set_power_sensor(binary_sensor::BinarySensor *sensor) { power_sensor_ = sensor; }  void set_salt_missing_sensor(binary_sensor::BinarySensor *sensor) { salt_missing_sensor_ = sensor; }  void set_half_load_sensor(binary_sensor::BinarySensor *sensor) { half_load_sensor_ = sensor; }  void set_running_sensor(binary_sensor::BinarySensor *sensor) { running_sensor_ = sensor; }  void set_remaining_minutes_sensor(sensor::Sensor *sensor) { remaining_minutes_sensor_ = sensor; } protected:  static void ICACHE_RAM_ATTR isr_stb();  static void ICACHE_RAM_ATTR isr_clk();  void decode_packet_(uint8_t *data, uint8_t len);  int program_duration_minutes_(const std::string &amp;program);  text_sensor::TextSensor *program_sensor_{nullptr};  text_sensor::TextSensor *delay_timer_sensor_{nullptr};  binary_sensor::BinarySensor *power_sensor_{nullptr};  binary_sensor::BinarySensor *salt_missing_sensor_{nullptr};  binary_sensor::BinarySensor *half_load_sensor_{nullptr};  binary_sensor::BinarySensor *running_sensor_{nullptr};  sensor::Sensor *remaining_minutes_sensor_{nullptr};  bool program_was_selected_{false};  bool was_running_{false};  uint32_t started_at_ms_{0};  int selected_duration_min_{0};  std::string selected_program_{\"\u041d\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u0430\"};  static volatile bool active_;  static volatile uint8_t bit_count_;  static volatile uint8_t cur_byte_;  static volatile uint8_t buf_[128];  static volatile uint8_t len_;  static volatile bool ready_;  static uint8_t last_buf_[14];  static uint8_t last_len_;};}  \/\/ namespace tm1638_sniffer}  \/\/ namespace esphome<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<ul>\n<li>\n<p><code>STB<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043d\u0430\u0447\u0430\u043b\u043e \u0438 \u043a\u043e\u043d\u0435\u0446 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438.<\/p>\n<\/li>\n<li>\n<p><code>CLK<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0431\u0438\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p><code>DIO<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u0430\u043d\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 LSB-first.<\/p>\n<h3>\u041f\u0435\u0440\u0432\u044b\u0435 \u043e\u0441\u043c\u044b\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b<\/h3>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u043d\u0438\u0444\u0444\u0435\u0440\u0430 \u0432 \u043b\u043e\u0433\u0430\u0445 \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b \u0434\u0432\u0443\u0445 \u0442\u0438\u043f\u043e\u0432:<\/p>\n<pre><code>42 00 00 80 08C0 00 01 00 00 00 01 00 00 00 00 00 00 00<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<ul>\n<li>\n<p><code>0x42<\/code> \u2014 \u043e\u043f\u0440\u043e\u0441 \u043a\u043d\u043e\u043f\u043e\u043a.<\/p>\n<\/li>\n<li>\n<p><code>0xC0<\/code> \u2014 \u0437\u0430\u043f\u0438\u0441\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c \u0434\u0438\u0441\u043f\u043b\u0435\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u043f\u0430\u043a\u0435\u0442\u044b <code>C0<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043b\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u043f\u0430\u043d\u0435\u043b\u0438.<\/p>\n<h3>\u0411\u043e\u0440\u044c\u0431\u0430 \u0441\u043e \u0441\u043f\u0430\u043c\u043e\u043c<\/h3>\n<p>\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u043b \u0434\u0438\u0441\u043f\u043b\u0435\u0439 \u0434\u0435\u0441\u044f\u0442\u043a\u0438 \u0440\u0430\u0437 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043b\u043e\u0433 \u043e\u0441\u0442\u0430\u0432\u0430\u043b\u0441\u044f \u0447\u0438\u0442\u0430\u0435\u043c\u044b\u043c, \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c:<\/p>\n<ol>\n<li>\n<p>\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u043a\u0435\u0442\u044b <code>0x42<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u043d\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b <code>0xC0<\/code> \u0434\u043b\u0438\u043d\u043e\u0439 14 \u0431\u0430\u0439\u0442.<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e.<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043b\u043e\u0433 \u0441\u0442\u0430\u043b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0430\u0448\u0438\u043d\u044b.<\/p>\n<h3>\u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c<\/h3>\n<p>\u0420\u0443\u0447\u043d\u043e\u0435 \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c.<\/p>\n<h4>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0423\u0441\u043b\u043e\u0432\u0438\u0435<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u042d\u043a\u043e<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>d[6] &amp; 0x02<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0414\u0435\u043b\u0438\u043a\u0430\u0442\u043d\u0430\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>d[8] &amp; 0x02<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">90 \u043c\u0438\u043d<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>d[10] &amp; 0x02<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0411\u044b\u0441\u0442\u0440\u0430\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>d[12] &amp; 0x02<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0418\u043d\u0442\u0435\u043d\u0441\u0438\u0432\u043d\u0430\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>d[2] &amp; 0x02<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>d[4] &amp; 0x02<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h4>\u041e\u0442\u0441\u0440\u043e\u0447\u043a\u0430 \u0441\u0442\u0430\u0440\u0442\u0430<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0422\u0430\u0439\u043c\u0435\u0440<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0423\u0441\u043b\u043e\u0432\u0438\u0435<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">3 \u0447\u0430\u0441\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>d[1] &amp; 0x80<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">6 \u0447\u0430\u0441\u043e\u0432<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>d[3] &amp; 0x80<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">9 \u0447\u0430\u0441\u043e\u0432<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>d[5] &amp; 0x80<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">12 \u0447\u0430\u0441\u043e\u0432<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>d[7] &amp; 0x80<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h4>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u044b<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0424\u0443\u043d\u043a\u0446\u0438\u044f<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0423\u0441\u043b\u043e\u0432\u0438\u0435<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041c\u0430\u043b\u043e \u0441\u043e\u043b\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>d[6] &amp; 0x01<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">1\/2 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>d[8] &amp; 0x01<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h3>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0432 Home Assistant<\/h3>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/137\/9e6\/cea\/1379e6cea623568f9fd35ea6212f1320.png\" width=\"798\" height=\"524\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/137\/9e6\/cea\/1379e6cea623568f9fd35ea6212f1320.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/137\/9e6\/cea\/1379e6cea623568f9fd35ea6212f1320.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430 \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043b\u044f ESPHome, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0432 Home Assistant:<\/p>\n<details class=\"spoiler\">\n<summary>washmashine.yaml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\">esphome:  name: washmashine  friendly_name: Washmashineesp8266:  board: d1_miniexternal_components:  - source:      type: local      path: componentslogger:  level: DEBUG  baud_rate: 0api:  encryption:    key: \"\"ota:  - platform: esphome    password: \"\"wifi:  ssid: !secret wifi_ssid  password: !secret wifi_password  min_auth_mode: WPA2  ap:    ssid: \"Washmashine Fallback\"    password: \"\"captive_portal:tm1638_sniffer:  program:    name: \"Dishwasher Program\"  delay_timer:    name: \"Dishwasher Delay Timer\"  power:    name: \"Dishwasher Power\"  salt_missing:    name: \"Dishwasher Salt Missing\"  half_load:    name: \"Dishwasher Half Load\"  running:    name: \"Dishwasher Running\"  remaining_minutes:    name: \"Dishwasher Remaining Minutes\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<ul>\n<li>\n<p>Dishwasher Program<\/p>\n<\/li>\n<li>\n<p>Dishwasher Delay Timer<\/p>\n<\/li>\n<li>\n<p>Dishwasher Power<\/p>\n<\/li>\n<li>\n<p>Dishwasher Salt Missing<\/p>\n<\/li>\n<li>\n<p>Dishwasher Half Load<\/p>\n<\/li>\n<li>\n<p>Dishwasher Running<\/p>\n<\/li>\n<li>\n<p>Dishwasher Remaining Minutes<\/p>\n<\/li>\n<\/ul>\n<h3>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f Running<\/h3>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u00ab\u0434\u0432\u0435\u0440\u044c \u0437\u0430\u043a\u0440\u044b\u0442\u0430\u00bb \u044f \u043d\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b.<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0431\u043e\u0440\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0438 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u0434\u0432\u0435\u0440\u0446\u044b \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u0433\u0430\u0441\u043d\u0443\u0442.<\/p>\n<p>\u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443:<\/p>\n<ol>\n<li>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0438 \u0435\u0451 \u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u044e\u0442\u0441\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0418\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u0433\u0430\u0441\u043d\u0443\u0442.<\/p>\n<\/li>\n<li>\n<p><code>Dishwasher Running = ON<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0439 \u043e\u0442\u0441\u0447\u0451\u0442.<\/p>\n<\/li>\n<\/ol>\n<h4>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u043c\u0438\u0433\u0430\u044e\u0449\u0435\u0433\u043e \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u0430<\/h4>\n<p>\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0431\u043e\u0440\u0430 \u0432\u043e\u0434\u044b (\u043f\u0435\u0440\u0432\u044b\u0435 2\u20133 \u043c\u0438\u043d\u0443\u0442\u044b) \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043c\u0438\u0433\u0430\u0435\u0442.<\/p>\n<p>\u0418\u0437-\u0437\u0430 \u044d\u0442\u043e\u0433\u043e <code>Running<\/code> \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u043b\u0441\u044f \u043c\u0435\u0436\u0434\u0443 <code>ON<\/code> \u0438 <code>OFF<\/code>.<\/p>\n<p>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u2014 \u0442\u0440\u0451\u0445\u043c\u0438\u043d\u0443\u0442\u043d\u044b\u0439 <code>startup grace period<\/code>, \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u043e\u0439 \u043c\u043e\u0439\u043a\u0438.<\/p>\n<h3>\u0420\u0430\u0441\u0447\u0451\u0442 \u043e\u0441\u0442\u0430\u0432\u0448\u0435\u0433\u043e\u0441\u044f \u0432\u0440\u0435\u043c\u0435\u043d\u0438<\/h3>\n<p>\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0431\u044b\u043b\u0438 \u0437\u0430\u0434\u0430\u043d\u044b \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u043e\u0447\u043d\u044b\u0435 \u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0412\u0440\u0435\u043c\u044f<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u042d\u043a\u043e<\/p>\n<\/td>\n<td>\n<p align=\"left\">175 \u043c\u0438\u043d<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0414\u0435\u043b\u0438\u043a\u0430\u0442\u043d\u0430\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">110 \u043c\u0438\u043d<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">90 \u043c\u0438\u043d<\/p>\n<\/td>\n<td>\n<p align=\"left\">90 \u043c\u0438\u043d<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0411\u044b\u0441\u0442\u0440\u0430\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">40 \u043c\u0438\u043d<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0418\u043d\u0442\u0435\u043d\u0441\u0438\u0432\u043d\u0430\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">130 \u043c\u0438\u043d<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">155 \u043c\u0438\u043d<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0441\u0442\u0430\u0440\u0442\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u0440\u043e\u0448\u043b\u043e, \u0438 \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0445\u0441\u044f \u043c\u0438\u043d\u0443\u0442.<\/p>\n<h3>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043f\u043e\u0441\u043b\u0435 \u0441\u0442\u0430\u0440\u0442\u0430<\/h3>\n<p>\u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043c\u0430\u0448\u0438\u043d\u0443, \u0430 \u0437\u0430\u0442\u0435\u043c \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0434\u0432\u0435\u0440\u0446\u0443 \u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u0434\u0440\u0443\u0433\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443, \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438:<\/p>\n<ul>\n<li>\n<p>\u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043e\u0442\u0441\u0447\u0451\u0442;<\/p>\n<\/li>\n<li>\n<p>\u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 <code>Running<\/code>;<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442 \u043d\u043e\u0432\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443;<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u0442\u0430\u0439\u043c\u0435\u0440 \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0441\u0442\u0430\u0440\u0442\u0430.<\/p>\n<\/li>\n<\/ul>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1039434\/\">https:\/\/habr.com\/ru\/articles\/1039434\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Reverse engineering \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0448\u0438\u043d\u044b \u043f\u0430\u043d\u0435\u043b\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043b\u044f ESPHome \u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0432 Home Assistant.\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u0421\u0442\u043e\u0438\u0442 \u0443 \u043c\u0435\u043d\u044f \u0441\u0442\u0430\u0440\u0430\u044f \u043f\u043e\u0441\u0443\u0434\u043e\u043c\u043e\u0435\u0447\u043d\u0430\u044f \u043c\u0430\u0448\u0438\u043d\u0430 Gorenje GV 51211. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438\u0441\u043f\u0440\u0430\u0432\u043d\u043e, \u043d\u043e \u0432\u043e\u0437\u0440\u0430\u0441\u0442 \u0443 \u043d\u0435\u0451 \u0443\u0436\u0435 \u0442\u0430\u043a\u043e\u0439, \u0447\u0442\u043e \u043c\u043e\u0440\u0430\u043b\u044c\u043d\u043e \u044f \u0434\u0430\u0432\u043d\u043e \u0433\u043e\u0442\u043e\u0432 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043e\u0434\u043d\u0430\u0436\u0434\u044b \u043e\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043a\u0430\u0436\u0435\u0442: \u00ab\u041d\u0430 \u044d\u0442\u043e\u043c \u0432\u0441\u0451\u00bb.  \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0443\u043c\u043d\u043e\u0433\u043e \u0434\u043e\u043c\u0430 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 Home Assistant \u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043c\u044b\u0441\u043b\u044c: \u0430 \u043f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b \u043d\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043a \u0441\u0438\u0441\u0442\u0435\u043c\u0435  \u0438 \u043f\u043e\u0441\u0443\u0434\u043e\u043c\u043e\u0439\u043a\u0443?  \u0423\u0434\u0430\u043b\u0451\u043d\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0441\u0443\u0434\u043e\u043c\u043e\u0435\u0447\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u043e\u0439 \u044f \u043d\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0441\u044f. \u041c\u0435\u043d\u044f \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043b \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433:  \u043a\u0430\u043a\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u0430;\u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u043b\u0438 \u043e\u0442\u0441\u0440\u043e\u0447\u043a\u0430 \u0441\u0442\u0430\u0440\u0442\u0430;\u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u043d \u043b\u0438 \u0440\u0435\u0436\u0438\u043c \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438;\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043b\u0438 \u0441\u043e\u043b\u0438;\u0438\u0434\u0451\u0442 \u043b\u0438 \u0441\u0435\u0439\u0447\u0430\u0441 \u043c\u043e\u0439\u043a\u0430;\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0434\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f.\u0413\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043c\u043e\u0435\u0439 \u043f\u043e\u0441\u0443\u0434\u043e\u043c\u043e\u0435\u0447\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b Gorenje GV 51211. \u044f \u043d\u0435 \u043d\u0430\u0448\u0451\u043b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0435\u0448\u0438\u043b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u043c \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u043e\u043c \u043f\u0430\u043d\u0435\u043b\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0435\u0451 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e.\u0412\u0430\u0436\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435\u26a0\ufe0f \u0412\u043d\u0443\u0442\u0440\u0438 \u0431\u044b\u0442\u043e\u0432\u043e\u0439 \u0442\u0435\u0445\u043d\u0438\u043a\u0438 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0435\u0442\u0435\u0432\u043e\u0435 \u043d\u0430\u043f\u0440\u044f\u0436\u0435\u043d\u0438\u0435 230 \u0412.\u0412\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043d\u0430 \u0432\u0430\u0448 \u0441\u0442\u0440\u0430\u0445 \u0438 \u0440\u0438\u0441\u043a. \u042d\u0442\u043e\u0442 \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043f\u0430\u0441\u0441\u0438\u0432\u043d\u043e\u0433\u043e \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u043d\u0438\u0437\u043a\u043e\u0432\u043e\u043b\u044c\u0442\u043d\u043e\u0439 \u0448\u0438\u043d\u044b \u043f\u0430\u043d\u0435\u043b\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u043d\u0435 \u0432\u043c\u0435\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043c\u0430\u0448\u0438\u043d\u043e\u0439.\u0427\u0442\u043e \u0431\u044b\u043b\u043e \u043d\u0443\u0436\u043d\u043e\u0410\u043f\u043f\u0430\u0440\u0430\u0442\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044cWemos D1 mini (ESP8266)\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0443\u0440\u043e\u0432\u043d\u0435\u0439 5V \u2192 3.3V\u041a\u043e\u043d\u0434\u0435\u043d\u0441\u0430\u0442\u043e\u0440 1000 \u043c\u043a\u0424\u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0432\u043e\u0434\u043e\u0432\u041f\u0430\u044f\u043b\u044c\u043d\u0438\u043a\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044cESPHomeHome Assistant\u0420\u0430\u0437\u0431\u043e\u0440\u043a\u0430 \u0438 \u043f\u043e\u0438\u0441\u043a \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u041f\u043e\u0441\u043b\u0435 \u0440\u0430\u0437\u0431\u043e\u0440\u043a\u0438 \u043f\u0435\u0440\u0435\u0434\u043d\u0435\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 \u044f \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b \u043f\u043b\u0430\u0442\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430. \u041d\u0430 \u043d\u0435\u0451 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b \u0448\u043b\u0435\u0439\u0444 \u0441 \u043f\u044f\u0442\u044c\u044e \u043a\u043e\u043d\u0442\u0430\u043a\u0442\u0430\u043c\u0438:5VGNDDIOCLKSTB\u0422\u0430\u043a\u043e\u0439 \u043d\u0430\u0431\u043e\u0440 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u043e\u0432 \u0442\u0438\u043f\u0430 TM1638, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043d\u044b\u043c\u0438 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u0430\u043c\u0438 \u0438 \u0447\u0442\u0435\u043d\u0438\u044f \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b.\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 Wemos d1 mini\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c:\u041f\u043b\u0430\u0442\u0430 \u043f\u043e\u0441\u0443\u0434\u043e\u043c\u043e\u0439\u043a\u0438Wemos D1 mini5V5VGNDGNDDIOD5CLKD6STBD7\u0421\u0438\u0433\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043b\u0438\u043d\u0438\u0438 \u0431\u044b\u043b\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0443\u0440\u043e\u0432\u043d\u0435\u0439 5\u0412-3.3\u0412, \u0430 \u043d\u0430 \u043f\u0438\u0442\u0430\u043d\u0438\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u043a\u043e\u043d\u0434\u0435\u043d\u0441\u0430\u0442\u043e\u0440 6.3\u0412 1000 \u043c\u043a\u0424. \u041f\u0438\u0442\u0430\u043d\u0438\u0435 \u0432\u0437\u044f\u043b \u0441\u043e \u0448\u043b\u0435\u0439\u0444\u0430\u041f\u0435\u0440\u0432\u044b\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0438\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u044f \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 binary_sensor \u0432 ESPHome \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0444\u0440\u043e\u043d\u0442\u043e\u0432 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432.\u042d\u0442\u043e \u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e: \u043f\u043e\u0442\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0431\u044b\u0441\u0442\u0440\u044b\u043c, \u0447\u0430\u0441\u0442\u044c \u0431\u0438\u0442\u043e\u0432 \u0442\u0435\u0440\u044f\u043b\u0430\u0441\u044c, \u0430 \u043b\u043e\u0433 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u043b\u0441\u044f \u0445\u0430\u043e\u0442\u0438\u0447\u043d\u044b\u043c\u0438 \u043f\u0430\u043a\u0435\u0442\u0430\u043c\u0438.\u041f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043b\u044f ESPHome \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0430\u043f\u043f\u0430\u0440\u0430\u0442\u043d\u044b\u0445 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 attachInterrupt().\u0421\u043d\u0438\u0444\u0444\u0438\u043d\u0433 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442:washmashine.yamlcomponents\/tm1638_sniffer\/__init__.pycomponents\/tm1638_sniffer\/tm1638_sniffer.hcomponents\/tm1638_sniffer\/tm1638_sniffer.cpp__init__.pyimport esphome.codegen as cgimport esphome.config_validation as cvfrom esphome.components import text_sensor, binary_sensor, sensorfrom esphome.const import CONF_ID, UNIT_MINUTE, ICON_TIMERCONF_PROGRAM = &#171;program&#187;CONF_DELAY_TIMER = &#171;delay_timer&#187;CONF_POWER = &#171;power&#187;CONF_SALT_MISSING = &#171;salt_missing&#187;CONF_HALF_LOAD = &#171;half_load&#187;CONF_RUNNING = &#171;running&#187;CONF_REMAINING_MINUTES = &#171;remaining_minutes&#187;AUTO_LOAD = [&#171;text_sensor&#187;, &#171;binary_sensor&#187;, &#171;sensor&#187;]CODEOWNERS = [&#171;&#187;]tm1638_sniffer_ns = cg.esphome_ns.namespace(&#171;tm1638_sniffer&#187;)TM1638Sniffer = tm1638_sniffer_ns.class_(&#171;TM1638Sniffer&#187;, cg.Component)CONFIG_SCHEMA = cv.Schema({    cv.GenerateID(): cv.declare_id(TM1638Sniffer),    cv.Optional(CONF_PROGRAM): text_sensor.text_sensor_schema(),    cv.Optional(CONF_DELAY_TIMER): text_sensor.text_sensor_schema(),    cv.Optional(CONF_POWER): binary_sensor.binary_sensor_schema(),    cv.Optional(CONF_SALT_MISSING): binary_sensor.binary_sensor_schema(),    cv.Optional(CONF_HALF_LOAD): binary_sensor.binary_sensor_schema(),    cv.Optional(CONF_RUNNING): binary_sensor.binary_sensor_schema(),    cv.Optional(CONF_REMAINING_MINUTES): sensor.sensor_schema(        unit_of_measurement=UNIT_MINUTE,        icon=ICON_TIMER,        accuracy_decimals=0,    ),}).extend(cv.COMPONENT_SCHEMA)async def to_code(config):    var = cg.new_Pvariable(config[CONF_ID])    await cg.register_component(var, config)    if CONF_PROGRAM in config:        sens = await text_sensor.new_text_sensor(config[CONF_PROGRAM])        cg.add(var.set_program_sensor(sens))    if CONF_DELAY_TIMER in config:        sens = await text_sensor.new_text_sensor(config[CONF_DELAY_TIMER])        cg.add(var.set_delay_timer_sensor(sens))    if CONF_POWER in config:        sens = await binary_sensor.new_binary_sensor(config[CONF_POWER])        cg.add(var.set_power_sensor(sens))    if CONF_SALT_MISSING in config:        sens = await binary_sensor.new_binary_sensor(config[CONF_SALT_MISSING])        cg.add(var.set_salt_missing_sensor(sens))    if CONF_HALF_LOAD in config:        sens = await binary_sensor.new_binary_sensor(config[CONF_HALF_LOAD])        cg.add(var.set_half_load_sensor(sens))    if CONF_RUNNING in config:        sens = await binary_sensor.new_binary_sensor(config[CONF_RUNNING])        cg.add(var.set_running_sensor(sens))    if CONF_REMAINING_MINUTES in config:        sens = await sensor.new_sensor(config[CONF_REMAINING_MINUTES])        cg.add(var.set_remaining_minutes_sensor(sens))tm1638_sniffer.cpp#include &#171;tm1638_sniffer.h&#187;#include &#171;esphome\/core\/log.h&#187;#include &lt;Arduino.h&gt;namespace esphome {namespace tm1638_sniffer {static const char *const TAG = &#171;tm1638_sniffer&#187;;#define PIN_DIO D5#define PIN_CLK D6#define PIN_STB D7volatile bool TM1638Sniffer::active_ = false;volatile uint8_t TM1638Sniffer::bit_count_ = 0;volatile uint8_t TM1638Sniffer::cur_byte_ = 0;volatile uint8_t TM1638Sniffer::buf_[128];volatile uint8_t TM1638Sniffer::len_ = 0;volatile bool TM1638Sniffer::ready_ = false;uint8_t TM1638Sniffer::last_buf_[14];uint8_t TM1638Sniffer::last_len_ = 0;void TM1638Sniffer::setup() {  pinMode(PIN_DIO, INPUT_PULLUP);  pinMode(PIN_CLK, INPUT_PULLUP);  pinMode(PIN_STB, INPUT_PULLUP);  attachInterrupt(digitalPinToInterrupt(PIN_STB), TM1638Sniffer::isr_stb, CHANGE);  attachInterrupt(digitalPinToInterrupt(PIN_CLK), TM1638Sniffer::isr_clk, RISING);  ESP_LOGI(TAG, &#171;TM1638 dishwasher sniffer started&#187;);}void TM1638Sniffer::loop() {  if (!ready_) return;  noInterrupts();  uint8_t local_len = len_;  if (local_len &lt; 4 || local_len &gt; 16) {    ready_ = false;    interrupts();    return;  }  uint8_t local_buf[128];  for (uint8_t i = 0; i &lt; local_len; i++) {    local_buf[i] = buf_[i];  }  ready_ = false;  interrupts();  if (local_buf[0] != 0xC0) return;  if (local_len &lt; 14) return;  local_len = 14;  bool same = last_len_ == local_len;  if (same) {    for (uint8_t i = 0; i &lt; local_len; i++) {      if (local_buf[i] != last_buf_[i]) {        same = false;        break;      }    }  }  if (!same) {    last_len_ = local_len;    for (uint8_t i = 0; i &lt; local_len; i++) {      last_buf_[i] = local_buf[i];    }    std::string out = &#171;display changed:&#187;;    char tmp[8];    for (uint8_t i = 0; i &lt; local_len; i++) {      snprintf(tmp, sizeof(tmp), &#187; %02X&#187;, local_buf[i]);      out += tmp;    }    ESP_LOGD(TAG, &#171;%s&#187;, out.c_str());    decode_packet_(local_buf, local_len);  } else {    \/\/ \u0414\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0434\u0438\u0441\u043f\u043b\u0435\u0439 \u043d\u0435 \u043c\u0435\u043d\u044f\u043b\u0441\u044f, \u0442\u0430\u0439\u043c\u0435\u0440 \u043e\u0441\u0442\u0430\u0442\u043a\u0430 \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0440\u0430\u0437 \u0432 \u043c\u0438\u043d\u0443\u0442\u0443.    static uint32_t last_timer_update_ms = 0;    uint32_t now = millis();    if (was_running_ &amp;&amp; selected_duration_min_ &gt; 0 &amp;&amp; now &#8212; last_timer_update_ms &gt; 60000) {      last_timer_update_ms = now;      uint32_t elapsed_min = (now &#8212; started_at_ms_) \/ 60000;      int remaining = selected_duration_min_ &#8212; elapsed_min;      if (remaining &lt; 0) remaining = 0;      if (remaining_minutes_sensor_ != nullptr) {        remaining_minutes_sensor_-&gt;publish_state(remaining);      }    }  }}int TM1638Sniffer::program_duration_minutes_(const std::string &amp;program) {  if (program == &#171;\u042d\u043a\u043e&#187;) return 175;  if (program == &#171;\u0414\u0435\u043b\u0438\u043a\u0430\u0442\u043d\u0430\u044f&#187;) return 110;  if (program == &#171;90 \u043c\u0438\u043d&#187;) return 90;  if (program == &#171;\u0411\u044b\u0441\u0442\u0440\u0430\u044f&#187;) return 40;  if (program == &#171;\u0418\u043d\u0442\u0435\u043d\u0441\u0438\u0432\u043d\u0430\u044f&#187;) return 130;  if (program == &#171;\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f&#187;) return 155;  return 0;}void TM1638Sniffer::decode_packet_(uint8_t *d, uint8_t len) {  if (len &lt; 14) return;  bool power = d[2] &amp; 0x01;  bool salt_missing = d[6] &amp; 0x01;  bool half_load = d[8] &amp; 0x01;  bool any_program_led =      (d[6] &amp; 0x02) ||      (d[8] &amp; 0x02) ||      (d[10] &amp; 0x02) ||      (d[12] &amp; 0x02) ||      (d[2] &amp; 0x02) ||      (d[4] &amp; 0x02);  std::string program = &#171;\u041d\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u0430&#187;;  if (d[6] &amp; 0x02) {    program = &#171;\u042d\u043a\u043e&#187;;  } else if (d[8] &amp; 0x02) {    program = &#171;\u0414\u0435\u043b\u0438\u043a\u0430\u0442\u043d\u0430\u044f&#187;;  } else if (d[10] &amp; 0x02) {    program = &#171;90 \u043c\u0438\u043d&#187;;  } else if (d[12] &amp; 0x02) {    program = &#171;\u0411\u044b\u0441\u0442\u0440\u0430\u044f&#187;;  } else if (d[2] &amp; 0x02) {    program = &#171;\u0418\u043d\u0442\u0435\u043d\u0441\u0438\u0432\u043d\u0430\u044f&#187;;  } else if (d[4] &amp; 0x02) {    program = &#171;\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f&#187;;  }  if (any_program_led) {    program_was_selected_ = true;    selected_program_ = program;    selected_duration_min_ = program_duration_minutes_(program);  }  bool running = power &amp;&amp; program_was_selected_ &amp;&amp; !any_program_led;  if (!power) {    program_was_selected_ = false;    was_running_ = false;    started_at_ms_ = 0;    selected_duration_min_ = 0;    selected_program_ = &#171;\u041d\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u0430&#187;;  }  if (running &amp;&amp; !was_running_) {    was_running_ = true;    started_at_ms_ = millis();    if (selected_duration_min_ == 0) {      selected_duration_min_ = program_duration_minutes_(selected_program_);    }    ESP_LOGI(TAG, &#171;Dishwasher started: program=%s duration=%d min&#187;,             selected_program_.c_str(), selected_duration_min_);  }  if (!running &amp;&amp; was_running_) {    was_running_ = false;    ESP_LOGI(TAG, &#171;Dishwasher stopped or finished&#187;);  }  int remaining = 0;  if (running &amp;&amp; selected_duration_min_ &gt; 0) {    uint32_t elapsed_min = (millis() &#8212; started_at_ms_) \/ 60000;    remaining = selected_duration_min_ &#8212; elapsed_min;    if (remaining &lt; 0) remaining = 0;  }  std::string delay = &#171;\u0412\u044b\u043a\u043b\u044e\u0447\u0435\u043d&#187;;  if (d[1] &amp; 0x80) {    delay = &#171;3 \u0447\u0430\u0441\u0430&#187;;  } else if (d[3] &amp; 0x80) {    delay = &#171;6 \u0447\u0430\u0441\u043e\u0432&#187;;  } else if (d[5] &amp; 0x80) {    delay = &#171;9 \u0447\u0430\u0441\u043e\u0432&#187;;  } else if (d[7] &amp; 0x80) {    delay = &#171;12 \u0447\u0430\u0441\u043e\u0432&#187;;  }  if (program_sensor_ != nullptr) {    program_sensor_-&gt;publish_state(any_program_led ? program : selected_program_);  }  if (delay_timer_sensor_ !=&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-481042","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/481042","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=481042"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/481042\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=481042"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=481042"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=481042"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}