added proj
This commit is contained in:
commit
d38f26291f
403
.gitignore
vendored
Normal file
403
.gitignore
vendored
Normal file
@ -0,0 +1,403 @@
|
||||
## 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/main/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# 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/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# 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
|
||||
|
||||
# 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/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# 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
|
||||
*.tlog
|
||||
*.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
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# 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 6 auto-generated project file (contains which files were open etc.)
|
||||
*.vbp
|
||||
|
||||
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
||||
*.dsw
|
||||
*.dsp
|
||||
|
||||
# Visual Studio 6 technical files
|
||||
*.ncb
|
||||
*.aps
|
||||
|
||||
# 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/
|
||||
|
||||
# Visual Studio History (VSHistory) files
|
||||
.vshistory/
|
||||
|
||||
# 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/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
# VS Code files for those working on multiple tools
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Windows Installer files from build outputs
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# JetBrains Rider
|
||||
*.sln.iml
|
||||
Thumbs.db
|
||||
|
||||
*.bak
|
||||
|
||||
.idea/
|
||||
BIN
Actor.csv
Normal file
BIN
Actor.csv
Normal file
Binary file not shown.
|
BIN
ActorType.csv
Normal file
BIN
ActorType.csv
Normal file
Binary file not shown.
|
25
Iot.sln
Normal file
25
Iot.sln
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.1.32210.238
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Iot", "Iot\Iot.csproj", "{29858458-29BE-4432-BADD-3F00367A34D5}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{29858458-29BE-4432-BADD-3F00367A34D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{29858458-29BE-4432-BADD-3F00367A34D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{29858458-29BE-4432-BADD-3F00367A34D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{29858458-29BE-4432-BADD-3F00367A34D5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {8E039742-FC97-46AF-9602-39FD513A6A88}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
113
Iot.sln.DotSettings
Normal file
113
Iot.sln.DotSettings
Normal file
@ -0,0 +1,113 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=39FD3420_002D6140_002D4A24_002D82D3_002D2E9FB14B096E_002Fd_003AClientApp_002Fd_003Adist/@EntryIndexedValue">ExplicitlyExcluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=D2B2F798_002D28FC_002D4515_002D966F_002DB92C3D11D3F2_002Fd_003AClientApp_002Fd_003Adist/@EntryIndexedValue">ExplicitlyExcluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/GeneratedFilesAndFolders/=39FD3420_002D6140_002D4A24_002D82D3_002D2E9FB14B096E_002Fd_003AClientApp_002Fd_003Adist/@EntryIndexedValue">39FD3420-6140-4A24-82D3-2E9FB14B096E/d:ClientApp/d:dist</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/GeneratedFilesAndFolders/=972C43C8_002D8BF9_002D41FA_002DBA3C_002D299AC44A6938_002Fd_003AMigrations/@EntryIndexedValue">972C43C8-8BF9-41FA-BA3C-299AC44A6938/d:Migrations</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/GeneratedFilesAndFolders/=BD772F21_002DD4E2_002D4577_002D9AF3_002DFBE59BB72C03_002Fd_003AMigrations/@EntryIndexedValue">BD772F21-D4E2-4577-9AF3-FBE59BB72C03/d:Migrations</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/GeneratedFilesAndFolders/=D2B2F798_002D28FC_002D4515_002D966F_002DB92C3D11D3F2_002Fd_003AClientApp_002Fd_003Adist/@EntryIndexedValue">D2B2F798-28FC-4515-966F-B92C3D11D3F2/d:ClientApp/d:dist</s:String>
|
||||
|
||||
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedFileMasks/=clipper_002Ecs/@EntryIndexedValue">clipper.cs</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedFileMasks/=package_002Dlock_002Ejson/@EntryIndexedValue">package-lock.json</s:String>
|
||||
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InconsistentNaming/@EntryIndexedValue">SUGGESTION</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnassignedGetOnlyAutoProperty/@EntryIndexedValue">SUGGESTION</s:String>
|
||||
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CppFormatting/INT_ALIGN_COMMENTS/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CppFormatting/INT_ALIGN_DECLARATION_NAMES/@EntryValue">True</s:Boolean>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_BETWEEN_USING_GROUPS/@EntryValue">1</s:Int64>
|
||||
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_ASSIGNMENTS/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_COMMENTS/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_FIELDS/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_INVOCATIONS/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_METHODS/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_PARAMETERS/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_PROPERTIES/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_SWITCH_EXPRESSIONS/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_SWITCH_SECTIONS/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_VARIABLES/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_ATTRIBUTE_ARRANGEMENT/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean>
|
||||
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">250</s:Int64>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/HtmlFormatter/MaxIndentedTagSize/@EntryValue">20000</s:Int64>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/WRAP_LIMIT/@EntryValue">250</s:Int64>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/AddImportsToDeepestScope/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/QualifiedUsingAtNestedScope/@EntryValue">True</s:Boolean>
|
||||
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CRUD/@EntryIndexedValue">CRUD</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/Abbreviations/=CNC/@EntryIndexedValue">CNC</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FBLOCK_005FSCOPE_005FCONSTANT/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FBLOCK_005FSCOPE_005FFUNCTION/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FBLOCK_005FSCOPE_005FVARIABLE/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FCLASS/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FCONSTRUCTOR/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FFUNCTION/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FGLOBAL_005FVARIABLE/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FLABEL/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FLOCAL_005FCONSTRUCTOR/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FLOCAL_005FVARIABLE/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FOBJECT_005FPROPERTY_005FOF_005FFUNCTION/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FPARAMETER/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FCLASS/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FENUM/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FENUM_005FMEMBER/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FINTERFACE/@EntryIndexedValue"><Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FMIXED_005FENUM/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FMODULE/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FMODULE_005FEXPORTED/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FMODULE_005FLOCAL/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPRIVATE_005FMEMBER_005FACCESSOR/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPRIVATE_005FSTATIC_005FTYPE_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPRIVATE_005FTYPE_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPRIVATE_005FTYPE_005FMETHOD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPROTECTED_005FMEMBER_005FACCESSOR/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPROTECTED_005FSTATIC_005FTYPE_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPROTECTED_005FTYPE_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPROTECTED_005FTYPE_005FMETHOD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPUBLIC_005FMEMBER_005FACCESSOR/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPUBLIC_005FSTATIC_005FTYPE_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPUBLIC_005FTYPE_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPUBLIC_005FTYPE_005FMETHOD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FTYPE_005FALIAS/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FTYPE_005FPARAMETER/@EntryIndexedValue"><Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FHTML_005FCONTROL/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FTAG_005FNAME/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FTAG_005FPREFIX/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=NAMESPACE_005FALIAS/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=XAML_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=XAML_005FRESOURCE/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
|
||||
<s:Boolean x:Key="/Default/Environment/ExcludedFiles/FileMasksThirdParty/=node_005Fmodules_005C_002A_002A/@EntryIndexedValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/ExcludedFiles/FileMasksThirdParty/=node_005Fmodules_005C_002A_002A/@EntryIndexRemoved">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/ExcludedFiles/FileMasksThirdParty/=node_005Fmodules_005C_002A_002A/@EntryIndexedValue">True</s:Boolean>
|
||||
|
||||
<s:String x:Key="/Default/Environment/PerformanceGuide/SwitchBehaviour/=Antivirus/@EntryIndexedValue">DO_NOTHING</s:String>
|
||||
<s:String x:Key="/Default/Environment/PerformanceGuide/SwitchBehaviour/=AutoRecoverer/@EntryIndexedValue">LIVE_MONITOR</s:String>
|
||||
<s:String x:Key="/Default/Environment/PerformanceGuide/SwitchBehaviour/=Format/@EntryIndexedValue">LIVE_MONITOR</s:String>
|
||||
<s:String x:Key="/Default/Environment/PerformanceGuide/SwitchBehaviour/=Roslyn_002Dswea/@EntryIndexedValue">DO_NOTHING</s:String>
|
||||
<s:String x:Key="/Default/Environment/PerformanceGuide/SwitchBehaviour/=ShowAnnotations/@EntryIndexedValue">LIVE_MONITOR</s:String>
|
||||
<s:String x:Key="/Default/Environment/PerformanceGuide/SwitchBehaviour/=SolExp_002DTrack/@EntryIndexedValue">LIVE_MONITOR</s:String>
|
||||
<s:String x:Key="/Default/Environment/PerformanceGuide/SwitchBehaviour/=StartPage_002DIsDownloadRefreshEnabled/@EntryIndexedValue">LIVE_MONITOR</s:String>
|
||||
<s:String x:Key="/Default/Environment/PerformanceGuide/SwitchBehaviour/=StartPage_002DOnEnvironmentStatup/@EntryIndexedValue">LIVE_MONITOR</s:String>
|
||||
<s:String x:Key="/Default/Environment/PerformanceGuide/SwitchBehaviour/=SyncSettings/@EntryIndexedValue">LIVE_MONITOR</s:String>
|
||||
<s:String x:Key="/Default/Environment/PerformanceGuide/SwitchBehaviour/=TextEditor_002DCodeLens/@EntryIndexedValue">LIVE_MONITOR</s:String>
|
||||
<s:String x:Key="/Default/Environment/PerformanceGuide/SwitchBehaviour/=TextEditor_002DTrackChanges_002D2/@EntryIndexedValue">LIVE_MONITOR</s:String>
|
||||
<s:String x:Key="/Default/Environment/PerformanceGuide/SwitchBehaviour/=VCS/@EntryIndexedValue">LIVE_MONITOR</s:String>
|
||||
<s:String x:Key="/Default/Environment/PerformanceGuide/SwitchBehaviour/=VsBulb/@EntryIndexedValue">DO_NOTHING</s:String>
|
||||
<s:String x:Key="/Default/Environment/PerformanceGuide/SwitchBehaviour/=XAML_0020Designer/@EntryIndexedValue">LIVE_MONITOR</s:String>
|
||||
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002ECpp_002ECodeStyle_002ESettingsUpgrade_002EFunctionReturnStyleSettingsUpgrader/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
||||
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Aitenbichler/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Arduino/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Cambam/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=HPGL/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=NONINFRINGEMENT/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
11
Iot/CsvEntities/Actor.cs
Normal file
11
Iot/CsvEntities/Actor.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace Iot.CsvEntities;
|
||||
|
||||
using System;
|
||||
|
||||
public class Actor
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public DateTime FirstSeen { get; set; }
|
||||
public int ActorTypeId { get; set; }
|
||||
}
|
||||
7
Iot/CsvEntities/ActorType.cs
Normal file
7
Iot/CsvEntities/ActorType.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace Iot.CsvEntities;
|
||||
|
||||
public class ActorType
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
12
Iot/CsvEntities/Measurement.cs
Normal file
12
Iot/CsvEntities/Measurement.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace Iot.CsvEntities;
|
||||
|
||||
using System;
|
||||
|
||||
public class Measurement
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public DateTime Time { get; set; }
|
||||
public int ActorId { get; set; }
|
||||
public int MeasurementTypeId { get; set; }
|
||||
public double Value { get; set; }
|
||||
}
|
||||
8
Iot/CsvEntities/MeasurementType.cs
Normal file
8
Iot/CsvEntities/MeasurementType.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Iot.CsvEntities;
|
||||
|
||||
public class MeasurementType
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Comment { get; set; }
|
||||
}
|
||||
16
Iot/Entities/Actor.cs
Normal file
16
Iot/Entities/Actor.cs
Normal file
@ -0,0 +1,16 @@
|
||||
namespace Iot.Entities;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class Actor
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public DateTime FirstSeen { get; set; }
|
||||
public int ActorTypeId { get; set; }
|
||||
|
||||
// Navigation Properties
|
||||
public ActorType ActorType { get; set; }
|
||||
public List<Measurement> Measurements { get; set; } = new List<Measurement>();
|
||||
}
|
||||
12
Iot/Entities/ActorType.cs
Normal file
12
Iot/Entities/ActorType.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace Iot.Entities;
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class ActorType
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
// Navigation Property
|
||||
public List<Actor> Actors { get; set; } = new List<Actor>();
|
||||
}
|
||||
45
Iot/Entities/Entities.cd
Normal file
45
Iot/Entities/Entities.cd
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ClassDiagram MajorVersion="1" MinorVersion="1">
|
||||
<Class Name="Iot.Entities.Actor">
|
||||
<Position X="8.5" Y="3" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAACAAAAAAAAAAAEAAAACAQAAAAAAAAAAAAQAAAAAAQ=</HashCode>
|
||||
<FileName>Entities\Actor.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<ShowAsCollectionAssociation>
|
||||
<Property Name="Measurements" />
|
||||
</ShowAsCollectionAssociation>
|
||||
</Class>
|
||||
<Class Name="Iot.Entities.ActorType">
|
||||
<Position X="8.5" Y="0.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAACAAAAAAAAgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Entities\ActorType.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<ShowAsCollectionAssociation>
|
||||
<Property Name="Actors" />
|
||||
</ShowAsCollectionAssociation>
|
||||
</Class>
|
||||
<Class Name="Iot.Entities.Measurement">
|
||||
<Position X="5.75" Y="3.25" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAACAAAAAAAAgAAAAAAAAAAIAAAAIAAAAAAgAQAAAQA=</HashCode>
|
||||
<FileName>Entities\Measurement.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<ShowAsAssociation>
|
||||
<Property Name="MeasurementType" />
|
||||
<Property Name="Actor" />
|
||||
</ShowAsAssociation>
|
||||
</Class>
|
||||
<Class Name="Iot.Entities.MeasurementType">
|
||||
<Position X="5.75" Y="0.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAACAAAEAAAAAAAAAAAAAAQAAAAAAAAAAAAQAAAAAAA=</HashCode>
|
||||
<FileName>Entities\MeasurementType.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<ShowAsCollectionAssociation>
|
||||
<Property Name="Measurements" />
|
||||
</ShowAsCollectionAssociation>
|
||||
</Class>
|
||||
<Font Name="Segoe UI" Size="9" />
|
||||
</ClassDiagram>
|
||||
16
Iot/Entities/Measurement.cs
Normal file
16
Iot/Entities/Measurement.cs
Normal file
@ -0,0 +1,16 @@
|
||||
namespace Iot.Entities;
|
||||
|
||||
using System;
|
||||
|
||||
public class Measurement
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public DateTime Time { get; set; }
|
||||
public int ActorId { get; set; }
|
||||
public int MeasurementTypeId { get; set; }
|
||||
public double Value { get; set; }
|
||||
|
||||
// Navigation Properties
|
||||
public Actor Actor { get; set; }
|
||||
public MeasurementType MeasurementType { get; set; }
|
||||
}
|
||||
13
Iot/Entities/MeasurementType.cs
Normal file
13
Iot/Entities/MeasurementType.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace Iot.Entities;
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class MeasurementType
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Comment { get; set; }
|
||||
|
||||
// Navigation Property
|
||||
public List<Measurement> Measurements { get; set; } = new List<Measurement>();
|
||||
}
|
||||
23
Iot/Iot.csproj
Normal file
23
Iot/Iot.csproj
Normal file
@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\Actor.csv" Link="Actor.csv">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\ActorType.csv" Link="ActorType.csv">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\Measurement.csv" Link="Measurement.csv">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\MeasurementType.csv" Link="MeasurementType.csv">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
195
Iot/Program.cs
Normal file
195
Iot/Program.cs
Normal file
@ -0,0 +1,195 @@
|
||||
/*--------------------------------------------------------------
|
||||
* HTBLA-Leonding / Class: 1xHIF
|
||||
*--------------------------------------------------------------
|
||||
* Musterlösung-HA
|
||||
*--------------------------------------------------------------
|
||||
* Description: Iot
|
||||
*--------------------------------------------------------------
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Iot.Tools;
|
||||
|
||||
|
||||
Console.WriteLine("Iot");
|
||||
Console.WriteLine("=====================");
|
||||
|
||||
#region Import Csvs
|
||||
|
||||
string fileNameActor = "Actor.csv";
|
||||
string fileNameActorType = "ActorType.csv";
|
||||
string fileNameMeasurement = "Measurement.csv";
|
||||
string fileNameMeasurementType = "MeasurementType.csv";
|
||||
|
||||
var actorsCsv = new CsvImport<Iot.CsvEntities.Actor>()
|
||||
{
|
||||
DateFormat = "yyyy/MM/dd",
|
||||
TimeFormat = "HH:mm:ss",
|
||||
Encoding = Encoding.UTF8
|
||||
}.Read(fileNameActor);
|
||||
|
||||
var actorsTypeCsv = new CsvImport<Iot.CsvEntities.ActorType>()
|
||||
{
|
||||
DateFormat = "yyyy/MM/dd",
|
||||
TimeFormat = "HH:mm:ss",
|
||||
Encoding = Encoding.UTF8
|
||||
}.Read(fileNameActorType);
|
||||
|
||||
var measurementsCsv = new CsvImport<Iot.CsvEntities.Measurement>()
|
||||
{
|
||||
DateFormat = "yyyy/MM/dd",
|
||||
TimeFormat = "HH:mm:ss",
|
||||
Encoding = Encoding.UTF8
|
||||
}.Read(fileNameMeasurement);
|
||||
|
||||
var measurementTypesCsv = new CsvImport<Iot.CsvEntities.MeasurementType>()
|
||||
{
|
||||
DateFormat = "yyyy/MM/dd",
|
||||
TimeFormat = "HH:mm:ss",
|
||||
Encoding = Encoding.UTF8
|
||||
}.Read(fileNameMeasurementType);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Convert to Entities (with navigation properties)
|
||||
|
||||
var actorTypes = actorsTypeCsv.Select(at => new Iot.Entities.ActorType
|
||||
{
|
||||
Id = at.Id,
|
||||
Name = at.Name
|
||||
}).ToDictionary(x => x.Id, x => x);
|
||||
|
||||
var actors = actorsCsv.Select(a => new Iot.Entities.Actor
|
||||
{
|
||||
Id = a.Id,
|
||||
Name = a.Name,
|
||||
FirstSeen = a.FirstSeen,
|
||||
ActorTypeId = a.ActorTypeId,
|
||||
ActorType = actorTypes[a.ActorTypeId]
|
||||
}).ToList();
|
||||
|
||||
var measurementTypes = measurementTypesCsv.Select(mt => new Iot.Entities.MeasurementType
|
||||
{
|
||||
Id = mt.Id,
|
||||
Name = mt.Name,
|
||||
Comment = mt.Comment
|
||||
}).ToList();
|
||||
|
||||
var measurementTypeDict = measurementTypes.ToDictionary(x => x.Id);
|
||||
var actorDict = actors.ToDictionary(a => a.Id);
|
||||
|
||||
var measurements = measurementsCsv.Select(m =>
|
||||
{
|
||||
actorDict.TryGetValue(m.ActorId, out var actor);
|
||||
measurementTypeDict.TryGetValue(m.MeasurementTypeId, out var measurementType);
|
||||
|
||||
return new Iot.Entities.Measurement
|
||||
{
|
||||
Id = m.Id,
|
||||
Time = m.Time,
|
||||
ActorId = m.ActorId,
|
||||
MeasurementTypeId = m.MeasurementTypeId,
|
||||
Value = m.Value,
|
||||
Actor = actor,
|
||||
MeasurementType = measurementType
|
||||
};
|
||||
}).ToList();
|
||||
|
||||
|
||||
// Populate Actor.Measurements using ToLookup (O(n) instead of O(n*m))
|
||||
var measurementsByActor = measurements.ToLookup(m => m.ActorId);
|
||||
foreach (var actor in actors)
|
||||
{
|
||||
actor.Measurements = measurementsByActor[actor.Id].ToList();
|
||||
}
|
||||
|
||||
// Populate MeasurementType.Measurements using ToLookup (O(n) instead of O(n*m))
|
||||
var measurementsByType = measurements.ToLookup(m => m.MeasurementTypeId);
|
||||
foreach (var measurementType in measurementTypes)
|
||||
{
|
||||
measurementType.Measurements = measurementsByType[measurementType.Id].ToList();
|
||||
}
|
||||
|
||||
// Populate ActorType.Actors using ToLookup (O(n) instead of O(n*m))
|
||||
var actorsByType = actors.ToLookup(a => a.ActorTypeId);
|
||||
foreach (var actorType in actorTypes.Values)
|
||||
{
|
||||
actorType.Actors = actorsByType[actorType.Id].ToList();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region some Reports
|
||||
|
||||
Console.WriteLine("List of Actors");
|
||||
Console.WriteLine("Id Name Count");
|
||||
Console.WriteLine("==========================");
|
||||
|
||||
var actorReport = actors
|
||||
.Select(a => new
|
||||
{
|
||||
a.Id,
|
||||
a.Name,
|
||||
Count = a.Measurements.Count
|
||||
})
|
||||
.OrderBy(a => a.Id);
|
||||
|
||||
foreach (var item in actorReport)
|
||||
{
|
||||
Console.WriteLine($"{item.Id,2} {item.Name,-17} {item.Count,5}");
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("List of Measurement-Types");
|
||||
Console.WriteLine("Id Name Count");
|
||||
Console.WriteLine("==========================");
|
||||
|
||||
var measurementTypeReport = measurementTypes
|
||||
.Select(mt => new
|
||||
{
|
||||
mt.Id,
|
||||
mt.Name,
|
||||
Count = mt.Measurements.Count
|
||||
})
|
||||
.OrderBy(mt => mt.Id);
|
||||
|
||||
foreach (var item in measurementTypeReport)
|
||||
{
|
||||
Console.WriteLine($"{item.Id,2} {item.Name,-17} {item.Count,5}");
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("List of Actor by Measurement-Types");
|
||||
Console.WriteLine("Actor Measurement Count Min Max");
|
||||
Console.WriteLine("==============================================================");
|
||||
|
||||
var actorMeasurementReport = measurements
|
||||
.GroupBy(m => new
|
||||
{
|
||||
ActorName = m.Actor?.Name ?? "Unknown",
|
||||
MeasurementName = m.MeasurementType?.Name ?? "Unknown"
|
||||
})
|
||||
.Select(g =>
|
||||
{
|
||||
var values = g.Select(m => m.Value).ToList();
|
||||
return new
|
||||
{
|
||||
Actor = g.Key.ActorName,
|
||||
Measurement = g.Key.MeasurementName,
|
||||
Count = values.Count,
|
||||
Min = values.Min(),
|
||||
Max = values.Max()
|
||||
};
|
||||
})
|
||||
.OrderBy(r => r.Actor)
|
||||
.ThenBy(r => r.Measurement);
|
||||
|
||||
foreach (var item in actorMeasurementReport)
|
||||
{
|
||||
Console.WriteLine($"{item.Actor,-14} {item.Measurement,-18} {item.Count,5} {item.Min,10:F2} {item.Max,10:F2}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
253
Iot/Tools/CsvImport.cs
Normal file
253
Iot/Tools/CsvImport.cs
Normal file
@ -0,0 +1,253 @@
|
||||
/*
|
||||
This file is part of https://github.com/aiten/Framework.
|
||||
|
||||
Copyright (c) Herbert Aitenbichler
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
namespace Iot.Tools
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class CsvImport<T> : CsvImportBase where T : new()
|
||||
{
|
||||
public class ColumnMapping
|
||||
{
|
||||
public string ColumnName { get; set; }
|
||||
public PropertyInfo MapTo { get; set; }
|
||||
public bool Ignore { get; set; }
|
||||
|
||||
#pragma warning disable CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
|
||||
public Func<string, object> GetValue { get; set; }
|
||||
public Func<object, object> AdjustValue { get; set; }
|
||||
public Action<T, string> SetValue { get; set; }
|
||||
|
||||
#pragma warning restore CS8632
|
||||
|
||||
public bool IsConfigured => Ignore || MapTo != null || SetValue != null;
|
||||
public bool IsMapped => !Ignore && MapTo != null;
|
||||
public bool IsSetValue => !Ignore && SetValue != null;
|
||||
}
|
||||
|
||||
public ICollection<string> IgnoreColumns { get; set; }
|
||||
public IDictionary<string, string> MapColumns { get; set; }
|
||||
|
||||
public IList<T> Read(string[] csvLines)
|
||||
{
|
||||
var lines = ReadStringMatrixFromCsv(csvLines, false);
|
||||
return MapTo(lines);
|
||||
}
|
||||
|
||||
public IList<T> Read(string fileName)
|
||||
{
|
||||
var lines = ReadStringMatrixFromCsv(fileName, false);
|
||||
return MapTo(lines);
|
||||
}
|
||||
|
||||
public async Task<IList<T>> ReadAsync(string fileName)
|
||||
{
|
||||
var lines = await ReadStringMatrixFromCsvAsync(fileName, false);
|
||||
return MapTo(lines);
|
||||
}
|
||||
|
||||
public IList<T> MapTo(IList<IList<string>> lines)
|
||||
{
|
||||
// first line is columnLineHeader!!!!
|
||||
|
||||
var mapping = GetPropertyMapping(lines[0]);
|
||||
CheckPropertyMapping(mapping);
|
||||
|
||||
var list = new List<T>();
|
||||
var first = true;
|
||||
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add(Map(line, mapping));
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private void CheckPropertyMapping(ColumnMapping[] mapping)
|
||||
{
|
||||
var notConfigured = mapping.Where(m => !m.IsConfigured).ToList();
|
||||
if (notConfigured.Any())
|
||||
{
|
||||
var columnList = string.Join(", ", notConfigured.Select(m => m.ColumnName));
|
||||
throw new ArgumentException($"Column cannot be mapped: {columnList}");
|
||||
}
|
||||
|
||||
var notCanWrite = mapping.Where(x => x.IsMapped && !x.MapTo.CanWrite).ToList();
|
||||
if (notCanWrite.Any())
|
||||
{
|
||||
var columnList = string.Join(", ", notCanWrite.Select(m => m.ColumnName));
|
||||
throw new ArgumentException($"Column is readonly: {columnList}");
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual ColumnMapping[] GetPropertyMapping(IList<string> columnNames)
|
||||
{
|
||||
return columnNames
|
||||
.Select(GetColumnMapping)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
public Action<ColumnMapping> ConfigureColumnMapping { get; set; }
|
||||
|
||||
protected virtual ColumnMapping GetColumnMapping(string columnName)
|
||||
{
|
||||
var ignoreColumn = IgnoreColumns?.Contains(columnName, StringComparer.InvariantCultureIgnoreCase) ?? false;
|
||||
var mapToColumn = MapColumns?.ContainsKey(columnName) ?? false ? MapColumns[columnName] : columnName;
|
||||
|
||||
var columnMapping = new ColumnMapping
|
||||
{
|
||||
ColumnName = columnName,
|
||||
Ignore = ignoreColumn,
|
||||
MapTo = ignoreColumn ? null : GetPropertyInfo(mapToColumn),
|
||||
};
|
||||
|
||||
ConfigureColumnMapping?.Invoke(columnMapping);
|
||||
return columnMapping;
|
||||
}
|
||||
|
||||
public static PropertyInfo GetPropertyInfo(string columnName)
|
||||
{
|
||||
return typeof(T).GetProperty(columnName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
|
||||
}
|
||||
|
||||
private T Map(IList<string> line, ColumnMapping[] mapping)
|
||||
{
|
||||
var newT = new T();
|
||||
|
||||
var idx = 0;
|
||||
foreach (var column in line)
|
||||
{
|
||||
AssignProperty(newT, column, mapping[idx++]);
|
||||
}
|
||||
|
||||
return newT;
|
||||
}
|
||||
|
||||
#pragma warning disable 8632
|
||||
private object GetValue(string valueAsString, Type type)
|
||||
#pragma warning restore 8632
|
||||
{
|
||||
if (type.IsGenericType && type.Name.StartsWith(@"Nullable"))
|
||||
{
|
||||
if (string.IsNullOrEmpty(valueAsString))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
type = type.GenericTypeArguments[0];
|
||||
}
|
||||
|
||||
if (type == typeof(string))
|
||||
{
|
||||
return ExcelString(valueAsString);
|
||||
}
|
||||
else if (type == typeof(int))
|
||||
{
|
||||
return ExcelInt(valueAsString);
|
||||
}
|
||||
else if (type == typeof(long))
|
||||
{
|
||||
return ExcelLong(valueAsString);
|
||||
}
|
||||
else if (type == typeof(short))
|
||||
{
|
||||
return ExcelShort(valueAsString);
|
||||
}
|
||||
else if (type == typeof(uint))
|
||||
{
|
||||
return ExcelUInt(valueAsString);
|
||||
}
|
||||
else if (type == typeof(ulong))
|
||||
{
|
||||
return ExcelULong(valueAsString);
|
||||
}
|
||||
else if (type == typeof(ushort))
|
||||
{
|
||||
return ExcelUShort(valueAsString);
|
||||
}
|
||||
else if (type == typeof(decimal))
|
||||
{
|
||||
return ExcelDecimal(valueAsString);
|
||||
}
|
||||
else if (type == typeof(byte))
|
||||
{
|
||||
return ExcelByte(valueAsString);
|
||||
}
|
||||
else if (type == typeof(bool))
|
||||
{
|
||||
return ExcelBool(valueAsString);
|
||||
}
|
||||
else if (type == typeof(DateTime))
|
||||
{
|
||||
return ExcelDateOrDateTime(valueAsString);
|
||||
}
|
||||
else if (type == typeof(TimeSpan))
|
||||
{
|
||||
return ExcelTimeSpan(valueAsString);
|
||||
}
|
||||
else if (type == typeof(double))
|
||||
{
|
||||
return ExcelDouble(valueAsString);
|
||||
}
|
||||
else if (type.IsEnum)
|
||||
{
|
||||
return ExcelEnum(type, valueAsString);
|
||||
}
|
||||
else if (type == typeof(byte[]))
|
||||
{
|
||||
return ExcelImage(valueAsString);
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void AssignProperty(object obj, string valueAsString, ColumnMapping mapping)
|
||||
{
|
||||
if (mapping.IsSetValue)
|
||||
{
|
||||
mapping.SetValue((T)obj, valueAsString);
|
||||
}
|
||||
else if (mapping.IsMapped)
|
||||
{
|
||||
var mapTo = mapping.MapTo;
|
||||
#pragma warning disable 8632
|
||||
object val = mapping.GetValue != null
|
||||
? mapping.GetValue(valueAsString)
|
||||
: GetValue(valueAsString, mapTo.PropertyType);
|
||||
#pragma warning restore 8632
|
||||
|
||||
if (mapping.AdjustValue != null)
|
||||
{
|
||||
val = mapping.AdjustValue(val);
|
||||
}
|
||||
|
||||
mapTo.SetValue(obj, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
410
Iot/Tools/CsvImportBase.cs
Normal file
410
Iot/Tools/CsvImportBase.cs
Normal file
@ -0,0 +1,410 @@
|
||||
/*
|
||||
This file is part of https://github.com/aiten/Framework.
|
||||
|
||||
Copyright (c) Herbert Aitenbichler
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
namespace Iot.Tools
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class CsvImportBase
|
||||
{
|
||||
private readonly NumberFormatInfo _nfi;
|
||||
|
||||
public Encoding Encoding { get; set; } = Encoding.Default;
|
||||
|
||||
public string DateFormat { get; set; } = "yyyy/MM/dd";
|
||||
public string TimeFormat { get; set; } = "HH:mm:ss";
|
||||
public string Fraction3Format { get; set; } = ".fff";
|
||||
public string Fraction5Format { get; set; } = ".fffff";
|
||||
|
||||
public string DateTimeFormat => GetDateTimeFormat(DateFormat, TimeFormat);
|
||||
public string DateTimeFraction1Format => GetDateTimeFormat(DateFormat, TimeFormat, Fraction3Format);
|
||||
public string DateTimeFraction5Format => GetDateTimeFormat(DateFormat, TimeFormat, Fraction5Format);
|
||||
|
||||
public string GetDateTimeFormat(string dateFormat, string timeFormat, string fractionFormat = null) => $"{dateFormat} {timeFormat}{fractionFormat ?? ""}";
|
||||
|
||||
public event EventHandler<IList<string>> ReadFirstLine;
|
||||
|
||||
public char ListSeparatorChar { get; set; } = ';';
|
||||
|
||||
public string NewLineInString { get; set; } = "\n";
|
||||
|
||||
public CsvImportBase()
|
||||
{
|
||||
// Retrieve a writable NumberFormatInfo object.
|
||||
var enUS = CultureInfo.CreateSpecificCulture("en-US");
|
||||
_nfi = enUS.NumberFormat;
|
||||
}
|
||||
|
||||
public NumberFormatInfo NumberFormat => _nfi;
|
||||
|
||||
public void SetAustriaNumberFormat()
|
||||
{
|
||||
_nfi.NumberDecimalSeparator = ",";
|
||||
_nfi.NumberGroupSeparator = ".";
|
||||
}
|
||||
|
||||
#region read
|
||||
|
||||
public IList<IList<string>> ReadStringMatrixFromCsv(string[] lines, bool skipTitleLine)
|
||||
{
|
||||
var elements = new List<IList<string>>();
|
||||
var lineIdx = 0;
|
||||
var readLineIdx = 0;
|
||||
var compareLineIdx = skipTitleLine ? 1 : 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
var row = ReadLine(() =>
|
||||
{
|
||||
if (readLineIdx >= lines.Length)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return lines[readLineIdx++];
|
||||
});
|
||||
|
||||
if (row == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (lineIdx == 0)
|
||||
{
|
||||
ReadFirstLine?.Invoke(this, row);
|
||||
}
|
||||
|
||||
if (lineIdx >= compareLineIdx)
|
||||
{
|
||||
elements.Add(row);
|
||||
}
|
||||
|
||||
lineIdx++;
|
||||
}
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
public IList<IList<string>> ReadStringMatrixFromCsv(string fileName, bool skipTitleLine)
|
||||
{
|
||||
var lines = File.ReadAllLines(fileName, Encoding);
|
||||
return ReadStringMatrixFromCsv(lines, skipTitleLine);
|
||||
}
|
||||
|
||||
public async Task<IList<IList<string>>> ReadStringMatrixFromCsvAsync(string fileName, bool skipTitleLine)
|
||||
{
|
||||
var lines = await File.ReadAllLinesAsync(fileName, Encoding);
|
||||
return ReadStringMatrixFromCsv(lines, skipTitleLine);
|
||||
}
|
||||
|
||||
private IList<string> ReadLine(Func<string> getNextLine)
|
||||
{
|
||||
var line = getNextLine();
|
||||
if (line == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var columns = new List<string>();
|
||||
var sb = new StringBuilder(line.Length);
|
||||
var noQuoteChar = '\0';
|
||||
var quoteChar = noQuoteChar;
|
||||
|
||||
while (true)
|
||||
{
|
||||
for (var idx = 0; idx < line.Length; idx++)
|
||||
{
|
||||
var ch = line[idx];
|
||||
|
||||
if (ch == quoteChar)
|
||||
{
|
||||
// end of " or ""
|
||||
if (idx + 1 < line.Length && line[idx + 1] == quoteChar)
|
||||
{
|
||||
idx++;
|
||||
sb.Append(ch);
|
||||
}
|
||||
else
|
||||
{
|
||||
quoteChar = noQuoteChar;
|
||||
}
|
||||
}
|
||||
else if (quoteChar == noQuoteChar && ch == '"')
|
||||
{
|
||||
quoteChar = ch;
|
||||
}
|
||||
else if (quoteChar == noQuoteChar && ch == ListSeparatorChar)
|
||||
{
|
||||
columns.Add(sb.ToString());
|
||||
sb.Clear();
|
||||
}
|
||||
|
||||
else if (quoteChar == noQuoteChar && ch == '|')
|
||||
{
|
||||
columns.Add(sb.ToString());
|
||||
sb.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(ch);
|
||||
}
|
||||
}
|
||||
|
||||
if (quoteChar == noQuoteChar)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
sb.Append(NewLineInString);
|
||||
|
||||
line = getNextLine();
|
||||
}
|
||||
|
||||
columns.Add(sb.ToString());
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region convert
|
||||
|
||||
public string ExcelString(string excelField)
|
||||
{
|
||||
return excelField;
|
||||
}
|
||||
|
||||
public short ExcelShort(string excelField)
|
||||
{
|
||||
return short.Parse(excelField);
|
||||
}
|
||||
|
||||
public int ExcelInt(string excelField)
|
||||
{
|
||||
return int.Parse(excelField);
|
||||
}
|
||||
|
||||
public long ExcelLong(string excelField)
|
||||
{
|
||||
return long.Parse(excelField);
|
||||
}
|
||||
|
||||
public ushort ExcelUShort(string excelField)
|
||||
{
|
||||
return ushort.Parse(excelField);
|
||||
}
|
||||
|
||||
public uint ExcelUInt(string excelField)
|
||||
{
|
||||
return uint.Parse(excelField);
|
||||
}
|
||||
|
||||
public ulong ExcelULong(string excelField)
|
||||
{
|
||||
return ulong.Parse(excelField);
|
||||
}
|
||||
|
||||
public float ExcelFloat(string excelField)
|
||||
{
|
||||
return float.Parse(excelField, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands, _nfi);
|
||||
}
|
||||
|
||||
public byte ExcelByte(string excelField)
|
||||
{
|
||||
return byte.Parse(excelField);
|
||||
}
|
||||
|
||||
public bool ExcelBool(string excelField)
|
||||
{
|
||||
switch (excelField)
|
||||
{
|
||||
case @"0":
|
||||
case @"false":
|
||||
return false;
|
||||
case @"1":
|
||||
case @"true":
|
||||
return true;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(excelField), excelField, $@"cannot convert '{excelField}' to 'bool'.");
|
||||
}
|
||||
}
|
||||
|
||||
public decimal ExcelDecimal(string excelField)
|
||||
{
|
||||
return decimal.Parse(excelField, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands, _nfi);
|
||||
}
|
||||
|
||||
public double ExcelDouble(string excelField)
|
||||
{
|
||||
return double.Parse(excelField, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands, _nfi);
|
||||
}
|
||||
|
||||
public DateTime ExcelDateOrDateTime(string excelField)
|
||||
{
|
||||
if (excelField.Length > DateFormat.Length)
|
||||
{
|
||||
return ExcelDateTime(excelField, DateFormat, TimeFormat, Fraction3Format, Fraction3Format);
|
||||
}
|
||||
|
||||
return ExcelDate(excelField, DateFormat);
|
||||
}
|
||||
|
||||
public DateTime ExcelDate(string excelField, string format)
|
||||
{
|
||||
try
|
||||
{
|
||||
return DateTime.ParseExact(excelField, format, CultureInfo.InvariantCulture);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime ExcelDate(string excelField)
|
||||
{
|
||||
return ExcelDate(excelField, DateFormat);
|
||||
}
|
||||
|
||||
public DateTime ExcelDateDMY(string excelField)
|
||||
{
|
||||
// Parse date and time with custom specifier.
|
||||
// e.g. string dateString = "19.01.2018";
|
||||
return ExcelDate(excelField, "dd.MM.yyyy");
|
||||
}
|
||||
|
||||
public DateTime ExcelDateYMD(string excelField)
|
||||
{
|
||||
// Parse date and time with custom specifier.
|
||||
// e.g. string dateString = "19.01.2018";
|
||||
return ExcelDate(excelField, "yyyy/MM/dd");
|
||||
}
|
||||
|
||||
public object ExcelTimeSpan(string excelField)
|
||||
{
|
||||
try
|
||||
{
|
||||
var timeSpan = TimeSpan.Parse(excelField);
|
||||
return timeSpan;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception(e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime ExcelDateTime(string excelField, string formatDate, string formatTime, string formatFraction3, string formatFraction5)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fractionFormat = string.Empty;
|
||||
|
||||
var dotIdx = excelField.LastIndexOf('.');
|
||||
if (dotIdx > formatDate.Length)
|
||||
{
|
||||
var fractionLength = excelField.Length - dotIdx - 1;
|
||||
fractionFormat = fractionLength == 3 ? formatFraction3 : formatFraction5;
|
||||
}
|
||||
|
||||
return DateTime.ParseExact(excelField, GetDateTimeFormat(formatDate, formatTime, fractionFormat), CultureInfo.InvariantCulture);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime ExcelDateTime(string excelField)
|
||||
{
|
||||
return ExcelDateTime(excelField, DateFormat, TimeFormat, Fraction3Format, Fraction5Format);
|
||||
}
|
||||
|
||||
public DateTime ExcelDateTimeYMD(string excelField)
|
||||
{
|
||||
return ExcelDateTime(excelField, "yyyy/MM/dd", TimeFormat, Fraction3Format, Fraction5Format);
|
||||
}
|
||||
|
||||
public object ExcelEnum(Type enumType, string excelField)
|
||||
{
|
||||
try
|
||||
{
|
||||
var enumValue = Enum.Parse(enumType, excelField);
|
||||
return enumValue;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] ExcelImage(string excelField)
|
||||
{
|
||||
byte[] bytes;
|
||||
|
||||
if (excelField.StartsWith(@"0x"))
|
||||
{
|
||||
if (excelField.Length % 2 == 1)
|
||||
{
|
||||
throw new ArgumentException(@"string has odd length.", nameof(excelField));
|
||||
}
|
||||
|
||||
int length = (excelField.Length - 2) / 2;
|
||||
int chIdx = 2;
|
||||
|
||||
bytes = new byte[length];
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
bytes[i] = (byte)(ToHex(excelField[chIdx]) * 16 + ToHex(excelField[chIdx + 1]));
|
||||
chIdx += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes = Convert.FromBase64String(excelField);
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private int ToHex(char ch)
|
||||
{
|
||||
if (ch >= '0' && ch <= '9')
|
||||
{
|
||||
return ch - '0';
|
||||
}
|
||||
|
||||
if (ch >= 'a' && ch <= 'f')
|
||||
{
|
||||
return 10 + ch - 'a';
|
||||
}
|
||||
|
||||
if (ch >= 'A' && ch <= 'F')
|
||||
{
|
||||
return 10 + ch - 'F';
|
||||
}
|
||||
|
||||
throw new ArgumentException(nameof(ch), $@"'{ch}' is not a hex digit.");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
BIN
Measurement.csv
Normal file
BIN
Measurement.csv
Normal file
Binary file not shown.
|
Can't render this file because it is too large.
|
BIN
MeasurementType.csv
Normal file
BIN
MeasurementType.csv
Normal file
Binary file not shown.
|
77
README.md
Normal file
77
README.md
Normal file
@ -0,0 +1,77 @@
|
||||
"# 10-Iot
|
||||
|
||||
## Lehrziele
|
||||
- LINQ to Object
|
||||
- Navigation Properties
|
||||
- Wiederholung: Projektion, Join, GroupBy
|
||||
|
||||
## Aufgabenstellung
|
||||
In einem IoT Projekt werden Messdaten gesammelt und in einer Datenbank abgespeichert. Von dieser Datenbank sind CSV Exportdateien vorhanden:
|
||||
|
||||
### Datenstruktur
|
||||
|
||||
#### ActorType.csv
|
||||
Kategorisierung der Aktoren.
|
||||
- Id: Eindeutige ID
|
||||
- Name: Bezeichnung der Aktorkategorie
|
||||
|
||||
#### Actor.csv
|
||||
Liste aller im System vorhandenen Aktoren.
|
||||
- Id: Eindeutige ID
|
||||
- Name: Bezeichnung des Aktors
|
||||
- FirstSeen: Zeitpunkt der ersten Registrierung
|
||||
- ActorTypeId: Beziehung zu den Aktoren-Kategorien
|
||||
|
||||
#### MeasurementType.csv
|
||||
Liste aller Messwert-Kategorien.
|
||||
- Id: Eindeutige ID
|
||||
- Name: Bezeichnung (z.B. "Temperature")
|
||||
- Comment: Kommentar/Beschreibung
|
||||
|
||||
#### Measurement.csv
|
||||
Liste aller (historischen) Messwerte.
|
||||
- Id: Eindeutige ID
|
||||
- Time: Zeitpunkt der Messung
|
||||
- ActorId: Zuordnung zu einem Aktor
|
||||
- MeasurementTypeId: Zuordnung zu einer Messwert-Kategorie
|
||||
- Value: Der gemessene Wert
|
||||
|
||||
## Implementierung
|
||||
|
||||
### Entitäten
|
||||
Das Projekt enthält zwei Arten von Entitäten:
|
||||
|
||||
1. **CsvEntities**: Einfache DTOs für den CSV-Import (ohne Beziehungen)
|
||||
2. **Entities**: Domain-Entitäten mit Navigation Properties
|
||||
|
||||
### Navigation Properties
|
||||
Die Entities implementieren folgende Beziehungen:
|
||||
- `ActorType` → `Actors` (1:n)
|
||||
- `Actor` → `ActorType` (n:1)
|
||||
- `Actor` → `Measurements` (1:n)
|
||||
- `MeasurementType` → `Measurements` (1:n)
|
||||
- `Measurement` → `Actor` (n:1)
|
||||
- `Measurement` → `MeasurementType` (n:1)
|
||||
|
||||
### LINQ Queries
|
||||
Das Programm demonstriert verschiedene LINQ-Operationen:
|
||||
|
||||
#### Report 1: Liste aller Aktoren mit Anzahl der Messungen
|
||||
- **Verwendete LINQ-Operationen**: Select, Projection, OrderBy
|
||||
|
||||
#### Report 2: Liste aller Messwert-Typen mit Anzahl
|
||||
- **Verwendete LINQ-Operationen**: Select, Projection, OrderBy
|
||||
|
||||
#### Report 3: Aktoren nach Messwert-Typen gruppiert mit Statistiken
|
||||
- **Verwendete LINQ-Operationen**: GroupBy, Select, Projection, Min, Max, Count, OrderBy
|
||||
- Zeigt für jede Kombination von Aktor und Messwert-Typ:
|
||||
- Anzahl der Messungen
|
||||
- Minimaler Wert
|
||||
- Maximaler Wert
|
||||
|
||||
## Ausführung
|
||||
```bash
|
||||
dotnet run --project Iot/Iot.csproj
|
||||
```
|
||||
"
|
||||
|
||||
61
flake.lock
generated
Normal file
61
flake.lock
generated
Normal file
@ -0,0 +1,61 @@
|
||||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1768305791,
|
||||
"narHash": "sha256-AIdl6WAn9aymeaH/NvBj0H9qM+XuAuYbGMZaP0zcXAQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "1412caf7bf9e660f2f962917c14b1ea1c3bc695e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
25
flake.nix
Normal file
25
flake.nix
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
description = "Dev shell with .NET 9";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils, ... }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
};
|
||||
in {
|
||||
devShells.default = pkgs.mkShell {
|
||||
packages = [
|
||||
pkgs.dotnet-sdk_9
|
||||
# alternativ/zusätzlich:
|
||||
# pkgs.dotnetCorePackages.sdk_9_0
|
||||
];
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user