Tuesday, January 30, 2024

ESPHome Water Softener Salt Level Sensor

Sometime ago I was searching for a way to monitor the level of salt in my water softener and came across this post using a D1 mini and an Ultrasonic Distance Sensor with ESPHome. I don't have many devices connected to ESPHome, and it is quite sparse only about 5 devices. Some temperature/humidity sensors, a string light switch, a bluetooth proxy, and now this water softener sensor.

The configuration from here was working great until the latest update to ESPHome, mostly my fault because I didn't read the release notes. When I went to update the sensor, I could only get the measurements to return and not the percentage. Come to find out that what was missing was the ability for the trigger pin and echo pin to allow to be reused:

- platform: ultrasonic
  trigger_pin: 
    number: D2
    allow_other_uses: true
  echo_pin: 
    number: D1
    allow_other_uses: true

A few modifications that I made (albeit not sure if it makes any difference) was to set a global variable for the maximum distance detected by the sensor

globals:
 - id: maximum_distance
   type: float
   initial_value: '0.83'

Then also to save the measurement as an id salt_level_measurement to be reused for the calculation of percentage and use the maximum_distance variable:

 - platform: ultrasonic
    trigger_pin: 
      number: D2
      allow_other_uses: true
    echo_pin: 
      number: D1
      allow_other_uses: true
    name: Salt level measurement
    update_interval: 60s
    pulse_time: 200ms
    timeout: 4.0m
    id: salt_level_measurement
    filters:
      - lambda: return (id(maximum_distance)-x)*(100/id(maximum_distance));
      - filter_out: nan
    unit_of_measurement: cm

All in all, it works really well. Here is the complete config file for the sensor, the update time is every 60 seconds which may be overkill, but I'll end up adjusting it if need be. Hope this helps!

api:
  encryption:
    key: "redacted"
captive_portal:
esp8266:
  board: d1_mini
esphome:
  name: ${name}
  friendly_name: ${friendly_name}
globals:
 - id: maximum_distance
   type: float
   initial_value: '0.83'
logger:
ota:
  password: "redacted"
sensor:
  - platform: uptime
    name: salt_level_sensor Uptime
  - platform: wifi_signal
    name: salt_level_sensor WiFi Signal
    update_interval: 60s
  - platform: ultrasonic
    trigger_pin: 
      number: D2
      allow_other_uses: true
    echo_pin: 
      number: D1
      allow_other_uses: true
    name: Salt level measurement
    update_interval: 60s
    pulse_time: 200ms
    timeout: 4.0m
    id: salt_level_measurement
    filters:
      - lambda: return (id(maximum_distance)-x)*(100/id(maximum_distance));
      - filter_out: nan
    unit_of_measurement: cm
  - platform: ultrasonic
    trigger_pin: 
      number: D2
      allow_other_uses: true
    echo_pin: 
      number: D1
      allow_other_uses: true
    name: Salt level percent
    update_interval: 60s
    pulse_time: 200ms
    timeout: 4.0m
    filters:
      - lambda: return (id(maximum_distance)-x)*100;
      - filter_out: nan
    unit_of_measurement: "%"
substitutions:
  name: salt-level-sensor
  friendly_name: Water Softener
switch:
  - platform: restart
    name: salt_level_sensor Restart
text_sensor:
  - platform: version
    name: salt_level_sensor ESPHome Version
  - platform: wifi_info
    ip_address:
      name: salt_level_sensor IP
    ssid:
      name: salt_level_sensor SSID
    bssid:
      name: salt_level_sensor BSSID
time:
  - platform: homeassistant
    id: homeassistant_time
web_server:
  port: 80
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: "Salt-Level-Sensor"
    password: "redacted"

Saturday, November 6, 2021

Add install path for pip packages

After installing pip packages on Ubuntu 20.04, an warning message that packages are installed in '/home/user/.local/bin' which is not on PATH.Consider adding this directory to PATH.

To achieve this, open terminal and add the pip packages path to your .bashrc and then reload the file into your environment.

echo "export PATH=\"/home/${USER}/.local/bin:\$PATH\"" >> ~/.bashrc && source ~/.bashrc

If adding the install location to the path is not needed, this is only a warning and can be suppressed by using --no-warn-script-location when running pip install

Sunday, August 22, 2021

Control Sunforce Solar String Lights with Raspberry Pi

I recently picked up these Sunforce 35' Solar String Lights with a remote control from Costco


 

After some initial research, and looking up the FCC ID 2AX4R-101015 the remote control operates on 433.92MHz. There are plenty of tutorials about using either a Raspberry Pi or an Arduino ESP32 to make a transmitter and receiver, and a lot of programs to help decode the signal. The remote control uses Amplitude Shift Keyring (ASK) which is just an on or off binary code repeated. Some 433MHz codes use a rolling code to change the code each time, but not any of the cheap stuff. You can find a number of these cheap remote controls on Amazon or AliExpress.

REMEMBER: This is just a guide for hobbyists, and is not intended for any malicious activity. Check with your local government before proceeding.

I ordered this Nooelec NESDR Mini dongle from Amazon, it worked with Ubuntu 20.04 out of the box. The first thing that we need to do is to use a dongle for Software Defined Radio (SDR) with a program called Universal Radio Hacker.

Installing URH:

$ sudo apt update && sudo apt install python3 # Install Python3
$ sudo python3 -m pip install --upgrade pip # Update your pip installation $ sudo python3 -m pip install urh # Install URH
$ urh # Launch URH

After launching URH, we can now capture the radio signal from the remote control by clicking File > Record Signal

URH will show the waveform and you can save it to a file to further analyze the signal.


You can see the signal here repeats itself and URH will show a proposed code, and you can zoom in one one of the repetitions to further analyze it. We'll need to note the length between the pauses, and the binary code that gets sent. Further analysis we can get the length of the codes from when the transmitter is switched on and off:



This is measured in micro seconds which will need to be converted into seconds, and find the pattern of the code that gets repeated.


After further investigation, the binary code seemed to be as follows from URH:

1 = 0111

0 = 0100

So for the code, I used the long_delay as 1 and short_delay as 0 and the final signal was found to be 1010101011111111111010001. Now we can wire up the Raspberry Pi 4 with the 433MHz transmitter from Amazon connecting it to GPIO pin 17.The Python Code can be found on GitHub and is originally from an Instructables tutorial. Be sure to install RPi.GPIO if it is not already installed


sudo python3 -m pip install RPi.GPIO

and put the user in the gpio group on the pi

sudo usermod -aG gpio ${USER}

To run the script enter the terminal via ssh and run

python3 /path/to/script/string_lights.py switch

I am not sure why the number of attempts is set at 6, but it works. Be sure to change the transmit pin to which ever you connect the transmitter to. Also, it doesn't have to be on GPIO pin 17 but that is what worked in my case.  Next project is to integrate it with MQTT and HomeAssistant.

Thursday, May 6, 2021

Install sshpass on MacOS

 If you are using Ansible, and connecting to hosts via password and not ssh keys you'll need the sshpass program to run playbooks or you may see an error similar to this:

TASK [Gathering Facts] ************************************************************************************
fatal: [host01]: FAILED! => {"msg": "to use the 'ssh' connection type with passwords, you must install the sshpass program"}

To get around this, you can install it with brew. From stackoverflow this one liner worked to install it.

curl -L https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb > sshpass.rb && brew install sshpass.rb && rm sshpass.rb

You can also download the tar file from sourceforge and build it locally:

curl -O -L  https://sourceforge.net/projects/sshpass/files/sshpass/1.06/sshpass-1.06.tar.gz && tar xvzf sshpass-1.06.tar.gz
cd sshpass-1.06/
./configure
sudo make install

Hope this helps. Please comment if you have found a better way, Thanks!

Thursday, April 29, 2021

Show Git Branch in zsh

Doing a google search for setting the git branch in terminal will return a number or blogs or stackoverflow posts. The guide here at The Modern Coder is an easy guide to follow and really well explained. I took what Jack did and wrapped it into a script to set it for zsh on Mac OS. Similar to my script for setting Python3 as the default Python interpreter (it uses the same if statement for determining the shell).

# set rc file
SHELL=$(echo ${SHELL})
if [ ${SHELL} == "/bin/bash" ]; then
    RC="/Users/${USER}/.bashrc"
elif [ ${SHELL} == "/bin/zsh" ]; then
    RC="/Users/${USER}/.zshrc"
else
    echo "${SHELL} not supported"
fi

read -r -d '' SHOW_GIT_BRANCH <<'EOF'
    # Load version control information
    autoload -Uz vcs_info
    precmd() { vcs_info }
    # Format the vcs_info_msg_0_ variable
    zstyle ':vcs_info:git:*' formats 'on branch %b'
    # Set up the prompt (with git branch name)
    setopt PROMPT_SUBST
    PROMPT='%n in ${PWD/#$HOME/~} ${vcs_info_msg_0_} > '
EOF

GIT_BRANCH_SET=$(cat ${RC} | grep -q PROMPT=)
if [ ${?} == 1 ] && [ ${SHELL} == "/bin/zsh" ]; then
    echo ${SHOW_GIT_BRANCH} >> ${RC}
else
    echo "git shell settings already exist"
fi

This has been tested on a fresh install of macOS Big Sur (11.2.3). The script can also be pulled from a gist here on GitHub here. Hope this helps. If there are any issues or improvements please reach out.

Sunday, April 25, 2021

Set Python3 Default for Mac OS

With the deprecation of Python 2 and macOS shipping with it as the default, there are many guides on how to update it to Python 3. Following a guide here using Homebrew, I decided to put it into a script to run in case I needed to reinstall the operating system on my laptop. 

# install homebrew if not present; password required
HOMEBREW=$(which brew)
if [ ${HOMEBREW} == "" ]; then
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
else
    brew update && brew install python
fi

# set rc file
SHELL=$(echo ${SHELL})
if [ ${SHELL} == "/bin/bash" ]; then
    RC="/Users/${USER}/.bashrc"
elif [ ${SHELL} == "/bin/zsh" ]; then
    RC="/Users/${USER}/.zshrc"
else
    echo "${SHELL} not supported"
fi

# set alias for python to python3
PY_ALIAS="alias python=/usr/local/bin/python3"
ALIAS=$(cat ${RC} | grep -q python)
if [ ${?} == 1 ]; then
    echo ${PY_ALIAS} >> ${RC}
fi

This has been tested on a fresh install of macOS Big Sur (11.2.3), and will install homebrew if not present. It can be run for both bash and z-shell by setting the run commands file as a variable, then set the alias if it is not present. Hope this helps, if there are any issues or improvements please reach out. You can download the .sh file from a gist on GitHub here.

Friday, December 27, 2019

Discover External IP from Command Line

Getting your external IP address from the command line in both windows and linux is very easy with the OpenDNS resolver and a couple of easy commands found here.

In short, use dig on any unix variant (Linux, BSD, MacOS) as it is usually installed by default

dig +short myip.opendns.com @resolver1.opendns.com

and on Windows, if you don't have dig installed you can use nslookup

nslookup myip.opendns.com. resolver1.opendns.com