[NF] Senml now has a configure option to setup the guid [NF] Zway-Bot now listen on /exit [NF] Implment searchpath for Zway-Bot (/etc/zwaybot and %appdata%/zwaybot)
135 lines
5.1 KiB
C#
135 lines
5.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text.RegularExpressions;
|
|
using BlubbFish.IoT.Zway;
|
|
using BlubbFish.IoT.Zway.Events;
|
|
using BlubbFish.IoT.Zway.Interfaces;
|
|
using BlubbFish.Utils;
|
|
using BlubbFish.Utils.IoT.Connector;
|
|
using BlubbFish.Utils.IoT.Events;
|
|
using LitJson;
|
|
|
|
namespace ZwayBot.Moduls {
|
|
class Mqtt : AModul, IDisposable {
|
|
private ABackend mqtt;
|
|
private Dictionary<String, AModul> modules;
|
|
|
|
public override event ModulEvent Update;
|
|
|
|
public Mqtt(ZwayController zway, InIReader settings) : base(zway, settings) {
|
|
if (this.config.ContainsKey("settings")) {
|
|
this.mqtt = ABackend.GetInstance(this.config["settings"], ABackend.BackendType.Data);
|
|
this.mqtt.MessageIncomming += this.Mqtt_MessageIncomming;
|
|
this.zw.Update += this.ZwayEvent;
|
|
}
|
|
}
|
|
|
|
private void ZwayEvent(Object sender, DeviceUpdateEvent e) {
|
|
String topic = "";
|
|
String data = "";
|
|
if(e.Parent.HasAbstract(typeof(ACommandClass))) {
|
|
ACommandClass sensor = (ACommandClass)e.Parent;
|
|
topic = "/zwavebot/devices/" + sensor.MqttTopic();
|
|
data = sensor.ToJson();
|
|
}
|
|
if(topic != "" && data != "") {
|
|
((ADataBackend)this.mqtt).Send(topic, data);
|
|
this.Update?.Invoke(this, new MqttEvent(topic, data));
|
|
}
|
|
}
|
|
|
|
private void Mqtt_MessageIncomming(Object sender, BackendEvent e) {
|
|
if (e.From.ToString().StartsWith("/zwavebot/devices/") && (e.From.ToString().EndsWith("/set") || e.From.ToString().EndsWith("/get"))) {
|
|
Match m = new Regex("^/zwavebot/devices/(\\d+)/(\\d+)/(\\d+)/[gs]et$|^/zwavebot/devices/(\\d+)/(\\d+)/(\\d+)/(\\d+)/[gs]et$").Match(e.From.ToString());
|
|
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.From.ToString().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.From.ToString().EndsWith("/get")) {
|
|
c.PollOnce = true;
|
|
((ADataBackend)this.mqtt).Send("/zwavebot/devices/" + c.MqttTopic(), c.ToJson());
|
|
this.Update?.Invoke(this, new MqttEvent(e.From.ToString(), "Dataget"));
|
|
}
|
|
}
|
|
if (e.From.ToString().StartsWith("/zwavebot/config/") && (e.From.ToString().EndsWith("/set") || e.From.ToString().EndsWith("/get"))) {
|
|
Match m = new Regex("^/zwavebot/config/(\\w+)/[gs]et$|").Match(e.From.ToString());
|
|
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.From.ToString().EndsWith("/get") && modul.HasConfig && modul.ConfigPublic) {
|
|
String topic = "/zwavebot/config/" + m.Groups[1].Value;
|
|
String data = JsonMapper.ToJson(modul.GetConfig()).ToString();
|
|
((ADataBackend)this.mqtt).Send(topic, data);
|
|
this.Update?.Invoke(this, new MqttEvent(topic, data));
|
|
}
|
|
if (e.From.ToString().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;
|
|
|
|
protected virtual void Dispose(Boolean disposing) {
|
|
if (!this.disposedValue) {
|
|
if (disposing) {
|
|
this.mqtt.Dispose();
|
|
}
|
|
this.disposedValue = true;
|
|
}
|
|
}
|
|
|
|
public override void Dispose() {
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|