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