Smart Oil Guage

+1 to this, I’m also interested!

Just to chime in here again - is anyone actively developing this? I’m brand new to Home Assistant (and so maybe not quite ready to take this on entirely myself), but I am willing to help code it if someone has more experience with Python and Home Assistant.

Currently no one seems to be working on this. Do you have an idea where to start?

I didn’t realize this when I bought the device, but it looks like they are really targeting fuel suppliers with their product (see https://www.dropletfuel.com/ )

It also looks like access to their API costs $2/month/device which seems a little crazy… I’m kicking myself for not having purchased a Tank Utility monitor, and asking my oil company to install the right guage (https://support.tankutility.com/hc/en-us/articles/360024514933-Can-you-monitor-fuel-oil-)

I’m not really interested in using their API if they’re going to charge hobbyists for using it. I have heard that some people have had luck scraping the site. I also saw a thread somewhere (can’t find it again) where someone was thinking about using the Alexa integration to pull data. But personally, no I don’t know where to start with this one…

Okay, i came up with maybe the hackiest solution, but it works. Definitely open to ideas on improvement. (NOTE: I’m still new to this forum, so if it makes sense let me know if this should be a separate thread)

UPDATE: See @Zalaban’s post below for a better strategy using Node-Red

The end result I wanted was a percentage for my oil tank, and that’s what I ended up getting to:
image

Here’s how I did it:

1. Log into https://app.smartoilgauge.com/
2. Right-click and get some cookie values… the ones you want are “_fpb” and “PHPSESSID”
3. Find a good, random user agent string to use… you can find one here: Random User Agent | User Agents
4. Edit configuration.yaml, add the following for the new sensor:

  - platform: command_line
    command: "curl 'https://app.smartoilgauge.com/ajax/main_ajax.php' -H 'X-Requested-With: XMLHttpRequest' -H '<YOUR_RANDOM_USER_AGENT_STRING>' -H 'Cookie: _fbp=<YOUR_FPB_VALUE> PHPSESSID=<YOUR_PHPSESSID_VALUE>' --data 'action=get_tanks_list' |  jq '.tanks| .[] | { sensor_status: .sensor_status, battery: .battery, sensor_gallons: .sensor_gallons | tonumber, nominal: .nominal | tonumber }'"
    name: "Oil Monitor"
    json_attributes:
      - sensor_status
      - battery
      - sensor_gallons
      - nominal
    scan_interval: 3600
    value_template: "{{ value_json }}"

5. Also in configuration.yaml, add the following:

template:
  - sensor:
    - name: "Oil Tank Percent"
      unit_of_measurement: "%"
      state: "{{ (state_attr('sensor.oil_monitor', 'sensor_gallons') / state_attr('sensor.oil_monitor', 'nominal') | float * 100) | round(1) }}"
      icon: "mdi:oil"

6. You should now have a sensor entity for “Oil Monitor” with some helpful values as well as “Oil Tank Percent” that you can use elsewhere

NOTES:
* I did try this with REST but could not get that to return values from the endpoint… something about the Python library that Home Assistant uses…
* I was unable to combine the percentage into the command_line sensor… if anyone knows how to do that please let me know!
* Because there isn’t any real authentication method here, I don’t know how often or even if you will have to log in separately to keep the responses coming. I’m definitely open to suggestions on this since it will probably be the single biggest headache with this approach.

1 Like

I’m interested in an oil tank gauge and wish someone would make an open local gauge. I also hope that the home-assistant team adds oil to the energy dashboard soon.

With that said the smart oil tank meter is the common one floating around the web. But has anyone come across the Beckett link connected tank gaige before? It looks like it requires a base station which means it’s probably running some RF 433MHz chip or ZigBee. Maybe we can use this sucker.

https://www.beckettcorp.com/beckettlink-connected-tank-gauge-system/

1 Like

I haven’t finished setting up HASS yet but I have an integration working in NodeRED (which you can also enable in HASS).

The integration logs into the website, gets the required cookies and then hits the same main_ajax page you are in order to extract the required data.

NodeRED import code:

[{"id":"679fbd256c1ec156","type":"inject","z":"4a88c65d5156b41a","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":340,"y":340,"wires":[["1819507890ac02e0"]]},{"id":"1819507890ac02e0","type":"http request","z":"4a88c65d5156b41a","name":"Get Session Cookie","method":"GET","ret":"txt","paytoqs":"ignore","url":"https://app.smartoilgauge.com/login.php","tls":"","persist":false,"proxy":"","authType":"","x":350,"y":400,"wires":[["4fb8a0f4e7819484"]]},{"id":"4fb8a0f4e7819484","type":"function","z":"4a88c65d5156b41a","name":"LOGIN CONFIG HERE","func":"var smartOilUser = \"[email protected]\";\nvar smartOilPassword = \"P4ssw0rd\";\nvar cookies = msg.responseCookies;\nvar cff_nonce = msg.payload.match(\"(?<=name='ccf_nonce' value=')(?:[^']|'')*(?=')\");\nmsg.headers = {\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Cookie\" : \"PHPSESSID=\" + cookies.PHPSESSID.value,\n        \"User-Agent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36\"\n};\n\nmsg.payload =  \"username=\" + smartOilUser + \"&user_pass=\" + smartOilPassword + \"&ccf_nonce=\"+cff_nonce[0];\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":340,"y":460,"wires":[["e1b71817c7ef2a23"]]},{"id":"e1b71817c7ef2a23","type":"http request","z":"4a88c65d5156b41a","name":"Login to the smartoil website","method":"POST","ret":"txt","paytoqs":"ignore","url":"https://app.smartoilgauge.com/app.php","tls":"","persist":false,"proxy":"","authType":"","x":380,"y":520,"wires":[["1c8ac8aee89e36fa"]]},{"id":"a7124ae6be1f3c0c","type":"http request","z":"4a88c65d5156b41a","name":"Scrape website for info","method":"POST","ret":"obj","paytoqs":"ignore","url":"https://app.smartoilgauge.com/ajax/main_ajax.php","tls":"","persist":false,"proxy":"","authType":"","x":370,"y":640,"wires":[["48570d654a9c6c55"]]},{"id":"1c8ac8aee89e36fa","type":"function","z":"4a88c65d5156b41a","name":"Prepare query","func":"var cookies = msg.responseCookies\nmsg.headers = {\n\"X-Requested-With\": \"XMLHttpRequest\",\n\"Content-Type\": \"application/x-www-form-urlencoded\",\n\"User-Agent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36\",\n\"Cookie\" : \"PHPSESSID=\" + cookies.PHPSESSID.value\n};\nmsg.payload =  {\n  \"action\": \"get_tanks_list\",\n  \"tank_id\": \"0\"\n};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":580,"wires":[["a7124ae6be1f3c0c"]]},{"id":"48570d654a9c6c55","type":"function","z":"4a88c65d5156b41a","name":"Extract required data here","func":"node.status({text:msg.payload.tanks[0].sensor_rt + \" gal: \" + msg.payload.tanks[0].sensor_gallons});\nmsg.payload = msg.payload.tanks[0].sensor_gallons;\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":630,"y":640,"wires":[[]]}]

@Insearchofth1ngs if you’re willing to make your own you should check out this youtube video:

Alternatively as a HASS integration there’s also this github code:

1 Like

Sounds like a good price. Could you post a TLDR? I’m just curious what sensor make/model and what device(s) I’d have to buy to drive it.

Worked perfectly for me. Thanks for the code.

How do you search for the “_fpb” cookie? I don’t find it anywhere…

Is it possible to get access to the sample script? And/or any other documentation they sent you?

Finding the fpb was also an issue for me which is why I posted the NodeRED code above.

Actually in the end I used your code to extract the values and it works! Thank you for that, by the way. The only thing I am not sure yet is how to take those values contained in the message and transfer them onto the Lovelace dashboard. Do you know?

You should have an entity called sensor in node-red, that’s how you can pass the value on to HA.

Just switched to the Node-Red version that @Zalaban posted. It’s much easier to scrape that _fpb

One thing to note is unless you have very simple UN/PW you’re going to need to use encodeURIComponent() to make sure you can authenticate.

@bramrodrigo89 - hopefully you got your answer, there is a node-red integration through the HACS that lets you push data as a sensor: https://github.com/zachowj/hass-node-red

@lost

Can you post your entities code by any chance? I’ve been struggling with trying to get the data to get represented in a histogram, but it only wants to show me a bar graph…

[
    {
        "id": "679fbd256c1ec156",
        "type": "inject",
        "z": "4a88c65d5156b41a",
        "name": "Website version",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "7200",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 130,
        "y": 320,
        "wires": [
            [
                "1819507890ac02e0"
            ]
        ]
    },
    {
        "id": "1819507890ac02e0",
        "type": "http request",
        "z": "4a88c65d5156b41a",
        "name": "Get Session Cookie",
        "method": "GET",
        "ret": "txt",
        "paytoqs": "ignore",
        "url": "https://app.smartoilgauge.com/login.php",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "x": 140,
        "y": 360,
        "wires": [
            [
                "4fb8a0f4e7819484"
            ]
        ]
    },
    {
        "id": "4fb8a0f4e7819484",
        "type": "function",
        "z": "4a88c65d5156b41a",
        "name": "LOGIN CONFIG HERE",
        "func": "var smartOilUser = \"[email protected]\";\nvar smartOilPassword = \"YourPassword\";\nvar cookies = msg.responseCookies;\nvar cff_nonce = msg.payload.match(\"(?<=name='ccf_nonce' value=')(?:[^']|'')*(?=')\");\nmsg.headers = {\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Cookie\" : \"PHPSESSID=\" + cookies.PHPSESSID.value,\n        \"User-Agent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36\"\n};\n\nmsg.payload =  \"username=\" + smartOilUser + \"&user_pass=\" + smartOilPassword + \"&ccf_nonce=\"+cff_nonce[0];\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 140,
        "y": 400,
        "wires": [
            [
                "e1b71817c7ef2a23"
            ]
        ]
    },
    {
        "id": "e1b71817c7ef2a23",
        "type": "http request",
        "z": "4a88c65d5156b41a",
        "name": "Login to the smartoil website",
        "method": "POST",
        "ret": "txt",
        "paytoqs": "ignore",
        "url": "https://app.smartoilgauge.com/app.php",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "x": 160,
        "y": 440,
        "wires": [
            [
                "1c8ac8aee89e36fa"
            ]
        ]
    },
    {
        "id": "a7124ae6be1f3c0c",
        "type": "http request",
        "z": "4a88c65d5156b41a",
        "name": "Scrape website for info",
        "method": "POST",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "https://app.smartoilgauge.com/ajax/main_ajax.php",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "x": 150,
        "y": 520,
        "wires": [
            [
                "48570d654a9c6c55"
            ]
        ]
    },
    {
        "id": "1c8ac8aee89e36fa",
        "type": "function",
        "z": "4a88c65d5156b41a",
        "name": "Prepare query",
        "func": "var cookies = msg.responseCookies\nmsg.headers = {\n\"X-Requested-With\": \"XMLHttpRequest\",\n\"Content-Type\": \"application/x-www-form-urlencoded\",\n\"User-Agent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36\",\n\"Cookie\" : \"PHPSESSID=\" + cookies.PHPSESSID.value\n};\nmsg.payload =  {\n  \"action\": \"get_tanks_list\",\n  \"tank_id\": \"0\"\n};\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 120,
        "y": 480,
        "wires": [
            [
                "a7124ae6be1f3c0c"
            ]
        ]
    },
    {
        "id": "48570d654a9c6c55",
        "type": "function",
        "z": "4a88c65d5156b41a",
        "name": "Extract required data here",
        "func": "node.status({text:msg.payload.tanks[0].sensor_rt + \" gal: \" + msg.payload.tanks[0].sensor_gallons});\nmsg.payload = Number(msg.payload.tanks[0].sensor_gallons);\nreturn msg;\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 150,
        "y": 560,
        "wires": [
            [
                "13b148a7503d5fc7"
            ]
        ]
    },
    {
        "id": "13b148a7503d5fc7",
        "type": "ha-entity",
        "z": "4a88c65d5156b41a",
        "name": "GasLevel",
        "server": "e0ae21e440ba5f41",
        "version": 2,
        "debugenabled": false,
        "outputs": 1,
        "entityType": "sensor",
        "config": [
            {
                "property": "name",
                "value": ""
            },
            {
                "property": "device_class",
                "value": "gas"
            },
            {
                "property": "icon",
                "value": ""
            },
            {
                "property": "unit_of_measurement",
                "value": ""
            },
            {
                "property": "state_class",
                "value": ""
            },
            {
                "property": "last_reset",
                "value": ""
            }
        ],
        "state": "payload",
        "stateType": "msg",
        "attributes": [],
        "resend": true,
        "outputLocation": "payload",
        "outputLocationType": "none",
        "inputOverride": "allow",
        "outputOnStateChange": false,
        "outputPayload": "",
        "outputPayloadType": "str",
        "x": 400,
        "y": 560,
        "wires": [
            []
        ]
    },
    {
        "id": "e0ae21e440ba5f41",
        "type": "server",
        "name": "Home Assistant",
        "version": 2,
        "addon": false,
        "rejectUnauthorizedCerts": true,
        "ha_boolean": "y|yes|true|on|home|open",
        "connectionDelay": true,
        "cacheJson": true,
        "heartbeat": false,
        "heartbeatInterval": "30"
    }
]

@Zalaban I was actually running into the same issue. Your post inspired me:

I did a little digging and came across this. With that in mind, I updated the entity. I have to wait an hour or two to see if it fixes it, but :crossed_fingers: that this will do the trick.

1 Like

@lost :partying_face: thanks :slight_smile:

Many thanks to @Zalaban and @lost for posting the above node-RED solution. I’ve successfully managed to get my Smart Oil Gauge reading to my Home Assistant Dashboard!

I’ve been struggling though to then pass the info on to Homebridge in a way that Homebridge/Homekit can best represent it. I’m using the node-red-contrib-homekit-bridged node-RED Palette. Have either of you done anything similar or have any guesses as to a solution? I’m stumped! By default the Entity in your flow above is shown as an Air Quality sensor, which shows the tank reading as the Air Particulate Density value. However, this value is only available after tapping into the Air Quality sensor to see the details; it’s not visible from the parent screen, which only shows the Air Quality status in the tile. If you have any insight, please let me know. Thanks again for all the work you’ve done and shared in this thread!

Hi, I went and installed the palette to see what the options would be.

So far, the only one I could see working for you would be if you would use the temperature sensor in order the send the level as a percentage in between 0 and 100.

I haven’t been able to find any other services that would report the tank level which would be supported by Homekit.

If you do find a working solution, share it back here so we can use it as well :slight_smile:

Arrived here looking for the sensor code to turn ‘oil level’ into ‘rate of oil use’ for the energy dashboard.

Meanwhile here’s my variation on a DIY ESPhome oil tank sensor for an (indoor and powered) oil tank sensor. It has helped me order the correct amount of oil over a few years without maintenance. Now with the price of oil I’m interested in energy metrics.

https://www.rogerfrost.com/oil-tank-level-sensor-also-water-softener-salt-level/

project: oil tank level sensor oil tank level sensor - Roger Frost's home automation projects

2 Likes