-- WKA Steuermodul
-- Version 1.0
-- Copyright(C) 2024 by Tobias Uhle (TU1)

--======================================================
-- !!! ACHTUNG !!! CAUTION !!! ATTENTION !!! UWAGA !!!
-- Änderungen im nachfolgenden Code können zu Fehlern führen, für die keine Haftung übernommen wird!
-- Changes in the following code can lead to errors for which no liability is accepted!
-- Toute modification du code ci-dessous peut entrainer des erreurs pour lesquelles nous declinons toute responsabilite !
-- Zmiany w ponizszym kodzie moga prowadzic do bledow, za ktore nie ponosimy odpowiedzialnosci!
--======================================================

-- SPRACHE

function WKA_ErmittleEEPSprache()
	-- Determine EEP language / Déterminer la langue EEP
	for zeile in io.lines(".\\eep.lng") do
		if (string.sub(zeile, 0, 12) == "IDS_LANGUAGE") then
			if (string.sub(zeile, string.len(zeile) - 4) == "\"GER\"") then
				return "GER"
			elseif (string.sub(zeile, string.len(zeile) - 4) == "\"ENG\"") then
				return "ENG"
			elseif (string.sub(zeile, string.len(zeile) - 4) == "\"FRA\"") then
				return "FRA"
			end
		end
	end
	print([[Konnte EEPSprache nicht ermitteln!
	Could not determine EEP language! All further messages in German!
	Impossible de determiner la langue EEP ! Tous les autres messages sont en allemand !]])
	return nil
end
local Sprache = EEPLng or WKA_ErmittleEEPSprache()

-- WINDSTAERKE

local Windstaerke = WKA_Windstaerke or 0  -- Mittelwert der Windstaerke von 0 (windstill) bis 10 (Sturm)
local Windstaerke_Sig = WKA_Windstaerke_Sig or -1  -- Mittelwert der Windstaerke ueber Zaehelersignal (10) einstellen
local Windstaerke_Varianz = WKA_Windstaerke_Varianz or 0 -- Varianz der Windstärke zwischen 0 und 3 in Schritten von 0.1

-- WINDRICHTUNG

local Windrichtung = WKA_Windrichtung or 0  -- Mittelwert der Windrichtung von 0 bis 360 Grad, 0 Grad ist (aktuell noch) rechter Anlagenrand
local Windrichtung_Sig = WKA_Windrichtung_Sig or -1	-- Mittelwert der Windrichtung ueber Zaehelersignal (40) einstellen
local Windrichtung_Varianz = WKA_Windrichtung_Varianz or 0 -- Varianz der Windrichtung zwischen 0 und 180 Grad in Schritten von 1

-- ENERGIEBEDARF

local Energiebedarf = WKA_Energiebedarf or 0  -- Mittelwert des Energiebedarfs von 0 (niedrig) bis 10 (hoch)
local Energiebedarf_Sig = WKA_Energiebedarf_Sig or -1	-- Mittelwert des Energiebedarfs ueber Zaehelersignal (10) einstellen
local Energiebedarf_Varianz = WKA_Energiebedarf_Varianz or 0 -- Varianz des Energiebedarfs zwischen 0 und 5 in Schritten von 0.1

-- WINDRAD-LISTE

local Windraeder = WKA_Windraeder or {} 

-- SOUNDMODUL-LISTE

local Soundmodule = WKA_Soundmodule or {}
-- Extra-Infos

local extra_info = WKA_extra_info or false



-- VORVERARBEITUNG

math.randomseed(os.time())

local blink_interval = 75
local gondel_interval = 50
local energie_interval = 3000 -- Langes Intervall wichtig!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
local windstaerke_interval = 2500 -- Langes Intervall wichtig!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
local windrichtung_interval = 2750 -- Langes Intervall wichtig!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
local ziel_interval = 2
local sound_interval = 6
local cur_windrichtung = Windrichtung
local cur_energiebedarf = Energiebedarf
local cur_windstaerke = Windstaerke

local untere_Windgrenze = 2

local counter_blink = blink_interval
local counter_gondel = 0
local counter_energie = energie_interval
local counter_windstaerke = windstaerke_interval
local counter_windrichtung = windrichtung_interval
local WKA_cnt = 1
local counter_ziel = 1
local counter_sound = sound_interval

-- DEBUG-MODUS
WKA_debug = false

-- Grenzen der Windstaerken setzen
if Windstaerke < 0 then
	Windstaerke = 0
elseif Windstaerke > 10 then 
	Windstaerke = 10
end
if Windstaerke_Varianz < 0 then
	Windstaerke_Varianz = 0
elseif Windstaerke_Varianz > 3 then 
	Windstaerke_Varianz = 3
end

-- Grenzen des Energiebedarfs setzen
if Energiebedarf < 0 then
	Energiebedarf = 0
elseif Energiebedarf > 10 then 
	Energiebedarf = 10
end
if Energiebedarf_Varianz < 0 then
	Energiebedarf_Varianz = 0
elseif Energiebedarf_Varianz > 5 then 
	Energiebedarf_Varianz = 5
end

-- Grenzen der Windrichtung setzen
if Windrichtung < 0 then
	Windrichtung = 0
elseif Windrichtung > 360 then 
	Windrichtung = 360
end
if Windrichtung_Varianz < 0 then
	Windrichtung_Varianz = 0
elseif Windrichtung_Varianz > 180 then 
	Windrichtung_Varianz = 180
end

--SPRACHVARIABLEN

local lang_Modul_ver = "V1.0"
local lang_init, lang_getset, lang_bind_windr, lang_bind_energie, lang_bind_winds
local lang_energieverteilt, lang_energv,lang_windst, lang_windr1, lang_windr2
local lang_WKA_winddrehen1, lang_WKA_winddrehen2, lang_WKA_starten, lang_WKA_stoppen
local lang_Windr_eingest, lang_Energie_eingest, lang_Windst_eingest
local lang_EEP15, lang_EEP16, lang_keineWKA1, lang_keineWKA2, lang_undefiniert1, lang_undefiniert2, lang_keinWinkel1, lang_keinWinkel2
local Blink_Achsname = "System_Blink"
local Drehzahl_Achsname, Gondel_Achsname, Blattstellung_Achsname, Blattbiegung_Achsname
local Sound_RefAchse_Rotor = "08_RPM"
local Sound_RefAchse_Maschine

if Sprache == "ENG" then

	Drehzahl_Achsname = "Speed"
	Gondel_Achsname = "Nacelle orientation"
	Blattstellung_Achsname = "Blade position"
	Blattbiegung_Achsname = "Blade bending"
	Sound_RefAchse_Maschine = "Operating_noise"
	
	lang_Modul_ver = "Wind turbine control module "..lang_Modul_ver
	lang_init = " turbines found. Module initialised"
	lang_getset = "Getter and setter methods generated"
	lang_bind_windr = "Wind direction bound to signal "
	lang_bind_energie = "Energy requirement bound to signal "
	lang_bind_winds = "Wind strength bound to signal "
	lang_WKA_winddrehen1 = "Rotate turbine "
	lang_WKA_winddrehen2 = " into the wind"
	lang_WKA_starten = "Starting turbine "
	lang_WKA_stoppen = "Stopping turbine "
	lang_energv = "Distribute the energy demand to the turbines. Calculated value including the variance: "
	lang_energieverteilt = "Turbines are set as follows:"
	lang_windst = "Create a new wind strength. Calculated value including the variance: "
	lang_windr1 = "Create a new wind direction. Calculated value including the variance: "
	lang_windr2 = " degrees"
	lang_EEP15 = "EEP version is less than 16.1, use the angle data of the turbines from the list"
	lang_EEP16 = "EEP version is greater than 16.1, get the angle data of the turbines directly from EEP"
	lang_Windr_eingest = "Average value of the wind direction specified: "
	lang_Energie_eingest = "Average value of the energy demand specified: "
	lang_Windst_eingest = "Mean value of the wind strength specified: "
	lang_keineWKA1 = "WARNING: Model "
	lang_keineWKA2 = " is no wind turbine!"
	lang_undefined1 = "WARNING: Model "
	lang_undefined2 = " was not entered with complete Lua names!"
	lang_Sound_kein_Windrad1 = "WARNING: Registered sound module "
	lang_Sound_kein_Windrad2 = " could not be assigned to a windmill!"
	lang_Soundmodul_gehoert1 = "Sound module "
	lang_Soundmodul_gehoert2 = " belongs to wind turbine "
	lang_Soundmodul_gehoert3 = " and has the type "
	lang_Sound_kein_Modul1 = "WARNING: Registered model "
	lang_Sound_kein_Modul2 = " is not a suitable sound module!"
	lang_keinWinkel1 = "WARNING: For the wind turbine "
	lang_keinWinkel2 = " no angle was entered!"

elseif Sprache == "FRA" then

	Drehzahl_Achsname = "Vitesse de rotation"
	Gondel_Achsname = "Orientation de la nacelle"
	Blattstellung_Achsname = "Position des feuilles"
	Blattbiegung_Achsname = "Courbure de la feuille"
	Sound_RefAchse_Maschine = "Bruit_de_fonctionnement"
	
	lang_Modul_ver = "Module de controle de l'eolienne "..lang_Modul_ver
	lang_init = " WKAs trouve. Module initialise."
	lang_getset = "Methodes Getter et Setter generees"
	lang_bind_windr = "Direction du vent liee au signal"
	lang_bind_energie = "Besoin en energie lie au signal "
	lang_bind_winds = "Force du vent liee au signal "
	lang_WKA_winddrehen1 = "Faire tourner la turbine"
	lang_WKA_winddrehen2 = "dans le vent"
	lang_WKA_starten = "Demarrer WKA "
	lang_WKA_stoppen = "Arreter WKA"
	lang_energv = "Distribuer la demande d'energie aux WKA. Valeur calculee incluant la variance : "
	lang_energieverteilt = "Les installations sont reglees comme suit :"
	lang_windst = "Creer une nouvelle force de vent. Valeur calculee, y compris la variance : "
	lang_windr1 = "Creer une nouvelle direction du vent. Valeur calculee avec la variance : "
	lang_windr2 = " degres "
	lang_EEP15 = "La version EEP est inferieure a 16.1, utiliser les donnees d'angle des WKA de la liste"
	lang_EEP16 = "La version de l'EEP est superieure a 16.1, obtenir les donnees angulaires des WKA directement a partir de l'EEP"
	lang_Windr_eingest = "Valeur moyenne de la direction du vent specifiee: "
	lang_Energie_eingest = "Valeur moyenne de la demande d'energie specifiee: "
	lang_Windst_eingest = "Valeur moyenne de la force du vent specifiee: "
	lang_keineWKA1 = "AVERTISSEMENT: Modele "
	lang_keineWKA2 = " n'est pas une eolienne!"
	lang_undefiniert1 = "AVERTISSEMENT : Modele "
	lang_undefiniert2 = " n'a pas ete enregistre avec le nom Lua complet !"
	lang_Sound_kein_Windrad1 = "AVERTISSEMENT: Module sonore enregistre "
	lang_Sound_kein_Windrad2 = " n'a pas pu etre attribue a une eolienne!"
	lang_Soundmodul_gehoert1 = "Module sonore "
	lang_Soundmodul_gehoert2 = " associe a une eolienne "
	lang_Soundmodul_gehoert3 = " et a le type "
	lang_Sound_kein_Modul1 = "AVERTISSEMENT: Modele enregistre "
	lang_Sound_kein_Modul2 = " n'est pas un module sonore correspondant!"
	lang_keinWinkel1 = "AVERTISSEMENT : Pour l'eolienne "
	lang_keinWinkel2 = " aucun angle n'a ete saisi!"

elseif Sprache == "POL" then

	Drehzahl_Achsname = "Predkosc"
	Gondel_Achsname = "Wyrownanie gondoli"
	Blattstellung_Achsname = "Pozycja liscia"
	Blattbiegung_Achsname = "Zginanie lisci"
	Sound_RefAchse_Maschine = "Halas_podczas_pracy"
	
	lang_Modul_ver = "Modul sterowania turbina wiatrowa "..lang_Modul_ver
	lang_init = " Znaleziono WKA. Modul zainicjowany."
	lang_getset = "Wygenerowano metody pobierajace i ustawiajace"
	lang_bind_windr = "Kierunek wiatru powiazany z sygnalem "
	lang_bind_energie = "Zapotrzebowanie na energie powiazane z sygnalem "
	lang_bind_winds = "Sila wiatru powiazana z sygnalem"
	lang_WKA_winddrehen1 = "Obroc turbine"
	lang_WKA_winddrehen2 = "do wiatru"
	lang_WKA_starten = "Uruchom WKA "
	lang_WKA_stoppen = "Zatrzymaj WKA "
	lang_energv = "Rozdziel zapotrzebowanie na energie do WKA. Obliczona wartosc z uwzglednieniem wariancji: "
	lang_energieverteilt = "Rosliny sa ustawione w nastepujacy sposob:"
	lang_windst = "Utworz nowa sile wiatru. Obliczona wartosc z uwzglednieniem wariancji: "
	lang_windr1 = "Utworz nowy kierunek wiatru. Obliczona wartosc wraz z wariancja: "
	lang_windr2 = " stopni"
	lang_EEP15 = "Wersja EEP jest mniejsza niz 16.1, uzyj danych kata WKA z listy"
	lang_EEP16 = "Wersja EEP jest wieksza niz 16.1, pobierz dane katowe WKA bezposrednio z EEP"
	lang_Windr_eingest = "Srednia wartosc okreslonego kierunku wiatru: "
	lang_Energie_eingest = "Srednia wartosc okreslonego zapotrzebowania na energie: "
	lang_Windst_eingest = "Okreslona srednia wartosc sily wiatru: "
	lang_keineWKA1 = "OSTRZEZENIE: Model "
	lang_keineWKA2 = " nie jest modelem WKA!"
	lang_undefined1 = "OSTRZEZENIE: Model "
	lang_undefined2 = " nie zostal wprowadzony z pelnymi nazwami Lua!"
	lang_Sound_kein_Windrad1 = "OSTRZEZENIE: Modulem dzwiekowym model "
	lang_Sound_kein_Windrad2 = " nie mozna przypisac do wiatraka!"
	lang_Soundmodul_gehoert1 = "Modul dzwiekowy "
	lang_Soundmodul_gehoert2 = " nalezy do turbiny wiatrowej "
	lang_Soundmodul_gehoert3 = " i ma typ "
	lang_Sound_kein_Modul1 = "OSTRZEZENIE: Zarejestrowany model "
	lang_Sound_kein_Modul2 = " nie jest odpowiednim modulem dzwiekowym!"
	lang_keinWinkel1 = "OSTRZEZENIE: Dla turbiny wiatrowej "
	lang_keinWinkel2 = " nie wprowadzono kata!"

else

	Drehzahl_Achsname = "Drehzahl"
	Gondel_Achsname = "Gondelausrichtung"
	Blattstellung_Achsname = "Blattstellung"
	Blattbiegung_Achsname = "Blattbiegung"
	Sound_RefAchse_Maschine = "Betriebsgeraeusch"

	lang_Modul_ver = "WKA-Steuermodul "..lang_Modul_ver
	lang_init = " WKAs gefunden. Modul initialisiert."
	lang_getset = "Getter- und Setter-Methoden erzeugt"
	lang_bind_windr = "Windrichtung gebunden an Signal "
	lang_bind_energie = "Energiebedarf gebunden an Signal "
	lang_bind_winds = "Windstaerke gebunden an Signal "
	lang_WKA_winddrehen1 = "Drehe WKA "
	lang_WKA_winddrehen2 = " in den Wind"
	lang_WKA_starten = "Starte WKA "
	lang_WKA_stoppen = "Stoppe WKA "
	lang_energv = "Verteile den Energiebedarf auf die WKAs. Berechnerter Wert mit Einbezug der Varianz: "
	lang_energieverteilt = "WKAs werden wie folgt eingestellt:"
	lang_windst = "Erzeuge eine neue Windstaerke. Berechneter Wert mit Einbezug der Varianz: "
	lang_windr1 = "Erzeuge eine neue Windrichtung. Berechneter Wert mit Einbezug der Varianz: "
	lang_windr2 = " Grad"
	lang_EEP15 = "EEP-Version ist kleiner 16.1, nutze die Winkeldaten der WKAs aus der Liste"
	lang_EEP16 = "EEP-Version ist groesser 16.1, hole die Winkeldaten der WKAs direkt aus EEP"
	lang_Windr_eingest = "Mittelwert der Windrichtung vorgegeben: "
	lang_Energie_eingest = "Mittelwert des Energiebedarfs vorgegeben: "
	lang_Windst_eingest = "Mittelwert der Windstaerke vorgegeben: "
	lang_keineWKA1 = "WARNUNG: Modell "
	lang_keineWKA2 = " ist keine WKA!"
	lang_undefiniert1 = "WARNUNG: Modell "
	lang_undefiniert2 = " wurde nicht mit komplettem Lua-Namen eingetragen!"
	lang_Sound_kein_Windrad1 = "WARNUNG: Eingetragenes Soundmodul "
	lang_Sound_kein_Windrad2 = " konnte keinem Windrad zugeordnet werden!"
	lang_Soundmodul_gehoert1 = "Soundmodul "
	lang_Soundmodul_gehoert2 = " gehoert zu Windrad "
	lang_Soundmodul_gehoert3 = " und hat den Typ "
	lang_Sound_kein_Modul1 = "WARNUNG: Eingetragenes Modell "
	lang_Sound_kein_Modul2 = " ist kein passendes Soundmodul!"
	lang_keinWinkel1 = "WARNUNG: Fuer das Windrad "
	lang_keinWinkel2 = " wurde kein Winkel eingetragen!"

end

-- MAXIMALDREHZAHL LISTE

local Max_Drehzahl = {

{"E-33",39},
{"E-40",38},
{"E-58",24},
{"E-82",18},
{"E-101",14.5},
{"V25",44},
{"V47",28.5},
{"V80",19},
{"V112",17.7},
{"N27",40},
{"N43",26.9},
{"N62",19.2},
{"N117",13.2}

}

local Soundmodul_Drehzahlliste = {"04","05","06","07","08","09","10","11","12","13","15","17","19","21","23","25","28","31","34","37","40","43"}
local Soundmodul_Drehzahlliste_num = {4,5,6,7,8,9,10,11,12,13,15,17,19,21,23,25,28,31,34,37,40,43}

-- EEP-Versions-Check. Wenn EEP > 16.1, dann hole Winkelwerte direkt aus den Modellwerten

if EEPStructureGetRotation ~= nil then
	print(lang_Modul_ver..": "..lang_EEP16)
	for loop = 1,#Windraeder do
		local dummy,dummy,dummy,rot = EEPStructureGetRotation(Windraeder[loop][1]) -- Funktion exisitert erst sei EEP 16.1
		if rot < 0 then rot = rot + 360 end		-- Konvertieren von -180/180 auf 0/360
		Windraeder[loop][2] = math.floor(rot)
	end	
else
	print(lang_Modul_ver..": "..lang_EEP15)
	for loop = 1,#Windraeder do
		local rot = Windraeder[loop][2]
		if rot == nil then
			print(lang_Modul_ver..": "..lang_keinWinkel1..Windraeder[loop][1]..lang_keinWinkel2)
			Windraeder[loop][2] = 0
		else
			if rot < 0 then rot = rot + 360 end		-- Konvertieren von -180/180 auf 0/360
			Windraeder[loop][2] = math.floor(rot)
		end
	end
end

-- Zaehlersignale ans Skript koppeln

if Windstaerke_Sig > 0 then

	EEPRegisterSignal(Windstaerke_Sig)
	
	_ENV["EEPOnSignal_"..Windstaerke_Sig] = function()	-- Funktion für Windstärke
		Windstaerke = EEPGetSignal(Windstaerke_Sig)-1
		if Windstaerke > 10 then
			Windstaerke = 10
		end
		print(lang_Modul_ver..": "..lang_Windst_eingest..Windstaerke)
		counter_windstaerke = windstaerke_interval-50	-- Counter für Windstaerke kurz vor Ablauf setzen
		
		if Windstaerke - Windstaerke_Varianz <= untere_Windgrenze then	-- Wenn Untere Windgrenze unterschritten werden koennte
			counter_energie = energie_interval-55	-- Counter für Energieberechnung kurz vor Ablauf setzen
		elseif cur_windstaerke < untere_Windgrenze then
			counter_energie = energie_interval-55
		end
		
	end
	
	Windstaerke = EEPGetSignal(Windstaerke_Sig)-1
	if Windstaerke > 10 then
		Windstaerke = 10
	end
	
	print(lang_Modul_ver..": "..lang_bind_winds..Windstaerke_Sig)
	
end

if Energiebedarf_Sig > 0 then

	EEPRegisterSignal(Energiebedarf_Sig)
	
	_ENV["EEPOnSignal_"..Energiebedarf_Sig] = function()	-- Funktion für Energiebedarf
		Energiebedarf = EEPGetSignal(Energiebedarf_Sig)-1
		if Energiebedarf > 10 then
			Energiebedarf = 10
		end
		print(lang_Modul_ver..": "..lang_Energie_eingest..Energiebedarf)
		counter_energie = energie_interval-50	-- Counter für Energieberechnung kurz vor Ablauf setzen
	end
	
	Energiebedarf = EEPGetSignal(Energiebedarf_Sig)-1
	if Energiebedarf > 10 then
		Energiebedarf = 10
	end
	
	print(lang_Modul_ver..": "..lang_bind_energie..Energiebedarf_Sig)

end

if Windrichtung_Sig > 0 then

	EEPRegisterSignal(Windrichtung_Sig)
	
	_ENV["EEPOnSignal_"..Windrichtung_Sig] = function()	-- Funktion für Windrichtung
		Windrichtung = (EEPGetSignal(Windrichtung_Sig)-1)*10
		if Windrichtung > 350 then
			Windrichtung = 350
		end
		print(lang_Modul_ver..": "..lang_Windr_eingest..Windrichtung)
		counter_windrichtung = windrichtung_interval-50	-- Counter für Windrichtung kurz vor Ablauf setzen
	end
	
	Windrichtung = (EEPGetSignal(Windrichtung_Sig)-1)*10
	if Windrichtung > 350 then
		Windrichtung = 350
	end
	
	print(lang_Modul_ver..": "..lang_bind_windr..Windrichtung_Sig)

end

-- Get Set Blattstellung

function getBlattstellung(id) -- 0 bis 100 %
	empty, erg = EEPStructureGetAxis(id,Blattstellung_Achsname)
	return erg
end

function getBlattstellung_Anim(id)
	empty, erg = EEPStructureIsAxisAnimate(id,Blattstellung_Achsname) -- Funktion gibt 0 bis 100
	return erg
end

function AnimBlattstellung(id,wert) -- 0 bis 100%
	EEPStructureAnimateAxis(id,Blattstellung_Achsname,wert)
end

-- Get Set Gondel

function getGondel_Anim(id)
	empty, erg = EEPStructureIsAxisAnimate(id,Gondel_Achsname)
	return erg
end

function getGondel(id) -- 0 bis 360 Grad
	empty, erg = EEPStructureGetAxis(id,Gondel_Achsname) -- Funktion gibt 0 bis 100
	return erg * 3.6
end

function AnimGondel(id,wert) -- 0 bis 360 Grad in 0.5 Grad
	EEPStructureAnimateAxis(id,Gondel_Achsname,(wert*2))
end

-- Get Set Drehzahl

function getDrehzahl_Anim(id)
	empty, erg = EEPStructureIsAxisAnimate(id,Drehzahl_Achsname)
	return erg
end

function getDrehzahl(id) -- 0 bis 100 %
	is, erg = EEPStructureGetAxis(id,Drehzahl_Achsname) -- Funktion gibt 0 bis 100
	return is, erg
end

function AnimDrehzahl(id,wert) -- 0 bis 100% in 0.5%
	EEPStructureAnimateAxis(id,Drehzahl_Achsname,(wert*2))
end

print(lang_Modul_ver..": "..lang_getset)

-- STATI INITIALISIEREN

local Windradstatus = {}
local Windradstatus_Ziel = {}
local Windrad_Drehzahlen = {}
local Windrad_Umrechungsreferenzen = {}

local WKA_cnt_init = 0

for loop = 1,#Windraeder do

	local Blattstellung = getBlattstellung(Windraeder[loop][1])
	local Gondelstellung = getGondel(Windraeder[loop][1])
	local isWKA, Drehzahl = getDrehzahl(Windraeder[loop][1])
	local Gondel_Anim = getGondel_Anim(Windraeder[loop][1])
	
	if isWKA then
	
		WKA_cnt_init = WKA_cnt_init + 1
	
		if Gondel_Anim == 0 and Blattstellung == 0 then -- Windrad aus, wenn Gondel fest und Blaetter in Fahnenstellung
			Windradstatus[loop] = "aus"
		elseif Gondel_Anim > 0 and Blattstellung == 0 then	-- Gondel dreht, wenn Gondel in Bewegung und Blaetter in Fahnenstellung
			Windradstatus[loop] = "gondel_drehen"
		elseif Blattstellung > 0 or Drehzahl > 2 then	-- Windrad an, wenn Drehzahl > 2 oder Blaetter gepitcht
			Windradstatus[loop] = "an"
		else
			Windradstatus[loop] = "an"
		end
		
		Windradstatus_Ziel[loop] = Windradstatus[loop]
		Windrad_Drehzahlen[loop] = Drehzahl
	else
	
		print(lang_Modul_ver..": "..lang_keineWKA1..Windraeder[loop][1]..lang_keineWKA2)
		
		Windradstatus_Ziel[loop] = "nichts"
		Windradstatus[loop] = "nichts"
		Windrad_Drehzahlen[loop] = 0
	end
	
	local umrechnungsreferenz = 32
	
	local isdefined = false
	
	for m = 1,#Max_Drehzahl do
		if string.match(Windraeder[loop][1],"_"..Max_Drehzahl[m][1]) then
			--print("Nutze Daten von WKA "..Max_Drehzahl[m][1])
			umrechnungsreferenz = Max_Drehzahl[m][2]
			isdefined = true
			break
		end
	end
	
	if isdefined == false then
		print(lang_Modul_ver..": "..lang_undefiniert1..Windraeder[loop][1]..lang_undefiniert2)
	end
	
	Windrad_Umrechungsreferenzen[loop] = umrechnungsreferenz
	
end

-- ZUORDNUNG DER SOUNDMODULE ZU DEN WINDRAEDERN

local Windradpos = {}
local Soundmodul_Zugeh = {}
local Soundmodul_Drehzahlen = {}
local Soundmodul_Drehzahlen_String = {}

-- Positionen und Drehzahlen der Windraeder auflisten

for loop = 1,#Windraeder do

	local dummy,x,y,dummy = EEPStructureGetPosition(Windraeder[loop][1])
	Windradpos[loop] = {x,y}
	
end

-- Positionen der Soundmodule auslesen und schauen, welches Windrad im Radius von 5 Metern steht.

for loop = 1,#Soundmodule do

	local dummy,sx,sy,dummy = EEPStructureGetPosition(Soundmodule[loop])
	
	Soundmodul_Zugeh[loop] = {0,"keiner"}
	
	for w = 1,#Windradpos do
	
		local wx = Windradpos[w][1]
		local wy = Windradpos[w][2]
		
		if math.sqrt(math.abs(sx-wx)^2 + math.abs(sy-wy)^2) <= 5 then
			
			
			-- Checken, welche Art von Soundmodul das ist
			local erg,dummy = EEPStructureGetAxis(Soundmodule[loop],Sound_RefAchse_Rotor)
			local typ = "keiner"
			if erg == true then
				typ = "rotor"
			end
			local erg,dummy = EEPStructureGetAxis(Soundmodule[loop],Sound_RefAchse_Maschine.."_1")
			if erg == true then
				typ = "maschine"
			end
			
			if typ == "keiner" then
				print(lang_Modul_ver..": "..lang_Sound_kein_Modul1.."\""..Soundmodule[loop].."\""..lang_Sound_kein_Modul2)
			end
			
			Soundmodul_Zugeh[loop] = {w,typ}
			
			print(lang_Modul_ver..": "..lang_Soundmodul_gehoert1.."\""..Soundmodule[loop].."\""..lang_Soundmodul_gehoert2.."\""..Windraeder[w][1].."\""..lang_Soundmodul_gehoert3.."\""..typ.."\"")
			
			break
		end
	end
	
	local akt_drehz = 0
	local akt_drehz_string = "00"
	
	if Soundmodul_Zugeh[loop][2] == "rotor" then
	
		for d = 1,#Soundmodul_Drehzahlliste do
			
			local dummy, erg = EEPStructureIsAxisAnimate(Soundmodule[loop],Soundmodul_Drehzahlliste[d].."_RPM")
			
			if erg == 1 then
				akt_drehz = Soundmodul_Drehzahlliste_num[d]
				akt_drehz_string = Soundmodul_Drehzahlliste[d]
				break
			end
			
		end
		
	elseif Soundmodul_Zugeh[loop][2] == "maschine" then
	
		for d = 1,3 do
		
			local dummy, erg = EEPStructureGetAxis(Soundmodule[loop],Sound_RefAchse_Maschine.."_"..d)
			
			if erg == 100 then
				akt_drehz = d
				akt_drehz_string = "" .. d
				break
			end
			
		end
	
	end
	
	if Soundmodul_Zugeh[loop][1] == 0 then
		print(lang_Modul_ver..": "..lang_Sound_kein_Windrad1.."\""..Soundmodule[loop].."\""..lang_Sound_kein_Windrad2)
	end
	
	Soundmodul_Drehzahlen[loop] = akt_drehz
	Soundmodul_Drehzahlen_String[loop] = akt_drehz_string
	
	if WKA_debug == true then print("Aktuelle Drehzahl: "..akt_drehz) end
	
end

print(lang_Modul_ver..": "..WKA_cnt_init..lang_init)
print(lang_Modul_ver..": ==============================================")

--======================================================

-- FUNKTIONEN

function WKA_Ausfuehren()	-- Hauptroutine, muss in EEPMain aufgerufen werden

	-- Blink
	if counter_blink >= blink_interval then
		WKA_Sync_Blink()
		counter_blink = 0
	end
	counter_blink = counter_blink + 1
	
	-- Windstaerke festlegen
	if counter_windstaerke >= windstaerke_interval then
	
		WKA_Windstaerke_festlegen()
		counter_windstaerke = 0
	end
	counter_windstaerke = counter_windstaerke + 1
	
	-- Windrichtung festlegen
	if counter_windrichtung >= windrichtung_interval then
	
		WKA_Windrichtung_festlegen()
		counter_windrichtung = 0
	end
	counter_windrichtung = counter_windrichtung + 1
	
	-- Zielverfolgung
	if counter_ziel == ziel_interval then
	
		if #Windraeder > 0 then
			WKA_Zielverfolgung(WKA_cnt)
		end
		WKA_cnt = WKA_cnt + 1
		counter_ziel = 1
	
	else
		counter_ziel = counter_ziel + 1
	end
	
	if WKA_cnt > #Windraeder then WKA_cnt = 1 end
	
	-- Energieverteilung und Ziellisten-Erstellung
	if counter_energie >= energie_interval then
	
		WKA_Energie_verteilen()
		counter_energie = 0
	end
	counter_energie = counter_energie + 1
	
	-- Windrichtung 
	if counter_gondel >= gondel_interval then -- or cur_windrichtung ~= Windrichtung then
		--cur_windrichtung = Windrichtung	
		WKA_Windrichtung_nachfuehren()
		counter_gondel = 0
	end
	counter_gondel = counter_gondel + 1
	
	-- Soundmodule
	if counter_sound >= sound_interval then	
		WKA_Soundmodule_einstellen()
		counter_sound = 0
	end
	counter_sound = counter_sound + 1
	
	
end

--======================================================

function WKA_Sync_Blink()	-- Blinken synchronisieren

	local anz_blink = 0
	local cur_blinks = {}
				
	for loop = 1,#Windraeder do	-- 

		local is, val = EEPStructureGetAxis(Windraeder[loop][1],"System_Blink")
		val = math.floor(val*100)/100
		
		if is then	-- nur zaehlen, wenn WKA ein Blinklicht hat
			cur_blinks[loop] = val
			anz_blink = anz_blink + 1
		else
			cur_blinks[loop] = -1
		end

	end
	
	-- fuer jede vorhandene Achsstellung die Anzahl der Vertretungen auflisten
	local freq = {}
	for _, v in ipairs(cur_blinks) do
		if v > 0 then
			freq[v] = (freq[v] or 0) + 1
		end
	end
	
	-- Achsstellung herausfinden, die am meisten vertreten ist
	local maximum = 0
	local axis_goal = 0
	
	for x,y in pairs(freq) do
		if y > maximum then
			maximum = y
			axis_goal = x
		end
	end
	
	-- wenn es Windraeder gibt, die sich von der Mehrzahl unterscheiden, alle Achsen neu setzen
	if maximum ~= anz_blink then
		for x = 1,#Windraeder do
			EEPStructureSetAxis(Windraeder[x][1],"System_Blink",axis_goal)
		end
	end
end

function WKA_Windrichtung_nachfuehren()	-- Windnachfuehrung der Gondel

	if WKA_debug == true then print("aktuelle Windrichtung: "..cur_windrichtung) end

	for loop = 1,#Windraeder do
		-- Nur ausgefuehrt, wenn das Windrad an ist und die Gondel steht
		if Windradstatus[loop] ~= "aus" and Windradstatus_Ziel[loop] ~= "aus" and getGondel_Anim(Windraeder[loop][1]) == 0 then
		
			local akt_ausr = (getGondel(Windraeder[loop][1]) + Windraeder[loop][2]) % 360
			local ziel_diff = 0
			
			akt_diff = math.abs(cur_windrichtung - akt_ausr)	-- Differenz ausrechnen
			if akt_diff > 180 then	-- Auf Kreis beschraenken
				akt_diff = 360 - akt_diff
			end
						
			local aendern = false
			local ziel = 0
			
			-- bei zu grosser Differenz oder wenn die Gondel gedreht werden muss
			if akt_diff > 5.5 or Windradstatus[loop] == "gondel_drehen_anf" then
				if WKA_debug == true then  print("forced") end
				ziel = cur_windrichtung + generateRandom(-5,5,0.5)	-- Zufaelligen Wert addieren, Schrittweite 0.5
				aendern = true
			elseif generateRandom(0,1,1) == 0 then	-- Zufaellig, wenn eigentlich nicht noetig
				if WKA_debug == true then print("random") end
				ziel = cur_windrichtung + generateRandom(-5,5,0.5)	-- Zufaelligen Wert addieren, Schrittweite 0.5
				aendern = true
			end
			
			if aendern then
				if ziel < 0 then ziel = ziel + 360 end	-- Ziel auf 0 bis 360 beschraenken
				
				if ziel >= 0 then
					ziel_diff = math.min(360 - math.abs(ziel - akt_ausr),math.abs(akt_ausr - ziel))	-- kleinsten Weg zum Ziel errechnen
					
					if (akt_ausr + ziel_diff) % 360 ~= ziel then	-- Pruefen, ob positiv oder negativ gedreht werden muss
						ziel_diff = -ziel_diff
					end
				end
				
				ziel_diff = math.floor(ziel_diff*2)/2	-- Differenz auf 0 bis 720 umrechnen
				
			end
			
			if ziel_diff ~= 0 or Windradstatus[loop] == "gondel_drehen_anf" then	-- Gondel drehen
				--print("Windrad "..loop.." Zieldifferenz: "..ziel_diff)
				AnimGondel(Windraeder[loop][1],ziel_diff)
				if Windradstatus[loop] == "gondel_drehen_anf" then Windradstatus[loop] = "gondel_drehen" end
			end
		end
	end
end

function WKA_Energie_verteilen()	-- Energiebedarf aufteilen

	if WKA_debug == true then print("Status-Ziel-Liste vorher: " .. table.concat(Windradstatus_Ziel,",")) end
	cur_energiebedarf = Energiebedarf + generateRandom(-Energiebedarf_Varianz,Energiebedarf_Varianz,0.1)	-- Energiebedarf randomisieren
	
	if cur_energiebedarf < 0 or cur_windstaerke < untere_Windgrenze then cur_energiebedarf = 0 end	-- Bedarf auf 0 bis 10 beschraenken
	if cur_energiebedarf > 10 then cur_energiebedarf = 10 end
	
	if extra_info == true then print(lang_Modul_ver..": "..lang_energv..(cur_energiebedarf*10).."%") end
	
	-- Energiebedarf auf Anlagenzahl umrechnen
	
	local an_need = math.floor((#Windraeder * (cur_energiebedarf/10)) + 0.9)	-- Damit Bedarf auf jeden Fall gedeckt ist, 0.9 aufaddieren
	
	local an_cnt = 0
	
	local Liste_An = {}
	local i_an = 1
	local Liste_Aus = {}
	local i_aus = 1
	
	for loop = 1,#Windradstatus_Ziel do
		if Windradstatus_Ziel[loop] ~= "aus" then	-- WKAs mit dem Ziel "aus" zaehlen und auflisten
			an_cnt = an_cnt + 1
			Liste_An[i_an] = loop
			i_an = i_an + 1
		else										-- WKAs mit dem Ziel "an" zaehlen und auflisten
			Liste_Aus[i_aus] = loop
			i_aus = i_aus + 1
		end
	end
	
	-- Bedarf mit ist-Bestand vergleichen
	
	if an_need < an_cnt then	-- Mehr an, als noetig -> WKAs abschalten
		for loop = 1,(an_cnt-an_need) do	-- so viele WKAs wie nötig
			local rnd = generateRandom(1,#Liste_An,1)	-- Zufaellige angeschaltete WKA waehlen
			Windradstatus_Ziel[Liste_An[rnd]] = "aus"	
			
			for i = rnd,#Liste_An-1 do					-- gerade ausgeschaltete Anlage aus der Liste entfernen
				Liste_An[i] = Liste_An[i+1]
			end
			
			Liste_An[#Liste_An] = nil 	
		end
		
	elseif an_need > an_cnt then	-- Weniger an, als noetig -> WKAs einschalten
		for loop = 1,(an_need - an_cnt) do	-- so viele WKAs wie nötig
			local rnd = generateRandom(1,#Liste_Aus,1)	-- Zufaellige ausgeschaltete WKA waehlen
		
			Windradstatus_Ziel[Liste_Aus[rnd]] = "an"
			
			for i = rnd,#Liste_Aus-1 do					-- gerade angeschaltete Anlage aus der Liste entfernen 
				Liste_Aus[i] = Liste_Aus[i+1]
			end
			Liste_Aus[#Liste_Aus] = nil 
		
		end
	end
	
	if extra_info == true then 
		print(lang_Modul_ver..": "..lang_energieverteilt)
		for i = 1,#Windradstatus_Ziel do
			print(lang_Modul_ver..": "..Windraeder[i][1]..": "..Windradstatus_Ziel[i])
		end
	end

	if WKA_debug == true then print("Status-Ziel-Liste nachher: " .. table.concat(Windradstatus_Ziel,",")) end
end

function WKA_Windstaerke_festlegen() -- Windstaerke aus Varianz und Vorgabe festlegen und auf 0 bis 10 begrenzen

	cur_windstaerke = Windstaerke + generateRandom(-Windstaerke_Varianz,Windstaerke_Varianz,0.1)
	if cur_windstaerke < 0 then cur_windstaerke = 0 end
	if cur_windstaerke > 10 then cur_windstaerke = 10 end
	if WKA_debug == true then print("Windstaerke festgelegt auf "..cur_windstaerke) end
	if extra_info == true then print(lang_Modul_ver..": "..lang_windst..cur_windstaerke) end
end

function WKA_Windrichtung_festlegen() -- Windrichtung aus Varianz und Vorgabe festlegen und auf 0 bis 360 Grad begrenzen

	cur_windrichtung = Windrichtung + generateRandom(-Windrichtung_Varianz,Windrichtung_Varianz,0.5)
	if cur_windrichtung < 0 then cur_windrichtung = cur_windrichtung + 360 end
	if cur_windrichtung > 360 then cur_windrichtung = cur_windrichtung - 360 end
	if WKA_debug == true then print("Windrichtung festgelegt auf "..cur_windrichtung) end
	if extra_info == true then print(lang_Modul_ver..": "..lang_windr1..cur_windrichtung..lang_windr2) end
end

function WKA_Zielverfolgung(id)	-- Ablauf der WKAs steuern

	-- Wichtige Daten auslesen

	local name = Windraeder[id][1]
	local status = Windradstatus[id]
	local statusziel = Windradstatus_Ziel[id]
	local blattstellung_anim = getBlattstellung_Anim(name)
	local blattstellung = getBlattstellung(name)
	local drehzahl_anim = getDrehzahl_Anim(name)
	local isWKA, drehzahl = getDrehzahl(name)
	local gondel_anim = getGondel_Anim(name)
	
	-- Aktuelle Drehzahl in die Drehzahlliste fuer Soundmodule eintragen
	Windrad_Drehzahlen[id] = drehzahl
	
	if isWKA then
	
		if WKA_debug == true then 
			print("blattstellung_anim: "..blattstellung_anim)
			print("blattstellung: "..blattstellung)
			print("drehzahl_anim: "..drehzahl_anim)
			print("drehzahl: "..drehzahl)
			print("gondel_anim: "..gondel_anim)
			
			print("status: "..status)
			print("statusziel"..statusziel)
		end

		if status == "aus" and statusziel == "an" then	-- Wenn IST ausgeschaltet und SOLL eingeschaltet
				
			if extra_info == true then print(lang_Modul_ver..": "..lang_WKA_winddrehen1..name..lang_WKA_winddrehen2) end
			if WKA_debug == true then print(name..": Gondel in Wind drehen") end
			status = "gondel_drehen_anf"

		elseif status == "gondel_drehen" and gondel_anim == 0 then	-- Wenn gedreht wurde

			AnimBlattstellung(name,50) -- Blatt 50% reinpitchen
			
			local diff = math.floor(60*(cur_windstaerke/10)-(drehzahl*2))/2		-- 30% der Drehzahl aus Windstaerke berechnen
			
			AnimDrehzahl(name,diff)
			
			if extra_info == true then print(lang_Modul_ver..": "..lang_WKA_starten..name) end
			if WKA_debug == true then print(name..": Anlaufen") end
			status = "anlaufen"
			
		elseif status == "anlaufen" and drehzahl_anim == 0 and blattstellung_anim == 0 then		-- Wenn angelaufen

			AnimBlattstellung(name,50) -- Blatt voll reinpitchen
			
			local diff = math.floor(200*(cur_windstaerke/10)-(drehzahl*2))/2	-- finale Drehzahl aus Windstaerke berechnen
			
			AnimDrehzahl(name,diff)

			if WKA_debug == true then print(name..": pitch_in") end
			status = "pitch_in"
			
		elseif status == "pitch_in" and drehzahl_anim == 0 and blattstellung_anim == 0 then		-- Wenn fertig gepitcht, Anlage auf "an" setzen

			if WKA_debug == true then print(name..": Eingeschaltet") end
			status = "an"
			
		elseif status == "an" and statusziel == "an" and drehzahl_anim == 0 and cur_windstaerke >= untere_Windgrenze then -- Drehzahl im Betrieb veraendern

			-- Wenn Drehzahl zu stark abweicht oder zufaellig
			if generateRandom(0,math.floor(150/#Windraeder),1) == 0 or drehzahl < cur_windstaerke*10 - 2 or drehzahl > cur_windstaerke*10 + 2  then

				if WKA_debug == true then print(name..": variiere Drehzahl") end
				
				if blattstellung < 95 then	-- Blattstellung immer auf maximum halten
					AnimBlattstellung(name,100)
				end
				
				local ziel = 200*(cur_windstaerke/10) + generateRandom(-4,4,1)	-- Zufaellige neue Drehzahl berechnen
				
				local diff = math.floor(ziel-(drehzahl*2))/2
				
				if diff ~= 0 then
				
					AnimDrehzahl(name,diff)
				
				end
			end
			
		elseif status == "an" and statusziel == "aus" and drehzahl_anim == 0 then	-- Wenn IST eingeschaltet und SOLL ausgeschaltet 

			if extra_info == true then print(lang_Modul_ver..": "..lang_WKA_stoppen..name) end
			if WKA_debug == true then print(name..": pitch_out") end
			
			local diff = 0
			if cur_windstaerke > 1 then		-- Wenn Wind > 1 direkt ins Trudeln uebergehen
				local ziel = generateRandom(1,3,1)
				diff = math.floor(ziel-(drehzahl*2))/2
			else	-- ansonsten bis zum Stillstand ausschalten
				diff = -200
			end
			
			AnimDrehzahl(name,diff)
			AnimBlattstellung(name,-100)	-- Blaetter herauspitchen
			EEPStructureSetAxis(name, Blattbiegung_Achsname, 0)
			
			status = "pitch_out"
			
		elseif status == "pitch_out" and drehzahl_anim == 0 and blattstellung_anim == 0 then	-- Wenn Ausschalten abgeschlossen

			if WKA_debug == true then print(name..": ausgeschaltet") end
			status = "aus"
			
		elseif status == "aus" and statusziel == "aus" and drehzahl_anim == 0 and generateRandom(0,3,1) == 3 then

			if cur_windstaerke > 1 then		-- Wenn Wind stark genug, Trudeln simulieren
			
				if WKA_debug == true then print(name..": Trudeln") end
			
				local ziel = generateRandom(1,3,1)	-- Trudeln zwischen 0.5 und 1.5% Drehzahl halten
				
				local diff = math.floor(ziel-(drehzahl*2))/2
				
				if diff ~= 0 then
				
					AnimDrehzahl(name,diff)
				
				end
			else	-- Wenn Wind zu schwach, Drehzahl auf 0
				AnimDrehzahl(name,-10)
			end
		end

		-- Regelung der Biegung der Rotorblätter, nur wenn Ziel "an" ist und Anlagen nicht im Pitch_out
		if statusziel == "an" and status ~= "pitch_out" then
			if drehzahl < 20 then
				EEPStructureSetAxis(name, Blattbiegung_Achsname, 0)
			elseif drehzahl > 70 then 
				EEPStructureSetAxis(name, Blattbiegung_Achsname, 100)
			else
				EEPStructureSetAxis(name, Blattbiegung_Achsname, 50)
			end
		end

		-- neu gesetzen Status in die Stati-Liste schreiben

		Windradstatus[id] = status
	else
		
		print(lang_Modul_ver..": "..lang_keineWKA1..Windraeder[id][1]..lang_keineWKA2)
	
	end
end

-- Soundmodul_Zugeh= {WindradID,Typ}
-- Soundmodul_Drehzahlen
-- Soundmodul_Drehzahlen_String
-- Windrad_Drehzahlen

function WKA_Soundmodule_einstellen()
	for id = 1,#Soundmodule do	
		if Soundmodul_Zugeh[id][1] > 0 then -- nur, wenn Soundmodul einem Windrad zugeordnet wurde
		
			local WKA_id = Soundmodul_Zugeh[id][1]
			local cur_windraddrehzahl = Windrad_Drehzahlen[WKA_id]

			-- Drehzahl des Windrads auf den Windradtypen umrechnen
						
			local cur_reale_drehzahl = (cur_windraddrehzahl/100)*Windrad_Umrechungsreferenzen[WKA_id]
			
			-- SOUND ERST AB WINDSTAERKE 2 ABSPIELEN
			
			if Soundmodul_Zugeh[id][2] == "rotor" then -- Fuer Rotorsoundmodule
			
				local zieldrehzahl = 0
				local zieldrehzahl_string = "0"
				
				-- Herausfinden, welche Drehzahl benoetigt wird
				if cur_windstaerke > 2 then
					for d = #Soundmodul_Drehzahlliste_num,1,-1 do
						if cur_reale_drehzahl > Soundmodul_Drehzahlliste_num[d] then
							zieldrehzahl = Soundmodul_Drehzahlliste_num[d]
							zieldrehzahl_string = Soundmodul_Drehzahlliste[d]
							break
						end
					end
				end
				
				if zieldrehzahl ~= Soundmodul_Drehzahlen[id] then
				
					if WKA_debug == true then print("aendere Zieldrehzahl des Soundmoduls") end
					
					
					EEPStructureAnimateAxis(Soundmodule[id],Soundmodul_Drehzahlen_String[id].."_RPM",1)
					EEPStructureAnimateAxis(Soundmodule[id],zieldrehzahl_string.."_RPM",1000)
					
					
					Soundmodul_Drehzahlen_String[id] = zieldrehzahl_string
					Soundmodul_Drehzahlen[id] = zieldrehzahl
				end
			elseif Soundmodul_Zugeh[id][2] == "maschine" then -- Fuer Maschinensoundmodule
			
				local zieldrehzahl = 0
				local zieldrehzahl_string = "0"
				
				-- Herausfinden, welche Drehzahl benoetigt wird
				if cur_windraddrehzahl < 3 then
					if Soundmodul_Drehzahlen[id] ~= 0 then
						if WKA_debug == true then print("aus") end
						
						zieldrehzahl = 0
						zieldrehzahl_string = "0"
						
						EEPStructureSetAxis(Soundmodule[id],Sound_RefAchse_Maschine.."_"..Soundmodul_Drehzahlen_String[id],0)
						
						Soundmodul_Drehzahlen_String[id] = zieldrehzahl_string
						Soundmodul_Drehzahlen[id] = zieldrehzahl
					end
				elseif cur_windraddrehzahl < 33 then
					if Soundmodul_Drehzahlen[id] ~= 1 then
						if WKA_debug == true then print("Stufe 1") end
						
						zieldrehzahl = 1
						zieldrehzahl_string = "1"
						
						EEPStructureSetAxis(Soundmodule[id],Sound_RefAchse_Maschine.."_"..Soundmodul_Drehzahlen_String[id],0)
						EEPStructureSetAxis(Soundmodule[id],Sound_RefAchse_Maschine.."_"..zieldrehzahl_string,100)
						
						Soundmodul_Drehzahlen_String[id] = zieldrehzahl_string
						Soundmodul_Drehzahlen[id] = zieldrehzahl
					end
				elseif cur_windraddrehzahl < 66 then
					if Soundmodul_Drehzahlen[id] ~= 2 then
						if WKA_debug == true then print("Stufe 2") end
						
						zieldrehzahl = 2
						zieldrehzahl_string = "2"
						
						EEPStructureSetAxis(Soundmodule[id],Sound_RefAchse_Maschine.."_"..Soundmodul_Drehzahlen_String[id],0)
						EEPStructureSetAxis(Soundmodule[id],Sound_RefAchse_Maschine.."_"..zieldrehzahl_string,100)
						
						Soundmodul_Drehzahlen_String[id] = zieldrehzahl_string
						Soundmodul_Drehzahlen[id] = zieldrehzahl
					end
				else
					if Soundmodul_Drehzahlen[id] ~= 3 then
						if WKA_debug == true then print("Stufe 3") end
						
						zieldrehzahl = 3
						zieldrehzahl_string = "3"
						
						EEPStructureSetAxis(Soundmodule[id],Sound_RefAchse_Maschine.."_"..Soundmodul_Drehzahlen_String[id],0)
						EEPStructureSetAxis(Soundmodule[id],Sound_RefAchse_Maschine.."_"..zieldrehzahl_string,100)
						
						Soundmodul_Drehzahlen_String[id] = zieldrehzahl_string
						Soundmodul_Drehzahlen[id] = zieldrehzahl
					end
				end
			end
		end
	end
end

-- Zufallswert mit Schrittweite generieren
function generateRandom(first, last, stepSize)
    local maxSteps = math.floor((last-first)/stepSize)
    return first + stepSize * math.random(0, maxSteps)
end

WKA_Sync_Blink()