[
  {
    "path": ".gitattributes",
    "content": "# Auto detect text files and perform LF normalization\n* text=auto\n"
  },
  {
    "path": "Config/ESPHome/droplet.yaml",
    "content": "substitutions:\n  name: droplet\n\nesphome:\n  name: ${name}\n  name_add_mac_suffix: true\n  project:\n    name: pricelesstoolkit.droplet\n    version: \"1.0\"\n    \n  on_boot:\n    priority: -100\n    then:\n      - lambda: id(oled).turn_off();\n\nesp32:\n  board: esp32dev\n\ndashboard_import:\n  package_import_url: github://PricelessToolkit/Droplet/Config/ESPHome/droplet.yaml@main\n  import_full_config: true\n\n\n# Enable logging\nlogger:\n\nota:\n- platform: esphome\n  password: bfec11234xsfea57e1b5d3b985cfe06c\n\nwifi:\n  ssid: !secret wifi_ssid\n  password: !secret wifi_password\n  fast_connect: true\n  # domain: .lab.lan # if you have custom domain not .local\n\n  # Enable fallback hotspot (captive portal) in case wifi connection fails\n  ap:\n    ssid: ${name} Fallback Hotspot\n    password: password\n\ncaptive_portal:\n\none_wire: #https://esphome.io/components/one_wire\n- platform: gpio\n  pin: GPIO25\n\ni2c: # i2c Pins\n  sda: 21\n  scl: 22\n  scan: true\n\nmcp23017: # Expansion Board  https://esphome.io/components/mcp230xx.html\n- id: mcp23017_hub\n  address: 0x20\n\nfont: # Fonts for Display\n- file: arial.ttf\n  id: font1\n  size: 8\n- file: arial.ttf\n  id: font2\n  size: 10\n- file: arial.ttf\n  id: font3\n  size: 14\n\ndisplay: # More info https://esphome.io/components/display/ssd1306.html?highlight=1306         \n- platform: ssd1306_i2c\n  id: oled\n  model: SSD1306 128x64\n  address: 0x3C   # Oled Display Address\n  lambda: |-\n    it.printf(2, 0, id(font2), TextAlign::TOP_LEFT, \"DROPLET\");\n    it.printf(61, 0, id(font2) ,\"%.1f\", id(dbm).state);\n    it.line(0, 12, 98, 12);\n    it.line(98, 0, 98, 64);\n    it.printf(102, 0, id(font2) ,\"%.1f\", id(Soil1).state);\n    it.printf(102, 12, id(font2) ,\"%.1f\", id(Soil2).state);\n    it.printf(102, 24, id(font2) ,\"%.1f\", id(Soil3).state);\n    it.printf(102, 36, id(font2) ,\"%.1f\", id(Soil4).state);\n    it.printf(102, 48, id(font2) ,\"%.1f\", id(Soil5).state);\n#    it.printf(5, 15, id(font3) ,\"%.1f°C\", id(intergratedtmp).state);\n#    it.printf(5, 30, id(font3) ,\"%.1fH\", id(dhthumidity).state);\n#    it.printf(5, 45, id(font3) ,\"%.1fP\", id(pressure).state);\n\n\n  # Integrated BUZZER # If you using pin23 for something else, delete this and remove jumper 1\n\nrtttl:\n  output: rtttl_out\n  on_finished_playback:\n  - logger.log: Song ended!\n\napi:\n  services:\n  - service: play_rtttl\n    variables:\n      song_str: string\n    then:\n    - rtttl.play:\n        rtttl: !lambda 'return song_str;'\n\n            # https://esphome.io/components/rtttl.html\n            # In the developer tools. E.g. for calling rtttl.play select the service droplet_play_rtttl and in service data enter    siren:d=8,o=5,b=100:d,e,d,e,d,e,d,e   or  scale_up:d=32,o=5,b=100:c,c#,d#,e,f#,g#,a#,b  \n\n\nsensor:\n  # MOISTUR LEVEL SENSORS #   https://esphome.io/components/sensor/adc.html?highlight=adc\n- platform: adc\n  pin: 34\n  id: Soil1\n  name: ${name} SoilM Sens 1\n  icon: mdi:water-percent\n  update_interval: 2s\n  unit_of_measurement: '%'\n  attenuation: 12db\n  filters:\n  - calibrate_linear:\n    - 2.520 -> 0.00      # Calibrate Min in dry soil\n    - 0.99 -> 100.00     # Calibrate MAX in 100% wet soil \n  - lambda: |\n      if (x < 0) return 0; \n      else if (x > 100) return 100;\n      else return (x);\n  accuracy_decimals: 0\n\n- platform: adc\n  pin: 35\n  id: Soil2\n  name: ${name} SoilM Sens 2\n  icon: mdi:water-percent\n  update_interval: 2s\n  unit_of_measurement: '%'\n  attenuation: 12db\n  filters:\n  - calibrate_linear:\n    - 2.520 -> 0.00      # Calibrate Min in dry soil\n    - 0.99 -> 100.00     # Calibrate MAX in 100% wet soil \n  - lambda: |\n      if (x < 0) return 0; \n      else if (x > 100) return 100;\n      else return (x);\n  accuracy_decimals: 0\n\n- platform: adc\n  pin: 32\n  id: Soil3\n  name: ${name} SoilM Sens 3\n  icon: mdi:water-percent\n  update_interval: 2s\n  unit_of_measurement: '%'\n  attenuation: 12db\n  filters:\n  - calibrate_linear:\n    - 2.520 -> 0.00      # Calibrate Min in dry soil\n    - 0.99 -> 100.00     # Calibrate MAX in 100% wet soil \n  - lambda: |\n      if (x < 0) return 0;\n      else if (x > 100) return 100;\n      else return (x);\n  accuracy_decimals: 0\n\n- platform: adc\n  pin: 33\n  id: Soil4\n  name: ${name} SoilM Sens 4\n  icon: mdi:water-percent\n  update_interval: 2s\n  unit_of_measurement: '%'\n  attenuation: 12db\n  filters:\n  - calibrate_linear:\n    - 2.520 -> 0.00      # Calibrate Min in dry soil\n    - 0.99 -> 100.00     # Calibrate MAX in 100% wet soil \n  - lambda: |\n      if (x < 0) return 0;\n      else if (x > 100) return 100;\n      else return (x);\n  accuracy_decimals: 0\n\n- platform: adc\n  pin: 39\n  id: Soil5\n  name: ${name} SoilM Sens 5\n  icon: mdi:water-percent\n  update_interval: 2s\n  unit_of_measurement: '%'\n  attenuation: 12db\n  filters:\n  - calibrate_linear:\n    - 2.520 -> 0.00      # Calibrate Min in dry soil\n    - 0.99 -> 100.00     # Calibrate MAX in 100% wet soil \n  - lambda: |\n      if (x < 0) return 0;\n      else if (x > 100) return 100;\n      else return (x);\n  accuracy_decimals: 0\n\n  # HOME ASSISTANT DESIRED MOISTURE LEVELS #  https://esphome.io/components/sensor/homeassistant.html\n- platform: homeassistant\n  name: Desired Moisture level 1\n  id: desired_mois_value_1\n  internal: true\n  entity_id: input_number.moisture_level_for_pump1\n\n- platform: homeassistant\n  name: Desired Moisture level 2\n  id: desired_mois_value_2\n  internal: true\n  entity_id: input_number.moisture_level_for_pump2\n\n- platform: homeassistant\n  name: Desired Moisture level 3\n  id: desired_mois_value_3\n  internal: true\n  entity_id: input_number.moisture_level_for_pump3\n\n- platform: homeassistant\n  name: Desired Moisture level 4\n  id: desired_mois_value_4\n  internal: true\n  entity_id: input_number.moisture_level_for_pump4\n\n- platform: homeassistant\n  name: Desired Moisture level 5\n  id: desired_mois_value_5\n  internal: true\n  entity_id: input_number.moisture_level_for_pump5\n\n  # KEEPS MOISTURE LEVEL # Comment out or delete these 5 sensors \"Comparison Sens 1,2,3,4,5\" if you want to automate the Soil Moisture level with Home Assistant \"Automation\".\n- platform: template\n  name: Comparison Sens1\n  internal: true\n  update_interval: 2s   # Seconds to pump water then stops pumping and starts comparing sensors data, if needed it will pump again\n  lambda: |-\n    if (id(Soil1).state < id(desired_mois_value_1).state) {\n      id(pump1).toggle();\n    } else {\n      id(pump1).turn_off();\n    }\n    return {};\n\n- platform: template\n  name: Comparison Sens2\n  internal: true\n  update_interval: 2s   # Seconds to pump water then stops pumping and starts comparing sensors data, if needed it will pump again\n  lambda: |-\n    if (id(Soil2).state < id(desired_mois_value_2).state) {\n      id(pump2).toggle();\n    } else {\n      id(pump2).turn_off();\n    }\n    return {};\n\n- platform: template\n  name: Comparison Sens3\n  internal: true\n  update_interval: 2s   # Seconds to pump water then stops pumping and starts comparing sensors data, if needed it will pump again\n  lambda: |-\n    if (id(Soil3).state < id(desired_mois_value_3).state) {\n      id(pump3).toggle();\n    } else {\n      id(pump3).turn_off();\n    }\n    return {};\n\n- platform: template\n  name: Comparison Sens4\n  internal: true\n  update_interval: 2s   # Seconds to pump water then stops pumping and starts comparing sensors data, if needed it will pump again\n  lambda: |-\n    if (id(Soil4).state < id(desired_mois_value_4).state) {\n      id(pump4).toggle();\n    } else {\n      id(pump4).turn_off();\n    }\n    return {};\n\n- platform: template\n  name: Comparison Sens5\n  internal: true\n  update_interval: 2s   # Seconds to pump water then stops pumping and starts comparing sensors data, if needed it will pump again\n  lambda: |-\n    if (id(Soil5).state < id(desired_mois_value_5).state) {\n      id(pump5).toggle();\n    } else {\n      id(pump5).turn_off();\n    }\n    return {};\n\n  # DHT TMP and HUMIDITY SENSOR  #  https://esphome.io/components/sensor/dht.html    Delet if not used\n#- platform: dht\n#  pin: 5\n#  temperature:\n#    name: \"${name} DHT Temperature\"\n#    id: \"dhttemperature\"\n#  humidity:\n#    name: \"${name} DHT Humidity\"\n#    id: \"dhthumidity\"\n#  update_interval: 5s\n\n  # DISTANCE SENSOR #     # You can measure the height of the plant and plot the growth reight #  https://esphome.io/components/sensor/vl53l0x.html?highlight=vl53l0  Delet if not used\n#- platform: vl53l0x\n#  name: \"${name} VL53L0x Distance\"\n#  id: \"distance\"\n#  address: 0x29\n#  update_interval: 2s\n#  long_range: true\n\n  # BMP280 TMP and HUMIDITY SENSOR #  https://esphome.io/components/sensor/bmp280.html?highlight=bmp280   Delet if not used\n#- platform: bmp280_i2c\n#  temperature:\n#    name: \"${name} bmp280 Temperature\"\n#    oversampling: 16x\n#  pressure:\n#    name: \"${name} bmp280 Pressure\"\n#    id: \"pressure\"\n#  address: 0x76\n#  update_interval: 5s\n\n# https://esphome.io/components/sensor/dallas_temp.html\n#- platform: dallas_temp  \n#  address: 0x6e3c......\n#  name: \"${name} Integrated TMP\"\n#  id: \"intergratedtmp\"\n\n\n  # WIFI #\n- platform: wifi_signal\n  name: ${name} WiFi Signal Sensor\n  id: dbm\n  update_interval: 5s\n\n  # Uptime sensor #\n- platform: uptime\n  name: ${name} Uptime\n  update_interval: 3600s\n\n\nswitch:\n\n  # PUMPS GPIOs #  https://esphome.io/components/switch/gpio.html?highlight=switch\n- platform: gpio\n  pin: 13\n  id: pump1\n  name: ${name} Pump 1\n  icon: mdi:water-pump\n  restore_mode: ALWAYS_OFF\n\n- platform: gpio\n  pin: 4\n  id: pump2\n  name: ${name} Pump 2\n  icon: mdi:water-pump\n  restore_mode: ALWAYS_OFF\n\n- platform: gpio\n  pin: 16\n  id: pump3\n  name: ${name} Pump 3\n  icon: mdi:water-pump\n  restore_mode: ALWAYS_OFF\n\n- platform: gpio\n  pin: 17\n  id: pump4\n  name: ${name} Pump 4\n  icon: mdi:water-pump\n  restore_mode: ALWAYS_OFF\n\n- platform: gpio\n  pin: 18\n  id: pump5\n  name: ${name} Pump 5\n  icon: mdi:water-pump\n  restore_mode: ALWAYS_OFF\n\n  # MCP230017 FOR EXPANSION BOARD # Uncomment when using expansion board  https://esphome.io/components/mcp230xx.html\n- platform: gpio\n  name: '${name} MCP23017 Pin #0'\n  restore_mode: ALWAYS_OFF\n  pin:\n    mcp23xxx: mcp23017_hub\n      # Use pin number 0\n    number: 0\n    mode:\n      output: true\n    inverted: true\n\n- platform: gpio\n  name: '${name} MCP23017 Pin #1'\n  restore_mode: ALWAYS_OFF\n  pin:\n    mcp23xxx: mcp23017_hub\n      # Use pin number 0\n    number: 1\n    mode:\n      output: true\n    inverted: true\n\n- platform: gpio\n  name: '${name} MCP23017 Pin #2'\n  restore_mode: ALWAYS_OFF\n  pin:\n    mcp23xxx: mcp23017_hub\n      # Use pin number 0\n    number: 2\n    mode:\n      output: true\n    inverted: true\n\n- platform: gpio\n  name: '${name} MCP23017 Pin #3'\n  restore_mode: ALWAYS_OFF\n  pin:\n    mcp23xxx: mcp23017_hub\n      # Use pin number 0\n    number: 3\n    mode:\n      output: true\n    inverted: true\n\n- platform: gpio\n  name: '${name} MCP23017 Pin #4'\n  restore_mode: ALWAYS_OFF\n  pin:\n    mcp23xxx: mcp23017_hub\n      # Use pin number 0\n    number: 4\n    mode:\n      output: true\n    inverted: true\n\n- platform: gpio\n  name: '${name} MCP23017 Pin #5'\n  restore_mode: ALWAYS_OFF\n  pin:\n    mcp23xxx: mcp23017_hub\n      # Use pin number 0\n    number: 5\n    mode:\n      output: true\n    inverted: true\n\n- platform: gpio\n  name: '${name} MCP23017 Pin #6'\n  restore_mode: ALWAYS_OFF\n  pin:\n    mcp23xxx: mcp23017_hub\n      # Use pin number 0\n    number: 6\n    mode:\n      output: true\n    inverted: true\n\n- platform: gpio\n  name: '${name} MCP23017 Pin #7'\n  restore_mode: ALWAYS_OFF\n  pin:\n    mcp23xxx: mcp23017_hub\n      # Use pin number 0\n    number: 7\n    mode:\n      output: true\n    inverted: true\n\n- platform: gpio\n  name: '${name} MCP23017 Pin #8'\n  restore_mode: ALWAYS_OFF\n  pin:\n    mcp23xxx: mcp23017_hub\n      # Use pin number 0\n    number: 8\n    mode:\n      output: true\n    inverted: true\n\n- platform: gpio\n  name: '${name} MCP23017 Pin #9'\n  restore_mode: ALWAYS_OFF\n  pin:\n    mcp23xxx: mcp23017_hub\n      # Use pin number 0\n    number: 9\n    mode:\n      output: true\n    inverted: true\n\n- platform: gpio\n  name: '${name} MCP23017 Pin #10'\n  restore_mode: ALWAYS_OFF\n  pin:\n    mcp23xxx: mcp23017_hub\n      # Use pin number 0\n    number: 10\n    mode:\n      output: true\n    inverted: true\n\n- platform: gpio\n  name: '${name} MCP23017 Pin #11'\n  restore_mode: ALWAYS_OFF\n  pin:\n    mcp23xxx: mcp23017_hub\n      # Use pin number 0\n    number: 11\n    mode:\n      output: true\n    inverted: true\n\n- platform: gpio\n  name: '${name} MCP23017 Pin #12'\n  restore_mode: ALWAYS_OFF\n  pin:\n    mcp23xxx: mcp23017_hub\n      # Use pin number 0\n    number: 12\n    mode:\n      output: true\n    inverted: true\n\n- platform: gpio\n  name: '${name} MCP23017 Pin #13'\n  restore_mode: ALWAYS_OFF\n  pin:\n    mcp23xxx: mcp23017_hub\n      # Use pin number 0\n    number: 13\n    mode:\n      output: true\n    inverted: true\n\n- platform: gpio\n  name: '${name} MCP23017 Pin #14'\n  restore_mode: ALWAYS_OFF\n  pin:\n    mcp23xxx: mcp23017_hub\n      # Use pin number 0\n    number: 14\n    mode:\n      output: true\n    inverted: true\n\n- platform: gpio\n  name: '${name} MCP23017 Pin #15'\n  restore_mode: ALWAYS_OFF\n  pin:\n    mcp23xxx: mcp23017_hub\n      # Use pin number 0\n    number: 15\n    mode:\n      output: true\n    inverted: true\n\n- platform: restart\n  name: ${name} Restart\n\noutput:\n\n  # Integrated BUZZER # If you using pin23 for something else, delete this and remove jumper 1  https://esphome.io/components/output/ledc.html?highlight=buzzer\n- platform: ledc\n  pin: GPIO23\n  id: rtttl_out\n\nbinary_sensor:\n\n  # BUTTON SHORT and LONG PRES AVALIABLE IN HOME ASSISTANT #  https://esphome.io/components/binary_sensor/index.html?highlight=binary_sensor\n- platform: gpio\n  name: ${name} Button\n  pin:\n    number: 36\n      # Short press activates OLED for 20s\n  on_click:\n  - min_length: 10ms\n    max_length: 350ms\n    then:\n    - lambda: id(oled).turn_on();\n    - delay: 20s\n    - lambda: id(oled).turn_off();\n      # Long press Do whatever you want\n  - min_length: 500ms\n    max_length: 1500ms\n    then:\n#        - switch.turn_on: relay_1\n\n  # Status (connection) sensor#\n- platform: status\n  name: ${name} Status\n"
  },
  {
    "path": "Config/Home Assistant/VerticalStackCardConfiguration.txt",
    "content": "type: vertical-stack\ncards:\n  - type: horizontal-stack\n    cards:\n      - type: vertical-stack\n        cards:\n          - type: entities\n            entities:\n              - input_number.moisture_level_for_pump1\n          - type: sensor\n            entity: sensor.droplet_soilm_sens_1\n            graph: line\n      - type: vertical-stack\n        cards:\n          - type: entities\n            entities:\n              - input_number.moisture_level_for_pump2\n          - type: sensor\n            entity: sensor.droplet_soilm_sens_2\n            graph: line\n  - type: horizontal-stack\n    cards:\n      - type: vertical-stack\n        cards:\n          - type: entities\n            entities:\n              - input_number.moisture_level_for_pump3\n          - type: sensor\n            entity: sensor.droplet_soilm_sens_3\n            graph: line\n      - type: vertical-stack\n        cards:\n          - type: entities\n            entities:\n              - entity: input_number.moisture_level_for_pump4\n          - type: sensor\n            entity: sensor.droplet_soilm_sens_4\n            graph: line\n  - type: entities\n    entities:\n      - input_number.moisture_level_for_pump5\n  - type: sensor\n    entity: sensor.droplet_soilm_sens_5\n    graph: line\n"
  },
  {
    "path": "Config/Home Assistant/desiredmoisturelevel.yaml",
    "content": "input_number:\n  moisture_level_for_pump1:\n    name: Desired Moisture level 1\n    unit_of_measurement: \"%\"\n    min: 0\n    max: 90\n    step: 1\n    mode: box\n    \n  moisture_level_for_pump2:\n    name: Desired Moisture level 2\n    unit_of_measurement: \"%\"\n    min: 0\n    max: 90\n    step: 1\n    mode: box\n\n  moisture_level_for_pump3:\n    name: Desired Moisture level 3\n    unit_of_measurement: \"%\"\n    min: 0\n    max: 90\n    step: 1\n    mode: box\n\n  moisture_level_for_pump4:\n    name: Desired Moisture level 4\n    unit_of_measurement: \"%\"\n    min: 0\n    max: 90\n    step: 1\n    mode: box\n\n  moisture_level_for_pump5:\n    name: Desired Moisture level 5\n    unit_of_measurement: \"%\"\n    min: 0\n    max: 90\n    step: 1\n    mode: box"
  },
  {
    "path": "LICENSE",
    "content": "BSD 3-Clause License\n\nCopyright (c) 2022, PricelessToolkit\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "README.md",
    "content": "🤗 Please consider subscribing to my [YouTube channel](https://www.youtube.com/@PricelessToolkit/videos)\nYour subscription goes a long way in backing my work.\n\n\n[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/U6U2QLAF8)\n\n# Droplet\n ALL-IN-ONE Irrigation and monitoring system for ESPHome and Home Assistant.\n * Youtube How-To https://youtu.be/mCXTqONmpZk\n * Shop https://www.pricelesstoolkit.com\n \n\n \n ![DROPLETFull](https://raw.githubusercontent.com/PricelessToolkit/Droplet/main/img/dropletfull.JPEG)\n \n \n \n   ### Main Board\n   \n   \n ![DROPLET](https://raw.githubusercontent.com/PricelessToolkit/Droplet/main/img/droplet.jpg)\n \n\n 1. 5x Micro Pump outputs \"5v\"\n 2. 5x Soil Moisture sensor inputs \"Data-5v-GND\" 'Data line pulled down with 1M ohm resistor' ( Data line MAX 3.3v !!!!! )\n 3. Onboard Temperature sensor \"DS18B20\" https://esphome.io/components/sensor/dallas.html\n 4. Onboard Buzzer \"Buzzer port can be free up with jumper\" https://esphome.io/components/rtttl.html?highlight=buzzer\n 5. Breakout pins for connecting \"i2c OLED Display\" https://esphome.io/components/display/ssd1306.html?highlight=display\n 6. 5x Buttons for manual Pumps controll\n 7. 1x Button \"Short press\" for wake-up Oled \"Long press\" for general purpose. \"2x Binary sensors available for HA\"\n 8. All pumps outputs and moisture sensor inputs have fuses\n 9. Pins Which can be used \"GPIO 19,5,26,2,15,27,14,12\" and \"1xi2c GPIO 21,22\" \"1xUART\" \"GPIO25 External port for DS18B20 TMP Sensor!!\"\n \n  ### Expansion Board v3\n  \n  \n ![ExpBoard](https://raw.githubusercontent.com/PricelessToolkit/Droplet/main/img/ExpaBoard.JPG)\n \n \n 1. 1x JST 10pin connector Outputs for 8 Relays  \"MCP23017\" Expander  https://esphome.io/components/mcp230xx.html\n 2. 1x 8 Pin Header \"MCP23017\" Expander  https://esphome.io/components/mcp230xx.html\n 3. 2x XH 4pin i2c (V, GPIO 21, GPIO 22 GND)\n 4. 7x XH 3pin GPIO 19,5,26,2,15,27,14\n 5. 1x XH 3pin for \"DS18B20 TMP Sensors\" (3.3v, GPIO 25, GND)\n 6. 1x 1pin Header GPIO23 connected to buzzer. Buzzer port can be free up, \"remove jumper JP\"\n \n \n\n ## What sensors Droplet support ?\n ### Droplet support \"Almost all sensors supported by ESPHome\" https://esphome.io/index.html\n \n I connected and tested at the same time.\n* 5x Pump\n* 5x Moisture Sensor V2, \n* 2x \"DS18B20\" Temperature, \n* 1x BMP280 Temperature and Pressure, \n* 1x VL53L0x Distance Sensor, \n* 1x DHT Temperature and Humidity, \n* 8x Relays. \n \n \n \n ![HA](https://raw.githubusercontent.com/PricelessToolkit/Droplet/main/img/HASensors.JPG)\n \n \n## First time setup\n\n### WIFI Captive Portal\n\nThe captive portal component in ESPHome is a fallback mechanism for when connecting to the configured WiFi fails.\nAfter 1 minute of unsuccessful WiFi connection attempts, the ESP will start a WiFi hotspot with the credentials\n```\nSSID: \"Droplet Fallback Hotspot\"\npassword: \"password\"\n```\n\nWhen you connect to the fallback network, the web interface should open automatically (see also login to network notifications).\nIf that does not work, you can also navigate to http://192.168.4.1/ manually in your browser.\nIn this web interface, you can manually override the WiFi settings of the device.\nAdditionally, you can upload a new firmware file to your node without having to use a USB cable for uploads.\n\n<img src=\"https://esphome.io/_images/captive_portal-ui.png\" width=\"390\" height=\"400\" />\n\n\n### Reflashing via USB-UART adapter\n\nFirst, you need to create in the ESPhome new device using the Droplet Config file \"don't forget to change it to your needs\" then compile it and download the \".bin\" file. To upload it to the Droplet, we also need  \"ESPHome Flasher\" software\n\n* Connect your USB-UART adapter to the Droplet Mainboard \"GND, 3.3V, TX, RX\"\n* \n  ![HA](https://raw.githubusercontent.com/PricelessToolkit/Droplet/main/img/prog_header.jpg)\n  \n* Push the \"PROG\" button on the Droplet Mainboard \"Don't release it\"\n* Plug the USB-UART adapter to the PC.\n* Upload firmware via ESPHome Flasher.\n* Release the \"PROG\" button.\n \n\n\n\n## Setting the onboard DS18b20 temperature sensor\n\nFirst of all we need to find out the address of the Onboard temperature sensor.\nFor example with this configuration: \"which is already in the default config\"\n\n```yaml\none_wire: #https://esphome.io/components/one_wire\n  - platform: gpio\n    pin: GPIO25\n```\n\nIn the log output (ensure the log level is set to at least debug), you’ll see something like this.\n\n\n<img src=\"https://esphome.io/_images/dallas-log.png\" width=\"634\" height=\"321\" />\n\n\nWith the temperature sensor address identified in the log, we can now enable the Display component by uncomenting  this line.\n\n```yaml\nit.printf(5, 15, id(font3) ,\"%.1f°C\", id(intergratedtmp).state);\n```\n\nIt should look like this in the full configuration.\n\n```yaml\ndisplay: # More info https://esphome.io/components/display/ssd1306.html?highlight=1306         \n- platform: ssd1306_i2c\n  id: oled\n  model: SSD1306 128x64\n  address: 0x3C   # Oled Display Address\n  lambda: |-\n    it.printf(2, 0, id(font2), TextAlign::TOP_LEFT, \"DROPLET\");\n    it.printf(61, 0, id(font2) ,\"%.1f\", id(dbm).state);\n    it.line(0, 12, 98, 12);\n    it.line(98, 0, 98, 64);\n    it.printf(102, 0, id(font2) ,\"%.1f\", id(Soil1).state);\n    it.printf(102, 12, id(font2) ,\"%.1f\", id(Soil2).state);\n    it.printf(102, 24, id(font2) ,\"%.1f\", id(Soil3).state);\n    it.printf(102, 36, id(font2) ,\"%.1f\", id(Soil4).state);\n    it.printf(102, 48, id(font2) ,\"%.1f\", id(Soil5).state);\n    it.printf(5, 15, id(font3) ,\"%.1f°C\", id(intergratedtmp).state);\n#   it.printf(5, 30, id(font3) ,\"%.1fH\", id(dhthumidity).state);\n#   it.printf(5, 45, id(font3) ,\"%.1fP\", id(pressure).state);\n\n```\n\nNow, uncomment the integrated temperature sensor configuration and add the address.\n\n```yaml\n  - platform: dallas_temp\n    address: 0x6e3c......\n    name: \"${name} Integrated TMP\"\n    id: \"intergratedtmp\"\n```\nAfter adding it to the configuration, reinstall the firmware once more.\n \n\n## Part List\n> [!NOTE]\n> !!! Sellers often change the type of pump, so the link may not be relevant. !!!\n> The correct pump connector pitch is 2.54 mm.\n\n* Power adapter 5v 2-3.5Ah Connector DC-005 2.0 - https://s.click.aliexpress.com/e/_DEsuOdV\n* OLED Display - https://s.click.aliexpress.com/e/_DlkmoXv\n* Water Pump \"Model B JSB1523\" 5V \"Connector pitch 2.54mm\"\n- - https://s.click.aliexpress.com/e/_ok8vbDj\n- -  https://s.click.aliexpress.com/e/_op1xxnx\n- -  Any 5v 0.3A pump with Connector pitch 2.54mm - https://fr.aliexpress.com/w/wholesale-water-pump-5v--jsb1523.html\n \n* Water Pump Datasheet - https://github.com/PricelessToolkit/Droplet/blob/main/Water_Pump_JSB1523008.pdf\n* Silicone tube \"inner diameters 3 and 4mm\" - https://s.click.aliexpress.com/e/_DBnM9qL\n* Heat Set Insert M3 X D4.6 X L4.5 - https://s.click.aliexpress.com/e/_9xbSZC\n* Capacitive Soil Moisture Sensor \"lottery may be working or defective\" - https://s.click.aliexpress.com/e/_oDhHhEv\n* Cables with connectors for sensors and relays \"pin pitch XH 2.54MM\" - https://s.click.aliexpress.com/e/_DDpn7iB\n* 3D Case \"For those who live in France\" you can order here - https://www.facebook.com/Upin3d\n* Cable for soil moisture sensor https://s.click.aliexpress.com/e/_DDGNx5h\n"
  }
]