# Berechnung des 1. Advent mit CoDeSys 2.3.9.x



## guwen (21 November 2011)

Hallo zusammen,
meine herzallerliebst Frau möchte pünktlich zum 1. Advent die Weihnachtsdeko-Beleutung in Gang bringen.
Hat jemand schon mal die Berechnung des Datums des 1. Advent eines jeden Jahres programmiert und könnte es mir (für CoDeSys 2.3.9.x) zur Verfügung stellen?

Danke euch,
Gruß
Guwen


----------



## uncle_tom (21 November 2011)

hab ich zwar nicht fertig - aber einen Lösungsansatz hätte ich:

In der Oscat-Lib gibt´s die Funktion "DAY_OF_WEEK", damit kannst du für ein beliebiges Datum den Wochentag (Mo=1, So=7) ermitteln.
Mit dieser Funktion ermittelst du dann den Wochentag für den 24. Dezember.
Mit dieser Info kannst du dann ja das Datum  für den 1. Advent ausrechnen - du musst halt entsprechend des Wochentages die jeweilige Anzahl an Tagen zurückrechnen.

Noch ein Tipp:
Wenn der 24. Dezember ein Sonntag ist, dann ist dieser Tag auch gleichzeit der 4. Advent.

Link zur Oscat-Lib http://www.oscat.de


----------



## Rudi (21 November 2011)

Ich wundere mich immer was mancher für Zeit hat sich mit solchen Problemen rumzuschlagen.
Möchte auch mal die grüne Langeweile haben.


----------



## Larry Laffer (22 November 2011)

@Rudi:
Das war übrigens ein blöder Kommentar ...
Für mich ist dieses ein Problem wie jedes andere auch - Uncle_Tom hat den Lösungsansatz ja auch schon schön erklärt.

Gruß
Larry


----------



## Rudi (22 November 2011)

Larry Laffer schrieb:


> @Rudi:
> Das war übrigens ein blöder Kommentar ...
> Für mich ist dieses ein Problem wie jedes andere auch - Uncle_Tom hat den Lösungsansatz ja auch schon schön erklärt.
> 
> ...



Ich wollte eben auch mal einen blöder Kommentar abgeben


----------



## good_mike (22 November 2011)

*hab da letzes Jahr mal was programmiert....*

Hallo,

habe mich letzetes Jahr auch mal an das "Problem" gesetzt. Natürlich kann man das auch über manuelles Ein-/Ausschalten lösen, aber ich habe das auch zu Übungszwecken gemacht. Sicher gibt es hier auch noch Optimierungspotential.



```
PROGRAM Weihnachtsbeleuchtung
VAR
 Einschaltdatum:BOOL;
 Date_ein: DATE;
 Date_aus: DATE;
 x2512JJ:SDT;
 x0601JJ: SDT;
 Ein_abend: BOOL;
 Ein_morgen: BOOL;
 Ausschaltzeit_abend: TOD;
 R_TRIG_Ein_abend: R_TRIG;
 Weihnachstbeleuchtung_Ein: BOOL;
 ErsterEinSamstag: BOOL;

END_VAR
 

(*
Funktionsbeschreibung:
Die Weihnachstbeleuchtung wird in der Zeit vom Samstag abend vor dem 1. Advent bis zum Sonntag nach dem 06. Januar betrieben.
Sie wird  20 Minunten nach Sonnenuntergang eingeschaltet, um 22:00 Uhr ausgeschaltet und um 06:00 Uhr eingeschaltet und 20Minuten vor 
Sonnenaufgang ausgeschaltet.
Besonderheiten: Am 24.12, 25.12 und 31.12. brennt die Beleuchtung die ganze Nacht durch.
*)

(* Füllen der SDT-Struktur mit dem 25.12.[aktuelles Jahr]*)
x2512JJ.DAY:=25;
x2512JJ.MONTH:=12;
x2512JJ.YEAR:=Kalender.YEAR;
(* Füllen der SDT-Struktur mit dem 06.01.[aktuelles Jahr]*)
x0601JJ.DAY:=06;
x0601JJ.MONTH:=01;
x0601JJ.YEAR:=L_TimeSTD.YEAR;
(*Berechnung des Samstag's vor dem 1. Advent : Berechnung des Wochentages des 25.12 (1-7). *)
Date_ein:=DATE_ADD(SDT_TO_DATE(x2512JJ),-(DAY_OF_WEEK(SDT_TO_DATE(x2512JJ))+22),0,0,0);
(*Berechung des 1. Sonntag's nach dem 6. Januar: *)
Date_aus:=DATE_ADD(SDT_TO_DATE(x0601JJ),+7-(DAY_OF_WEEK(SDT_TO_DATE(x0601JJ))),0,0,0);
(* Datum Periode in der die Beleuchtung ein sein soll*)
Einschaltdatum:=PERIOD(Date_ein, Kalender.LDATE, Date_aus);
(* Generierung einer BOOL Variable um festzustellen ob es sich momentan um des Samstag vor dem 1. Advendt handelt.
An diesemTag soll die Beleuchtung nur abends und nicht morgens eingeschaltet werden*)
IF Kalender.LDATE = Date_ein THEN
 ErsterEinSamstag:= TRUE;
ELSE
 ErsterEinSamstag:= FALSE;
END_IF;
(* Im Moment des Einschaltens am Abend die Ausschaltzeit für die folgende Nacht festlegen: an besonderen Tagen (24. /25.12. u. 01.01.) wird die Ausschaltzeit auf 20 min
vor Sonnenaufgang am nächsten Morgen festgelegt. Ansonsten wir zu einer fixen Zeit (22:00 Uhr) ausgeschaltet*)
R_TRIG_Ein_abend(CLK:=Ein_abend , Q=> );
IF R_TRIG_Ein_abend.Q = TRUE THEN
 IF L_TimeSTD.MONTH = 12 AND (L_TimeSTD.DAY = 24 OR L_TimeSTD.DAY=25 OR L_TimeSTD.DAY = 31) THEN
  Ausschaltzeit_abend:=Kalender.SUN_RISE;
 ELSE
  Ausschaltzeit_abend:=TOD#22:00;
 END_IF;
END_IF;
(* Ein-Zeit morgens: 6:00 Uhr  Sonnenaufgang*)
Ein_morgen:=TIMECHECK(Kalender.LTOD, TOD#06:00, Kalender.SUN_RISE);
(* Ein-Zeit abend: Sonnenuntergang  bis berechnete Ausschaltzeit*)
Ein_abend:=TIMECHECK(Kalender.LTOD,Kalender.SUN_SET, Ausschaltzeit_abend);
Weihnachstbeleuchtung_Ein:= Einschaltdatum AND ((Ein_morgen AND NOT ErsterEinSamstag) OR Ein_abend);
DO_Weihnachtsbeleuchtung:=Weihnachstbeleuchtung_Ein;
```


----------



## guwen (22 November 2011)

Danke schön an good_mike und uncle_tom,
uncle_tom: Der Tipp mit der Oscat und dem DAY_OF_WEEK hat mich auf die entscheidende Idee gebracht.
good_mike: So als NewBee muss ich mir das erst einmal in Ruhe zu gemüte führen. Das sieht aber toll aus.

Die eigentliche Weihnachtsbeleuchtung hatte ich schon fertig, hier nun (dank eurer Hilfe) mein geistiger Erguss:

FUNCTION Advent : STRING
VAR_INPUT
END_VAR
VAR
 WeekDay: STRING;  (* Tag der Woche, an dem Heiligabend ist *)
 XMasDate : INT;     (* Tage vor Weihnachten *)
(* Wobei YearJJJJ separat definiert ist, und einfach eine 4-Stellige Jahresangabe beinhaltet *)
END_VAR

WeekDay :=CONCAT (INT_TO_STRING(YearJJJJ()),'-12-24');
XMasDate := 21 + DAY_OF_WEEK(STRING_TO_DATE(CONCAT('d#',weekday)));
Advent := DATE_TO_STRING(DATE_ADD(STRING_TO_DATE(CONCAT('d#',weekday)),-XMasDate,1,1,-1));


Mein einziges Problem war zum Schluss: Ich verstehe das DATE_ADD nicht:
Eigentlich sollte es doch DATE_ADD(Datum, tag, woche, monat, jahr) sein. Wenn ich nun DATE_ADD(d#2011-12-24, -1, 0, 0, 0) genommen habe, ist da als Ergebnis der 23.11.2012 rausgekommen?!

Danke nochmals an alle "guten Geister"

Glückauf!
Guwen


----------



## guwen (7 Dezember 2013)

Hallo nochmals,
in diesem Jahr ist die Weihnachtsbeleuchtung zum Leidwesen meiner Frau am 1. Advent nicht angegangen.
Festgestellt habe ich, dass ich noch immer das leidige Problem mit dem DATE_ADD habe.
DATE_ADD(D#2013-12-24, -23, 0, 0, 0) macht bei mir nicht den 1.12.2013 (also #D2013-12-01) sondern den 31.10.2014 (also  D#2014-10-31).
Woran kann das liegen? Was mache ich falsch?

Danke schon mal für eure Antorten,
Guwen.


----------



## Thomas_v2.1 (7 Dezember 2013)

In der Oscat Funktion von DATE_ADD ist ein Fehler. Wenn der Parameter D oder W negativ ist funktioniert er nicht wie gewünscht.
Am Besten ist es wenn du den Fehler bei Oscat meldest.

Zur Strafe muss Hugo deiner Frau dann ein Weihnachtsständchen singen... ;-)


----------

