first commit
This commit is contained in:
commit
b54624be96
226 files changed
+108840
No files matched your search
@@ -0,0 +1,111 @@
|
||||
"""Fast sample scan of IoT flocks API — day/date mapping without full pagination."""
|
||||
import json
|
||||
import urllib.request
|
||||
from collections import defaultdict
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
BASE = "https://dashboard.cpsp.id/api/iot/flocks/"
|
||||
CYCLE_START = datetime(2026, 5, 22).date()
|
||||
TZ = timezone(timedelta(hours=7))
|
||||
|
||||
|
||||
def parse_dt(value: str) -> datetime:
|
||||
return datetime.fromisoformat(value.replace("Z", "+00:00"))
|
||||
|
||||
|
||||
def fetch_page(page: int) -> dict:
|
||||
with urllib.request.urlopen(f"{BASE}?page={page}", timeout=60) as resp:
|
||||
return json.loads(resp.read())
|
||||
|
||||
|
||||
def summarize_records(records: list) -> None:
|
||||
by_day: dict[int, list] = defaultdict(list)
|
||||
for r in records:
|
||||
day = r["payload"]["data"].get("day")
|
||||
if day is not None:
|
||||
by_day[day].append(r)
|
||||
|
||||
print(f" unique days: {len(by_day)} range {min(by_day)}..{max(by_day)}")
|
||||
for day in sorted(by_day)[:3]:
|
||||
r = max(by_day[day], key=lambda x: parse_dt(x["fetched_at"]))
|
||||
d = r["payload"]["data"]
|
||||
cal = CYCLE_START + timedelta(days=day - 1)
|
||||
print(
|
||||
f" day {day} -> {cal} | wind={d.get('wind')} hum={d.get('humidity')} "
|
||||
f"temp={d.get('actualTemperature')} water={d.get('water')} HSI={d.get('HSI')}"
|
||||
)
|
||||
if len(by_day) > 6:
|
||||
print(" ...")
|
||||
for day in sorted(by_day)[-3:]:
|
||||
r = max(by_day[day], key=lambda x: parse_dt(x["fetched_at"]))
|
||||
d = r["payload"]["data"]
|
||||
cal = CYCLE_START + timedelta(days=day - 1)
|
||||
print(
|
||||
f" day {day} -> {cal} | wind={d.get('wind')} hum={d.get('humidity')} "
|
||||
f"temp={d.get('actualTemperature')} water={d.get('water')} HSI={d.get('HSI')}"
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
p1 = fetch_page(1)
|
||||
total = p1["count"]
|
||||
page_size = len(p1["results"])
|
||||
last_page = (total + page_size - 1) // page_size
|
||||
print(f"API total={total} page_size={page_size} pages={last_page}")
|
||||
|
||||
r0 = p1["results"][0]
|
||||
d0 = r0["payload"]["data"]
|
||||
coop = d0.get("coop") or {}
|
||||
print(f"flock_id={r0['flock_id']} floor={d0.get('name')} site={coop.get('kode')}")
|
||||
print(f"kandang field (Mongo id)={d0.get('kandang')}")
|
||||
|
||||
# Sample: first pages (newest), last pages (oldest), and mid pages
|
||||
sample_pages = sorted({1, 2, 3, 10, 50, 100, 200, 400, 600, last_page, last_page - 1, last_page - 2})
|
||||
all_records = []
|
||||
for page in sample_pages:
|
||||
if page < 1 or page > last_page:
|
||||
continue
|
||||
data = fetch_page(page)
|
||||
all_records.extend(data["results"])
|
||||
days = {r["payload"]["data"].get("day") for r in data["results"]}
|
||||
fdates = {parse_dt(r["fetched_at"]).astimezone(TZ).date() for r in data["results"]}
|
||||
print(f"page {page:4d}: days={min(days)}..{max(days)} fetched_dates={min(fdates)}..{max(fdates)}")
|
||||
|
||||
# Roll up sampled data: latest fetched_at per cycle day
|
||||
daily: dict[int, dict] = {}
|
||||
for r in all_records:
|
||||
day = r["payload"]["data"].get("day")
|
||||
if day is None:
|
||||
continue
|
||||
ts = parse_dt(r["fetched_at"])
|
||||
if day not in daily or ts > daily[day]["ts"]:
|
||||
daily[day] = {"ts": ts, "r": r}
|
||||
|
||||
print(f"\nFrom sample: {len(daily)} unique cycle days seen")
|
||||
missing = [d for d in range(1, 50) if d not in daily]
|
||||
print(f"Missing in sample (1..49): {missing}")
|
||||
|
||||
print("\nField mapping -> iot_panel (exclude experience_temperature):")
|
||||
print(" date = cycle_start + (day - 1) # 2026-05-22 + day-1")
|
||||
print(" wind_speed = payload.data.wind")
|
||||
print(" humidity = payload.data.humidity # likely /10 for %")
|
||||
print(" water_total = payload.data.water")
|
||||
print(" average_temperature = payload.data.actualTemperature # likely /10 for °C")
|
||||
print(" experience_temperature = formula (HSI? TBD)")
|
||||
|
||||
print("\nSample rollup table:")
|
||||
print(f"{'day':>3} {'date':>10} {'wind':>5} {'hum':>6} {'temp_raw':>8} {'water':>6} {'HSI':>7}")
|
||||
for day in range(1, 50):
|
||||
cal = CYCLE_START + timedelta(days=day - 1)
|
||||
entry = daily.get(day)
|
||||
if not entry:
|
||||
continue
|
||||
d = entry["r"]["payload"]["data"]
|
||||
print(
|
||||
f"{day:3d} {cal} {d.get('wind', 0):5} {d.get('humidity', 0):6} "
|
||||
f"{d.get('actualTemperature', 0):8} {d.get('water', 0):6} {d.get('HSI', 0):7.2f}"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user