Compare commits

..
4 Commits
Author SHA1 Message Date
BlubbFish 80baca45e5 [NF] v.1.3 add possability to modify the config over mqtt 2017-12-22 22:13:28 +00:00
BlubbFish 75eac65510 [BF] v1.3.4.0 Fixing Json Names
[NF] v1.2.2.0 Mqtt can now get and set values
2017-12-19 20:18:30 +00:00
BlubbFish 44b8daa325 [BF] v.1.3.3 fixing polling once bug 2017-12-19 17:33:31 +00:00
BlubbFish 2cd2c7c02e [BF] v1.3.1.0 Forgot some settings, now configuration setting also works again 2017-12-18 16:02:18 +00:00
14 changed files with 223 additions and 77 deletions
+10
View File
@@ -59,5 +59,15 @@ namespace ZwayBot {
Console.Error.WriteLine("ERROR: " + text); Console.Error.WriteLine("ERROR: " + text);
Console.ResetColor(); Console.ResetColor();
} }
internal static String ToUpperLower(this String s) {
if(s.Length == 0) {
return "";
}
if(s.Length == 1) {
return s.ToUpper();
}
return s[0].ToString().ToUpper() + s.Substring(1).ToLower();
}
} }
} }
+48 -2
View File
@@ -6,14 +6,44 @@ using BlubbFish.Utils;
namespace ZwayBot { namespace ZwayBot {
abstract class AModul { abstract class AModul {
protected ZwayController zw; protected ZwayController zw;
protected InIReader ini; private InIReader settings;
protected Dictionary<String, Dictionary<String, String>> config = new Dictionary<String, Dictionary<String, String>>();
public Boolean HasConfig { get; private set; }
public Boolean ConfigPublic { get; private set; }
public delegate void ModulEvent(Object sender, ModulEventArgs e); public delegate void ModulEvent(Object sender, ModulEventArgs e);
public abstract event ModulEvent Update; public abstract event ModulEvent Update;
public AModul(ZwayController zway, InIReader settings) { public AModul(ZwayController zway, InIReader settings) {
this.HasConfig = false;
this.ConfigPublic = false;
this.zw = zway; this.zw = zway;
this.ini = settings; this.settings = settings;
this.ParseConfig();
}
private void ParseConfig() {
if (this.settings != null) {
this.HasConfig = true;
foreach (String item in this.settings.GetSections(false)) {
this.config.Add(item, this.settings.GetSection(item));
}
if(this.config.ContainsKey("modul")) {
this.ConfigPublic = this.config["modul"].ContainsKey("config") && this.config["modul"]["config"].ToLower() == "public";
}
}
}
public Dictionary<String, Dictionary<String, String>> GetConfig() {
if (this.HasConfig && this.ConfigPublic) {
Dictionary<String, Dictionary<String, String>> ret = new Dictionary<String, Dictionary<String, String>>(this.config);
if(ret.ContainsKey("modul")) {
ret.Remove("modul");
}
return ret;
}
return new Dictionary<String, Dictionary<String, String>>();
} }
public virtual void Interconnect(Dictionary<String, AModul> moduls) { } public virtual void Interconnect(Dictionary<String, AModul> moduls) { }
@@ -21,5 +51,21 @@ namespace ZwayBot {
public virtual void SetInterconnection(String param, Action<Object> hook, Object data) { } public virtual void SetInterconnection(String param, Action<Object> hook, Object data) { }
public abstract void Dispose(); public abstract void Dispose();
internal void SetConfig(Dictionary<String, Dictionary<String, String>> newconf) {
if (this.HasConfig && this.ConfigPublic) {
if (newconf.ContainsKey("modul")) {
newconf.Remove("modul");
}
if (this.config.ContainsKey("modul")) {
newconf.Add("modul", this.config["modul"]);
}
this.config = newconf;
this.settings.SetSections(this.config);
this.UpdateConfig();
}
}
protected abstract void UpdateConfig();
} }
} }
+6 -4
View File
@@ -36,10 +36,10 @@ namespace ZwayBot.Moduls {
while (true) { while (true) {
if(this.crontime.Minute != DateTime.Now.Minute) { if(this.crontime.Minute != DateTime.Now.Minute) {
this.crontime = DateTime.Now; this.crontime = DateTime.Now;
if (this.ini != null) { if (this.config.Count != 0) {
foreach (String item in this.ini.GetSections()) { foreach (KeyValuePair<String, Dictionary<String, String>> item in this.config) {
if (this.ParseCronString(this.ini.GetValue(item, "cron"))) { if (item.Value.ContainsKey("cron") && item.Value.ContainsKey("set") && this.ParseCronString(item.Value["cron"])) {
this.SetValues(this.ini.GetValue(item, "set")); this.SetValues(item.Value["set"]);
} }
} }
} }
@@ -157,6 +157,8 @@ namespace ZwayBot.Moduls {
this.internalCron.Add(new Tuple<String, Action<Object>, Object>(cron, hook, data)); this.internalCron.Add(new Tuple<String, Action<Object>, Object>(cron, hook, data));
} }
protected override void UpdateConfig() { }
#region IDisposable Support #region IDisposable Support
private Boolean disposedValue = false; private Boolean disposedValue = false;
+45 -39
View File
@@ -20,22 +20,24 @@ namespace ZwayBot.Moduls {
public override event ModulEvent Update; public override event ModulEvent Update;
public Flex4Grid(ZwayController zway, InIReader settings) : base(zway, settings) { public Flex4Grid(ZwayController zway, InIReader settings) : base(zway, settings) {
this.mqtt = ADataBackend.GetInstance(this.ini.GetSection("settings")); if (this.config.ContainsKey("settings")) {
this.ParseIni(); this.mqtt = ADataBackend.GetInstance(this.config["settings"]);
this.mqtt.MessageIncomming += this.Mqtt_MessageIncomming; this.ParseIni();
this.mqtt.MessageIncomming += this.Mqtt_MessageIncomming;
}
} }
private void ParseIni() { private void ParseIni() {
if (this.ini.GetValue("zway", "devices") != null) { if (this.config.ContainsKey("zway") && this.config["zway"].ContainsKey("devices")) {
foreach (String device in this.ini.GetValue("zway", "devices").Split(',')) { foreach (String device in this.config["zway"]["devices"].Split(',')) {
Int32 deviceid = Int32.Parse(device); Int32 deviceid = Int32.Parse(device);
if (this.zw.Devices.ContainsKey(deviceid) && this.zw.Devices[deviceid].Instances.ContainsKey(0)) { if (this.zw.Devices.ContainsKey(deviceid) && this.zw.Devices[deviceid].Instances.ContainsKey(0)) {
this.zw.Devices[deviceid].Instances[0].Update += this.DeviceUpdate; this.zw.Devices[deviceid].Instances[0].Update += this.DeviceUpdate;
} }
} }
} }
if(this.ini.GetValue("f4g", "household") != null) { if(this.config.ContainsKey("f4g") && this.config["f4g"].ContainsKey("household")) {
this.household = this.ini.GetValue("f4g", "household"); this.household = this.config["f4g"]["household"];
} }
} }
@@ -85,8 +87,8 @@ namespace ZwayBot.Moduls {
if(topic == "/flex4grid/v1/households/" + this.household + "/device/actuate") { if(topic == "/flex4grid/v1/households/" + this.household + "/device/actuate") {
if(message.Keys.Contains("deviceId") && message.Keys.Contains("command")) { if(message.Keys.Contains("deviceId") && message.Keys.Contains("command")) {
String device = message["deviceId"].ToString(); String device = message["deviceId"].ToString();
if(this.ini.GetValue("zway", "devices") != null) { if(this.config.ContainsKey("zway") && this.config["zway"].ContainsKey("devices")) {
foreach (String item in this.ini.GetValue("zway", "devices").Split(',')) { foreach (String item in this.config["zway"]["devices"].Split(',')) {
if (item == device) { if (item == device) {
Int32 deviceid = Int32.Parse(device); Int32 deviceid = Int32.Parse(device);
if (this.zw.Devices.ContainsKey(deviceid) && this.zw.Devices[deviceid].Instances.ContainsKey(0) && if (this.zw.Devices.ContainsKey(deviceid) && this.zw.Devices[deviceid].Instances.ContainsKey(0) &&
@@ -99,9 +101,9 @@ namespace ZwayBot.Moduls {
} }
} }
if (topic == "/flex4grid/v1/households/" + this.household + "/devices/state/request") { if (topic == "/flex4grid/v1/households/" + this.household + "/devices/state/request") {
if (this.ini.GetValue("zway", "devices") != null) { if (this.config.ContainsKey("zway") && this.config["zway"].ContainsKey("devices")) {
Dictionary<String, String> response = new Dictionary<String, String>(); Dictionary<String, String> response = new Dictionary<String, String>();
foreach (String device in this.ini.GetValue("zway", "devices").Split(',')) { foreach (String device in this.config["zway"]["devices"].Split(',')) {
Int32 deviceid = Int32.Parse(device); Int32 deviceid = Int32.Parse(device);
if (this.zw.Devices.ContainsKey(deviceid) && this.zw.Devices[deviceid].Instances.ContainsKey(0)) { if (this.zw.Devices.ContainsKey(deviceid) && this.zw.Devices[deviceid].Instances.ContainsKey(0)) {
if (this.zw.Devices[deviceid].Instances[0].CommandClasses.ContainsKey(ACommandClass.Classes.SwitchBinary)) { if (this.zw.Devices[deviceid].Instances[0].CommandClasses.ContainsKey(ACommandClass.Classes.SwitchBinary)) {
@@ -120,38 +122,40 @@ namespace ZwayBot.Moduls {
} }
private void RequestAlive(Object o) { private void RequestAlive(Object o) {
String raspi = this.ini.GetValue("f4g", "raspi"); if (this.config.ContainsKey("f4g") && this.config["f4g"].ContainsKey("raspi")) {
lock (this.requestalivelock) { String raspi = this.config["f4g"]["raspi"];
String req = "https://wiki.flex4grid.eu/rupdate/rupdate_general.yml.gpg.asc?gw=" + raspi; lock (this.requestalivelock) {
HttpWebRequest request = WebRequest.CreateHttp(req); String req = "https://wiki.flex4grid.eu/rupdate/rupdate_general.yml.gpg.asc?gw=" + raspi;
try { HttpWebRequest request = WebRequest.CreateHttp(req);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { try {
this.Update?.Invoke(this, new Flex4gridEvent(req, response.StatusCode.ToString())); using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
} this.Update?.Invoke(this, new Flex4gridEvent(req, response.StatusCode.ToString()));
} catch (Exception) { } }
} } catch (Exception) { }
lock (this.requestalivelock) { }
String req = "https://wiki.flex4grid.eu/rupdate/rupdate_general.yml?gw=" + raspi; lock (this.requestalivelock) {
HttpWebRequest request = WebRequest.CreateHttp(req); String req = "https://wiki.flex4grid.eu/rupdate/rupdate_general.yml?gw=" + raspi;
try { HttpWebRequest request = WebRequest.CreateHttp(req);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { try {
this.Update?.Invoke(this, new Flex4gridEvent(req, response.StatusCode.ToString())); using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
} this.Update?.Invoke(this, new Flex4gridEvent(req, response.StatusCode.ToString()));
} catch (Exception) { } }
} } catch (Exception) { }
lock (this.requestalivelock) { }
String req = "http://swb.pcs.flex4grid.eu/gateway/" + raspi; lock (this.requestalivelock) {
HttpWebRequest request = WebRequest.CreateHttp(req); String req = "http://swb.pcs.flex4grid.eu/gateway/" + raspi;
try { HttpWebRequest request = WebRequest.CreateHttp(req);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { try {
this.Update?.Invoke(this, new Flex4gridEvent(req, response.StatusCode.ToString())); using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
} this.Update?.Invoke(this, new Flex4gridEvent(req, response.StatusCode.ToString()));
} catch (Exception) { } }
} catch (Exception) { }
}
} }
} }
public override void Interconnect(Dictionary<String, AModul> moduls) { public override void Interconnect(Dictionary<String, AModul> moduls) {
if (this.ini.GetValue("f4g", "raspi") != null) { if (this.config.ContainsKey("f4g") && this.config["f4g"].ContainsKey("raspi")) {
foreach (KeyValuePair<String, AModul> item in moduls) { foreach (KeyValuePair<String, AModul> item in moduls) {
if (item.Value is CronJob) { if (item.Value is CronJob) {
item.Value.SetInterconnection("10,40 * * * *", new Action<Object>(this.RequestAlive), null); item.Value.SetInterconnection("10,40 * * * *", new Action<Object>(this.RequestAlive), null);
@@ -160,6 +164,8 @@ namespace ZwayBot.Moduls {
} }
} }
protected override void UpdateConfig() { }
#region IDisposable Support #region IDisposable Support
private Boolean disposedValue = false; private Boolean disposedValue = false;
+80 -5
View File
@@ -1,20 +1,26 @@
using System; using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using BlubbFish.IoT.Zway; using BlubbFish.IoT.Zway;
using BlubbFish.IoT.Zway.Events; using BlubbFish.IoT.Zway.Events;
using BlubbFish.IoT.Zway.Interfaces; using BlubbFish.IoT.Zway.Interfaces;
using BlubbFish.Utils; using BlubbFish.Utils;
using BlubbFish.Utils.IoT.Connector; using BlubbFish.Utils.IoT.Connector;
using LitJson;
namespace ZwayBot.Moduls { namespace ZwayBot.Moduls {
class Mqtt : AModul, IDisposable { class Mqtt : AModul, IDisposable {
private ADataBackend mqtt; private ADataBackend mqtt;
private Dictionary<String, AModul> modules;
public override event ModulEvent Update; public override event ModulEvent Update;
public Mqtt(ZwayController zway, InIReader settings) : base(zway, settings) { public Mqtt(ZwayController zway, InIReader settings) : base(zway, settings) {
this.mqtt = ADataBackend.GetInstance(this.ini.GetSection("settings")); if (this.config.ContainsKey("settings")) {
this.mqtt.MessageIncomming += this.Mqtt_MessageIncomming; this.mqtt = ADataBackend.GetInstance(this.config["settings"]);
this.zw.Update += this.ZwayEvent; this.mqtt.MessageIncomming += this.Mqtt_MessageIncomming;
this.zw.Update += this.ZwayEvent;
}
} }
private void ZwayEvent(Object sender, DeviceUpdateEvent e) { private void ZwayEvent(Object sender, DeviceUpdateEvent e) {
@@ -32,11 +38,80 @@ namespace ZwayBot.Moduls {
} }
private void Mqtt_MessageIncomming(Object sender, MqttEventArgs e) { private void Mqtt_MessageIncomming(Object sender, MqttEventArgs e) {
if(e.Message.StartsWith("/zwavebot/devices/") && e.Message.EndsWith("set")) { if (e.Topic.StartsWith("/zwavebot/devices/") && (e.Topic.EndsWith("/set") || e.Topic.EndsWith("/get"))) {
Match m = new Regex("^/zwavebot/devices/(\\d+)/(\\d+)/(\\d+)/[gs]et$|^/zwavebot/devices/(\\d+)/(\\d+)/(\\d+)/(\\d+)/[gs]et$").Match(e.Topic);
String id = "";
if(m.Groups[1].Success) {
id = m.Groups[1].Value + "-" + m.Groups[2].Value + "-" + m.Groups[3].Value;
}
if(m.Groups[4].Success) {
id = m.Groups[4].Value + "-" + m.Groups[5].Value + "-" + m.Groups[6].Value + "-" + m.Groups[7].Value;
}
ACommandClass c = this.zw.GetCommandClass(id);
if(c == null) {
return;
}
if (e.Topic.EndsWith("/set")) {
try {
JsonData a = JsonMapper.ToObject(e.Message);
foreach (String item in a.Keys) {
String key = item.ToUpperLower();
if (c.HasProperty(key)) {
c.SetProperty(key, a[item].ToString());
this.Update?.Invoke(this, new MqttEvent(c.Id, a[item].ToString()));
}
}
} catch (Exception) { }
} else if(e.Topic.EndsWith("/get")) {
c.PollOnce = true;
this.mqtt.Send("/zwavebot/devices/" + c.MqttTopic(), c.ToJson());
this.Update?.Invoke(this, new MqttEvent(e.Topic, "Dataget"));
}
}
if (e.Topic.StartsWith("/zwavebot/config/") && (e.Topic.EndsWith("/set") || e.Topic.EndsWith("/get"))) {
Match m = new Regex("^/zwavebot/config/(\\w+)/[gs]et$|").Match(e.Topic);
if (!m.Groups[1].Success) {
return;
}
AModul modul = null;
foreach (KeyValuePair<String, AModul> item in this.modules) {
if (item.Key.ToLower() == m.Groups[1].Value) {
modul = item.Value;
}
}
if (modul == null) {
return;
}
if(e.Topic.EndsWith("/get") && modul.HasConfig && modul.ConfigPublic) {
String topic = "/zwavebot/config/" + m.Groups[1].Value;
String data = JsonMapper.ToJson(modul.GetConfig()).ToString();
this.mqtt.Send(topic, data);
this.Update?.Invoke(this, new MqttEvent(topic, data));
}
if (e.Topic.EndsWith("/set") && modul.HasConfig && modul.ConfigPublic) {
try {
JsonData a = JsonMapper.ToObject(e.Message);
Dictionary<String, Dictionary<String, String>> newconf = new Dictionary<String, Dictionary<String, String>>();
foreach (String section in a.Keys) {
Dictionary<String, String> sectiondata = new Dictionary<String, String>();
foreach (String item in a[section].Keys) {
sectiondata.Add(item, a[section][item].ToString());
}
newconf.Add(section, sectiondata);
}
modul.SetConfig(newconf);
this.Update?.Invoke(this, new MqttEvent("New Config", "Write"));
} catch (Exception) { }
}
} }
} }
public override void Interconnect(Dictionary<String, AModul> moduls) {
this.modules = moduls;
}
protected override void UpdateConfig() { }
#region IDisposable Support #region IDisposable Support
private Boolean disposedValue = false; private Boolean disposedValue = false;
+23 -17
View File
@@ -16,14 +16,16 @@ namespace ZwayBot.Moduls {
} }
private void ParseIni() { private void ParseIni() {
foreach (String item in this.ini.GetSections()) { foreach (KeyValuePair<String, Dictionary<String, String>> item in this.config) {
String from = this.ini.GetValue(item, "from"); if (item.Value.ContainsKey("from")) {
String[] source = from.Split(':'); String from = item.Value["from"];
this.events.Add(source[0], this.ini.GetSection(item)); String[] source = from.Split(':');
ACommandClass c = this.zw.GetCommandClass(source[0]); this.events.Add(source[0], item.Value);
if (c != null) { ACommandClass c = this.zw.GetCommandClass(source[0]);
c.Polling = true; if (c != null) {
c.Update += this.ChangedEvent; c.Polling = true;
c.Update += this.ChangedEvent;
}
} }
} }
} }
@@ -56,15 +58,17 @@ namespace ZwayBot.Moduls {
} }
} }
} }
foreach (String to in dictionary["to"].Split(';')) { if (dictionary.ContainsKey("to")) {
String[] target = to.Split(':'); foreach (String to in dictionary["to"].Split(';')) {
if(target.Length == 2) { String[] target = to.Split(':');
ACommandClass c = this.zw.GetCommandClass(target[0]); if (target.Length == 2) {
if (c != null) { ACommandClass c = this.zw.GetCommandClass(target[0]);
if (c.HasProperty(target[1])) { if (c != null) {
if (c.GetProperty(target[1]).ToString() != source_value) { if (c.HasProperty(target[1])) {
c.SetProperty(target[1], source_value); if (c.GetProperty(target[1]).ToString() != source_value) {
this.Update?.Invoke(this, new OvertakerEvent(target[0], target[1], source_value)); c.SetProperty(target[1], source_value);
this.Update?.Invoke(this, new OvertakerEvent(target[0], target[1], source_value));
}
} }
} }
} }
@@ -72,6 +76,8 @@ namespace ZwayBot.Moduls {
} }
} }
protected override void UpdateConfig() { }
#region IDisposable Support #region IDisposable Support
private Boolean disposedValue = false; private Boolean disposedValue = false;
+6 -4
View File
@@ -17,10 +17,10 @@ namespace ZwayBot.Moduls {
foreach (KeyValuePair<String, AModul> item in moduls) { foreach (KeyValuePair<String, AModul> item in moduls) {
if (item.Value is CronJob) { if (item.Value is CronJob) {
item.Value.SetInterconnection("0 0 * * *", new Action<Object>(this.PollAll), null); item.Value.SetInterconnection("0 0 * * *", new Action<Object>(this.PollAll), null);
if (this.ini != null) { if (this.config.Count != 0) {
foreach (String section in this.ini.GetSections()) { foreach (KeyValuePair<String, Dictionary<String, String>> section in this.config) {
if (this.ini.GetValue(section, "cron") != null && this.ini.GetValue(section, "devices") != null) { if (section.Value.ContainsKey("cron") && section.Value.ContainsKey("devices")) {
item.Value.SetInterconnection(this.ini.GetValue(section, "cron"), new Action<Object>(this.PollSpecific), this.ini.GetValue(section, "devices")); item.Value.SetInterconnection(section.Value["cron"], new Action<Object>(this.PollSpecific), section.Value["devices"]);
} }
} }
} }
@@ -53,6 +53,8 @@ namespace ZwayBot.Moduls {
this.Update?.Invoke(this, new StatusPollingEvent("Polling", "all nodes")); this.Update?.Invoke(this, new StatusPollingEvent("Polling", "all nodes"));
} }
protected override void UpdateConfig() { }
public override void Dispose() {} public override void Dispose() {}
} }
} }
+5 -6
View File
@@ -1,6 +1,5 @@
using System.Resources; using System.Reflection;
using System.Reflection; using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über die folgenden // Allgemeine Informationen über eine Assembly werden über die folgenden
@@ -11,7 +10,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("BlubbFish")] [assembly: AssemblyCompany("BlubbFish")]
[assembly: AssemblyProduct("Zway-Bot")] [assembly: AssemblyProduct("Zway-Bot")]
[assembly: AssemblyCopyright("Copyright © 2017")] [assembly: AssemblyCopyright("Copyright © 2017 - 22.12.2017")]
[assembly: AssemblyTrademark("BlubbFish")] [assembly: AssemblyTrademark("BlubbFish")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
@@ -33,8 +32,8 @@ using System.Runtime.InteropServices;
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden, // Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
// übernehmen, indem Sie "*" eingeben: // übernehmen, indem Sie "*" eingeben:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.2.1.0")] [assembly: AssemblyVersion("1.3.0.0")]
[assembly: AssemblyFileVersion("1.2.1.0")] [assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: NeutralResourcesLanguage("de-DE")] [assembly: NeutralResourcesLanguage("de-DE")]
// “Internet Of Things” icon by By Michael Wohlwend, US, from thenounproject.com. // “Internet Of Things” icon by By Michael Wohlwend, US, from thenounproject.com.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.