init sensormat
This commit is contained in:
commit
e21b483862
358
.gitignore
vendored
Normal file
358
.gitignore
vendored
Normal file
@ -0,0 +1,358 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
*.7z
|
||||
*.mde
|
||||
|
||||
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
nuget.exe
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
#/Office Line/8.1/MHK81/LBAbfKirstein81 - Kopie.laccdb
|
||||
38
Sensormat/ESP8266_Gaszaehler/ESP8266_Gaszaehler.cs
Normal file
38
Sensormat/ESP8266_Gaszaehler/ESP8266_Gaszaehler.cs
Normal file
@ -0,0 +1,38 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: Sensormat.ESP8266_Gaszaehler.ESP8266_Gaszaehler
|
||||
// Assembly: ESP8266_Gaszaehler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: 4783B34D-C78D-4F6E-946E-4E4DC92855C4
|
||||
// Assembly location: \\192.168.178.26\Freigabe\ESP8266_Gaszaehler.dll
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Sensormat.Entities;
|
||||
using System;
|
||||
|
||||
#nullable disable
|
||||
namespace Sensormat.ESP8266_Gaszaehler
|
||||
{
|
||||
public class ESP8266_Gaszaehler : ISensor
|
||||
{
|
||||
public override bool Execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
int id = this.Sensor.ID;
|
||||
new ResultSet().XMLSerializeData<ResultSet>();
|
||||
string str = this.HttpRequest(this.Sensor.URL);
|
||||
if (str != null)
|
||||
{
|
||||
this.LastValue = JsonConvert.DeserializeObject<ResultSet>(str).GasMeter;
|
||||
this.LastValueDate = new DateTime?(DateTime.Now);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine((object)ex);
|
||||
this.ErrorMsg = ex.Message;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
18
Sensormat/ESP8266_Gaszaehler/ESP8266_Gaszaehler.csproj
Normal file
18
Sensormat/ESP8266_Gaszaehler/ESP8266_Gaszaehler.csproj
Normal file
@ -0,0 +1,18 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Sensormat\Sensormat.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\Sensormat\References\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
24
Sensormat/ESP8266_Gaszaehler/ResultSet.cs
Normal file
24
Sensormat/ESP8266_Gaszaehler/ResultSet.cs
Normal file
@ -0,0 +1,24 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: Sensormat.ESP8266_Gaszaehler.ResultSet
|
||||
// Assembly: ESP8266_Gaszaehler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: 4783B34D-C78D-4F6E-946E-4E4DC92855C4
|
||||
// Assembly location: \\192.168.178.26\Freigabe\ESP8266_Gaszaehler.dll
|
||||
|
||||
using System;
|
||||
|
||||
#nullable disable
|
||||
namespace Sensormat.ESP8266_Gaszaehler
|
||||
{
|
||||
public class ResultSet
|
||||
{
|
||||
public DateTime? StartTime { get; set; }
|
||||
|
||||
public string Version { get; set; }
|
||||
|
||||
public int WIFIConnectCounter { get; set; }
|
||||
|
||||
public string GasMeter { get; set; }
|
||||
|
||||
public string ErrorMsg { get; set; }
|
||||
}
|
||||
}
|
||||
206
Sensormat/FritzBox/API/FritzWebAccess/FritzSoapAccess.cs
Normal file
206
Sensormat/FritzBox/API/FritzWebAccess/FritzSoapAccess.cs
Normal file
@ -0,0 +1,206 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: FritzBox.API.FritzWebAccess.FritzSoapAccess
|
||||
// Assembly: FritzBox, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: DC9FD63C-0A96-43D7-A76E-0506FEB07200
|
||||
// Assembly location: \\192.168.178.26\Freigabe\FritzBox.dll
|
||||
|
||||
using FritzBox.API.FritzWebAccess.SoapTypes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Xml.XPath;
|
||||
|
||||
#nullable disable
|
||||
namespace FritzBox.API.FritzWebAccess
|
||||
{
|
||||
public class FritzSoapAccess
|
||||
{
|
||||
public Uri BaseAddress { get; set; } = new Uri("https://fritz.box/");
|
||||
|
||||
public string Username { get; set; } = "admin";
|
||||
|
||||
public string Password { get; set; } = string.Empty;
|
||||
|
||||
public int GetHostNumberOfEntries()
|
||||
{
|
||||
string elementValue = this.GetElementValue(((WebResponse)this.SendSoapRequest("tr064/upnp/control/hosts", "urn:dslforum-org:service:Hosts:1#GetHostNumberOfEntries")).GetResponseStream(), "NewHostNumberOfEntries");
|
||||
return elementValue != null ? Convert.ToInt32(elementValue) : -1;
|
||||
}
|
||||
|
||||
public HostInfo GetGenericHostEntryExt(int index)
|
||||
{
|
||||
Dictionary<string, string> elementValues = this.GetElementValues(((WebResponse)this.SendSoapRequest("tr064/upnp/control/hosts", "urn:dslforum-org:service:Hosts:1#X_AVM-DE_GetGenericHostEntryExt", new Dictionary<string, string>()
|
||||
{
|
||||
{
|
||||
"NewIndex",
|
||||
index.ToString()
|
||||
}
|
||||
})).GetResponseStream(), (IEnumerable<string>)new string[7]
|
||||
{
|
||||
"NewIPAddress",
|
||||
"NewMACAddress",
|
||||
"NewActive",
|
||||
"NewHostName",
|
||||
"NewInterfaceType",
|
||||
"NewX_AVM-DE_Port",
|
||||
"NewX_AVM-DE_Speed"
|
||||
});
|
||||
return new HostInfo()
|
||||
{
|
||||
IPAddress = elementValues["NewIPAddress"],
|
||||
MACAddress = elementValues["NewMACAddress"],
|
||||
IsActive = elementValues["NewActive"] == "1",
|
||||
HostName = elementValues["NewHostName"],
|
||||
InterfaceType = elementValues["NewInterfaceType"],
|
||||
Port = elementValues["NewX_AVM-DE_Port"],
|
||||
Speed = elementValues["NewX_AVM-DE_Speed"]
|
||||
};
|
||||
}
|
||||
|
||||
public int GetTotalBytesSent()
|
||||
{
|
||||
string elementValue = this.GetElementValue(((WebResponse)this.SendSoapRequest("tr064/upnp/control/wancommonifconfig1", "urn:dslforum-org:service:WANCommonInterfaceConfig:1#GetTotalBytesSent")).GetResponseStream(), "NewTotalBytesSent");
|
||||
return elementValue == null ? -1 : Convert.ToInt32(elementValue);
|
||||
}
|
||||
|
||||
public int GetTotalBytesReceived()
|
||||
{
|
||||
string elementValue = this.GetElementValue(((WebResponse)this.SendSoapRequest("tr064/upnp/control/wancommonifconfig1", "urn:dslforum-org:service:WANCommonInterfaceConfig:1#GetTotalBytesReceived")).GetResponseStream(), "NewTotalBytesReceived");
|
||||
return elementValue == null ? -1 : Convert.ToInt32(elementValue);
|
||||
}
|
||||
|
||||
public CommonLinkProperties GetCommonLinkProperties()
|
||||
{
|
||||
Dictionary<string, string> elementValues = this.GetElementValues(((WebResponse)this.SendSoapRequest("tr064/upnp/control/wancommonifconfig1", "urn:dslforum-org:service:WANCommonInterfaceConfig:1#GetCommonLinkProperties")).GetResponseStream(), (IEnumerable<string>)new string[4]
|
||||
{
|
||||
"NewWANAccessType",
|
||||
"NewLayer1UpstreamMaxBitRate",
|
||||
"NewLayer1DownstreamMaxBitRate",
|
||||
"NewPhysicalLinkStatus"
|
||||
});
|
||||
return new CommonLinkProperties()
|
||||
{
|
||||
AccessType = elementValues["NewWANAccessType"],
|
||||
MaxUpstreamBitRate = elementValues["NewLayer1UpstreamMaxBitRate"],
|
||||
MaxDownstreamBitRate = elementValues["NewLayer1DownstreamMaxBitRate"],
|
||||
Status = elementValues["NewPhysicalLinkStatus"]
|
||||
};
|
||||
}
|
||||
|
||||
public DslInterfaceInfo GetDslInterfaceInfo()
|
||||
{
|
||||
Dictionary<string, string> elementValues = this.GetElementValues(((WebResponse)this.SendSoapRequest("tr064/upnp/control/wandslifconfig1", "urn:dslforum-org:service:WANDSLInterfaceConfig:1#GetInfo")).GetResponseStream(), (IEnumerable<string>)new string[9]
|
||||
{
|
||||
"NewStatus",
|
||||
"NewUpstreamCurrRate",
|
||||
"NewDownstreamCurrRate",
|
||||
"NewUpstreamMaxRate",
|
||||
"NewDownstreamMaxRate",
|
||||
"NewUpstreamNoiseMargin",
|
||||
"NewDownstreamNoiseMargin",
|
||||
"NewUpstreamAttenuation",
|
||||
"NewDownstreamAttenuation"
|
||||
});
|
||||
return new DslInterfaceInfo()
|
||||
{
|
||||
Status = elementValues["NewStatus"],
|
||||
CurrentUpstreamRate = elementValues["NewUpstreamCurrRate"],
|
||||
CurrentDownstreamRate = elementValues["NewDownstreamCurrRate"],
|
||||
MaxUpstreamRate = elementValues["NewUpstreamMaxRate"],
|
||||
MaxDownstreamRate = elementValues["NewDownstreamMaxRate"],
|
||||
UpstreamNoiseMargin = elementValues["NewUpstreamNoiseMargin"],
|
||||
DownstreamNoiseMargin = elementValues["NewDownstreamNoiseMargin"],
|
||||
UpstreamAttenuation = elementValues["NewUpstreamAttenuation"],
|
||||
DownstreamAttenuation = elementValues["NewDownstreamAttenuation"]
|
||||
};
|
||||
}
|
||||
|
||||
public string GetExternalIPAddress()
|
||||
{
|
||||
return this.GetElementValue(((WebResponse)this.SendSoapRequest("tr064/upnp/control/wanpppconn1", "urn:dslforum-org:service:WANPPPConnection:1#GetExternalIPAddress")).GetResponseStream(), "NewExternalIPAddress");
|
||||
}
|
||||
|
||||
public WirelessLanInfo GetWirelessLanInfo()
|
||||
{
|
||||
Dictionary<string, string> elementValues = this.GetElementValues(((WebResponse)this.SendSoapRequest("tr064/upnp/control/wlanconfig1", "urn:dslforum-org:service:WLANConfiguration:1#GetInfo")).GetResponseStream(), (IEnumerable<string>)new string[4]
|
||||
{
|
||||
"NewEnable",
|
||||
"NewStatus",
|
||||
"NewChannel",
|
||||
"NewSSID"
|
||||
});
|
||||
return new WirelessLanInfo()
|
||||
{
|
||||
IsEnabled = elementValues["NewEnable"] == "1",
|
||||
Status = elementValues["NewStatus"],
|
||||
Channel = elementValues["NewChannel"],
|
||||
SSID = elementValues["NewSSID"]
|
||||
};
|
||||
}
|
||||
|
||||
public void SetWirelessLan(bool enable)
|
||||
{
|
||||
this.SendSoapRequest("tr064/upnp/control/wlanconfig1", "urn:dslforum-org:service:WLANConfiguration:1#SetEnable", new Dictionary<string, string>()
|
||||
{
|
||||
{
|
||||
"NewEnable",
|
||||
enable ? "1" : "0"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private HttpWebResponse SendSoapRequest(
|
||||
string relativeUrl,
|
||||
string soapAction,
|
||||
Dictionary<string, string> soapActionParameters = null)
|
||||
{
|
||||
HttpWebRequest httpWebRequest = WebRequest.Create(new Uri(this.BaseAddress, relativeUrl)) as HttpWebRequest;
|
||||
httpWebRequest.Method = "POST";
|
||||
httpWebRequest.ContentType = "text/xml; charset=utf-8";
|
||||
httpWebRequest.Headers.Add("SOAPAction", soapAction);
|
||||
httpWebRequest.Credentials = (ICredentials)new NetworkCredential(this.Username, this.Password);
|
||||
string[] strArray = soapAction.Split('#', StringSplitOptions.None);
|
||||
StreamWriter streamWriter = new StreamWriter(((WebRequest)httpWebRequest).GetRequestStream(), Encoding.ASCII);
|
||||
((TextWriter)streamWriter).WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
|
||||
((TextWriter)streamWriter).WriteLine("<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">");
|
||||
((TextWriter)streamWriter).WriteLine("<s:Body>");
|
||||
if (soapActionParameters == null)
|
||||
{
|
||||
((TextWriter)streamWriter).WriteLine("<{1} xmlns=\"{0}\"/>", (object)strArray[0], (object)strArray[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
((TextWriter)streamWriter).WriteLine("<{1} xmlns=\"{0}\">", (object)strArray[0], (object)strArray[1]);
|
||||
foreach (string key in soapActionParameters.Keys)
|
||||
((TextWriter)streamWriter).WriteLine("<{0}>{1}</{0}>", (object)key, (object)soapActionParameters[key]);
|
||||
((TextWriter)streamWriter).WriteLine("</{0}>", (object)strArray[1]);
|
||||
}
|
||||
((TextWriter)streamWriter).WriteLine("</s:Body>");
|
||||
((TextWriter)streamWriter).WriteLine("</s:Envelope>");
|
||||
((TextWriter)streamWriter).Close();
|
||||
return httpWebRequest.GetResponse() as HttpWebResponse;
|
||||
}
|
||||
|
||||
private string GetElementValue(Stream xmlStream, string elementName)
|
||||
{
|
||||
return ((XPathItem)new XPathDocument(xmlStream).CreateNavigator().SelectSingleNode("//" + elementName))?.Value;
|
||||
}
|
||||
|
||||
private Dictionary<string, string> GetElementValues(
|
||||
Stream xmlStream,
|
||||
IEnumerable<string> elementNames)
|
||||
{
|
||||
Dictionary<string, string> elementValues = new Dictionary<string, string>();
|
||||
XPathNavigator navigator = new XPathDocument(xmlStream).CreateNavigator();
|
||||
foreach (string elementName in elementNames)
|
||||
{
|
||||
XPathNavigator xpathNavigator = navigator.SelectSingleNode("//" + elementName);
|
||||
if (xpathNavigator != null)
|
||||
elementValues[elementName] = ((XPathItem)xpathNavigator).Value;
|
||||
}
|
||||
return elementValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
87
Sensormat/FritzBox/API/FritzWebAccess/FritzWebAccess.cs
Normal file
87
Sensormat/FritzBox/API/FritzWebAccess/FritzWebAccess.cs
Normal file
@ -0,0 +1,87 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: FritzBox.API.FritzWebAccess.FritzWebAccess
|
||||
// Assembly: FritzBox, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: DC9FD63C-0A96-43D7-A76E-0506FEB07200
|
||||
// Assembly location: \\192.168.178.26\Freigabe\FritzBox.dll
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
|
||||
#nullable disable
|
||||
namespace FritzBox.API.FritzWebAccess
|
||||
{
|
||||
public class FritzWebAccess
|
||||
{
|
||||
public Uri Address { get; set; } = new Uri("http://fritz.box/");
|
||||
|
||||
public Uri SoapAddress => new Uri(this.Address.Scheme + "://" + this.Address.Host + ":49000/");
|
||||
|
||||
public string SessionId { get; private set; }
|
||||
|
||||
public bool IsAuthenticated
|
||||
{
|
||||
get => !string.IsNullOrEmpty(this.SessionId) && this.SessionId != "0000000000000000";
|
||||
}
|
||||
|
||||
public FritzWebAccess()
|
||||
{
|
||||
}
|
||||
|
||||
public FritzWebAccess(string username, string password) => this.LogIn(username, password);
|
||||
|
||||
public void LogIn(string password) => this.LogIn(string.Empty, password);
|
||||
|
||||
public void LogIn(string username, string password)
|
||||
{
|
||||
Uri uri = new Uri(this.Address, "login_sid.lua");
|
||||
XDocument doc = XDocument.Load(uri.AbsoluteUri);
|
||||
this.SessionId = this.GetValue(doc, "SID");
|
||||
if (this.IsAuthenticated)
|
||||
return;
|
||||
string challenge = this.GetValue(doc, "Challenge");
|
||||
this.SessionId = this.GetValue(XDocument.Load(string.Format("{0}?username={1}&response={2}", (object)uri.AbsoluteUri, (object)username, (object)this.GetAuthResponse(challenge, password))), "SID");
|
||||
}
|
||||
|
||||
private string GetValue(XDocument doc, string elementName)
|
||||
{
|
||||
return (doc.FirstNode as XElement).Element((XName)elementName).Value;
|
||||
}
|
||||
|
||||
private string GetAuthResponse(string challenge, string password)
|
||||
{
|
||||
return challenge + "-" + this.GetMD5Hash(challenge + "-" + password);
|
||||
}
|
||||
|
||||
private string GetMD5Hash(string input)
|
||||
{
|
||||
byte[] hash = MD5.Create().ComputeHash(Encoding.Unicode.GetBytes(input));
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int index = 0; index < hash.Length; ++index)
|
||||
stringBuilder.Append(hash[index].ToString("x2"));
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
public string GetWebContent(string relativeUrl, string parameter = "")
|
||||
{
|
||||
return this.GetContent(this.Address, relativeUrl, parameter);
|
||||
}
|
||||
|
||||
public string GetSoapContent(string relativeUrl, string parameter = "")
|
||||
{
|
||||
return this.GetContent(this.SoapAddress, relativeUrl, parameter);
|
||||
}
|
||||
|
||||
public string GetContent(Uri baseAddress, string relativeUrl, string parameter = "")
|
||||
{
|
||||
using (HttpWebResponse response = (WebRequest.Create(new Uri(baseAddress, relativeUrl + "?sid=" + this.SessionId + parameter)) as HttpWebRequest).GetResponse() as HttpWebResponse)
|
||||
{
|
||||
using (StreamReader streamReader = new StreamReader(((WebResponse)response).GetResponseStream()))
|
||||
return ((TextReader)streamReader).ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: FritzBox.API.FritzWebAccess.SoapTypes.CommonLinkProperties
|
||||
// Assembly: FritzBox, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: DC9FD63C-0A96-43D7-A76E-0506FEB07200
|
||||
// Assembly location: \\192.168.178.26\Freigabe\FritzBox.dll
|
||||
|
||||
#nullable disable
|
||||
namespace FritzBox.API.FritzWebAccess.SoapTypes
|
||||
{
|
||||
public class CommonLinkProperties
|
||||
{
|
||||
public string AccessType { get; set; }
|
||||
|
||||
public string MaxUpstreamBitRate { get; set; }
|
||||
|
||||
public string MaxDownstreamBitRate { get; set; }
|
||||
|
||||
public string Status { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("AccessType: {0}, MaxUpstreamBitRate: {1}, MaxDownstreamBitRate: {2}, Status: {3}", (object)this.AccessType, (object)this.MaxUpstreamBitRate, (object)this.MaxDownstreamBitRate, (object)this.Status);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: FritzBox.API.FritzWebAccess.SoapTypes.DslInterfaceInfo
|
||||
// Assembly: FritzBox, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: DC9FD63C-0A96-43D7-A76E-0506FEB07200
|
||||
// Assembly location: \\192.168.178.26\Freigabe\FritzBox.dll
|
||||
|
||||
#nullable disable
|
||||
namespace FritzBox.API.FritzWebAccess.SoapTypes
|
||||
{
|
||||
public class DslInterfaceInfo
|
||||
{
|
||||
public string Status { get; set; }
|
||||
|
||||
public string CurrentUpstreamRate { get; set; }
|
||||
|
||||
public string CurrentDownstreamRate { get; set; }
|
||||
|
||||
public string MaxUpstreamRate { get; set; }
|
||||
|
||||
public string MaxDownstreamRate { get; set; }
|
||||
|
||||
public string UpstreamNoiseMargin { get; set; }
|
||||
|
||||
public string DownstreamNoiseMargin { get; set; }
|
||||
|
||||
public string UpstreamAttenuation { get; set; }
|
||||
|
||||
public string DownstreamAttenuation { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("Status: {0}, Up/Down- RateCurrent: {1}/{2}, RateMax: {3}/{4}, NoiseMargin: {5}/{6}, Attenuation: {7}/{8}", (object)this.Status, (object)this.CurrentUpstreamRate, (object)this.CurrentDownstreamRate, (object)this.MaxUpstreamRate, (object)this.MaxDownstreamRate, (object)this.UpstreamNoiseMargin, (object)this.DownstreamNoiseMargin, (object)this.UpstreamAttenuation, (object)this.DownstreamAttenuation);
|
||||
}
|
||||
}
|
||||
}
|
||||
31
Sensormat/FritzBox/API/FritzWebAccess/SoapTypes/HostInfo.cs
Normal file
31
Sensormat/FritzBox/API/FritzWebAccess/SoapTypes/HostInfo.cs
Normal file
@ -0,0 +1,31 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: FritzBox.API.FritzWebAccess.SoapTypes.HostInfo
|
||||
// Assembly: FritzBox, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: DC9FD63C-0A96-43D7-A76E-0506FEB07200
|
||||
// Assembly location: \\192.168.178.26\Freigabe\FritzBox.dll
|
||||
|
||||
#nullable disable
|
||||
namespace FritzBox.API.FritzWebAccess.SoapTypes
|
||||
{
|
||||
public class HostInfo
|
||||
{
|
||||
public string IPAddress { get; set; }
|
||||
|
||||
public string MACAddress { get; set; }
|
||||
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
public string HostName { get; set; }
|
||||
|
||||
public string InterfaceType { get; set; }
|
||||
|
||||
public string Port { get; set; }
|
||||
|
||||
public string Speed { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("IP: {0}, MAC: {1}, IsActive: {2}, HostName: {3}, Interface: {4}, Port: {5}, Speed: {6}", (object)this.IPAddress, (object)this.MACAddress, (object)this.IsActive, (object)this.HostName, (object)this.InterfaceType, (object)this.Port, (object)this.Speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: FritzBox.API.FritzWebAccess.SoapTypes.WirelessLanInfo
|
||||
// Assembly: FritzBox, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: DC9FD63C-0A96-43D7-A76E-0506FEB07200
|
||||
// Assembly location: \\192.168.178.26\Freigabe\FritzBox.dll
|
||||
|
||||
#nullable disable
|
||||
namespace FritzBox.API.FritzWebAccess.SoapTypes
|
||||
{
|
||||
public class WirelessLanInfo
|
||||
{
|
||||
public bool IsEnabled { get; set; }
|
||||
|
||||
public string Status { get; set; }
|
||||
|
||||
public string Channel { get; set; }
|
||||
|
||||
public string SSID { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("IsEnabled: {0}, Status: {1}, Channel: {2}, SSID: {3}", (object)this.IsEnabled, (object)this.Status, (object)this.Channel, (object)this.SSID);
|
||||
}
|
||||
}
|
||||
}
|
||||
20
Sensormat/FritzBox/Config.cs
Normal file
20
Sensormat/FritzBox/Config.cs
Normal file
@ -0,0 +1,20 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: FritzBox.Config
|
||||
// Assembly: FritzBox, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: DC9FD63C-0A96-43D7-A76E-0506FEB07200
|
||||
// Assembly location: \\192.168.178.26\Freigabe\FritzBox.dll
|
||||
|
||||
#nullable disable
|
||||
namespace FritzBox
|
||||
{
|
||||
public class Config
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
|
||||
public string Password { get; set; }
|
||||
|
||||
public string AIN { get; set; }
|
||||
|
||||
public string Property { get; set; }
|
||||
}
|
||||
}
|
||||
12
Sensormat/FritzBox/FritzBox.csproj
Normal file
12
Sensormat/FritzBox/FritzBox.csproj
Normal file
@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Sensormat\Sensormat.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
55
Sensormat/FritzBox/GetDeviceInfoResponse.cs
Normal file
55
Sensormat/FritzBox/GetDeviceInfoResponse.cs
Normal file
@ -0,0 +1,55 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: FritzBox.GetDeviceInfoResponse
|
||||
// Assembly: FritzBox, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: DC9FD63C-0A96-43D7-A76E-0506FEB07200
|
||||
// Assembly location: \\192.168.178.26\Freigabe\FritzBox.dll
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
#nullable disable
|
||||
namespace FritzBox
|
||||
{
|
||||
[XmlRoot(ElementName = "device")]
|
||||
public class GetDeviceInfoResponse
|
||||
{
|
||||
[XmlElement(ElementName = "present")]
|
||||
public int Present { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "txbusy")]
|
||||
public int Txbusy { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "switch")]
|
||||
public Switch Switch { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "simpleonoff")]
|
||||
public Simpleonoff Simpleonoff { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "powermeter")]
|
||||
public Powermeter Powermeter { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "temperature")]
|
||||
public Temperature Temperature { get; set; }
|
||||
|
||||
[XmlAttribute(AttributeName = "identifier")]
|
||||
public string Identifier { get; set; }
|
||||
|
||||
[XmlAttribute(AttributeName = "id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[XmlAttribute(AttributeName = "functionbitmask")]
|
||||
public int Functionbitmask { get; set; }
|
||||
|
||||
[XmlAttribute(AttributeName = "fwversion")]
|
||||
public string Fwversion { get; set; }
|
||||
|
||||
[XmlAttribute(AttributeName = "manufacturer")]
|
||||
public string Manufacturer { get; set; }
|
||||
|
||||
[XmlAttribute(AttributeName = "productname")]
|
||||
public string Productname { get; set; }
|
||||
}
|
||||
}
|
||||
60
Sensormat/FritzBox/GetValue.cs
Normal file
60
Sensormat/FritzBox/GetValue.cs
Normal file
@ -0,0 +1,60 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: FritzBox.GetValue
|
||||
// Assembly: FritzBox, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: DC9FD63C-0A96-43D7-A76E-0506FEB07200
|
||||
// Assembly location: \\192.168.178.26\Freigabe\FritzBox.dll
|
||||
|
||||
using Sensormat;
|
||||
using Sensormat.Entities;
|
||||
using System;
|
||||
|
||||
#nullable disable
|
||||
namespace FritzBox
|
||||
{
|
||||
public class GetValue : ISensor
|
||||
{
|
||||
private Config cfg;
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.cfg = this.getConfiguration<Config>();
|
||||
string webContent = new FritzBox.API.FritzWebAccess.FritzWebAccess(this.cfg.UserName, this.cfg.Password)
|
||||
{
|
||||
Address = new Uri(this.Sensor.URL)
|
||||
}.GetWebContent("webservices/homeautoswitch.lua", "&ain=" + this.cfg.AIN + "&switchcmd=getdeviceinfos");
|
||||
if (webContent != null)
|
||||
{
|
||||
GetDeviceInfoResponse deviceInfoResponse = webContent.XMLDeserializeData<GetDeviceInfoResponse>();
|
||||
if (deviceInfoResponse != null)
|
||||
{
|
||||
this.LastValueDate = new DateTime?(DateTime.Now);
|
||||
switch (this.cfg.Property?.ToLower())
|
||||
{
|
||||
case "power":
|
||||
this.LastValue = deviceInfoResponse.Powermeter?.Power.ToString();
|
||||
break;
|
||||
case "energy":
|
||||
this.LastValue = deviceInfoResponse.Powermeter?.Energy.ToString();
|
||||
break;
|
||||
default:
|
||||
this.LastValue = "property " + this.cfg.Property + " unknown";
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
this.ErrorMsg = "empty result";
|
||||
}
|
||||
else
|
||||
this.ErrorMsg = "response is empty";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine((object)ex);
|
||||
this.ErrorMsg = ex.Message;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
24
Sensormat/FritzBox/Powermeter.cs
Normal file
24
Sensormat/FritzBox/Powermeter.cs
Normal file
@ -0,0 +1,24 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: FritzBox.Powermeter
|
||||
// Assembly: FritzBox, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: DC9FD63C-0A96-43D7-A76E-0506FEB07200
|
||||
// Assembly location: \\192.168.178.26\Freigabe\FritzBox.dll
|
||||
|
||||
using System.Xml.Serialization;
|
||||
|
||||
#nullable disable
|
||||
namespace FritzBox
|
||||
{
|
||||
[XmlRoot(ElementName = "powermeter")]
|
||||
public class Powermeter
|
||||
{
|
||||
[XmlElement(ElementName = "voltage")]
|
||||
public int Voltage { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "power")]
|
||||
public int Power { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "energy")]
|
||||
public int Energy { get; set; }
|
||||
}
|
||||
}
|
||||
18
Sensormat/FritzBox/Simpleonoff.cs
Normal file
18
Sensormat/FritzBox/Simpleonoff.cs
Normal file
@ -0,0 +1,18 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: FritzBox.Simpleonoff
|
||||
// Assembly: FritzBox, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: DC9FD63C-0A96-43D7-A76E-0506FEB07200
|
||||
// Assembly location: \\192.168.178.26\Freigabe\FritzBox.dll
|
||||
|
||||
using System.Xml.Serialization;
|
||||
|
||||
#nullable disable
|
||||
namespace FritzBox
|
||||
{
|
||||
[XmlRoot(ElementName = "simpleonoff")]
|
||||
public class Simpleonoff
|
||||
{
|
||||
[XmlElement(ElementName = "state")]
|
||||
public int State { get; set; }
|
||||
}
|
||||
}
|
||||
27
Sensormat/FritzBox/Switch.cs
Normal file
27
Sensormat/FritzBox/Switch.cs
Normal file
@ -0,0 +1,27 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: FritzBox.Switch
|
||||
// Assembly: FritzBox, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: DC9FD63C-0A96-43D7-A76E-0506FEB07200
|
||||
// Assembly location: \\192.168.178.26\Freigabe\FritzBox.dll
|
||||
|
||||
using System.Xml.Serialization;
|
||||
|
||||
#nullable disable
|
||||
namespace FritzBox
|
||||
{
|
||||
[XmlRoot(ElementName = "switch")]
|
||||
public class Switch
|
||||
{
|
||||
[XmlElement(ElementName = "state")]
|
||||
public int State { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "mode")]
|
||||
public string Mode { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "lock")]
|
||||
public int Lock { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "devicelock")]
|
||||
public int Devicelock { get; set; }
|
||||
}
|
||||
}
|
||||
21
Sensormat/FritzBox/Temperature.cs
Normal file
21
Sensormat/FritzBox/Temperature.cs
Normal file
@ -0,0 +1,21 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: FritzBox.Temperature
|
||||
// Assembly: FritzBox, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: DC9FD63C-0A96-43D7-A76E-0506FEB07200
|
||||
// Assembly location: \\192.168.178.26\Freigabe\FritzBox.dll
|
||||
|
||||
using System.Xml.Serialization;
|
||||
|
||||
#nullable disable
|
||||
namespace FritzBox
|
||||
{
|
||||
[XmlRoot(ElementName = "temperature")]
|
||||
public class Temperature
|
||||
{
|
||||
[XmlElement(ElementName = "celsius")]
|
||||
public int Celsius { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "offset")]
|
||||
public int Offset { get; set; }
|
||||
}
|
||||
}
|
||||
85
Sensormat/SQL/spSensorCalculate.sql
Normal file
85
Sensormat/SQL/spSensorCalculate.sql
Normal file
@ -0,0 +1,85 @@
|
||||
DELIMITER $$
|
||||
|
||||
|
||||
DROP PROCEDURE IF EXISTS spSensorCalculate$$
|
||||
|
||||
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `spSensorCalculate`()
|
||||
NOT DETERMINISTIC
|
||||
SQL SECURITY DEFINER
|
||||
BEGIN
|
||||
DECLARE dfrom DATETIME;
|
||||
SET dfrom = NOW() - INTERVAL 14 DAY;
|
||||
|
||||
/* Stundenwerte erzeugen / aktualisieren (ohne CTE) */
|
||||
INSERT INTO tblSensorDataStunde
|
||||
(SensorID, Datum, StartValue, EndValue, ValueMIN, ValueMAX, ValueAVG)
|
||||
SELECT
|
||||
sd.SensorID,
|
||||
DATE_FORMAT(sd.ValueDate, '%Y-%m-%d %H:00:00') AS Datum,
|
||||
CASE s.Berechnung
|
||||
WHEN 1 THEN MIN(sd.Value)
|
||||
WHEN 2 THEN MAX(sd.Value)
|
||||
END AS StartValue,
|
||||
NULL AS EndValue,
|
||||
MIN(sd.Value) AS ValueMIN,
|
||||
MAX(sd.Value) AS ValueMAX,
|
||||
AVG(sd.Value) AS ValueAVG
|
||||
FROM tblSensoren s
|
||||
JOIN tblSensorData sd ON s.ID = sd.SensorID
|
||||
WHERE sd.Value IS NOT NULL
|
||||
AND sd.ValueDate >= dfrom
|
||||
AND s.Berechnung <> 0
|
||||
GROUP BY sd.SensorID, DATE_FORMAT(sd.ValueDate, '%Y-%m-%d %H:00:00')
|
||||
ON DUPLICATE KEY UPDATE
|
||||
StartValue = VALUES(StartValue),
|
||||
EndValue = NULL,
|
||||
ValueMIN = VALUES(ValueMIN),
|
||||
ValueMAX = VALUES(ValueMAX),
|
||||
ValueAVG = VALUES(ValueAVG);
|
||||
|
||||
/* --- 1093-sicher: NextStart in TEMP-Tabelle berechnen --- */
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp_next;
|
||||
|
||||
/* Variante ohne Window-Funktionen (läuft auch auf älteren Versionen):
|
||||
Wir sortieren pro Sensor DESC nach Datum, dann ist "prev_start" die nächste Stunde. */
|
||||
CREATE TEMPORARY TABLE tmp_next
|
||||
AS
|
||||
SELECT SensorID, Datum, NextStart
|
||||
FROM (
|
||||
SELECT
|
||||
x.SensorID,
|
||||
x.Datum,
|
||||
/* beim Abstieg ist die "vorherige" StartValue die nächste in der Zukunft */
|
||||
CASE WHEN @cur_sid = x.SensorID THEN @prev_start ELSE NULL END AS NextStart,
|
||||
/* Hilfszuweisungen für den nächsten Datensatz */
|
||||
@prev_start := x.StartValue AS _set_prev,
|
||||
@cur_sid := x.SensorID AS _set_sid
|
||||
FROM (
|
||||
SELECT SensorID, Datum, StartValue
|
||||
FROM tblSensorDataStunde
|
||||
WHERE Datum >= dfrom
|
||||
ORDER BY SensorID, Datum DESC
|
||||
) x
|
||||
/* Variablen initialisieren */
|
||||
JOIN (SELECT @cur_sid := NULL, @prev_start := NULL) vars
|
||||
) z;
|
||||
|
||||
|
||||
/* Jetzt gefahrlos updaten, weil wir aus tmp_next lesen, nicht aus der Zieltabelle */
|
||||
UPDATE tblSensorDataStunde t
|
||||
JOIN tmp_next n
|
||||
ON n.SensorID = t.SensorID AND n.Datum = t.Datum
|
||||
SET t.EndValue = n.NextStart
|
||||
WHERE t.Datum >= dfrom
|
||||
AND t.EndValue IS NULL
|
||||
AND n.NextStart IS NOT NULL;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp_next;
|
||||
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
|
||||
CALL spSensorCalculate;
|
||||
|
||||
43
Sensormat/Sensormat.sln
Normal file
43
Sensormat/Sensormat.sln
Normal file
@ -0,0 +1,43 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.14.36414.22 d17.14
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sensormat", "Sensormat\Sensormat.csproj", "{AD805DAC-A72F-4785-9CAD-4DEE29D7B647}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FritzBox", "FritzBox\FritzBox.csproj", "{73C49A84-293E-442C-8198-B3CBE2E8CFF8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ESP8266_Gaszaehler", "ESP8266_Gaszaehler\ESP8266_Gaszaehler.csproj", "{CEB7D1F4-BB04-44D1-9CE1-0EF04D3EE958}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shelly", "Shelly\Shelly.csproj", "{A63DCF66-60EF-4256-8609-6C423F484EFF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{AD805DAC-A72F-4785-9CAD-4DEE29D7B647}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AD805DAC-A72F-4785-9CAD-4DEE29D7B647}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AD805DAC-A72F-4785-9CAD-4DEE29D7B647}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AD805DAC-A72F-4785-9CAD-4DEE29D7B647}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{73C49A84-293E-442C-8198-B3CBE2E8CFF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{73C49A84-293E-442C-8198-B3CBE2E8CFF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{73C49A84-293E-442C-8198-B3CBE2E8CFF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{73C49A84-293E-442C-8198-B3CBE2E8CFF8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CEB7D1F4-BB04-44D1-9CE1-0EF04D3EE958}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CEB7D1F4-BB04-44D1-9CE1-0EF04D3EE958}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CEB7D1F4-BB04-44D1-9CE1-0EF04D3EE958}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CEB7D1F4-BB04-44D1-9CE1-0EF04D3EE958}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A63DCF66-60EF-4256-8609-6C423F484EFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A63DCF66-60EF-4256-8609-6C423F484EFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A63DCF66-60EF-4256-8609-6C423F484EFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A63DCF66-60EF-4256-8609-6C423F484EFF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {B15582B7-B501-4507-8D60-4312FE32CC79}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
58
Sensormat/Sensormat/Config.cs
Normal file
58
Sensormat/Sensormat/Config.cs
Normal file
@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Sensormat
|
||||
{
|
||||
public class Config
|
||||
{
|
||||
private const string ConfigName = "cfg/config.json";
|
||||
|
||||
// Beispiel-Properties (passen an deine JSON-Struktur an!)
|
||||
public string MainUrl { get; set; } = @"http://*:810/";
|
||||
|
||||
public string MYSQL_Server { get; set; } = "docker-1";
|
||||
public string MYSQL_User { get; set; } = "ESP8266_Gaszaehler";
|
||||
public string MYSQL_Password { get; set; } = "gFKWa8lFJwFUcBysn4HI";
|
||||
public string MYSQL_Database { get; set; } = "zeidlerme";
|
||||
|
||||
public static Config Load()
|
||||
{
|
||||
string basePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
|
||||
?? AppContext.BaseDirectory;
|
||||
|
||||
string configPath = Path.Combine(basePath, ConfigName);
|
||||
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true,
|
||||
PropertyNameCaseInsensitive = true,
|
||||
ReadCommentHandling = JsonCommentHandling.Skip,
|
||||
AllowTrailingCommas = true
|
||||
};
|
||||
|
||||
// Datei fehlt → Standardobjekt erzeugen und abspeichern
|
||||
if (!File.Exists(configPath))
|
||||
{
|
||||
var defaultConfig = new Config();
|
||||
string json = JsonSerializer.Serialize(defaultConfig, options);
|
||||
File.WriteAllText(configPath, json);
|
||||
Console.WriteLine($"Config created {configPath}");
|
||||
return defaultConfig;
|
||||
}
|
||||
|
||||
// Datei vorhanden → einlesen
|
||||
string content = File.ReadAllText(configPath);
|
||||
var cfg = JsonSerializer.Deserialize<Config>(content, options);
|
||||
|
||||
if (cfg == null)
|
||||
throw new InvalidOperationException("Konfigurationsdatei konnte nicht geladen werden.");
|
||||
|
||||
Console.WriteLine($"config loaded {configPath}");
|
||||
return cfg;
|
||||
}
|
||||
}
|
||||
}
|
||||
6
Sensormat/Sensormat/Dockerfile
Normal file
6
Sensormat/Sensormat/Dockerfile
Normal file
@ -0,0 +1,6 @@
|
||||
FROM mcr.microsoft.com/dotnet/core/sdk:3.1
|
||||
COPY ./bin/Release/netcoreapp3.1/. /app
|
||||
WORKDIR /app
|
||||
EXPOSE 810/tcp
|
||||
ENV TZ=Europe/Berlin
|
||||
CMD ["sh", "-c", "dotnet Sensormat.dll $Config" ]
|
||||
100
Sensormat/Sensormat/Entities/ISensor.cs
Normal file
100
Sensormat/Sensormat/Entities/ISensor.cs
Normal file
@ -0,0 +1,100 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: Sensormat.Entities.ISensor
|
||||
// Assembly: Sensormat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: 49795081-3467-4846-904D-9A360FB2FA3C
|
||||
// Assembly location: \\192.168.178.26\Freigabe\Sensormat.dll
|
||||
|
||||
using MySqlConnector;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
#nullable disable
|
||||
namespace Sensormat.Entities
|
||||
{
|
||||
public class ISensor
|
||||
{
|
||||
private Sensoren _sensor;
|
||||
|
||||
public ISensor()
|
||||
{
|
||||
}
|
||||
|
||||
public ISensor(int SensorID) => this.SensorID = SensorID;
|
||||
|
||||
public MySqlConnection connection { get; set; }
|
||||
|
||||
public string ErrorMsg { get; set; }
|
||||
|
||||
public string LastValue { get; set; }
|
||||
|
||||
public DateTime? LastValueDate { get; set; }
|
||||
|
||||
public virtual int SensorID { get; set; }
|
||||
|
||||
public virtual bool Execute() => false;
|
||||
|
||||
public Sensoren Sensor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.SensorID == 0)
|
||||
throw new Exception("SensorID = 0");
|
||||
if (this._sensor == null)
|
||||
{
|
||||
using (MySqlCommand command = this.connection.CreateCommand())
|
||||
{
|
||||
command.CommandText = "SELECT * FROM tblSensoren WHERE ID = @SensorID";
|
||||
command.Parameters.AddWithValue("SensorID", (object)this.SensorID);
|
||||
using (MySqlDataReader rd = command.ExecuteReader())
|
||||
{
|
||||
if (rd.HasRows)
|
||||
{
|
||||
rd.Read();
|
||||
this._sensor = rd.ParseObject<Sensoren>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this._sensor;
|
||||
}
|
||||
}
|
||||
|
||||
public T getConfiguration<T>()
|
||||
{
|
||||
if (this.Sensor != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(this.Sensor.config))
|
||||
{
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>(this.Sensor.config);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
EventLog.Write(((MemberInfo)MethodBase.GetCurrentMethod()).Name, string.Format("{0}", (object)this.Sensor.ID), (object)ex);
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
}
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public string HttpRequest(string URL)
|
||||
{
|
||||
WebRequest webRequest = WebRequest.Create(URL);
|
||||
webRequest.Method = "GET";
|
||||
using (WebResponse response = webRequest.GetResponse())
|
||||
{
|
||||
using (Stream responseStream = response.GetResponseStream())
|
||||
{
|
||||
using (StreamReader streamReader = new StreamReader(responseStream))
|
||||
return ((TextReader)streamReader).ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
20
Sensormat/Sensormat/Entities/ISensorData.cs
Normal file
20
Sensormat/Sensormat/Entities/ISensorData.cs
Normal file
@ -0,0 +1,20 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: Sensormat.Entities.SensorData
|
||||
// Assembly: Sensormat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: 49795081-3467-4846-904D-9A360FB2FA3C
|
||||
// Assembly location: \\192.168.178.26\Freigabe\Sensormat.dll
|
||||
|
||||
using System;
|
||||
|
||||
#nullable disable
|
||||
namespace Sensormat.Entities
|
||||
{
|
||||
public class SensorData
|
||||
{
|
||||
public int SensorID { get; set; }
|
||||
|
||||
public Decimal Value { get; set; }
|
||||
|
||||
public DateTime? ValueDate { get; set; }
|
||||
}
|
||||
}
|
||||
50
Sensormat/Sensormat/Entities/Sensoren.cs
Normal file
50
Sensormat/Sensormat/Entities/Sensoren.cs
Normal file
@ -0,0 +1,50 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: Sensormat.Entities.Sensoren
|
||||
// Assembly: Sensormat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: 49795081-3467-4846-904D-9A360FB2FA3C
|
||||
// Assembly location: \\192.168.178.26\Freigabe\Sensormat.dll
|
||||
|
||||
using System;
|
||||
|
||||
#nullable disable
|
||||
namespace Sensormat.Entities
|
||||
{
|
||||
public class Sensoren
|
||||
{
|
||||
public int ID { get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
|
||||
public string URL { get; set; }
|
||||
|
||||
public string LastValue { get; set; }
|
||||
|
||||
public DateTime? LastCall { get; set; }
|
||||
|
||||
public string ErrorMsg { get; set; }
|
||||
|
||||
public int Intervall { get; set; }
|
||||
|
||||
public string Assembly { get; set; }
|
||||
|
||||
public string TypeName { get; set; }
|
||||
|
||||
public int Aktiv { get; set; }
|
||||
|
||||
public DateTime? LastValueDate { get; set; }
|
||||
|
||||
public Sensoren.CheckChangedMethods CheckChanged { get; set; }
|
||||
|
||||
public string Passphrase { get; set; }
|
||||
|
||||
public string config { get; set; }
|
||||
|
||||
public enum CheckChangedMethods
|
||||
{
|
||||
none,
|
||||
value,
|
||||
valuedate,
|
||||
valueorvaluedate,
|
||||
}
|
||||
}
|
||||
}
|
||||
38
Sensormat/Sensormat/EventLog.cs
Normal file
38
Sensormat/Sensormat/EventLog.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Sensormat
|
||||
{
|
||||
public class EventLog
|
||||
{
|
||||
public static void Write(string Source, string Message, params object[] param)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists("LOG"))
|
||||
Directory.CreateDirectory("LOG");
|
||||
string path = "LOG/" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
|
||||
string contents = Environment.NewLine + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + Source + Environment.NewLine + " " + Message;
|
||||
if (param != null)
|
||||
{
|
||||
foreach (object obj in param)
|
||||
{
|
||||
if (obj != null)
|
||||
{
|
||||
if (obj.GetType() == typeof(string))
|
||||
contents += string.Format("{0}{1}", obj, (object)Environment.NewLine);
|
||||
if (obj.GetType() == typeof(Exception))
|
||||
contents += string.Format("{0}{1} {2} {3}{4}", obj, (object)((Exception)obj).Message, (object)((Exception)obj).Message, (object)((Exception)obj).InnerException, (object)Environment.NewLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
Console.WriteLine(contents);
|
||||
File.AppendAllText(path, contents);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Logging Error: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
89
Sensormat/Sensormat/HttpServer.cs
Normal file
89
Sensormat/Sensormat/HttpServer.cs
Normal file
@ -0,0 +1,89 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: Sensormat.HttpServer
|
||||
// Assembly: Sensormat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: 49795081-3467-4846-904D-9A360FB2FA3C
|
||||
// Assembly location: \\192.168.178.26\Freigabe\Sensormat.dll
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable disable
|
||||
namespace Sensormat
|
||||
{
|
||||
public class HttpServer
|
||||
{
|
||||
public HttpListener listener;
|
||||
private string URL;
|
||||
|
||||
public HttpServer.HttpServerIncomingRequestCallBack httpServerIncomingRequest { get; set; }
|
||||
|
||||
public async Task HandleIncomingConnections()
|
||||
{
|
||||
bool runServer = true;
|
||||
while (runServer)
|
||||
{
|
||||
HttpListenerContext contextAsync = await this.listener.GetContextAsync();
|
||||
HttpListenerRequest request = contextAsync.Request;
|
||||
HttpListenerResponse resp = contextAsync.Response;
|
||||
Console.WriteLine(request.Url.ToString());
|
||||
Console.WriteLine(request.HttpMethod);
|
||||
Console.WriteLine(request.UserHostName);
|
||||
Console.WriteLine(request.UserAgent);
|
||||
Console.WriteLine();
|
||||
HttpServerIncomingRequestCallBackParameter e = new HttpServerIncomingRequestCallBackParameter()
|
||||
{
|
||||
StatusCode = 200,
|
||||
StatusDescription = "",
|
||||
Result = "",
|
||||
URL = this.URL,
|
||||
Request = request,
|
||||
AbsolutePath = request.Url.AbsolutePath.Trim('/')
|
||||
};
|
||||
if (request.QueryString != null)
|
||||
{
|
||||
foreach (string allKey in request.QueryString.AllKeys)
|
||||
e.Query.Add(allKey, request.QueryString[allKey]);
|
||||
}
|
||||
if (this.httpServerIncomingRequest != null)
|
||||
this.httpServerIncomingRequest(e);
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(e.Result);
|
||||
resp.ContentType = "text/html";
|
||||
resp.ContentEncoding = Encoding.UTF8;
|
||||
resp.ContentLength64 = (long)bytes.Length;
|
||||
resp.StatusCode = e.StatusCode;
|
||||
resp.StatusDescription = e.StatusDescription;
|
||||
await resp.OutputStream.WriteAsync(bytes, 0, bytes.Length);
|
||||
resp.Close();
|
||||
resp = (HttpListenerResponse)null;
|
||||
}
|
||||
}
|
||||
|
||||
private string getValue(string ID) => "OK " + ID;
|
||||
|
||||
private string setValue(string ID, string Parameter) => "setValue " + ID + " " + Parameter;
|
||||
|
||||
public HttpServer(string url)
|
||||
{
|
||||
this.listener = new HttpListener();
|
||||
this.listener.Prefixes.Add(url);
|
||||
this.listener.Start();
|
||||
Console.WriteLine("Listening for connections on {0}", (object)url);
|
||||
this.URL = url;
|
||||
this.HandleIncomingConnections();
|
||||
}
|
||||
|
||||
public bool Test() => !string.IsNullOrEmpty(new WebClient().DownloadString(this.URL));
|
||||
|
||||
public void Release()
|
||||
{
|
||||
if (this.listener == null)
|
||||
return;
|
||||
this.listener.Close();
|
||||
}
|
||||
|
||||
public delegate void HttpServerIncomingRequestCallBack(
|
||||
HttpServerIncomingRequestCallBackParameter e);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: Sensormat.HttpServerIncomingRequestCallBackParameter
|
||||
// Assembly: Sensormat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: 49795081-3467-4846-904D-9A360FB2FA3C
|
||||
// Assembly location: \\192.168.178.26\Freigabe\Sensormat.dll
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
|
||||
#nullable disable
|
||||
namespace Sensormat
|
||||
{
|
||||
public class HttpServerIncomingRequestCallBackParameter
|
||||
{
|
||||
public string Result { get; set; }
|
||||
|
||||
public string StatusDescription { get; set; }
|
||||
|
||||
public int StatusCode { get; set; }
|
||||
|
||||
public string URL { get; set; }
|
||||
|
||||
public HttpListenerRequest Request { get; set; }
|
||||
|
||||
public string AbsolutePath { get; set; }
|
||||
|
||||
public Dictionary<string, string> Query { get; set; } = new Dictionary<string, string>();
|
||||
}
|
||||
}
|
||||
295
Sensormat/Sensormat/Manager.cs
Normal file
295
Sensormat/Sensormat/Manager.cs
Normal file
@ -0,0 +1,295 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: Sensormat.Manager
|
||||
// Assembly: Sensormat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: 49795081-3467-4846-904D-9A360FB2FA3C
|
||||
// Assembly location: \\192.168.178.26\Freigabe\Sensormat.dll
|
||||
|
||||
using MySqlConnector;
|
||||
using Sensormat.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
|
||||
#nullable disable
|
||||
namespace Sensormat
|
||||
{
|
||||
public class Manager
|
||||
{
|
||||
private Config config;
|
||||
private MySqlConnection connection;
|
||||
private static Semaphore semaphore = new Semaphore(1, 1);
|
||||
private HttpServer httpServer;
|
||||
private DateTime lastCalculate;
|
||||
public string HelpData = "<!DOCTYPE>\r\n <html>\r\n <head>\r\n <title>Sensormat WebInterface</title>\r\n </head>\r\n <body>\r\n <p>Help</p>\r\n <p>GetValue</p> [URL]/GetValue?Passphrase={Passphrase}&ID={SensorID}\r\n <p>SetValue</p> \r\n [URL]/SetValue?Passphrase={Passphrase}&ID={SensorID}&Value={Value}&[ValueDate={ValueDate}]\r\n </body>\r\n </html>";
|
||||
|
||||
private bool UpdateSensor(Sensoren sensor)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (MySqlCommand command = this.connection.CreateCommand())
|
||||
{
|
||||
command.CommandText = "UPDATE tblSensoren SET LastValue = @LastValue, LastValueDate = @LastValueDate, LastCall = @LastCall, ErrorMsg = @ErrorMsg WHERE ID = @SensorID";
|
||||
command.Parameters.AddWithValue("LastValue", (object)sensor.LastValue);
|
||||
command.Parameters.AddWithValue("LastValueDate", (object)sensor.LastValueDate);
|
||||
command.Parameters.AddWithValue("LastCall", (object)sensor.LastCall);
|
||||
command.Parameters.AddWithValue("ErrorMsg", (object)sensor.ErrorMsg);
|
||||
command.Parameters.AddWithValue("SensorID", (object)sensor.ID);
|
||||
return command.ExecuteNonQuery() == 1;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
EventLog.Write(((MemberInfo)MethodBase.GetCurrentMethod()).Name, ex.Message, (object)string.Format("SensorID={0}", (object)sensor.ID), (object)ex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool UpdateSensorData(Sensoren sensor)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (MySqlCommand command = this.connection.CreateCommand())
|
||||
{
|
||||
command.CommandText = "INSERT INTO tblSensorData (SensorID, RawValue, ValueDate,CD) VALUES (@SensorID, @RawValue, @ValueDate, @Datum)";
|
||||
command.Parameters.AddWithValue("SensorID", (object)sensor.ID);
|
||||
command.Parameters.AddWithValue("RawValue", (object)sensor.LastValue);
|
||||
command.Parameters.AddWithValue("ValueDate", (object)sensor.LastValueDate);
|
||||
command.Parameters.AddWithValue("Datum", (object)DateTime.Now);
|
||||
return command.ExecuteNonQuery() == 1;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
EventLog.Write(((MemberInfo)MethodBase.GetCurrentMethod()).Name, ex.Message, (object)string.Format("SensorID={0}", (object)sensor.ID), (object)ex);
|
||||
sensor.ErrorMsg = string.Format("{0} SensorID={1} {2} {3}", (object)((MemberInfo)MethodBase.GetCurrentMethod()).Name, (object)sensor.ID, (object)ex.Message, (object)ex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void HandleSensor(ISensor SensorEntity)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (SensorEntity == null)
|
||||
return;
|
||||
if (SensorEntity.Sensor.LastCall.HasValue)
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
DateTime? lastCall = SensorEntity.Sensor.LastCall;
|
||||
if ((lastCall.HasValue ? new TimeSpan?(now - lastCall.GetValueOrDefault()) : new TimeSpan?()).Value.TotalMinutes < (double)SensorEntity.Sensor.Intervall)
|
||||
return;
|
||||
}
|
||||
SensorEntity.Execute();
|
||||
this.SetValue(SensorEntity, SensorEntity.LastValue, (string)null);
|
||||
SensorEntity.Sensor.ErrorMsg = "";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
EventLog.Write(((MemberInfo)MethodBase.GetCurrentMethod()).Name, ex.Message, (object)string.Format("SensorID={0}", (object)SensorEntity.SensorID), (object)ex);
|
||||
Console.WriteLine((object)ex);
|
||||
}
|
||||
}
|
||||
|
||||
private ISensor GetSensor(int SensorID, string Passphrase)
|
||||
{
|
||||
ISensor isensor = new ISensor(SensorID);
|
||||
isensor.connection = this.connection;
|
||||
return isensor.Sensor == null || isensor.Sensor.Passphrase != Passphrase ? (ISensor)null : isensor;
|
||||
}
|
||||
|
||||
private bool GetValue(int SensorID, out string Result)
|
||||
{
|
||||
Result = "";
|
||||
ISensor isensor = new ISensor(SensorID);
|
||||
isensor.connection = this.connection;
|
||||
if (isensor.Sensor == null)
|
||||
return false;
|
||||
Result = isensor.Sensor.LastValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool SetValue(ISensor SensorEntity, string Value, string ValueDateString)
|
||||
{
|
||||
DateTime result;
|
||||
if (!DateTime.TryParse(ValueDateString, out result))
|
||||
result = DateTime.Now;
|
||||
if (SensorEntity.Sensor.CheckChanged != Sensoren.CheckChangedMethods.none && (SensorEntity.Sensor.CheckChanged != Sensoren.CheckChangedMethods.value || !(SensorEntity.Sensor.LastValue != Value) && SensorEntity.Sensor.LastValue != null))
|
||||
{
|
||||
DateTime? lastValueDate;
|
||||
if (SensorEntity.Sensor.CheckChanged == Sensoren.CheckChangedMethods.valuedate)
|
||||
{
|
||||
lastValueDate = SensorEntity.Sensor.LastValueDate;
|
||||
DateTime dateTime = result;
|
||||
if ((lastValueDate.HasValue ? (lastValueDate.HasValue ? (lastValueDate.GetValueOrDefault() != dateTime ? 1 : 0) : 0) : 1) == 0)
|
||||
{
|
||||
lastValueDate = SensorEntity.Sensor.LastValueDate;
|
||||
if (!lastValueDate.HasValue)
|
||||
goto label_9;
|
||||
}
|
||||
else
|
||||
goto label_9;
|
||||
}
|
||||
if (SensorEntity.Sensor.CheckChanged == Sensoren.CheckChangedMethods.valueorvaluedate)
|
||||
{
|
||||
lastValueDate = SensorEntity.Sensor.LastValueDate;
|
||||
DateTime dateTime = result;
|
||||
if ((lastValueDate.HasValue ? (lastValueDate.HasValue ? (lastValueDate.GetValueOrDefault() != dateTime ? 1 : 0) : 0) : 1) == 0)
|
||||
{
|
||||
lastValueDate = SensorEntity.Sensor.LastValueDate;
|
||||
if (lastValueDate.HasValue && !(SensorEntity.Sensor.LastValue != Value) && SensorEntity.Sensor.LastValue != null)
|
||||
goto label_10;
|
||||
}
|
||||
}
|
||||
else
|
||||
goto label_10;
|
||||
}
|
||||
label_9:
|
||||
SensorEntity.Sensor.LastValue = Value;
|
||||
SensorEntity.Sensor.LastValueDate = new DateTime?(result);
|
||||
this.UpdateSensorData(SensorEntity.Sensor);
|
||||
label_10:
|
||||
SensorEntity.Sensor.LastCall = new DateTime?(DateTime.Now);
|
||||
SensorEntity.Sensor.ErrorMsg = SensorEntity.ErrorMsg;
|
||||
this.UpdateSensor(SensorEntity.Sensor);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void CheckConnection()
|
||||
{
|
||||
if (this.connection.State == ConnectionState.Connecting)
|
||||
{
|
||||
do
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
Console.Write(".");
|
||||
}
|
||||
while (this.connection.State == ConnectionState.Connecting);
|
||||
}
|
||||
if (this.connection.State == ConnectionState.Open)
|
||||
return;
|
||||
this.connection.Open();
|
||||
}
|
||||
|
||||
private void CalculateData()
|
||||
{
|
||||
try
|
||||
{
|
||||
if ((DateTime.Now - this.lastCalculate).TotalMinutes < 10.0)
|
||||
return;
|
||||
this.connection.CallCalculate();
|
||||
this.lastCalculate = DateTime.Now;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
EventLog.Write(((MemberInfo)MethodBase.GetCurrentMethod()).Name, ex.Message, (object)ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.config = Config.Load();
|
||||
this.httpServer = new HttpServer(config.MainUrl);
|
||||
this.httpServer.httpServerIncomingRequest += new HttpServer.HttpServerIncomingRequestCallBack(this.httpServerIncomingRequest);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
EventLog.Write(((MemberInfo)MethodBase.GetCurrentMethod()).Name, "cant't start server " + ex.Message, (object)ex);
|
||||
}
|
||||
this.connection = new MySqlConnection($"Server={config.MYSQL_Server};User ID={config.MYSQL_User};Password={config.MYSQL_Password};Database={config.MYSQL_Database}");
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.CheckConnection();
|
||||
Manager.semaphore.WaitOne();
|
||||
foreach (Sensoren sensor in this.connection.GetSensoren().ToArray<Sensoren>())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(sensor.Assembly))
|
||||
throw new Exception("Assemblyfile " + sensor.Assembly + " not found");
|
||||
Type type = Assembly.LoadFrom(sensor.Assembly).GetType(sensor.TypeName);
|
||||
ISensor SensorEntity = !(type == (Type)null) ? Activator.CreateInstance(type) as ISensor : throw new Exception("type " + sensor.TypeName + " not found");
|
||||
SensorEntity.SensorID = sensor.ID;
|
||||
SensorEntity.connection = this.connection;
|
||||
if (SensorEntity == null)
|
||||
throw new Exception(string.Format("can't create Instance {0}", (object)type));
|
||||
this.HandleSensor(SensorEntity);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
sensor.ErrorMsg = string.Format("{0} {1} {2} {3}", (object)ex.Message, (object)ex.Source, (object)ex.StackTrace, (object)ex.InnerException);
|
||||
this.UpdateSensor(sensor);
|
||||
}
|
||||
}
|
||||
this.CalculateData();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
EventLog.Write(((MemberInfo)MethodBase.GetCurrentMethod()).Name, ex.Message, (object)ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Manager.semaphore.Release();
|
||||
Thread.Sleep(60000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void httpServerIncomingRequest(HttpServerIncomingRequestCallBackParameter e)
|
||||
{
|
||||
try
|
||||
{
|
||||
Manager.semaphore.WaitOne();
|
||||
string str1 = this.HelpData.Replace("[URL]", e.URL);
|
||||
string[] strArray = e.AbsolutePath.Trim('/').Split('/', StringSplitOptions.None);
|
||||
KeyValuePair<string, string> keyValuePair = e.Query.FirstOrDefault<KeyValuePair<string, string>>((Func<KeyValuePair<string, string>, bool>)(f => f.Key.ToLower() == "id"));
|
||||
string s = keyValuePair.Value;
|
||||
keyValuePair = e.Query.FirstOrDefault<KeyValuePair<string, string>>((Func<KeyValuePair<string, string>, bool>)(f => f.Key.ToLower() == "value"));
|
||||
string str2 = keyValuePair.Value;
|
||||
keyValuePair = e.Query.FirstOrDefault<KeyValuePair<string, string>>((Func<KeyValuePair<string, string>, bool>)(f => f.Key.ToLower() == "valuedate"));
|
||||
string ValueDateString = keyValuePair.Value;
|
||||
keyValuePair = e.Query.FirstOrDefault<KeyValuePair<string, string>>((Func<KeyValuePair<string, string>, bool>)(f => f.Key.ToLower() == "passphrase"));
|
||||
string Passphrase = keyValuePair.Value;
|
||||
int result;
|
||||
if (strArray.Length == 1 && int.TryParse(s, out result) && result > 0)
|
||||
{
|
||||
ISensor sensor = this.GetSensor(result, Passphrase);
|
||||
if (sensor == null)
|
||||
{
|
||||
e.StatusCode = 500;
|
||||
return;
|
||||
}
|
||||
switch (strArray[0].ToLower())
|
||||
{
|
||||
case "getvalue":
|
||||
str1 = sensor.Sensor.LastValue;
|
||||
break;
|
||||
case "setvalue":
|
||||
if (!this.SetValue(sensor, str2, ValueDateString))
|
||||
{
|
||||
e.StatusCode = 404;
|
||||
break;
|
||||
}
|
||||
str1 = "ok";
|
||||
break;
|
||||
}
|
||||
}
|
||||
e.Result = str1;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
EventLog.Write(((MemberInfo)MethodBase.GetCurrentMethod()).Name, ex.Message, (object)ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Manager.semaphore.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
153
Sensormat/Sensormat/ParseExtensions.cs
Normal file
153
Sensormat/Sensormat/ParseExtensions.cs
Normal file
@ -0,0 +1,153 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: Sensormat.ParseExtensions
|
||||
// Assembly: Sensormat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: 49795081-3467-4846-904D-9A360FB2FA3C
|
||||
// Assembly location: \\192.168.178.26\Freigabe\Sensormat.dll
|
||||
|
||||
using MySqlConnector;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
#nullable disable
|
||||
namespace Sensormat
|
||||
{
|
||||
public static class ParseExtensions
|
||||
{
|
||||
public static string XMLSerializeData<T>(this T data)
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
new XmlSerializer(typeof(T)).Serialize((TextWriter)new StringWriter(stringBuilder), (object)data);
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
public static T XMLDeserializeData<T>(this string dataXML)
|
||||
{
|
||||
XmlDocument xmlDocument = new XmlDocument();
|
||||
xmlDocument.LoadXml(dataXML);
|
||||
return (T)new XmlSerializer(typeof(T)).Deserialize((XmlReader)new XmlNodeReader((XmlNode)xmlDocument.DocumentElement));
|
||||
}
|
||||
public static T ParseObject<T>(this MySqlDataReader rd) where T : class, new()
|
||||
{
|
||||
var type = typeof(T);
|
||||
var instance = new T();
|
||||
|
||||
// Properties vorbereiten (Case-insensitive, nur schreibbare)
|
||||
var props = type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
|
||||
.Where(p => p.CanWrite)
|
||||
.ToDictionary(p => p.Name, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
for (int ordinal = 0; ordinal < rd.FieldCount; ordinal++)
|
||||
{
|
||||
if (rd.IsDBNull(ordinal)) continue;
|
||||
|
||||
string fieldName = rd.GetName(ordinal);
|
||||
if (!props.TryGetValue(fieldName, out var propertyInfo)) continue; // Spalte ohne passende Property
|
||||
|
||||
object value = rd.GetValue(ordinal);
|
||||
Type targetType = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
|
||||
|
||||
try
|
||||
{
|
||||
object? converted = ConvertTo(value, targetType);
|
||||
propertyInfo.SetValue(instance, converted);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Optional: Logging einbauen, wenn eine Spalte mal nicht passt.
|
||||
// throw; // oder bewusst schlucken
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
public static object ParseObject(this MySqlDataReader rd, Type type)
|
||||
{
|
||||
if (type == null) throw new ArgumentNullException(nameof(type));
|
||||
|
||||
var instance = Activator.CreateInstance(type)
|
||||
?? throw new InvalidOperationException($"Kann Instanz von {type.FullName} nicht erzeugen.");
|
||||
|
||||
// Schreibbare Properties case-insensitiv mappen
|
||||
var props = type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
|
||||
.Where(p => p.CanWrite)
|
||||
.ToDictionary(p => p.Name, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
for (int ordinal = 0; ordinal < rd.FieldCount; ordinal++)
|
||||
{
|
||||
if (rd.IsDBNull(ordinal)) continue;
|
||||
|
||||
string fieldName = rd.GetName(ordinal);
|
||||
if (!props.TryGetValue(fieldName, out var propertyInfo)) continue;
|
||||
|
||||
object value = rd.GetValue(ordinal);
|
||||
Type targetType = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
|
||||
|
||||
try
|
||||
{
|
||||
object? converted = ConvertTo(value, targetType);
|
||||
propertyInfo.SetValue(instance, converted);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Optional: Logging/Tracing hier einbauen
|
||||
// Wenn du strikt sein willst: throw;
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static object? ConvertTo(object value, Type targetType)
|
||||
{
|
||||
if (value == null) return null;
|
||||
|
||||
// Schon richtig typisiert?
|
||||
if (targetType.IsInstanceOfType(value)) return value;
|
||||
|
||||
// Enums (Zahl oder Name)
|
||||
if (targetType.IsEnum)
|
||||
{
|
||||
if (value is string s) return Enum.Parse(targetType, s, ignoreCase: true);
|
||||
var underlying = Enum.GetUnderlyingType(targetType);
|
||||
var num = Convert.ChangeType(value, underlying, CultureInfo.InvariantCulture);
|
||||
return Enum.ToObject(targetType, num!);
|
||||
}
|
||||
|
||||
// Guid
|
||||
if (targetType == typeof(Guid))
|
||||
return value is Guid g ? g : Guid.Parse(value.ToString()!);
|
||||
|
||||
// DateTimeOffset
|
||||
if (targetType == typeof(DateTimeOffset))
|
||||
{
|
||||
if (value is DateTimeOffset dto) return dto;
|
||||
if (value is DateTime dt) return new DateTimeOffset(dt);
|
||||
return DateTimeOffset.Parse(value.ToString()!, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
// DateTime: ChangeType kann das meist, sonst Parse
|
||||
if (targetType == typeof(DateTime) && value is string sdt)
|
||||
return DateTime.Parse(sdt, CultureInfo.InvariantCulture);
|
||||
|
||||
// Bool aus 0/1 oder "0"/"1"
|
||||
if (targetType == typeof(bool) && value is IConvertible)
|
||||
{
|
||||
var s = value.ToString();
|
||||
if (s == "0") return false;
|
||||
if (s == "1") return true;
|
||||
}
|
||||
|
||||
// Fallback: Convert.ChangeType
|
||||
return Convert.ChangeType(value, targetType, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
29
Sensormat/Sensormat/Program.cs
Normal file
29
Sensormat/Sensormat/Program.cs
Normal file
@ -0,0 +1,29 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: Sensormat.Program
|
||||
// Assembly: Sensormat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: 49795081-3467-4846-904D-9A360FB2FA3C
|
||||
// Assembly location: \\192.168.178.26\Freigabe\Sensormat.dll
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
#nullable disable
|
||||
namespace Sensormat
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
EventLog.Write(((MemberInfo)MethodBase.GetCurrentMethod()).Name, "START");
|
||||
new Manager().Run();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
EventLog.Write(((MemberInfo)MethodBase.GetCurrentMethod()).Name, ex.Message, (object)ex);
|
||||
Console.WriteLine((object)ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Sensormat/Sensormat/References/MySqlConnector.dll
Normal file
BIN
Sensormat/Sensormat/References/MySqlConnector.dll
Normal file
Binary file not shown.
BIN
Sensormat/Sensormat/References/Newtonsoft.Json.dll
Normal file
BIN
Sensormat/Sensormat/References/Newtonsoft.Json.dll
Normal file
Binary file not shown.
56
Sensormat/Sensormat/SQLExtensions.cs
Normal file
56
Sensormat/Sensormat/SQLExtensions.cs
Normal file
@ -0,0 +1,56 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: Sensormat.SQLExtensions
|
||||
// Assembly: Sensormat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: 49795081-3467-4846-904D-9A360FB2FA3C
|
||||
// Assembly location: \\192.168.178.26\Freigabe\Sensormat.dll
|
||||
|
||||
using MySqlConnector;
|
||||
using Sensormat.Entities;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#nullable disable
|
||||
namespace Sensormat
|
||||
{
|
||||
public static class SQLExtensions
|
||||
{
|
||||
public static IEnumerable<Sensoren> GetSensoren(this MySqlConnection connection)
|
||||
{
|
||||
using (MySqlCommand cmd = connection.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "SELECT * FROM tblSensoren WHERE Aktiv <> 0";
|
||||
MySqlDataReader reader = cmd.ExecuteReader();
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (reader.HasRows)
|
||||
{
|
||||
if (reader.Read())
|
||||
yield return reader.ParseObject<Sensoren>();
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
goto label_5;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
reader?.Dispose();
|
||||
}
|
||||
yield break;
|
||||
label_5:
|
||||
reader = (MySqlDataReader)null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void CallCalculate(this MySqlConnection connection)
|
||||
{
|
||||
using (MySqlCommand command = connection.CreateCommand())
|
||||
{
|
||||
command.CommandText = "CALL spSensorCalculate; ";
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
17
Sensormat/Sensormat/Sensormat.csproj
Normal file
17
Sensormat/Sensormat/Sensormat.csproj
Normal file
@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="MySqlConnector">
|
||||
<HintPath>References\MySqlConnector.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>References\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
8
Sensormat/Shelly/Class1.cs
Normal file
8
Sensormat/Shelly/Class1.cs
Normal file
@ -0,0 +1,8 @@
|
||||
using System;
|
||||
|
||||
namespace Shelly
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
}
|
||||
}
|
||||
17
Sensormat/Shelly/Shelly.csproj
Normal file
17
Sensormat/Shelly/Shelly.csproj
Normal file
@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Sensormat\Sensormat.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\Sensormat\References\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
20
Sensormat/Shelly/Shelly1PM/ResultMeters.cs
Normal file
20
Sensormat/Shelly/Shelly1PM/ResultMeters.cs
Normal file
@ -0,0 +1,20 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: Shelly.Shelly1PM.ResultMeters
|
||||
// Assembly: Shelly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: 2DDB6D74-8C37-490A-B928-07FB0E37240C
|
||||
// Assembly location: \\192.168.178.26\Freigabe\Shelly.dll
|
||||
|
||||
using System;
|
||||
|
||||
#nullable disable
|
||||
namespace Shelly.Shelly1PM
|
||||
{
|
||||
public class ResultMeters
|
||||
{
|
||||
public Decimal power { get; set; }
|
||||
|
||||
public Decimal overload { get; set; }
|
||||
|
||||
public Decimal total { get; set; }
|
||||
}
|
||||
}
|
||||
14
Sensormat/Shelly/Shelly1PM/ResultSet.cs
Normal file
14
Sensormat/Shelly/Shelly1PM/ResultSet.cs
Normal file
@ -0,0 +1,14 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: Shelly.Shelly1PM.ResultSet
|
||||
// Assembly: Shelly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: 2DDB6D74-8C37-490A-B928-07FB0E37240C
|
||||
// Assembly location: \\192.168.178.26\Freigabe\Shelly.dll
|
||||
|
||||
#nullable disable
|
||||
namespace Shelly.Shelly1PM
|
||||
{
|
||||
public class ResultSet
|
||||
{
|
||||
public ResultMeters[] meters { get; set; }
|
||||
}
|
||||
}
|
||||
39
Sensormat/Shelly/Shelly1PM/SensorEntity.cs
Normal file
39
Sensormat/Shelly/Shelly1PM/SensorEntity.cs
Normal file
@ -0,0 +1,39 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: Shelly.Shelly1PM.SensorEntity
|
||||
// Assembly: Shelly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: 2DDB6D74-8C37-490A-B928-07FB0E37240C
|
||||
// Assembly location: \\192.168.178.26\Freigabe\Shelly.dll
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Sensormat;
|
||||
using Sensormat.Entities;
|
||||
using System;
|
||||
|
||||
#nullable disable
|
||||
namespace Shelly.Shelly1PM
|
||||
{
|
||||
public class SensorEntity : ISensor
|
||||
{
|
||||
public override bool Execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
int id = this.Sensor.ID;
|
||||
new ResultSet().XMLSerializeData<ResultSet>();
|
||||
string str = this.HttpRequest(this.Sensor.URL);
|
||||
if (str != null)
|
||||
{
|
||||
this.LastValue = JsonConvert.DeserializeObject<ResultSet>(str).meters?[0]?.total.ToString();
|
||||
this.LastValueDate = new DateTime?(DateTime.Now);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine((object)ex);
|
||||
this.ErrorMsg = ex.Message;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
16
Sensormat/Shelly/Shelly3PM/Config.cs
Normal file
16
Sensormat/Shelly/Shelly3PM/Config.cs
Normal file
@ -0,0 +1,16 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: Shelly.Shelly3PM.Config
|
||||
// Assembly: Shelly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: 2DDB6D74-8C37-490A-B928-07FB0E37240C
|
||||
// Assembly location: \\192.168.178.26\Freigabe\Shelly.dll
|
||||
|
||||
#nullable disable
|
||||
namespace Shelly.Shelly3PM
|
||||
{
|
||||
public class Config
|
||||
{
|
||||
public bool Sum { get; set; }
|
||||
|
||||
public int index { get; set; }
|
||||
}
|
||||
}
|
||||
24
Sensormat/Shelly/Shelly3PM/ResultMeters.cs
Normal file
24
Sensormat/Shelly/Shelly3PM/ResultMeters.cs
Normal file
@ -0,0 +1,24 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: Shelly.Shelly3PM.ResultMeters
|
||||
// Assembly: Shelly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: 2DDB6D74-8C37-490A-B928-07FB0E37240C
|
||||
// Assembly location: \\192.168.178.26\Freigabe\Shelly.dll
|
||||
|
||||
using System;
|
||||
|
||||
#nullable disable
|
||||
namespace Shelly.Shelly3PM
|
||||
{
|
||||
public class ResultMeters
|
||||
{
|
||||
public Decimal current { get; set; }
|
||||
|
||||
public Decimal power { get; set; }
|
||||
|
||||
public Decimal voltage { get; set; }
|
||||
|
||||
public Decimal total { get; set; }
|
||||
|
||||
public Decimal total_returned { get; set; }
|
||||
}
|
||||
}
|
||||
14
Sensormat/Shelly/Shelly3PM/ResultSet.cs
Normal file
14
Sensormat/Shelly/Shelly3PM/ResultSet.cs
Normal file
@ -0,0 +1,14 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: Shelly.Shelly3PM.ResultSet
|
||||
// Assembly: Shelly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: 2DDB6D74-8C37-490A-B928-07FB0E37240C
|
||||
// Assembly location: \\192.168.178.26\Freigabe\Shelly.dll
|
||||
|
||||
#nullable disable
|
||||
namespace Shelly.Shelly3PM
|
||||
{
|
||||
public class ResultSet
|
||||
{
|
||||
public ResultMeters[] emeters { get; set; }
|
||||
}
|
||||
}
|
||||
47
Sensormat/Shelly/Shelly3PM/SensorEntity.cs
Normal file
47
Sensormat/Shelly/Shelly3PM/SensorEntity.cs
Normal file
@ -0,0 +1,47 @@
|
||||
// Decompiled with JetBrains decompiler
|
||||
// Type: Shelly.Shelly3PM.SensorEntity
|
||||
// Assembly: Shelly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
// MVID: 2DDB6D74-8C37-490A-B928-07FB0E37240C
|
||||
// Assembly location: \\192.168.178.26\Freigabe\Shelly.dll
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Sensormat;
|
||||
using Sensormat.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
#nullable disable
|
||||
namespace Shelly.Shelly3PM
|
||||
{
|
||||
public class SensorEntity : ISensor
|
||||
{
|
||||
private Config cfg;
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.cfg = this.getConfiguration<Config>();
|
||||
new ResultSet().XMLSerializeData<ResultSet>();
|
||||
string str = this.HttpRequest(this.Sensor.URL);
|
||||
if (str != null)
|
||||
{
|
||||
ResultSet resultSet = JsonConvert.DeserializeObject<ResultSet>(str);
|
||||
if (this.cfg.Sum)
|
||||
this.LastValue = ((IEnumerable<ResultMeters>)resultSet.emeters).Sum<ResultMeters>((Func<ResultMeters, Decimal>)(f => f.total)).ToString();
|
||||
else
|
||||
this.LastValue = resultSet.emeters?[this.cfg.index]?.total.ToString();
|
||||
this.LastValueDate = new DateTime?(DateTime.Now);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine((object)ex);
|
||||
this.ErrorMsg = ex.Message;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user