Bluetooth propane tank monitor: ESPhome, Otodata, Nee-vo, Ferrellgas, BLE

Any chance you can post your full YAML? Whenever I try I’m getting config errors on line 1, so I’m not sure what I’m doing wrong at this point. Complete noob and the esphome documentation really lacks.

@tinker_ha

@tinker_ha I got this working, think I had some issues with the distance of course. Were you able to get these readings into the Energy Dashboard?

I know what you mean. ESPHome docs are often not very helpful. Tell me, with max detail, what you have a problem with? Perhap I can help you out with more detail?

I did not try to incorporate this data into the Energy Dashboard because I do not think it is an accurate reading that can be translated to an accurate cost. The tank percentage value is based on a physical float sensor value that is not proportional to actual usage. This inferred usage value fluctuaces a lot during the day due to temperature and sunlight exposure. Higher temp or more sunlight gives higher pressure, higher pressure is used to infer higher percentage capacity. So none of this is useful as “actual energy cost”.

1 Like

I got it all working, my issue was finding the right spot to put my ESP32 at. My tank is out by a barn, so I put it in there. Trying a metal shed gave me issues, but the barn worked.

I’ve noticed the fluctuation too. Makes sense not to put it in the energy dashboard. I made a gauge card that has a red/yellow/green status.

I was so happy to find this article! I had tried scraping the values off the Otodata website and other tricks since I got the gauge installed last year, but after some time just gave up since it didn’t work.
So I set up an ESP32 and let it listen on BLE. And sure enough – got the messages! So I implemented the code shown above and was a happy camper for about a week. Since then, no more bluetooth messages from the gauge. It’s still updating via cellular (I can see the updates in the app).
Wondering if they rolled out new firmware that turned off BLE? Or maybe something is wrong with my gauge? Any thoughts?
(for clarity – it’s still picking up lots of other BLE traffic, so I don’t think it’s the ESP board)

May have figured it out … The BLE messages cycle between TM6030, unit sleeping, 310410.1|0|-73 and trbl:ACC (45.2).
The 310410.1 is the cell network it’s connected to. And I suspect the -73 is the RSSI for that. The TM6030 speaks for itself as does the unit sleeping.
I logged on to the Otodata portal (my supplier gave me access to just my tank), and found that the sensor is reporting a problem. Specifically with accuracy. So perhaps trbl:ACC means trouble code Accuracy. I guess the 45.2 is probably the tank level now.
I’ll wait it out a few days and see if it changes. If not, I’ll ask the propane company to come service it.

For completeness – this is my updated yaml:

esphome:
  name: ble-propane

esp32:
  board: esp32dev
  framework:
    type: arduino

wifi:
  ssid: "xxxxxxx"
  password: "xxxxxx"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "BLE-Propane Fallback Hotspot"
    password: "xxxxxxxx"

# Enable logging
logger:

ota:

esp32_ble_tracker:
  scan_parameters:
    interval: 1100ms
    window: 1100ms
  on_ble_advertise:
    - mac_address: XX:XX:XX:XX:XX:XX
      then:
        - lambda: |-
            ESP_LOGD("ble_adv", "  name: %s", x.get_name().c_str());
            std::string name = x.get_name();
            if (esphome::str_startswith(name, "level:")) {
              name.erase(0,7);
              std::string value = esphome::str_until(name.c_str(), ' ');
              id(propane_level).publish_state(atof(value.c_str()));
              id(propane_sensor_ok).publish_state(true);
            }
            if (esphome::str_startswith(name, "trbl:ACC")) {
              name.erase(0,10); 
              std::string value = esphome::str_until(name.c_str(), ')');
              id(propane_level).publish_state(atof(value.c_str()));
              id(propane_sensor_ok).publish_state(false);
            }

sensor:
# To store the propane level percentage - does nothing on its own.
  - platform: template
    name: Propane Level
    id: propane_level
    unit_of_measurement: '%'

# Reports the signal strength auto magically.
  - platform: ble_rssi
    mac_address: XX:XX:XX:XX:XX:XX
    name: "Propane RSSI"

binary_sensor:
  - platform: template
    name: Propane Sensor Ok
    id: propane_sensor_ok

api:


      
4 Likes

They don’t sell them. I picked up a TM6030 on eBay. I was able to add it to the Nee-Vo app (to my surprise as I found another unit for sale with a picture of the auth code and was unable to add it). The app showed 50% for a day, but finally is showing the correct percentage.

Even without adding it to the app, it broadcasts propane percentage every 15-20 mins or so. Since my genmon controller (pi zero 2) is close to my propane tank, I figured I’d use it as to look for updates and post those to genmon and hubitat. Running sudo hcitool lescan --duplicates and sending that to a script to look for the level updates appears to work great. I’m super-happy to have a low-tech solution working.

Date: Tue  6 Dec 21:35:59 EST 2022 Level: 56.3                                  
DATA: 'generator: set_tank_data={"Tank Name": "External Tank", "Capacity": 320, "Percentage": 56.3}'                                                            
OK : Auto, Off - Ready                                                          
>OK                                                                                                                 
                                                                                
Date: Tue  6 Dec 21:42:53 EST 2022 Level: 56.1                                  
DATA: 'generator: set_tank_data={"Tank Name": "External Tank", "Capacity": 320, "Percentage": 56.1}'                                                            
OK : Auto, Off - Ready                                                          
>OK

My biggest concern is battery. Says it has a 10-15 yr battery. I took the screws out and could not easily get into it. Since it’s working, I’m not going to mess with it to break any seals. If anyone has successfully removed/opened the unit, I’d be interested in the details.

To meet code the unit are completely sealed (no ignition source). I’m sure you will be able to replace the battery, and probably reseal it, but agree you should not do it until it dies.

Awesome - thanks for the addition. Will add that to my install.

It took some effort but I did open mine. I put a flat head into the slot on the one side and peeled it up.
I also don’t need to replace the battery but was curious. Here is a pic of the battery. I couldn’t find a pack anywhere but i am sure it can be made easily by buying each cell separately.
Thank you all for this ! @tinker_ha

2 Likes

SOLVED: default scanning windows is too short to reliably catch the level. Increasing window to 1100ms picks it up!

Ok, so the code compiles alright and the config goes onto the esp32…but it doesn’t seem to be pinging the tank? If I use nRF Connect the esp32 picks up the tank levels, but it’s not doing it on it’s own. What am I missing here?

Config below:

# Bluetooth for Propane tank sensor

esp32_ble_tracker:
  scan_parameters:
    interval: 10s
    duration: 300s

# Sending state data: '{"timestamp":1309,"address":"C3:2E:95:XX:XX:XX","rssi":-69,"name":"level: 67.4 % horiz"}'
  on_ble_advertise:
    - mac_address: DC:24:XX:XX:XX:XX
      then:
        - lambda: |-
            std::string name = x.get_name();
            if (esphome::str_startswith(name, "level:")) {
              name.erase(0,7);
              std::string value = esphome::str_until(name.c_str(), ' ');
              id(propane_level).publish_state(atof(value.c_str()));
            }

sensor:
# To store the propane level percentage - does nothing on its own.
  - platform: template
    name: Propane Level
    id: propane_level
    unit_of_measurement: '%'

# Reports the signal strength auto magically.
  - platform: ble_rssi
    mac_address: DC:24:XX:XX:XX:XX
    name: "Propane RSSI"
2 Likes

Looks like you can get it here.

I am curious how one would charge it or if a standard lipo charging circuit would work?

$20 isn’t bad for a 10 year battery (woops. minimum quantity is 100!)

1 Like

Good stuff!

My Tank Utility Unit stopped working in November 22 after a long time off-line and a battery replacement. I get the feeling they tombstoned them, or it was a failed update. What this does do is leave me with the right angle gauge sensor and a shell for an ESP32 replacement. Eventually i’ll get that up on github if it isn’t already there.

In the meantime, i see a couple of inexpensive monitors mentioned here on the 'bay.

Cheers!

In case you want to dig into how the OEM app communicates with the BLE controller to replicate the same behaviour you can use an Andorid phone and enable the HCI Snoop Log:

That log file can be loaded into Wireshark and you will be able to see what’s being sent and received by the app.

In case y’all are interested, Sinope finally released their long-promised zigbee monitor.
$160 each.
May be a reasonable price compared to all the effort of finding parts and assembling a DIY model.

I asked them, and they said they have “no plans” to offer a wifi or BLE or zwave model. :frowning:

Thanks for posting this, it got me up and running in no time. I had been trying to merge this config on a ESP32 dev board that I had been using for ESPHome Bluetooth Proxy but it wasn’t working. I had to comment out the BT Proxy business:

#packages:
#  esphome.bluetooth-proxy: github://esphome/bluetooth-proxies/esp32-generic.yaml@main

And then after a few minutes the propane tank data started flowing into HA. Hope maybe this helps someone else. Thanks again!

DaBer

I’ve been totally impressed with the Mopeka Pro and Pro+ tank monitors.

I found a post on Reddit that listed the URL to the JSON data and I was able to get my propane level into my Home Assistance dashboard by using the command_line platform. There may be better ways to do this, but this is what I came up with and it seems to work.

command_line:
  - sensor:
      command: "curl -u Neevoemailaddress:Neevopassword https://telematics.otodatanetwork.com:4432/v1.5/DataService.svc/GetAllDisplayPropaneDevices --header Content-Type:application/json"
      name: "Propane Tank"
      unique_id: propane_tank
      value_template: "{{ value_json[0].Level }}"
      scan_interval: 86400
3 Likes

Holy cow!

This is exactly what I’ve been looking for and exactly what I need.

I just implemented it and it works great.

FYI, for multiple tanks, increment the “value_json” by 1 for each tank (value_json[1], for example).

Now I need the same thing for Amerigas…

Thank you!

3 Likes

Have been trying to implement this and not seeing the sensor created. My curl command works fine at the command line with my credentials.

Am I missing something as far as any formatting that needs to occur? I’ve tried it both directly in the configuration.yaml and the templates.yaml that I’ve created and still not seeing results.