Local Deployment for SureFlap / SurePetCare Connect using only local MQTT Broker

so the kitchen battery in this image…thats the combined voltage of the 4 batteries right? How do surepet then convert it to a %. Something like voltage / 6 * 100 = % ?

That must be done client side in JavaScript as the raw voltage level is sent via the start call.
It seems the battery percentage is quite iffy in the app as I had my stack connected to it and the feeder battery was listed as completely empty but it is still going fine, however the pet door got very bent out of shape once the voltage dropped below a certain value.
I’ll have a dig through the JavaScript when time permits but the calculation and which icon to display is 100% client side.

1 Like

ok. Well I see the home assistant built-in integration does it similar.

    @property
    def state(self) -> int | None:
        """Return battery level in percent."""
        battery_percent: int | None
        try:
            per_battery_voltage = self._state["battery"] / 4
            voltage_diff = per_battery_voltage - SURE_BATT_VOLTAGE_LOW
            battery_percent = min(int(voltage_diff / SURE_BATT_VOLTAGE_DIFF * 100), 100)
        except (KeyError, TypeError):
            battery_percent = None

        return battery_percent

source

and from consts:

# flap
BATTERY_ICON = "mdi:battery"
SURE_BATT_VOLTAGE_FULL = 1.6  # voltage
SURE_BATT_VOLTAGE_LOW = 1.25  # voltage
SURE_BATT_VOLTAGE_DIFF = SURE_BATT_VOLTAGE_FULL - SURE_BATT_VOLTAGE_LOW

source

Yeah it is in the JS:

            function b(e, t) {
                if (1 & e && (o.Tb(0, "span", 2), o.Hc(1, r, 1, 0, "i", 3), o.Hc(2, a, 1, 0, "i", 4), o.Hc(3, s, 1, 0, "i", 5), o.Hc(4, u, 1, 0, "i", 6), o.Hc(5, l, 1, 0, "i", 7), o.Sb()), 2 & e) {
                    var n = o.fc(2);
                    o.Ab(1), o.nc("ngIf", n.voltage <= 4.8), o.Ab(1), o.nc("ngIf", n.voltage > 4.8 && n.voltage <= 5.1), o.Ab(1), o.nc("ngIf", n.voltage > 5.1 && n.voltage <= 5.4), o.Ab(1), o.nc("ngIf", n.voltage > 5.4 && n.voltage <= 5.6), o.Ab(1), o.nc("ngIf", n.voltage > 5.6)
                }
            }

1 Like

I have no idea what this javascript does. Like where is o defined.

The app is what is called a “Single Page App” probably built in nodejs so when the site loads it loads a stack of javascript into the browser. The specific JS that has the code is “18.131d50a85dc517c031ab.js” for me, but that could change every time the page gets rebuilt.
It was then packed but you can use many online unpackers to get more readable JS. The important bit is:

"ngIf", n.voltage <= 4.8), o.Ab(1), o.nc("ngIf", n.voltage > 4.8 && n.voltage <= 5.1), o.Ab(1), o.nc("ngIf", n.voltage > 5.1 && n.voltage <= 5.4), o.Ab(1), o.nc("ngIf", n.voltage > 5.4 && n.voltage <= 5.6), o.Ab(1), o.nc("ngIf", n.voltage > 5.6)

or turned back into pseudocode:

if voltage <= 4.8 then empty
elif voltage > 4.8 and voltage <= 5.1 then 1 Bars
elif voltage > 5.1 and voltage <= 5.4 then 2 Bars
elif voltage > 5.4 and voltage <= 5.6 then 3 Bars
elif voltage > 5.6 then Full

Does that make sense?

2 Likes

Yes that makes it perfectly clear thank you very much!

So that means I think:

4.8v = 0% (does mean it can read lower and that you will see a -% but probably not great function from door)
5.1v = 25%
5.4v = 50%
5.6v = 75%
6.0v = 100% (4x 1.5v C batteries but should probably work out at 5.8v as 100%)

Totally something I can work with, and actually makes more sense than the python code currently used in the built-in integration.

So peter, can we not make it really simple.

(battery voltage - 4.8)*100 = battery %

so on for 5.103 it will end up with 30.3% which we can round to 0 digits to be 30%

Added support for the Felaqua earlier this morning and pushed the change. Seems that it is just a single scale value similar to the feeder so use that same table instead of creating a new one. Haven’t fully tested the code as I moved most data objects over to Box rather than using Dict so I would deploy into a new folder or backup the docker/source just in case I have broken something.

1 Like

So I recommend everyone turns on Firmware support in the web.py so that you have a local copy of the hub firmware. It might come in handy soon.

Set it to True rather than false, bounce the docker stack and then your hub and then it should download the current firmware for your hub.

Can we update it so that it can be set via the config file?

Just been working on something, just pushed this file: pethublocal/fwlogtopw.py at 9cf1183d6fddf31a2ea8a44ceb0171dfc44e4edf · plambrechtsen/pethublocal · GitHub

1 Like

Hi Peter
Thought I would finally ask for help. I am VERY new to all this and still finding my way around Linux. Anyway after lots of trial and error in an Ubuntu VM I have my catflap and hub connected but still have some issues. You will see from the screen shot I get several Non matched message errors come up and if I try to lock the flap from HA pethub crashes out with the error on the second screen shot. The database seems to be created despite mkpetlocaldb.py being unable to close the session at the end and I downgraded surepy to the previous version as suggested earlier…

So, any idea where I have gone wrong trying to implement your great work?


The non-matched messages are fine for the most part, it’s just I had a catch all and those messages are the pethub setting the persistent value. The crash indicates that the table weren’t properly populated and it is doing a select and not finding the mac address in the doors table.
There were a few bugs that were fixed in the last week with the cat flap in the doors table.
If you use sqlite to view the doors and devices table.
I would try doing a git pull, rebuilding the database and see if the problem still persists.
Or perhaps it was my latest update where I may have broken a few things as I don’t have a cat flap only pet door so I can’t test that as easily.
Should have some more complete cat flap messages now that someone else on here has their credentials certificate password so they can man in the middle all traffic.

I already pulled the updates and recreated the database last night, I think you are right it’s not properly populated. I will try again tonight.

I’d be happy to help if you want me to capture traffic, just tell me what you need and I will do what I can. I only have the hub and catflap with two cats so it should be pretty targeted data if that helps

Ok, so investigated a bit more last night. The database looks fine to me but I wonder if its not getting the mac address data from MQTT. Are these MQTT topics correct? Should the second device end with _flap or something similar

I’ve also removed the comments in pethubmqtt.py to test the catflap so let me know if you need any data from that… for some reason it started crashing after that! To be honest it was probably something I did so I will do a reroll from scratch over the next few days and see if that helps.

Some more catflap investigation…

I let the hub connect back to surepet, fiddled with app some options to see the results by rebuilding the database after each change. Locking mode changes if I lock the pets in or out as expected. However curefew mode and times never change, I always have “curefenabled=0”, “lock_time=” and "lock_time= "

I assume this isn’t being parsed correctly by the script… let me know if you have any ideas of what I can change and test to help find out whats going on.

Sorry I have been incredibly busy this week and I am going to have a crack through it over the weekend. If you want to email me offline your start.json I can see what I am missing. I suspect I have made assumptions on certain values existing and we all know what happens with assumptions.

Hi Peter, no problem. I do appreciate your efforts. I’ve emailed you so please let me know if you haven’t got it.

1 Like