{"id":469872,"date":"2025-08-07T03:03:20","date_gmt":"2025-08-07T03:03:20","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=469872"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=469872","title":{"rendered":"<span>\u0412\u0435\u0431-\u043a\u0430\u043c\u0435\u0440\u0430 \u2014 \u0433\u043b\u0430\u0437\u0430 \u0440\u043e\u0431\u043e\u0442\u0430. \u041f\u0438\u0448\u0443 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 FastApi \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f DIY-\u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c. \u0427\u0430\u0441\u0442\u044c 3<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bb5\/310\/a67\/bb5310a67ce565b9ee5ce44c5127139f.png\" width=\"780\" height=\"440\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/bb5\/310\/a67\/bb5310a67ce565b9ee5ce44c5127139f.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bb5\/310\/a67\/bb5310a67ce565b9ee5ce44c5127139f.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 <a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/919060\/\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0435<\/a> \u044f \u043f\u043e\u043a\u0430\u0437\u0430\u043b, \u043a\u0430\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 Orange Pi Zero \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b. \u041d\u0430\u043f\u0438\u0441\u0430\u043b \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0439 \u043f\u0440\u043e\u043a\u0441\u0438 \u043d\u0430 Nginx, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0438\u0434\u0435\u043e\u0441\u0442\u0440\u0438\u043c. \u0422\u0430\u043a\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b \u0441\u0435\u0440\u0432\u0438\u0441 robot_pi_service \u0434\u043b\u044f \u043f\u0440\u0438\u0451\u043c\u0430 \u043a\u043e\u043c\u0430\u043d\u0434 \u043e\u0442 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432. \u0412 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u043a\u043e\u0434 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043e\u043c\u0430\u043d\u0434 \u0440\u043e\u0431\u043e\u0442\u0443 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u043e\u0432.<\/p>\n<p>\u0412 \u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c GPIO-\u043f\u0438\u043d\u0430\u043c\u0438 \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u0438\u043a\u0430 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 Orange Pi Zero \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Python. \u042f \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434 (LED) \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u043c \u0447\u0435\u0440\u0435\u0437 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u043e\u0432\u0435\u0434\u0443 \u043e\u0442\u043b\u0430\u0434\u043a\u0443 \u0437\u0430\u0434\u0435\u0440\u0436\u0435\u043a.<\/p>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u0430 \u043b\u044e\u0431\u0438\u0442\u0435\u043b\u044f\u043c DIY-\u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0438 \u0432\u0435\u0431-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c, \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0449\u0438\u043c\u0441\u044f \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u043c FastAPI.<\/p>\n<h3>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 GPIO \u043d\u0430 \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u0438\u043a\u0435<\/h3>\n<p>GPIO (General Purpose Input\/Output) \u2014 \u044d\u0442\u043e \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0438\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u043c\u0435\u044e\u0442\u0441\u044f \u043a\u0430\u043a \u043d\u0430 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430\u0445, \u0442\u0430\u043a \u0438 \u043d\u0430 \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430\u0445, \u0438 \u043c\u043e\u0433\u0443\u0442 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e \u0434\u043b\u044f \u043f\u0440\u0438\u0451\u043c\u0430 \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0446\u0438\u0444\u0440\u043e\u0432\u044b\u0445 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432. \u0421 \u0438\u0445 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043c\u043e\u0436\u0435\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u043c\u0438\u0440\u043e\u043c \u2014 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u0434\u0430\u0442\u0447\u0438\u043a\u043e\u0432 \u0438\u043b\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u0430\u043c\u0438, \u0440\u0435\u043b\u0435 \u0438 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438.<\/p>\n<p>\u0417\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 \u0447\u0435\u043c-\u0442\u043e \u043d\u043e\u0432\u044b\u043c \u0447\u0430\u0441\u0442\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442 \u0441 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e. \u0418\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u044f\u0437\u044b\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u2014 \u0441 \u0432\u044b\u0432\u043e\u0434\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 Hello, World!, \u0430 \u043f\u0435\u0440\u0432\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 GPIO \u2014 \u0441 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043e\u043c (LED).<\/p>\n<p>\u0414\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f LED \u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0443 \u0435\u0433\u043e \u043a GPIO \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u0438\u043a\u0430. \u041d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u0438\u043a\u0435 \u0441\u0445\u0435\u043c\u0430 \u043f\u043e\u0440\u0442\u043e\u0432 GPIO \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/693\/731\/8fb\/6937318fb121fe5da7c50a09fb33e34e.png\" alt=\"\u0420\u0430\u0441\u043f\u0438\u043d\u043e\u0432\u043a\u0430 GPIO \u0434\u043b\u044f Orange Pi Zero H+\" title=\"\u0420\u0430\u0441\u043f\u0438\u043d\u043e\u0432\u043a\u0430 GPIO \u0434\u043b\u044f Orange Pi Zero H+\" width=\"1000\" height=\"524\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/693\/731\/8fb\/6937318fb121fe5da7c50a09fb33e34e.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/693\/731\/8fb\/6937318fb121fe5da7c50a09fb33e34e.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption><em>\u0420\u0430\u0441\u043f\u0438\u043d\u043e\u0432\u043a\u0430 GPIO \u0434\u043b\u044f Orange Pi Zero H+<\/em><\/figcaption><\/div>\n<\/figure>\n<p><strong>\u0414\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u0430 \u043c\u043d\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0434\u0432\u0430 \u043f\u0438\u043d\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p>PWM1 (PA6) \u2014 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0438\u043d 20;<\/p>\n<\/li>\n<li>\n<p>GND \u2014 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0438\u043d 7 (\u0437\u0435\u043c\u043b\u044f).<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u0421\u0445\u0435\u043c\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f LED:<\/strong><\/p>\n<ul>\n<li>\n<p>PWM1 (PA6) \u2192 \u0440\u0435\u0437\u0438\u0441\u0442\u043e\u0440 150 \u041e\u043c \u2192 \u0430\u043d\u043e\u0434 LED (\u0434\u043b\u0438\u043d\u043d\u0430\u044f \u043d\u043e\u0436\u043a\u0430);<\/p>\n<\/li>\n<li>\n<p>GND \u2192 \u043a\u0430\u0442\u043e\u0434 LED (\u043a\u043e\u0440\u043e\u0442\u043a\u0430\u044f \u043d\u043e\u0436\u043a\u0430).<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0435\u0437\u0438\u0441\u0442\u043e\u0440 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u0435\u043d \u2014 \u043e\u043d \u0441\u043d\u0438\u0436\u0430\u0435\u0442 \u0441\u0438\u043b\u0443 \u0442\u043e\u043a\u0430, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0441\u043f\u0430\u043b\u0438\u0442\u044c \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2e1\/a74\/563\/2e1a74563cfa3b48d74bef4e5907dc9c.jpeg\" alt=\"\u0424\u043e\u0442\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u0433\u043e LED \u043a \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u0438\u043a\u0443\" title=\"\u0424\u043e\u0442\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u0433\u043e LED \u043a \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u0438\u043a\u0443\" width=\"800\" height=\"680\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/2e1\/a74\/563\/2e1a74563cfa3b48d74bef4e5907dc9c.jpeg 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2e1\/a74\/563\/2e1a74563cfa3b48d74bef4e5907dc9c.jpeg 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption><em>\u0424\u043e\u0442\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u0433\u043e LED \u043a \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u0438\u043a\u0443<\/em><\/figcaption><\/div>\n<\/figure>\n<p><strong>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 GPIO \u044f \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 gpiod \u0432 Armbian Linux \u043d\u0430 \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u0438\u043a\u0435:<\/strong><\/p>\n<pre><code class=\"bash\">sudo apt install gpiod<\/code><\/pre>\n<p><strong>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 gpiod \u0432 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 Python:<\/strong><\/p>\n<pre><code class=\"bash\">pip install gpiod<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 GPIO \u043a\u0430\u043a \u0438\u0437 Linux, \u0442\u0430\u043a \u0438 \u0438\u0437 Python. \u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e, \u043a\u0430\u043a\u0438\u0435 GPIO-\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438.<\/p>\n<pre><code class=\"bash\">gpiodetect<\/code><\/pre>\n<p><strong>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:<\/strong><\/p>\n<pre><code class=\"bash\">gpiochip0 [1c20800.pinctrl] (224 lines)   gpiochip1 [1f02c00.pinctrl] (32 lines)<\/code><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u043e\u0440 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p>gpiochip0 \u0438 gpiochip1 \u2014 \u044d\u0442\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 GPIO-\u0447\u0438\u043f\u043e\u0432, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0447\u0435\u0440\u0435\u0437 \/dev\/gpiochip*;<\/p>\n<\/li>\n<li>\n<p>1c20800.pinctrl \u0438 1f02c00.pinctrl \u2014 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u043e\u0432 \u0438\u043b\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u044d\u0442\u0438 \u0447\u0438\u043f\u044b. \u041e\u043d\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u044f\u0434\u0440\u043e\u043c Linux (\u043e\u0431\u044b\u0447\u043d\u043e \u0438\u0437 Device Tree);<\/p>\n<\/li>\n<li>\n<p>(224 lines) \u0438 (32 lines) \u2014 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e GPIO-\u043b\u0438\u043d\u0438\u0439, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0447\u0438\u043f\u0435. \u042d\u0442\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u0442, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0432\u0445\u043e\u0434\u043e\u0432\/\u0432\u044b\u0445\u043e\u0434\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<\/li>\n<\/ul>\n<p>\u041c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e gpiochip0, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043e\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 GPIO-\u043f\u0438\u043d\u043e\u0432. \u041d\u0430 \u044d\u0442\u043e\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u044f \u043d\u0430\u0439\u0434\u0443 \u043d\u0443\u0436\u043d\u0443\u044e \u043c\u043d\u0435 \u043b\u0438\u043d\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0443\u0436\u043d\u0430 \u043c\u043d\u0435 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f LED.<\/p>\n<p><strong>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043b\u0438\u043d\u0438\u0439:<\/strong><\/p>\n<pre><code class=\"bash\">gpioinfo gpiochip0<\/code><\/pre>\n<p><strong>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:<\/strong><\/p>\n<pre><code class=\"bash\">gpiochip0 - 224 lines:        line   0:      unnamed       unused   input  active-high            line   1:      unnamed       unused   input  active-high            line   2:      unnamed       unused   input  active-high            line   3:      unnamed       unused   input  active-high            line   4:      unnamed       unused   input  active-high            line   5:      unnamed       unused   input  active-high            line   6:      unnamed       unused  output  active-high        ...<\/code><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u043e\u0440 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p>gpiochip0 &#8212; 224 lines: \u2014 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 224 \u043b\u0438\u043d\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u043c\u0438 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u043a\u0430\u043d\u0430\u043b\u0430\u043c\u0438;<\/p>\n<\/li>\n<li>\n<p>line \u2014 \u0438\u043d\u0434\u0435\u043a\u0441 \u043b\u0438\u043d\u0438\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \u0447\u0438\u043f\u0430;<\/p>\n<\/li>\n<li>\n<p>unnamed \u2014 \u043b\u0438\u043d\u0438\u044f \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0438\u043c\u0435\u043d\u0438;<\/p>\n<\/li>\n<li>\n<p>unused \u2014 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p>output \u2014 \u043b\u0438\u043d\u0438\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434 (\u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f LED, \u0437\u0443\u043c\u043c\u0435\u0440\u0430\u043c\u0438 \u0438 \u0442. \u0434.);<\/p>\n<\/li>\n<li>\n<p>input \u2014 \u043b\u0438\u043d\u0438\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u043d\u0430 \u0432\u0445\u043e\u0434 (\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043a\u043d\u043e\u043f\u043e\u043a, \u0434\u0430\u0442\u0447\u0438\u043a\u043e\u0432);<\/p>\n<\/li>\n<li>\n<p>active-high \u2014 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0438\u0433\u043d\u0430\u043b \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0435\u0434\u0438\u043d\u0438\u0446\u0435 (HIGH).<\/p>\n<\/li>\n<\/ul>\n<p>\u041c\u043d\u0435 \u043d\u0443\u0436\u043d\u0430 line 6, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 PA6 \u043d\u0430 GPIO Orange Pi. \u0415\u0451 \u044f \u0438 \u0431\u0443\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f LED.<\/p>\n<p><strong>\u041f\u043e\u0434\u0430\u044e \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0435\u0434\u0438\u043d\u0438\u0446\u0443, \u0447\u0442\u043e\u0431\u044b \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c LED \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0435\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u0443:<\/strong><\/p>\n<pre><code class=\"bash\">sudo gpioset gpiochip0 6=1<\/code><\/pre>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/384\/dbf\/11f\/384dbf11f216d4a78ae558c5728b9e25.jpeg\" alt=\"\u0424\u043e\u0442\u043e \u0433\u043e\u0440\u044f\u0449\u0435\u0433\u043e LED\" title=\"\u0424\u043e\u0442\u043e \u0433\u043e\u0440\u044f\u0449\u0435\u0433\u043e LED\" width=\"800\" height=\"907\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/384\/dbf\/11f\/384dbf11f216d4a78ae558c5728b9e25.jpeg 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/384\/dbf\/11f\/384dbf11f216d4a78ae558c5728b9e25.jpeg 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption><em>\u0424\u043e\u0442\u043e \u0433\u043e\u0440\u044f\u0449\u0435\u0433\u043e LED<\/em><\/figcaption><\/div>\n<\/figure>\n<p>\u041a\u0440\u0430\u0441\u043d\u044b\u0439 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0437\u0430\u0433\u043e\u0440\u0435\u043b\u0441\u044f. \u041f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430 \u044f \u0435\u0433\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u043b, \u043f\u0435\u0440\u0435\u043f\u0443\u0442\u0430\u043b \u043f\u0440\u043e\u0432\u043e\u0434\u0430 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b, \u0432\u043a\u043b\u044e\u0447\u0451\u043d \u043b\u0438 LED \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e.<\/p>\n<p><strong>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043b\u0438\u043d\u0438\u0438:<\/strong><\/p>\n<pre><code class=\"bash\">sudo gpioget gpiochip0 6<\/code><\/pre>\n<p><strong>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:<\/strong><\/p>\n<pre><code class=\"bash\">1<\/code><\/pre>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 1 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e line 6 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430 (HIGH).<\/p>\n<p><strong>\u0414\u043b\u044f \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u0430\u044e 0:<\/strong><\/p>\n<pre><code class=\"bash\">sudo gpioset gpiochip0 6=0<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 GPIO \u0431\u0435\u0437 sudo, \u043d\u0443\u0436\u043d\u044b \u043f\u0440\u0430\u0432\u0430 \u0441\u0443\u043f\u0435\u0440\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u042f \u043d\u0430\u043f\u0438\u0448\u0443 \u0441\u043a\u0440\u0438\u043f\u0442 sh, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0433\u0440\u0443\u043f\u043f\u0443 gpio \u0438 \u0434\u0430\u0441\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0434\u043e\u0441\u0442\u0443\u043f \u043a GPIO.<\/p>\n<p><strong>\u0424\u0430\u0439\u043b gpio_<\/strong><a href=\"http:\/\/setup.sh\" rel=\"noopener noreferrer nofollow\"><strong>setup.sh<\/strong><\/a><strong>:<\/strong><\/p>\n<pre><code class=\"bash\">#!\/bin\/bash chmod -R +x robot_pi_service\/ sudo groupadd gpio sudo usermod -aG gpio $USER echo 'SUBSYSTEM==\"gpio\", KERNEL==\"gpiochip[0-9]*\", GROUP=\"gpio\", MODE=\"0660\"' | sudo tee \/etc\/udev\/rules.d\/99-gpio.rules sudo udevadm control --reload-rules sudo udevadm trigger<\/code><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u043e\u0440 \u0441\u043a\u0440\u0438\u043f\u0442\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p>sudo groupadd gpio \u2014 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0433\u0440\u0443\u043f\u043f\u0443 gpio;<\/p>\n<\/li>\n<li>\n<p>sudo usermod -aG gpio $USER \u2014 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0433\u0440\u0443\u043f\u043f\u0443 gpio;<\/p>\n<\/li>\n<li>\n<p>echo &#8230; | sudo tee &#8230; \u2014 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u043e udev, \u0447\u0442\u043e\u0431\u044b \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 gpiochip \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0430\u043b\u0438 \u0433\u0440\u0443\u043f\u043f\u0435 gpio \u0438 \u0438\u043c\u0435\u043b\u0438 \u043f\u0440\u0430\u0432\u0430 0660;<\/p>\n<\/li>\n<li>\n<p>sudo udevadm control &#8212;reload-rules \u2014 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 udev;<\/p>\n<\/li>\n<li>\n<p>sudo udevadm trigger \u2014 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043a \u0443\u0436\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u043c.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u043a\u0440\u0438\u043f\u0442 gpio_<a href=\"http:\/\/setup.sh\" rel=\"noopener noreferrer nofollow\">setup.sh<\/a> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0440\u0430\u0437. \u0412 \u043d\u0435\u0433\u043e \u044f \u043f\u0435\u0440\u0435\u043d\u0451\u0441 \u0441\u0442\u0440\u043e\u043a\u0443 chmod -R +x robot_pi_service\/ \u0438\u0437 Makefile, \u0447\u0442\u043e\u0431\u044b \u0434\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0430 \u043d\u0430 \u043f\u0430\u043f\u043a\u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 GPIO \u0431\u0435\u0437 sudo \u0438\u0437 Python.<\/p>\n<p><strong>\u0414\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u0443 \u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435:<\/strong><\/p>\n<pre><code class=\"bash\">chmod +x gpio_setup.sh<\/code><\/pre>\n<p><strong>\u0417\u0430\u043f\u0443\u0441\u043a \u0441\u043a\u0440\u0438\u043f\u0442\u0430:<\/strong><\/p>\n<pre><code class=\"bash\">.\/gpio_setup.sh<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u0430\u0432\u0430 \u0432\u0441\u0442\u0443\u043f\u0438\u043b\u0438 \u0432 \u0441\u0438\u043b\u0443, \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0439\u0442\u0438 \u0438\u0437 \u0441\u0435\u0441\u0441\u0438\u0438 \u0438 \u0432\u043e\u0439\u0442\u0438 \u0437\u0430\u043d\u043e\u0432\u043e. \u042f \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0449\u0443 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e:<\/p>\n<pre><code class=\"bash\">sudo shutdown -h now<\/code><\/pre>\n<p><strong>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0433\u0440\u0443\u043f\u043f:<\/strong><\/p>\n<pre><code class=\"bash\">groups<\/code><\/pre>\n<p><strong>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:<\/strong><\/p>\n<pre><code class=\"bash\">user_name sudo users gpio<\/code><\/pre>\n<p>\u0413\u0440\u0443\u043f\u043f\u0430 gpio \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c. GPIO \u0438 LED \u0433\u043e\u0442\u043e\u0432\u044b \u043a \u0440\u0430\u0431\u043e\u0442\u0435 \u2014 \u043f\u043e\u0440\u0430 \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434.<\/p>\n<h3>\u041a\u043e\u0434 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h3>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u0438\u043d\u043d\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 poetry run uvicorn web_robot_control.main:app &#8212;host server_ip &#8212;port port_number \u043d\u0435\u0443\u0434\u043e\u0431\u043d\u043e. \u042f \u0445\u043e\u0447\u0443 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a, \u043d\u0430\u043f\u0438\u0441\u0430\u0432 \u0441\u043a\u0440\u0438\u043f\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0434\u043b\u044f Poetry. \u0412 \u043f\u0430\u043a\u0435\u0442\u0435 web_robot_control \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u0444\u0430\u0439\u043b <a href=\"http:\/\/start.py\" rel=\"noopener noreferrer nofollow\">start.py<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0447\u0435\u0440\u0435\u0437 uvicorn.<\/p>\n<p><strong>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 uvicorn \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e poetry:<\/strong><\/p>\n<pre><code class=\"bash\">poetry add uvicorn<\/code><\/pre>\n<p><strong>\u0421\u043a\u0440\u0438\u043f\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430:<\/strong><\/p>\n<pre><code class=\"python\">import uvicorn   def start_app():     \"\"\"\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\"\"\"          uvicorn.run(         'web_robot_control.main:app',          host='127.0.0.1',         port=8000,         reload=True     ) <\/code><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u043e\u0440 \u043a\u043e\u0434\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p>import uvicorn \u2014 \u0438\u043c\u043f\u043e\u0440\u0442 ASGI-\u0441\u0435\u0440\u0432\u0435\u0440\u0430 uvicorn, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0433\u043e \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 FastAPI-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p><a href=\"http:\/\/uvicorn.run\" rel=\"noopener noreferrer nofollow\">uvicorn.run<\/a>(&#8230;) \u2014 \u0432\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u0430 run \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:<\/p>\n<\/li>\n<li>\n<p>&#8216;web_robot_control.main:app&#8217; \u2014 \u043f\u0443\u0442\u044c \u043a FastAPI-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e: \u043c\u043e\u0434\u0443\u043b\u044c main \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0430\u043a\u0435\u0442\u0430 web_robot_control, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 app;<\/p>\n<\/li>\n<li>\n<p>host=&#8217;127.0.0.1&#8242; \u2014 \u0441\u0435\u0440\u0432\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u0435 \u043d\u0430 ip 127.0.0.1;<\/p>\n<\/li>\n<li>\n<p>port=8000 \u2014 \u0441\u0435\u0440\u0432\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0443\u0448\u0430\u0442\u044c \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 8000;<\/p>\n<\/li>\n<li>\n<p>reload=True \u2014 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 (\u0443\u0434\u043e\u0431\u043d\u043e \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438);<\/p>\n<\/li>\n<li>\n<p>\u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c ip \u0438 port \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0447\u0438\u0442\u0430\u0442\u044c\u0441\u044f \u0438\u0437 .env \u0444\u0430\u0439\u043b\u0430, \u0447\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c Poetry, \u0433\u0434\u0435 \u0438\u0441\u043a\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0437\u0430\u043f\u0443\u0441\u043a\u0430.<\/p>\n<p><strong>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 pyproject.toml:<\/strong><\/p>\n<p>[tool.poetry.scripts]<br \/> start_app = &#171;web_robot_control.start:start_app&#187;<\/p>\n<p><strong>\u0420\u0430\u0437\u0431\u043e\u0440 \u043d\u043e\u0432\u044b\u0445 \u0441\u0442\u0440\u043e\u043a:<\/strong><\/p>\n<ul>\n<li>\n<p>[tool.poetry.scripts] \u2014 \u0441\u0435\u043a\u0446\u0438\u044f \u0432 pyproject.toml, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043f\u043e\u0441\u043b\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043f\u0430\u043a\u0435\u0442\u0430;<\/p>\n<\/li>\n<li>\n<p>start_app \u2014 \u0438\u043c\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0438\u0437 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0430;<\/p>\n<\/li>\n<li>\n<p>&#171;web_robot_control.start:start_app&#187; \u2014 \u043f\u0443\u0442\u044c \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:<\/p>\n<\/li>\n<\/ul>\n<ul>\n<li>\n<p>web_robot_control \u2014 \u0438\u043c\u044f Python-\u043f\u0430\u043a\u0435\u0442\u0430;<\/p>\n<\/li>\n<li>\n<p>start \u2014 \u043c\u043e\u0434\u0443\u043b\u044c \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0430\u043a\u0435\u0442\u0430;<\/p>\n<\/li>\n<li>\n<p>start_app \u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u043e\u0434\u0443\u043b\u044f <a href=\"http:\/\/start.py\" rel=\"noopener noreferrer nofollow\">start.py<\/a>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d\u0430.<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443 start_app:<\/strong><\/p>\n<pre><code class=\"bash\">poetry install<\/code><\/pre>\n<p><strong>\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0432 \u0444\u0430\u0439\u043b\u0435<\/strong> <a href=\"http:\/\/README.md\" rel=\"noopener noreferrer nofollow\">README.md<\/a><strong>:<\/strong><\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a \u0434\u043b\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438: <code><strong><em>poetry run start_app<\/em><\/strong><\/code><\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u044f \u0438\u0437\u043c\u0435\u043d\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440. \u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u044f \u0431\u0443\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0443 \u043a\u043b\u044e\u0447\u2013\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0433\u0434\u0435 \u043a\u043b\u044e\u0447 \u2014 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u2014 \u0435\u0451 \u0441\u0442\u0430\u0442\u0443\u0441. \u0424\u0440\u043e\u043d\u0442\u0435\u043d\u0434 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 JSON \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440. \u0414\u043b\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b forward \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a\u043e\u0439:<\/p>\n<ul>\n<li>\n<p>{&#171;forward&#187;: True} \u2014 \u0434\u043b\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f LED;<\/p>\n<\/li>\n<li>\n<p>{&#171;forward&#187;: False} \u2014 \u0434\u043b\u044f \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f LED.<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0432 command.js \u0434\u043b\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b forward:<\/strong><\/p>\n<pre><code class=\"javascript\">\/\/ \u0414\u0440\u0443\u0433\u043e\u0439 \u043a\u043e\u0434 \/\/ \u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0434\u043b\u044f \u043a\u043d\u043e\u043f\u043a\u0438 \"\u0412\u043f\u0435\u0440\u0451\u0434\" const forwardButton = document.getElementById(\"forward-button\"); const forwardOn = { \"forward\": true }; forwardButton.addEventListener(\"mousedown\", () =&gt; startSendingCommand(forwardOn)); \/\/ \u041d\u0430\u0447\u0430\u043b\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b const forwardOff = { \"forward\": false }; forwardButton.addEventListener(\"mouseup\", () =&gt; {     sendCommand(JSON.stringify(forwardOff));     stopSendingCommand(); }); \/\/ \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b forwardOff \u0438 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043f\u0440\u0438 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u043d\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438 forwardButton.addEventListener(\"mouseleave\", stopSendingCommand);  \/\/ \u041e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438, \u0435\u0441\u043b\u0438 \u043a\u0443\u0440\u0441\u043e\u0440 \u0443\u0445\u043e\u0434\u0438\u0442 \u0441 \u043a\u043d\u043e\u043f\u043a\u0438 \/\/ \u0414\u0440\u0443\u0433\u043e\u0439 \u043a\u043e\u0434<\/code><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u043e\u0440 \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u0434\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p>const forwardOn = { &#171;forward&#187;: true }; \u2014 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442 forwardOn, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0432\u043f\u0435\u0440\u0451\u0434. \u041a\u043b\u044e\u0447 &#171;forward&#187; \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u0432 true, \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 (\u043f\u043e\u043a\u0430 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 LED);<\/p>\n<\/li>\n<li>\n<p>startSendingCommand(forwardOn); \u2014 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f startSendingCommand \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c forwardOn \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430. \u042d\u0442\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 WebSocket;<\/p>\n<\/li>\n<li>\n<p>const forwardOff = { &#171;forward&#187;: false }; \u2014 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442 forwardOff, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f. \u041a\u043b\u044e\u0447 &#171;forward&#187; \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u0432 false, \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043f\u0440\u0435\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f (\u043f\u043e\u043a\u0430 \u0432\u044b\u043a\u043b\u044e\u0447\u0430\u0435\u0442 LED);<\/p>\n<\/li>\n<li>\n<p>sendCommand(JSON.stringify(forwardOff)); \u2014 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f sendCommand, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438. \u041e\u0431\u044a\u0435\u043a\u0442 forwardOff \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0441\u0442\u0440\u043e\u043a\u0443 JSON \u043f\u0435\u0440\u0435\u0434 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u043e\u0439, \u0447\u0442\u043e\u0431\u044b \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043f\u043e \u0441\u0435\u0442\u0438. \u0412\u044b\u0437\u043e\u0432 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u043d\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438.<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c websocket_endpoint() \u0432 \u0431\u044d\u043a\u0435\u043d\u0434\u0435 \u043f\u043e\u0434 \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443:<\/strong><\/p>\n<ul>\n<li>\n<p>\u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 JSON, \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u044f \u0435\u0451 \u0432 dict;<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u0434\u043d\u0443 \u0438 \u0442\u0443 \u0436\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0434\u0432\u0430\u0436\u0434\u044b \u043f\u043e\u0434\u0440\u044f\u0434;<\/p>\n<\/li>\n<li>\n<p>\u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u0440\u0438 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 JSON.<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u041e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u044b\u0439 websocket_endpoint():<\/strong><\/p>\n<pre><code class=\"python\">@router.websocket('\/ws') async def websocket_endpoint(websocket: WebSocket) -&gt; None:     \"\"\"\u042d\u043d\u0434\u043f\u043e\u0438\u043d\u0442 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043a\u043e\u043c\u0430\u043d\u0434 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430\"\"\"          # \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441\u043e\u0434\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u043f\u043e \u0432\u0435\u0431-\u0441\u043e\u043a\u0435\u0442\u0443     await websocket.accept()          try:         previous_command = None                  while True:             # \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043e\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 (\u0441 \u0432\u0435\u0431-\u0441\u043e\u043a\u0435\u0442\u0430)             command = await websocket.receive_text()           if previous_command != command:                 previous_command = command                 valid_commands = settings.commands_robot.get_list_commands()                 data = loads(command)                 name_command = next(iter(data), None)                  if name_command in valid_commands:                     print(command)                     # \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0440\u043e\u0431\u043e\u0442\u0443                     robot_answer = await command_to_robot(command=command)                                          if robot_answer:                         # \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043e\u0442\u0432\u0435\u0442\u0430 \u0440\u043e\u0431\u043e\u0442\u0430 \u043d\u0430 \u0432\u0435\u0431\u0441\u043e\u043a\u0435\u0442 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430                         await websocket.send_text(                             f'\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430: {command}, \u043e\u0442\u0432\u0435\u0442 \u0440\u043e\u0431\u043e\u0442\u0430: {robot_answer}'                         )                         print(f'\u041e\u0442\u0432\u0435\u0442 \u0440\u043e\u0431\u043e\u0442\u0430: {robot_answer}')     except WebSocketDisconnect:         print('WebSocket \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d')  # Todo: \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u043e\u0448\u0438\u0431\u043e\u043a \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d logger     # Todo: \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0451 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435     except (WebSocketException, exceptions.InvalidMessage) as err:         print(f'{err.__class__.__name__}: {err}')     except JSONDecodeError:         print('\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 JSON') <\/code><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u043e\u0440 \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u0434\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p>previous_command = None \u2014 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b;<\/p>\n<\/li>\n<li>\n<p>if previous_command != command: \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u0434\u043d\u0443 \u0438 \u0442\u0443 \u0436\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e;<\/p>\n<\/li>\n<li>\n<p>data = loads(command) \u2014 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 JSON-\u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u0441\u043b\u043e\u0432\u0430\u0440\u044c;<\/p>\n<\/li>\n<li>\n<p>name_command = next(iter(data), None) \u2014 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0438\u043c\u0435\u043d\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0438\u0437 \u0441\u043b\u043e\u0432\u0430\u0440\u044f;<\/p>\n<\/li>\n<li>\n<p>except JSONDecodeError: \u2014 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u0440\u0438 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 JSON;<\/p>\n<\/li>\n<li>\n<p>print(&#8216;\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 JSON&#8217;) \u2014 \u0432\u044b\u0432\u043e\u0434 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 open-source \u043f\u0440\u043e\u0435\u043a\u0442\u00a0<a href=\"https:\/\/github.com\/Arduinum\/web-robot-control\/tree\/arduinum\/mvp_1\" rel=\"noopener noreferrer nofollow\"><strong>web-robot-control<\/strong><\/a><strong>.<\/strong><\/p>\n<h3>\u041a\u043e\u0434 \u0440\u043e\u0431\u043e\u0442\u0430<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043b LED \u043a GPIO \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b \u0435\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u0443 \u0432 Linux, \u044f \u043d\u0430\u043f\u0438\u0448\u0443 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434 \u043f\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u0435. \u041a\u043e\u043c\u0430\u043d\u0434\u0443 forward (\u0432\u043f\u0435\u0440\u0451\u0434) \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0434\u043b\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f LED \u2014 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435\u043c \u0440\u043e\u0431\u043e\u0442\u0430 \u0432\u043f\u0435\u0440\u0451\u0434.<\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 GPIO \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u0432 \u043f\u0430\u043a\u0435\u0442\u0435 robot_pi_service \u0444\u0430\u0439\u043b gpio_<a href=\"http:\/\/control.py\" rel=\"noopener noreferrer nofollow\">control.py<\/a>. \u0412 \u043d\u0451\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043a\u043b\u0430\u0441\u0441 LedLineGpio \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f LED \u0447\u0435\u0440\u0435\u0437 GPIO.<\/p>\n<p><strong>\u041c\u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b:<\/strong><\/p>\n<ol>\n<li>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u043c gpiochip0 \u0438 \u043b\u0438\u043d\u0438\u0435\u0439 line 6 \u0434\u043b\u044f LED;<\/p>\n<\/li>\n<li>\n<p>\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 LED.<\/p>\n<\/li>\n<\/ol>\n<p><strong>\u041a\u043e\u0434 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f LED:<\/strong><\/p>\n<pre><code class=\"python\">from gpiod import request_lines, LineSettings from gpiod.line import Direction, Value   class LedLineGpio:     \"\"\"\u041a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043b\u0438\u043d\u0438\u0435\u0439 GPIO \u0434\u043b\u044f LED\"\"\"          def __init__(self, line: int) -&gt; None:         self.line = line         self._request = request_lines(             '\/dev\/gpiochip0',             consumer='led-blinker',             config={                 line: LineSettings(                     direction=Direction.OUTPUT,                     output_value=Value.INACTIVE                 )             }         )      def on(self) -&gt; None:         \"\"\"\u041c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f LED\"\"\"                  self._request.set_value(self.line, Value.ACTIVE)      def off(self) -&gt; None:         \"\"\"\u041c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f LED\"\"\"                  self._request.set_value(self.line, Value.INACTIVE)      def close(self) -&gt; None:         \"\"\"\u041c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u0430\"\"\"                  self._request.release() <\/code><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u043e\u0440 \u043a\u043e\u0434\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p>\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f request_lines, LineSettings \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 gpiod, \u0430 \u0442\u0430\u043a\u0436\u0435 Direction \u0438 Value \u0438\u0437 gpiod.line;<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441 LedLineGpio \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0434\u043d\u043e\u0439 \u043b\u0438\u043d\u0438\u0435\u0439 GPIO, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0439 \u0434\u043b\u044f LED;<\/p>\n<\/li>\n<li>\n<p>\u0412 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 <strong>init<\/strong> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u043c\u0435\u0440 \u043b\u0438\u043d\u0438\u0438 GPIO \u043a\u0430\u043a \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440;<\/p>\n<\/li>\n<li>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f request_lines \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a gpiochip0 \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f &#8216;led-blinker&#8217; (\u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043f\u043e\u043d\u044f\u0442\u044c \u043a\u0442\u043e \u0437\u0430\u043d\u044f\u043b \u043b\u0438\u043d\u0438\u044e);<\/p>\n<\/li>\n<li>\n<p>\u0412 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043b\u0438\u043d\u0438\u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 OUTPUT \u0438 \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 INACTIVE;<\/p>\n<\/li>\n<li>\n<p>\u041c\u0435\u0442\u043e\u0434 on() \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u0435\u0442 \u043b\u0438\u043d\u0438\u044e, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 ACTIVE, \u0447\u0442\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434;<\/p>\n<\/li>\n<li>\n<p>\u041c\u0435\u0442\u043e\u0434 off() \u0432\u044b\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043b\u0438\u043d\u0438\u044e, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 INACTIVE;<\/p>\n<\/li>\n<li>\n<p>\u041c\u0435\u0442\u043e\u0434 close() \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0435\u0442 \u0440\u0435\u0441\u0443\u0440\u0441\u044b, \u0432\u044b\u0437\u0432\u0430\u0432 release() \u0443 \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u043d\u043e\u0439 \u043b\u0438\u043d\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p>\u041a\u043b\u0430\u0441\u0441 \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u0438\u0440\u0443\u0435\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 GPIO \u0432 \u043f\u0440\u043e\u0441\u0442\u043e\u043c API: \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438 \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u0435;<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c Python \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u043d\u0430\u0434 GPIO.<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e self._request.release() \u0434\u043b\u044f \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u0430, \u0442\u0430\u043a \u043a\u0430\u043a \u0432 request_lines() \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 with:<\/strong><\/p>\n<ul>\n<li>\n<p><strong>enter<\/strong>() \u2014 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0432\u0445\u043e\u0434\u0435 \u0432 with;<\/p>\n<\/li>\n<li>\n<p><strong>exit<\/strong>(exc_type, exc_val, exc_tb) \u2014 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0432\u044b\u0445\u043e\u0434\u0435 (\u0434\u0430\u0436\u0435 \u043f\u0440\u0438 \u043e\u0448\u0438\u0431\u043a\u0435).<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u044b\u0437\u043e\u0432 \u044d\u0442\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0432 \u043d\u0443\u0436\u043d\u044b\u0445 \u043c\u0435\u0441\u0442\u0430\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 robot_control_gpio(), \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0434\u043b\u044f \u0440\u043e\u0431\u043e\u0442\u0430 \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f.<\/p>\n<p><strong>\u042f \u0434\u043e\u0431\u0430\u0432\u043b\u044e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b:<\/strong><\/p>\n<ul>\n<li>\n<p>\u0412\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f LED;<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u0430 \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u043b\u0438\u043d\u0438\u0438 GPIO;<\/p>\n<\/li>\n<li>\n<p>\u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u0441\u0442\u0440\u043e\u043a\u0438 JSON.<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u041e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 robot_control_gpio():\u00a0<\/strong><\/p>\n<pre><code class=\"python\">import asyncio from websockets import serve, exceptions from websockets.legacy.server import WebSocketServerProtocol from json import loads, JSONDecodeError  from settings import settings from gpio_control import LedLineGpio   async def robot_control_gpio(websocket: WebSocketServerProtocol):     \"\"\"     \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f GPIO \u0440\u043e\u0431\u043e\u0442\u0430 (\u0447\u0435\u0440\u0435\u0437 websocket)     \"\"\"          try:         led_line_gpio = LedLineGpio(line=6)         action = None          while True:             try:                 command = await asyncio.wait_for(websocket.recv(), timeout=30.0)                 data = loads(command)             except asyncio.TimeoutError:                 print('\u0422\u0430\u0439\u043c\u0430\u0443\u0442 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043e\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0430')                 continue             except JSONDecodeError:                 print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 JSON\")                 continue              match next(iter(data), None):                 case settings.commands_robot.forward:                     if data.get(settings.commands_robot.forward):                         action = '\u0420\u043e\u0431\u043e\u0442 \u0435\u0434\u0435\u0442 \u0432\u043f\u0435\u0440\u0451\u0434'                         led_line_gpio.on()                     else:                         action = '\u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u0432\u043f\u0435\u0440\u0451\u0434 \u0441\u0442\u043e\u043f'                         led_line_gpio.off()                     print(action)                     await websocket.send(message=action)                 case settings.commands_robot.backward:                     action = '\u0420\u043e\u0431\u043e\u0442 \u0435\u0434\u0435\u0442 \u043d\u0430\u0437\u0430\u0434'                     print(action)                     await websocket.send(message=action)                 case settings.commands_robot.left:                     action = '\u0420\u043e\u0431\u043e\u0442 \u0435\u0434\u0435\u0442 \u043d\u0430\u043b\u0435\u0432\u043e'                     print(action)                     await websocket.send(message=action)                 case settings.commands_robot.right:                     action = '\u0420\u043e\u0431\u043e\u0442 \u0435\u0434\u0435\u0442 \u043d\u0430\u043f\u0440\u0430\u0432\u043e'                     print(action)                     await websocket.send(message=action)      except exceptions.ConnectionClosed:         pass     except (exceptions.ConnectionClosedOK, exceptions.InvalidMessage, exceptions.InvalidState) as err:         message_err = f'{err.__class__.__name__}: {err}'         print(message_err)         await websocket.send(message=message_err)     except Exception as err:         message_err = f'{err.__class__.__name__}: {err}'         print(message_err)         await websocket.send(message=message_err)     finally:         led_line_gpio.close() <\/code><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u043e\u0440 \u043e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p>from gpio_control import LedLineGpio \u2014 \u0418\u043c\u043f\u043e\u0440\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f GPIO-\u043b\u0438\u043d\u0438\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0438 \u0432\u044b\u043a\u043b\u044e\u0447\u0430\u0442\u044c LED;<\/p>\n<\/li>\n<li>\n<p>from json import loads, JSONDecodeError \u2014 \u0418\u043c\u043f\u043e\u0440\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 loads \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f JSON-\u0441\u0442\u0440\u043e\u043a\u0438 \u0432 Python-\u0441\u043b\u043e\u0432\u0430\u0440\u044c \u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f JSONDecodeError \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0448\u0438\u0431\u043e\u043a \u043f\u0440\u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0435;<\/p>\n<\/li>\n<li>\n<p>led_line_gpio = LedLineGpio(line=6) \u2014 \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 LedLineGpio \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f GPIO-\u043b\u0438\u043d\u0438\u0435\u0439 \u0441 \u043d\u043e\u043c\u0435\u0440\u043e\u043c 6. \u042d\u0442\u0430 \u043b\u0438\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0438\u043d\u0434\u0438\u043a\u0430\u0446\u0438\u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0440\u043e\u0431\u043e\u0442\u0430;<\/p>\n<\/li>\n<li>\n<p>action = None \u2014 \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 action, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0440\u043e\u0431\u043e\u0442\u0430 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u201c\u0435\u0434\u0435\u0442 \u0432\u043f\u0435\u0440\u0451\u0434\u201d);<\/p>\n<\/li>\n<li>\n<p>data = loads(command) \u2014 \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0439 JSON-\u0441\u0442\u0440\u043e\u043a\u0438 command \u0432 Python-\u0441\u043b\u043e\u0432\u0430\u0440\u044c data. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c\u0438 \u043a\u0430\u043a \u0441 \u043e\u0431\u044b\u0447\u043d\u044b\u043c\u0438 \u043a\u043b\u044e\u0447\u0430\u043c\u0438 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438;<\/p>\n<\/li>\n<li>\n<p>except JSONDecodeError: \u2014 \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u0432\u0445\u043e\u0434\u044f\u0449\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u043c JSON. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443, \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435;<\/p>\n<\/li>\n<li>\n<p>match next(iter(data), None): \u2014 \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 match (\u0430\u043d\u0430\u043b\u043e\u0433 switch) \u0434\u043b\u044f \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430 \u0432 \u0441\u043b\u043e\u0432\u0430\u0440\u0435 data \u0441 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u043c\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c\u0438 (\u0432\u043f\u0435\u0440\u0451\u0434, \u043d\u0430\u0437\u0430\u0434 \u0438 \u0442.\u0434.);<\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0440\u043e\u043a\u0430 next(iter(data), None) \u2014 \u044d\u0442\u043e \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u043a\u043b\u044e\u0447 \u0438\u0437 \u0441\u043b\u043e\u0432\u0430\u0440\u044f data, \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u0438 \u0431\u0435\u0437 \u043e\u0448\u0438\u0431\u043e\u043a, \u0435\u0441\u043b\u0438 \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u043f\u0443\u0441\u0442:<br \/>\u2014 iter(data) \u2014 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440 \u043f\u043e \u043a\u043b\u044e\u0447\u0430\u043c \u0441\u043b\u043e\u0432\u0430\u0440\u044f data;<br \/>\u2014 next(&#8230;, None) \u2014 \u0431\u0435\u0440\u0451\u0442 \u043f\u0435\u0440\u0432\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0438\u0437 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u0430.<br \/>\u2014 \u0415\u0441\u043b\u0438 \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u043f\u0443\u0441\u0442, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 None \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0438 StopIteration.<\/p>\n<\/li>\n<\/ul>\n<ul>\n<li>\n<p>if data.get(settings.commands_robot.forward) \u2014 \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430, \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043b\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u201c\u0432\u043f\u0435\u0440\u0451\u0434\u201d. \u0415\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u043a\u043b\u044e\u0447\u0443 forward \u2014 True, \u0440\u043e\u0431\u043e\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u043d\u0430\u0447\u0430\u0442\u044c \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435;<\/p>\n<\/li>\n<li>\n<p>led_line_gpio.on() \u2014 \u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 GPIO-\u043b\u0438\u043d\u0438\u0438 \u2014 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0437\u0430\u0436\u0438\u0433\u0430\u043d\u0438\u0435 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u0430, \u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u043e \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0438 \u0440\u043e\u0431\u043e\u0442\u0430;<\/p>\n<\/li>\n<li>\n<p>led_line_gpio.off() \u2014 \u0412\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 GPIO-\u043b\u0438\u043d\u0438\u0438 \u2014 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0438\u043d\u0434\u0438\u043a\u0430\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u201c\u0432\u043f\u0435\u0440\u0451\u0434\u201d \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u0430;<\/p>\n<\/li>\n<li>\n<p>finally: \u2014 \u0411\u043b\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u2014 \u0434\u0430\u0436\u0435 \u043f\u0440\u0438 \u043e\u0448\u0438\u0431\u043a\u0430\u0445. \u0417\u0434\u0435\u0441\u044c \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f led_line_gpio.close() \u0434\u043b\u044f \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u044f GPIO-\u0440\u0435\u0441\u0443\u0440\u0441\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u0435\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<p><strong>\u0424\u0443\u043d\u043a\u0446\u0438\u044f start():<\/strong><\/p>\n<pre><code class=\"python\">async def start():     \"\"\"\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0432\u0435\u0431\u0441\u043e\u043a\u0435\u0442\u0430 \u0438 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430\"\"\"      print('\u0421\u0442\u0430\u0440\u0442 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0440\u043e\u0431\u043e\u0442\u0430 \u0434\u043b\u044f \u043f\u0440\u0438\u0451\u043c\u0430 \u043a\u043e\u043c\u0430\u043d\u0434.')      async with serve(handler=robot_control_gpio, host=settings.websocket_host, port=settings.websocket_port):         # \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0446\u0438\u043a\u043b         await asyncio.Future()<\/code><\/pre>\n<p><strong>\u0424\u0443\u043d\u043a\u0446\u0438\u044f run_app():<\/strong><\/p>\n<pre><code class=\"python\">def run_app():     \"\"\"\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u0442\u0430\u0440\u0442\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\"\"\"      try:         asyncio.run(start())     except KeyboardInterrupt:         print('\u0412\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0440\u043e\u0431\u043e\u0442\u0430 \u0434\u043b\u044f \u043f\u0440\u0438\u0451\u043c\u0430 \u043a\u043e\u043c\u0430\u043d\u0434.')<\/code><\/pre>\n<p><strong>\u041e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u044b\u0439 \u043a\u043e\u0434:<\/strong><\/p>\n<ul>\n<li>\n<p>print(&#8216;\u0421\u0442\u0430\u0440\u0442 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0440\u043e\u0431\u043e\u0442\u0430 \u0434\u043b\u044f \u043f\u0440\u0438\u0451\u043c\u0430 \u043a\u043e\u043c\u0430\u043d\u0434.&#8217;) \u2014 \u0438\u043d\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u043e \u0441\u0442\u0430\u0440\u0442\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430;<\/p>\n<\/li>\n<li>\n<p>print(&#8216;\u0412\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0440\u043e\u0431\u043e\u0442\u0430 \u0434\u043b\u044f \u043f\u0440\u0438\u0451\u043c\u0430 \u043a\u043e\u043c\u0430\u043d\u0434.&#8217;) \u2014 \u0438\u043d\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u043b\u043e\u0433\u0433\u0435\u0440 \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 open-source \u043f\u0440\u043e\u0435\u043a\u0442\u00a0<a href=\"https:\/\/github.com\/Arduinum\/robot-pi-service\/tree\/arduinum\/service-orange-pi-mvp-1\" rel=\"noopener noreferrer nofollow\"><strong>robot-pi-service<\/strong><\/a>.<\/p>\n<h3>\u041e\u0442\u043b\u0430\u0434\u043a\u0430 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b<\/h3>\n<p>\u042f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b \u0432 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043b\u043e\u0433\u0438\u043a\u0443, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 LED \u0433\u043e\u0440\u0438\u0442, \u043f\u043e\u043a\u0430 \u044f \u0443\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e \u043a\u043d\u043e\u043f\u043a\u0443, \u0438 \u0433\u0430\u0441\u043d\u0435\u0442, \u043a\u043e\u0433\u0434\u0430 \u044f \u0435\u0451 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u044e. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e, \u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439, \u0430 \u043f\u0440\u0438 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u043d\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430, \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0430\u044f LED. \u0422\u0430\u043a\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0443\u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u0443 \u0433\u043e\u0440\u0435\u0442\u044c \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u043e \u0431\u0435\u0437 \u043c\u0438\u0433\u0430\u043d\u0438\u0439 \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u0430\u043d\u0434, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \u0440\u043e\u0431\u043e\u0442\u0443.<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 \u0438 \u0435\u0451 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u043e\u0439. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u0440\u0435\u0433\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043d\u0430 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u0441\u0435\u0440\u0432\u0438\u0441 \u0440\u043e\u0431\u043e\u0442\u0430.<\/p>\n<p><strong>\u0417\u0430\u043f\u0443\u0441\u043a \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0440\u043e\u0431\u043e\u0442\u0430:<\/strong><\/p>\n<pre><code class=\"bash\">make run<\/code><\/pre>\n<p><strong>\u0417\u0430\u043f\u0443\u0441\u043a \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:<\/strong><\/p>\n<pre><code class=\"bash\">poetry run start_app<\/code><\/pre>\n<p>\u042f \u043d\u0430\u0436\u0438\u043c\u0430\u044e \u043a\u043d\u043e\u043f\u043a\u0443 \u201c\u0432\u043f\u0435\u0440\u0451\u0434\u201d (\u0441\u0442\u0440\u0435\u043b\u043a\u0430 \u0432\u0432\u0435\u0440\u0445) \u0432 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0438 \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u0435\u0451 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u044e.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f91\/ee0\/762\/f91ee076203b64a95119c0ce4154f412.png\" alt=\"\u041a\u043e\u043d\u0441\u043e\u043b\u044c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430\" title=\"\u041a\u043e\u043d\u0441\u043e\u043b\u044c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430\" width=\"937\" height=\"110\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/f91\/ee0\/762\/f91ee076203b64a95119c0ce4154f412.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f91\/ee0\/762\/f91ee076203b64a95119c0ce4154f412.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption><em>\u041a\u043e\u043d\u0441\u043e\u043b\u044c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430<\/em><\/figcaption><\/div>\n<\/figure>\n<p>\u042f \u0432\u0438\u0436\u0443, \u0447\u0442\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0431\u044b\u043b\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 10 \u0440\u0430\u0437 \u0437\u0430 \u043e\u0434\u0438\u043d \u043a\u043b\u0438\u043a, \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u043f\u0440\u0438\u0448\u0451\u043b \u043e\u0442\u0432\u0435\u0442. \u0422\u0430\u043a\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043d\u0435 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/970\/776\/c4c\/970776c4c628316ddb51d73011b70369.png\" alt=\"\u041a\u043e\u043d\u0441\u043e\u043b\u044c \u0431\u0435\u043a\u0435\u043d\u0434\u0430\" title=\"\u041a\u043e\u043d\u0441\u043e\u043b\u044c \u0431\u0435\u043a\u0435\u043d\u0434\u0430\" width=\"477\" height=\"184\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/970\/776\/c4c\/970776c4c628316ddb51d73011b70369.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/970\/776\/c4c\/970776c4c628316ddb51d73011b70369.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption><em>\u041a\u043e\u043d\u0441\u043e\u043b\u044c \u0431\u0435\u043a\u0435\u043d\u0434\u0430<\/em><\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/027\/dd6\/eba\/027dd6ebab5667a070f084631a134b52.png\" alt=\"\u041a\u043e\u043d\u0441\u043e\u043b\u044c \u0440\u043e\u0431\u043e\u0442\u0430\" title=\"\u041a\u043e\u043d\u0441\u043e\u043b\u044c \u0440\u043e\u0431\u043e\u0442\u0430\" width=\"566\" height=\"112\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/027\/dd6\/eba\/027dd6ebab5667a070f084631a134b52.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/027\/dd6\/eba\/027dd6ebab5667a070f084631a134b52.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption><em>\u041a\u043e\u043d\u0441\u043e\u043b\u044c \u0440\u043e\u0431\u043e\u0442\u0430<\/em><\/figcaption><\/div>\n<\/figure>\n<p>\u0411\u044d\u043a\u0435\u043d\u0434 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b \u0440\u043e\u0431\u043e\u0442\u0443 \u0434\u0432\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u2014 \u043a\u0430\u043a \u0438 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u043e \u2014 \u0438 \u0440\u043e\u0431\u043e\u0442 \u0438\u0445 \u043f\u0440\u0438\u043d\u044f\u043b.<\/p>\n<p>\u0414\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u043a\u043b\u0438\u043a\u0430 10 \u043e\u0442\u043f\u0440\u0430\u0432\u043e\u043a \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u2014 \u044d\u0442\u043e \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0447\u0430\u0441\u0442\u043e. \u0422\u0430\u043a\u0430\u044f \u0447\u0430\u0441\u0442\u043e\u0442\u0430 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430, \u0442\u0430\u043a \u043a\u0430\u043a \u0438\u0437 \u044d\u0442\u0438\u0445 10 \u043a\u043e\u043c\u0430\u043d\u0434 \u0434\u043e \u0440\u043e\u0431\u043e\u0442\u0430 \u0434\u043e\u0439\u0434\u0451\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0432\u0430\u044f. \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u043e\u0439 \u0431\u044d\u043a\u0435\u043d\u0434\u0430. \u0414\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0437\u0430 \u043e\u0434\u0438\u043d \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u043a\u043b\u0438\u043a \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u043b\u0430\u0441\u044c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u043e\u0434\u0438\u043d \u0440\u0430\u0437. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043b \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443 \u043c\u0435\u0436\u0434\u0443 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430\u043c\u0438 \u0432 10 \u0440\u0430\u0437 \u2014 \u0441 10 \u043c\u0441 \u0434\u043e 100 \u043c\u0441 \u2014 \u0432 \u043a\u043e\u0434\u0435 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430.<\/p>\n<p><strong>\u0423\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0432 command.js:<\/strong><\/p>\n<pre><code class=\"javascript\">\/\/ \u0414\u0440\u0443\u0433\u043e\u0439 \u043a\u043e\u0434 \/\/ \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0434\u043b\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b commandInterval = setInterval(() =&gt; {     sendCommand(JSON.stringify(command)); \/\/ \u041f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u044b }, 100); \/\/ \u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u2014 \u043a\u0430\u0436\u0434\u044b\u0435 100 \u043c\u0441 \/\/ \u0414\u0440\u0443\u0433\u043e\u0439 \u043a\u043e\u0434<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u044f \u043d\u0430\u0436\u0438\u043c\u0430\u044e \u043a\u043d\u043e\u043f\u043a\u0443 \u0438 \u0441\u0440\u0430\u0437\u0443 \u0435\u0451 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u044e, \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u043d\u0435 10 \u0440\u0430\u0437, \u0430 \u043e\u0434\u0438\u043d.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/af5\/662\/8c6\/af56628c633768348176cd763a3fce6a.png\" alt=\"\u041a\u043e\u043d\u0441\u043e\u043b\u044c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430\" title=\"\u041a\u043e\u043d\u0441\u043e\u043b\u044c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430\" width=\"936\" height=\"117\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/af5\/662\/8c6\/af56628c633768348176cd763a3fce6a.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/af5\/662\/8c6\/af56628c633768348176cd763a3fce6a.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption><em>\u041a\u043e\u043d\u0441\u043e\u043b\u044c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430<\/em><\/figcaption><\/div>\n<\/figure>\n<p>\u0423\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 \u043c\u043e\u0436\u043d\u043e, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0432 \u0432\u0438\u0434\u0435\u043e, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u044f \u0437\u0430\u043f\u0438\u0441\u0430\u043b, \u043a\u0430\u043a LED \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0447\u0435\u0440\u0435\u0437 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/6891e1e23ee88c0a92839875\" data-style=\"\" id=\"6891e1e23ee88c0a92839875\" width=\"\"><\/div>\n<p>\u041d\u0430 \u0432\u0438\u0434\u0435\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e LED \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0438 \u0432\u044b\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0431\u0435\u0437 \u0437\u0430\u0434\u0435\u0440\u0436\u0435\u043a, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442, \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u042f \u0441\u0434\u0435\u043b\u0430\u043b \u0434\u0432\u0430 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0445, \u043e\u0434\u0438\u043d \u0441\u0440\u0435\u0434\u043d\u0438\u0439 \u0438 \u043e\u0434\u0438\u043d \u0434\u043e\u043b\u0433\u0438\u0439 \u043a\u043b\u0438\u043a \u043f\u043e \u043a\u043d\u043e\u043f\u043a\u0435.<\/p>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438 \u043f\u043b\u0430\u043d\u044b \u043d\u0430 \u0431\u0443\u0434\u0443\u0449\u0435\u0435<\/h3>\n<p>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043a \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u0438\u043a\u0443 \u043f\u043b\u0430\u0442\u0443 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043b\u044f\u043c\u0438 \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u0434\u043b\u044f \u0438\u0445 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f. \u041a\u043b\u0430\u0441\u0441 LedLineGpio \u044f \u0440\u0435\u0448\u0438\u043b \u043d\u0435 \u0443\u0434\u0430\u043b\u044f\u0442\u044c, \u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c: LED \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f. \u0421\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u043c\u043e\u0440\u0433\u0430\u0442\u044c, \u043a\u043e\u0433\u0434\u0430 \u0440\u043e\u0431\u043e\u0442 \u043d\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u0451\u043d \u043a \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e, \u0438 \u0433\u043e\u0440\u0435\u0442\u044c \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u043e \u043f\u0440\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0438.<\/p>\n<p>\u0417\u0430\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u044f \u0445\u043e\u0442\u0435\u043b \u0437\u0430\u043d\u044f\u0442\u044c\u0441\u044f \u0435\u0449\u0451 \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u0437\u0430\u0439\u043c\u0443\u0441\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0437\u0436\u0435.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0438\u0434\u0435\u0438 \u043f\u043e \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u0435\u0441\u044c \u0438\u043c\u0438 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445 \u2014 \u0431\u0443\u0434\u0443 \u0440\u0430\u0434 \u0443\u0441\u043b\u044b\u0448\u0430\u0442\u044c \u0432\u0430\u0448\u0438 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f!<\/p>\n<p><strong>\u0410\u0432\u0442\u043e\u0440 \u0441\u0442\u0430\u0442\u044c\u0438 <\/strong><a href=\"https:\/\/habr.com\/ru\/users\/Arduinum\/\" rel=\"noopener noreferrer nofollow\"><strong>@Arduinum<\/strong><\/a><\/p>\n<hr\/>\n<p>\u041d\u041b\u041e \u043f\u0440\u0438\u043b\u0435\u0442\u0435\u043b\u043e \u0438 \u043e\u0441\u0442\u0430\u0432\u0438\u043b\u043e \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u043c\u043e\u043a\u043e\u0434 \u0434\u043b\u044f \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435\u0439 \u043d\u0430\u0448\u0435\u0433\u043e \u0431\u043b\u043e\u0433\u0430:<\/p>\n<p><a href=\"https:\/\/firstvds.ru\/?utm_source=habr&amp;utm_medium=article&amp;utm_campaign=product&amp;utm_content=vds15exeptprogrev\" rel=\"noopener noreferrer nofollow\">-15% \u043d\u0430 \u0437\u0430\u043a\u0430\u0437 \u043b\u044e\u0431\u043e\u0433\u043e VDS<\/a>\u00a0(\u043a\u0440\u043e\u043c\u0435 \u0442\u0430\u0440\u0438\u0444\u0430 \u041f\u0440\u043e\u0433\u0440\u0435\u0432) \u2014 HABRFIRSTVDS.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \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\/933758\/\"> https:\/\/habr.com\/ru\/articles\/933758\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><\/figure>\n<p>\u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 <a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/919060\/\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0435<\/a> \u044f \u043f\u043e\u043a\u0430\u0437\u0430\u043b, \u043a\u0430\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 Orange Pi Zero \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b. \u041d\u0430\u043f\u0438\u0441\u0430\u043b \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0439 \u043f\u0440\u043e\u043a\u0441\u0438 \u043d\u0430 Nginx, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0438\u0434\u0435\u043e\u0441\u0442\u0440\u0438\u043c. \u0422\u0430\u043a\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b \u0441\u0435\u0440\u0432\u0438\u0441 robot_pi_service \u0434\u043b\u044f \u043f\u0440\u0438\u0451\u043c\u0430 \u043a\u043e\u043c\u0430\u043d\u0434 \u043e\u0442 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432. \u0412 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u043a\u043e\u0434 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043e\u043c\u0430\u043d\u0434 \u0440\u043e\u0431\u043e\u0442\u0443 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u043e\u0432.<\/p>\n<p>\u0412 \u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c GPIO-\u043f\u0438\u043d\u0430\u043c\u0438 \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u0438\u043a\u0430 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 Orange Pi Zero \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Python. \u042f \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434 (LED) \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u043c \u0447\u0435\u0440\u0435\u0437 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u043e\u0432\u0435\u0434\u0443 \u043e\u0442\u043b\u0430\u0434\u043a\u0443 \u0437\u0430\u0434\u0435\u0440\u0436\u0435\u043a.<\/p>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u0430 \u043b\u044e\u0431\u0438\u0442\u0435\u043b\u044f\u043c DIY-\u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0438 \u0432\u0435\u0431-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c, \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0449\u0438\u043c\u0441\u044f \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u043c FastAPI.<\/p>\n<h3>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 GPIO \u043d\u0430 \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u0438\u043a\u0435<\/h3>\n<p>GPIO (General Purpose Input\/Output) \u2014 \u044d\u0442\u043e \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0438\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u043c\u0435\u044e\u0442\u0441\u044f \u043a\u0430\u043a \u043d\u0430 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430\u0445, \u0442\u0430\u043a \u0438 \u043d\u0430 \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430\u0445, \u0438 \u043c\u043e\u0433\u0443\u0442 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e \u0434\u043b\u044f \u043f\u0440\u0438\u0451\u043c\u0430 \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0446\u0438\u0444\u0440\u043e\u0432\u044b\u0445 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432. \u0421 \u0438\u0445 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043c\u043e\u0436\u0435\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u043c\u0438\u0440\u043e\u043c \u2014 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u0434\u0430\u0442\u0447\u0438\u043a\u043e\u0432 \u0438\u043b\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u0430\u043c\u0438, \u0440\u0435\u043b\u0435 \u0438 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438.<\/p>\n<p>\u0417\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 \u0447\u0435\u043c-\u0442\u043e \u043d\u043e\u0432\u044b\u043c \u0447\u0430\u0441\u0442\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442 \u0441 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e. \u0418\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u044f\u0437\u044b\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u2014 \u0441 \u0432\u044b\u0432\u043e\u0434\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 Hello, World!, \u0430 \u043f\u0435\u0440\u0432\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 GPIO \u2014 \u0441 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043e\u043c (LED).<\/p>\n<p>\u0414\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f LED \u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0443 \u0435\u0433\u043e \u043a GPIO \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u0438\u043a\u0430. \u041d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u0438\u043a\u0435 \u0441\u0445\u0435\u043c\u0430 \u043f\u043e\u0440\u0442\u043e\u0432 GPIO \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f.<\/p>\n<figure class=\"full-width\">\n<div><figcaption><em>\u0420\u0430\u0441\u043f\u0438\u043d\u043e\u0432\u043a\u0430 GPIO \u0434\u043b\u044f Orange Pi Zero H+<\/em><\/figcaption><\/div>\n<\/figure>\n<p><strong>\u0414\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u0430 \u043c\u043d\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0434\u0432\u0430 \u043f\u0438\u043d\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p>PWM1 (PA6) \u2014 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0438\u043d 20;<\/p>\n<\/li>\n<li>\n<p>GND \u2014 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0438\u043d 7 (\u0437\u0435\u043c\u043b\u044f).<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u0421\u0445\u0435\u043c\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f LED:<\/strong><\/p>\n<ul>\n<li>\n<p>PWM1 (PA6) \u2192 \u0440\u0435\u0437\u0438\u0441\u0442\u043e\u0440 150 \u041e\u043c \u2192 \u0430\u043d\u043e\u0434 LED (\u0434\u043b\u0438\u043d\u043d\u0430\u044f \u043d\u043e\u0436\u043a\u0430);<\/p>\n<\/li>\n<li>\n<p>GND \u2192 \u043a\u0430\u0442\u043e\u0434 LED (\u043a\u043e\u0440\u043e\u0442\u043a\u0430\u044f \u043d\u043e\u0436\u043a\u0430).<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0435\u0437\u0438\u0441\u0442\u043e\u0440 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u0435\u043d \u2014 \u043e\u043d \u0441\u043d\u0438\u0436\u0430\u0435\u0442 \u0441\u0438\u043b\u0443 \u0442\u043e\u043a\u0430, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0441\u043f\u0430\u043b\u0438\u0442\u044c \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434.<\/p>\n<figure class=\"full-width\">\n<div><figcaption><em>\u0424\u043e\u0442\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u0433\u043e LED \u043a \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u0438\u043a\u0443<\/em><\/figcaption><\/div>\n<\/figure>\n<p><strong>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 GPIO \u044f \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 gpiod \u0432 Armbian Linux \u043d\u0430 \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u0438\u043a\u0435:<\/strong><\/p>\n<pre><code class=\"bash\">sudo apt install gpiod<\/code><\/pre>\n<p><strong>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 gpiod \u0432 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 Python:<\/strong><\/p>\n<pre><code class=\"bash\">pip install gpiod<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 GPIO \u043a\u0430\u043a \u0438\u0437 Linux, \u0442\u0430\u043a \u0438 \u0438\u0437 Python. \u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e, \u043a\u0430\u043a\u0438\u0435 GPIO-\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438.<\/p>\n<pre><code class=\"bash\">gpiodetect<\/code><\/pre>\n<p><strong>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:<\/strong><\/p>\n<pre><code class=\"bash\">gpiochip0 [1c20800.pinctrl] (224 lines)   gpiochip1 [1f02c00.pinctrl] (32 lines)<\/code><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u043e\u0440 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p>gpiochip0 \u0438 gpiochip1 \u2014 \u044d\u0442\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 GPIO-\u0447\u0438\u043f\u043e\u0432, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0447\u0435\u0440\u0435\u0437 \/dev\/gpiochip*;<\/p>\n<\/li>\n<li>\n<p>1c20800.pinctrl \u0438 1f02c00.pinctrl \u2014 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u043e\u0432 \u0438\u043b\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u044d\u0442\u0438 \u0447\u0438\u043f\u044b. \u041e\u043d\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u044f\u0434\u0440\u043e\u043c Linux (\u043e\u0431\u044b\u0447\u043d\u043e \u0438\u0437 Device Tree);<\/p>\n<\/li>\n<li>\n<p>(224 lines) \u0438 (32 lines) \u2014 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e GPIO-\u043b\u0438\u043d\u0438\u0439, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0447\u0438\u043f\u0435. \u042d\u0442\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u0442, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0432\u0445\u043e\u0434\u043e\u0432\/\u0432\u044b\u0445\u043e\u0434\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<\/li>\n<\/ul>\n<p>\u041c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e gpiochip0, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043e\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 GPIO-\u043f\u0438\u043d\u043e\u0432. \u041d\u0430 \u044d\u0442\u043e\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u044f \u043d\u0430\u0439\u0434\u0443 \u043d\u0443\u0436\u043d\u0443\u044e \u043c\u043d\u0435 \u043b\u0438\u043d\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0443\u0436\u043d\u0430 \u043c\u043d\u0435 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f LED.<\/p>\n<p><strong>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043b\u0438\u043d\u0438\u0439:<\/strong><\/p>\n<pre><code class=\"bash\">gpioinfo gpiochip0<\/code><\/pre>\n<p><strong>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:<\/strong><\/p>\n<pre><code class=\"bash\">gpiochip0 - 224 lines:        line   0:      unnamed       unused   input  active-high            line   1:      unnamed       unused   input  active-high            line   2:      unnamed       unused   input  active-high            line   3:      unnamed       unused   input  active-high            line   4:      unnamed       unused   input  active-high            line   5:      unnamed       unused   input  active-high            line   6:      unnamed       unused  output  active-high        ...<\/code><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u043e\u0440 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p>gpiochip0 &#8212; 224 lines: \u2014 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 224 \u043b\u0438\u043d\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u043c\u0438 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u043a\u0430\u043d\u0430\u043b\u0430\u043c\u0438;<\/p>\n<\/li>\n<li>\n<p>line \u2014 \u0438\u043d\u0434\u0435\u043a\u0441 \u043b\u0438\u043d\u0438\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \u0447\u0438\u043f\u0430;<\/p>\n<\/li>\n<li>\n<p>unnamed \u2014 \u043b\u0438\u043d\u0438\u044f \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0438\u043c\u0435\u043d\u0438;<\/p>\n<\/li>\n<li>\n<p>unused \u2014 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p>output \u2014 \u043b\u0438\u043d\u0438\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434 (\u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f LED, \u0437\u0443\u043c\u043c\u0435\u0440\u0430\u043c\u0438 \u0438 \u0442. \u0434.);<\/p>\n<\/li>\n<li>\n<p>input \u2014 \u043b\u0438\u043d\u0438\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u043d\u0430 \u0432\u0445\u043e\u0434 (\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043a\u043d\u043e\u043f\u043e\u043a, \u0434\u0430\u0442\u0447\u0438\u043a\u043e\u0432);<\/p>\n<\/li>\n<li>\n<p>active-high \u2014 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0438\u0433\u043d\u0430\u043b \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0435\u0434\u0438\u043d\u0438\u0446\u0435 (HIGH).<\/p>\n<\/li>\n<\/ul>\n<p>\u041c\u043d\u0435 \u043d\u0443\u0436\u043d\u0430 line 6, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 PA6 \u043d\u0430 GPIO Orange Pi. \u0415\u0451 \u044f \u0438 \u0431\u0443\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f LED.<\/p>\n<p><strong>\u041f\u043e\u0434\u0430\u044e \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0435\u0434\u0438\u043d\u0438\u0446\u0443, \u0447\u0442\u043e\u0431\u044b \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c LED \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0435\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u0443:<\/strong><\/p>\n<pre><code class=\"bash\">sudo gpioset gpiochip0 6=1<\/code><\/pre>\n<figure class=\"full-width\">\n<div><figcaption><em>\u0424\u043e\u0442\u043e \u0433\u043e\u0440\u044f\u0449\u0435\u0433\u043e LED<\/em><\/figcaption><\/div>\n<\/figure>\n<p>\u041a\u0440\u0430\u0441\u043d\u044b\u0439 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0437\u0430\u0433\u043e\u0440\u0435\u043b\u0441\u044f. \u041f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430 \u044f \u0435\u0433\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u043b, \u043f\u0435\u0440\u0435\u043f\u0443\u0442\u0430\u043b \u043f\u0440\u043e\u0432\u043e\u0434\u0430 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b, \u0432\u043a\u043b\u044e\u0447\u0451\u043d \u043b\u0438 LED \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e.<\/p>\n<p><strong>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043b\u0438\u043d\u0438\u0438:<\/strong><\/p>\n<pre><code class=\"bash\">sudo gpioget gpiochip0 6<\/code><\/pre>\n<p><strong>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:<\/strong><\/p>\n<pre><code class=\"bash\">1<\/code><\/pre>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 1 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e line 6 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430 (HIGH).<\/p>\n<p><strong>\u0414\u043b\u044f \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u0430\u044e 0:<\/strong><\/p>\n<pre><code class=\"bash\">sudo gpioset gpiochip0 6=0<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 GPIO \u0431\u0435\u0437 sudo, \u043d\u0443\u0436\u043d\u044b \u043f\u0440\u0430\u0432\u0430 \u0441\u0443\u043f\u0435\u0440\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u042f \u043d\u0430\u043f\u0438\u0448\u0443 \u0441\u043a\u0440\u0438\u043f\u0442 sh, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0433\u0440\u0443\u043f\u043f\u0443 gpio \u0438 \u0434\u0430\u0441\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0434\u043e\u0441\u0442\u0443\u043f \u043a GPIO.<\/p>\n<p><strong>\u0424\u0430\u0439\u043b gpio_<\/strong><a href=\"http:\/\/setup.sh\" rel=\"noopener noreferrer nofollow\"><strong>setup.sh<\/strong><\/a><strong>:<\/strong><\/p>\n<pre><code class=\"bash\">#!\/bin\/bash chmod -R +x robot_pi_service\/ sudo groupadd gpio sudo usermod -aG gpio $USER echo 'SUBSYSTEM==\"gpio\", KERNEL==\"gpiochip[0-9]*\", GROUP=\"gpio\", MODE=\"0660\"' | sudo tee \/etc\/udev\/rules.d\/99-gpio.rules sudo udevadm control --reload-rules sudo udevadm trigger<\/code><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u043e\u0440 \u0441\u043a\u0440\u0438\u043f\u0442\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p>sudo groupadd gpio \u2014 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0433\u0440\u0443\u043f\u043f\u0443 gpio;<\/p>\n<\/li>\n<li>\n<p>sudo usermod -aG gpio $USER \u2014 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0433\u0440\u0443\u043f\u043f\u0443 gpio;<\/p>\n<\/li>\n<li>\n<p>echo &#8230; | sudo tee &#8230; \u2014 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u043e udev, \u0447\u0442\u043e\u0431\u044b \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 gpiochip \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0430\u043b\u0438 \u0433\u0440\u0443\u043f\u043f\u0435 gpio \u0438 \u0438\u043c\u0435\u043b\u0438 \u043f\u0440\u0430\u0432\u0430 0660;<\/p>\n<\/li>\n<li>\n<p>sudo udevadm control &#8212;reload-rules \u2014 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 udev;<\/p>\n<\/li>\n<li>\n<p>sudo udevadm trigger \u2014 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043a \u0443\u0436\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u043c.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u043a\u0440\u0438\u043f\u0442 gpio_<a href=\"http:\/\/setup.sh\" rel=\"noopener noreferrer nofollow\">setup.sh<\/a> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0440\u0430\u0437. \u0412 \u043d\u0435\u0433\u043e \u044f \u043f\u0435\u0440\u0435\u043d\u0451\u0441 \u0441\u0442\u0440\u043e\u043a\u0443 chmod -R +x robot_pi_service\/ \u0438\u0437 Makefile, \u0447\u0442\u043e\u0431\u044b \u0434\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0430 \u043d\u0430 \u043f\u0430\u043f\u043a\u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 GPIO \u0431\u0435\u0437 sudo \u0438\u0437 Python.<\/p>\n<p><strong>\u0414\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u0443 \u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435:<\/strong><\/p>\n<pre><code class=\"bash\">chmod +x gpio_setup.sh<\/code><\/pre>\n<p><strong>\u0417\u0430\u043f\u0443\u0441\u043a \u0441\u043a\u0440\u0438\u043f\u0442\u0430:<\/strong><\/p>\n<pre><code class=\"bash\">.\/gpio_setup.sh<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u0430\u0432\u0430 \u0432\u0441\u0442\u0443\u043f\u0438\u043b\u0438 \u0432 \u0441\u0438\u043b\u0443, \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0439\u0442\u0438 \u0438\u0437 \u0441\u0435\u0441\u0441\u0438\u0438 \u0438 \u0432\u043e\u0439\u0442\u0438 \u0437\u0430\u043d\u043e\u0432\u043e. \u042f \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0449\u0443 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e:<\/p>\n<pre><code class=\"bash\">sudo shutdown -h now<\/code><\/pre>\n<p><strong>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0433\u0440\u0443\u043f\u043f:<\/strong><\/p>\n<pre><code class=\"bash\">groups<\/code><\/pre>\n<p><strong>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:<\/strong><\/p>\n<pre><code class=\"bash\">user_name sudo users gpio<\/code><\/pre>\n<p>\u0413\u0440\u0443\u043f\u043f\u0430 gpio \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c. GPIO \u0438 LED \u0433\u043e\u0442\u043e\u0432\u044b \u043a \u0440\u0430\u0431\u043e\u0442\u0435 \u2014 \u043f\u043e\u0440\u0430 \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434.<\/p>\n<h3>\u041a\u043e\u0434 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h3>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u0438\u043d\u043d\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 poetry run uvicorn web_robot_control.main:app &#8212;host server_ip &#8212;port port_number \u043d\u0435\u0443\u0434\u043e\u0431\u043d\u043e. \u042f \u0445\u043e\u0447\u0443 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a, \u043d\u0430\u043f\u0438\u0441\u0430\u0432 \u0441\u043a\u0440\u0438\u043f\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0434\u043b\u044f Poetry. \u0412 \u043f\u0430\u043a\u0435\u0442\u0435 web_robot_control \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u0444\u0430\u0439\u043b <a href=\"http:\/\/start.py\" rel=\"noopener noreferrer nofollow\">start.py<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0447\u0435\u0440\u0435\u0437 uvicorn.<\/p>\n<p><strong>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 uvicorn \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e poetry:<\/strong><\/p>\n<pre><code class=\"bash\">poetry add uvicorn<\/code><\/pre>\n<p><strong>\u0421\u043a\u0440\u0438\u043f\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430:<\/strong><\/p>\n<pre><code class=\"python\">import uvicorn   def start_app():     \"\"\"\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\"\"\"          uvicorn.run(         'web_robot_control.main:app',          host='127.0.0.1',         port=8000,         reload=True     ) <\/code><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u043e\u0440 \u043a\u043e\u0434\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p>import uvicorn \u2014 \u0438\u043c\u043f\u043e\u0440\u0442 ASGI-\u0441\u0435\u0440\u0432\u0435\u0440\u0430 uvicorn, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0433\u043e \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 FastAPI-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p><a href=\"http:\/\/uvicorn.run\" rel=\"noopener noreferrer nofollow\">uvicorn.run<\/a>(&#8230;) \u2014 \u0432\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u0430 run \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:<\/p>\n<\/li>\n<li>\n<p>&#8216;web_robot_control.main:app&#8217; \u2014 \u043f\u0443\u0442\u044c \u043a FastAPI-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e: \u043c\u043e\u0434\u0443\u043b\u044c main \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0430\u043a\u0435\u0442\u0430 web_robot_control, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 app;<\/p>\n<\/li>\n<li>\n<p>host=&#8217;127.0.0.1&#8242; \u2014 \u0441\u0435\u0440\u0432\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u0435 \u043d\u0430 ip 127.0.0.1;<\/p>\n<\/li>\n<li>\n<p>port=8000 \u2014 \u0441\u0435\u0440\u0432\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0443\u0448\u0430\u0442\u044c \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 8000;<\/p>\n<\/li>\n<li>\n<p>reload=True \u2014 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 (\u0443\u0434\u043e\u0431\u043d\u043e \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438);<\/p>\n<\/li>\n<li>\n<p>\u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c ip \u0438 port \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0447\u0438\u0442\u0430\u0442\u044c\u0441\u044f \u0438\u0437 .env \u0444\u0430\u0439\u043b\u0430, \u0447\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c Poetry, \u0433\u0434\u0435 \u0438\u0441\u043a\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0437\u0430\u043f\u0443\u0441\u043a\u0430.<\/p>\n<p><strong>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 pyproject.toml:<\/strong><\/p>\n<p>[tool.poetry.scripts]<br \/> start_app = &#171;web_robot_control.start:start_app&#187;<\/p>\n<p><strong>\u0420\u0430\u0437\u0431\u043e\u0440 \u043d\u043e\u0432\u044b\u0445 \u0441\u0442\u0440\u043e\u043a:<\/strong><\/p>\n<ul>\n<li>\n<p>[tool.poetry.scripts] \u2014 \u0441\u0435\u043a\u0446\u0438\u044f \u0432 pyproject.toml, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043f\u043e\u0441\u043b\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043f\u0430\u043a\u0435\u0442\u0430;<\/p>\n<\/li>\n<li>\n<p>start_app \u2014 \u0438\u043c\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0438\u0437 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0430;<\/p>\n<\/li>\n<li>\n<p>&#171;web_robot_control.start:start_app&#187; \u2014 \u043f\u0443\u0442\u044c \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:<\/p>\n<\/li>\n<\/ul>\n<ul>\n<li>\n<p>web_robot_control \u2014 \u0438\u043c\u044f Python-\u043f\u0430\u043a\u0435\u0442\u0430;<\/p>\n<\/li>\n<li>\n<p>start \u2014 \u043c\u043e\u0434\u0443\u043b\u044c \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0430\u043a\u0435\u0442\u0430;<\/p>\n<\/li>\n<li>\n<p>start_app \u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u043e\u0434\u0443\u043b\u044f <a href=\"http:\/\/start.py\" rel=\"noopener noreferrer nofollow\">start.py<\/a>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d\u0430.<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443 start_app:<\/strong><\/p>\n<pre><code class=\"bash\">poetry install<\/code><\/pre>\n<p><strong>\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0432 \u0444\u0430\u0439\u043b\u0435<\/strong> <a href=\"http:\/\/README.md\" rel=\"noopener noreferrer nofollow\">README.md<\/a><strong>:<\/strong><\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a \u0434\u043b\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438: <code><strong><em>poetry run start_app<\/em><\/strong><\/code><\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u044f \u0438\u0437\u043c\u0435\u043d\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440. \u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u044f \u0431\u0443\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0443 \u043a\u043b\u044e\u0447\u2013\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0433\u0434\u0435 \u043a\u043b\u044e\u0447 \u2014 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u2014 \u0435\u0451 \u0441\u0442\u0430\u0442\u0443\u0441. \u0424\u0440\u043e\u043d\u0442\u0435\u043d\u0434 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 JSON \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440. \u0414\u043b\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b forward \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a\u043e\u0439:<\/p>\n<ul>\n<li>\n<p>{&#171;forward&#187;: True} \u2014 \u0434\u043b\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f LED;<\/p>\n<\/li>\n<li>\n<p>{&#171;forward&#187;: False} \u2014 \u0434\u043b\u044f \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f LED.<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0432 command.js \u0434\u043b\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b forward:<\/strong><\/p>\n<pre><code class=\"javascript\">\/\/ \u0414\u0440\u0443\u0433\u043e\u0439 \u043a\u043e\u0434 \/\/ \u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0434\u043b\u044f \u043a\u043d\u043e\u043f\u043a\u0438 \"\u0412\u043f\u0435\u0440\u0451\u0434\" const forwardButton = document.getElementById(\"forward-button\"); const forwardOn = { \"forward\": true }; forwardButton.addEventListener(\"mousedown\", () =&gt; startSendingCommand(forwardOn)); \/\/ \u041d\u0430\u0447\u0430\u043b\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b const forwardOff = { \"forward\": false }; forwardButton.addEventListener(\"mouseup\", () =&gt; {     sendCommand(JSON.stringify(forwardOff));     stopSendingCommand(); }); \/\/ \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b forwardOff \u0438 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043f\u0440\u0438 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u043d\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438 forwardButton.addEventListener(\"mouseleave\", stopSendingCommand);  \/\/ \u041e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438, \u0435\u0441\u043b\u0438 \u043a\u0443\u0440\u0441\u043e\u0440 \u0443\u0445\u043e\u0434\u0438\u0442 \u0441 \u043a\u043d\u043e\u043f\u043a\u0438 \/\/ \u0414\u0440\u0443\u0433\u043e\u0439 \u043a\u043e\u0434<\/code><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u043e\u0440 \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u0434\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p>const forwardOn = { &#171;forward&#187;: true }; \u2014 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442 forwardOn, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0432\u043f\u0435\u0440\u0451\u0434. \u041a\u043b\u044e\u0447 &#171;forward&#187; \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u0432 true, \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 (\u043f\u043e\u043a\u0430 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 LED);<\/p>\n<\/li>\n<li>\n<p>startSendingCommand(forwardOn); \u2014 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f startSendingCommand \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c forwardOn \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430. \u042d\u0442\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 WebSocket;<\/p>\n<\/li>\n<li>\n<p>const forwardOff = { &#171;forward&#187;: false }; \u2014 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442 forwardOff, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f. \u041a\u043b\u044e\u0447 &#171;forward&#187; \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u0432 false, \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043f\u0440\u0435\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f (\u043f\u043e\u043a\u0430 \u0432\u044b\u043a\u043b\u044e\u0447\u0430\u0435\u0442 LED);<\/p>\n<\/li>\n<li>\n<p>sendCommand(JSON.stringify(forwardOff)); \u2014 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f sendCommand, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438. \u041e\u0431\u044a\u0435\u043a\u0442 forwardOff \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0441\u0442\u0440\u043e\u043a\u0443 JSON \u043f\u0435\u0440\u0435\u0434 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u043e\u0439, \u0447\u0442\u043e\u0431\u044b \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043f\u043e \u0441\u0435\u0442\u0438. \u0412\u044b\u0437\u043e\u0432 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u043d\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438.<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c websocket_endpoint() \u0432 \u0431\u044d\u043a\u0435\u043d\u0434\u0435 \u043f\u043e\u0434 \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443:<\/strong><\/p>\n<ul>\n<li>\n<p>\u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 JSON, \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u044f \u0435\u0451 \u0432 dict;<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u0434\u043d\u0443 \u0438 \u0442\u0443 \u0436\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0434\u0432\u0430\u0436\u0434\u044b \u043f\u043e\u0434\u0440\u044f\u0434;<\/p>\n<\/li>\n<li>\n<p>\u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u0440\u0438 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 JSON.<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u041e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u044b\u0439 websocket_endpoint():<\/strong><\/p>\n<pre><code class=\"python\">@router.websocket('\/ws') async def websocket_endpoint(websocket: WebSocket) -&gt; None:     \"\"\"\u042d\u043d\u0434\u043f\u043e\u0438\u043d\u0442 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043a\u043e\u043c\u0430\u043d\u0434 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430\"\"\"          # \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441\u043e\u0434\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u043f\u043e \u0432\u0435\u0431-\u0441\u043e\u043a\u0435\u0442\u0443     await<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-469872","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/469872","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=469872"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/469872\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=469872"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=469872"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=469872"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}