diff --git a/Bot-Utils.csproj b/Bot-Utils.csproj
index 7c26c2d..7592403 100644
--- a/Bot-Utils.csproj
+++ b/Bot-Utils.csproj
@@ -55,7 +55,10 @@
+
+
+
diff --git a/Moduls/CronJob.cs b/Moduls/CronJob.cs
new file mode 100644
index 0000000..0959169
--- /dev/null
+++ b/Moduls/CronJob.cs
@@ -0,0 +1,172 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text.RegularExpressions;
+using System.Threading;
+using BlubbFish.Utils.IoT.Bots.Interfaces;
+
+namespace BlubbFish.Utils.IoT.Bots.Moduls {
+ public abstract class CronJob : AModul, IDisposable, IForceLoad {
+ protected readonly List, Object>> internalCron = new List, Object>>();
+ protected Thread thread;
+ protected DateTime crontime;
+
+ protected readonly Dictionary cron_named = new Dictionary {
+ { "@yearly", "0 0 1 1 *" },
+ { "@annually", "0 0 1 1 *" },
+ { "@monthly", "0 0 1 * *" },
+ { "@weekly", "0 0 * * 0" },
+ { "@daily", "0 0 * * *" },
+ { "@hourly", "0 * * * *" }
+ };
+
+ #region Constructor
+ public CronJob(T lib, InIReader settings) : base(lib, settings) {
+ this.crontime = DateTime.Now;
+ this.thread = new Thread(this.Runner);
+ this.thread.Start();
+ }
+ #endregion
+
+ #region Cronjobrunner
+ protected void Runner() {
+ Thread.Sleep(DateTime.Now.AddMinutes(1).AddSeconds(DateTime.Now.Second * (-1)).AddMilliseconds(DateTime.Now.Millisecond * (-1)) - DateTime.Now);
+ while (true) {
+ if (this.crontime.Minute != DateTime.Now.Minute) {
+ this.crontime = DateTime.Now;
+ if (this.config.Count != 0) {
+ foreach (KeyValuePair> item in this.config) {
+ if (item.Value.ContainsKey("cron") && item.Value.ContainsKey("set") && this.ParseCronString(item.Value["cron"])) {
+ this.SetValues(item.Value["set"]);
+ }
+ }
+ }
+ foreach (Tuple, Object> item in this.internalCron) {
+ if (this.ParseCronString(item.Item1)) {
+ item.Item2?.Invoke(item.Item3);
+ }
+ }
+ }
+ Thread.Sleep(100);
+ }
+ }
+
+ protected abstract void SetValues(String value);
+ #endregion
+
+ #region CronFunctions
+ protected Boolean ParseCronString(String cronstring) {
+ cronstring = cronstring.Trim();
+ if (this.cron_named.ContainsKey(cronstring)) {
+ cronstring = this.cron_named[cronstring];
+ }
+ String[] value = cronstring.Split(' ');
+ if (value.Length != 5) {
+ return false;
+ }
+ if (!this.CheckDateStr(this.crontime.ToString("mm"), value[0], "0-59")) {
+ return false;
+ }
+ if (!this.CheckDateStr(this.crontime.ToString("HH"), value[1], "0-23")) {
+ return false;
+ }
+ if (!this.CheckDateStr(this.crontime.ToString("MM"), value[3], "1-12")) {
+ return false;
+ }
+ if (value[2] != "*" && value[4] != "*") {
+ if (!this.CheckDateStr(this.crontime.ToString("dd"), value[2], "1-31") && !this.CheckDateStr(((Int32)this.crontime.DayOfWeek).ToString(), value[4], "0-7")) {
+ return false;
+ }
+ } else {
+ if (!this.CheckDateStr(this.crontime.ToString("dd"), value[2], "1-31")) {
+ return false;
+ }
+ if (!this.CheckDateStr(((Int32)this.crontime.DayOfWeek).ToString(), value[4], "0-7")) {
+ return false;
+ }
+ }
+ return true;
+ }
+ protected Boolean CheckDateStr(String date, String cron, String limit) {
+ cron = cron.ToLower();
+ for (Int32 i = 0; i <= 6; i++) {
+ cron = cron.Replace(DateTime.Parse("2015-01-" + (4 + i) + "T00:00:00").ToString("ddd", CultureInfo.CreateSpecificCulture("en-US")), i.ToString());
+ cron = cron.Replace(DateTime.Parse("2015-01-" + (4 + i) + "T00:00:00").ToString("dddd", CultureInfo.CreateSpecificCulture("en-US")), i.ToString());
+ }
+ for (Int32 i = 1; i <= 12; i++) {
+ cron = cron.Replace(DateTime.Parse("2015-" + i + "-01T00:00:00").ToString("MMM", CultureInfo.CreateSpecificCulture("en-US")), i.ToString());
+ cron = cron.Replace(DateTime.Parse("2015-" + i + "-01T00:00:00").ToString("MMMM", CultureInfo.CreateSpecificCulture("en-US")), i.ToString());
+ }
+ if (cron.Contains("*")) {
+ cron = cron.Replace("*", limit);
+ }
+ if (cron.Contains("-")) {
+ MatchCollection m = new Regex("(\\d+)-(\\d+)").Matches(cron);
+ foreach (Match p in m) {
+ List s = new List();
+ for (Int32 i = Math.Min(Int32.Parse(p.Groups[1].Value), Int32.Parse(p.Groups[2].Value)); i <= Math.Max(Int32.Parse(p.Groups[1].Value), Int32.Parse(p.Groups[2].Value)); i++) {
+ s.Add(i.ToString());
+ }
+ cron = cron.Replace(p.Groups[0].Value, String.Join(",", s));
+ }
+ }
+ Int32 match = 0;
+ if (cron.Contains("/")) {
+ Match m = new Regex("/(\\d+)").Match(cron);
+ cron = cron.Replace(m.Groups[0].Value, "");
+ match = Int32.Parse(m.Groups[1].Value);
+ }
+ Dictionary ret = new Dictionary();
+ if (!cron.Contains(",")) {
+ ret.Add(Int32.Parse(cron), "");
+ } else {
+ foreach (String item in cron.Split(',')) {
+ if (!ret.ContainsKey(Int32.Parse(item))) {
+ ret.Add(Int32.Parse(item), "");
+ }
+ }
+ }
+ if (match != 0) {
+ Dictionary r = new Dictionary();
+ foreach (KeyValuePair item in ret) {
+ if (item.Key % match == 0) {
+ r.Add(item.Key, "");
+ }
+ }
+ ret = r;
+ }
+ return ret.ContainsKey(Int32.Parse(date));
+ }
+ #endregion
+
+ #region AModul
+ public override void SetInterconnection(String cron, Action