(*
  POU: PLC_App
  Main program (Option C: copy of output as relay feedback).
  Requires: NVL_In, NVL_Out, GVL_IO (EtherCAT_RelayFeedback).
  Map EL2809 DO channels in the device tree directly to NVL_Out (e.g. Ch0..5 = l_open_plan_living_room.l_1..l_6)
  and Ch15 to boiler relay (e.g. NVL_Out.boiler_status.relay_output or a GVL BOOL).
  Optional: DI_Emergency_Stop (physical E-Stop input).
*)
PROGRAM PLC_App
VAR
    open_plan_living_room: fb_room;
    open_plan_dining_room: fb_room;
    open_plan_entrance: fb_room;
    open_plan_guest_wc: fb_room;
    kitchen_kitchen: fb_room;
    kitchen_pantry: fb_room;
    bedrooms_office: fb_room;
    bedrooms_hallway: fb_room;
    bedrooms_laundry: fb_room;
    bedrooms_shower: fb_room;
    bedrooms_bedroom: fb_room;
    master_bedroom_suite: fb_room;
    master_bedroom_bathroom: fb_room;
    exterior_veranda: fb_room;
    exterior_entrance: fb_room;
    exterior_yard: fb_room;
    boiler: fb_boiler;
END_VAR

// ========== SECTION 1: LIGHTING (Option C: relay feedback = copy of output) ==========

// Open Plan - Living Room
open_plan_living_room(switches := NVL_In.open_plan_living_room, relay_status := EtherCAT_RelayFeedback.open_plan_living_room);
EtherCAT_RelayFeedback.open_plan_living_room := open_plan_living_room.lights;
NVL_Out.l_open_plan_living_room := open_plan_living_room.lights;

// Open Plan - Dining Room
open_plan_dining_room(switches := NVL_In.open_plan_dining_room, relay_status := EtherCAT_RelayFeedback.open_plan_dining_room);
EtherCAT_RelayFeedback.open_plan_dining_room := open_plan_dining_room.lights;
NVL_Out.l_open_plan_dining_room := open_plan_dining_room.lights;

// Open Plan - Entrance
open_plan_entrance(switches := NVL_In.open_plan_entrance, relay_status := EtherCAT_RelayFeedback.open_plan_entrance);
EtherCAT_RelayFeedback.open_plan_entrance := open_plan_entrance.lights;
NVL_Out.l_open_plan_entrance := open_plan_entrance.lights;

// Open Plan - Guest WC
open_plan_guest_wc(switches := NVL_In.open_plan_guest_wc, relay_status := EtherCAT_RelayFeedback.open_plan_guest_wc);
EtherCAT_RelayFeedback.open_plan_guest_wc := open_plan_guest_wc.lights;
NVL_Out.l_open_plan_guest_wc := open_plan_guest_wc.lights;

// Kitchen
kitchen_kitchen(switches := NVL_In.kitchen_kitchen, relay_status := EtherCAT_RelayFeedback.kitchen_kitchen);
EtherCAT_RelayFeedback.kitchen_kitchen := kitchen_kitchen.lights;
NVL_Out.l_kitchen_kitchen := kitchen_kitchen.lights;

// Pantry
kitchen_pantry(switches := NVL_In.kitchen_pantry, relay_status := EtherCAT_RelayFeedback.kitchen_pantry);
EtherCAT_RelayFeedback.kitchen_pantry := kitchen_pantry.lights;
NVL_Out.l_kitchen_pantry := kitchen_pantry.lights;

// Bedrooms - Office
bedrooms_office(switches := NVL_In.bedrooms_office, relay_status := EtherCAT_RelayFeedback.bedrooms_office);
EtherCAT_RelayFeedback.bedrooms_office := bedrooms_office.lights;
NVL_Out.l_bedrooms_office := bedrooms_office.lights;

// Bedrooms - Hallway
bedrooms_hallway(switches := NVL_In.bedrooms_hallway, relay_status := EtherCAT_RelayFeedback.bedrooms_hallway);
EtherCAT_RelayFeedback.bedrooms_hallway := bedrooms_hallway.lights;
NVL_Out.l_bedrooms_hallway := bedrooms_hallway.lights;

// Bedrooms - Laundry
bedrooms_laundry(switches := NVL_In.bedrooms_laundry, relay_status := EtherCAT_RelayFeedback.bedrooms_laundry);
EtherCAT_RelayFeedback.bedrooms_laundry := bedrooms_laundry.lights;
NVL_Out.l_bedrooms_laundry := bedrooms_laundry.lights;

// Bedrooms - Shower
bedrooms_shower(switches := NVL_In.bedrooms_shower, relay_status := EtherCAT_RelayFeedback.bedrooms_shower);
EtherCAT_RelayFeedback.bedrooms_shower := bedrooms_shower.lights;
NVL_Out.l_bedrooms_shower := bedrooms_shower.lights;

// Bedrooms - Bedroom
bedrooms_bedroom(switches := NVL_In.bedrooms_bedroom, relay_status := EtherCAT_RelayFeedback.bedrooms_bedroom);
EtherCAT_RelayFeedback.bedrooms_bedroom := bedrooms_bedroom.lights;
NVL_Out.l_bedrooms_bedroom := bedrooms_bedroom.lights;

// Master Bedroom - Suite
master_bedroom_suite(switches := NVL_In.master_bedroom_suite, relay_status := EtherCAT_RelayFeedback.master_bedroom_suite);
EtherCAT_RelayFeedback.master_bedroom_suite := master_bedroom_suite.lights;
NVL_Out.l_master_bedroom_suite := master_bedroom_suite.lights;

// Master Bedroom - Bathroom
master_bedroom_bathroom(switches := NVL_In.master_bedroom_bathroom, relay_status := EtherCAT_RelayFeedback.master_bedroom_bathroom);
EtherCAT_RelayFeedback.master_bedroom_bathroom := master_bedroom_bathroom.lights;
NVL_Out.l_master_bedroom_bathroom := master_bedroom_bathroom.lights;

// Exterior - Veranda
exterior_veranda(switches := NVL_In.exterior_veranda, relay_status := EtherCAT_RelayFeedback.exterior_veranda);
EtherCAT_RelayFeedback.exterior_veranda := exterior_veranda.lights;
NVL_Out.l_exterior_veranda := exterior_veranda.lights;

// Exterior - Entrance
exterior_entrance(switches := NVL_In.exterior_entrance, relay_status := EtherCAT_RelayFeedback.exterior_entrance);
EtherCAT_RelayFeedback.exterior_entrance := exterior_entrance.lights;
NVL_Out.l_exterior_entrance := exterior_entrance.lights;

// Exterior - Yard
exterior_yard(switches := NVL_In.exterior_yard, relay_status := EtherCAT_RelayFeedback.exterior_yard);
EtherCAT_RelayFeedback.exterior_yard := exterior_yard.lights;
NVL_Out.l_exterior_yard := exterior_yard.lights;

// ========== SECTION 2: BOILER ==========

boiler(
    ha_on := NVL_In.boiler.ha_on,
    ha_off := NVL_In.boiler.ha_off,
    schedule_on := NVL_In.boiler.schedule_on,
    schedule_off := NVL_In.boiler.schedule_off,
    emergency_stop := NVL_In.boiler.emergency_stop OR DI_Emergency_Stop,
    max_on_time := T#8H
);
NVL_Out.boiler_status.relay_output := boiler.relay_control;
NVL_Out.boiler_status.state := boiler.state;
NVL_Out.boiler_status.on_time_minutes := DINT_TO_INT(boiler.on_time_seconds / 60);
NVL_Out.boiler_status.remaining_minutes := DINT_TO_INT(boiler.remaining_seconds / 60);
NVL_Out.boiler_status.emergency_active := boiler.emergency_active;
NVL_Out.boiler_status.time_limit_reached := boiler.time_limit_reached;
NVL_Out.boiler_status.error_state := boiler.error_state;
NVL_Out.boiler_status.error_code := boiler.error_code;
