Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions app/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from fastapi import FastAPI
from app.models.signal_matrix import SignalMatrix
from app.models.scored_event import ScoredEvent
from datetime import datetime

app = FastAPI(title="Uwatu Intelligence Layer")

@app.get("/health")
async def health_check():
return {"status": "ok", "service": "uwatu-intelligence"}

@app.post("/score", response_model=ScoredEvent)
async def score_event(matrix: SignalMatrix):
return ScoredEvent(
request_id=matrix.request_id,
event_type="NORMAL_VARIATION",
confidence=0.99,
signals_fired=[],
suppressed=False,
suppression_reason=None,
alert_channels=[],
message_template="none",
gemini_narrative=None,
scored_at=datetime.utcnow().isoformat() + "Z",
model_version="1.0.0-draft"
)


25 changes: 25 additions & 0 deletions app/models/scored_event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from pydantic import BaseModel
from typing import List, Optional

class ScoredEvent(BaseModel):
request_id: str

event_type: str

confidence: float

signals_fired: List[str]

suppressed: bool

suppression_reason: Optional[str]

alert_channels: List[str]

message_template: str

gemini_narrative:Optional[str]

scored_at: str

model_version: str
79 changes: 79 additions & 0 deletions app/models/signal_matrix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
from pydantic import BaseModel
from typing import List, Optional

class Telemetry(BaseModel):
accel_mag : int
rssi_dbm : int
rat: int
cell_id: int
lac : int
bat_mv: int
body_temp_c: float
flags: int


class DeviceLocation(BaseModel):
lat: float
lon:float
uncertainty_m: int
fetched_at: str

class DeviceStatus(BaseModel):
reachability: str
last_seen_at: str

class SimSwap(BaseModel):
swapped: bool
last_swap_at: Optional[str]

class Connectivity(BaseModel):
rsrp_dbm: int
throughput_kbps: int
latency_ms: int
connection_type : str

class Roaming(BaseModel):
is_roaming: bool
visited_plmn: Optional[str]

class Congestion(BaseModel):
cell_load_pct:int
affected_cells: List[str]
estimated_duration_s: int

class NokiaSignals(BaseModel):
device_location: Optional[DeviceLocation]
device_status:Optional[DeviceStatus]
sim_swap:Optional[SimSwap]
connectivity:Optional[Connectivity]
roaming:Optional[Roaming]
congestion:Optional[Congestion]
qod_active:bool
slicing_active:bool

class Baseline(BaseModel):
avg_accel_mag: float
std_accel_mag:float
daily_range_m:float
avg_temp_c:float
avg_rssi_dbm:float
typical_cell_ids:List[int]
hourly_activity:List[float]

class Context(BaseModel):
hour_utc:int
is_dry_season:bool
market_day:bool
minutes_since_geofence_departure: Optional[int]

class SignalMatrix(BaseModel):
request_id:str
tag_id:str
animal_id:str
farm_id:str
timestamp:str
telemetry: Telemetry
nokia_signals:NokiaSignals
baseline:Baseline
context:Context