It's not easy to do exactly.
To get a rough answer, you can do a
subquery: (foo == 1)[24h:1m] will resample the timeseries at 1 minute intervals, then you can wrap that with count_over_time, giving:
count_over_time((foo == 1)[24h:1m])
But if you weren't scraping at exactly 1 minute intervals, the count may not be accurate. Also if there are missed samples, the value of foo at time T will look back for the previous value (up to 5 minutes by default), which means in that situation some samples may be double-counted (in effect, assuming the metric value remained constant over that time, when you don't actually know what value it had).
The only way I know to get an exact answer is to send the range vector query "foo[24h]" to the
*instant* query endpoint, then filter and count the samples client-side. A range vector like that gives the raw values with their raw timestamps as stored in the TSDB.
For this use case it would be nice if Prometheus were to allow certain operators to work directly on range vectors, so you could write
foo[24h] == 1
But that would add quite a lot of complexity into the semantics of the query language, which already has to consider argument combinations for (scalar, scalar), (scalar, instant vector) and (instant vector, instant vector).