import subprocess
import re
import time
import json
import paho.mqtt.client as mqtt

MQTT_BROKER = "192.168.50.247"       # IP serwera HA z brokerem
MQTT_PORT = 1883
MQTT_USER = "mqtt"              # <-- tu wpisz swojego usera
MQTT_PASS = "mqtt123"           # <-- tu wpisz swoje hasło
MQTT_PREFIX = "ibsystem"
HA_PREFIX = "homeassistant"

def run_cmd(cmd):
    result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
    return result.stdout.strip()

def parse_lines(output):
    data = []
    for line in output.splitlines():
        m = re.match(r"rs\.(\d+)\.id\.(\d+)\.(input|output)\.(\w+)\.(\d+)(?:\.(\w+))?\s*=\s*(.+)", line.strip())
        if m:
            rs, idn, io, group, idx, field, val = m.groups()
            field = field or "value"
            data.append({
                "rs": rs,
                "id": idn,
                "io": io,
                "group": group,
                "idx": idx,
                "field": field,
                "val": val.strip()
            })
    return data

def publish_discovery(client, rec):
    unique_id = f"rs{rec['rs']}_id{rec['id']}_{rec['io']}_{rec['group']}{rec['idx']}_{rec['field']}"
    state_topic = f"{MQTT_PREFIX}/rs{rec['rs']}/id{rec['id']}/{rec['io']}/{rec['group']}{rec['idx']}/{rec['field']}"
    device_id = f"rs{rec['rs']}_id{rec['id']}"

    # wybór encji
    if rec["io"] == "input":
        component = "sensor"
    elif rec["io"] == "output" and rec["group"].startswith("do"):
        component = "switch"
    else:
        component = "sensor"

    config_topic = f"{HA_PREFIX}/{component}/{unique_id}/config"

    payload = {
        "name": f"RS{rec['rs']} ID{rec['id']} {rec['io']} {rec['group']}{rec['idx']} {rec['field']}",
        "state_topic": state_topic,
        "unique_id": unique_id,
        "device": {
            "identifiers": [device_id],
            "name": f"Sterownik {rec['id']}",
            "manufacturer": "IBSystem"
        }
    }

    if component == "switch":
        payload["command_topic"] = f"{MQTT_PREFIX}/rs{rec['rs']}/id{rec['id']}/set/{rec['group']}{rec['idx']}"

    client.publish(config_topic, json.dumps(payload), retain=True)

def publish_states(client, rs=0, ids=40):
    for i in range(1, ids+1):
        cmd = f'/ibsystem/ibls -a 127.0.0.1 --pretty -p 2001 -c "get(rs.{rs}.id.{i}.inp;);get(rs.{rs}.id.{i}.out;);"'
        output = run_cmd(cmd)
        records = parse_lines(output)
        for rec in records:
            publish_discovery(client, rec)
            topic = f"{MQTT_PREFIX}/rs{rec['rs']}/id{rec['id']}/{rec['io']}/{rec['group']}{rec['idx']}/{rec['field']}"
            client.publish(topic, rec["val"], retain=True)

def on_message(client, userdata, msg):
    topic = msg.topic.split("/")
    # przykład: ibsystem/rs0/id35/set/do3
    if len(topic) >= 5 and topic[0] == MQTT_PREFIX and topic[3] == "set":
        rs = topic[1].replace("rs","")
        idn = topic[2].replace("id","")
        target = topic[4]  # np. do3
        value = msg.payload.decode()

        group = target[:-1]
        idx = target[-1]

        cmd = f'/ibsystem/ibls -a 127.0.0.1 --pretty -p 2001 -c "set(rs.{rs}.id.{idn}.output.{group}.{idx}={value};)"'
        run_cmd(cmd)

def main():
    client = mqtt.Client(protocol=mqtt.MQTTv311)
    client.username_pw_set(MQTT_USER, MQTT_PASS)  # <-- tu dodane
    client.on_message = on_message
    client.connect(MQTT_BROKER, MQTT_PORT, 60)
    client.subscribe(f"{MQTT_PREFIX}/+/+/set/+")
    client.loop_start()

    while True:
        publish_states(client, rs=0, ids=40)
        time.sleep(5)

if __name__ == "__main__":
    main()

