# -*- coding: utf-8 -*- """ FOCAS canlı okuyucu — cnc_acts (devir) + cnc_alarm2 (alarm) Kullanım: py -3-32 focas_okuyucu.py (Fwlib32.dll aynı klasörde) """ import ctypes import time import json import urllib.request import os MAKINE_IP = "192.168.5.91" FOCAS_PORT = 9999 MAKINE_ADI = "HTC200X560" VPS_URL = "https://cnc.sifirmakina.com.tr/api/focas-veri" SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) def fwlib_yukle(): for ad in ("Fwlib32.dll", "Fwlib30i.dll", "Fwlib64.dll"): yol = os.path.join(SCRIPT_DIR, ad) try: return ctypes.WinDLL(yol) except OSError: continue raise SystemExit("Fwlib DLL bulunamadi.") fwlib = fwlib_yukle() print("FOCAS kutuphanesi yuklendi.") handle = ctypes.c_ushort(0) baglan = getattr(fwlib, 'cnc_allclibhndl3', None) or getattr(fwlib, 'cnc_allclibhndl2', None) or fwlib.cnc_allclibhndl ret = baglan(ctypes.c_char_p(MAKINE_IP.encode()), ctypes.c_ushort(FOCAS_PORT), ctypes.c_long(10), ctypes.byref(handle)) if ret != 0: print("BAGLANTI HATASI:", ret) raise SystemExit(1) print("BAGLANDI! handle =", handle.value) # --- Fanuc model + seri numarası (cnc_rdcncid + cnc_sysinfo) --- class ODBCNCID(ctypes.Structure): _fields_ = [("cnc_id", ctypes.c_char * 64)] class ODBSYS(ctypes.Structure): _pack_ = 4 _fields_ = [("max_axis", ctypes.c_short), ("cnc_type", ctypes.c_char * 2), ("mt_type", ctypes.c_char * 2), ("series", ctypes.c_char * 4), ("version", ctypes.c_char * 4), ("axes", ctypes.c_char * 2)] try: cid = ODBCNCID() ret_cid = fwlib.cnc_rdcncid(handle, ctypes.byref(cid)) seri_no = cid.cnc_id.decode('ascii', 'ignore').strip() print("CNC SERI NO:", seri_no, "| ret:", ret_cid) except Exception as e: seri_no = "" print("cnc_rdcncid hata:", e) try: sysinfo = ODBSYS() ret_sys = fwlib.cnc_sysinfo(handle, ctypes.byref(sysinfo)) series = sysinfo.series.decode('ascii', 'ignore').strip() version = sysinfo.version.decode('ascii', 'ignore').strip() cnc_type = sysinfo.cnc_type.decode('ascii', 'ignore').strip() mt_type = sysinfo.mt_type.decode('ascii', 'ignore').strip() print("SISTEM BILGISI: seri:", series, "| versiyon:", version, "| cnc_tipi:", cnc_type, "| mt_tipi:", mt_type, "| ret:", ret_sys) except Exception as e: series = version = cnc_type = mt_type = "" print("cnc_sysinfo hata:", e) # Dün doğrulanmış çalışan struct (focas_test.py) class ODBACT(ctypes.Structure): _fields_ = [("dummy", ctypes.c_short * 2), ("data", ctypes.c_long)] MAX_AXIS = 32 class ODBAXIS(ctypes.Structure): _pack_ = 4 _fields_ = [("dummy", ctypes.c_short), ("type", ctypes.c_short), ("data", ctypes.c_long * MAX_AXIS)] def oku_eksen(): od = ODBAXIS() ret = fwlib.cnc_absolute(handle, ctypes.c_short(-1), ctypes.c_short(ctypes.sizeof(ODBAXIS)), ctypes.byref(od)) return [od.data[0], od.data[1], od.data[2]], ret def oku_taret_acisi(): """Taret/turret açısı — cnc_machine (makine koordinatı), A ekseni data[2] veya data[3]""" od = ODBAXIS() ret = fwlib.cnc_machine(handle, ctypes.c_short(-1), ctypes.c_short(ctypes.sizeof(ODBAXIS)), ctypes.byref(od)) return od.data[2], od.data[3], ret def oku_mod(): m = ctypes.c_short(0) ret = fwlib.cnc_rdopmode(handle, ctypes.byref(m)) return m.value, ret class ODBM(ctypes.Structure): _pack_ = 4 _fields_ = [("datano", ctypes.c_short), ("dummy", ctypes.c_short), ("mcr_val", ctypes.c_long), ("dec_val", ctypes.c_short)] def oku_takim(): m = ODBM() ret = fwlib.cnc_rdmacro(handle, ctypes.c_short(4120), ctypes.c_short(1), ctypes.byref(m)) return m.mcr_val, ret def oku_makro(no): m = ODBM() ret = fwlib.cnc_rdmacro(handle, ctypes.c_short(no), ctypes.c_short(1), ctypes.byref(m)) return m.mcr_val, ret # cnc_rdtimer — FANUC sayaç/süre okuma (resmî imza) class IODBTIME(ctypes.Structure): _pack_ = 4 _fields_ = [("minute", ctypes.c_long), ("msec", ctypes.c_long)] def oku_zaman(tip): t = IODBTIME() ret = fwlib.cnc_rdtimer(handle, ctypes.c_short(tip), ctypes.byref(t)) return (t.minute * 60 + t.msec / 1000.0), ret class LOADELM(ctypes.Structure): _pack_ = 4 _fields_ = [("data", ctypes.c_long), ("dec", ctypes.c_short), ("unit", ctypes.c_short), ("name", ctypes.c_char), ("suff1", ctypes.c_char), ("suff2", ctypes.c_char), ("reserve", ctypes.c_char)] class ODBSPLOAD(ctypes.Structure): _pack_ = 4 _fields_ = [("spload", LOADELM), ("spspeed", LOADELM)] def oku_yuk(): spl = ODBSPLOAD() num = ctypes.c_short(1) ret = fwlib.cnc_rdspmeter(handle, ctypes.c_short(0), ctypes.byref(num), ctypes.byref(spl)) return spl.spload.data, ret def oku_feed(): """F ilerleme hızı (actual feed) — cnc_actf""" f = ODBACT() ret = fwlib.cnc_actf(handle, ctypes.byref(f)) return f.data, ret class IODBPMC_U(ctypes.Union): _pack_ = 4 _fields_ = [("cdata", ctypes.c_byte * 5), ("idata", ctypes.c_short * 5), ("ldata", ctypes.c_long * 5), ("fdata", ctypes.c_float * 5), ("dfdata", ctypes.c_double * 5)] class IODBPMC(ctypes.Structure): _pack_ = 4 _fields_ = [("type_a", ctypes.c_short), ("type_d", ctypes.c_short), ("st_adr", ctypes.c_ushort), ("ed_adr", ctypes.c_ushort), ("u", IODBPMC_U)] def oku_io(): # TÜM I/O: X (input, type_a=3) + Y (output, type_a=2), X0-X127 + Y0-Y127 io = {} for tip, ad in [(3, "X"), (2, "Y")]: baytlar = [] for start in range(0, 128, 5): buf = IODBPMC() fwlib.pmc_rdpmcrng(handle, tip, 0, start, min(start + 4, 127), 8 + 5, ctypes.byref(buf)) baytlar += list(buf.u.cdata) io[ad] = baytlar return io print("Canli okuma basladi. Cikis: Ctrl+C") onceki_x = None onceki_y = None while True: try: act = ODBACT() ret_devir = fwlib.cnc_acts(handle, ctypes.byref(act)) devir = act.data alarmno = ctypes.c_long(0) ret_alarm = fwlib.cnc_alarm2(handle, ctypes.byref(alarmno)) eksen, ret_eksen = oku_eksen() taret2, taret3, ret_taret = oku_taret_acisi() mod, ret_mod = oku_mod() yuk, ret_yuk = oku_yuk() feed, ret_feed = oku_feed() takim, ret_takim = oku_takim() parca, _ = oku_makro(6711) # PARTS COUNT (sistem değişkeni) parca_6700, _ = oku_makro(6700) # aday: total machined parts parca_6710, _ = oku_makro(6710) # aday: required count parca_3901, _ = oku_makro(3901) # aday: total parts (alternatif) poweron, _ = oku_zaman(0) # POWER ON TIME (açık kalma) run_t, _ = oku_zaman(1) # OPERATING TIME (çalışma) cutting, _ = oku_zaman(2) # CUTTING TIME (kesme) cycle, _ = oku_zaman(3) # CYCLE TIME (çevrim) io_veri = oku_io() x_bytes = io_veri.get("X", []) y_bytes = io_veri.get("Y", []) # DEĞİŞİM TAKİBİ — sinyal tetiklenince hangi X/Y byte + bit değişti göster if onceki_x is not None: for i in range(min(len(x_bytes), len(onceki_x))): d = (x_bytes[i] & 0xFF) ^ (onceki_x[i] & 0xFF) if d: for b in range(8): if d & (1 << b): print(">>> X", i, ".", b, "=", bool(x_bytes[i] & (1 << b))) if onceki_y is not None: for i in range(min(len(y_bytes), len(onceki_y))): d = (y_bytes[i] & 0xFF) ^ (onceki_y[i] & 0xFF) if d: for b in range(8): if d & (1 << b): print(">>> Y", i, ".", b, "=", bool(y_bytes[i] & (1 << b))) onceki_x = x_bytes[:] onceki_y = y_bytes[:] y3 = y_bytes[3] if len(y_bytes) > 3 else 0 ayna_kap = bool(y3 & 0x10) # Y3.4 = CHUCK CLOSE (ayna kapama) ayna_ac = bool(y3 & 0x20) # Y3.5 = CHUCK OPEN (ayna açma) veri = {"makine": MAKINE_ADI, "devir": devir, "spindle_load": yuk, "feed": feed, "alarm": alarmno.value, "eksen": eksen, "taret": taret3, "mod": mod, "tool": takim, "io": io_veri, "ayna_ac": ayna_ac, "ayna_kap": ayna_kap, "parca": parca, "cycle": cycle, "run_time": run_t, "power_on": poweron, "cutting_time": cutting, "zaman": time.time()} print("devir:", devir, "rpm | feed:", feed, "| alarm:", alarmno.value, "| takim:", takim, "| parca:", parca, "| parca_aday(6700/6710/3901):", parca_6700, "/", parca_6710, "/", parca_3901, "| taret(A):", taret3, "/", taret2, "| cycle:", cycle, "| run:", run_t, "| poweron:", poweron, "| cutting:", cutting, "| ayna_ac:", ayna_ac, "| ayna_kap:", ayna_kap) try: req = urllib.request.Request(VPS_URL, data=json.dumps(veri).encode(), headers={"Content-Type": "application/json"}) urllib.request.urlopen(req, timeout=3) print(" VPS gonderim: OK") except Exception as e: print(" VPS gonderim HATA:", e) time.sleep(0.3) except KeyboardInterrupt: break except Exception as e: print("hata:", e) time.sleep(1) fwlib.cnc_freelibhndl(handle) print("Baglanti kapatildi.")