[NF] Funktioniert nun über Konfigfiles
This commit is contained in:
parent
0fe7c5067f
commit
8e9e49e685
@ -33,5 +33,9 @@ namespace Dashboard.Connector {
|
|||||||
private void Client_MqttMsgPublishReceived(Object sender, MqttMsgPublishEventArgs e) {
|
private void Client_MqttMsgPublishReceived(Object sender, MqttMsgPublishEventArgs e) {
|
||||||
this.MessageIncomming?.Invoke(this, e);
|
this.MessageIncomming?.Invoke(this, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Send(String topic, String data) {
|
||||||
|
this.client.Publish(topic, Encoding.UTF8.GetBytes(data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,9 +85,15 @@
|
|||||||
<DependentUpon>Settings.settings</DependentUpon>
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<None Include="sensor.ini">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<None Include="settings.ini">
|
<None Include="settings.ini">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="tracings.ini">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="App.config" />
|
<None Include="App.config" />
|
||||||
|
30
Mqtt-Dashboard/Form1.Designer.cs
generated
30
Mqtt-Dashboard/Form1.Designer.cs
generated
@ -23,15 +23,8 @@
|
|||||||
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
|
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void InitializeComponent() {
|
private void InitializeComponent() {
|
||||||
System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
|
|
||||||
System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
|
|
||||||
System.Windows.Forms.DataVisualization.Charting.DataPoint dataPoint1 = new System.Windows.Forms.DataVisualization.Charting.DataPoint(42955.833344907405D, 10D);
|
|
||||||
System.Windows.Forms.DataVisualization.Charting.DataPoint dataPoint2 = new System.Windows.Forms.DataVisualization.Charting.DataPoint(42955D, 2D);
|
|
||||||
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
|
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
|
||||||
this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel();
|
this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel();
|
||||||
this.chart1 = new System.Windows.Forms.DataVisualization.Charting.Chart();
|
|
||||||
this.flowLayoutPanel2.SuspendLayout();
|
|
||||||
((System.ComponentModel.ISupportInitialize)(this.chart1)).BeginInit();
|
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// statusStrip1
|
// statusStrip1
|
||||||
@ -44,31 +37,11 @@
|
|||||||
//
|
//
|
||||||
// flowLayoutPanel2
|
// flowLayoutPanel2
|
||||||
//
|
//
|
||||||
this.flowLayoutPanel2.Controls.Add(this.chart1);
|
|
||||||
this.flowLayoutPanel2.Location = new System.Drawing.Point(12, 12);
|
this.flowLayoutPanel2.Location = new System.Drawing.Point(12, 12);
|
||||||
this.flowLayoutPanel2.Name = "flowLayoutPanel2";
|
this.flowLayoutPanel2.Name = "flowLayoutPanel2";
|
||||||
this.flowLayoutPanel2.Size = new System.Drawing.Size(819, 289);
|
this.flowLayoutPanel2.Size = new System.Drawing.Size(819, 289);
|
||||||
this.flowLayoutPanel2.TabIndex = 3;
|
this.flowLayoutPanel2.TabIndex = 3;
|
||||||
//
|
//
|
||||||
// chart1
|
|
||||||
//
|
|
||||||
chartArea1.AxisX.LabelStyle.Enabled = false;
|
|
||||||
chartArea1.Name = "ChartArea1";
|
|
||||||
this.chart1.ChartAreas.Add(chartArea1);
|
|
||||||
this.chart1.Location = new System.Drawing.Point(3, 3);
|
|
||||||
this.chart1.Name = "chart1";
|
|
||||||
series1.ChartArea = "ChartArea1";
|
|
||||||
series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
|
|
||||||
series1.Name = "Series1";
|
|
||||||
series1.Points.Add(dataPoint1);
|
|
||||||
series1.Points.Add(dataPoint2);
|
|
||||||
series1.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.DateTime;
|
|
||||||
series1.YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Single;
|
|
||||||
this.chart1.Series.Add(series1);
|
|
||||||
this.chart1.Size = new System.Drawing.Size(101, 66);
|
|
||||||
this.chart1.TabIndex = 0;
|
|
||||||
this.chart1.Text = "chart1";
|
|
||||||
//
|
|
||||||
// Dashboard
|
// Dashboard
|
||||||
//
|
//
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
@ -78,8 +51,6 @@
|
|||||||
this.Controls.Add(this.statusStrip1);
|
this.Controls.Add(this.statusStrip1);
|
||||||
this.Name = "Dashboard";
|
this.Name = "Dashboard";
|
||||||
this.Text = "Dashboard";
|
this.Text = "Dashboard";
|
||||||
this.flowLayoutPanel2.ResumeLayout(false);
|
|
||||||
((System.ComponentModel.ISupportInitialize)(this.chart1)).EndInit();
|
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
this.PerformLayout();
|
this.PerformLayout();
|
||||||
|
|
||||||
@ -89,7 +60,6 @@
|
|||||||
|
|
||||||
private System.Windows.Forms.StatusStrip statusStrip1;
|
private System.Windows.Forms.StatusStrip statusStrip1;
|
||||||
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2;
|
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2;
|
||||||
private System.Windows.Forms.DataVisualization.Charting.Chart chart1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,37 +4,58 @@ using System.Windows.Forms;
|
|||||||
using Dashboard.Connector;
|
using Dashboard.Connector;
|
||||||
using Dashboard.Sensor;
|
using Dashboard.Sensor;
|
||||||
using Dashboard.Tracings;
|
using Dashboard.Tracings;
|
||||||
|
using BlubbFish.Utils;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Dashboard {
|
namespace Dashboard {
|
||||||
public partial class Dashboard : Form {
|
public partial class Dashboard : Form {
|
||||||
|
private Dictionary<String, ASensor> sensors = new Dictionary<string, ASensor>();
|
||||||
public Dashboard() {
|
public Dashboard() {
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Mqtt.Instance.Connect();
|
Mqtt.Instance.Connect();
|
||||||
|
|
||||||
ATracings g1 = new Graph();
|
this.generateSensors();
|
||||||
ASensor s1 = new Power();
|
this.generateForms();
|
||||||
s1.SetMqttTopic("zway/wohnzimmer/thinkpad/power");
|
|
||||||
Mqtt.Instance.MessageIncomming += s1.IncommingMqttMessage;
|
|
||||||
g1.SetSensor(s1);
|
|
||||||
this.flowLayoutPanel2.Controls.Add(g1.GetTracing());
|
|
||||||
|
|
||||||
ATracings g2 = new Graph();
|
|
||||||
ASensor s2 = new Power();
|
|
||||||
s2.SetMqttTopic("zway/wohnzimmer/tV/power");
|
|
||||||
Mqtt.Instance.MessageIncomming += s2.IncommingMqttMessage;
|
|
||||||
g2.SetSensor(s2);
|
|
||||||
this.flowLayoutPanel2.Controls.Add(g2.GetTracing());
|
|
||||||
|
|
||||||
ATracings g3 = new Graph();
|
|
||||||
ASensor s3 = new Power();
|
|
||||||
s3.SetMqttTopic("zway/küche/kuehlschrank/power");
|
|
||||||
Mqtt.Instance.MessageIncomming += s3.IncommingMqttMessage;
|
|
||||||
g3.SetSensor(s3);
|
|
||||||
this.flowLayoutPanel2.Controls.Add(g3.GetTracing());
|
|
||||||
|
|
||||||
Mqtt.Instance.MessageIncomming += this.Instance_MessageIncomming;
|
Mqtt.Instance.MessageIncomming += this.Instance_MessageIncomming;
|
||||||
|
Thread a = new Thread(this.SensorPolling);
|
||||||
|
a.Start();
|
||||||
|
}
|
||||||
|
private void generateSensors() {
|
||||||
|
InIReader ini = InIReader.GetInstance("sensor.ini");
|
||||||
|
List<String> sensorini = ini.GetSections();
|
||||||
|
foreach(String sensor in sensorini) {
|
||||||
|
ASensor s;
|
||||||
|
switch(ini.GetValue(sensor, "type").ToLower()) {
|
||||||
|
case "power": s = new Power(ini.GetSection(sensor)); break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentException("sensor.ini: " + sensor + " section has a missconfiguration in type");
|
||||||
|
}
|
||||||
|
this.sensors.Add(sensor.ToLower().Substring(1, sensor.Length - 2), s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void generateForms() {
|
||||||
|
InIReader ini = InIReader.GetInstance("tracings.ini");
|
||||||
|
List<String> tracingini = ini.GetSections();
|
||||||
|
foreach(String tracing in tracingini) {
|
||||||
|
ATracings t;
|
||||||
|
switch(ini.GetValue(tracing, "type").ToLower()) {
|
||||||
|
case "graph": t = new Graph(this.sensors[ini.GetValue(tracing, "sensor").ToLower()],ini.GetSection(tracing)); break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentException("tracings.ini: " + tracing + " section has a missconfiguration in type");
|
||||||
|
}
|
||||||
|
this.flowLayoutPanel2.Controls.Add(t.GetPanel());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void SensorPolling() {
|
||||||
|
while(true) {
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
foreach(KeyValuePair<String, ASensor> sensor in sensors) {
|
||||||
|
sensor.Value.Poll();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Instance_MessageIncomming(Object sender, uPLibrary.Networking.M2Mqtt.Messages.MqttMsgPublishEventArgs e) {
|
private void Instance_MessageIncomming(Object sender, uPLibrary.Networking.M2Mqtt.Messages.MqttMsgPublishEventArgs e) {
|
||||||
System.Diagnostics.Debug.WriteLine("Received = " + Encoding.UTF8.GetString(e.Message) + " on topic " + e.Topic+" at "+DateTime.Now.ToUniversalTime());
|
System.Diagnostics.Debug.WriteLine("Received = " + Encoding.UTF8.GetString(e.Message) + " on topic " + e.Topic+" at "+DateTime.Now.ToUniversalTime());
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,31 @@
|
|||||||
using System;
|
using Dashboard.Connector;
|
||||||
|
using System;
|
||||||
using uPLibrary.Networking.M2Mqtt.Messages;
|
using uPLibrary.Networking.M2Mqtt.Messages;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Dashboard.Sensor {
|
namespace Dashboard.Sensor {
|
||||||
public abstract class ASensor {
|
public abstract class ASensor {
|
||||||
private String topic;
|
private String topic;
|
||||||
|
private Int32 pollcount;
|
||||||
|
private Dictionary<String, String> settings;
|
||||||
public enum Types {
|
public enum Types {
|
||||||
Bool,
|
Bool,
|
||||||
Int,
|
Int,
|
||||||
Float
|
Float
|
||||||
}
|
}
|
||||||
public void SetMqttTopic(String topic) {
|
|
||||||
this.topic = topic;
|
|
||||||
}
|
|
||||||
public delegate void UpdatedValue(Object sender, EventArgs e);
|
public delegate void UpdatedValue(Object sender, EventArgs e);
|
||||||
public event UpdatedValue Update;
|
public event UpdatedValue Update;
|
||||||
internal void IncommingMqttMessage(Object sender, MqttMsgPublishEventArgs e) {
|
|
||||||
|
public ASensor(Dictionary<String, String> settings) {
|
||||||
|
this.topic = (settings.Keys.Contains("topic")) ? settings["topic"] : "";
|
||||||
|
this.Polling = (settings.Keys.Contains("polling")) ? Int32.Parse(settings["polling"]) : 60;
|
||||||
|
this.pollcount = this.Polling;
|
||||||
|
this.settings = settings;
|
||||||
|
Mqtt.Instance.MessageIncomming += this.IncommingMqttMessage;
|
||||||
|
}
|
||||||
|
private void IncommingMqttMessage(Object sender, MqttMsgPublishEventArgs e) {
|
||||||
if(e.Topic == this.topic) {
|
if(e.Topic == this.topic) {
|
||||||
this.UpdateValue(e);
|
this.UpdateValue(e);
|
||||||
this.Timestamp = DateTime.Now;
|
this.Timestamp = DateTime.Now;
|
||||||
@ -27,5 +38,12 @@ namespace Dashboard.Sensor {
|
|||||||
public Boolean GetBool { get; protected set; }
|
public Boolean GetBool { get; protected set; }
|
||||||
public Types Datatypes { get; protected set; }
|
public Types Datatypes { get; protected set; }
|
||||||
public DateTime Timestamp { get; protected set; }
|
public DateTime Timestamp { get; protected set; }
|
||||||
|
public int Polling { get; private set; }
|
||||||
|
public void Poll() {
|
||||||
|
if(this.pollcount++ >= Polling) {
|
||||||
|
this.pollcount = 1;
|
||||||
|
Mqtt.Instance.Send(this.topic + "/status","");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,17 +1,17 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using uPLibrary.Networking.M2Mqtt.Messages;
|
using uPLibrary.Networking.M2Mqtt.Messages;
|
||||||
|
|
||||||
namespace Dashboard.Sensor {
|
namespace Dashboard.Sensor {
|
||||||
class Power : ASensor {
|
class Power : ASensor {
|
||||||
public Power() {
|
public Power(Dictionary<String, String> settings) : base(settings) {
|
||||||
this.GetBool = true;
|
this.GetBool = true;
|
||||||
this.GetFloat = 0.0f;
|
this.GetFloat = 0.0f;
|
||||||
this.GetInt = 0;
|
this.GetInt = 0;
|
||||||
this.Datatypes = Types.Float;
|
this.Datatypes = Types.Float;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateValue(MqttMsgPublishEventArgs e) {
|
protected override void UpdateValue(MqttMsgPublishEventArgs e) {
|
||||||
this.GetFloat = Single.Parse(Encoding.UTF8.GetString(e.Message), new CultureInfo("en-US"));
|
this.GetFloat = Single.Parse(Encoding.UTF8.GetString(e.Message), new CultureInfo("en-US"));
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using Dashboard.Sensor;
|
using Dashboard.Sensor;
|
||||||
|
|
||||||
namespace Dashboard.Tracings {
|
namespace Dashboard.Tracings {
|
||||||
public abstract class ATracings {
|
public abstract class ATracings {
|
||||||
protected ASensor sensor;
|
protected ASensor sensor;
|
||||||
public void SetSensor(ASensor sensor) {
|
private Dictionary<String, String> settings;
|
||||||
|
|
||||||
|
public ATracings(ASensor sensor, Dictionary<String, String> settings) {
|
||||||
this.sensor = sensor;
|
this.sensor = sensor;
|
||||||
this.sensor.Update += this.SensorUpdate;
|
this.sensor.Update += this.SensorUpdate;
|
||||||
|
this.settings = settings;
|
||||||
}
|
}
|
||||||
protected abstract void SensorUpdate(Object sender, EventArgs e);
|
protected abstract void SensorUpdate(Object sender, EventArgs e);
|
||||||
public abstract Panel GetTracing();
|
public abstract Panel GetPanel();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,24 +1,39 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using System.Windows.Forms.DataVisualization.Charting;
|
using System.Windows.Forms.DataVisualization.Charting;
|
||||||
|
using Dashboard.Sensor;
|
||||||
|
|
||||||
namespace Dashboard.Tracings {
|
namespace Dashboard.Tracings {
|
||||||
class Graph : ATracings {
|
class Graph : ATracings {
|
||||||
private Series series;
|
private Series series;
|
||||||
private Chart chart;
|
private Chart chart;
|
||||||
|
|
||||||
public override Panel GetTracing() {
|
public Graph(ASensor sensor, Dictionary<String, String> settings) : base(sensor, settings) { }
|
||||||
|
public override Panel GetPanel() {
|
||||||
Panel panel = new Panel();
|
Panel panel = new Panel();
|
||||||
|
|
||||||
this.chart = new Chart();
|
this.chart = new Chart();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
|
||||||
ChartArea chartArea = new ChartArea();
|
ChartArea chartArea = new ChartArea();
|
||||||
chartArea.AxisX.LabelStyle.Enabled = false;
|
chartArea.AxisX.LabelStyle.Enabled = false;
|
||||||
|
chartArea.AxisX.LineColor = System.Drawing.Color.Gainsboro;
|
||||||
|
chartArea.AxisX.MajorGrid.LineColor = System.Drawing.Color.Gainsboro;
|
||||||
|
chartArea.AxisX.MinorGrid.Enabled = true;
|
||||||
|
chartArea.AxisX.MinorGrid.LineColor = System.Drawing.Color.Gainsboro;
|
||||||
|
chartArea.AxisX.MinorGrid.LineDashStyle = ChartDashStyle.Dot;
|
||||||
|
|
||||||
|
chartArea.AxisY.LineColor = System.Drawing.Color.Gainsboro;
|
||||||
|
chartArea.AxisY.MajorGrid.LineColor = System.Drawing.Color.Gainsboro;
|
||||||
|
chartArea.AxisY.MinorGrid.Enabled = true;
|
||||||
|
chartArea.AxisY.MinorGrid.LineColor = System.Drawing.Color.Gainsboro;
|
||||||
|
chartArea.AxisY.MinorGrid.LineDashStyle = ChartDashStyle.Dot;
|
||||||
this.chart.ChartAreas.Add(chartArea);
|
this.chart.ChartAreas.Add(chartArea);
|
||||||
this.series = new Series() {
|
this.series = new Series() {
|
||||||
ChartType = SeriesChartType.Line,
|
ChartType = SeriesChartType.Line,
|
||||||
XValueType = ChartValueType.DateTime
|
XValueType = ChartValueType.DateTime,
|
||||||
};
|
Color = System.Drawing.Color.Red
|
||||||
|
};
|
||||||
if (this.sensor.Datatypes == Sensor.ASensor.Types.Bool) {
|
if (this.sensor.Datatypes == Sensor.ASensor.Types.Bool) {
|
||||||
this.series.YValueType = ChartValueType.Int32;
|
this.series.YValueType = ChartValueType.Int32;
|
||||||
} else if (this.sensor.Datatypes == Sensor.ASensor.Types.Int) {
|
} else if (this.sensor.Datatypes == Sensor.ASensor.Types.Int) {
|
||||||
@ -36,16 +51,15 @@ namespace Dashboard.Tracings {
|
|||||||
panel.ResumeLayout(false);
|
panel.ResumeLayout(false);
|
||||||
return panel;
|
return panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void SensorUpdate(Object sender, EventArgs e) {
|
protected override void SensorUpdate(Object sender, EventArgs e) {
|
||||||
this.chart.BeginInvoke((MethodInvoker)delegate {
|
this.chart.BeginInvoke((MethodInvoker)delegate {
|
||||||
if (this.sensor.Datatypes == Sensor.ASensor.Types.Bool) {
|
if (this.sensor.Datatypes == ASensor.Types.Bool) {
|
||||||
this.series.Points.AddXY(this.sensor.Timestamp, (this.sensor.GetBool) ? 1 : 0);
|
this.series.Points.AddXY(this.sensor.Timestamp, (this.sensor.GetBool) ? 1 : 0);
|
||||||
}
|
}
|
||||||
if (this.sensor.Datatypes == Sensor.ASensor.Types.Int) {
|
if (this.sensor.Datatypes == ASensor.Types.Int) {
|
||||||
this.series.Points.AddXY(this.sensor.Timestamp, this.sensor.GetInt);
|
this.series.Points.AddXY(this.sensor.Timestamp, this.sensor.GetInt);
|
||||||
}
|
}
|
||||||
if (this.sensor.Datatypes == Sensor.ASensor.Types.Float) {
|
if (this.sensor.Datatypes == ASensor.Types.Float) {
|
||||||
this.series.Points.AddXY(this.sensor.Timestamp, this.sensor.GetFloat);
|
this.series.Points.AddXY(this.sensor.Timestamp, this.sensor.GetFloat);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
8
Mqtt-Dashboard/sensor.ini
Normal file
8
Mqtt-Dashboard/sensor.ini
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[Ventilator]
|
||||||
|
topic=zway/power/test/wVentilator
|
||||||
|
type=Power
|
||||||
|
polling=10
|
||||||
|
|
||||||
|
;zway/wohnzimmer/thinkpad/power
|
||||||
|
;zway/wohnzimmer/tV/power
|
||||||
|
;zway/küche/kuehlschrank/power
|
3
Mqtt-Dashboard/tracings.ini
Normal file
3
Mqtt-Dashboard/tracings.ini
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[VentilatorGraph]
|
||||||
|
sensor=Ventilator
|
||||||
|
type=Graph
|
Loading…
Reference in New Issue
Block a user