Propane Tank Monitor TankUtility Python Script

I put together a small Python script to check the TankUtility propane tank gauge and put into an openHAB item which you can see below. I’ve just started using it, so I can’t say much about the script or the gauge reliability. I’ll post an update as I use it more.

Some notes:

  1. The gauge updates once per day, so there is no point in running this more than once per day.
  2. This is not local; it pulls the data from TankUtility’s server. If I find out how to get the data locally, I’ll change the script.
  3. You need an RRD gauge on your tank which TankUtility will sell you for $15 if you don’t already have this.
  4. I chose Python because I’m guessing that this could be converted to a Jython rule easily. I think this can be done fairly easily in rules DSL as well.
  5. I call the script from cron once per day.
  6. There is no error checking - that needs to be added.

The API is here. I am new to Python, so I’m sure this could use some improvement. There is other data that can be collected as well including the time of the reading and the temperature (of what? there’s no sensor in the tank - maybe it is the interface box’s temperature).

import requests
from requests.auth import HTTPBasicAuth

# change these appropriately
openHABHostAndPort = 'http://192.168.1.216:8080'
TankUser           = 'email@somewhere.com'
TankPassword       = 'whatever'

def putToOpenHAB(item, itemData):
    ItemURL = openHABHostAndPort + '/rest/items/' + item + '/state'
    OpenHABResponse = requests.put(ItemURL, data = str(itemData).encode('utf-8'), allow_redirects = True)

def Main():
    jsonTokenResponse = requests.get('https://data.tankutility.com/api/getToken', auth=HTTPBasicAuth(TankUser, TankPassword)).json()
    jsonDeviceResponse = requests.get('https://data.tankutility.com/api/devices?token=' + jsonTokenResponse["token"]).json()
    # below is querying the first tank in the account - adjust the [0] if you want other tanks
    jsonTankDataResponse = requests.get('https://data.tankutility.com/api/devices/' + jsonDeviceResponse["devices"][0] + '?token=' + jsonTokenResponse["token"]).json()

    print(jsonTankDataResponse["device"]["lastReading"]["tank"])
 
    putToOpenHAB('TankLevel', jsonTankDataResponse["device"]["lastReading"]["tank"])

if __name__ == '__main__':
    Main()

1 Like

Very easily… let me know if you’d like some help with it!

Is there any way to monitor the tank without utilizing a connection over the internet? This is something I’d like to implement, but I’m leery of connections to equipment that require an internet connection back to the manufacturer. I’d like to know the status just over the LAN if possible.

There is no supported way with the TankUtility to get local information. I have requested that they add that. If you and others request it too, it might get implemented. As far as unsupported, I haven’t had a chance to look at it yet. I’d probably need to get wireshark running around the time it tries to update and see what it is doing. I can’t really say how hard it will be.

The other way to go about this is to make your own hall effect sensor. I think this is probably possible and then you could add other features such as a solar panel and rechargeable batteries. But what dissuaded me is that equipment around propane tanks is supposed to be certified for that use (at least in my area). It wasn’t worth risking being blamed for an explosion just to have a few features and local data. Not that this is likely, but in my mind it wasn’t worth it.

Here’s the Jython version. Took some work, but it is possible.

The monitor itself seems to work fairly well. Some bouncing around because the level is dependent on the temperature. Need to work on a compensation method for that. Overall, though, I’m pretty happy with it.

"""
TankUtility Jython Rule
"""

from core.rules import rule
from core.triggers import when
from core.actions import HTTP
import json
import base64

@rule("TankUtility", description="Picks up propane tank values from Tank Utility servers", tags=[])
@when("Time cron 14 20 4,10,16,22 * * ?")
def tankUtilityDataCollection(event):
    # tankUtilityDataCollection.log.info("TankUtility script is running")

    # change these appropriately
    TankUser           = 'someEmail@gmail.com'
    TankPassword       = 'XXXYYYZZZ'
    encoded = base64.b64encode(TankUser + ':' + TankPassword)

    headers={'Authorization': 'Basic ' + encoded}

    TokenResponse = HTTP.sendHttpGetRequest("https://data.tankutility.com/api/getToken", headers, 10000)
    jsonTokenResponse = json.loads(TokenResponse)
    # tankUtilityDataCollection.log.info("Token is: " + jsonTokenResponse["token"])
    DeviceResponse = HTTP.sendHttpGetRequest('https://data.tankutility.com/api/devices?token=' + jsonTokenResponse["token"])
    # tankUtilityDataCollection.log.info("Device response is: " + str(DeviceResponse))
    jsonDeviceResponse = json.loads(DeviceResponse)
    # tankUtilityDataCollection.log.info("Device 0 is: " + jsonDeviceResponse["devices"][0])
    TankDataResponse = HTTP.sendHttpGetRequest('https://data.tankutility.com/api/devices/' + jsonDeviceResponse["devices"][0] +
 '?token=' + jsonTokenResponse["token"])
    jsonTankDataResponse = json.loads(TankDataResponse)

    tankUtilityDataCollection.log.info("Device 0 data is: " + str(jsonTankDataResponse["device"]["lastReading"]["tank"]))

#update for your Items appropriately
    events.postUpdate("TankLevel", str(jsonTankDataResponse["device"]["lastReading"]["tank"]))
    events.postUpdate("TankTemperature", str(jsonTankDataResponse["device"]["lastReading"]["temperature"]))
    events.postUpdate("TankTime", str(jsonTankDataResponse["device"]["lastReading"]["time"]))

Moving over from Home Assistant to Openhab. Had this previously installed and reading properly. I’ve gone ahead and added the script, but have NO idea how to pull data into anything now. Any help available?

Which script have you added (the Python in the first post, or the Jython version)? Does the basic Python script work for you in the first post? Do you see anything in the logs? Did you edit the script for your particular settings?

Note that the first post requires you to run the script outside of OH. You must run it from a cron job or equivalent. Run it from the command line (assuming you are using Linux) while debugging before trying to add it to cron.

I’ve only used OH 2.5. The script may need adjustments for 3.2. Once I upgrade, I’ll convert this to JS.

I’m using Windows 10. Yes, I have Python installed, changed the appropriate information, and ran it. Looks like I need to get a propane order in soon. Works fine, just trying to figure out how to pull the reading into Openhab.

So I’ve run it like this:

python tankutility.py >tanklevel.txt

It generated the tanklevel.txt with the reported reading. How would I use that, possibly JSON style?

This line in the Python script puts the update to the Item in OH. Are you getting any error response from it? That’s the key line to get Item with the correct value in OH. This is using the rest API. I have hard coded the Item to be “TankLevel”. You do have an Item named “TankLevel”? If you have a different Item name, then change that line appropriately. I suppose I should change this script to have a “TankItemName” at the top.

Figured it out, thank you. Set up HTTP binding and the JSON transformation, pulls data from the API. Took a while to figure out that I needed to set up channels (properly) to add points.