initial commit

This commit is contained in:
Iñigo Etxaniz
2026-07-15 10:15:42 +00:00
parent 81936f2ca5
commit 1f80394ad1
4 changed files with 184 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
# i7lib
i7 library for scripts
+88
View File
@@ -0,0 +1,88 @@
import os
import time
import math
import requests
try:
from dotenv import load_dotenv
load_dotenv()
except ImportError:
pass
SIDECAR_URL = os.getenv("SIDECAR_URL", "http://localhost:80")
class WriteBatch:
def __init__(self):
self.payload = []
def add(self, signal_id, value, name=""):
self.payload.append({
"id": int(signal_id),
"value": float(value),
"name": str(name)
})
class Plant:
def __init__(self):
self.state = {}
self.instants = {}
self.signals = []
def _parse(self, data):
self.signals = data
self.state = {}
self.instants = {}
for item in data:
val = item.get("value", math.nan)
instant = item.get("instant", 0)
self.state[item["id"]] = val
self.instants[item["id"]] = instant
if item.get("name"):
self.state[item["name"]] = val
self.instants[item["name"]] = instant
def read_all(self):
try:
res = requests.get(f"{SIDECAR_URL}/api/read/", timeout=2)
res.raise_for_status()
self._parse(res.json().get("data", []))
return self.state
except Exception as e:
print(f"Error reading state: {e}")
return {}
def read_sync(self, interval_ms, offset_ms):
try:
timeout_sec = (interval_ms / 1000.0) + 2.0
res = requests.get(f"{SIDECAR_URL}/api/read/{interval_ms}/{offset_ms}/", timeout=timeout_sec)
res.raise_for_status()
self._parse(res.json().get("data", []))
return self.state
except Exception as e:
print(f"Error reading state: {e}")
return {}
def new_write_batch(self):
return WriteBatch()
def send(self, batch):
if not batch.payload:
return
try:
res = requests.post(f"{SIDECAR_URL}/api/write/", json=batch.payload, timeout=2)
res.raise_for_status()
except Exception as e:
print(f"Error sending batch: {e}")
def run(logic_func, interval_ms=1000, offset_ms=200):
print(f"Connected to: {SIDECAR_URL} (Sync: {interval_ms}ms, Offset: {offset_ms}ms)")
plant = Plant()
while True:
try:
if not plant.read_sync(interval_ms, offset_ms):
time.sleep(1.0)
continue
logic_func(plant)
except Exception as e:
print(f"Logic Error: {e}")
time.sleep(1.0)
+79
View File
@@ -0,0 +1,79 @@
import os
import requests
try:
from dotenv import load_dotenv
load_dotenv()
except ImportError:
pass
DB_URL = os.getenv("DB_CONTROLLER_URL", "http://127.0.0.1:13213")
class Database:
def __init__(self):
self.base_url = f"{DB_URL}/api"
def get_row(self, table, row_id):
"""GET /api/db/:table/:id/"""
try:
res = requests.get(f"{self.base_url}/db/{table}/{row_id}/")
res.raise_for_status()
return res.json().get("data")
except Exception as e:
print(f"DB Read Error: {e}")
return None
def insert(self, table, data):
"""POST /api/db/:table/"""
try:
res = requests.post(f"{self.base_url}/db/{table}/", json=data)
res.raise_for_status()
return res.json().get("data") # Returns {'id': lastID}
except Exception as e:
print(f"DB Insert Error: {e}")
return None
def query(self, table, filters=None, order_by=None, limit=100):
"""POST /api/db-query/:table/"""
payload = {
"filters": filters or [],
"orderBy": order_by or [],
"limit": limit
}
try:
res = requests.post(f"{self.base_url}/db-query/{table}/", json=payload)
res.raise_for_status()
return res.json().get("data")
except Exception as e:
print(f"DB Query Error: {e}")
return []
def update(self, table, row_id, data):
"""PUT /api/db/:table/:id/"""
try:
res = requests.put(f"{self.base_url}/db/{table}/{row_id}/", json=data)
res.raise_for_status()
return True
except Exception as e:
print(f"DB Update Error: {e}")
return False
def list_tables(self):
"""GET /api/db-meta/tables"""
try:
res = requests.get(f"{self.base_url}/db-meta/tables")
res.raise_for_status()
return res.json().get("data")
except Exception as e:
print(f"DB List Tables Error: {e}")
return []
def list_columns(self, table):
"""GET /api/db-meta/tables/:table/columns"""
try:
res = requests.get(f"{self.base_url}/db-meta/tables/{table}/columns")
res.raise_for_status()
return res.json().get("data")
except Exception as e:
print(f"DB List Columns Error: {e}")
return []
+14
View File
@@ -0,0 +1,14 @@
import time
def now():
"""Returns current time in Unix Milliseconds (standard JS/App format)"""
return int(time.time() * 1000)
def now_sec():
"""Returns current time in Unix Milliseconds, but floored to the second"""
return (int(time.time()) * 1000)
# If you need to convert a JS-style milli back to a Python datetime for local logging
def to_datetime(unix_milli):
from datetime import datetime
return datetime.fromtimestamp(unix_milli / 1000.0)