FindMySync icon indicating copy to clipboard operation
FindMySync copied to clipboard

Have battery status of devices passed through to Home Assistant

Open deepcoder opened this issue 1 year ago • 11 comments

I see a JSON pair "batteryStatus" : {0,1,2...?} in the Items.data file for devices, however this info does not seem to be passed to Home Assistant. Is there a way to pass this data?

Thanks!

deepcoder avatar Oct 01 '24 20:10 deepcoder

It is passed to home assistant, this is using a deprecated API, but you should see a "battery" attribute on the entity.

ext4xfs avatar Jan 08 '25 22:01 ext4xfs

@ext4xfs I don't see it, could you provide more details about the API it is supposedly using?

miguelangel-nubla avatar Mar 14 '25 12:03 miguelangel-nubla

get battery level https://github.com/MartinPham/FindMySync/blob/842bb6454b2796b4ccc332ffe3742eeabf9cbd70/FindMySync/Synchronizer.swift#L640-L654

entities to update https://github.com/MartinPham/FindMySync/blob/842bb6454b2796b4ccc332ffe3742eeabf9cbd70/FindMySync/Synchronizer.swift#L656-L665

request body sent to home assistant https://github.com/MartinPham/FindMySync/blob/842bb6454b2796b4ccc332ffe3742eeabf9cbd70/FindMySync/Synchronizer.swift#L740-L756

device_tracker domain https://www.home-assistant.io/integrations/device_tracker/#device_trackersee-action

rest api /api/services/<domain>/<service> https://developers.home-assistant.io/docs/api/rest/#actions

ext4xfs avatar Mar 14 '25 17:03 ext4xfs

Thank you for the detailed response.

I think we are talking about different things, the code is reading batteryLevel which I only see on Devices.data for the full devices (iphone, etc).

This issue is about getting the battery status of airtags and similar devices in Items.data, which seem to only have a batteryStatus attribute.

On my devices batteryStatus=1 corresponds to a full battery, batteryStatus=2 next to full. I don't know if that attribute is supposed to represent battery level but it is certainly not parsed or sent to home assistant right now.

miguelangel-nubla avatar Mar 16 '25 02:03 miguelangel-nubla

ah I see what you mean, yeah it's there for devices but not items.

ext4xfs avatar Mar 16 '25 02:03 ext4xfs

@MartinPham any chance to include battery status for items?

miguelangel-nubla avatar Mar 16 '25 14:03 miguelangel-nubla

yeah need battery status for items its quite important so we know the status of the items battery so even if dont have iphone near us we know battery conditions @MartinPham

jasgroupit avatar Mar 19 '25 12:03 jasgroupit

I don't think it's useful information, batteryStatus 1 or 2 doesn't tell you much for airtags at least, since they use a coin battery without any fancy circuitry.

ext4xfs avatar Mar 21 '25 03:03 ext4xfs

At the very least using battery status 1 or 2 we can tell if the battery is in ok or degraded stage so we can monitor , if u can add that or enable that would great so i can scene in homeassistant to cross check if 24 hour

jasgroupit avatar Mar 21 '25 05:03 jasgroupit

@MartinPham @ext4xfs the status for items possible ?

jasgroupit avatar Mar 27 '25 03:03 jasgroupit

FWIW, my fork FindMySyncPlus supports this capability. But it was mainly written to support new macOS's versions which have the data files encrypted. My function can be ported to this project if desired:

private func batteryFromStatus(_ any: Any?) -> Double? {
    // Accept a few common shapes for Items:
    // - String statuses like "full", "normal", "medium", "low", "verylow", "critical"
    // - Numeric percentages (0-100)
    // - Fractions (0.0-1.0)
    if let d = any as? Double {
        if d.isNaN || d.isInfinite { return nil }
        return d > 1.0 ? max(0.0, min(1.0, d / 100.0)) : max(0.0, min(1.0, d))
    }
    if let i = any as? Int {
        return max(0.0, min(1.0, Double(i) / 100.0))
    }
    if let s = (any as? String)?.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() {
        switch s {
        case "full", "max", "high":
            return 1.0
        case "normal", "good":
            return 0.75
        case "medium", "fair":
            return 0.5
        case "low":
            return 0.25
        case "verylow", "critical", "very low":
            return 0.1
        default:
            // Try to parse numeric-in-string (either percent or fraction)
            if let asNum = Double(s) {
                return asNum > 1.0 ? max(0.0, min(1.0, asNum / 100.0)) : max(0.0, min(1.0, asNum))
            }
            return nil
        }
    }
    return nil
}

manonstreet avatar Nov 11 '25 16:11 manonstreet