update api configuration for panel iot and adjust ai insight
This commit is contained in:
1 parent
a2b5b10977
commit
20d04acb3e
20 files changed
+814
-177
No files matched your search
@@ -164,12 +164,21 @@ class SyncSummary:
|
||||
|
||||
|
||||
class IotApiClient:
|
||||
def __init__(self, base_url: str | None = None, timeout: float | None = None):
|
||||
self.base_url = (base_url or settings.IOT_API_BASE_URL).rstrip("/") + "/"
|
||||
def __init__(self, base_url: str, timeout: float | None = None):
|
||||
self.base_url = (base_url or "").strip()
|
||||
if not self.base_url:
|
||||
raise IotApiError("IoT API URL is empty")
|
||||
self.timeout = timeout or settings.IOT_API_SYNC_TIMEOUT_SECONDS
|
||||
|
||||
def fetch_page(self, page: int) -> dict[str, Any]:
|
||||
url = f"{self.base_url}?page={page}"
|
||||
from urllib.parse import parse_qsl, urlencode, urlsplit, urlunsplit
|
||||
|
||||
parts = urlsplit(self.base_url)
|
||||
query = dict(parse_qsl(parts.query, keep_blank_values=True))
|
||||
query["page"] = str(page)
|
||||
url = urlunsplit(
|
||||
(parts.scheme, parts.netloc, parts.path, urlencode(query), parts.fragment)
|
||||
)
|
||||
try:
|
||||
with httpx.Client(timeout=self.timeout) as client:
|
||||
response = client.get(url)
|
||||
@@ -183,32 +192,19 @@ class IotApiClient:
|
||||
return response.json()
|
||||
|
||||
|
||||
def sync_iot_panels(
|
||||
def _sync_flock_pages(
|
||||
flock: Flock,
|
||||
*,
|
||||
lookback_minutes: int | None = None,
|
||||
max_pages: int | None = None,
|
||||
lookback_minutes: int,
|
||||
max_pages: int,
|
||||
cutoff,
|
||||
) -> SyncSummary:
|
||||
flock_map: dict[str, int] = getattr(settings, "IOT_FLOCK_ID_MAP", {}) or {}
|
||||
if not flock_map:
|
||||
return SyncSummary(upserted=0, skipped=0, pages=0)
|
||||
|
||||
lookback = lookback_minutes if lookback_minutes is not None else settings.IOT_SYNC_LOOKBACK_MINUTES
|
||||
page_limit = max_pages if max_pages is not None else settings.IOT_SYNC_MAX_PAGES
|
||||
cutoff = timezone.now() - timedelta(minutes=lookback)
|
||||
|
||||
django_flocks: dict[str, Flock] = {}
|
||||
for external_id, django_id in flock_map.items():
|
||||
try:
|
||||
django_flocks[str(external_id)] = Flock.objects.select_related("kandang").get(pk=int(django_id))
|
||||
except Flock.DoesNotExist:
|
||||
continue
|
||||
|
||||
client = IotApiClient()
|
||||
client = IotApiClient(flock.iot_api_url)
|
||||
upserted = 0
|
||||
skipped = 0
|
||||
pages_read = 0
|
||||
|
||||
for page in range(1, page_limit + 1):
|
||||
for page in range(1, max_pages + 1):
|
||||
payload = client.fetch_page(page)
|
||||
pages_read += 1
|
||||
results = payload.get("results") or []
|
||||
@@ -217,12 +213,6 @@ def sync_iot_panels(
|
||||
|
||||
page_has_recent = False
|
||||
for record in results:
|
||||
external_flock_id = str(record.get("flock_id") or "")
|
||||
flock = django_flocks.get(external_flock_id)
|
||||
if flock is None:
|
||||
skipped += 1
|
||||
continue
|
||||
|
||||
fetched_raw = record.get("fetched_at")
|
||||
payload_data = (record.get("payload") or {}).get("data")
|
||||
if not fetched_raw or not payload_data:
|
||||
@@ -262,3 +252,40 @@ def sync_iot_panels(
|
||||
break
|
||||
|
||||
return SyncSummary(upserted=upserted, skipped=skipped, pages=pages_read)
|
||||
|
||||
|
||||
def sync_iot_panels(
|
||||
*,
|
||||
flock_id: int | None = None,
|
||||
lookback_minutes: int | None = None,
|
||||
max_pages: int | None = None,
|
||||
) -> SyncSummary:
|
||||
lookback = lookback_minutes if lookback_minutes is not None else settings.IOT_SYNC_LOOKBACK_MINUTES
|
||||
page_limit = max_pages if max_pages is not None else settings.IOT_SYNC_MAX_PAGES
|
||||
cutoff = timezone.now() - timedelta(minutes=lookback)
|
||||
|
||||
flocks = Flock.objects.select_related("kandang").exclude(iot_api_url="")
|
||||
if flock_id is not None:
|
||||
flocks = flocks.filter(pk=flock_id)
|
||||
|
||||
flock_list = list(flocks)
|
||||
if not flock_list:
|
||||
return SyncSummary(upserted=0, skipped=0, pages=0)
|
||||
|
||||
upserted = 0
|
||||
skipped = 0
|
||||
pages_read = 0
|
||||
for flock in flock_list:
|
||||
if not (flock.iot_api_url or "").strip():
|
||||
continue
|
||||
summary = _sync_flock_pages(
|
||||
flock,
|
||||
lookback_minutes=lookback,
|
||||
max_pages=page_limit,
|
||||
cutoff=cutoff,
|
||||
)
|
||||
upserted += summary.upserted
|
||||
skipped += summary.skipped
|
||||
pages_read += summary.pages
|
||||
|
||||
return SyncSummary(upserted=upserted, skipped=skipped, pages=pages_read)
|
||||
Reference in new issue
Block a user