#!/usr/bin/python3

import linuxcnc
import os
import sys
import paho.mqtt.client as mqtt
import time
import json

# Configuration
MQTT_BROKER = "*redacted*"
MQTT_PORT = *redacted
MQTT_USER = "*redacted*"
MQTT_PASSWORD = "*redacted*"
TOPIC_STATUS = "cnc/status"

# Connect to LinuxCNC
try:
    s = linuxcnc.stat()
except linuxcnc.error as e:
    print(f"Could not connect to LinuxCNC. Is it running? {e}")
    exit(1)

initial_parent_pid = os.getppid()


# Connect to MQTT
client = mqtt.Client()
client.username_pw_set(MQTT_USER, MQTT_PASSWORD)
client.connect(MQTT_BROKER, MQTT_PORT, 60)
client.loop_start()

last_state = None

print("LinuxCNC to Home Assistant bridge is running...")

while True:
    current_parent_pid = os.getppid()
    if current_parent_pid == 1 or current_parent_pid != initial_parent_pid:
        print("LinuxCNC has exited. Shutting down Home Assistant bridge.")
        sys.exit(0)

    try:
        s.poll()
        
        # Gather states
        # task_state: 1=New, 2=ESTOP, 3=ESTOP_RESET, 4=OFF, 5=ON
        # interp_state: 1=Initializing, 2=Idle, 3=Paused, 4=Reading, 5=Waiting, 6=Running
        payload = {
            "task_state": s.task_state,
            "task_mode": s.task_mode,
            "interp_state": s.interp_state,
            "file": s.file or "None",
            "line": s.motion_line,
            "tool_in_spindle": s.tool_in_spindle,
            "velocity": s.current_vel,
            "spindle_speed": s.spindle[0]['speed']
        }
        
        # Only publish if something changes to avoid flooding MQTT
        if payload != last_state:
            client.publish(TOPIC_STATUS, json.dumps(payload), retain=True)
            last_state = payload

    except linuxcnc.error:
        printf("error")
        sys.exit(1)

    except Exception as e:
        print(f"Error: {e}")
        sys.exit(1)
        
    time.sleep(0.25) # Poll every 0.25 second
