From e533a5232a11763c15b32ba2ed3ffd97772070a5 Mon Sep 17 00:00:00 2001 From: BlubbFish Date: Tue, 3 Oct 2017 00:55:04 +0200 Subject: [PATCH] =?UTF-8?q?[NF]=20AUserBackend=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IoT-Bot/IoT-Bot/Condition/ACondition.cs | 12 ++-- IoT-Bot/IoT-Bot/Condition/Edge.cs | 6 +- IoT-Bot/IoT-Bot/ConditionWorker.cs | 12 ++-- IoT-Bot/IoT-Bot/Program.cs | 11 +-- IoT-Bot/IoT-Bot/settings.ini.example | 3 +- .../Mqtt-Dashboard/bin/Release/Dashboard.exe | Bin 21504 -> 21504 bytes .../Mqtt-Dashboard/bin/Release/Utils-IoT.dll | Bin 21504 -> 22016 bytes Utils/IoT.sln | 6 -- Utils/IoT/Connector/ADataBackend.cs | 20 ++---- Utils/IoT/Connector/AUserBackend.cs | 34 +++++++++ Utils/IoT/Connector/{ => Data}/Mosquitto.cs | 2 +- Utils/IoT/Connector/{ => Data}/Mqtt.cs | 2 +- Utils/IoT/Connector/Helper.cs | 30 ++++++++ Utils/IoT/Connector/Telegram.cs | 65 ------------------ Utils/IoT/Connector/User/Telegram.cs | 47 +++++++++++++ Utils/IoT/Utils-IoT.csproj | 14 ++-- Utils/IoT/bin/Release/Utils-IoT.dll | Bin 21504 -> 22016 bytes 17 files changed, 145 insertions(+), 119 deletions(-) create mode 100644 Utils/IoT/Connector/AUserBackend.cs rename Utils/IoT/Connector/{ => Data}/Mosquitto.cs (98%) rename Utils/IoT/Connector/{ => Data}/Mqtt.cs (97%) create mode 100644 Utils/IoT/Connector/Helper.cs delete mode 100644 Utils/IoT/Connector/Telegram.cs create mode 100644 Utils/IoT/Connector/User/Telegram.cs diff --git a/IoT-Bot/IoT-Bot/Condition/ACondition.cs b/IoT-Bot/IoT-Bot/Condition/ACondition.cs index d6aae87..6a737b8 100644 --- a/IoT-Bot/IoT-Bot/Condition/ACondition.cs +++ b/IoT-Bot/IoT-Bot/Condition/ACondition.cs @@ -7,9 +7,13 @@ namespace IoTBot.Condition { abstract class ACondition { protected ASensor sensor; protected Dictionary settings; + protected ADataBackend data; + protected AUserBackend user; - public ACondition(Dictionary settings, ADataBackend backend) { + public ACondition(Dictionary settings, ADataBackend data, AUserBackend user) { this.settings = settings; + this.data = data; + this.user = user; Dictionary l = new Dictionary { { "topic", this.settings["sensor_topic"] }, { "type", this.settings["sensor"] } @@ -17,13 +21,13 @@ namespace IoTBot.Condition { if(settings.ContainsKey("sensor_polling")) { l.Add("polling", this.settings["sensor_polling"]); } - this.sensor = ASensor.GetInstance(backend, l, "testSensor"); + this.sensor = ASensor.GetInstance(data, l, "testSensor"); this.sensor.Update += this.Sensor_Update; } protected abstract void Sensor_Update(Object sender, EventArgs e); - public static ACondition GetInstance(Dictionary settings, ADataBackend backend) { + public static ACondition GetInstance(Dictionary settings, ADataBackend data, AUserBackend user) { String object_condition = "IoTBot.Condition." + Char.ToUpper(settings["type"][0]) + settings["type"].Substring(1).ToLower(); Type t = null; try { @@ -31,7 +35,7 @@ namespace IoTBot.Condition { } catch(TypeLoadException) { throw new ArgumentException("condition.ini: " + settings["type"] + " is not a Sensor"); } - return (ACondition)t.GetConstructor(new Type[] { typeof(Dictionary), typeof(ADataBackend) }).Invoke(new Object[] { settings, backend }); + return (ACondition)t.GetConstructor(new Type[] { typeof(Dictionary), typeof(ADataBackend), typeof(AUserBackend) }).Invoke(new Object[] { settings, data, user }); } } } \ No newline at end of file diff --git a/IoT-Bot/IoT-Bot/Condition/Edge.cs b/IoT-Bot/IoT-Bot/Condition/Edge.cs index 32114cd..d7683af 100644 --- a/IoT-Bot/IoT-Bot/Condition/Edge.cs +++ b/IoT-Bot/IoT-Bot/Condition/Edge.cs @@ -7,15 +7,13 @@ namespace IoTBot.Condition { class Edge : ACondition { private Boolean histBool; - public Edge(Dictionary settings, ADataBackend backend) : base(settings, backend) { - - } + public Edge(Dictionary settings, ADataBackend data, AUserBackend user) : base(settings, data, user) { } protected override void Sensor_Update(Object sender, EventArgs e) { if(this.sensor.Datatypes == ASensor.Types.Bool) { if(this.sensor.GetBool == Boolean.Parse(this.settings["sensor_value"]) && this.histBool != this.sensor.GetBool) { this.histBool = this.sensor.GetBool; - Telegram.Instance.Send("Jemand ist DA!"); + this.user.Send("Jemand ist DA!"); } else { this.histBool = this.sensor.GetBool; } diff --git a/IoT-Bot/IoT-Bot/ConditionWorker.cs b/IoT-Bot/IoT-Bot/ConditionWorker.cs index fc53037..6eac744 100644 --- a/IoT-Bot/IoT-Bot/ConditionWorker.cs +++ b/IoT-Bot/IoT-Bot/ConditionWorker.cs @@ -9,25 +9,23 @@ namespace IoTBot { private InIReader ini; private static ConditionWorker instance; private List conditions; - private Telegram telegram; - public static ConditionWorker GetInstance(ADataBackend backend) { + public static ConditionWorker GetInstance(ADataBackend data, AUserBackend user) { if (instance == null) { - instance = new ConditionWorker(backend); + instance = new ConditionWorker(data, user); } return instance; } - internal void Run(Telegram telegram) { - this.telegram = telegram; + internal void Run() { } - private ConditionWorker(ADataBackend backend) { + private ConditionWorker(ADataBackend data, AUserBackend user) { this.ini = InIReader.GetInstance("condition.ini"); this.conditions = new List(); List sections = this.ini.GetSections(); foreach(String section in sections) { - this.conditions.Add(ACondition.GetInstance(this.ini.GetSection(section), backend)); + this.conditions.Add(ACondition.GetInstance(this.ini.GetSection(section), data, user)); } } } diff --git a/IoT-Bot/IoT-Bot/Program.cs b/IoT-Bot/IoT-Bot/Program.cs index e726dbb..d52d84b 100644 --- a/IoT-Bot/IoT-Bot/Program.cs +++ b/IoT-Bot/IoT-Bot/Program.cs @@ -6,11 +6,12 @@ namespace IoTBot { class Program { static void Main(String[] args) { ADataBackend mqtt = ADataBackend.GetInstance(InIReader.GetInstance("settings.ini").GetSection("mqtt")); - ConditionWorker.GetInstance(mqtt).Run(Telegram.Instance); + AUserBackend telegram = AUserBackend.GetInstance(InIReader.GetInstance("settings.ini").GetSection("user")); + ConditionWorker.GetInstance(mqtt, telegram).Run(); mqtt.MessageIncomming += Mqtt_MessageIncomming; mqtt.MessageSending += Mqtt_MessageSending; - Telegram.Instance.MessageIncomming += Telegram_MessageIncomming; - Telegram.Instance.MessageSending += Telegram_MessageSending; + telegram.MessageIncomming += Telegram_MessageIncomming; + telegram.MessageSending += Telegram_MessageSending; while(true) { System.Threading.Thread.Sleep(100); @@ -21,11 +22,11 @@ namespace IoTBot { Console.WriteLine("-> [" + DateTime.Now.ToUniversalTime() + "] MQTT: " + e.Message + " on " + e.Topic); } - private static void Telegram_MessageSending(Object sender, TelegramEventArgs e) { + private static void Telegram_MessageSending(Object sender, UserMessageEventArgs e) { Console.WriteLine("-> [" + e.Date.ToUniversalTime() + "] Telegram: " + e.Message + " on " + e.UserId); } - private static void Telegram_MessageIncomming(Object sender, TelegramEventArgs e) { + private static void Telegram_MessageIncomming(Object sender, UserMessageEventArgs e) { Console.WriteLine("<- [" + e.Date.ToUniversalTime() + "] Telegram: " + e.Message + " on " + e.UserId); } diff --git a/IoT-Bot/IoT-Bot/settings.ini.example b/IoT-Bot/IoT-Bot/settings.ini.example index c5a9de1..35cc5a2 100644 --- a/IoT-Bot/IoT-Bot/settings.ini.example +++ b/IoT-Bot/IoT-Bot/settings.ini.example @@ -1,4 +1,5 @@ -[general] +[user] +type=telegram telegram-key=ABCDEFGH chatid=1234 diff --git a/Mqtt-Dashboard/Mqtt-Dashboard/bin/Release/Dashboard.exe b/Mqtt-Dashboard/Mqtt-Dashboard/bin/Release/Dashboard.exe index 0bd647cd51a447d75ad19ccf01ea87ef3b37d134..404f6d5caa4958f1f18fad118ef54bbe9bc0aac3 100644 GIT binary patch delta 87 zcmZoz!Pu~ZaY6^vheI2?b~y;#_`hOi7K5JWnk64255ynT*&O1yhePMXp-YhrK)?jV pGK>ri8W}+B#lR30>=LYcLTT2%>L9=6?lLa-ZaMzmY~yu=6962yAwK{B delta 87 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 delta 9879 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 dictionary) { - String object_sensor = "BlubbFish.Utils.IoT.Connector." + Char.ToUpper(dictionary["type"][0]) + dictionary["type"].Substring(1).ToLower(); + public static ADataBackend GetInstance(Dictionary settings) { + String object_sensor = "BlubbFish.Utils.IoT.Connector.Data." + Char.ToUpper(settings["type"][0]) + settings["type"].Substring(1).ToLower(); Type t = null; try { t = Type.GetType(object_sensor, true); } catch (TypeLoadException) { - throw new ArgumentException("settings.ini: " + dictionary["type"] + " is not a Connector"); + throw new ArgumentException("settings.ini: " + settings["type"] + " is not a DataBackend"); } - return (ADataBackend)t.GetConstructor(new Type[] { typeof(Dictionary) }).Invoke(new Object[] { dictionary }); + return (ADataBackend)t.GetConstructor(new Type[] { typeof(Dictionary) }).Invoke(new Object[] { settings }); } public abstract void Send(String topic, String data); public abstract void Dispose(); } - public class MqttEventArgs : EventArgs { - public MqttEventArgs() : base() { } - public MqttEventArgs(String message, String topic) { - this.Topic = topic; - this.Message = message; - this.Date = DateTime.Now; - } - - public String Topic { get; private set; } - public String Message { get; private set; } - public DateTime Date { get; private set; } - } } diff --git a/Utils/IoT/Connector/AUserBackend.cs b/Utils/IoT/Connector/AUserBackend.cs new file mode 100644 index 0000000..18efaf0 --- /dev/null +++ b/Utils/IoT/Connector/AUserBackend.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlubbFish.Utils.IoT.Connector { + public abstract class AUserBackend { + protected Dictionary settings; + + public abstract event TelegramMessage MessageIncomming; + public abstract event TelegramMessage MessageSending; + public delegate void TelegramMessage(Object sender, UserMessageEventArgs e); + + public AUserBackend(Dictionary settings) { + this.settings = settings; + } + + public static AUserBackend GetInstance(Dictionary settings) { + String object_sensor = "BlubbFish.Utils.IoT.Connector.User." + Char.ToUpper(settings["type"][0]) + settings["type"].Substring(1).ToLower(); + Type t = null; + try { + t = Type.GetType(object_sensor, true); + } catch (TypeLoadException) { + throw new ArgumentException("settings.ini: " + settings["type"] + " is not a UserBackend"); + } + return (AUserBackend)t.GetConstructor(new Type[] { typeof(Dictionary) }).Invoke(new Object[] { settings }); + } + + public abstract void Send(String message); + + public abstract void Dispose(); + } +} diff --git a/Utils/IoT/Connector/Mosquitto.cs b/Utils/IoT/Connector/Data/Mosquitto.cs similarity index 98% rename from Utils/IoT/Connector/Mosquitto.cs rename to Utils/IoT/Connector/Data/Mosquitto.cs index a740999..faf674f 100644 --- a/Utils/IoT/Connector/Mosquitto.cs +++ b/Utils/IoT/Connector/Data/Mosquitto.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Text.RegularExpressions; -namespace BlubbFish.Utils.IoT.Connector { +namespace BlubbFish.Utils.IoT.Connector.Data { class Mosquitto : ADataBackend, IDisposable { private Process p; private String message; diff --git a/Utils/IoT/Connector/Mqtt.cs b/Utils/IoT/Connector/Data/Mqtt.cs similarity index 97% rename from Utils/IoT/Connector/Mqtt.cs rename to Utils/IoT/Connector/Data/Mqtt.cs index 8eaca93..b9a75be 100644 --- a/Utils/IoT/Connector/Mqtt.cs +++ b/Utils/IoT/Connector/Data/Mqtt.cs @@ -4,7 +4,7 @@ using System.Text; using uPLibrary.Networking.M2Mqtt; using uPLibrary.Networking.M2Mqtt.Messages; -namespace BlubbFish.Utils.IoT.Connector { +namespace BlubbFish.Utils.IoT.Connector.Data { class Mqtt : ADataBackend, IDisposable { private MqttClient client; diff --git a/Utils/IoT/Connector/Helper.cs b/Utils/IoT/Connector/Helper.cs new file mode 100644 index 0000000..243bebe --- /dev/null +++ b/Utils/IoT/Connector/Helper.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlubbFish.Utils.IoT.Connector { + public class UserMessageEventArgs : EventArgs { + public UserMessageEventArgs() : base() { } + public UserMessageEventArgs(String message, Int64 UserId, DateTime date) { + this.UserId = UserId; + this.Message = message; + this.Date = date; + } + public Int64 UserId { get; private set; } + public String Message { get; private set; } + public DateTime Date { get; private set; } + } + public class MqttEventArgs : EventArgs { + public MqttEventArgs() : base() { } + public MqttEventArgs(String message, String topic) { + this.Topic = topic; + this.Message = message; + this.Date = DateTime.Now; + } + public String Topic { get; private set; } + public String Message { get; private set; } + public DateTime Date { get; private set; } + } +} diff --git a/Utils/IoT/Connector/Telegram.cs b/Utils/IoT/Connector/Telegram.cs deleted file mode 100644 index 7df80fb..0000000 --- a/Utils/IoT/Connector/Telegram.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -using Telegram.Bot; -using Telegram.Bot.Args; -using Telegram.Bot.Exceptions; -using Telegram.Bot.Types; - -namespace BlubbFish.Utils.IoT.Connector { - public class Telegram { - private static Telegram instance; - private TelegramBotClient bot; - private ChatId chat; - - public delegate void TelegramMessage(Object sender, TelegramEventArgs e); - - public event TelegramMessage MessageIncomming; - public event TelegramMessage MessageSending; - - private Telegram() { - this.bot = new TelegramBotClient(InIReader.GetInstance("settings.ini").GetValue("general", "telegram-key")); - this.bot.OnMessage += this.Bot_OnMessage; - this.Connect(); - } - - private void Bot_OnMessage(Object sender, MessageEventArgs e) { - this.MessageIncomming?.Invoke(this, new TelegramEventArgs(e.Message.Text, e.Message.Chat.Id, e.Message.Date)); - } - - public static Telegram Instance { - get { - if(instance == null) { - instance = new Telegram(); - } - return instance; - } - } - - private void Connect() { - this.bot.StartReceiving(); - this.chat = new ChatId(InIReader.GetInstance("settings.ini").GetValue("general", "chatid")); - } - - public async void Send(String text) { - try { - Message x = await this.bot.SendTextMessageAsync(this.chat, text); - this.MessageSending?.Invoke(this, new TelegramEventArgs(x.Text, x.Chat.Id, x.Date)); - } catch(ApiRequestException e) { - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine(e.Message+" "+e.ErrorCode+" "+e.Parameters); - Console.ForegroundColor = ConsoleColor.White; - } - } - } - public class TelegramEventArgs : EventArgs { - public TelegramEventArgs() : base() { } - public TelegramEventArgs(String message, Int64 UserId, DateTime date) { - this.UserId = UserId; - this.Message = message; - this.Date = date; - } - - public Int64 UserId { get; private set; } - public String Message { get; private set; } - public DateTime Date { get; private set; } - } -} diff --git a/Utils/IoT/Connector/User/Telegram.cs b/Utils/IoT/Connector/User/Telegram.cs new file mode 100644 index 0000000..d8b92b8 --- /dev/null +++ b/Utils/IoT/Connector/User/Telegram.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using Telegram.Bot; +using Telegram.Bot.Args; +using Telegram.Bot.Exceptions; +using Telegram.Bot.Types; + +namespace BlubbFish.Utils.IoT.Connector.User { + public class Telegram : AUserBackend { + private TelegramBotClient bot; + private ChatId chat; + + public override event TelegramMessage MessageIncomming; + public override event TelegramMessage MessageSending; + + public Telegram(Dictionary settings) : base(settings) { + this.bot = new TelegramBotClient(settings["telegram-key"]); + this.bot.OnMessage += this.Bot_OnMessage; + this.Connect(); + } + + private void Bot_OnMessage(Object sender, MessageEventArgs e) { + this.MessageIncomming?.Invoke(this, new UserMessageEventArgs(e.Message.Text, e.Message.Chat.Id, e.Message.Date)); + } + + private void Connect() { + this.bot.StartReceiving(); + this.chat = new ChatId(this.settings["chatid"]); + } + + public async override void Send(String message) { + try { + Message x = await this.bot.SendTextMessageAsync(this.chat, message); + this.MessageSending?.Invoke(this, new UserMessageEventArgs(x.Text, x.Chat.Id, x.Date)); + } catch(ApiRequestException e) { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine(e.Message+" "+e.ErrorCode+" "+e.Parameters); + Console.ForegroundColor = ConsoleColor.White; + } + } + + public override void Dispose() { + this.bot.StopReceiving(); + this.bot = null; + } + } +} diff --git a/Utils/IoT/Utils-IoT.csproj b/Utils/IoT/Utils-IoT.csproj index ca5ca5e..4630305 100644 --- a/Utils/IoT/Utils-IoT.csproj +++ b/Utils/IoT/Utils-IoT.csproj @@ -109,9 +109,11 @@ - - - + + + + + @@ -126,11 +128,5 @@ - - - {fac8ce64-bf13-4ece-8097-aeb5dd060098} - Utils - - \ No newline at end of file diff --git a/Utils/IoT/bin/Release/Utils-IoT.dll b/Utils/IoT/bin/Release/Utils-IoT.dll index e0255a5a5d272b520b9c72b5ea4895bf8a795f97..3552837d0b70b4ffa316af74276d9372e28233e4 100644 GIT binary patch delta 10147 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 delta 9879 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