{"id":73,"date":"2024-04-05T21:37:12","date_gmt":"2024-04-05T15:37:12","guid":{"rendered":"http:\/\/192.168.1.106\/?p=73"},"modified":"2024-05-15T18:27:12","modified_gmt":"2024-05-15T12:27:12","slug":"i-used-ai-to-make-my-indoor-plants-talk","status":"publish","type":"post","link":"https:\/\/creatrix.us\/?p=73","title":{"rendered":"How I Used AI to Make My Indoor Plants Talk"},"content":{"rendered":"\n<p>Disclaimer: In fact, plants themselves don&#8217;t speak. Rather, a generative AI reads the soil sensor data and generates messages based on that information. These messages are then automatically broadcast through smart speakers in the house whenever selected individuals approach the plant.<\/p>\n\n\n\n<div style=\"height:16px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading has-medium-font-size\">Here is a quick demonstration in Bangla<\/h3>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"I used AI to make my indoor plants talk in Bangla\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/TVgYT9QInX0?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><figcaption class=\"wp-element-caption\">Note to myself: replace it with English demo video.<\/figcaption><\/figure>\n\n\n\n<div style=\"height:16px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">Let&#8217;s see how it works<\/h4>\n\n\n\n<p>I have a number of indoor plants in different rooms of my house. To monitor them, I bought some HHCC Flower Care soil sensors about a year ago. The mobile app allows me to see the soil moisture, fertilizer level, and other information. <\/p>\n\n\n\n<p>Since the sensors send data to the mobile phone via Bluetooth, the range is naturally not very wide.<\/p>\n\n\n\n<p>I had some spare ESP32 development boards in my drawer so the first thing I did was flash a few ESP32 boards and turn them into <a href=\"https:\/\/esphome.io\/components\/bluetooth_proxy.html\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Bluetooth proxies<\/a>.<\/p>\n\n\n\n<p>These essentially take the data from the Bluetooth beacon and send it to my home assistant server via WiFi. As a result, I don&#8217;t have to go near the sensor to see the data.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/2024\/04\/image-2-1024x669.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>Now the data can be viewed in my home dashboard app like these.<\/p>\n\n\n\n<div style=\"height:16px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>To make the data visualization more useful, I added some color coding here. Green indicates that the level is just right, red means it is below the required level, and yellow means it is above the required level. However, this part has nothing to do with the automation but hey, why not?<\/p>\n\n\n\n<div class=\"dm-code-snippet dark dm-slim-version no-background no-background-mobile\" snippet-height=\"\" style=\"background-color:#abb8c3\"><div class=\"control-language\"><div class=\"dm-buttons\"><div class=\"dm-buttons-left\"><div class=\"dm-button-snippet red-button\"><\/div><div class=\"dm-button-snippet orange-button\"><\/div><div class=\"dm-button-snippet green-button\"><\/div><\/div><div class=\"dm-buttons-right\"><a id=\"dm-copy-raw-code\"><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\" style=\"display:none\">Copied<\/span><span class=\"dm-error-message\" style=\"display:none\">Use a different Browser<\/span><\/a><\/div><\/div><pre class=\" no-line-numbers\"><code id=\"dm-code-raw\" class=\" wrap language-python\">type: custom:mini-graph-card\nentities:\n  - sensor.snake_plants_moisture\nname: Moisture\nicon: mdi:water-percent\nline_width: 8\nanimate: true\nline_color: var(--accent-color)\ncolor_thresholds:\n  - value: 10\n    color: '#e06c75'\n  - value: 30\n    color: '#069869'\n  - value: 50\n    color: '#e5c07b'<\/code><\/pre><\/div><\/div>\n\n\n\n<div style=\"height:16px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>And then I&#8217;ve also flashed couple of ESP32 boards with <a href=\"https:\/\/espresense.com\/\" data-type=\"link\" data-id=\"https:\/\/espresense.com\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Espresence<\/a> to be used as room presence sensors. It monitors where we (actually our phones) are and I use this data for a lot of other automations as well. Perhaps that might be a topic for another day.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/2024\/04\/image-3.png\" alt=\"\"\/><\/figure>\n\n\n\n<div style=\"height:16px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">The hardest part is done<\/h4>\n\n\n\n<p>Now, what we need to do now is to use AI to convert this data into dynamic sentences.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/2024\/04\/AI-powered-plant-monitoring-flow-931x1024.jpeg\" alt=\"\"\/><\/figure>\n\n\n\n<p>To do this, I created a very basic automation in Home Assistant. Each automation typically has three parts:<\/p>\n\n\n\n<p><strong>1. Trigger:<\/strong> When and how the automation will start. In this case, I used my phone&#8217;s Bluetooth beacon as the trigger. For example, when I enter the office room with my phone, the automation will start.<\/p>\n\n\n\n<div class=\"dm-code-snippet dark dm-slim-version no-background no-background-mobile\" snippet-height=\"\" style=\"background-color:#abb8c3\"><div class=\"control-language\"><div class=\"dm-buttons\"><div class=\"dm-buttons-left\"><div class=\"dm-button-snippet red-button\"><\/div><div class=\"dm-button-snippet orange-button\"><\/div><div class=\"dm-button-snippet green-button\"><\/div><\/div><div class=\"dm-buttons-right\"><a id=\"dm-copy-raw-code\"><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\" style=\"display:none\">Copied<\/span><span class=\"dm-error-message\" style=\"display:none\">Use a different Browser<\/span><\/a><\/div><\/div><pre class=\" no-line-numbers\"><code id=\"dm-code-raw\" class=\" wrap language-python\">trigger:\n  - platform: state\n    entity_id:\n      - sensor.mamun_phone\n    to: office<\/code><\/pre><\/div><\/div>\n\n\n\n<div style=\"height:16px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><strong>2. Condition:<\/strong> In this step, the automation checks to see if the conditions that are necessary for it to perform its task are met. For example, in this case, I used the condition that if the soil moisture of the snake plant in the office room is less than 25%, the automation will proceed to the next step. Otherwise, it will be ignored.<\/p>\n\n\n\n<div class=\"dm-code-snippet dark dm-slim-version no-background no-background-mobile\" snippet-height=\"\" style=\"background-color:#abb8c3\"><div class=\"control-language\"><div class=\"dm-buttons\"><div class=\"dm-buttons-left\"><div class=\"dm-button-snippet red-button\"><\/div><div class=\"dm-button-snippet orange-button\"><\/div><div class=\"dm-button-snippet green-button\"><\/div><\/div><div class=\"dm-buttons-right\"><a id=\"dm-copy-raw-code\"><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\" style=\"display:none\">Copied<\/span><span class=\"dm-error-message\" style=\"display:none\">Use a different Browser<\/span><\/a><\/div><\/div><pre class=\" no-line-numbers\"><code id=\"dm-code-raw\" class=\" wrap language-python\">- conditions:\n  - condition: numeric_state\n    entity_id: sensor.snake_plants_moisture\n    below: 25<\/code><\/pre><\/div><\/div>\n\n\n\n<div style=\"height:16px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><strong>3. Action:<\/strong> This part is about what will happen if the condition is fulfilled after the automation is triggered.<\/p>\n\n\n\n<p>Here, I want a message to be generated that makes it seem like the plant itself is asking for water if the soil moisture is less than 25%. Instead of using the same boring message every time, I am now using Google Gemini to write the messages, although I initially started with ChatGPT. Both work great in their own way.<\/p>\n\n\n\n<div class=\"dm-code-snippet dark dm-slim-version no-background no-background-mobile\" snippet-height=\"\" style=\"background-color:#abb8c3\"><div class=\"control-language\"><div class=\"dm-buttons\"><div class=\"dm-buttons-left\"><div class=\"dm-button-snippet red-button\"><\/div><div class=\"dm-button-snippet orange-button\"><\/div><div class=\"dm-button-snippet green-button\"><\/div><\/div><div class=\"dm-buttons-right\"><a id=\"dm-copy-raw-code\"><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\" style=\"display:none\">Copied<\/span><span class=\"dm-error-message\" style=\"display:none\">Use a different Browser<\/span><\/a><\/div><\/div><pre class=\" no-line-numbers\"><code id=\"dm-code-raw\" class=\" wrap language-python\">service: conversation.process\nmetadata: {}\ndata:\n  agent_id: [YOUR_AI_AGENT]\n  text: \"write a humorous notification message based on this prompt: Imagine you are my favorite Snake Plant and you are very thirsty. The soil is very dry, current moisture level is {{states.sensor.snake_plants_moisture.state }} only. It's difficult to survive in this condition. Request for water in a sentence or two like a child.\"\n\nresponse_variable: gptplant<\/code><\/pre><\/div><\/div>\n\n\n\n<div style=\"height:16px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>As a result, our AI is writing a response like this, and it is a little different each time. Isn&#8217;t that interesting?<\/p>\n\n\n\n<div class=\"dm-code-snippet dark dm-slim-version no-background no-background-mobile\" snippet-height=\"\" style=\"background-color:#abb8c3\"><div class=\"control-language\"><div class=\"dm-buttons\"><div class=\"dm-buttons-left\"><div class=\"dm-button-snippet red-button\"><\/div><div class=\"dm-button-snippet orange-button\"><\/div><div class=\"dm-button-snippet green-button\"><\/div><\/div><div class=\"dm-buttons-right\"><a id=\"dm-copy-raw-code\"><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\" style=\"display:none\">Copied<\/span><span class=\"dm-error-message\" style=\"display:none\">Use a different Browser<\/span><\/a><\/div><\/div><pre class=\" no-line-numbers\"><code id=\"dm-code-raw\" class=\" wrap language-python\">response:\n  speech:\n    plain:\n      speech: \"I'm so thirsty! Can you please give me some water? I'm so dry, I can barely hold on!\"\n      extra_data: null\n  card: {}\n  language: en\n  response_type: action_done\n  data:\n    targets: []\n    success: []\n    failed: []<\/code><\/pre><\/div><\/div>\n\n\n\n<div style=\"height:16px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Now, the final piece of the automation is converting this text to speech for broadcast.<\/p>\n\n\n\n<p>There are many text-to-speech engines and voice models available these days. I primarily use Piper and Nabu Casa Cloud to cast messages through my Google Nest.<\/p>\n\n\n\n<div class=\"dm-code-snippet dark dm-slim-version no-background no-background-mobile\" snippet-height=\"\" style=\"background-color:#abb8c3\"><div class=\"control-language\"><div class=\"dm-buttons\"><div class=\"dm-buttons-left\"><div class=\"dm-button-snippet red-button\"><\/div><div class=\"dm-button-snippet orange-button\"><\/div><div class=\"dm-button-snippet green-button\"><\/div><\/div><div class=\"dm-buttons-right\"><a id=\"dm-copy-raw-code\"><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\" style=\"display:none\">Copied<\/span><span class=\"dm-error-message\" style=\"display:none\">Use a different Browser<\/span><\/a><\/div><\/div><pre class=\" no-line-numbers\"><code id=\"dm-code-raw\" class=\" wrap language-python\">service: [your_tts_service]\nmetadata: {}\ndata:\n  cache: false\n  entity_id: media_player.office_speaker\n  message: \"{{ gptplant.response.speech.plain.speech }}\"\n  language: en-US\n  options:\n    voice: [your_preferred_voice_model]<\/code><\/pre><\/div><\/div>\n\n\n\n<div style=\"height:16px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Yep, that&#8217;s exactly it! In addition, I&#8217;ve also added a few other plants with their fertilizer and light level thresholds to the automation.<\/p>\n\n\n\n<p>Now, whenever I&#8217;m near my plants, I can hear what they need.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Disclaimer: In fact, plants themselves don&#8217;t speak. Rather, a generative AI reads the soil sensor data and generates messages based on that information. These messages are then automatically broadcast through smart speakers in the house whenever selected individuals approach the plant. Here is a quick demonstration in Bangla Let&#8217;s see how it works I have [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":146,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"single-with-sidebar","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[7,8,9],"class_list":["post-73","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-home-automation","tag-ai","tag-automation","tag-smart-home"],"_links":{"self":[{"href":"https:\/\/creatrix.us\/index.php?rest_route=\/wp\/v2\/posts\/73","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/creatrix.us\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/creatrix.us\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/creatrix.us\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/creatrix.us\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=73"}],"version-history":[{"count":62,"href":"https:\/\/creatrix.us\/index.php?rest_route=\/wp\/v2\/posts\/73\/revisions"}],"predecessor-version":[{"id":671,"href":"https:\/\/creatrix.us\/index.php?rest_route=\/wp\/v2\/posts\/73\/revisions\/671"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/creatrix.us\/index.php?rest_route=\/wp\/v2\/media\/146"}],"wp:attachment":[{"href":"https:\/\/creatrix.us\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=73"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/creatrix.us\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=73"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/creatrix.us\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=73"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}