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