40-clients/ucepsa/edge-oee-demo/tools/probe_odoo_cutters.py
2026-06-25 18:51:33 +02:00

171 lines
4.5 KiB
Python
Executable File

#!/usr/bin/env python3
import os
import sys
import xmlrpc.client
from pathlib import Path
from datetime import datetime
MACHINE_MAP = {
"CORT-00": "Cortadora 0",
"CORT-01": "Cortadora 01",
"CORT-02": "Cortadora 02",
}
WORKORDER_STATES = ["waiting", "ready", "progress", "done"]
def read_env(path=".env"):
env = {}
p = Path(path)
for raw in p.read_text().splitlines():
line = raw.strip()
if not line or line.startswith("#") or "=" not in line:
continue
k, v = line.split("=", 1)
env[k.strip()] = v.strip().strip('"').strip("'")
return env
def existing_fields(models, db, uid, password, model, wanted):
fields = models.execute_kw(
db, uid, password,
model, "fields_get",
[],
{"attributes": ["string", "type"]},
)
return [f for f in wanted if f in fields]
def search_read(models, db, uid, password, model, domain, fields, limit=20, order="id asc"):
fields = existing_fields(models, db, uid, password, model, fields)
return models.execute_kw(
db, uid, password,
model, "search_read",
[domain],
{"fields": fields, "limit": limit, "order": order},
)
def main():
env = read_env()
url = env["ODOO_URL"].rstrip("/")
db = os.getenv("ODOO_DB_OVERRIDE") or env["ODOO_DB"]
user = env["ODOO_USER"]
password = env["ODOO_PASSWORD"]
print("ODOO_URL =", url)
print("ODOO_DB =", db)
print("ODOO_USER=", user)
print()
common = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/common")
uid = common.authenticate(db, user, password, {})
if not uid:
raise SystemExit("ERROR: autenticación Odoo fallida")
print("uid =", uid)
print()
models = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/object")
wc_fields = existing_fields(
models, db, uid, password,
"mrp.workcenter",
["id", "name", "code", "active", "display_name"],
)
wo_fields = existing_fields(
models, db, uid, password,
"mrp.workorder",
[
"id",
"name",
"state",
"workcenter_id",
"production_id",
"product_id",
"date_start",
"date_finished",
"duration_expected",
"duration",
"qty_production",
],
)
print("Campos workcenter disponibles:", wc_fields)
print("Campos workorder disponibles :", wo_fields)
print()
for machine_id, wc_name in MACHINE_MAP.items():
print("=" * 80)
print(f"{machine_id} -> {wc_name}")
workcenters = search_read(
models, db, uid, password,
"mrp.workcenter",
[("name", "=", wc_name)],
["id", "name", "code", "active", "display_name"],
limit=5,
order="id asc",
)
if not workcenters:
print("ERROR: no se encuentra centro de trabajo exacto")
continue
if len(workcenters) > 1:
print("AVISO: hay más de un centro exacto")
wc = workcenters[0]
wc_id = wc["id"]
print("Workcenter:", wc)
workorders = search_read(
models, db, uid, password,
"mrp.workorder",
[
("workcenter_id", "=", wc_id),
("state", "in", WORKORDER_STATES),
],
[
"id",
"name",
"state",
"workcenter_id",
"production_id",
"product_id",
"date_start",
"date_finished",
"duration_expected",
"duration",
"qty_production",
],
limit=20,
order="id desc",
)
if not workorders:
print("Sin workorders candidatas")
continue
print(f"Workorders candidatas: {len(workorders)}")
for wo in workorders:
print(
" -",
{
"id": wo.get("id"),
"name": wo.get("name"),
"state": wo.get("state"),
"production_id": wo.get("production_id"),
"product_id": wo.get("product_id"),
"date_start": wo.get("date_start"),
"date_finished": wo.get("date_finished"),
"qty_production": wo.get("qty_production"),
},
)
if __name__ == "__main__":
main()