Skip to main content

Das Script (V1.0)

 

-- Version: 1.0
-- ####################################################
-- Globale statische Listen/Variablen
-- ####################################################
local LT = ic.enums.LogicType
local SUM = ic.enums.LogicBatchMethod.Sum
local AVG = ic.enums.LogicBatchMethod.Average
local LST = ic.enums.LogicSlotType
local SI = ic.enums.SorterInstruction

local plant_list = {
    { name = "Rutenhirse",          hash_plant = ic.hash("ItemPlantSwitchGrass"),           hash_seed = ic.hash("SeedBag_Switchgrass") },
    { name = "Erdbeere",            hash_plant = ic.hash("ItemStrawberry"),                 hash_seed = ic.hash("SeedBag_Strawberry") },
    { name = "Blaubeere",           hash_plant = ic.hash("ItemBlueberry"),                  hash_seed = ic.hash("SeedBag_Blueberry") },
    { name = "Wassermelone",        hash_plant = ic.hash("ItemWatermelon"),                 hash_seed = ic.hash("SeedBag_Watermelon") },
    { name = "Kartoffel",           hash_plant = ic.hash("ItemPotato"),                     hash_seed = ic.hash("SeedBag_Potato") },
    { name = "Mais",                hash_plant = ic.hash("ItemCorn"),                       hash_seed = ic.hash("SeedBag_Corn") },
    { name = "Darga Farn",          hash_plant = ic.hash("ItemFilterFern"),                 hash_seed = ic.hash("SeedBag_DargaFern") },
    { name = "Farn",                hash_plant = ic.hash("ItemFern"),                       hash_seed = ic.hash("SeedBag_Fern") },
    { name = "Kakao",               hash_plant = ic.hash("ItemCocoaTree"),                  hash_seed = ic.hash("SeedBag_Cocoa") },
    { name = "Zuckerrohr",          hash_plant = ic.hash("ItemSugarCane"),                  hash_seed = ic.hash("SeedBag_SugarCane") },
    { name = "Weizen",              hash_plant = ic.hash("ItemWheat"),                      hash_seed = ic.hash("SeedBag_Wheet") },
    { name = "Sojabohnen",          hash_plant = ic.hash("ItemSoybean"),                    hash_seed = ic.hash("SeedBag_Soybean") },
    { name = "Reis",                hash_plant = ic.hash("ItemRice"),                       hash_seed = ic.hash("SeedBag_Rice") },
    { name = "Kürbis",              hash_plant = ic.hash("ItemPumpkin"),                    hash_seed = ic.hash("SeedBag_Pumpkin") },
    { name = "Pilze",               hash_plant = ic.hash("ItemMushroom"),                   hash_seed = ic.hash("SeedBag_Mushroom") },
    { name = "Winterspawn (Alpha)", hash_plant = ic.hash("ItemPlantEndothermic_Genepool1"), hash_seed = ic.hash("SeedBag_WinterspawnAlpha") },
    { name = "Winterspawn (Beta)",  hash_plant = ic.hash("ItemPlantEndothermic_Genepool2"), hash_seed = ic.hash("SeedBag_WinterspawnBeta") },
    { name = "Hadesblume (Alpha)",  hash_plant = ic.hash("ItemPlantThermogenic_Genepool1"), hash_seed = ic.hash("SeedBag_HadesAlpha") },
    { name = "Hadesblume (Beta)",   hash_plant = ic.hash("ItemPlantThermogenic_Genepool2"), hash_seed = ic.hash("SeedBag_HadesBeta") },
}

local gases = {
    { id = "O2",     type = "gas", icon = ss.ui.icons.gas.Oxygen,                 filter = "ItemGasFilterOxygen",        ratio=LT.RatioOxygen,                 sh = 21.1, mpl = 0,    temp_liq = 162, temp_ice = 57},
    { id = "N2",     type = "gas", icon = ss.ui.icons.gas.Nitrogen,               filter = "ItemGasFilterNitrogen",      ratio=LT.RatioNitrogen,               sh = 20.6, mpl = 0,    temp_liq = 190, temp_ice = 40},
    { id = "CH4",    type = "gas", icon = ss.ui.icons.gas.Methane,                filter = "ItemGasFilterVolatiles",     ratio=LT.RatioMethane,                sh = 20.4, mpl = 0,    temp_liq = 195, temp_ice = 82},
    { id = "X",      type = "gas", icon = ss.ui.icons.gas.Pollutant,              filter = "ItemGasFilterPollutants",    ratio=LT.RatioPollutant,              sh = 24.8, mpl = 0,    temp_liq = 434, temp_ice = 173},
    { id = "N2O",    type = "gas", icon = ss.ui.icons.gas.NitrousOxide,           filter = "ItemGasFilterNitrousOxide",  ratio=LT.RatioNitrousOxide,           sh = 37.2, mpl = 0,    temp_liq = 431, temp_ice = 251},
    { id = "H2O",    type = "gas", icon = ss.ui.icons.gas.Steam,                  filter = "ItemGasFilterWater",         ratio=LT.RatioSteam,                  sh = 72.0, mpl = 0,    temp_liq = 644, temp_ice = 274},
    { id = "CO2",    type = "gas", icon = ss.ui.icons.gas.CarbonDioxide,          filter = "ItemGasFilterCarbonDioxide", ratio=LT.RatioCarbonDioxide,          sh = 28.2, mpl = 0,    temp_liq = 266, temp_ice = 218},
    { id = "H2",     type = "gas", icon = ss.ui.icons.gas.Hydrogen,               filter = "ItemGasFilterHydrogen",      ratio=LT.RatioHydrogen,               sh = 20.4, mpl = 0,    temp_liq = 71,  temp_ice = 16 },
    { id = "N2H4",   type = "gas", icon = ss.ui.icons.gas.Hydrazine,              filter = "ItemGasFilterHydrazine",     ratio=LT.RatioHydrazine,              sh = 48.4, mpl = 0,    temp_liq = 521, temp_ice = 246},
    { id = "He",     type = "gas", icon = ss.ui.icons.gas.Helium,                 filter = "ItemGasFilterHelium",        ratio=LT.RatioHelium,                 sh = 20.8, mpl = 0,    temp_liq = 0,   temp_ice = 0},
    { id = "Sil",    type = "gas", icon = ss.ui.icons.gas.Silanol,                filter = "ItemGasFilterSilanol",       ratio=LT.RatioSilanol,                sh = 101,  mpl = 0,    temp_liq = 823, temp_ice = 143},
    { id = "HCI",    type = "gas", icon = ss.ui.icons.gas.HydrochloricAcid,       filter = "ItemGasFilterHCl",           ratio=LT.RatioHydrochloricAcid,       sh = 37.0, mpl = 0,    temp_liq = 431, temp_ice = 247},
    { id = "O3",     type = "gas", icon = ss.ui.icons.gas.Ozone,                  filter = "ItemGasFilterOzone",         ratio=LT.RatioOzone,                  sh = 38.6, mpl = 0,    temp_liq = 305, temp_ice = 51},
    
    { id = "l_O2",   type = "liq", icon = ss.ui.icons.gas.LiquidOxygen,           filter = "ItemGasFilterOxygen",        ratio=LT.RatioLiquidOxygen,           sh = 21.1, mpl = 33.3, temp_liq = 162, temp_ice = 57},
    { id = "l_N2",   type = "liq", icon = ss.ui.icons.gas.LiquidNitrogen,         filter = "ItemGasFilterNitrogen",      ratio=LT.RatioLiquidNitrogen,         sh = 20.6, mpl = 28.7, temp_liq = 190, temp_ice = 40},
    { id = "l_CH4",  type = "liq", icon = ss.ui.icons.gas.LiquidMethane,          filter = "ItemGasFilterVolatiles",     ratio=LT.RatioLiquidMethane,          sh = 20.4, mpl = 25,   temp_liq = 195, temp_ice = 82},
    { id = "l_X",    type = "liq", icon = ss.ui.icons.gas.LiquidPollutant,        filter = "ItemGasFilterPollutants",    ratio=LT.RatioLiquidPollutant,        sh = 24.8, mpl = 25,   temp_liq = 434, temp_ice = 173},
    { id = "l_N2O",  type = "liq", icon = ss.ui.icons.gas.LiquidNitrousOxide,     filter = "ItemGasFilterNitrousOxide",  ratio=LT.RatioLiquidNitrousOxide,     sh = 37.2, mpl = 38.5, temp_liq = 431, temp_ice = 251},
    { id = "l_H2O",  type = "liq", icon = ss.ui.icons.gas.Water,                  filter = "ItemGasFilterWater",         ratio=LT.RatioWater,                  sh = 72.0, mpl = 55.6, temp_liq = 644, temp_ice = 274},
    { id = "l_PH2O", type = "liq", icon = ss.ui.icons.gas.PollutedWater,          filter = "ItemGasFilterPollutedWater", ratio=LT.RatioPollutedWater,          sh = 64.0, mpl = 55.6, temp_liq = 644, temp_ice = 274},
    { id = "l_CO2",  type = "liq", icon = ss.ui.icons.gas.LiquidCarbonDioxide,    filter = "ItemGasFilterCarbonDioxide", ratio=LT.RatioLiquidCarbonDioxide,    sh = 28.2, mpl = 25,   temp_liq = 266, temp_ice = 218},
    { id = "l_H2",   type = "liq", icon = ss.ui.icons.gas.LiquidHydrogen,         filter = "ItemGasFilterHydrogen",      ratio=LT.RatioLiquidHydrogen,         sh = 20.4, mpl = 35.7, temp_liq = 71,  temp_ice = 16},
    { id = "l_N2H4", type = "liq", icon = ss.ui.icons.gas.LiquidHydrazine,        filter = "ItemGasFilterHydrazine",     ratio=LT.RatioLiquidHydrazine,        sh = 48.4, mpl = 33.3, temp_liq = 521, temp_ice = 246},
    { id = "l_Sil",  type = "liq", icon = ss.ui.icons.gas.LiquidSilanol,          filter = "ItemGasFilterSilanol",       ratio=LT.RatioLiquidSilanol,          sh = 101,  mpl = 6.25, temp_liq = 823, temp_ice = 143},
    { id = "l_HCI",  type = "liq", icon = ss.ui.icons.gas.LiquidHydrochloricAcid, filter = "ItemGasFilterHCl",           ratio=LT.RatioLiquidHydrochloricAcid, sh = 37.0, mpl = 35.7, temp_liq = 431, temp_ice = 247},
    { id = "l_O3",   type = "liq", icon = ss.ui.icons.gas.LiquidOzone,            filter = "ItemGasFilterOzone",         ratio=LT.RatioLiquidOzone,            sh = 38.6, mpl = 38.5, temp_liq = 305, temp_ice = 51},
    
    { id = "l_NaCi", type = "liq", icon = ss.ui.icons.gas.LiquidSodiumChloride,   filter = "ItemGasFilterSalt",          ratio=LT.RatioLiquidSodiumChloride,   sh = 130,  mpl = 25,   temp_liq = 2799,temp_ice = 606},
    { id = "l_ALC",  type = "liq", icon = ss.ui.icons.gas.LiquidAlcohol,          filter = "ItemGasFilterAlcohol",       ratio=LT.RatioLiquidAlcohol,          sh = 33.0, mpl = 17.2, temp_liq = 424, temp_ice = 232},
}

-- ####################################################
-- Einstellungen
-- ####################################################
local Settings = {

    hash_hd             = ic.hash("StructureHydroponicsTrayData"),
    hd_prefix           = "HD.",
    hash_plant          = ic.hash("ItemPotato"),
    hash_plant_seed     = ic.hash("SeedBag_Potato"),
    hash_fertilizer     = ic.hash("Fertilizer"),
    light_on            = 490,
    light_off           = 197,
    light_current       = 0,
    temp_min            = 293.15,
    temp_max            = 302.15,
    press_min           = 53,
    press_max           = 100,
    soll_n2             = 0.3,
    soll_co2            = 0.3,
    larre_use           = 1,
    larre_import_pos    = 1,
    larre_export_pos    = 2,
    larre_fert_pos      = 3,
    larre_hd_offset     = 3,
    gasabweichung       = 0.1,

    Devices = {
        AC              = { prefab = ic.hash("StructureAirConditioner"),        name = ic.hash("AC"),               desc = "Klimaanlage",           allowed_types = {} },
        AV_AC           = { prefab = ic.hash("StructureActiveVent"),            name = ic.hash("AV.AC"),            desc = "Ventilator Klima:",     allowed_types = {} },
        GS              = { prefab = ic.hash("StructureGasSensor"),             name = ic.hash("GS"),               desc = "Gas-Sensor",            allowed_types = {} },
        Door            = { prefab = ic.hash("StructureGlassDoor"),             name = ic.hash("DOOR"),             desc = "Tür",                   allowed_types = {} },
        GL              = { prefab = ic.hash("StructureGrowLight"),             name = ic.hash("GL"),               desc = "Pflanzlicht",           allowed_types = {} },
        AV_Waste        = { prefab = ic.hash("StructureActiveVent"),            name = ic.hash("AV.WASTE"),         desc = "Abgas-Ventilator",      allowed_types = {} },
        AV_NewGas       = { prefab = ic.hash("StructureActiveVent"),            name = ic.hash("AV.NEW_GAS"),       desc = "Frischluft-Ventilator", allowed_types = {} },
        ST_Fert         = { prefab = ic.hash("StructureStacker"),               name = ic.hash("ST.FERT"),          desc = "Stacker Dünger",        allowed_types = {} },
        ST_Seed         = { prefab = ic.hash("StructureStacker"),               name = ic.hash("ST.SEED"),          desc = "Stacker Saatgut",       allowed_types = {} },
        Sorter          = { prefab = ic.hash("StructureLogicSorter"),           name = ic.hash("LS.SORTER"),        desc = "Sorter",                allowed_types = {} },
        Larre           = { prefab = ic.hash("StructureLarreDockHydroponics"),  name = ic.hash("LARRE"),            desc = "LArRE",                 allowed_types = {} },
        Bin_Import      = { prefab = ic.hash("StructureChuteBin"),              name = ic.hash("BIN.IMPORT"),       desc = "Abwurfbehälter",        allowed_types = {} },
        Bin_Export_Seed = { prefab = ic.hash("StructureChuteExportBin"),        name = ic.hash("BIN.EXPORT.SEED"),   desc = "Saatausgabe",           allowed_types = {} },
        Bin_Export_Fert = { prefab = ic.hash("StructureChuteExportBin"),        name = ic.hash("BIN.EXPORT.FERT"),  desc = "Düngerausgabe",         allowed_types = {} },
    }
}

function loadSettings()
    if ic.persist.has("Settings") then
        Settings = util.json.decode(ic.persist.get("Settings"))
    end
end
loadSettings()

function saveSettings()
    ic.persist.set("Settings", util.json.encode(Settings))
end

-- ####################################################
-- Hilfsvariablen
-- ####################################################
local temp_mid = Settings.temp_min + (Settings.temp_max - Settings.temp_min) / 2
local press_mid = Settings.press_min + (Settings.press_max - Settings.press_min) / 2

-- ####################################################
-- Screens
-- ####################################################

local screens = {
    main = { surface = ss.ui.surface("main"), name = "main", loaded = false },
    settings = { surface = ss.ui.surface("settings"), name = "settings", loaded = false },
    devices = { surface = ss.ui.surface("devices"), name = "devices", loaded = false }
}

local size = screens.main.surface:size()
local W, H = size.w, size.h

-- ####################################################
-- Funktionen
-- ####################################################
function isBreathable(sensor)

    local press = ic.read(sensor, LT.Pressure)
    local temp = ic.read(sensor, LT.Temperature)
    local totalMols = ic.read(sensor, LT.TotalMoles)
    local o2_prec = ic.read(sensor, LT.RatioOxygen)
    local x_prec = ic.read(sensor, LT.RatioPollutant)
    local ch4_prec = ic.read(sensor, LT.RatioMethane)
    local h2_prec = ic.read(sensor, LT.RatioHydrogen)
    local n2h4_prec = ic.read(sensor, LT.RatioHydrazine)
    local n2o_prec = ic.read(sensor, LT.RatioNitrousOxide)
       
    local o2_mols = o2_prec * totalMols
    local toxin_mols = x_prec * totalMols + ch4_prec * totalMols + n2h4_prec * totalMols + h2_prec * totalMols
    local n2o_mols = n2o_prec * totalMols
    
    if temp < 273.15 then
        return {
            state = false,
            comment = "Zu kalt"
        }
    elseif temp > 323.15 then
        return {
            state = false,
            comment = "Zu heiß"
        }
    elseif press < 20 then
        return {
            state = false,
            comment = "Zu wenig druck"
        }
    elseif press > 400 then
        return {
            state = false,
            comment = "Zu viel Druck"
        }
    elseif o2_mols < 54 then
        return {
            state = false,
            comment = "Zu wenig O2"
        }
    elseif toxin_mols > 2 then
        return {
            state = false,
            comment = "Toxine erkannt"
        }
    elseif n2o_mols > 15  then
        return {
            state = false,
            comment = "Narkosegas erkannt"
        }
    end
    
    return {
        state = true,
        comment = "Atembar"    
    }
end

function getHDs()
    --print("Call: getHDs()")
    local devices = ic.find_all(Settings.hd_prefix .. "([0-9]*)", "regex")
    local hydroponic_devices = #devices
    local hd_list = {}
    --print("Hydroponic devices found: " .. hydroponic_devices)
    for i = 1, hydroponic_devices do
        hd_list[i] = { hash = ic.hash(Settings.hd_prefix .. i) }
    end
    return hydroponic_devices, hd_list
end

function initDevices()

    print("Call: initDevices()")
    local devs = Settings.Devices

    ic.batch_write_name(devs.GL.name, devs.GL.name, LT.Lock, 1)
    ic.batch_write_name(devs.AV_Waste.prefab, devs.AV_Waste.name, LT.Mode, 1)
    ic.batch_write_name(devs.AV_Waste.prefab, devs.AV_Waste.name, LT.PressureInternal, 45000)
    ic.batch_write_name(devs.AV_Waste.prefab, devs.AV_Waste.name, LT.Lock, 1)
    ic.batch_write_name(devs.AV_NewGas.prefab, devs.AV_NewGas.name, LT.Mode, 0)
    ic.batch_write_name(devs.AV_NewGas.prefab, devs.AV_NewGas.name, LT.PressureExternal, press_mid)
    ic.batch_write_name(devs.AV_NewGas.prefab, devs.AV_NewGas.name, LT.Lock, 1)
    ic.batch_write_name(devs.AC.prefab, devs.AC.name, LT.Lock, 1)
    ic.batch_write_name(devs.AV_AC.prefab, devs.AV_AC.name, LT.Lock, 1)
    ic.batch_write_name(devs.AV_AC.prefab, devs.AV_AC.name, LT.PressureInternal, 1000)
    ic.batch_write_name(devs.ST_Fert.prefab, devs.ST_Fert.name, LT.Setting, 1)
    ic.batch_write_name(devs.ST_Seed.prefab, devs.ST_Seed.name, LT.Setting, 1)
    ic.batch_write_name(devs.Bin_Import.prefab, devs.Bin_Import.name, LT.Lock, 1)
    ic.batch_write_name(devs.Bin_Export_Seed.prefab, devs.Bin_Export_Seed.name, LT.Lock, 1)
    ic.batch_write_name(devs.Bin_Export_Fert.prefab, devs.Bin_Export_Fert.name, LT.Lock, 1)
    --ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Lock, 1)
    ic.batch_write_name(devs.Sorter.prefab, devs.Sorter.name, LT.Lock, 1)
    ic.batch_write_name(devs.AV_Waste.prefab, devs.AV_Waste.name, LT.On, 0)
    ic.batch_write_name(devs.AV_NewGas.prefab, devs.AV_NewGas.name, LT.On, 0)
    ic.batch_write_name(devs.AC.prefab, devs.AC.name, LT.On, 0)
    ic.batch_write_name(devs.AV_AC.prefab, devs.AV_AC.name, LT.On, 0)
    ic.batch_write_name(devs.ST_Fert.prefab, devs.ST_Fert.name, LT.On, 1)
    ic.batch_write_name(devs.ST_Seed.prefab, devs.ST_Seed.name, LT.On, 1)
    ic.batch_write_name(devs.Bin_Import.prefab, devs.Bin_Import.name, LT.On, 1)
    ic.batch_write_name(devs.Bin_Export_Seed.prefab, devs.Bin_Export_Seed.name, LT.On, 1)
    ic.batch_write_name(devs.Bin_Export_Fert.prefab, devs.Bin_Export_Fert.name, LT.On, 1)
    ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.On, 1)
    ic.batch_write_name(devs.Sorter.prefab, devs.Sorter.name, LT.On, 1)

    -- sorter Programmieren
    ic.batch_write_name(devs.Sorter.prefab, devs.Sorter.name, LT.Mode, 1)
    local refid = ic.batch_read_name(devs.Sorter.prefab, devs.Sorter.name, LT.ReferenceId, AVG)
    local hash = 0
    hash = ic.bit.ins(hash, SI.FilterPrefabHashEquals, 0, 8)
    hash = ic.bit.ins(hash, Settings.hash_plant_seed, 8, 32)
    print("Put " .. prefab_name(Settings.hash_plant_seed) .. " to Sorter")
    ic.mem_put_id(refid, 0, hash)
end

function getDeviceList(sel_prefab, sel_name, allowed) 
    local devices = ic.device_list()
    local device_ids = {}
    local device_options = {}
    local selected = 0

    for i, dev in ipairs(devices) do        
        --if dev.prefab_hash ~= Settings.hash_hd then
        device_ids[i] = { display = dev.display_name, name = dev.name_hash, prefab = dev.prefab_hash }
        device_options[i] = dev.display_name
        
        if dev.name_hash == sel_name and dev.prefab_name == sel_prefab then
            selected = i
        end
        --end
    end

    return device_options, device_ids, selected

end

function getPlantList(sel)
    local plant_options = {}
    local plant_help_i = 1
    local selected = 0
    for i, plant in ipairs(plant_list) do
        plant_options[plant_help_i] = plant.name
        plant_help_i = plant_help_i + 1
        if sel == plant.hash_plant then
            selected = i
        end
    end
    return plant_options, plant_list, selected
end

-- ####################################################
-- START: MENÜ Geräteauswahl
-- ####################################################
function buildDevices() 
    
    local devs = Settings.Devices
    local screen_surface = screens.devices.surface
    local pos_x = 20
    local pos_y = 30
    
    print("Call:BuildDevices()")
    screen_surface:clear()

    -- Background
    screen_surface:element({ id = "bg", type = "panel",
        rect = { unit = "px", x = 0, y = 0, w = W, h = H },
        style = { bg = "#0B1120" }
    })
    -- Titel
    screen_surface:element({ id = "head_title_text", type = "panel",
        rect = { unit = "px", x = 0, y = 0, w = W, h = 20 },
        style = { bg = "#44DD44" }
    })
    screen_surface:element({ id = "head_title_panel", type = "label",
        rect = { unit = "px", x = 20, y = 0, w = W - 40, h = 20 },
        props = { text = "Geräteliste" },
        style = { font_size = 14, color = "#FFFFFF" }
    })

    local ol, idl, sel = getDeviceList()
    for key, dev in pairs(devs) do
        for i, d in ipairs(idl) do
            if d.prefab == dev.prefab and d.name == dev.name then
                sel = i-1
            end
        end
        screen_surface:element({ id = "lbl_settings_temp1" .. key, type = "label",
            rect = { unit = "px", x = pos_x, y = pos_y, w = 200, h = 20 },
            props = { text = dev.desc },
            style = { font_size = 12, color = "#FFFFFF" }
        })
        screen_surface:element({
            id = "select" .. key, type = "select",
            rect = { unit = "px", x = pos_x + 200, y = pos_y, w = W - pos_x - 210, h = 20 },
            props = { options = ol, selected = sel },
            style = { bg = "#0F172A", text = "#E2E8F0", font_size = 10 },
            on_change = function(value, player)
                print(tonumber(value))
                print(idl[tonumber(value)+1].prefab)
                print(prefab_name(idl[tonumber(value)+1].prefab))
                dev.prefab = idl[tonumber(value)+1].prefab
                dev.name = idl[tonumber(value)+1].name
                screen_surface:get("select" .. key):set_props({selected = tonumber(value)})
            end,
        })
        pos_y = pos_y + 22
    end

    screen_surface:element({
        id = "btn_settings_ok", type = "button",
        rect = { unit = "px", x = pos_x, y = pos_y, w = W - pos_x - 20, h = 30 },
        style = { bg = "#33FF55", text = "#FFFFFF" },
        props = { text = "Fertig", z_index = 101 },
        on_click = function(playerName)
            saveSettings()
            ss.ui.activate("settings")
            
        end
    })

    screen_surface:commit()
end

-- ####################################################
-- START: MENÜ EINSTELLUNGEN
-- ####################################################
function buildSettings()

    print("Call:buildSettings()")
    local devs = Settings.Devices
    local screen_surface = screens.settings.surface
    local pos_x = 20
    local pos_y = 30

    screen_surface:clear()

    -- Background
    screen_surface:element({ id = "bg", type = "panel",
        rect = { unit = "px", x = 0, y = 0, w = W, h = H },
        style = { bg = "#0B1120" }
    })
    -- Titel
    screen_surface:element({ id = "head_title_text", type = "panel",
        rect = { unit = "px", x = 0, y = 0, w = W-120, h = 20 },
        style = { bg = "#44DD44" }
    })
    screen_surface:element({ id = "head_title_panel", type = "label",
        rect = { unit = "px", x = 20, y = 0, w = W - 40, h = 20 },
        props = { text = "Einstellungen" },
        style = { font_size = 14, color = "#FFFFFF" }
    })

    -- Temperatur
    screen_surface:element({ id = "lbl_settings_temp1", type = "label",
        rect = { unit = "px", x = pos_x, y = pos_y, w = 120, h = 28 },
        props = { text = "Temperatur (°C)", z_index = 101 },
        style = { font_size = 14, color = "#FFFFFF" }
    })
    screen_surface:element({
        id = "input_min_temp", type = "textinput",
        rect = { unit = "px", x = pos_x + 200, y = pos_y, w = 50, h = 28 },
        props = { value = util.temp(Settings.temp_min), title = "Min. Temperatur (in °C)", z_index = 101 },
        style = { bg = "#0F172A", text = "#E2E8F0", placeholder_color = "#475569", font_size = 12 },
        on_change = function(value, player)
            Settings.temp_min = util.temp(value,"C","K")
            temp_mid = Settings.temp_min + (Settings.temp_max - Settings.temp_min) / 2
            screen_surface:get("input_settings_min_temp"):set_props({value = value})
        end,
    })
    screen_surface:element({ id = "lbl_settings_temp2", type = "label",
        rect = { unit = "px", x = pos_x + 255, y = pos_y, w = 25, h = 28 },
        props = { text = "bis", z_index = 101 },
        style = { font_size = 14, color = "#FFFFFF", align = "center" }
    })
    screen_surface:element({
        id = "input_max_temp", type = "textinput",
        rect = { unit = "px", x = pos_x + 285, y = pos_y, w = 50, h = 28 },
        props = { value = util.temp(Settings.temp_max), title = "Max. Temperatur (in °C)", z_index = 101 },
        style = { bg = "#0F172A", text = "#E2E8F0", placeholder_color = "#475569", font_size = 12 },
        on_change = function(value, player)
            Settings.temp_max = util.temp(value,"C","K")
            temp_mid = Settings.temp_min + (Settings.temp_max - Settings.temp_min) / 2
            screen_surface:get("input_settings_max_temp"):set_props({value = value})
        end,
    })
    pos_y = pos_y + 33
    
    -- Druck
    screen_surface:element({ id = "lbl_settings_press1", type = "label",
        rect = { unit = "px", x = pos_x, y = pos_y, w = 120, h = 28 },
        props = { text = "Druck (kPa)", z_index = 101 },
        style = { font_size = 14, color = "#FFFFFF" }
    })
    screen_surface:element({
        id = "input_min_press", type = "textinput",
        rect = { unit = "px", x = pos_x + 200, y = pos_y, w = 50, h = 28 },
        props = { value = tostring(Settings.press_min),  title = "Min. Druck (in kPa)", z_index = 101 },
        style = { bg = "#0F172A", text = "#E2E8F0", placeholder_color = "#475569", font_size = 12 },
        on_change = function(value, player)
            Settings.press_min = tonumber(value)
            press_mid = Settings.press_min + (Settings.press_max - Settings.press_min) / 2
            screen_surface:get("input_settings_min_press"):set_props({value = tostring(Settings.press_min)})
        end,
    })
    screen_surface:element({ id = "lbl_settings_press2", type = "label",
        rect = { unit = "px", x = pos_x + 255, y = pos_y, w = 25, h = 28 },
        props = { text = "bis", z_index = 101 },
        style = { font_size = 14, color = "#FFFFFF", align = "center" }
    })
    screen_surface:element({
        id = "input_max_press", type = "textinput",
        rect = { unit = "px", x = pos_x + 285, y = pos_y, w = 50, h = 28 },
        props = { value = tostring(Settings.press_max), title = "Max. Druck (in kPa)", z_index = 101 },
        style = { bg = "#0F172A", text = "#E2E8F0", placeholder_color = "#475569", font_size = 12 },
        on_change = function(value, player)
            Settings.press_max = tonumber(value)
            press_mid = Settings.press_min + (Settings.press_max - Settings.press_min) / 2
            screen_surface:get("input_settings_max_press"):set_props({value = tostring(Settings.press_max)})
        end,
    })
    pos_y = pos_y + 33

    -- Tageslicht
    screen_surface:element({ id = "lbl_settings_light", type = "label",
        rect = { unit = "px", x = pos_x, y = pos_y, w = 120, h = 28 },
        props = { text = "Licht an (sec.)", z_index = 101 },
        style = { font_size = 14, color = "#FFFFFF" }
    })
    screen_surface:element({
        id = "input_daylight", type = "textinput",
        rect = { unit = "px", x = pos_x + 200, y = pos_y, w = 50, h = 28 },
        props = { value = tostring(Settings.light_on), title = "Licht: an (in sec.)", z_index = 101 },
        style = { bg = "#0F172A", text = "#E2E8F0", placeholder_color = "#475569", font_size = 12 },
        on_change = function(value, player)
            Settings.light_on = tonumber(value)
            screen_surface:get("input_settings_light_on"):set_props({value = tostring(Settings.light_on)})
        end,
    })
    screen_surface:element({ id = "lbl_settings_light2", type = "label",
        rect = { unit = "px", x = pos_x + 255, y = pos_y, w = 25, h = 28 },
        props = { text = "/", z_index = 101 },
        style = { font_size = 14, color = "#FFFFFF", align = "center" }
    })
    screen_surface:element({
        id = "input_night", type = "textinput",
        rect = { unit = "px", x = pos_x + 285, y = pos_y, w = 50, h = 28 },
        props = { value = tostring(Settings.light_off), title = "Licht: aus (in sec.)", z_index = 101 },
        style = { bg = "#0F172A", text = "#E2E8F0", placeholder_color = "#475569", font_size = 12 },
        on_change = function(value, player)
            Settings.light_off = tonumber(value)
            screen_surface:get("input_settings_light_off"):set_props({value = tostring(Settings.light_off)})
        end,
    })
    pos_y = pos_y + 33

    -- Pflanze
    screen_surface:element({ id = "lbl_settings_plant", type = "label",
        rect = { unit = "px", x = pos_x, y = pos_y, w = 120, h = 28 },
        props = { text = "Pflanze", z_index = 101 },
        style = { font_size = 14, color = "#FFFFFF" }
    })

    local o, pl, sel = getPlantList(Settings.hash_plant)
    screen_surface:element({
        id = "input_plant", type = "select",
        rect = { unit = "px", x = pos_x + 200, y = pos_y, w = 150, h = 28 },
        props = { options = o, selected = sel },
        style = { bg = "#0F172A", text = "#E2E8F0", font_size = 12 },
        on_change = function(value, player)
            print(pl[tonumber(value)+1].name)
            Settings.hash_plant = pl[tonumber(value)+1].hash_plant
            Settings.hash_plant_seed = pl[tonumber(value)+1].hash_seed
            print(prefab_name(Settings.hash_plant))
            print(prefab_name(Settings.hash_plant_seed))
            screen_surface:get("input_plant"):set_props({selected = tostring(value)})
        end,
    })
    pos_y = pos_y + 33

    -- Gaszusammensetzung
    screen_surface:element({ id = "lbl_settings_gas1", type = "label",
        rect = { unit = "px", x = pos_x, y = pos_y, w = 120, h = 28 },
        props = { text = "CO2/N2 Sollanteil (in %)", z_index = 101 },
        style = { font_size = 14, color = "#FFFFFF" }
    })
        
    screen_surface:element({
        id = "input_soll_co2", type = "textinput",
        rect = { unit = "px", x = pos_x + 200, y = pos_y, w = 50, h = 28 },
        props = { value = tostring(Settings.soll_co2 * 100), title = "Sollmenge CO2 in %", z_index = 101 },
        style = { bg = "#0F172A", text = "#E2E8F0", font_size = 12 },
        on_change = function(value, player)
            Settings.soll_co2 = tonumber(value) / 100
            screen_surface:get("input_settings_soll_co2"):set_props({value = tostring(Settings.soll_co2 * 100)})
        end,
    }) 
    screen_surface:element({ id = "lbl_settings_gas2", type = "label",
        rect = { unit = "px", x = pos_x + 255, y = pos_y, w = 25, h = 28 },
        props = { text = "/", z_index = 101 },
        style = { font_size = 14, color = "#FFFFFF", align = "center" }
    })
    screen_surface:element({
        id = "input_soll_n2", type = "textinput",
        rect = { unit = "px", x = pos_x + 285, y = pos_y, w = 50, h = 28 },
        props = { value = tostring(Settings.soll_n2 * 100), title = "Sollmenge N2 in %", z_index = 101 },
        style = { bg = "#0F172A", text = "#E2E8F0", font_size = 12 },
        on_change = function(value, player)
            Settings.soll_n2 = tonumber(value) / 100
            screen_surface:get("input_settings_soll_n2"):set_props({value = tostring(Settings.soll_n2 * 100)})
        end,
    })
    pos_y = pos_y + 33

    -- Larre Use
    screen_surface:element({ id = "lbl_settings_larre_use", type = "label",
        rect = { unit = "px", x = pos_x, y = pos_y, w = 120, h = 28 },
        props = { text = "Larre Verwenden?", z_index = 101 },
        style = { font_size = 14, color = "#FFFFFF" }
    })
        
    screen_surface:element({
        id = "cb_settings_larre_use", type = "checkbox",
        rect = { unit = "px", x = pos_x + 200, y = pos_y, w = 150, h = 28 },
        props = { text = "Verwenden", checked = Settings.larre_use == 1 },
        style = { font_size = 12 },
        on_click = function(player)
            Settings.larre_use = Settings.larre_use == 1 and 0 or 1
            screen_surface:get("cb_settings_larre_use"):set_props({checked = Settings.larre_use == 1})
        end,
    }) 
    pos_y = pos_y + 33

    -- Larre Import Position
    screen_surface:element({ id = "lbl_settings_larre_import_pos", type = "label",
        rect = { unit = "px", x = pos_x, y = pos_y, w = 120, h = 28 },
        props = { text = "Larre Abwurf Pos.", z_index = 101 },
        style = { font_size = 14, color = "#FFFFFF" }
    })
        
    screen_surface:element({
        id = "input_settings_larre_import_pos", type = "textinput",
        rect = { unit = "px", x = pos_x + 200, y = pos_y, w = 50, h = 28 },
        props = { value = tostring(Settings.larre_import_pos), title = "Larre Abwurf Pos.", z_index = 101 },
        style = { bg = "#0F172A", text = "#E2E8F0", font_size = 12 },
        on_change = function(value, player)
            Settings.larre_import_pos = tonumber(value)
            screen_surface:get("input_settings_larre_import_pos"):set_props({value = tostring(Settings.larre_import_pos)})
        end,
    }) 
    pos_y = pos_y + 33

    -- Larre Export Position
    screen_surface:element({ id = "lbl_settings_larre_export_pos", type = "label",
        rect = { unit = "px", x = pos_x, y = pos_y, w = 120, h = 28 },
        props = { text = "Larre Saat-Aufnahme Pos.", z_index = 101 },
        style = { font_size = 14, color = "#FFFFFF" }
    })
        
    screen_surface:element({
        id = "input_settings_larre_export_pos", type = "textinput",
        rect = { unit = "px", x = pos_x + 200, y = pos_y, w = 50, h = 28 },
        props = { value = tostring(Settings.larre_export_pos), title = "Larre Saat-Aufnahme Pos.", z_index = 101 },
        style = { bg = "#0F172A", text = "#E2E8F0", font_size = 12 },
        on_change = function(value, player)
            Settings.larre_export_pos = tonumber(value)
            screen_surface:get("input_settings_larre_export_pos"):set_props({value = tostring(Settings.larre_export_pos)})
        end,
    }) 
    pos_y = pos_y + 33

    -- Larre Fert
    screen_surface:element({ id = "lbl_settings_larre_fert", type = "label",
        rect = { unit = "px", x = pos_x, y = pos_y, w = 120, h = 28 },
        props = { text = "Larre Fert-Aufnahme Pos.", z_index = 101 },
        style = { font_size = 14, color = "#FFFFFF" }
    })
        
    screen_surface:element({
        id = "input_settings_larre_fert_pos", type = "textinput",
        rect = { unit = "px", x = pos_x + 200, y = pos_y, w = 50, h = 28 },
        props = { value = tostring(Settings.larre_fert_pos), title = "Larre Fert-Aufnahme Pos.", z_index = 101 },
        style = { bg = "#0F172A", text = "#E2E8F0", font_size = 12 },
        on_change = function(value, player)
            Settings.larre_fert_pos = tonumber(value)
            screen_surface:get("input_settings_larre_fert_pos"):set_props({value = tostring(Settings.larre_fert_pos)})
        end,
    }) 
    pos_y = pos_y + 33

    -- Larre HD Offset
    screen_surface:element({ id = "lbl_settings_larre_hd_offset", type = "label",
        rect = { unit = "px", x = pos_x, y = pos_y, w = 120, h = 28 },
        props = { text = "Larre HD Offset", z_index = 101 },
        style = { font_size = 14, color = "#FFFFFF" }
    })
        
    screen_surface:element({
        id = "input_settings_larre_hd_offset", type = "textinput",
        rect = { unit = "px", x = pos_x + 200, y = pos_y, w = 50, h = 28 },
        props = { value = tostring(Settings.larre_hd_offset), title = "Larre HD Offset", z_index = 101 },
        style = { bg = "#0F172A", text = "#E2E8F0", font_size = 12 },
        on_change = function(value, player)
            Settings.larre_hd_offset = tonumber(value)
            screen_surface:get("input_settings_larre_hd_offset"):set_props({value = tostring(Settings.larre_hd_offset)})
        end,
    }) 
    pos_y = pos_y + 33

    screen_surface:element({
        id = "btn_settings_ok", type = "button",
        rect = { unit = "px", x = pos_x, y = pos_y, w = W - pos_x - 20, h = 30 },
        style = { bg = "#33FF55", text = "#FFFFFF" },
        props = { text = "Fertig", z_index = 101 },
        on_click = function(playerName)
            saveSettings()
            ss.ui.activate("main")
            
        end
    })
    pos_y = pos_y + 35

    -- Button zu Geräteauswahl
    screen_surface:element({ id = "btn_settings_dev", type = "button",
        rect = { unit = "px", x = pos_x, y = pos_y, w = W - pos_x - 20, h = 30 },
        props = { text = "Geräteliste", z_index = 101 },
        style = { font_size = 14, color = "#FFFFFF" },
        on_click = function(playerName)
            initDevices()
            buildDevices()
            ss.ui.activate("devices")
        end
    })

    screen_surface:commit()
end

-- ####################################################
-- START: MENÜ MAIN
-- ####################################################
function buildMain()

    print("Call:buildMain()")
    local devs = Settings.Devices
    local screen_surface = screens.main.surface
    local pos_x = 20
    local pos_y = 30
    screen_surface:clear()

    -- Background
    screen_surface:element({ id = "panel_main_bg", type = "panel",
        rect = { unit = "px", x = 0, y = 0, w = W, h = H },
        style = { bg = "#0B1120" }
    })

    -- Title
    screen_surface:element({ id = "panel_main_title", type = "panel",
        rect = { unit = "px", x = 0, y = 0, w = 200, h = 20 },
        style = { bg = "#44DD44" }
    })
    screen_surface:element({ id = "lbl_main_title", type = "label",
        rect = { unit = "px", x = 20, y = 0, w = 200, h = 20 },
        props = { text = "Greenhouse Monitor" },
        style = { font_size = 14, color = "#FFFFFF" }
    })
    -- Frucht-Icon
    screen_surface:element({ id = "panel_main_plant_icon", type = "panel",
        rect = { unit = "px", x = 0, y = 20, w = 60, h = 60 },
        style = { bg = "#44DD44" }
    })
    screen_surface:element({
        id = "icon_main_plant", type = "icon",
        rect = { unit = "px", x = 0, y = 20, w = 60, h = 60 },
        props = { icon_type = "prefab", name = prefab_name(Settings.hash_plant) },
    })

    -- Button zu Einstellungen
    screen_surface:element({
        id = "btn_main_settings", type = "button",
        rect = { unit = "px", x = 0, y = 100, w = 60, h = 60 },
        style = { bg = "#334155", text = "#FFFFFF" },
        props = { text = "Set" },
        on_click = function(playerName)
            ss.ui.activate("settings")
        end
    })

    -- Light
    screen_surface:element({
        id = "icon_main_light", type = "icon",
        rect = { unit = "px", x = 70, y = 30, w = 40, h = 40 },
        props = { icon_type = "prefab", name = prefab_name(devs.GL.prefab) },
    })
    screen_surface:element({ id = "lbl_main_gl_status", type = "label",
        rect = { unit = "px", x = 130, y = 30, w = 80, h = 25 },
        props = { text = "Licht: Unk." },
        style = { font_size = 14, color = "#FFFFFF" }
    })
    screen_surface:element({ id = "lbl_main_gl_time", type = "label",
        rect = { unit = "px", x = 130, y = 45, w = 80, h = 25 },
        props = { text = "0 s" },
        style = { font_size = 14, color = "#AAAAAA" }
    })

    -- AC
    screen_surface:element({
        id = "icon_main_ac", type = "icon",
        rect = { unit = "px", x = 70, y = 70, w = 40, h = 40 },
        props = { icon_type = "prefab", name = prefab_name(devs.AC.prefab) },
    })
    screen_surface:element({ id = "lbl_main_ac_status", type = "label",
        rect = { unit = "px", x = 130, y = 70, w = 100, h = 25 },
        props = { text = "AC: " },
        style = { font_size = 14, color = "#FFFFFF" }
    })
    screen_surface:element({ id = "lbl_main_ac_temp", type = "label",
        rect = { unit = "px", x = 130, y = 85, w = 100, h = 25 },
        props = { text = "0 °C" },
        style = { font_size = 14, color = "#AAAAAA" }
    })
    -- Tür
    screen_surface:element({
        id = "icon_main_door", type = "icon",
        rect = { unit = "px", x = 70, y = 110, w = 40, h = 40 },
        props = { icon_type = "prefab", name = prefab_name(devs.Door.prefab) },
    })
    screen_surface:element({ id = "lbl_main_door_status", type = "label",
        rect = { unit = "px", x = 130, y = 110, w = 100, h = 25 },
        props = { text = "Tür: " },
        style = { font_size = 14, color = "#FFFFFF" }
    })
    screen_surface:element({ id = "lbl_main_door_lock", type = "label",
        rect = { unit = "px", x = 130, y = 125, w = 100, h = 25 },
        props = { text = "0 °C" },
        style = { font_size = 14, color = "#AAAAAA" }
    })

    -- Temperature gauge
    screen_surface:element({ id = "gauge_main_temp", type = "gauge",
        rect = { unit = "px", x = 240, y = 100, w = 110, h = 70 },
        props = { value = 21, min = 0, max = 100, unit = "°C" },
    })

    -- Pressure gauge
    screen_surface:element({ id = "gauge_main_press", type = "gauge",
        rect = { unit = "px", x = 345, y = 100, w = 110, h = 70 },
        props = { value = 71, min = 0, max = 300, unit = " kPa" },
    })

    -- O2
    screen_surface:element({
        id = "icon_main_o2", type = "icon",
        rect = { unit = "px", x = 240, y = 30, w = 40, h = 40 },
        props = { name = ss.ui.icons.gas.Oxygen },
    })

    screen_surface:element({ 
        id = "lbl_main_o2", 
        type = "label",
        rect = { unit = "px", x = 240, y = 70, w = 40, h = 40 },
        props = { text = "0%" },
        style = { font_size = 14, color = "#22C55E", align = "center" }
    })

    -- N2
    screen_surface:element({
        id = "icon_main_n2", type = "icon",
        rect = { unit = "px", x = 290, y = 30, w = 40, h = 40 },
        props = { name = ss.ui.icons.gas.Nitrogen },
    })

    screen_surface:element({ 
        id = "lbl_main_n2", 
        type = "label",
        rect = { unit = "px", x = 290, y = 70, w = 40, h = 40 },
        props = { text = "0%" },
        style = { font_size = 14, color = "#22C55E", align = "center" }
    })

    -- CO2
    screen_surface:element({
        id = "icon_main_co2", type = "icon",
        rect = { unit = "px", x = 340, y = 30, w = 40, h = 40 },
        props = { name = ss.ui.icons.gas.CarbonDioxide },
    })

    screen_surface:element({ 
        id = "lbl_main_co2", 
        type = "label",
        rect = { unit = "px", x = 340, y = 70, w = 40, h = 40 },
        props = { text = "0%" },
        style = { font_size = 14, color = "#22C55E", align = "center" }
    })

    -- Pollutant
    screen_surface:element({
        id = "icon_main_x", type = "icon",
        rect = { unit = "px", x = 390, y = 30, w = 40, h = 40 },
        props = { name = ss.ui.icons.gas.Pollutant },
    })

    screen_surface:element({ 
        id = "lbl_main_x", 
        type = "label",
        rect = { unit = "px", x = 390, y = 70, w = 40, h = 40 },
        props = { text = "0%" },
        style = { font_size = 14, color = "#22C55E", align = "center" }
    })

    local table_W = 150
    -- Zone status table
    screen_surface:element({ id = "table_main_plants_1", type = "table",
        rect = { unit = "px", x = W - table_W * 2 - 30, y = 170, w = table_W, h = 290 },
        props = {
            columns = { "Topf", "Status", "" },
            rows = {},
            col_widths = { 1, 2, 1},
        },
        style = {
            header_bg = "#1E293B", header_color = "#94A3B8",
            row_bg = "#111827", alt_row_bg = "#0F172A",
            row_color = "#E2E8F0", font_size = 10, row_height = 10,
        },
    })

    screen_surface:element({ id = "table_main_plants_2", type = "table",
        rect = { unit = "px", x = W - table_W * 1 - 25, y = 170, w = table_W, h = 290 },
        props = {
            columns = { "Topf", "Status", "" },
            rows = {},
            col_widths = { 1, 2, 1},
        },
        style = {
            header_bg = "#1E293B", header_color = "#94A3B8",
            row_bg = "#111827", alt_row_bg = "#0F172A",
            row_color = "#E2E8F0", font_size = 10, row_height = 10,
        },
    })

    -- Larre-Icon
    screen_surface:element({
        id = "icon_main_larre", type = "icon",
        rect = { unit = "px", x = 20, y = 175, w = 60, h = 60 },
        props = { icon_type = "prefab", name = prefab_name(devs.Larre.prefab) },
    })

    screen_surface:element({ 
        id = "lbl_main_larre_mode", 
        type = "label",
        rect = { unit = "px", x = 20, y = 230, w = 100, h = 60 },
        props = { text = "Wartet" },
        style = { font_size = 12, color = "#FFFFFF", align = "left" }
    })

    screen_surface:commit()
end

-- ####################################################
-- TICK für Licht
-- ####################################################
function light_tick()

    local devs = Settings.Devices
    local light_state = ic.batch_read_name(devs.GL.prefab, devs.GL.name, LT.On, AVG);

    -- ------
    -- Licht schalten
    -- ------
    if Settings.light_current < Settings.light_on and light_state == 0 then

        print("[TASK: LIGHT] Schalte Licht ein")
        ic.batch_write_name(devs.GL.prefab, devs.GL.name, LT.On, 1)

    elseif Settings.light_current > Settings.light_on and Settings.light_current <= Settings.light_on + Settings.light_off and light_state == 1 then

        print("[TASK: LIGHT] Schalte Licht aus")
        ic.batch_write_name(devs.GL.prefab, devs.GL.name, LT.On, 0)

    elseif Settings.light_current > Settings.light_on + Settings.light_off then

        Settings.light_current = 0
        print("[TASK: LIGHT] Lichtzähler überschreitet maximum. Reset auf 0")

    end

    if light_state == 1 then
        screens.main.surface:get("lbl_main_gl_status"):set_props({text = "Licht: An"})
        screens.main.surface:get("lbl_main_gl_time"):set_props({text = tostring(Settings.light_on - Settings.light_current) .. "s"})
    elseif light_state == 1 then
        screens.main.surface:get("lbl_main_gl_status"):set_props({text = "Licht: Aus"})
        screens.main.surface:get("lbl_main_gl_time"):set_props({text = tostring(Settings.light_on + Settings.light_off - Settings.light_current) .. "s"})
    elseif light_state == 1 then
        screens.main.surface:get("lbl_main_gl_status"):set_props({text = "Licht: ERR"})
        screens.main.surface:get("lbl_main_gl_time"):set_props({text = "ERR"})
    end

    Settings.light_current = Settings.light_current + 1
    if(Settings.light_current > Settings.light_on + Settings.light_off) then
        Settings.light_current = 0
    end
end

-- ####################################################
-- TICK für Lüftung
-- ####################################################
local vent_mode = 0
function vent_tick() 

    local devs = Settings.Devices
    local temp = ic.batch_read_name(devs.GS.prefab, devs.GS.name, LT.Temperature, AVG)
    local press = ic.batch_read_name(devs.GS.prefab, devs.GS.name, LT.Pressure, AVG)
    local o2_ratio = ic.batch_read_name(devs.GS.prefab, devs.GS.name, LT.RatioOxygen, AVG)
    local n2_ratio = ic.batch_read_name(devs.GS.prefab, devs.GS.name, LT.RatioNitrogen, AVG)
    local co2_ratio = ic.batch_read_name(devs.GS.prefab, devs.GS.name, LT.RatioCarbonDioxide, AVG)  
    local door_open = ic.batch_read_name(devs.Door.prefab, devs.Door.name, LT.Open, SUM) == 1
     
    if not door_open then        
        if vent_mode == 0 then -- Nichts
            if press > Settings.press_max then 
                vent_mode = 1
            elseif press < Settings.press_min then
                vent_mode = 2
            elseif  (
                    n2_ratio < Settings.soll_n2 * (1 - Settings.gasabweichung) or 
                    co2_ratio < Settings.soll_co2 * (1 - Settings.gasabweichung)
                ) and
                temp > Settings.temp_min and temp < Settings.temp_max
            then
                vent_mode = 3
            else
                ic.batch_write_name(devs.AV_Waste.prefab, devs.AV_Waste.name, LT.On, 0)
                ic.batch_write_name(devs.AV_NewGas.prefab, devs.AV_NewGas.name, LT.On, 0)
            end
        elseif vent_mode == 1 then -- Gas Ablassen
            ic.batch_write_name(devs.AV_Waste.prefab, devs.AV_Waste.name, LT.On, 1)
            ic.batch_write_name(devs.AV_NewGas.prefab, devs.AV_NewGas.name, LT.On, 0)
            if press < press_mid then
                vent_mode = 0
            end
        elseif vent_mode == 2 then -- Gas Auffüllen
            ic.batch_write_name(devs.AV_Waste.prefab, devs.AV_Waste.name, LT.On, 0)
            ic.batch_write_name(devs.AV_NewGas.prefab, devs.AV_NewGas.name, LT.On, 1)
            if press > press_mid then
                vent_mode = 0
            end
        elseif vent_mode == 3 then -- Gas Umwelzen (Gemisch verbessern)
            ic.batch_write_name(devs.AV_Waste.prefab, devs.AV_Waste.name, LT.On, 1)
            ic.batch_write_name(devs.AV_NewGas.prefab, devs.AV_NewGas.name, LT.On, 1)
            if n2_ratio > Settings.soll_n2 and co2_ratio > Settings.soll_co2 then
                vent_mode = 0
            elseif temp < Settings.temp_min or temp > Settings.temp_max then
                vent_mode = 0
            elseif press < Settings.press_min then
                vent_mode = 2
            elseif press > Settings.press_max then
                vent_mode = 1
            end
        end
    else 
        ic.batch_write_name(devs.AV_Waste.prefab, devs.AV_Waste.name, LT.On, 0)
        ic.batch_write_name(devs.AV_NewGas.prefab, devs.AV_NewGas.name, LT.On, 0)
        vent_mode = 0
    end
end

-- ####################################################
-- TICK für Tür
-- ####################################################
function door_tick()

    local devs = Settings.Devices

    local door_open = ic.batch_read_name(devs.Door.prefab, devs.Door.name, LT.Open, SUM) == 1
        
    if door_open then
        screens.main.surface:get("lbl_main_door_status"):set_props({text = "Tür: Auf"})
    else
        screens.main.surface:get("lbl_main_door_status"):set_props({text = "Tür: Zu"})    
    end
    if door_locked then
        screens.main.surface:get("lbl_main_door_lock"):set_props({text = "Verriegelt"})
    else
        screens.main.surface:get("lbl_main_door_lock"):set_props({text = "Zugang frei"})    
    end
end

-- ####################################################
-- TICK für Klimaanlage
-- ####################################################
function ac_tick()

    local devs = Settings.Devices
    local door_open = ic.batch_read_name(devs.Door.prefab, devs.Door.name, LT.Open, SUM) == 1
    local temp = ic.batch_read_name(devs.GS.prefab, devs.GS.name, LT.Temperature, AVG)
    local press = ic.batch_read_name(devs.GS.prefab, devs.GS.name, LT.Pressure, AVG)

    -- ------
    -- AC
    -- ------
    -- Modus bestimmen
    local ac_mode = 0
    if ic.batch_read_name(devs.AC.prefab, devs.AC.name, LT.On, SUM) == 1 and ic.batch_read_name(devs.AC.prefab, devs.AC.name, LT.Mode, SUM) == 1 then
        if ic.batch_read_name(devs.AC.prefab, devs.AC.name, LT.Setting, SUM) < temp_mid then
            ac_mode = -1 -- Kühlen
        elseif ic.batch_read_name(devs.AC.prefab, devs.AC.name, LT.Setting, SUM) > temp_mid then
            ac_mode = 1 -- Heizen
        end
    end
    -- Anzeige aktualisieren
    if ac_mode == 1 then
        screens.main.surface:get("lbl_main_ac_status"):set_props({text = "AC: Heizen"})
        local diff = ic.batch_read_name(devs.AC.prefab, devs.AC.name, LT.TemperatureOutput, SUM) - ic.batch_read_name(devs.AC.prefab, devs.AC.name, LT.TemperatureInput, SUM)
        screens.main.surface:get("lbl_main_ac_temp"):set_props({text = "Diff.: " .. string.format("%.1f", diff) .. "°C"})
    elseif ac_mode == -1 then
        screens.main.surface:get("lbl_main_ac_status"):set_props({text = "AC: Kühlen"})
        local diff = ic.batch_read_name(devs.AC.prefab, devs.AC.name, LT.TemperatureInput, SUM) - ic.batch_read_name(devs.AC.prefab, devs.AC.name, LT.TemperatureOutput, SUM)
        screens.main.surface:get("lbl_main_ac_temp"):set_props({text = "Diff.: " .. string.format("%.1f", diff) .. "°C"})
    else
        screens.main.surface:get("lbl_main_ac_status"):set_props({text = "AC: Aus"})
        screens.main.surface:get("lbl_main_ac_temp"):set_props({text = "Diff.: -°C"})
    end
    -- Abschaltbedingungen
    if door_open or (ac_mode == 1 and temp > temp_mid) or (ac_mode == -1 and temp < temp_mid) then
        ic.batch_write_name(devs.AV_AC.prefab, devs.AV_AC.name, LT.On, 0)
        ic.batch_write_name(devs.AC.prefab, devs.AC.name, LT.On, 0)
        ac_mode = 0
    end
    -- Einschaltbedngungen
    if temp > Settings.temp_max and ac_mode ~= 1 and not door_open then
        ic.batch_write_name(devs.AC.prefab, devs.AC.name, LT.Setting, Settings.temp_min)
        ic.batch_write_name(devs.AC.prefab, devs.AC.name, LT.On, 1)
        ic.batch_write_name(devs.AC.prefab, devs.AC.name, LT.Mode, 1)
        ic.batch_write_name(devs.AV_AC.prefab, devs.AV_AC.name, LT.On, 1)
    elseif temp < Settings.temp_min and ac_mode ~= -1 and not door_open then
        ic.batch_write_name(devs.AC.prefab, devs.AC.name, LT.Setting, Settings.temp_max)
        ic.batch_write_name(devs.AC.prefab, devs.AC.name, LT.On, 1)
        ic.batch_write_name(devs.AC.prefab, devs.AC.name, LT.Mode, 1)
        ic.batch_write_name(devs.AV_AC.prefab, devs.AV_AC.name, LT.On, 1)
    end

end

-- ####################################################
-- TICK für Larre
-- ####################################################

local larre_mode_enums = { None = 0, Activateing = 1, Activated = 2, Moving = 3, Arrived = 4, PlantSeed = 5, Harvest = 6, Move = 7, Drop = 8, TakeIt = 9 }
local larre_workload = {}

function searchNextEmptyHD(current_pos)
    local pos = 9999
    local hydroponic_devices, hd_list = getHDs()

    for i, hd in ipairs(hd_list) do
        local o = ic.batch_read_slot_name(Settings.hash_hd, hd.hash, 0, LST.Occupied, AVG)
        if o == 0 then
            if math.abs((i + Settings.larre_hd_offset) - current_pos) < math.abs(pos - current_pos)  then
                pos = (i + Settings.larre_hd_offset)
            end
        end
    end

    return pos
end

function searchNextUnFertHD(current_pos)
    local pos = 9999
    local hydroponic_devices, hd_list = getHDs()

    for i, hd in ipairs(hd_list) do
        local o = ic.batch_read_slot_name(Settings.hash_hd, hd.hash, 1, LST.Occupied, AVG)
        if o == 0 then
            if math.abs((i + Settings.larre_hd_offset) - current_pos) < math.abs(pos - current_pos)  then
                pos = (i + Settings.larre_hd_offset)
            end
        end
    end

    return pos
end

function searchnextHarvestableHD(current_pos)
    local pos = 9999
    local hydroponic_devices, hd_list = getHDs()

    for i, hd in ipairs(hd_list) do
        local o = ic.batch_read_slot_name(Settings.hash_hd, hd.hash, 0, LST.Occupied, AVG)
        local g = ic.batch_read_slot_name(Settings.hash_hd, hd.hash, 0, LST.Growth, SUM)
        if o == 1 and g == 5 then
            if math.abs((i + Settings.larre_hd_offset) - current_pos) < math.abs(pos - current_pos)  then
                pos = (i + Settings.larre_hd_offset)
            end
        end
    end

    return pos
end

function getPlantInfo(current_pos)
    local pos = current_pos - Settings.larre_hd_offset
    local hydroponic_devices, hd_list = getHDs()
    local o = ic.batch_read_slot_name(Settings.hash_hd, hd_list[pos].hash, 0, LST.Occupied, AVG)
    local g = ic.batch_read_slot_name(Settings.hash_hd, hd_list[pos].hash, 0, LST.Growth, SUM)

    return o, g
end

function larre_tick_new()

    local devs = Settings.Devices

    local status = "Wartet"
    if #larre_workload > 0 then
        if larre_workload[#larre_workload].mode == larre_mode_enums.PlantSeed then
            status = "Pflanzen"
        elseif larre_workload[#larre_workload].mode == larre_mode_enums.Harvest then
            status = "Ernten"
        elseif larre_workload[#larre_workload].mode == larre_mode_enums.Drop then
            status = "Abwerfen"
        elseif larre_workload[#larre_workload].mode == larre_mode_enums.TakeIt then
            if larre_workload[#larre_workload].target_pos == Settings.larre_export_pos then
                status = "Saat aufnehmen"
            elseif larre_workload[#larre_workload].target_pos == Settings.larre_fert_pos then
                status = "Dünger aufnehmen"
            end
        elseif larre_workload[#larre_workload].mode == larre_mode_enums.Move then
            if larre_workload[#larre_workload].target_pos == Settings.larre_import_pos then
                status = "Fahre zur Abwurfstelle"
            elseif larre_workload[#larre_workload].target_pos == Settings.larre_export_pos then
                status = "Fahre zur Saatausgabe"
            elseif larre_workload[#larre_workload].target_pos == Settings.larre_fert_pos then
                status = "Fahre zur Düngerausgabe"
            else
                status = "Fahre zum Topf " .. larre_workload[#larre_workload].target_pos - Settings.larre_hd_offset
            end
        end
    end
    screens.main.surface:get("lbl_main_larre_mode"):set_props({text = status})

    local bin_import_has_items = ic.batch_read_slot_name(devs.Bin_Import.prefab, devs.Bin_Import.name, 0, LST.Occupied, AVG)
    if bin_import_has_items > 0 then
        ic.batch_write_name(devs.Bin_Import.prefab, devs.Bin_Import.name, LT.Open, 0)
    end

    -- Larre wartet auf nächte anweiseung   
    local idle = ic.batch_read_name(devs.Larre.prefab, devs.Larre.name, LT.Idle, AVG)
    local pos = ic.batch_read_name(devs.Larre.prefab, devs.Larre.name, LT.PositionX, AVG)
    local larre_has_items = ic.batch_read_slot_name(devs.Larre.prefab, devs.Larre.name, 0, LST.Occupied, AVG)
    local bin_seed_has_items = ic.batch_read_slot_name(devs.Bin_Export_Seed.prefab, devs.Bin_Export_Seed.name, 0, LST.Occupied, AVG)
    local bin_fert_has_items = ic.batch_read_slot_name(devs.Bin_Export_Fert.prefab, devs.Bin_Export_Fert.name, 0, LST.Occupied, AVG)

    if idle == 1 and #larre_workload == 0 then

        -- Larre hat Items im Greifarm
        if larre_has_items > 0 then

            local pf = ic.batch_read_slot_name(devs.Larre.prefab, devs.Larre.name, 0, LST.PrefabHash, AVG)

            -- Larre hat Saat im Greifarm
            if pf == Settings.hash_plant_seed then

                local next_pos = searchNextEmptyHD(pos)
                if next_pos < 9999 then
                    print("[LArRE] Pflanze vorhandene Saat bei " .. next_pos .." (Topf " .. next_pos - Settings.larre_hd_offset .. ")")
                    table.insert(larre_workload, { target_pos = next_pos, mode = larre_mode_enums.PlantSeed, sub_mode = larre_mode_enums.None})
                else
                    print("[LArRE] Werfe Item bei " .. Settings.larre_import_pos .." ab")
                    table.insert(larre_workload, { target_pos = Settings.larre_import_pos, mode = larre_mode_enums.Drop, sub_mode = larre_mode_enums.None})
                end
            -- Larre hat Pflanze im Greifarm
            elseif pf == Settings.hash_plant then
                
                if bin_seed_has_items > 0 then

                    print("[LArRE] Werfe Item bei " .. Settings.larre_import_pos .." ab")
                    table.insert(larre_workload, { target_pos = Settings.larre_import_pos, mode = larre_mode_enums.Drop, sub_mode = larre_mode_enums.None})

                else

                    local next_pos = searchNextEmptyHD(pos)
                    if next_pos < 9999 then
                        print("[LArRE] Pflanze vorhandene Frucht bei " .. next_pos .." (Topf " .. next_pos - Settings.larre_hd_offset .. ")")
                        table.insert(larre_workload, { target_pos = next_pos, mode = larre_mode_enums.PlantSeed, sub_mode = larre_mode_enums.None})
                    else
                        print("[LArRE] Werfe Item bei " .. Settings.larre_import_pos .." ab")
                        table.insert(larre_workload, { target_pos = Settings.larre_import_pos, mode = larre_mode_enums.Drop, sub_mode = larre_mode_enums.None})
                    end

                end

            -- Larre hat Dünger im Greifarm
            elseif pf == Settings.hash_fertilizer then

                local next_pos = searchNextUnFertHD(pos)
                if next_pos < 9999 then
                    print("[LArRE] Pflanze vorhandene Saat bei " .. next_pos .." (Topf " .. next_pos - Settings.larre_hd_offset .. ")")
                    table.insert(larre_workload, { target_pos = next_pos, mode = larre_mode_enums.PlantSeed, sub_mode = larre_mode_enums.None})
                else
                    print("[LArRE] Werfe Item bei " .. Settings.larre_import_pos .." ab")
                    table.insert(larre_workload, { target_pos = Settings.larre_import_pos, mode = larre_mode_enums.Drop, sub_mode = larre_mode_enums.None})
                end

            -- Larre hat irgendwas unbekanntes im Greifarm
            else
                print("[LArRE] Werfe Item bei " .. Settings.larre_import_pos .." ab")
                table.insert(larre_workload, { target_pos = Settings.larre_import_pos, mode = larre_mode_enums.Drop, sub_mode = larre_mode_enums.None})
            end
        -- Larres Greifarm ist leer
        else

            local next_pos = searchnextHarvestableHD(pos)
            if next_pos < 9999 then
                print("[LArRE] Ernte Pflanze bei " .. next_pos .." (Topf " .. next_pos - Settings.larre_hd_offset .. ")")
                table.insert(larre_workload, { target_pos = next_pos, mode = larre_mode_enums.Harvest, sub_mode = larre_mode_enums.None})
            else
                next_pos = searchNextEmptyHD(pos)
                if next_pos < 9999 and bin_seed_has_items > 0 then
                    print("[LArRE] Hole Saat bei " .. Settings.larre_export_pos .. " und Pflanze bei " .. next_pos .." (Topf " .. next_pos - Settings.larre_hd_offset .. ")")
                    table.insert(larre_workload, { target_pos = Settings.larre_export_pos, mode = larre_mode_enums.TakeIt, sub_mode = larre_mode_enums.None})
                    table.insert(larre_workload, { target_pos = next_pos, mode = larre_mode_enums.PlantSeed, sub_mode = larre_mode_enums.None})
                else
                    next_pos = searchNextUnFertHD(pos)
                    if next_pos < 9999 and bin_fert_has_items > 0 then
                        print("[LArRE] Hole Dünger bei " .. Settings.larre_fert_pos .. " und Pflanze bei " .. next_pos .." (Topf " .. next_pos - Settings.larre_hd_offset .. ")")
                        table.insert(larre_workload, { target_pos = Settings.larre_fert_pos, mode = larre_mode_enums.TakeIt, sub_mode = larre_mode_enums.None})
                        table.insert(larre_workload, { target_pos = next_pos, mode = larre_mode_enums.PlantSeed, sub_mode = larre_mode_enums.None})
                    else
                        print("[LArRE] Nicht zu tun")
                    end
                end
            end
        end

    elseif idle == 1 and #larre_workload > 0 then

        next_wl = larre_workload[#larre_workload];

        if next_wl.mode == larre_mode_enums.TakeIt then

            -- Position anfahren
            if next_wl.sub_mode == larre_mode_enums.None then
                
                print("[LArRE] TakeIt | Fahre zur Position " .. next_wl.target_pos)
                ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Setting, next_wl.target_pos)
                next_wl.sub_mode = larre_mode_enums.Moving

            -- Warten bis Position angefahren wurde
            elseif next_wl.sub_mode == larre_mode_enums.Moving then

                if idle == 1 and pos == next_wl.target_pos then
                    print("[LArRE] TakeIt | Position " .. next_wl.target_pos .. " erreicht")
                    next_wl.sub_mode = larre_mode_enums.Arrived
                elseif idle == 1 and pos ~= next_wl.target_pos then
                    print("[LArRE] TakeIt | Fahrt wurde unterbrochen. Versuche neustart zur Position" .. next_wl.target_pos)
                    ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Setting, next_wl.target_pos)
                end

            -- Aufnehmen
            elseif next_wl.sub_mode == larre_mode_enums.Arrived then

                print("[LArRE] TakeIt | Nehme auf")
                ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Activate, 1)
                next_wl.sub_mode = larre_mode_enums.Activateing

            -- Job beenden
            elseif next_wl.sub_mode == larre_mode_enums.Activateing then
                
                if idle == 1 then
                    print("[LArRE] TakeIt | Aufgenommen")
                    table.remove(larre_workload, #larre_workload)
                end

            end

        elseif next_wl.mode == larre_mode_enums.Drop then

            -- Position anfahren
            if next_wl.sub_mode == larre_mode_enums.None then
                
                print("[LArRE] Drop | Fahre zur Position " .. next_wl.target_pos)
                ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Setting, next_wl.target_pos)
                next_wl.sub_mode = larre_mode_enums.Moving

            -- Warten bis Position angefahren wurde
            elseif next_wl.sub_mode == larre_mode_enums.Moving then

                if idle == 1 and pos == next_wl.target_pos then
                    print("[LArRE] Drop | Position " .. next_wl.target_pos .. " erreicht")
                    next_wl.sub_mode = larre_mode_enums.Arrived
                elseif idle == 1 and pos ~= next_wl.target_pos then
                    print("[LArRE] Drop | Fahrt wurde unterbrochen. Versuche neustart zur Position" .. next_wl.target_pos)
                    ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Setting, next_wl.target_pos)
                end

            -- Abwerfen
            elseif next_wl.sub_mode == larre_mode_enums.Arrived then

                print("[LArRE] Drop | Werfe ab")
                ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Activate, 1)
                next_wl.sub_mode = larre_mode_enums.Activateing

            -- Job beenden
            elseif next_wl.sub_mode == larre_mode_enums.Activateing then

                if idle == 1 and larre_has_items > 0 then
                    print("[LArRE] Drop | Werfe erneut ab")
                    ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Activate, 1)
                    next_wl.sub_mode = larre_mode_enums.Activateing
                elseif idle == 1 and larre_has_items == 0 then
                    print("[LArRE] Drop | Alles abgeworfen")
                    table.remove(larre_workload, #larre_workload)
                end

            end

        elseif next_wl.mode == larre_mode_enums.Move then

            -- Position anfahren
            if next_wl.sub_mode == larre_mode_enums.None then
                
                print("[LArRE] Move | Fahre zur Position " .. next_wl.target_pos)
                ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Setting, next_wl.target_pos)
                next_wl.sub_mode = larre_mode_enums.Moving

            -- Warten bis Position angefahren wurde
            elseif next_wl.sub_mode == larre_mode_enums.Moving then

                if idle == 1 and pos == next_wl.target_pos then
                    print("[LArRE] Move | Position " .. next_wl.target_pos .. " erreicht")
                    next_wl.sub_mode = larre_mode_enums.Arrived
                    table.remove(larre_workload, #larre_workload)
                elseif idle == 1 and pos ~= next_wl.target_pos then
                    print("[LArRE] Move | Fahrt wurde unterbrochen. Versuche neustart zur Position" .. next_wl.target_pos)
                    ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Setting, next_wl.target_pos)
                end

            end

        elseif next_wl.mode == larre_mode_enums.PlantSeed then
            
            -- Position anfahren
            if next_wl.sub_mode == larre_mode_enums.None then
                
                print("[LArRE] Pflanzen | Fahre zur Position " .. next_wl.target_pos)
                ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Setting, next_wl.target_pos)
                next_wl.sub_mode = larre_mode_enums.Moving

            -- Warten bis Position angefahren wurde
            elseif next_wl.sub_mode == larre_mode_enums.Moving then

                if idle == 1 and pos == next_wl.target_pos then
                    print("[LArRE] Pflanzen | Position " .. next_wl.target_pos .. " erreicht")
                    next_wl.sub_mode = larre_mode_enums.Arrived
                elseif idle == 1 and pos ~= next_wl.target_pos then
                    print("[LArRE] Pflanzen | Fahrt wurde unterbrochen. Versuche neustart zur Position" .. next_wl.target_pos)
                    ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Setting, next_wl.target_pos)
                end

            -- Arm aktivieren
            elseif next_wl.sub_mode == larre_mode_enums.Arrived then
                
                print("[LArRE] Pflanzen | Setze Saat")
                ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Activate, 1)
                next_wl.sub_mode = larre_mode_enums.Activateing

            -- Job beenden
            elseif next_wl.sub_mode == larre_mode_enums.Activateing then

                if idle == 1 then

                    print("[LArRE] Pflanzen | Saat gesetzt")
                    next_wl.sub_mode = larre_mode_enums.Activated
                    table.remove(larre_workload, #larre_workload)

                end
            end

        elseif next_wl.mode == larre_mode_enums.Harvest then
            
            -- Position anfahren
            if next_wl.sub_mode == larre_mode_enums.None then
                
                print("[LArRE] Ernte | Fahre zur Position " .. next_wl.target_pos)
                ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Setting, next_wl.target_pos)
                next_wl.sub_mode = larre_mode_enums.Moving

            -- Warten bis Position angefahren wurde
            elseif next_wl.sub_mode == larre_mode_enums.Moving then

                if idle == 1 and pos == next_wl.target_pos then
                    print("[LArRE] Ernte | Position " .. next_wl.target_pos .. " erreicht")
                    next_wl.sub_mode = larre_mode_enums.Arrived
                elseif idle == 1 and pos ~= next_wl.target_pos then
                    print("[LArRE] Ernte | Fahrt wurde unterbrochen. Versuche neustart zur Position" .. next_wl.target_pos)
                    ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Setting, next_wl.target_pos)
                end

            -- Arm aktivieren
            elseif next_wl.sub_mode == larre_mode_enums.Arrived then
                
                print("[LArRE] Ernte | Sammle")
                ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Activate, 1)
                next_wl.sub_mode = larre_mode_enums.Activateing

            -- Job beenden
            elseif next_wl.sub_mode == larre_mode_enums.Activateing then

                if idle == 1 then

                    next_wl.sub_mode = larre_mode_enums.Activated

                    local o, g = getPlantInfo(pos)
                    local pf = ic.batch_read_slot_name(devs.Larre.prefab, devs.Larre.name, 0, LST.PrefabHash, AVG)

                    if pf == Settings.hash_plant_seed then

                        local next_pos = searchNextEmptyHD(pos)
                        if next_pos < 9999 then
                            print("[LArRE] Ernte | Pflanze Saat bei " .. next_pos .." (Topf " .. next_pos - Settings.larre_hd_offset .. ")")
                            next_wl.sub_mode = larre_mode_enums.Activateing
                            table.insert(larre_workload, { target_pos = next_wl.target_pos, mode = larre_mode_enums.Move, sub_mode = larre_mode_enums.None})
                            table.insert(larre_workload, { target_pos = next_pos, mode = larre_mode_enums.PlantSeed, sub_mode = larre_mode_enums.None})
                            return
                        else
                            print("[LArRE] Ernte | Ernte Pflanze erneut")
                            ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Activate, 1)
                            next_wl.sub_mode = larre_mode_enums.Activateing
                        end

                    elseif pf == Settings.hash_plant and o > 0 then

                        print("[LArRE] Ernte | Ernte Pflanze weiter")
                        ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Activate, 1)
                        next_wl.sub_mode = larre_mode_enums.Activateing

                    end

                    if o > 0 then
                        print("[LArRE] Ernte | Ernte entnommen, weiterernten")
                        ic.batch_write_name(devs.Larre.prefab, devs.Larre.name, LT.Activate, 1)
                        next_wl.sub_mode = larre_mode_enums.Activateing
                    else
                        print("[LArRE] Ernte | Ernten beendet")
                        table.remove(larre_workload, #larre_workload)
                    end

                end
            end
            
        end
    end

end

-- ####################################################
-- MAIN-TICK
-- ####################################################

--local accum = 0
function tick(dt)
    local devs = Settings.Devices
    
    for _, s in ipairs(screens) do
        if not s.loaded then
            return
        end
    end

    -- ------
    -- Anzeige von Gas, Temp und Druck
    -- ------
    local temp = ic.batch_read_name(devs.GS.prefab, devs.GS.name, LT.Temperature, AVG)
    local press = ic.batch_read_name(devs.GS.prefab, devs.GS.name, LT.Pressure, AVG)
    local o2_ratio = ic.batch_read_name(devs.GS.prefab, devs.GS.name, LT.RatioOxygen, AVG)
    local n2_ratio = ic.batch_read_name(devs.GS.prefab, devs.GS.name, LT.RatioNitrogen, AVG)
    local co2_ratio = ic.batch_read_name(devs.GS.prefab, devs.GS.name, LT.RatioCarbonDioxide, AVG)
    local x_ratio = ic.batch_read_name(devs.GS.prefab, devs.GS.name, LT.RatioPollutant, AVG)    

    screens.main.surface:get("lbl_main_o2"):set_props({ text = string.format("%.0f", o2_ratio*100) .. " %" })
    screens.main.surface:get("lbl_main_n2"):set_props({ text = string.format("%.0f", n2_ratio*100) .. " %" })
    screens.main.surface:get("lbl_main_co2"):set_props({ text = string.format("%.0f", co2_ratio*100) .. " %" })
    screens.main.surface:get("lbl_main_x"):set_props({ text = string.format("%.0f", x_ratio*100) .. " %" })

    screens.main.surface:get("gauge_main_temp"):set_props({ value = string.format("%.1f", temp - 273.15), min = Settings.temp_min - 273.15, max = Settings.temp_max - 273.15 })
    screens.main.surface:get("gauge_main_press"):set_props({ value = string.format("%.1f", press), min = Settings.press_min, max = Settings.press_max })

    -- ------
    -- Tabelle mit Pflanzen
    -- ------
    local rows1 = {}
    local rows2 = {}
    local hydroponic_devices, hd_list = getHDs()
    for i = 1, hydroponic_devices do
        local h = ic.batch_read_slot_name(Settings.hash_hd, hd_list[i].hash, 0, LST.Health, SUM)
        local g = ic.batch_read_slot_name(Settings.hash_hd, hd_list[i].hash, 0, LST.Growth, SUM)
        local e = ic.batch_read_slot_name(Settings.hash_hd, hd_list[i].hash, 0, LST.Efficiency, SUM)
        local q = ic.batch_read_slot_name(Settings.hash_hd, hd_list[i].hash, 0, LST.Quantity, SUM)
        local status, status1 = "", ""
        local color, color1 = "#000000", "#000000"

        if q == 0 then
            h = 0
            g = 0
            e = 0

            status = "No Plant"
            color = "#0000FF"

        else
            status = ""
            if g == 4 and h > 0 then
                status = "Fruit"
                color = "#44FF44"
            elseif g == 5 and h > 0 then
                status = "Seed"
                color = "#fc03d7"
            elseif h == 0 then
                status = "DEAD"
                color = "#EF4444"
            else
                status = "Growing"
                color = "#44FF44"
            end
        end 

        
        if q > 0 then
            if h < 0.5 then
                status1 = "LH"
                color1 = "#FFAA00"
            elseif e < 0.5 then
                status1 = "LE"
                color1 = "#FFAA00"
            elseif h < 1 then
                status1 = "H"
                color1 = "#BBBB00"
            end
        end
        
        if #larre_workload > 0 then
            if larre_workload[#larre_workload].target_pos - Settings.larre_hd_offset == i then
                status = "**** " .. status
                --color = "#34ebe5"
            end
        end
            
        if i <= 27 then
            rows1[i] = { 
                tostring(i),
                { 
                    text = status, 
                    style = { color = color } 
                },
                { 
                    text = status1, 
                    style = { color = color1 } 
                } 
            }
        else
            rows2[i-27] = { 
                tostring(i),
                { 
                    text = status, 
                    style = { color = color } 
                },
                { 
                    text = status1, 
                    style = { color = color1 } 
                } 
            }
        end
    end

    screens.main.surface:get("table_main_plants_1"):set_props({ rows = rows1 })
    screens.main.surface:get("table_main_plants_2"):set_props({ rows = rows2 })

    screens.main.surface:commit()
    sleep(0.2)
end

-- ####################################################
-- Abschluss
-- ####################################################

-- Menüs bauen
buildDevices()
buildSettings()
buildMain()

-- Timer starten
initDevices()
ic.timer.every(1, light_tick)
ic.timer.every(0.5, vent_tick)
ic.timer.every(0.5, door_tick)
ic.timer.every(0.5, ac_tick)
ic.timer.every(1, larre_tick_new)

-- Hauptmenü aktivieren
ss.ui.activate("main")