iOS won't tell me a BLE device's MAC, so I started reading it out of the vendors' own payloads. What else leaks like this?

CoreBluetooth will not give you a peripheral's Bluetooth address. You get a UUID that the system assigns the first time it encounters the peer, and Apple documents it exactly that way, so on iOS every address-level trick is off the table before you start.

Then I noticed that a lot of devices just hand it over themselves.

Xiaomi MiBeacon, service data UUID 0xFE95, carries a frame control word where bit 4 means "MAC included". When that bit is set, the six bytes at offset 5 are the address, stored reversed. It is right there in the xiaomi-ble parser that Home Assistant depends on, so this is not me guessing at a hex dump. SwitchBot and Govee do their own version of the same thing in their own service data.

So the reliable route to a hardware address, on a platform that deliberately hides it, runs straight through the payload the device is already shouting at everyone in range.

The part I cannot make sense of is that this forecloses address rotation completely. Whatever the link layer does with private addresses, a fixed six bytes sitting in the advertisement hands any passive scanner a permanent handle on the device. I can construct one excuse, that the vendor's app needs something stable to bind against while the address moves underneath it, but that argues for a derived per-vendor id rather than the real MAC.

I am now checking both ends of every service data blob I decode for six plausible bytes, and I am hitting more than I expected to.

Which vendors am I still missing, and has anyone found an actual protocol constraint that justifies putting it there? I would rather be corrected than write it off as sloppiness.

Disclosure so nobody has to check: the scanner is my own iOS app, BLE Scanner. The payload is the interesting part here, not the app.

reddit.com
u/BigBalli — 17 hours ago

When you backtest a player prop, does a DNP count as a loss or does it not count at all?

I have been building the split engine for a prop research app and this is the decision I went back and forth on the longest.

Player misses the game. You are computing how often he cleared 26.5 points over his last 10. Is that game a miss, or is it not one of the 10?

I settled on excluding it from both the numerator and the denominator, so a DNP shrinks the window rather than counting against him. The reasoning was that a DNP is not evidence about whether he clears the line, it is an absence of evidence, and treating it as an under quietly biases every hit rate downward for exactly the players whose availability is already in question.

The counterargument I keep running into is that if you actually placed that bet you would have been refunded rather than graded, so the honest denominator is games he played, which is where I landed. But if you are modelling expected value across a season rather than grading a single ticket, availability risk is real and stripping it out hides a cost you actually bear.

Related and messier: I also made an empty window return no value rather than zero percent. Zero of four is a claim. Zero of zero is not, and rendering both as 0% is how a research tool ends up lying to you.

The app is PropSplits if it matters, but the modelling question is the part I am stuck on and it is not app specific.

So how do you handle it in your own backtests? Drop the game, count it as a loss, or carry availability as a separate term?

reddit.com
u/BigBalli — 1 day ago

How many gallons are sitting in your water heater right now?

Mine holds 50. I'd owned the thing for six years before it occurred to me that it is also the largest single container of drinking water on the property.

FEMA lists it first among in-home emergency water sources, and most tanks are 40 gallons or more. The catch is you have to kill the power or the gas before you drain it, and let it cool, or you'll wreck the element and scald yourself doing it.

The rest of the list is smaller but adds up. The pipes themselves hold a few gallons: open the highest faucet in the house to let air in, then drain from the lowest. Ice cubes in the freezer. The toilet tank, meaning the upper part, as long as nobody has dropped one of those blue cleaner pucks in it.

What is explicitly off the list is the part I found useful, because some of it looks fine. Not radiators. Not a hot water boiler used for heating. Not waterbeds, pools, or spas. Those all carry additives or corrosion you cannot boil out, and boiling concentrates them rather than removing them.

I put all of this into an offline reference app I built called Outlast, since none of it is any use on a page you cannot load. It cites the agency behind every article: https://BigBalli.com/Outlast/

What I still cannot decide is bookkeeping. Do you count the heater toward your stored water number, or keep it as a separate reserve you only touch when the jugs are gone?

u/BigBalli — 3 days ago

[Discussion] Does anyone here actually refreeze meat after an outage, or do you just toss it?

We lost power for about two days last winter and I spent most of it worrying about a chest freezer with most of a hog in it. Everyone I called told me the same thing: once it thaws, it's gone.

That turns out not to be what USDA and FoodSafety.gov actually say. Their test is whether the food still has ice crystals in it, or is still at or below 40F. If either is true, it can be refrozen. You lose quality, because the cells rupture and it weeps when you thaw it the second time, but it is not a safety problem. The "never refreeze" rule people repeat is a texture rule that got promoted to a safety rule somewhere along the way.

The timings surprised me more. An unopened fridge holds about 4 hours. A full freezer holds about 48. A half full freezer holds about 24. Half the food, half the time, which means the empty space in my freezer was costing me a full day of margin. I've been filling the gaps with jugs of water since.

The one that stayed non negotiable: never taste anything to decide. Bacteria that will put you in hospital usually leave no smell and no change in color.

Official version is here, it's short: https://www.foodsafety.gov/food-safety-charts/food-safety-during-power-outage

I ended up building an offline first aid and disaster reference called Outlast, partly because I was standing in a dark kitchen trying to load a government page on one bar of signal. Every article in it cites which agency it came from, which is how I found the refreezing thing in the first place.

So what do you actually do? Ice crystals, a thermometer in the freezer, or straight in the bin?

reddit.com
u/BigBalli — 3 days ago

Italy publishes every fuel station's prices daily as open data, and every price carries the timestamp the operator filed it

Disclosure first, because rule 1: I used this dataset to build a free iOS app, so I am not a neutral party here. Posting it because the dataset is genuinely good and I could not find it discussed on this sub.

Italian law requires every fuel station operator to file its prices with the Ministry of Enterprise, and the Ministry republishes the whole lot daily under IODL 2.0. Around 23,955 stations and roughly 93,000 prices, split across a price file and a station registry that carries address, brand and a self service flag.

The part I find unusual is that every individual price carries the timestamp of when that operator filed it. Most national fuel feeds I have looked at hand you a number and tell you nothing about its age. Here you can actually measure it: the median price is one day old, 71.8% are under 24 hours, 93.3% under three days, and 0.6% are more than a month old. That last sliver matters more than its size suggests, because pump prices drift upward, so a station that quietly stops filing keeps an old low number and floats straight to the top of any cheapest-first sort.

One warning if you go to parse it. The file is pipe delimited and does not escape pipes, so 106 rows carry a literal pipe inside a field. There are also 2,466 unbalanced double quotes sitting in company names, which means any reader treating the quote character as an enclosure will silently merge rows and hand you no error at all. I gave up and split on raw pipes without touching quotes. Worth knowing that the values are not sanity checked either: diesel gets filed at €0.123 and at €8.888, about 74 rows a day.

Does anyone know of another country publishing fuel prices at station level with a per-station filing timestamp? I have been through the French and Spanish feeds and both are day resolution at best, which is enough to sort but not enough to tell a driver whether to trust a number.

Source: https://www.mimit.gov.it/it/open-data/elenco-dataset/carburanti-prezzi-praticati-e-anagrafica-degli-impianti

(The app is Riserva, if it matters for the disclosure. Italy only.)

reddit.com
u/BigBalli — 4 days ago

Italy publishes every fuel station's prices daily as open data, and every price carries the timestamp the operator filed it

Disclosure first, because rule 1: I used this dataset to build a free iOS app, so I am not a neutral party here. Posting it because the dataset is genuinely good and I could not find it discussed on this sub.

Italian law requires every fuel station operator to file its prices with the Ministry of Enterprise, and the Ministry republishes the whole lot daily under IODL 2.0. Around 23,955 stations and roughly 93,000 prices, split across a price file and a station registry that carries address, brand and a self service flag.

The part I find unusual is that every individual price carries the timestamp of when that operator filed it. Most national fuel feeds I have looked at hand you a number and tell you nothing about its age. Here you can actually measure it: the median price is one day old, 71.8% are under 24 hours, 93.3% under three days, and 0.6% are more than a month old. That last sliver matters more than its size suggests, because pump prices drift upward, so a station that quietly stops filing keeps an old low number and floats straight to the top of any cheapest-first sort.

One warning if you go to parse it. The file is pipe delimited and does not escape pipes, so 106 rows carry a literal pipe inside a field. There are also 2,466 unbalanced double quotes sitting in company names, which means any reader treating the quote character as an enclosure will silently merge rows and hand you no error at all. I gave up and split on raw pipes without touching quotes. Worth knowing that the values are not sanity checked either: diesel gets filed at €0.123 and at €8.888, about 74 rows a day.

Does anyone know of another country publishing fuel prices at station level with a per-station filing timestamp? I have been through the French and Spanish feeds and both are day resolution at best, which is enough to sort but not enough to tell a driver whether to trust a number.

Source: https://www.mimit.gov.it/it/open-data/elenco-dataset/carburanti-prezzi-praticati-e-anagrafica-degli-impianti

(The app is Riserva, if it matters for the disclosure. Italy only.)

reddit.com
u/BigBalli — 5 days ago
▲ 5 r/gis

When an official agency classification disagrees with your own computed geometry at a boundary, which one do you ship?

Spain's IGN published per-municipality circumstances for yesterday's solar eclipse, covering all 7,531 municipalities. I was building against that table and hit a case I still am not sure I handled correctly.

Madrid's row carries an eclipse magnitude of exactly 1.00, and no totality start time and no totality end time at all. Run a standard Besselian-elements solve on the coordinates of Puerta del Sol and the point lands inside the umbral shadow. The two sources disagree about which side of the limit the city centre sits on.

The suburbs make it sharper rather than softer. Alcobendas at 15 km, San Sebastián de los Reyes at 17 km and Tres Cantos at 21 km from the Madrid centroid all carry magnitude 1.03, and all have real totality timestamps. So the boundary genuinely runs between the city and its northern edge. This is not a data error, it is a real feature at a scale smaller than the polygons.

My reading of why they diverge: the umbral limit moves on the order of a kilometre once you account for the lunar limb profile and station elevation, and a textbook Besselian solve models neither. A municipality is also a polygon, not a point, so any single computed verdict for "Madrid" is answering a question the geometry does not really support.

The other thing that table forced on me: 6,034 of the 7,531 municipalities, just over 80 percent, never reach last contact, because the Sun sets first. The end of the eclipse is therefore not last contact but min(last contact, sunset), evaluated per municipality. With the Sun between 2 and 12 degrees above the horizon nationwide, local terrain does more to decide what is observable than the ephemeris does.

What I shipped was to treat the agency classification as authoritative, and where a query point falls close enough to the limit that the polygon cannot answer it, return "on the limit" together with the nearest municipality that is unambiguously total, instead of picking a side and sounding confident.

I am not confident that is right in general. When you hold an authoritative categorical classification and your own computation, and they disagree only in the boundary cases, do you defer to the agency completely, surface both and let the user judge, or do you go back and refine your own model until it reproduces theirs?

The app I built on this is Eclipse, https://BigBalli.com/Eclipse/, but the question is the part I actually want an answer to.

u/BigBalli — 7 days ago

Which intra-file consistency checks actually catch a re-saved JPEG, and which ones produce too many false positives to be worth running

I have been implementing tamper detection that works on a single file with no reference copy and no network, and I would like a sanity check from people who do this for a living on which of these hold up in practice.

The checks that have been earning their keep:

Timestamp disagreement. DateTimeOriginal, DateTimeDigitized and DateTime diverging is weak on its own, since plenty of pipelines rewrite one and not the others, but the pattern of which one moved is informative.

Camera clock against GPS time. GPSDateStamp and GPSTimeStamp come from the satellite fix rather than the device clock, so the offset between them and DateTimeOriginal is one of the few internal cross-references a file carries that an editor rarely thinks to update.

Recorded dimensions against decoded dimensions. EXIF PixelXDimension disagreeing with the actual decoded raster is a cheap and fairly reliable signal that something rewrote the pixels without rewriting the header.

Embedded preview against the main image. The thumbnail and preview often survive an edit that the full-size image did not. This is the one that produces the most striking results, since you can sometimes see the pre-edit frame.

Quantization table fingerprinting. Comparing the JPEG tables against the known encoder profiles for a given device tells you whether the claimed camera plausibly produced this encoding. This one I trust least. Any re-save at a matching quality setting muddies it, and the profile database is the hard part.

Separately, on provenance: I read C2PA Content Credentials, the IPTC digital source type fields, and the generator fingerprints that Midjourney, DALL-E, Stable Diffusion and Firefly leave behind. The discipline I settled on is that these are declarations only. A file carrying no marks gets reported as unproven, never as authentic. Reporting absence of evidence as evidence of absence seems like the failure mode most likely to burn someone.

Two questions for the people here. Which of these do you consider strong enough to put in a report, and which are only good for triage? And is there a check that works on a lone file with no reference that I have missed?

Context for what this is: an iPhone app that runs all of it on device with nothing uploaded. Free, no account. https://BigBalli.com/ImageInspector

u/BigBalli — 9 days ago
▲ 20 r/RacketStringers+2 crossposts

Polyester loses more tension at low tension than at high. ALU Power sheds 55% at 40 lb and 37% at 62.

Same string, same test, three reference tensions:

40 lb → 55% tension loss

51 lb → 47%

62 lb → 37%

Everyone tells low-tension poly players they'll get more comfort and more spin. Nobody mentions the bed also goes dead faster in relative terms.

I don't think this changes the advice much, but it's the sort of thing that never appears in a spec sheet  because spec sheets only ever quote one condition.

https://stringspec.com/luxilon-alu-power-125-16l/

u/BigBalli — 19 days ago
▲ 3 r/TennisNerds+1 crossposts

788 tennis strings lab-tested and plotted in one chart

There's a hole in the middle where the string you actually want would be.

Comfort on one axis, power on the other, colored by material.

Polyester and multifilament sit in two separate clouds with almost nothing between them. The soft-and-controlled quadrant is nearly empty. That's not a gap in the market, it's a gap in the physics: nobody has managed it, which is why every "poly that's easy on the arm" thread ends the same way.

Any two of the six measurements, so you can plot spin against tension hold and see the same trade-off from a different angle.

https://stringspec.com/map

reddit.com
u/BigBalli — 20 days ago

Enclosure design to 3d print

Hello everyone,

I finally completed my project using ESP32-S rounded display and now need an enclosure.

Does anyone happen to have a design they're willing to share? Ideally it has a way to stand and open usb for power, everything else sealed. Snap on (rubber) or hard plastic with screws are both ok.

Thanks!

reddit.com
u/BigBalli — 2 months ago
▲ 9 r/DIY_tech+3 crossposts

I built a BLE scanner to debug my own app, and learned the air is way more crowded than I expected

I've been building CozyCritter, which talks to some Bluetooth hardware, and I kept hitting the same wall: I couldn't actually see what my device was broadcasting. The scanner apps I tried either buried the data I wanted or asked me to pay before showing me anything useful. So I did the side-project thing and built my own.

It started as a debugging tool just for me. GATT explorer, RSSI, manufacturer data, export to CSV/JSON so I could diff things between sessions. Nothing fancy, just the stuff I wished existed while I was stuck.

The part that surprised me: I have never been anywhere with fewer than 50 devices broadcasting BLE. My apartment, a coffee shop, a train, a parking lot in the middle of nowhere. Earbuds, TVs, fitness trackers, random sensors, things I genuinely can't identify. Once you can see it, you can't unsee it. The room is always talking.

It's on the App Store as BLEScanner if you want to poke at the airwaves around you. Happy to answer anything about the BLE side, it was a fun rabbit hole.

reddit.com
u/BigBalli — 2 months ago