Compare commits

..
1 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
13 changed files with 194 additions and 97 deletions
+48 -2
View File
@@ -6,14 +6,44 @@ using BlubbFish.Utils;
namespace ZwayBot {
abstract class AModul {
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 abstract event ModulEvent Update;
public AModul(ZwayController zway, InIReader settings) {
this.HasConfig = false;
this.ConfigPublic = false;
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) { }
@@ -21,5 +51,21 @@ namespace ZwayBot {
public virtual void SetInterconnection(String param, Action<Object> hook, Object data) { }
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) {
if(this.crontime.Minute != DateTime.Now.Minute) {
this.crontime = DateTime.Now;
if (this.ini != null) {
foreach (String item in this.ini.GetSections()) {
if (this.ParseCronString(this.ini.GetValue(item, "cron"))) {
this.SetValues(this.ini.GetValue(item, "set"));
if (this.config.Count != 0) {
foreach (KeyValuePair<String, Dictionary<String, String>> item in this.config) {
if (item.Value.ContainsKey("cron") && item.Value.ContainsKey("set") && this.ParseCronString(item.Value["cron"])) {
this.SetValues(item.Value["set"]);
}
}
}
@@ -157,6 +157,8 @@ namespace ZwayBot.Moduls {
this.internalCron.Add(new Tuple<String, Action<Object>, Object>(cron, hook, data));
}
protected override void UpdateConfig() { }
#region IDisposable Support
private Boolean disposedValue = false;
+17 -11
View File
@@ -20,22 +20,24 @@ namespace ZwayBot.Moduls {
public override event ModulEvent Update;
public Flex4Grid(ZwayController zway, InIReader settings) : base(zway, settings) {
this.mqtt = ADataBackend.GetInstance(this.ini.GetSection("settings"));
if (this.config.ContainsKey("settings")) {
this.mqtt = ADataBackend.GetInstance(this.config["settings"]);
this.ParseIni();
this.mqtt.MessageIncomming += this.Mqtt_MessageIncomming;
}
}
private void ParseIni() {
if (this.ini.GetValue("zway", "devices") != null) {
foreach (String device in this.ini.GetValue("zway", "devices").Split(',')) {
if (this.config.ContainsKey("zway") && this.config["zway"].ContainsKey("devices")) {
foreach (String device in this.config["zway"]["devices"].Split(',')) {
Int32 deviceid = Int32.Parse(device);
if (this.zw.Devices.ContainsKey(deviceid) && this.zw.Devices[deviceid].Instances.ContainsKey(0)) {
this.zw.Devices[deviceid].Instances[0].Update += this.DeviceUpdate;
}
}
}
if(this.ini.GetValue("f4g", "household") != null) {
this.household = this.ini.GetValue("f4g", "household");
if(this.config.ContainsKey("f4g") && this.config["f4g"].ContainsKey("household")) {
this.household = this.config["f4g"]["household"];
}
}
@@ -85,8 +87,8 @@ namespace ZwayBot.Moduls {
if(topic == "/flex4grid/v1/households/" + this.household + "/device/actuate") {
if(message.Keys.Contains("deviceId") && message.Keys.Contains("command")) {
String device = message["deviceId"].ToString();
if(this.ini.GetValue("zway", "devices") != null) {
foreach (String item in this.ini.GetValue("zway", "devices").Split(',')) {
if(this.config.ContainsKey("zway") && this.config["zway"].ContainsKey("devices")) {
foreach (String item in this.config["zway"]["devices"].Split(',')) {
if (item == device) {
Int32 deviceid = Int32.Parse(device);
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 (this.ini.GetValue("zway", "devices") != null) {
if (this.config.ContainsKey("zway") && this.config["zway"].ContainsKey("devices")) {
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);
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)) {
@@ -120,7 +122,8 @@ namespace ZwayBot.Moduls {
}
private void RequestAlive(Object o) {
String raspi = this.ini.GetValue("f4g", "raspi");
if (this.config.ContainsKey("f4g") && this.config["f4g"].ContainsKey("raspi")) {
String raspi = this.config["f4g"]["raspi"];
lock (this.requestalivelock) {
String req = "https://wiki.flex4grid.eu/rupdate/rupdate_general.yml.gpg.asc?gw=" + raspi;
HttpWebRequest request = WebRequest.CreateHttp(req);
@@ -149,9 +152,10 @@ namespace ZwayBot.Moduls {
} catch (Exception) { }
}
}
}
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) {
if (item.Value is CronJob) {
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
private Boolean disposedValue = false;
+53 -18
View File
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using BlubbFish.IoT.Zway;
using BlubbFish.IoT.Zway.Events;
@@ -10,14 +11,17 @@ using LitJson;
namespace ZwayBot.Moduls {
class Mqtt : AModul, IDisposable {
private ADataBackend mqtt;
private Dictionary<String, AModul> modules;
public override event ModulEvent Update;
public Mqtt(ZwayController zway, InIReader settings) : base(zway, settings) {
this.mqtt = ADataBackend.GetInstance(this.ini.GetSection("settings"));
if (this.config.ContainsKey("settings")) {
this.mqtt = ADataBackend.GetInstance(this.config["settings"]);
this.mqtt.MessageIncomming += this.Mqtt_MessageIncomming;
this.zw.Update += this.ZwayEvent;
}
}
private void ZwayEvent(Object sender, DeviceUpdateEvent e) {
String topic = "";
@@ -34,8 +38,8 @@ namespace ZwayBot.Moduls {
}
private void Mqtt_MessageIncomming(Object sender, MqttEventArgs e) {
if (e.Topic.StartsWith("/zwavebot/devices/") && e.Topic.EndsWith("set")) {
Match m = new Regex("^/zwavebot/devices/(\\d+)/(\\d+)/(\\d+)/set$|^/zwavebot/devices/(\\d+)/(\\d+)/(\\d+)/(\\d+)/set$").Match(e.Topic);
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;
@@ -47,35 +51,66 @@ namespace ZwayBot.Moduls {
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)) {
if (c.HasProperty(key)) {
c.SetProperty(key, a[item].ToString());
this.Update?.Invoke(this, new MqttEvent(c.Id, a[item].ToString()));
}
}
} catch (Exception) { }
}
if(e.Topic.StartsWith("/zwavebot/devices/") && e.Topic.EndsWith("get")) {
Match m = new Regex("^/zwavebot/devices/(\\d+)/(\\d+)/(\\d+)/get$|^/zwavebot/devices/(\\d+)/(\\d+)/(\\d+)/(\\d+)/get$").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;
}
} 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
private Boolean disposedValue = false;
+10 -4
View File
@@ -16,10 +16,11 @@ namespace ZwayBot.Moduls {
}
private void ParseIni() {
foreach (String item in this.ini.GetSections()) {
String from = this.ini.GetValue(item, "from");
foreach (KeyValuePair<String, Dictionary<String, String>> item in this.config) {
if (item.Value.ContainsKey("from")) {
String from = item.Value["from"];
String[] source = from.Split(':');
this.events.Add(source[0], this.ini.GetSection(item));
this.events.Add(source[0], item.Value);
ACommandClass c = this.zw.GetCommandClass(source[0]);
if (c != null) {
c.Polling = true;
@@ -27,6 +28,7 @@ namespace ZwayBot.Moduls {
}
}
}
}
private void ChangedEvent(Object sender, DeviceUpdateEvent e) {
if(sender.HasAbstract(typeof(ACommandClass))) {
@@ -56,9 +58,10 @@ namespace ZwayBot.Moduls {
}
}
}
if (dictionary.ContainsKey("to")) {
foreach (String to in dictionary["to"].Split(';')) {
String[] target = to.Split(':');
if(target.Length == 2) {
if (target.Length == 2) {
ACommandClass c = this.zw.GetCommandClass(target[0]);
if (c != null) {
if (c.HasProperty(target[1])) {
@@ -71,6 +74,9 @@ namespace ZwayBot.Moduls {
}
}
}
}
protected override void UpdateConfig() { }
#region IDisposable Support
private Boolean disposedValue = false;
+6 -4
View File
@@ -17,10 +17,10 @@ namespace ZwayBot.Moduls {
foreach (KeyValuePair<String, AModul> item in moduls) {
if (item.Value is CronJob) {
item.Value.SetInterconnection("0 0 * * *", new Action<Object>(this.PollAll), null);
if (this.ini != null) {
foreach (String section in this.ini.GetSections()) {
if (this.ini.GetValue(section, "cron") != null && this.ini.GetValue(section, "devices") != null) {
item.Value.SetInterconnection(this.ini.GetValue(section, "cron"), new Action<Object>(this.PollSpecific), this.ini.GetValue(section, "devices"));
if (this.config.Count != 0) {
foreach (KeyValuePair<String, Dictionary<String, String>> section in this.config) {
if (section.Value.ContainsKey("cron") && section.Value.ContainsKey("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"));
}
protected override void UpdateConfig() { }
public override void Dispose() {}
}
}
+3 -3
View File
@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("BlubbFish")]
[assembly: AssemblyProduct("Zway-Bot")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyCopyright("Copyright © 2017 - 22.12.2017")]
[assembly: AssemblyTrademark("BlubbFish")]
[assembly: AssemblyCulture("")]
@@ -32,8 +32,8 @@ using System.Runtime.InteropServices;
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
// übernehmen, indem Sie "*" eingeben:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.2.2.0")]
[assembly: AssemblyFileVersion("1.2.2.0")]
[assembly: AssemblyVersion("1.3.0.0")]
[assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: NeutralResourcesLanguage("de-DE")]
// “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.