- "def sip_query_latest(sensor_id: str) -> Dict[str, Any]:\n \"\"\"\n GET_LATEST: Retrieve most recent sensor reading\n Fast query (<10ms) for dashboards/real-time monitoring\n \"\"\"\n if not pancake_ready or not sips_loaded:\n return None\n \n try:\n conn = psycopg2.connect(PANCAKE_DB)\n cur = conn.cursor()\n \n start_time = time.time()\n \n cur.execute(\"\"\"\n SELECT time, value, unit\n FROM sips\n WHERE sensor_id = %s\n ORDER BY time DESC\n LIMIT 1\n \"\"\", (sensor_id,))\n \n result = cur.fetchone()\n cur.close()\n conn.close()\n \n elapsed_ms = (time.time() - start_time) * 1000\n \n if result:\n return {\n \"sensor_id\": sensor_id,\n \"time\": result[0].isoformat(),\n \"value\": result[1],\n \"unit\": result[2],\n \"query_time_ms\": elapsed_ms\n }\n return None\n except Exception as e:\n print(f\"\u26a0\ufe0f SIP query error: {e}\")\n return None\n\ndef sip_query_stats(sensor_id: str, hours_back: int = 24) -> Dict[str, Any]:\n \"\"\"\n GET_STATS: Aggregate statistics for time range\n Efficient for summaries/alerts\n \"\"\"\n if not pancake_ready or not sips_loaded:\n return None\n \n try:\n conn = psycopg2.connect(PANCAKE_DB)\n cur = conn.cursor()\n \n start_time = time.time()\n \n cur.execute(\"\"\"\n SELECT \n COUNT(*) as count,\n AVG(value) as mean,\n MIN(value) as min,\n MAX(value) as max,\n STDDEV(value) as std\n FROM sips\n WHERE sensor_id = %s\n AND time >= NOW() - INTERVAL '%s hours'\n \"\"\", (sensor_id, hours_back))\n \n result = cur.fetchone()\n cur.close()\n conn.close()\n \n elapsed_ms = (time.time() - start_time) * 1000\n \n if result and result[0] > 0:\n return {\n \"sensor_id\": sensor_id,\n \"time_range_hours\": hours_back,\n \"count\": result[0],\n \"mean\": float(result[1]) if result[1] else None,\n \"min\": float(result[2]) if result[2] else None,\n \"max\": float(result[3]) if result[3] else None,\n \"std\": float(result[4]) if result[4] else None,\n \"query_time_ms\": elapsed_ms\n }\n return None\n except Exception as e:\n print(f\"\u26a0\ufe0f SIP stats query error: {e}\")\n return None\n\n# Demo: SIP Queries\nprint(\"\ud83d\ude80 SIP Query Demonstrations:\\n\")\n\n# 1. GET_LATEST (real-time dashboard use case)\nprint(\"1\ufe0f\u20e3 GET_LATEST (Real-time Dashboard)\")\nprint(\" Use case: 'What is the current soil moisture?'\\n\")\n\ntest_sensor = \"SOIL_MOISTURE-01\"\nlatest = sip_query_latest(test_sensor)\n\nif latest:\n print(f\" Sensor: {latest['sensor_id']}\")\n print(f\" Value: {latest['value']:.2f} {latest['unit']}\")\n print(f\" Time: {latest['time']}\")\n print(f\" \u26a1 Query latency: {latest['query_time_ms']:.2f} ms (<10ms target!)\\n\")\nelse:\n print(\" \u26a0\ufe0f No data available\\n\")\n\n# 2. GET_STATS (summary/alert use case)\nprint(\"2\ufe0f\u20e3 GET_STATS (Last 24 Hours)\")\nprint(\" Use case: 'Has soil moisture dropped below threshold?'\\n\")\n\nstats = sip_query_stats(test_sensor, hours_back=24)\n\nif stats:\n print(f\" Sensor: {stats['sensor_id']}\")\n print(f\" Readings: {stats['count']}\")\n print(f\" Mean: {stats['mean']:.2f}\")\n print(f\" Range: {stats['min'] if stats['min'] is not None else 'N/A'} - {stats['max'] if stats['max'] is not None else 'N/A'}\")\n print(f\" Std Dev: {stats['std']:.2f if stats['std'] is not None else 'N/A'}\")\n print(f\" \u26a1 Query latency: {stats['query_time_ms']:.2f} ms\\n\")\n \n # Alert logic example\n if stats['min'] is not None and stats['min'] < 15.0:\n print(\" \ud83d\udea8 ALERT: Soil moisture dropped below 15% (irrigation needed!)\")\n else:\n print(\" \u2713 Status: Soil moisture within normal range\")\nelse:\n print(\" \u26a0\ufe0f No data available\\n\")\n\nprint(\"\\n\" + \"=\"*70)\nprint(\"\ud83d\udca1 SIP vs BITE Comparison:\")\nprint(\"=\"*70)\nprint(\"SIP Queries (time-series):\")\nprint(\" \u2713 Latency: <10ms (indexed, no embedding)\")\nprint(\" \u2713 Use case: Real-time dashboards, alerts, current values\")\nprint(\" \u2713 Storage: Lightweight (60 bytes/reading)\")\nprint(\"\\nBITE Queries (intelligence):\")\nprint(\" \u2713 Latency: 50-100ms (semantic search, multi-pronged)\")\nprint(\" \u2713 Use case: 'Why?' questions, historical context, recommendations\")\nprint(\" \u2713 Storage: Rich (500 bytes, with embeddings)\")\nprint(\"\\n\ud83e\udd5e PANCAKE uses BOTH (dual-agent architecture)!\")\nprint(\"=\"*70)\n"
0 commit comments