xuhsili 1 anno fa
commit
2b632b7340
100 ha cambiato i file con 3560 aggiunte e 0 eliminazioni
  1. 63 0
      .gitattributes
  2. 363 0
      .gitignore
  3. 9 0
      .idea/NEIntelligentControl2.iml
  4. 6 0
      .idea/misc.xml
  5. 8 0
      .idea/modules.xml
  6. 6 0
      .idea/vcs.xml
  7. 31 0
      NEIntelligentControl2.sln
  8. 174 0
      NEIntelligentControl2/AlarmInfo.json
  9. 94 0
      NEIntelligentControl2/App.config
  10. 216 0
      NEIntelligentControl2/App.xaml
  11. 108 0
      NEIntelligentControl2/App.xaml.cs
  12. 231 0
      NEIntelligentControl2/ComparisonInfo.json
  13. BIN
      NEIntelligentControl2/Images/AGC/agc_off.png
  14. BIN
      NEIntelligentControl2/Images/AGC/agc_on.png
  15. BIN
      NEIntelligentControl2/Images/AGC/restricted.png
  16. BIN
      NEIntelligentControl2/Images/AGC/unrestricted.png
  17. BIN
      NEIntelligentControl2/Images/BoostStation/boost_station_title.png
  18. BIN
      NEIntelligentControl2/Images/PV/close.png
  19. BIN
      NEIntelligentControl2/Images/PV/pv_arrow_pic.png
  20. BIN
      NEIntelligentControl2/Images/PV/pv_box_pic.png
  21. BIN
      NEIntelligentControl2/Images/PV/pv_box_transformer.png
  22. BIN
      NEIntelligentControl2/Images/PV/pv_elec_pic.png
  23. BIN
      NEIntelligentControl2/Images/PV/pv_nb_pic.png
  24. BIN
      NEIntelligentControl2/Images/PV/pv_pic.png
  25. BIN
      NEIntelligentControl2/Images/PV/pv_state_blue.png
  26. BIN
      NEIntelligentControl2/Images/PV/pv_state_gre.png
  27. BIN
      NEIntelligentControl2/Images/PV/pv_state_grey.png
  28. BIN
      NEIntelligentControl2/Images/PV/pv_state_org.png
  29. BIN
      NEIntelligentControl2/Images/PV/pv_state_red.png
  30. BIN
      NEIntelligentControl2/Images/PV/pv_state_un.png
  31. BIN
      NEIntelligentControl2/Images/PV/pv_state_vio.png
  32. BIN
      NEIntelligentControl2/Images/PV/zhengti.png
  33. BIN
      NEIntelligentControl2/Images/Remomend/calc_all.png
  34. BIN
      NEIntelligentControl2/Images/Remomend/calc_maintain.png
  35. BIN
      NEIntelligentControl2/Images/Remomend/calc_reset.png
  36. BIN
      NEIntelligentControl2/Images/Remomend/calc_startr.png
  37. BIN
      NEIntelligentControl2/Images/Remomend/calc_stop.png
  38. BIN
      NEIntelligentControl2/Images/Remomend/calc_unmaintian.png
  39. BIN
      NEIntelligentControl2/Images/StatusBar/agc.png
  40. BIN
      NEIntelligentControl2/Images/StatusBar/alarm.png
  41. BIN
      NEIntelligentControl2/Images/StatusBar/alarm_center.png
  42. BIN
      NEIntelligentControl2/Images/StatusBar/booster_station.png
  43. BIN
      NEIntelligentControl2/Images/StatusBar/calculation_result_playback.png
  44. BIN
      NEIntelligentControl2/Images/StatusBar/help.png
  45. BIN
      NEIntelligentControl2/Images/StatusBar/menu.png
  46. BIN
      NEIntelligentControl2/Images/StatusBar/menu_over.png
  47. BIN
      NEIntelligentControl2/Images/StatusBar/recommend.png
  48. BIN
      NEIntelligentControl2/Images/StatusBar/recommend_over.png
  49. BIN
      NEIntelligentControl2/Images/StatusBar/track.png
  50. BIN
      NEIntelligentControl2/Images/StatusBar/track_over.png
  51. BIN
      NEIntelligentControl2/Images/StatusBar/windturbine_matrix.png
  52. BIN
      NEIntelligentControl2/Images/TitleBar/background.png
  53. BIN
      NEIntelligentControl2/Images/TitleBar/item_background.png
  54. BIN
      NEIntelligentControl2/Images/TitleBar/item_background_selected.png
  55. BIN
      NEIntelligentControl2/Images/TitleBar/user_add.png
  56. BIN
      NEIntelligentControl2/Images/TitleBar/user_edit.png
  57. BIN
      NEIntelligentControl2/Images/TitleBar/user_logout.png
  58. BIN
      NEIntelligentControl2/Images/User/finger.gif
  59. BIN
      NEIntelligentControl2/Images/User/finger.png
  60. BIN
      NEIntelligentControl2/Images/Windturbine/windturbine.png
  61. 26 0
      NEIntelligentControl2/MainWindow.xaml
  62. 63 0
      NEIntelligentControl2/MainWindow.xaml.cs
  63. 32 0
      NEIntelligentControl2/MessageWindow.xaml
  64. 53 0
      NEIntelligentControl2/MessageWindow.xaml.cs
  65. 63 0
      NEIntelligentControl2/Models/AGC/AGCInfo.cs
  66. 82 0
      NEIntelligentControl2/Models/AGC/TagInfo.cs
  67. 28 0
      NEIntelligentControl2/Models/AGC/TagType.cs
  68. 135 0
      NEIntelligentControl2/Models/AGC/ViewModel.cs
  69. 89 0
      NEIntelligentControl2/Models/Alarm/AlarmInfo.cs
  70. 28 0
      NEIntelligentControl2/Models/Alarm/AlarmPage.cs
  71. 25 0
      NEIntelligentControl2/Models/Alarm/AlarmTypeInfo.cs
  72. 183 0
      NEIntelligentControl2/Models/Alarm/FaultInfo.cs
  73. 53 0
      NEIntelligentControl2/Models/Alarm/FaultInfoModel.cs
  74. 19 0
      NEIntelligentControl2/Models/Attributes/StringValue.cs
  75. 46 0
      NEIntelligentControl2/Models/BoostStation/BoostStationEventEditer.cs
  76. 44 0
      NEIntelligentControl2/Models/BoostStation/BoostStationInfo.cs
  77. 48 0
      NEIntelligentControl2/Models/BoostStation/BoostStationPointInfo.cs
  78. 57 0
      NEIntelligentControl2/Models/BoostStation/IBoostStationPoint.cs
  79. 37 0
      NEIntelligentControl2/Models/Datas/TsData.cs
  80. 136 0
      NEIntelligentControl2/Models/Helper.cs
  81. 24 0
      NEIntelligentControl2/Models/Matrix/IStationInfo.cs
  82. 35 0
      NEIntelligentControl2/Models/Messages/AlarmCountBridge.cs
  83. 36 0
      NEIntelligentControl2/Models/Messages/FaultCountBridge.cs
  84. 36 0
      NEIntelligentControl2/Models/Messages/FaultPopupBridge.cs
  85. 38 0
      NEIntelligentControl2/Models/Messages/PVInfoBridge.cs
  86. 267 0
      NEIntelligentControl2/Models/Messages/WEBHelper.cs
  87. 38 0
      NEIntelligentControl2/Models/Messages/WindturbineInfoBridge.cs
  88. 28 0
      NEIntelligentControl2/Models/PV/PVDetails.cs
  89. 81 0
      NEIntelligentControl2/Models/PV/PVInfo.cs
  90. 47 0
      NEIntelligentControl2/Models/PV/PVState.cs
  91. 98 0
      NEIntelligentControl2/Models/PV/PVTagInfo.cs
  92. 64 0
      NEIntelligentControl2/Models/PV/SUN2000Info.cs
  93. 48 0
      NEIntelligentControl2/Models/PageInfo.cs
  94. 21 0
      NEIntelligentControl2/Models/Pages/IPageAction.cs
  95. 19 0
      NEIntelligentControl2/Models/Pages/IPageBase.cs
  96. 19 0
      NEIntelligentControl2/Models/Pages/IPageMessage.cs
  97. 42 0
      NEIntelligentControl2/Models/Pages/PageManager.cs
  98. 28 0
      NEIntelligentControl2/Models/Pages/TagManager.cs
  99. 35 0
      NEIntelligentControl2/Models/Station/StationInfo.cs
  100. 0 0
      NEIntelligentControl2/Models/Station/StationType.cs

+ 63 - 0
.gitattributes

@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs     diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following 
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln       merge=binary
+#*.csproj    merge=binary
+#*.vbproj    merge=binary
+#*.vcxproj   merge=binary
+#*.vcproj    merge=binary
+#*.dbproj    merge=binary
+#*.fsproj    merge=binary
+#*.lsproj    merge=binary
+#*.wixproj   merge=binary
+#*.modelproj merge=binary
+#*.sqlproj   merge=binary
+#*.wwaproj   merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg   binary
+#*.png   binary
+#*.gif   binary
+
+###############################################################################
+# diff behavior for common document formats
+# 
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the 
+# entries below.
+###############################################################################
+#*.doc   diff=astextplain
+#*.DOC   diff=astextplain
+#*.docx  diff=astextplain
+#*.DOCX  diff=astextplain
+#*.dot   diff=astextplain
+#*.DOT   diff=astextplain
+#*.pdf   diff=astextplain
+#*.PDF   diff=astextplain
+#*.rtf   diff=astextplain
+#*.RTF   diff=astextplain

+ 363 - 0
.gitignore

@@ -0,0 +1,363 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# 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/
+[Oo]ut/
+[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
+*.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 LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd

+ 9 - 0
.idea/NEIntelligentControl2.iml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 6 - 0
.idea/misc.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="JavaScriptSettings">
+    <option name="languageLevel" value="ES6" />
+  </component>
+</project>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/NEIntelligentControl2.iml" filepath="$PROJECT_DIR$/.idea/NEIntelligentControl2.iml" />
+    </modules>
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

+ 31 - 0
NEIntelligentControl2.sln

@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.1.32319.34
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NEIntelligentControl2", "NEIntelligentControl2\NEIntelligentControl2.csproj", "{1F4B32B2-8B11-4739-9582-6F3D339816A6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SVGViewer", "..\GYEEFIX\SVGViewer\SVGViewer.csproj", "{921181A9-2807-43CD-8E51-F4DB4639EE4E}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{1F4B32B2-8B11-4739-9582-6F3D339816A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{1F4B32B2-8B11-4739-9582-6F3D339816A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{1F4B32B2-8B11-4739-9582-6F3D339816A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{1F4B32B2-8B11-4739-9582-6F3D339816A6}.Release|Any CPU.Build.0 = Release|Any CPU
+		{921181A9-2807-43CD-8E51-F4DB4639EE4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{921181A9-2807-43CD-8E51-F4DB4639EE4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{921181A9-2807-43CD-8E51-F4DB4639EE4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{921181A9-2807-43CD-8E51-F4DB4639EE4E}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {1B850BA6-85D6-4945-8F4D-4B216EDBAE82}
+	EndGlobalSection
+EndGlobal

+ 174 - 0
NEIntelligentControl2/AlarmInfo.json

@@ -0,0 +1,174 @@
+{
+  "rankInfo": [
+    {
+      "name": "全部",
+      "id": "all"
+    },
+    {
+      "name": "高",
+      "id": "5"
+    },
+    {
+      "name": "中高",
+      "id": "4"
+    },
+    {
+      "name": "中",
+      "id": "3"
+    },
+    {
+      "name": "中低",
+      "id": "2"
+    },
+    {
+      "name": "低",
+      "id": "1"
+    }
+  ],
+  "deviceType": [
+    {
+      "name": "全部",
+      "id": "all"
+    },
+    {
+      "name": "风机",
+      "id": "windturbine",
+      "subItem": [
+        {
+          "name": "全部",
+          "id": "all"
+        },
+        {
+          "name": "发电机",
+          "id": "fdj"
+        },
+        {
+          "name": "控制",
+          "id": "kz"
+        },
+        {
+          "name": "主轴",
+          "id": "zz"
+        },
+        {
+          "name": "叶轮",
+          "id": "yl"
+        },
+        {
+          "name": "液压",
+          "id": "yy"
+        },
+        {
+          "name": "偏航",
+          "id": "ph"
+        },
+        {
+          "name": "电网",
+          "id": "dw"
+        },
+        {
+          "name": "箱变",
+          "id": "xb"
+        },
+        {
+          "name": "变桨",
+          "id": "bj"
+        },
+        {
+          "name": "齿轮箱",
+          "id": "clx"
+        },
+        {
+          "name": "变频器",
+          "id": "bpq"
+        },
+        {
+          "name": "变流器",
+          "id": "blq"
+        },
+        {
+          "name": "机舱加热",
+          "id": "jcjr"
+        },
+        {
+          "name": "其他",
+          "id": "other"
+        }
+      ]
+    },
+    {
+      "name": "光伏",
+      "id": "GF",
+      "subItem": [
+        {
+          "name": "全部",
+          "id": "all"
+        },
+        {
+          "name": "逆变器",
+          "id": "NBQ"
+        },
+        {
+          "name": "电网",
+          "id": "DW"
+        },
+        {
+          "name": "其它",
+          "id": "other"
+        }
+      ]
+    },
+    {
+      "name": "升压站",
+      "id": "SYZ",
+      "subItem": [
+        {
+          "name": "全部",
+          "id": "all"
+        },
+        {
+          "name": "事故报警",
+          "id": "SYZSG"
+        },
+        {
+          "name": "开关",
+          "id": "SYZKG"
+        },
+        {
+          "name": "普通报警",
+          "id": "SYZBJ"
+        }
+      ]
+    },
+    {
+      "name": "自定义",
+      "id": "custom",
+      "subItem": [
+        {
+          "name": "全部",
+          "id": "all"
+        },
+        {
+          "name": "风机",
+          "id": "1"
+        },
+        {
+          "name": "风场",
+          "id": "2"
+        },
+        {
+          "name": "工程",
+          "id": "3"
+        },
+        {
+          "name": "线路",
+          "id": "4"
+        },
+        {
+          "name": "电气",
+          "id": "5"
+        }
+      ]
+    }
+  ]
+}

File diff suppressed because it is too large
+ 94 - 0
NEIntelligentControl2/App.config


+ 216 - 0
NEIntelligentControl2/App.xaml

@@ -0,0 +1,216 @@
+<Application x:Class="NEIntelligentControl2.App"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:local="clr-namespace:NEIntelligentControl2"
+             Startup="Application_Startup" ShutdownMode="OnMainWindowClose" DispatcherUnhandledException="Application_DispatcherUnhandledException">
+    <Application.Resources>
+
+        <SolidColorBrush x:Key="ScrollBarDisabledBackground" Color="#7FF4F4F4"/>
+
+        <!--滚动条-->
+        <ControlTemplate x:Key="ScrollViewerTemplate" TargetType="{x:Type ScrollViewer}">
+            <Grid x:Name="Grid" Background="{TemplateBinding Background}">
+                <Grid.ColumnDefinitions>
+                    <ColumnDefinition Width="*"/>
+                    <ColumnDefinition Width="Auto"/>
+                </Grid.ColumnDefinitions>
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="*"/>
+                    <RowDefinition Height="Auto"/>
+                </Grid.RowDefinitions>
+                <Rectangle x:Name="Corner" Grid.Column="1" Fill="White" Grid.Row="1"/>
+                <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="0" Margin="{TemplateBinding Padding}" Grid.Row="0"/>
+                <ScrollBar x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}" Style="{DynamicResource ScrollBarStyle}"/>
+                <ScrollBar x:Name="PART_HorizontalScrollBar" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="0" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"  Style="{DynamicResource ScrollBarStyle}"/>
+            </Grid>
+        </ControlTemplate>
+
+
+        <!--滚动条颜色、圆角等设置-->
+        <Style x:Key="ScrollBarThumb" TargetType="{x:Type Thumb}">
+            <Setter Property="OverridesDefaultStyle" Value="true"/>
+            <Setter Property="IsTabStop" Value="false"/>
+            <Setter Property="Template">
+                <Setter.Value>
+                    <ControlTemplate TargetType="{x:Type Thumb}">
+                        <!--滚动条颜色和圆角设置-->
+                        <Rectangle Name="thumbRect" Fill="#CC6495ED" RadiusX="3" RadiusY="3"/>
+                        <!--鼠标拉动滚动条时的颜色-->
+                        <ControlTemplate.Triggers>
+                            <Trigger Property="IsMouseOver" Value="True">
+                                <Setter Property="Fill" Value="CornflowerBlue" TargetName="thumbRect" />
+                            </Trigger>
+                        </ControlTemplate.Triggers>
+                    </ControlTemplate>
+                </Setter.Value>
+            </Setter>
+        </Style>
+        
+        <Style x:Key="HorizontalScrollBarPageButton" TargetType="{x:Type RepeatButton}">
+            <Setter Property="OverridesDefaultStyle" Value="true"/>
+            <Setter Property="Background" Value="Transparent"/>
+            <Setter Property="Focusable" Value="false"/>
+            <Setter Property="IsTabStop" Value="false"/>
+            <Setter Property="Template">
+                <Setter.Value>
+                    <ControlTemplate TargetType="{x:Type RepeatButton}">
+                        <Rectangle Fill="{TemplateBinding Background}" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}"/>
+                    </ControlTemplate>
+                </Setter.Value>
+            </Setter>
+        </Style>
+
+        <Style x:Key="VerticalScrollBarPageButton" TargetType="{x:Type RepeatButton}">
+            <Setter Property="OverridesDefaultStyle" Value="true"/>
+            <Setter Property="Background" Value="Transparent"/>
+            <Setter Property="Focusable" Value="false"/>
+            <Setter Property="IsTabStop" Value="false"/>
+            <Setter Property="Template">
+                <Setter.Value>
+                    <ControlTemplate TargetType="{x:Type RepeatButton}">
+                        <Rectangle Fill="{TemplateBinding Background}" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}"/>
+                    </ControlTemplate>
+                </Setter.Value>
+            </Setter>
+        </Style>
+        
+        <Style x:Key="ScrollBarStyle" TargetType="{x:Type ScrollBar}">
+            <Setter Property="Background" Value="#77F0F8FF"/>
+            <Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/>
+            <Setter Property="Stylus.IsFlicksEnabled" Value="false"/>
+            <!--滚动条宽度-->
+            <Setter Property="Width" Value="8"/>
+            <Setter Property="MinWidth" Value="6"/>
+            <Setter Property="Template">
+                <Setter.Value>
+                    <ControlTemplate TargetType="{x:Type ScrollBar}">
+                        <!--滚动条背景色-->
+                        <Grid x:Name="Bg" Background="#77DDDDDD" SnapsToDevicePixels="true" Width="8">
+                            <Grid.RowDefinitions>
+                                <RowDefinition />
+                            </Grid.RowDefinitions>
+                            <Track x:Name="PART_Track" IsDirectionReversed="true" IsEnabled="{TemplateBinding IsMouseOver}">
+                                <Track.DecreaseRepeatButton>
+                                    <RepeatButton Command="{x:Static ScrollBar.PageUpCommand}" Style="{StaticResource VerticalScrollBarPageButton}"/>
+                                </Track.DecreaseRepeatButton>
+                                <Track.IncreaseRepeatButton>
+                                    <RepeatButton Command="{x:Static ScrollBar.PageDownCommand}" Style="{StaticResource VerticalScrollBarPageButton}"/>
+                                </Track.IncreaseRepeatButton>
+                                <Track.Thumb>
+                                    <Thumb Style="{StaticResource ScrollBarThumb}"/>
+                                </Track.Thumb>
+                            </Track>
+                        </Grid>
+                        <ControlTemplate.Triggers>
+                            <Trigger Property="IsEnabled" Value="false">
+                                <Setter Property="Background" TargetName="Bg" Value="{StaticResource ScrollBarDisabledBackground}"/>
+                            </Trigger>
+                        </ControlTemplate.Triggers>
+                    </ControlTemplate>
+                </Setter.Value>
+            </Setter>
+            <Style.Triggers>
+                <Trigger Property="Orientation" Value="Horizontal">
+                    <Setter Property="Width" Value="Auto"/>
+                    <Setter Property="MinWidth" Value="0"/>
+                    <Setter Property="Height" Value="6"/>
+                    <Setter Property="MinHeight" Value="6"/>
+                    <Setter Property="Background" Value="#77F0F8FF"/>
+                    <Setter Property="Template">
+                        <Setter.Value>
+                            <ControlTemplate TargetType="{x:Type ScrollBar}">
+                                <Grid x:Name="Bg" Background="Red" SnapsToDevicePixels="true">
+                                    <Grid.ColumnDefinitions>
+                                        <ColumnDefinition />
+                                    </Grid.ColumnDefinitions>
+                                    <Track x:Name="PART_Track"  IsEnabled="{TemplateBinding IsMouseOver}">
+                                        <Track.DecreaseRepeatButton>
+                                            <RepeatButton Command="{x:Static ScrollBar.PageLeftCommand}" Style="{StaticResource HorizontalScrollBarPageButton}"/>
+                                        </Track.DecreaseRepeatButton>
+                                        <Track.IncreaseRepeatButton>
+                                            <RepeatButton Command="{x:Static ScrollBar.PageRightCommand}" Style="{StaticResource HorizontalScrollBarPageButton}"/>
+                                        </Track.IncreaseRepeatButton>
+                                        <Track.Thumb>
+                                            <Thumb Style="{StaticResource ScrollBarThumb}" />
+                                        </Track.Thumb>
+                                    </Track>
+                                </Grid>
+                                <ControlTemplate.Triggers>
+                                    <Trigger Property="IsEnabled" Value="false">
+                                        <Setter Property="Background" TargetName="Bg" Value="{StaticResource ScrollBarDisabledBackground}"/>
+                                    </Trigger>
+                                </ControlTemplate.Triggers>
+                            </ControlTemplate>
+                        </Setter.Value>
+                    </Setter>
+                </Trigger>
+            </Style.Triggers>
+        </Style>
+
+        <!--升压站背景颜色-->
+        <SolidColorBrush x:Key="BoostStationBackground" Color="#FF0B2F6A"/>
+        <!--升压站控件颜色-->
+        <SolidColorBrush x:Key="BoostStationUndefined" Color="DarkGray"/>
+        <SolidColorBrush x:Key="BoostStationOn" Color="#FFFF0005"/>
+        <SolidColorBrush x:Key="BoostStationOff" Color="#FF1B9D3A"/>
+
+
+        <!--按钮默认-->
+        <Style x:Key="CancelButtonStyle" TargetType="{x:Type Button}">
+            <Setter Property="Background" Value="#FFFE8864"/>
+            <Setter Property="Foreground" Value="WhiteSmoke"/>
+            <Setter Property="HorizontalContentAlignment" Value="Center"/>
+            <Setter Property="VerticalContentAlignment" Value="Center"/>
+            <Setter Property="Padding" Value="17,6"/>
+            <Setter Property="FontSize" Value="14"/>
+            <Setter Property="BorderThickness" Value="0"/>
+            <Setter Property="Margin" Value="20,0"/>
+            <Setter Property="Template">
+                <Setter.Value>
+                    <ControlTemplate TargetType="{x:Type Button}">
+                        <Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true" CornerRadius="3">
+                            <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
+                        </Border>
+                        <ControlTemplate.Triggers>
+                            <Trigger Property="IsMouseOver" Value="true">
+                                <Setter Property="Background" TargetName="border" Value="#FFFE9777"/>
+                            </Trigger>
+                            <Trigger Property="IsPressed" Value="true">
+                                <Setter Property="Background" TargetName="border" Value="#FFFE8864"/>
+                            </Trigger>
+                        </ControlTemplate.Triggers>
+                    </ControlTemplate>
+                </Setter.Value>
+            </Setter>
+        </Style>
+
+        <Style x:Key="ConfirmButtonStyle" TargetType="{x:Type Button}">
+            <Setter Property="Background" Value="#FF006ACC"/>
+            <Setter Property="Foreground" Value="WhiteSmoke"/>
+            <Setter Property="HorizontalContentAlignment" Value="Center"/>
+            <Setter Property="VerticalContentAlignment" Value="Center"/>
+            <Setter Property="Padding" Value="17,6"/>
+            <Setter Property="FontSize" Value="14"/>
+            <Setter Property="BorderThickness" Value="0"/>
+            <Setter Property="Margin" Value="20,0"/>
+            <Setter Property="Template">
+                <Setter.Value>
+                    <ControlTemplate TargetType="{x:Type Button}">
+                        <Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true" CornerRadius="3">
+                            <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
+                        </Border>
+                        <ControlTemplate.Triggers>
+                            <Trigger Property="IsMouseOver" Value="true">
+                                <Setter Property="Background" TargetName="border" Value="#FF2E81CC"/>
+                            </Trigger>
+                            <Trigger Property="IsPressed" Value="true">
+                                <Setter Property="Background" TargetName="border" Value="#FF006ACC"/>
+                            </Trigger>
+                        </ControlTemplate.Triggers>
+                    </ControlTemplate>
+                </Setter.Value>
+            </Setter>
+        </Style>
+        <!--按钮默认结束-->
+    </Application.Resources>
+</Application>

+ 108 - 0
NEIntelligentControl2/App.xaml.cs

@@ -0,0 +1,108 @@
+using log4net;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace NEIntelligentControl2
+{
+    /// <summary>
+    /// 新能源智能发电集中控制系统
+    /// </summary>
+    public partial class App : Application
+    {
+        /// <summary>
+        /// 依赖注入
+        /// </summary>
+        public static IServiceProvider ServiceProvider { get; set; }
+
+        private ILog log = LogManager.GetLogger("File");
+        private void Application_Startup(object sender, StartupEventArgs e)
+        {
+            var serviceCollection = new ServiceCollection();
+            ConfigureServices(serviceCollection);
+            ServiceProvider = serviceCollection.BuildServiceProvider();
+
+            var mainWindow = ServiceProvider.GetRequiredService<MainWindow>();
+            mainWindow.Show();
+        }
+
+        private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
+        {
+            try
+            {
+                e.Handled = true;
+                log.Error("应用程序出现重大错误,但可继续运行!", e.Exception);
+            }
+            catch (Exception ex)
+            {
+                log.Fatal("应用程序出现致命错误,已经结束运行!", e.Exception);
+            }
+        }
+
+        /// <summary>
+        /// 获取服务
+        /// </summary>
+        /// <typeparam name="T">类型</typeparam>
+        /// <returns>服务</returns>
+        public static T GetService<T>()
+        {
+            return (T)ServiceProvider.GetService(typeof(T));
+        }
+
+        /// <summary>
+        /// 依赖注入
+        /// </summary>
+        private void ConfigureServices(IServiceCollection services)
+        {
+            services.AddSingleton<Models.Pages.IPageAction, Models.Pages.PageManager>()
+                .AddSingleton<Service.WebSocket.MessageBridge>()
+                .AddSingleton<Models.Messages.WEBHelper>()
+                .AddSingleton<Service.Windturbine.CacheManager>()
+                .AddSingleton<Service.WebSocket.UrlManager>()
+                .AddSingleton<Service.User.UserManager>()
+                .AddSingleton<Service.Voice.VoiceManager>()
+                .AddSingleton<Service.AGC.AGCManager>()
+                .AddSingleton<Service.Alarm.AlarmManager>()
+                .AddSingleton<Service.Windturbine.InfoManager>()
+                .AddSingleton<Service.Windturbine.SuggestionManager>()
+                .AddSingleton<Service.Windturbine.ControlManager>()
+                .AddSingleton<Models.Pages.TagManager>()
+                .AddSingleton<Service.Station.StationManager>()
+                .AddSingleton<MainWindow>()
+                .AddTransient<Windows.ConfirmWindow>()
+                .AddTransient<Windows.WindturbineInfoWindow>()
+                .AddTransient<Windows.UserWindow>()
+                .AddTransient< Pages.User.PageLogin>()
+                .AddTransient< Pages.User.PageUserEdit>()
+                .AddSingleton<Pages.Matrix.PageMatrix>()
+                .AddTransient<Pages.AGC.PageAGC>()
+                .AddSingleton<Pages.Help.PageHelp>()
+                .AddSingleton<Pages.BoostStation.PageBoostStation>()
+                .AddSingleton<Pages.BoostStation.PageBoostStation2>()
+                .AddTransient<Pages.BoostStation.PageStation>()
+                .AddTransient<Pages.BoostStation.PageStation2>()
+                .AddSingleton<Pages.Home.HomePage>()
+                .AddSingleton<Pages.Home.StateTimePage>()
+                .AddSingleton<Pages.Alarm.PageAlarmCenter>()
+                .AddTransient<Pages.Matrix.PageMatrixAll>()
+                .AddTransient<Pages.Home.PageWindturbineAGC>()
+                .AddTransient<Pages.Matrix.PageMatrixStation>()
+                .AddTransient<Windows.ParameterComparisonWindow>()
+                .AddTransient<Windows.Alarm.DeviceDetailAlarmWindow>()
+                .AddTransient<Windows.Alarm.HistoryAlarmWindow>()
+                .AddTransient<Windows.Alarm.HistoryFaultWindow>()
+                .AddTransient<Windows.Alarm.RealTimeAlarmWindow>()
+                .AddTransient<Windows.ControlTrackWindow>()
+                .AddTransient<Windows.RecomendWindow>()
+                .AddTransient<Windows.HistoryDataWindow>()
+                .AddTransient<Windows.PV.InverterInfoWindow>()
+                .AddTransient<Windows.PV.SUN2000InfoWindow>();
+        }
+    }
+}

+ 231 - 0
NEIntelligentControl2/ComparisonInfo.json

@@ -0,0 +1,231 @@
+{
+    "MHS_FDC":{
+        "UP77":[
+            {"name":"风速","code":"AI007"},
+            {"name":"叶轮转速","code":"AI012"},
+            {"name":"转子位置与转子速度","code":"AI017"},
+            {"name":"主系统液压","code":"AI018"},
+            {"name":"转子刹车系统液压","code":"AI019"},
+            {"name":"偏航位置","code":"AI034"},
+            {"name":"对风偏差","code":"AI036"},
+            {"name":"齿轮箱输入轴1温度","code":"AI038"},
+            {"name":"齿轮箱输出轴2温度","code":"AI039"},
+            {"name":"齿轮箱入口油温","code":"AI301"},
+            {"name":"齿轮箱油温","code":"AI041"},
+            {"name":"发电机定子绕组温度U1","code":"AI045"},
+            {"name":"发电机定子绕组温度V1","code":"AI047"},
+            {"name":"发电机定子绕组温度W1","code":"AI049"},
+            {"name":"发电机轴承A温度","code":"AI052"},
+            {"name":"发电机轴承B温度","code":"AI053"},
+            {"name":"塔底柜温度","code":"AI069"},
+            {"name":"主轴叶轮侧温度","code":"AI071"},
+            {"name":"主轴齿轮箱侧温度","code":"AI072"},
+            {"name":"叶片1位置","code":"AI085"},
+            {"name":"叶片2位置","code":"AI086"},
+            {"name":"叶片3位置","code":"AI087"},
+            {"name":"发电机转速","code":"AI128"},
+            {"name":"有功功率","code":"AI130"},
+            {"name":"无功功率","code":"AI131"}
+        ],
+        "UP105-2000-S":[
+            {"name":"风速","code":"AI022"},
+            {"name":"叶轮转速","code":"AI012"},
+            {"name":"齿轮箱入口油温","code":"AI160"},
+            {"name":"齿轮箱输入轴温度","code":"AI038"},
+            {"name":"齿轮箱油槽温度","code":"AI041"},
+            {"name":"齿轮箱输出轴温度","code":"AI039"},
+            {"name":"发电机定子绕组温度U1","code":"AI045"},
+            {"name":"发电机定子绕组温度V1","code":"AI047"},
+            {"name":"发电机定子绕组温度W1","code":"AI049"},
+            {"name":"发电机轴承A温度","code":"AI052"},
+            {"name":"发电机轴承B温度","code":"AI053"},
+            {"name":"塔底柜温度","code":"AI069A"},
+            {"name":"无功功率","code":"AI131"},
+            {"name":"有功功率","code":"AI130"}
+        ]
+    },
+    "NSS_FDC":{
+        "UP82":[
+            {"name":"风速","code":"AI007"},
+            {"name":"叶轮转速","code":"AI012"},
+            {"name":"转子位置与转子速度","code":"AI017"},
+            {"name":"液压系统压力","code":"AI613"},
+            {"name":"转子刹车压力","code":"AI019"},
+            {"name":"液压油温度","code":"AI020"},
+            {"name":"偏航位置","code":"AI034"},
+            {"name":"偏航速度","code":"AI035"},
+            {"name":"齿轮箱输入轴1温度","code":"AI038"},
+            {"name":"齿轮箱输出轴2温度","code":"AI039"},
+            {"name":"齿轮箱入口油温","code":"AI040"},
+            {"name":"齿轮箱油温","code":"AI041"},
+            {"name":"齿轮箱冷却水温度","code":"AI042"},
+            {"name":"发电机U1绕组温度","code":"AI045"},
+            {"name":"发电机U2绕组温度","code":"AI046"},
+            {"name":"发电机V1绕组温度","code":"AI047"},
+            {"name":"发电机V2绕组温度","code":"AI048"},
+            {"name":"发电机W1绕组温度","code":"AI049"},
+            {"name":"发电机W2绕组温度","code":"AI050"},
+            {"name":"发电机轴承a温度","code":"AI052"},
+            {"name":"发电机轴承b温度","code":"AI053"},
+            {"name":"机舱温度","code":"AI057"},
+            {"name":"电网功率","code":"AI065"},
+            {"name":"电网无功功率","code":"AI066"},
+            {"name":"塔底柜温度","code":"AI069"},
+            {"name":"塔顶柜温度","code":"AI070"},
+            {"name":"主轴叶轮侧温度","code":"AI071"},
+            {"name":"主轴齿轮箱侧温度","code":"AI072"},
+            {"name":"叶片1位置","code":"AI085"},
+            {"name":"叶片2位置","code":"AI086"},
+            {"name":"叶片3位置","code":"AI087"},
+            {"name":"发电机转速","code":"AI128"},
+            {"name":"有功功率","code":"AI130"},
+            {"name":"无功功率","code":"AI131"}
+        ]
+    },
+    "SBQ_FDC":{
+        "UP82_2":[
+            {"name":"风速","code":"AI007"},
+            {"name":"叶轮转速","code":"AI012"},
+            {"name":"转子位置与转子速度","code":"AI017"},
+            {"name":"主系统液压","code":"AI018"},
+            {"name":"转子刹车系统液压","code":"AI019"},
+            {"name":"偏航位置","code":"AI034"},
+            {"name":"对风偏差","code":"AI036"},
+            {"name":"齿轮箱输入轴1温度","code":"AI038"},
+            {"name":"齿轮箱输出轴2温度","code":"AI039"},
+            {"name":"齿轮箱入口油温","code":"AI040"},
+            {"name":"齿轮箱油温","code":"AI041"},
+            {"name":"发电机定子绕组温度U1","code":"AI045"},
+            {"name":"发电机定子绕组温度V1","code":"AI047"},
+            {"name":"发电机定子绕组温度W1","code":"AI049"},
+            {"name":"发电机轴承A温度","code":"AI052"},
+            {"name":"发电机轴承B温度","code":"AI053"},
+            {"name":"塔底柜温度","code":"AI069"},
+            {"name":"主轴叶轮侧温度","code":"AI071"},
+            {"name":"主轴齿轮箱侧温度","code":"AI072"},
+            {"name":"叶片1位置","code":"AI085"},
+            {"name":"叶片2位置","code":"AI086"},
+            {"name":"叶片3位置","code":"AI087"},
+            {"name":"发电机转速","code":"AI128"},
+            {"name":"有功功率","code":"AI130"},
+            {"name":"无功功率","code":"AI066"}
+        ],
+        "UP97":[
+            {"name":"风速","code":"AI007"},
+            {"name":"叶轮转速","code":"AI012"},
+            {"name":"转子位置与转子速度","code":"AI017"},
+            {"name":"主系统液压","code":"AI018"},
+            {"name":"转子刹车系统液压","code":"AI019"},
+            {"name":"偏航位置","code":"AI034"},
+            {"name":"对风偏差","code":"AI036"},
+            {"name":"齿轮箱输入轴1温度","code":"AI038"},
+            {"name":"齿轮箱输出轴2温度","code":"AI039"},
+            {"name":"齿轮箱入口油温","code":"AI040"},
+            {"name":"齿轮箱油温","code":"AI041"},
+            {"name":"发电机定子绕组温度U1","code":"AI045"},
+            {"name":"发电机定子绕组温度V1","code":"AI047"},
+            {"name":"发电机定子绕组温度W1","code":"AI049"},
+            {"name":"发电机轴承A温度","code":"AI052"},
+            {"name":"发电机轴承B温度","code":"AI053"},
+            {"name":"塔底柜温度","code":"AI069"},
+            {"name":"主轴叶轮侧温度","code":"AI071"},
+            {"name":"主轴齿轮箱侧温度","code":"AI072"},
+            {"name":"叶片1位置","code":"AI085"},
+            {"name":"叶片2位置","code":"AI086"},
+            {"name":"叶片3位置","code":"AI087"},
+            {"name":"发电机转速","code":"AI128"},
+            {"name":"有功功率","code":"AI130"},
+            {"name":"有功功率限值","code":"AI426"},
+            {"name":"无功功率","code":"AI131"}
+        ],
+        "UP105-2000-S":[
+            {"name":"风速","code":"AI022"},
+            {"name":"叶轮转速","code":"AI012"},
+            {"name":"齿轮箱输入轴温度","code":"AI038"},
+            {"name":"齿轮箱输出轴温度","code":"AI039"},
+            {"name":"齿轮箱入口油温","code":"AI160"},
+            {"name":"齿轮箱油槽温度","code":"AI041"},
+            {"name":"发电机定子绕组温度U1","code":"AI045"},
+            {"name":"发电机定子绕组温度V1","code":"AI047"},
+            {"name":"发电机定子绕组温度W1","code":"AI049"},
+            {"name":"发电机轴承A温度","code":"AI052"},
+            {"name":"发电机轴承B温度","code":"AI053"},
+            {"name":"塔底柜温度","code":"AI069A"},
+            {"name":"发电机转速","code":"AI128"},
+            {"name":"有功功率","code":"AI130"},
+            {"name":"无功功率","code":"AI131"},
+            {"name":"偏航位置","code":"AI034"}
+        ]
+    },
+    "QS_FDC":{
+        "UP105-2000-S":[
+            {"name":"风速","code":"AI022"},
+            {"name":"叶轮转速","code":"AI012"},
+            {"name":"齿轮箱输入轴温度","code":"AI038"},
+            {"name":"齿轮箱输出轴温度","code":"AI039"},
+            {"name":"齿轮箱入口油温","code":"AI160"},
+            {"name":"齿轮箱油槽温度","code":"AI041"},
+            {"name":"发电机定子绕组温度U1","code":"AI045"},
+            {"name":"发电机定子绕组温度V1","code":"AI047"},
+            {"name":"发电机定子绕组温度W1","code":"AI049"},
+            {"name":"发电机轴承A温度","code":"AI052"},
+            {"name":"发电机轴承B温度","code":"AI053"},
+            {"name":"塔底柜温度","code":"AI069A"},
+            {"name":"发电机转速","code":"AI128"},
+            {"name":"有功功率","code":"AI130"},
+            {"name":"偏航位置","code":"AI034"}
+        ]
+    },
+    "XS_FDC":{
+        "UP97":[
+            {"name":"风速","code":"AI007"},
+            {"name":"叶轮转速","code":"AI012"},
+            {"name":"转子位置与转子速度","code":"AI017"},
+            {"name":"主系统液压","code":"AI018"},
+            {"name":"转子刹车系统液压","code":"AI019"},
+            {"name":"偏航位置","code":"AI034"},
+            {"name":"对风偏差","code":"AI036"},
+            {"name":"偏航速度","code":"AI035"},
+            {"name":"齿轮箱输入轴1温度","code":"AI038"},
+            {"name":"齿轮箱输出轴2温度","code":"AI039"},
+            {"name":"齿轮箱入口油温","code":"AI040"},
+            {"name":"齿轮箱油槽温度","code":"AI041"},
+            {"name":"发电机定子绕组温度U1","code":"AI045"},
+            {"name":"发电机定子绕组温度V1","code":"AI047"},
+            {"name":"发电机定子绕组温度W1","code":"AI049"},
+            {"name":"发电机轴承A温度","code":"AI052"},
+            {"name":"发电机轴承B温度","code":"AI053"},
+            {"name":"塔底柜温度","code":"AI069"},
+            {"name":"主轴叶轮侧温度","code":"AI071"},
+            {"name":"主轴齿轮箱侧温度","code":"AI072"},
+            {"name":"叶片1位置","code":"AI085"},
+            {"name":"叶片2位置","code":"AI086"},
+            {"name":"叶片3位置","code":"AI087"},
+            {"name":"发电机转速","code":"AI128"},
+            {"name":"有功功率","code":"AI130"},
+            {"name":"有功功率限值","code":"AI426"},
+            {"name":"无功功率","code":"AI131"}
+        ],
+        "UP105-2000-S":[
+            {"name":"齿轮箱入口油温","code":"AI040"},
+            {"name":"齿轮箱输入轴温度","code":"AI038"},
+            {"name":"齿轮箱油槽温度","code":"AI041"},
+            {"name":"齿轮箱输出轴温度","code":"AI039"},
+            {"name":"发电机轴承A温度","code":"AI052"},
+            {"name":"发电机轴承B温度","code":"AI053"},
+            {"name":"发电机定子绕组温度U1","code":"AI045"},
+            {"name":"发电机定子绕组温度U2","code":"AI046"},
+            {"name":"发电机定子绕组温度V1","code":"AI047"},
+            {"name":"发电机定子绕组温度V2","code":"AI048"},
+            {"name":"发电机定子绕组温度W1","code":"AI049"},
+            {"name":"发电机定子绕组温度W2","code":"AI050"},
+            {"name":"无功功率","code":"AI131"},
+            {"name":"有功功率","code":"AI130"},
+            {"name":"叶轮转速","code":"AI012"},
+            {"name":"塔底柜温度","code":"AI069"},
+            {"name":"风速","code":"AI022"},
+            {"name":"发电机转速","code":"AI128"},
+            {"name":"偏航位置","code":"AI034"}
+        ]
+    }
+}

BIN
NEIntelligentControl2/Images/AGC/agc_off.png


BIN
NEIntelligentControl2/Images/AGC/agc_on.png


BIN
NEIntelligentControl2/Images/AGC/restricted.png


BIN
NEIntelligentControl2/Images/AGC/unrestricted.png


BIN
NEIntelligentControl2/Images/BoostStation/boost_station_title.png


BIN
NEIntelligentControl2/Images/PV/close.png


BIN
NEIntelligentControl2/Images/PV/pv_arrow_pic.png


BIN
NEIntelligentControl2/Images/PV/pv_box_pic.png


BIN
NEIntelligentControl2/Images/PV/pv_box_transformer.png


BIN
NEIntelligentControl2/Images/PV/pv_elec_pic.png


BIN
NEIntelligentControl2/Images/PV/pv_nb_pic.png


BIN
NEIntelligentControl2/Images/PV/pv_pic.png


BIN
NEIntelligentControl2/Images/PV/pv_state_blue.png


BIN
NEIntelligentControl2/Images/PV/pv_state_gre.png


BIN
NEIntelligentControl2/Images/PV/pv_state_grey.png


BIN
NEIntelligentControl2/Images/PV/pv_state_org.png


BIN
NEIntelligentControl2/Images/PV/pv_state_red.png


BIN
NEIntelligentControl2/Images/PV/pv_state_un.png


BIN
NEIntelligentControl2/Images/PV/pv_state_vio.png


BIN
NEIntelligentControl2/Images/PV/zhengti.png


BIN
NEIntelligentControl2/Images/Remomend/calc_all.png


BIN
NEIntelligentControl2/Images/Remomend/calc_maintain.png


BIN
NEIntelligentControl2/Images/Remomend/calc_reset.png


BIN
NEIntelligentControl2/Images/Remomend/calc_startr.png


BIN
NEIntelligentControl2/Images/Remomend/calc_stop.png


BIN
NEIntelligentControl2/Images/Remomend/calc_unmaintian.png


BIN
NEIntelligentControl2/Images/StatusBar/agc.png


BIN
NEIntelligentControl2/Images/StatusBar/alarm.png


BIN
NEIntelligentControl2/Images/StatusBar/alarm_center.png


BIN
NEIntelligentControl2/Images/StatusBar/booster_station.png


BIN
NEIntelligentControl2/Images/StatusBar/calculation_result_playback.png


BIN
NEIntelligentControl2/Images/StatusBar/help.png


BIN
NEIntelligentControl2/Images/StatusBar/menu.png


BIN
NEIntelligentControl2/Images/StatusBar/menu_over.png


BIN
NEIntelligentControl2/Images/StatusBar/recommend.png


BIN
NEIntelligentControl2/Images/StatusBar/recommend_over.png


BIN
NEIntelligentControl2/Images/StatusBar/track.png


BIN
NEIntelligentControl2/Images/StatusBar/track_over.png


BIN
NEIntelligentControl2/Images/StatusBar/windturbine_matrix.png


BIN
NEIntelligentControl2/Images/TitleBar/background.png


BIN
NEIntelligentControl2/Images/TitleBar/item_background.png


BIN
NEIntelligentControl2/Images/TitleBar/item_background_selected.png


BIN
NEIntelligentControl2/Images/TitleBar/user_add.png


BIN
NEIntelligentControl2/Images/TitleBar/user_edit.png


BIN
NEIntelligentControl2/Images/TitleBar/user_logout.png


BIN
NEIntelligentControl2/Images/User/finger.gif


BIN
NEIntelligentControl2/Images/User/finger.png


BIN
NEIntelligentControl2/Images/Windturbine/windturbine.png


+ 26 - 0
NEIntelligentControl2/MainWindow.xaml

@@ -0,0 +1,26 @@
+<Window x:Class="NEIntelligentControl2.MainWindow"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:NEIntelligentControl2"
+        xmlns:mw="clr-namespace:NEIntelligentControl2.Views.MainWindow"
+        xmlns:am="clr-namespace:NEIntelligentControl2.Views.Alarm"
+        mc:Ignorable="d"
+        Title="新能源智能发电集中控制系统" Height="1080" Width="1920" WindowState="Maximized" WindowStyle="None">
+    <Grid>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="17*"/>
+            <RowDefinition Height="244*"/>
+            <RowDefinition Height="9*"/>
+        </Grid.RowDefinitions>
+        <Frame x:Name="_FrameMain" Grid.Row="1" Grid.Column="1" NavigationUIVisibility="Hidden"/>
+
+        <mw:TitleBar x:Name="_TBMain"/>
+
+        <mw:StatusBar x:Name="_SBMain" Grid.Row="2" ItemClick="StatusBar_ItemClick"/>
+
+
+        <am:AlarmShowView Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Bottom" Visibility="Collapsed"/>
+    </Grid>
+</Window>

+ 63 - 0
NEIntelligentControl2/MainWindow.xaml.cs

@@ -0,0 +1,63 @@
+using log4net;
+using NEIntelligentControl2.Models.Messages;
+using NEIntelligentControl2.Models.Pages;
+using NEIntelligentControl2.Models.Station;
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace NEIntelligentControl2
+{
+    /// <summary>
+    /// 主界面
+    /// </summary>
+    public partial class MainWindow : Window
+    {
+        private IPageAction _IPageAction;           // 页面动作
+        private Page _CurrentPage;                  // 当前页面
+        public MainWindow(IPageAction action)
+        {
+            InitializeComponent();
+            _IPageAction = action;
+            SwitchPage("Home.PageWindturbineAGC");
+        }
+
+        private void StatusBar_ItemClick(object sender, RoutedEventArgs e)
+        {
+            var ee = e as Views.MainWindow.MenuItemRoutedEventArgs;
+            if (ee == null) return;
+            _SBMain.IsMenuOpen = false;
+            SwitchPage(ee.Tag);
+        }
+
+        /// <summary>
+        /// 切换页面
+        /// </summary>
+        private void SwitchPage(string tag)
+        {
+            var page = _IPageAction[tag];
+            if (page == _CurrentPage) return;
+            _CurrentPage = page;
+            _FrameMain.Navigate(page);
+
+            if (!_FrameMain.NavigationService.CanGoBack) return;
+            var en = _FrameMain.NavigationService.RemoveBackEntry();
+            while (en != null)
+            {
+                en = _FrameMain.NavigationService.RemoveBackEntry();
+            }
+        }
+    }
+}

+ 32 - 0
NEIntelligentControl2/MessageWindow.xaml

@@ -0,0 +1,32 @@
+<Window x:Class="NEIntelligentControl2.MessageWindow"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:NEIntelligentControl2"
+        mc:Ignorable="d"
+        Title="MessageWindow" Height="150" Width="266.666667" WindowStartupLocation="CenterOwner" ResizeMode="NoResize">
+    
+    <Grid>
+        <Grid.RowDefinitions>
+            <RowDefinition/>
+            <RowDefinition Height="Auto"/>
+        </Grid.RowDefinitions>
+        <Grid>
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="Auto"/>
+                <ColumnDefinition/>
+            </Grid.ColumnDefinitions>
+            <Viewbox Width="35" Height="35" Margin="5">
+                <Canvas Width="1024" Height="1024">
+                    <Path Data="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 170.666667a42.666667 42.666667 0 0 0-42.666667 42.666667v341.333333a42.666667 42.666667 0 0 0 85.333334 0V298.666667a42.666667 42.666667 0 0 0-42.666667-42.666667z m0 554.666667a42.666667 42.666667 0 1 0 0-85.333334 42.666667 42.666667 0 0 0 0 85.333334z" Fill="#FAAD14"/>
+                </Canvas>
+            </Viewbox>
+            <TextBlock Grid.Column="1" Text="{Binding RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}, Path=Message}" VerticalAlignment="Center" TextWrapping="Wrap"/>
+        </Grid>
+        <StackPanel Grid.Row="1" Orientation="Horizontal" Margin="10,0,10,0" HorizontalAlignment="Right">
+            <Button Content="确 定" Margin="10" Padding="12,3" Click="Button_Click" Tag="ok" Style="{StaticResource ConfirmButtonStyle}" IsDefault="True"/>
+            <Button Content="取 消" Margin="10" Padding="12,3" Click="Button_Click" Tag="cancel" Style="{StaticResource CancelButtonStyle}" IsCancel="True"/>
+        </StackPanel>
+    </Grid>
+</Window>

+ 53 - 0
NEIntelligentControl2/MessageWindow.xaml.cs

@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace NEIntelligentControl2
+{
+    /// <summary>
+    /// 提示窗口
+    /// </summary>
+    public partial class MessageWindow : Window
+    {
+        public string Message { get; set; }
+        public MessageWindow()
+        {
+            InitializeComponent();
+        }
+
+        private void Button_Click(object sender, RoutedEventArgs e)
+        {
+            switch (((Control)sender).Tag)
+            {
+                case "cancel":  // 取消
+                    DialogResult = false;
+                    break;
+                case "ok":      // 确认
+                    DialogResult = true;
+                    break;
+                default: return;
+            }
+        }
+
+        /// <summary>
+        /// 显示提示窗口
+        /// </summary>
+        public static bool ShowMessage(string message, string title = "提示")
+        {
+            MessageWindow mw = new MessageWindow() { Message = message, Title = title };
+            mw.Owner = Application.Current.MainWindow;
+            var v = mw.ShowDialog();
+            return v == true;
+        }
+    }
+}

+ 63 - 0
NEIntelligentControl2/Models/AGC/AGCInfo.cs

@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.AGC
+{
+    /// <summary>
+    /// AGC信息
+    /// </summary>
+    public class AGCInfo
+    {
+        /// <summary>
+        /// 升压站ID
+        /// </summary>
+        public string Id { get; set; }
+        /// <summary>
+        /// 坐标
+        /// </summary>
+        public Point Coordinate { get; set; }
+        /// <summary>
+        /// 装机容量
+        /// </summary>
+        public double InstalledCapacity { get; set; }
+        /// <summary>
+        /// 标题
+        /// </summary>
+        public string Title { get; set; }
+        /// <summary>
+        /// 小标题
+        /// </summary>
+        public string SmallTitle { get; set; }
+        /// <summary>
+        /// 状态(是否限电)
+        /// </summary>
+        public TagInfo Status { get; set; }
+        /// <summary>
+        /// AI点
+        /// </summary>
+        public List<TagInfo> AiPoints { get; set; }
+
+        /// <summary>
+        /// DI点
+        /// </summary>
+        public List<TagInfo> DiPoints { get; set; }
+    }
+
+    /// <summary>
+    /// 坐标点
+    /// </summary>
+    public class Point
+    {
+        /// <summary>
+        /// X
+        /// </summary>
+        public int X { get; set; }
+        /// <summary>
+        /// Y
+        /// </summary>
+        public int Y { get; set; }
+    }
+}

+ 82 - 0
NEIntelligentControl2/Models/AGC/TagInfo.cs

@@ -0,0 +1,82 @@
+using NEIntelligentControl2.Models.Datas;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.AGC
+{
+    /// <summary>
+    /// AGC数据标签
+    /// </summary>
+    public class TagInfo
+    {
+        /// <summary>
+        /// 名称
+        /// </summary>
+        public string Name { get; set; }
+        private string tag;
+        /// <summary>
+        /// 标签
+        /// </summary>
+        public string Tag { get => tag; set { tag = value; Tags = tag?.Split(','); } }
+        /// <summary>
+        /// 倍率
+        /// </summary>
+        public float Multiplier { get; set; } = 1;
+        /// <summary>
+        /// 单位
+        /// </summary>
+        public string Unit { get; set; }
+        /// <summary>
+        /// 类型
+        /// </summary>
+        public TagType Type { get; set; }
+        /// <summary>
+        /// 标签们
+        /// </summary>
+        public string[] Tags { get; set; }
+        /// <summary>
+        /// 时间戳
+        /// </summary>
+        public long Ts { get; set; }
+
+        /// <summary>
+        /// 值改变
+        /// </summary>
+        public Action<double> ValueChanged { get; internal set; }
+        /// <summary>
+        /// 值
+        /// </summary>
+        private double value;
+        public double Value { get { return value; } set { this.value = value * Multiplier; ValueChanged?.Invoke(this.value); } }
+        /// <summary>
+        /// 数据历史值改变
+        /// </summary>
+        public Action<TagInfo, List<TsData>> HistoryValueChanged { get; set; }
+        /// <summary>
+        /// 更新数据
+        /// </summary>
+        internal void UpdateData(Dictionary<string, TsData> vs)
+        {
+            if (vs == null || this.Tags == null) return;
+            double d = 0;
+            foreach (var v in this.Tags)
+            {
+                if (!vs.ContainsKey(v)) continue;
+                var td = vs[v];
+                d += td.Value;
+                Ts = td.Ts;
+            }
+            this.Value = d;
+        }
+        /// <summary>
+        /// 更新历史数据
+        /// </summary>
+        internal void UpdateHistoryData(List<TsData> dts)
+        {
+            HistoryValueChanged?.Invoke(this, dts);
+        }
+    }
+}

+ 28 - 0
NEIntelligentControl2/Models/AGC/TagType.cs

@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.AGC
+{
+
+    /// <summary>
+    /// AGC数据标签类型
+    /// </summary>
+    public enum TagType
+    {
+        /// <summary>
+        /// 其他
+        /// </summary>
+        Other,
+        /// <summary>
+        /// 有功设定
+        /// </summary>
+        PowerSet,
+        /// <summary>
+        /// 实发有功
+        /// </summary>
+        ActualPower
+    }
+}

+ 135 - 0
NEIntelligentControl2/Models/AGC/ViewModel.cs

@@ -0,0 +1,135 @@
+using NEIntelligentControl2.Models.Datas;
+using OxyPlot;
+using OxyPlot.Axes;
+using OxyPlot.Series;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.AGC
+{
+    /// <summary>
+    /// AGC曲线模型
+    /// </summary>
+    public class ViewModel : PlotModel
+    {
+        private List<TsData> _ActPower; // 实发有功数据
+        public List<TsData> ActPower { get => _ActPower; }
+        private List<TsData> _PowerSet;// 有功设定数据
+        public List<TsData> PowerSet { get => _PowerSet; }
+
+
+        private LineSeries ls1;
+        private LineSeries ls2;
+
+        public DateTimeAxis AxisX;
+
+        public ViewModel()
+        {
+            this.PlotAreaBorderThickness = new OxyThickness(0);
+            this.Legends.Add(new OxyPlot.Legends.Legend()
+            {
+                Key = "power",
+                LegendPosition = OxyPlot.Legends.LegendPosition.BottomCenter,
+                LegendPlacement = OxyPlot.Legends.LegendPlacement.Outside,
+                LegendOrientation = OxyPlot.Legends.LegendOrientation.Horizontal,
+                LegendTextColor = OxyColor.Parse("#FF000000"),
+                //LegendFontSize = 10
+            });
+
+            var dta2 = new LinearAxis() { Position = AxisPosition.Left };
+            dta2.MinorTicklineColor = OxyColors.Transparent;
+            dta2.AxislineColor = OxyColors.Transparent;
+            dta2.TickStyle = TickStyle.None;
+            //dta2.MajorStep = 20;
+            dta2.IntervalLength = 20;
+            dta2.IsZoomEnabled = false;
+            dta2.IsPanEnabled = false;
+            dta2.TextColor = OxyColor.Parse("#FF000000");
+            this.Axes.Add(dta2);
+
+            AxisX = new DateTimeAxis { Position = AxisPosition.Bottom, StringFormat = "HH:mm" };
+            AxisX.MinorTicklineColor = OxyColors.Transparent;
+            AxisX.TickStyle = TickStyle.None;
+            AxisX.IsZoomEnabled = false;
+            AxisX.IsPanEnabled = false;
+            //_AxisX.IntervalLength = 45;
+            AxisX.TextColor = OxyColor.Parse("#FF000000");
+
+            this.Axes.Add(AxisX);
+
+
+            ls1 = new LineSeries() { Title = "实发有功", Color = OxyColor.Parse("#FFF4A460"), StrokeThickness = 1.5 };
+            ls1.LegendKey = "power";
+            ls2 = new LineSeries() { Title = "有功设定", Color = OxyColor.Parse("#FF31B9FB"), StrokeThickness = 1.5 };
+            ls2.LegendKey = "power";
+            Series.Add(ls1);
+            Series.Add(ls2);
+        }
+
+        /// <summary>
+        /// AGC曲线模型
+        /// </summary>
+        /// <param name="ap">实发有功</param>
+        /// <param name="ps">有功设定</param>
+        public ViewModel(List<TsData> ap, List<TsData> ps) : this()
+        {
+            _PowerSet = ps;
+            AddData(ls2, ps);
+            _ActPower = ap;
+            AddData(ls1, ap);
+        }
+
+        internal void SetValueNow(TagInfo arg1, List<TsData> arg2)
+        {
+            if (arg2 == null || arg2.Count < 2) return;
+            if (arg1.Type == TagType.PowerSet)
+            {
+                _PowerSet = arg2;
+                AddData(ls2, arg2);
+            }
+            else
+            {
+                _ActPower = arg2;
+                AddData(ls1, arg2);
+            }
+            var dt = DateTime.Now;
+
+            AxisX.AbsoluteMinimum = DateTimeAxis.ToDouble(dt.AddHours(-8));
+            AxisX.AbsoluteMaximum = DateTimeAxis.ToDouble(dt);
+        }
+
+        internal void SetValue(TagInfo arg1, List<TsData> arg2)
+        {
+            if (arg2 == null || arg2.Count < 2) return;
+            if (arg1.Type == TagType.PowerSet)
+            {
+                _PowerSet = arg2;
+                AddData(ls2, arg2);
+            }
+            else
+            {
+                _ActPower = arg2;
+                AddData(ls1, arg2);
+            }
+            var dts = arg2[0].Ts.GetLongDateTime();
+            var dte = arg2[arg2.Count - 1].Ts.GetLongDateTime();
+
+            AxisX.AbsoluteMinimum = DateTimeAxis.ToDouble(dts);
+            AxisX.AbsoluteMaximum = DateTimeAxis.ToDouble(dte);
+        }
+
+        private void AddData(LineSeries ls, List<TsData> vs)
+        {
+            ls.Points.Clear();
+            if (vs == null) return;
+            foreach(var v in vs)
+            {
+                DataPoint dp = new DataPoint(DateTimeAxis.ToDouble(v.Ts.GetLongDateTime()), Math.Round(v.Value, 2));
+                ls.Points.Add(dp);
+            }
+        }
+    }
+}

+ 89 - 0
NEIntelligentControl2/Models/Alarm/AlarmInfo.cs

@@ -0,0 +1,89 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.Alarm
+{
+    /// <summary>
+    /// 报警信息
+    /// </summary>
+    public class AlarmInfo
+    {
+        public long Id { get; set; }
+        public DateTime? AlertTime { get; set; }
+        public int MessageType { get; set; }
+        public long SnapId { get; set; }
+        public string StationId { get; set; }
+        public string ProjectId { get; set; }
+        public string LineId { get; set; }
+        public string WindturbineId { get; set; }
+        public int AlertValue { get; set; }
+        public string Category1 { get; set; }
+        public string Category2 { get; set; }
+        public string Category3 { get; set; }
+        public string Rank { get; set; }
+        public string StationName { get; set; }
+        public string WindturbineName { get; set; }
+        public string AlertText { get; set; }
+        public string ModelId { get; set; }
+        public int IsOpened { get; set; }
+        public DateTime? LastUpdateTime { get; set; }
+
+        public string AlertTimeTimeString { get => AlertTime?.ToString("yyyy-MM-dd HH:mm:ss"); }
+        public string LatestUpdateTimeString { get => LastUpdateTime?.ToString("yyyy-MM-dd HH:mm:ss"); }
+        private string objectName;
+        public string ObjectName
+        {
+            set => objectName = value;
+            get
+            {
+                if (objectName != null) return objectName;
+                if (Category1 == "SYZ" || Category1 == "GF")
+                {
+                    return StationName;
+                }
+                return WindturbineName;
+            }
+        }
+        public string RankString
+        {
+            get
+            {
+                switch (Rank)
+                {
+                    case "1":
+                        return "低";
+                    case "2":
+                        return "中低";
+                    case "3":
+                        return "中";
+                    case "4":
+                        return "中高";
+                    case "5":
+                        return "高";
+                    default: return "";
+                }
+            }
+        }
+        public string Category1String
+        {
+            get
+            {
+                switch (Category1)
+                {
+                    case "custom":
+                        return "自定义";
+                    case "SYZ":
+                        return "升压站";
+                    case "windturbine":
+                        return "风机";
+                    default:return "";
+                }
+            }
+        }
+
+    }
+}

+ 28 - 0
NEIntelligentControl2/Models/Alarm/AlarmPage.cs

@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.Alarm
+{
+    /// <summary>
+    /// 报警分页信息
+    /// </summary>
+    public class AlarmPage
+    {
+        /// <summary>
+        /// 总数
+        /// </summary>
+        public long Total { get; set; }
+        /// <summary>
+        /// 大小
+        /// </summary>
+        public int Size { get; set; }
+        public int Current { get; set; }
+        public bool SearchCount { get; set; }
+        public int Pages { get; set; }
+
+        public List<AlarmInfo> Records { get; set; }
+    }
+}

+ 25 - 0
NEIntelligentControl2/Models/Alarm/AlarmTypeInfo.cs

@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.Alarm
+{
+    /// <summary>
+    /// 报警类型信息
+    /// </summary>
+    public class AlarmTypeInfo
+    {
+        public List<AlarmTypeItem> RankInfo { get; set; }
+        public List<AlarmTypeItem> DeviceType { get; set; }
+    }
+
+    public class AlarmTypeItem
+    {
+        public string Name { get; set; }
+        public string Id { get; set; }
+
+        public List<AlarmTypeItem> SubItem { get; set; }
+    }
+}

+ 183 - 0
NEIntelligentControl2/Models/Alarm/FaultInfo.cs

@@ -0,0 +1,183 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json.Serialization;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.Alarm
+{
+
+    /// <summary>
+    /// 故障信息
+    /// </summary>
+    public class FaultInfo
+    {
+        /// <summary>
+        /// 故障信息ID
+        /// </summary>
+        public long Id { get; set; }
+
+        /// <summary>
+        /// 报警时间
+        /// </summary>
+        public DateTime? FaultTime { get; set; }
+
+        /// <summary>
+        /// 对象类型
+        /// </summary>
+        public int MessageType { get; set; }
+
+        /// <summary>
+        /// 发送缺陷单使用   这个表的FaultSnap.id
+        /// </summary>
+        public long SnapID { get; set; }
+        /// <summary>
+        /// 确认类型
+        /// </summary>
+        public int ConfirmType { get; set; }
+        /// <summary>
+        /// 确认时间
+        /// </summary>
+        public DateTime? ConfirmTime { get; set; }
+        /// <summary>
+        /// 确认人
+        /// </summary>
+        public string ConfirmPerson { get; set; }
+        /// <summary>
+        /// 场站ID
+        /// </summary>
+        public string StationId { get; set; }
+        /// <summary>
+        /// ProjectID
+        /// </summary>
+        public string ProjectId { get; set; }
+        /// <summary>
+        /// LineID
+        /// </summary>
+        public string LineId { get; set; }
+        /// <summary>
+        /// 风机ID
+        /// </summary>
+        public string WindturbineId { get; set; }
+
+        /// <summary>
+        /// 报警对应故障编码
+        /// </summary>
+        public long AlertValue { get; set; }
+
+        /// <summary>
+        /// 报警级别
+        /// </summary>
+        public string Rank { get; set; }
+
+        /// <summary>
+        /// 类型1
+        /// </summary>
+        public string Category1 { get; set; }
+
+        /// <summary>
+        /// 类型2
+        /// </summary>
+        public string Category2 { get; set; }
+
+        /// <summary>
+        /// 类型3
+        /// </summary>
+        public string Category3 { get; set; }
+
+        /// <summary>
+        /// 是否活跃
+        /// </summary>
+        [JsonPropertyName("opened")]
+        public bool IsOpened { get; set; }
+
+        /// <summary>
+        /// 最新更新时间
+        /// </summary>
+        public DateTime? LastUpdateTime { get; set; }
+
+        /// <summary>
+        /// 最新更新人
+        /// </summary>
+        public string LastUpdatePerson { get; set; }
+
+        /// <summary>
+        /// 场站名称
+        /// </summary>
+        public string StationName { get; set; }
+
+        /// <summary>
+        /// ProjectName
+        /// </summary>
+        public string ProjectName { get; set; }
+
+        /// <summary>
+        /// LineName
+        /// </summary>
+        public string LineName { get; set; }
+
+        /// <summary>
+        /// 风机名称
+        /// </summary>
+        public string WindturbineName { get; set; }
+
+        /// <summary>
+        /// 报警信息
+        /// </summary>
+        public string AlertText { get; set; }
+
+        /// <summary>
+        /// 风机类型ID
+        /// </summary>
+        public string ModelId { get; set; }
+        /// <summary>
+        /// 报警设备名称
+        /// </summary>
+        public string ObjectName { get; set; }
+        /// <summary>
+        /// 报警设备id
+        /// </summary>
+        public string ObjectId { get; set; }
+
+        /// <summary>
+        /// 报警设备类型名称
+        /// </summary>
+        public string CategoryName { get; set; }
+        /// <summary>
+        /// 解除触发
+        /// </summary>
+        public string MessageTypeString { get; set; }
+
+        /// <summary>
+        /// 是否可以复位
+        /// </summary>
+        public bool IsAllowReset { get; set; }
+
+        public string LatestUpdateTimeString
+        {
+            get
+            {
+                if (FaultTime != null)
+                {
+                    return FaultTime.Value.ToString("yyyy-MM-dd HH:mm:ss");
+                }
+                return LastUpdateTime?.ToString("yyyy-MM-dd HH:mm:ss");
+            }
+        }
+        private string objectName;
+        public string ObjectNameString
+        {
+            set => objectName = value;
+            get
+            {
+                if (objectName != null) return objectName;
+                if (Category1 == "SYZ" || Category1 == "STATION" || Category1 == "GF")
+                {
+                    return StationName;
+                }
+                return WindturbineName;
+            }
+        }
+    }
+}

+ 53 - 0
NEIntelligentControl2/Models/Alarm/FaultInfoModel.cs

@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.Alarm
+{
+    /// <summary>
+    /// 故障信息包装
+    /// </summary>
+    public class FaultInfoModel
+    {
+        /// <summary>
+        /// 是否允许复位
+        /// </summary>
+        public bool AllowRest { get; set; }
+        /// <summary>
+        /// 设备ID
+        /// </summary>
+        public string ThingId { get; set; }
+        /// <summary>
+        /// 设备名称
+        /// </summary>
+        public string ThingName { get; set; }
+        /// <summary>
+        /// 报警时间
+        /// </summary>
+        public DateTime AlertTime { get; set; }
+        /// <summary>
+        /// 报警内容
+        /// </summary>
+        public string AlertText { get; set; }
+        public int AgCount { get; set; }
+        /// <summary>
+        /// 故障信息
+        /// </summary>
+        public FaultInfo FaultInfo { get; set; }
+
+        public string AlertTimeString { get => AlertTime.ToString("yyyy-MM-dd HH:mm:ss"); }
+        public string AlertString
+        {
+            get
+            {
+                if (FaultInfo.MessageType == 3)
+                {
+                    return $"{AlertText}  [解除]";
+                }
+                return AlertText;
+            }
+        }
+    }
+}

+ 19 - 0
NEIntelligentControl2/Models/Attributes/StringValue.cs

@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.Attributes
+{
+    internal class StringValue : System.Attribute
+    {
+        private string _value;
+        public StringValue(string value)
+        {
+            _value = value;
+        }
+
+        public string Value { get { return _value; } }
+    }
+}

+ 46 - 0
NEIntelligentControl2/Models/BoostStation/BoostStationEventEditer.cs

@@ -0,0 +1,46 @@
+using NEIntelligentControl2.Windows.BoostStation;
+using SVGViewer.Manager;
+using SVGViewer.Models.Editer;
+using SVGViewer.Views;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Input;
+
+namespace NEIntelligentControl2.Models.BoostStation
+{
+    /// <summary>
+    /// 升压站事件编辑器
+    /// </summary>
+    internal class BoostStationEventEditer : IEditer
+    {
+        public PenManager PenManager { get; set; }
+        public Action<object> EditCompleted { get; set; }
+
+        public void MouseLeftButtonDown(SVGCanvas canvas, object sender, MouseButtonEventArgs e)
+        {
+            if (e.ClickCount < 2) return;
+            var point = e.GetPosition(canvas);
+            var v = canvas.GetVisualByPoint(point);
+
+            if (v == null || string.IsNullOrWhiteSpace(v.InitialShapeInfo.Event)) return;
+
+            SubStationWindow sbsw = new SubStationWindow(v.InitialShapeInfo.Event);
+            sbsw.Owner = Application.Current.MainWindow;
+            sbsw.ShowDialog();
+        }
+
+        public void MouseLeftButtonUp(SVGCanvas canvas, object sender, MouseButtonEventArgs e)
+        {
+
+        }
+
+        public void MouseMove(SVGCanvas canvas, object sender, MouseEventArgs e)
+        {
+
+        }
+    }
+}

+ 44 - 0
NEIntelligentControl2/Models/BoostStation/BoostStationInfo.cs

@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.BoostStation
+{
+    /// <summary>
+    /// 升压站信息
+    /// </summary>
+    public class BoostStationInfo
+    {
+        /// <summary>
+        /// 升压站ID
+        /// </summary>
+        public string Id { get; set; }
+        /// <summary>
+        /// 场站名称
+        /// </summary>
+        public string Name { get; set; }
+        /// <summary>
+        /// 标签名称
+        /// </summary>
+        public string TagName { get; set; }
+        /// <summary>
+        /// 序号
+        /// </summary>
+        public int Index { get; set; }
+        /// <summary>
+        /// 背景图片路径
+        /// </summary>
+        public string Background { get; set; }
+        /// <summary>
+        /// 更新时间
+        /// </summary>
+        public long UpdatedDate { get; set; }
+        private List<BoostStationPointInfo> boostStationPointInfos;
+        /// <summary>
+        /// 控件信息
+        /// </summary>
+        public List<BoostStationPointInfo> BoostStationPointInfos { get => boostStationPointInfos ?? (boostStationPointInfos = new List<BoostStationPointInfo>()); set => boostStationPointInfos = value; }
+    }
+}

+ 48 - 0
NEIntelligentControl2/Models/BoostStation/BoostStationPointInfo.cs

@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace NEIntelligentControl2.Models.BoostStation
+{
+    /// <summary>
+    /// 升压站控件信息
+    /// </summary>
+    public class BoostStationPointInfo
+    {
+        /// <summary>
+        /// 坐标
+        /// </summary>
+        public Point Coordinate { get; set; }
+        /// <summary>
+        /// 类型
+        /// </summary>
+        public string Type { get; set; }
+        /// <summary>
+        /// 数据标签
+        /// </summary>
+        public string DataTag { get; set; }
+        /// <summary>
+        /// 中心点坐标
+        /// </summary>
+        public Point CenterCoordinate { get; set; }
+        /// <summary>
+        /// 角度
+        /// </summary>
+        public int Angle { get; set; }
+        /// <summary>
+        /// 数据标签与名称
+        /// </summary>
+        public string Info { get; set; }
+        /// <summary>
+        /// 缩放比例
+        /// </summary>
+        public int Proportion { get; set; }
+        /// <summary>
+        /// 是否取反
+        /// </summary>
+        public bool IsNegate { get; set; }
+    }
+}

+ 57 - 0
NEIntelligentControl2/Models/BoostStation/IBoostStationPoint.cs

@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+
+namespace NEIntelligentControl2.Models.BoostStation
+{
+    /// <summary>
+    /// 升压站点信息
+    /// </summary>
+    internal interface IBoostStationPoint
+    {
+        /// <summary>
+        /// 是否被选中
+        /// </summary>
+        bool IsSelected { get; set; }
+        /// <summary>
+        /// 值
+        /// </summary>
+        double Value { get; set; }
+        /// <summary>
+        /// 数据标签
+        /// </summary>
+        string DataTag { get; set; }
+        /// <summary>
+        /// 是否是模板
+        /// </summary>
+        bool IsTemplete { get; set; }
+        /// <summary>
+        /// 是否是编辑模式
+        /// </summary>
+        bool IsEditModel { get; set; }
+        /// <summary>
+        /// 比例
+        /// </summary>
+        int Proportion { get; set; }
+        /// <summary>
+        /// 数据标签与名称
+        /// </summary>
+        string Info { get; set; }
+        /// <summary>
+        /// 是否取反
+        /// </summary>
+        bool IsNegate { get; set; }
+        /// <summary>
+        /// 被单击
+        /// </summary>
+        Action<Control> Clicked { get; set; }
+        /// <summary>
+        /// 缩放
+        /// </summary>
+        /// <param name="times">缩放次数</param>
+        void Zoom(int times);
+    }
+}

+ 37 - 0
NEIntelligentControl2/Models/Datas/TsData.cs

@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json.Serialization;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.Datas
+{
+    /// <summary>
+    /// 时序数据
+    /// </summary>
+    public class TsData
+    {
+        /// <summary>
+        /// 时间戳
+        /// </summary>
+        public long Ts { get; set; }
+        public bool? boolValue { get; set; }
+        public double? doubleValue { get; set; }
+        /// <summary>
+        /// 值
+        /// </summary>
+        public double Value
+        {
+            get
+            {
+                if (doubleValue != null)
+                {
+                    return doubleValue.Value;
+                }
+                return boolValue == true ? 1 : 0;
+            }
+            set { doubleValue = value; }
+        }
+    }
+}

+ 136 - 0
NEIntelligentControl2/Models/Helper.cs

@@ -0,0 +1,136 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media.Imaging;
+
+namespace NEIntelligentControl2.Models
+{
+    public static class Helper
+    {
+        /// <summary>
+        /// 获取字符串的配置值
+        /// </summary>
+        /// <param name="cfgname"></param>
+        /// <returns></returns>
+        public static string GetConfiguration(this string cfgname)
+        {
+            try
+            {
+                return System.Configuration.ConfigurationManager.AppSettings[cfgname];
+            }
+            catch { }
+            return "";
+        }
+
+
+
+        /// <summary>
+        /// 从时间戳获取时间字符串
+        /// </summary>
+        /// <param name="l">时间戳</param>
+        /// <returns>时间字符串</returns>
+        public static string GetTimeString(this long l)
+        {
+            if (l <= 10000) return "";
+
+            DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
+            return startTime.AddMilliseconds(l).ToString("yyyy-MM-dd hh:mm:ss");
+        }
+
+
+
+        /// <summary>
+        /// 从时间戳获取时间字符串
+        /// </summary>
+        public static string GetTimeSpanString(this long l)
+        {
+            if (l < 10000) return "";
+
+            DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
+            startTime = startTime.AddMilliseconds(l);
+
+            TimeSpan tts = DateTime.Now - startTime;
+            var ll = (long)tts.TotalMinutes;
+            ll = ll < 0 ? 0 : ll;
+            return ll.ToString();
+        }
+
+
+        /// <summary>
+        /// 获取实例中的值
+        /// </summary>
+        public static object GetValue(this object op, string name)
+        {
+            string[] names = name.Split('.');
+            object obj = null;
+            if (names.Length == 1)
+            {
+                obj = op.GetType().GetProperty(name)?.GetValue(op);
+            }
+            else
+            {
+                var v1 = op.GetType().GetProperty(names[0])?.GetValue(op);
+                if (v1 != null)
+                    obj = v1.GetType().GetProperty(names[1])?.GetValue(v1);
+            }
+            return obj;
+        }
+
+
+        /// <summary>
+        /// 获取枚举的字符
+        /// </summary>
+        public static string GetStringValue(this System.Enum value)
+        {
+            string str = "";
+            var type = value.GetType();
+            var fi = type.GetField(value.ToString());
+            var attrs = fi.GetCustomAttributes(typeof(Attributes.StringValue), false) as Attributes.StringValue[];
+            if(attrs.Length > 0)
+            {
+                str = attrs[0].Value;
+            }
+            return str;
+        }
+
+        /// <summary>
+        /// 从时间获取时间戳值
+        /// </summary>
+        /// <param name="dateTime"></param>
+        /// <returns></returns>
+        public static long GetTimeSpan(this DateTime dateTime)
+        {
+            DateTime dt = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
+            TimeSpan time = dateTime.Subtract(dt);
+
+            return long.Parse(time.Ticks.ToString().Substring(0, time.Ticks.ToString().Length - 4));
+        }
+        /// <summary>
+        /// 从时间戳获取时间
+        /// </summary>
+        public static DateTime GetLongDateTime(this long utc)
+        {
+            DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
+            startTime = startTime.AddMilliseconds(utc);
+            return startTime;
+        }
+
+        public static BitmapImage GetBitmapImage(this Bitmap obj)
+        {
+            using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
+            {
+                obj.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
+                var bs = ms.GetBuffer();
+
+                BitmapImage bi = new BitmapImage();
+                bi.BeginInit();
+                bi.StreamSource = new System.IO.MemoryStream(bs);
+                bi.EndInit();
+                return bi;
+            }
+        }
+    }
+}

+ 24 - 0
NEIntelligentControl2/Models/Matrix/IStationInfo.cs

@@ -0,0 +1,24 @@
+using NEIntelligentControl2.Models.Station;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.Matrix
+{
+    /// <summary>
+    /// 场站信息
+    /// </summary>
+    internal interface IStationInfo
+    {
+        /// <summary>
+        /// 场站信息
+        /// </summary>
+        StationInfo StationInfo { get; set; }
+        /// <summary>
+        /// 更新数据
+        /// </summary>
+        void UpdateData(object data);
+    }
+}

+ 35 - 0
NEIntelligentControl2/Models/Messages/AlarmCountBridge.cs

@@ -0,0 +1,35 @@
+using NEIntelligentControl2.Service.WebSocket;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.Messages
+{
+    internal class AlarmCountBridge : IMessage
+    {
+        public List<string> MessageTypes { get; set; } = new List<string> { "SubscribeRuntimeAlarm".GetConfiguration() };
+
+        public Action<List<Models.Alarm.AlarmInfo>> Messaged { get; set; }
+
+        public async Task OnMessage(object message)
+        {
+            try
+            {
+                await Task.Run(onmessage);
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine($"报警信息WebSocket数据解析失败:{e.Message}");
+            }
+
+            void onmessage()
+            {
+                var ss = message as List<Models.Alarm.AlarmInfo>;
+                if (ss == null) return;
+                Messaged?.Invoke(ss);
+            }
+        }
+    }
+}

+ 36 - 0
NEIntelligentControl2/Models/Messages/FaultCountBridge.cs

@@ -0,0 +1,36 @@
+using NEIntelligentControl2.Models.Alarm;
+using NEIntelligentControl2.Service.WebSocket;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.Messages
+{
+    internal class FaultCountBridge : IMessage
+    {
+        public List<string> MessageTypes { get; set; } = new List<string> { "SubscribeRuntimeFault".GetConfiguration() };
+
+        public Action<List<Models.Alarm.FaultInfoModel>> Messaged { get; set; }
+
+        public async Task OnMessage(object message)
+        {
+            try
+            {
+                await Task.Run(onmessage);
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine($"故障信息WebSocket数据解析失败:{e.Message}");
+            }
+
+            void onmessage()
+            {
+                var ss = message as List<Models.Alarm.FaultInfoModel>;
+                if (ss == null) return;
+                Messaged?.Invoke(ss);
+            }
+        }
+    }
+}

+ 36 - 0
NEIntelligentControl2/Models/Messages/FaultPopupBridge.cs

@@ -0,0 +1,36 @@
+using NEIntelligentControl2.Models.Alarm;
+using NEIntelligentControl2.Service.WebSocket;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.Messages
+{
+    internal class FaultPopupBridge : IMessage
+    {
+        public List<string> MessageTypes { get; set; } = new List<string> { "SubscribePopupAlarm".GetConfiguration() };
+        
+        public Action<List<FaultInfo>> Messaged { get; set; }
+        
+        public async Task OnMessage(object message)
+        {
+            try
+            {
+                await Task.Run(onmessage);
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine($"风机信息WebSocket数据解析失败:{e.Message}");
+            }
+
+            void onmessage()
+            {
+                var ss = message as List<FaultInfo>;
+                if (ss == null) return;
+                Messaged?.Invoke(ss);
+            }
+        }
+    }
+}

+ 38 - 0
NEIntelligentControl2/Models/Messages/PVInfoBridge.cs

@@ -0,0 +1,38 @@
+using NEIntelligentControl2.Models.PV;
+using NEIntelligentControl2.Service.WebSocket;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.Messages
+{
+    /// <summary>
+    /// 光伏信息
+    /// </summary>
+    internal class PVInfoBridge : IMessage
+    {
+        public List<string> MessageTypes { get; set; } = new List<string>() { "PVInformation".GetConfiguration() };
+        public Action<Dictionary<string, PVInfo>> Messaged { get; set; }
+
+        public async Task OnMessage(object message)
+        {
+            try
+            {
+                await Task.Run(onmessage);
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine($"光伏信息WebSocket数据解析失败:{e.Message}");
+            }
+
+            void onmessage()
+            {
+                var ss = message as Dictionary<string, PVInfo>;
+                if (ss == null) return;
+                Messaged?.Invoke(ss);
+            }
+        }
+    }
+}

+ 267 - 0
NEIntelligentControl2/Models/Messages/WEBHelper.cs

@@ -0,0 +1,267 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.Messages
+{
+    /// <summary>
+    /// 用于进行WEB请求
+    /// </summary>
+    public class WEBHelper
+    {
+        /// <summary>
+        /// 全局JSON配置
+        /// </summary>
+        private readonly JsonSerializerOptions _jso = new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, IgnoreNullValues = true };
+        /// <summary>
+        /// 凭据
+        /// </summary>
+        public string Token { get; set; }
+
+        public WEBHelper()
+        {
+            _jso.Converters.Add(new DateTiemConverter());
+            _jso.Converters.Add(new DoubleConverter());
+        }
+        /// <summary>
+        /// 使用POST请求数据,无返回值,用于更新与添加,数据以JSON形式附加在Body中
+        /// </summary>
+        /// <param name="url">请求链接</param>
+        /// <param name="jval">附加的数据</param>
+        public T HttpPostBody<T>(string url, object jval)
+        {
+            HttpWebRequest request = WebRequest.CreateHttp(url);
+            request.Method = "POST";
+            request.ContentType = "application/json";// ;charset=utf-8  application/x-www-form-urlencoded
+            request.Headers.Add("Authorization",Token);
+            if (jval != null)
+            {
+                var vl = JsonSerializer.Serialize(jval, _jso);
+                var vs = Encoding.Default.GetBytes(vl);
+                using (Stream st = request.GetRequestStream())
+                {
+                    st.Write(vs, 0, vs.Length);
+                }
+            }
+            WebResponse res = request.GetResponse();
+            T value = default;
+            using (StreamReader reader = new StreamReader(res.GetResponseStream()))
+            {
+                var val = reader.ReadToEnd();
+#if(DEBUG)
+                Console.WriteLine(val);
+#endif
+                value = JsonSerializer.Deserialize<T>(val, _jso);
+            }
+            return value;
+        }
+
+        /// <summary>
+        /// 异步使用POST请求数据,无返回值,用于更新与添加,数据以JSON形式附加在Body中
+        /// </summary>
+        /// <param name="url">请求链接</param>
+        /// <param name="jval">附加的数据</param>
+        public async Task<T> HttpPostBodyAsync<T>(string url, object jval)
+        {
+            return await Task.Run(() => HttpPostBody<T>(url, jval));
+        }/// <summary>
+         /// 使用POST请求数据,用于更新与添加,数据以JSON形式附加在Body中
+         /// </summary>
+         /// <param name="url">请求链接</param>
+         /// <param name="jval">附加的数据</param>
+        internal string HttpPostBodyString(string url, object jval)
+        {
+            HttpWebRequest request = WebRequest.CreateHttp(url);
+            request.Method = "POST";
+            request.ContentType = "application/json";// ;charset=utf-8  application/x-www-form-urlencoded
+            request.Headers.Add("Authorization", Token);
+            if (jval != null)
+            {
+                var vl = JsonSerializer.Serialize(jval, _jso);
+                var vs = Encoding.Default.GetBytes(vl);
+                using (Stream st = request.GetRequestStream())
+                {
+                    st.Write(vs, 0, vs.Length);
+                }
+            }
+            WebResponse res = request.GetResponse();
+            using (StreamReader reader = new StreamReader(res.GetResponseStream()))
+            {
+                var val = reader.ReadToEnd();
+                return val;
+            }
+        }
+
+        /// <summary>
+        /// 使用GET请求数据(只能请求返回值为JSON格式的数据)
+        /// </summary>
+        /// <typeparam name="T">得到的数据</typeparam>
+        /// <param name="url">请求地址</param>
+        /// <param name="y">请求参数</param>
+        /// <returns>请求类型</returns>
+        public T HttpGetJSON<T>(string url)
+        {
+            HttpWebRequest request = WebRequest.CreateHttp(url);
+            request.Headers.Add("Authorization", Token);
+            WebResponse res = request.GetResponse();
+            string val = "";
+            using (StreamReader reader = new StreamReader(res.GetResponseStream()))
+            {
+                val = reader.ReadToEnd();
+            }
+            request.Abort();
+            var tt = JsonSerializer.Deserialize<T>(val, _jso);
+            return tt;
+        }
+
+
+        /// <summary>
+        /// 使用GET请求数据,获得请求字符串
+        /// </summary>
+        /// <typeparam name="T">得到的数据</typeparam>
+        /// <param name="url">请求地址</param>
+        /// <param name="y">请求参数</param>
+        /// <returns>请求类型</returns>
+        public string HttpGetString(string url)
+        {
+            HttpWebRequest request = WebRequest.CreateHttp(url);
+            request.Headers.Add("Authorization", Token);
+            WebResponse res = request.GetResponse();
+            string val = "";
+            using (StreamReader reader = new StreamReader(res.GetResponseStream()))
+            {
+                val = reader.ReadToEnd();
+            }
+            request.Abort();
+            return val;
+        }
+
+        /// <summary>
+        /// 使用GET请求数据,异步方法(只能请求返回值为JSON格式的数据)
+        /// </summary>
+        /// <typeparam name="T">得到的数据</typeparam>
+        /// <param name="url">请求地址</param>
+        /// <param name="y">请求参数</param>
+        /// <returns>请求类型</returns>
+        public async Task<T> HttpGetJSONAsync<T>(string url)
+        {
+            return await Task.Run(() =>
+            {
+                return HttpGetJSON<T>(url);
+            });
+        }
+
+
+        /// <summary>
+        /// 使用GET请求数据(只能请求返回值为JSON格式的数据)
+        /// </summary>
+        /// <typeparam name="T">得到的数据</typeparam>
+        /// <param name="url">请求地址</param>
+        /// <param name="y">请求参数</param>
+        /// <returns>请求类型</returns>
+        public string HttpGetString(string url, object args)
+        {
+            string arg = GetArgs(args);
+            var ur = url + arg;
+            HttpWebRequest request = WebRequest.CreateHttp(ur);
+            WebResponse res = request.GetResponse();
+            string val = "";
+            using (StreamReader reader = new StreamReader(res.GetResponseStream()))
+            {
+                val = reader.ReadToEnd();
+            }
+            request.Abort();
+            return val;
+        }
+
+
+        /// <summary>
+        /// 将对象转换成请求字符串
+        /// </summary>
+        /// <param name="args">要转换的对象</param>
+        /// <returns>转换后的字符串</returns>
+        private string GetArgs(object args)
+        {
+            if (args == null) return "";
+            StringBuilder sb = new StringBuilder();
+            sb.Append("?");
+            var tp = args.GetType();
+            var pr = tp.GetProperties();
+            bool isFirst = true;
+            foreach (var v in pr)
+            {
+                var vv = v.GetValue(args)?.ToString();
+                if (string.IsNullOrWhiteSpace(vv)) continue;
+                if (!isFirst)
+                {
+                    sb.Append("&");
+                }
+                sb.Append(v.Name).Append("=").Append(vv);
+                isFirst = false;
+            }
+            return sb.ToString();
+        }
+
+        /// <summary>
+        /// JSON编码
+        /// </summary>
+        public string Serialize(object obj)
+        {
+            return JsonSerializer.Serialize(obj, _jso);
+        }
+
+
+        /// <summary>
+        /// JSON解码
+        /// </summary>
+        public T Deserialize<T>(string s)
+        {
+            return JsonSerializer.Deserialize<T>(s, _jso);
+        }
+    }
+
+    /// <summary>
+    /// JSON时间转换
+    /// </summary>
+    public class DateTiemConverter : JsonConverter<DateTime>
+    {
+        public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+        {
+            DateTime.TryParse(reader.GetString(), out DateTime dt);
+            return dt;
+        }
+
+        public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
+        {
+            writer.WriteStringValue(value.ToString("yyyy-MM-dd HH:mm:ss"));
+        }
+    }
+
+    /// <summary>
+    /// JSON时间转换
+    /// </summary>
+    public class DoubleConverter : JsonConverter<double>
+    {
+        public override double Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+        {
+            if(reader.TokenType== JsonTokenType.Number)
+            {
+                reader.TryGetDouble(out double d);
+                return d;
+            }
+            double.TryParse(reader.GetString(), out double d2);
+            return d2;
+        }
+
+        public override void Write(Utf8JsonWriter writer, double value, JsonSerializerOptions options)
+        {
+            writer.WriteStringValue(value.ToString());
+        }
+    }
+}

+ 38 - 0
NEIntelligentControl2/Models/Messages/WindturbineInfoBridge.cs

@@ -0,0 +1,38 @@
+using NEIntelligentControl2.Models.Windturbine;
+using NEIntelligentControl2.Service.WebSocket;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.Messages
+{
+    /// <summary>
+    /// 风机信息桥
+    /// </summary>
+    class WindturbineInfoBridge : IMessage
+    {
+        public List<string> MessageTypes { get; set; } = new List<string>() { "WindturbineInformation".GetConfiguration() };
+        public Action<Dictionary<string, WindturbineInfo>> Messaged { get; set; }
+
+        public async Task OnMessage(object message)
+        {
+            try
+            {
+                await Task.Run(onmessage);
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine($"风机信息WebSocket数据解析失败:{e.Message}");
+            }
+
+            void onmessage()
+            {
+                var ss = message as Dictionary<string, WindturbineInfo>;
+                if (ss == null) return;
+                Messaged?.Invoke(ss);
+            }
+        }
+    }
+}

+ 28 - 0
NEIntelligentControl2/Models/PV/PVDetails.cs

@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.PV
+{
+    /// <summary>
+    /// 光伏信息
+    /// </summary>
+    public class PVDetails
+    {
+        /// <summary>
+        /// 名称
+        /// </summary>
+        public string Name { get; set; }
+        /// <summary>
+        /// 状态
+        /// </summary>
+        public PVTagInfo Status { get; set; }
+        private List<PVTagInfo> codeInfo;
+        /// <summary>
+        /// 标签点
+        /// </summary>
+        public List<PVTagInfo> CodeInfos { get => codeInfo ?? (codeInfo = new List<PVTagInfo>()); set => codeInfo = value; }
+    }
+}

+ 81 - 0
NEIntelligentControl2/Models/PV/PVInfo.cs

@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.PV
+{
+    /// <summary>
+    /// 光伏信息
+    /// </summary>
+    public class PVInfo
+    {
+        /// <summary>
+        /// 场站ID
+        /// </summary>
+        public string Station { get; set; }
+        /// <summary>
+        /// 期次
+        /// </summary>
+        public string Project { get; set; }
+        /// <summary>
+        /// 线路
+        /// </summary>
+        public string Line { get; set; }
+        /// <summary>
+        /// 机型
+        /// </summary>
+        public string Model { get; set; }
+        /// <summary>
+        /// 光伏设备ID
+        /// </summary>
+        public string Id { get; set; }
+        /// <summary>
+        /// 设备名称
+        /// </summary>
+        public string Code { get; set; }
+        /// <summary>
+        /// 光伏电流
+        /// </summary>
+        public double I { get; set; }
+        /// <summary>
+        /// 光伏电压
+        /// </summary>
+        public double U { get; set; }
+        /// <summary>
+        /// 光伏功率
+        /// </summary>
+        public double P { get; set; }
+        /// <summary>
+        /// 时间戳
+        /// </summary>
+        public long Ts { get; set; }
+        /// <summary>
+        /// 状态
+        /// </summary>
+        public double Status { get; set; }
+        /// <summary>
+        /// 状态
+        /// </summary>
+        public PVState State { get => (PVState)Status; }
+        private int index = -1;
+        /// <summary>
+        /// 设备序号
+        /// </summary>
+        public int Index
+        {
+            get
+            {
+                if (index < 0)
+                {
+                    if (Id == null) return index;
+                    var vs = Id.Split('_');
+                    if (vs.Length < 2) return index;
+                    int.TryParse(vs[1], out index);
+                }
+                return index;
+            }
+        }
+    }
+}

+ 47 - 0
NEIntelligentControl2/Models/PV/PVState.cs

@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.PV
+{
+    /// <summary>
+    /// 光伏状态
+    /// </summary>
+    public enum PVState
+    {
+        /// <summary>
+        /// 未知
+        /// </summary>
+        UnKnow = -1,
+        /// <summary>
+        /// 待机
+        /// </summary>
+        Standby = 0,
+        /// <summary>
+        /// 并网
+        /// </summary>
+        GridConnected = 1,
+        /// <summary>
+        /// 故障
+        /// </summary>
+        Malfunction = 2,
+        /// <summary>
+        /// 离线
+        /// </summary>
+        Offline = 3,
+        /// <summary>
+        /// 维护
+        /// </summary>
+        Maintain = 4,
+        /// <summary>
+        /// 限电
+        /// </summary>
+        Restriction = 5,
+        /// <summary>
+        /// 限电停机
+        /// </summary>
+        RestrictionShutdown = 6
+    }
+}

+ 98 - 0
NEIntelligentControl2/Models/PV/PVTagInfo.cs

@@ -0,0 +1,98 @@
+using NEIntelligentControl2.Models.Datas;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.PV
+{
+    /// <summary>
+    /// 光伏标签点信息
+    /// </summary>
+    public class PVTagInfo
+    {
+        /// <summary>
+        /// 名称
+        /// </summary>
+        public string Name { get; set; }
+        private string code;
+        /// <summary>
+        /// UniformCode
+        /// </summary>
+        public string Code { get => code; set { code = value; Codes = code.Split(','); } }
+        /// <summary>
+        /// UniformCode们
+        /// </summary>
+        public string[] Codes { get; set; }
+        /// <summary>
+        /// 单位
+        /// </summary>
+        public string Unit { get; set; }
+        /// <summary>
+        /// 是否忽视此标签点
+        /// </summary>
+        public bool IsIgnore { get; set; }
+        /// <summary>
+        /// 标签类型
+        /// </summary>
+        public PVTagType Type { get; set; }
+        /// <summary>
+        /// 值
+        /// </summary>
+        private double value;
+        public double Value { get { return value; } set { this.value = value; ValueChanged?.Invoke(this.value); } }
+        /// <summary>
+        /// 值改变
+        /// </summary>
+        public Action<double> ValueChanged { get; set; }
+        /// <summary>
+        /// 数据历史值改变
+        /// </summary>
+        public Action<PVTagInfo, List<TsData>> HistoryValueChanged { get; set; }
+
+        internal void UpdateValue(Dictionary<string, TsData> vs)
+        {
+            if (vs == null || this.Code == null) return;
+            double d = 0;
+            foreach (var v in Codes)
+            {
+                if (!vs.ContainsKey(v)) continue;
+                d += vs[v].Value;
+            }
+            this.Value = d;
+        }
+
+        /// <summary>
+        /// 更新历史数据
+        /// </summary>
+        internal void UpdateHistoryData(List<TsData> vs)
+        {
+            HistoryValueChanged?.Invoke(this, vs);
+        }
+    }
+
+
+    /// <summary>
+    /// 光伏标签类型
+    /// </summary>
+    public enum PVTagType
+    {
+        /// <summary>
+        /// 其他(默认)
+        /// </summary>
+        Other,
+        /// <summary>
+        /// 温度
+        /// </summary>
+        Temperature,
+        /// <summary>
+        /// 功率
+        /// </summary>
+        Power,
+        /// <summary>
+        /// 光照强度
+        /// </summary>
+        Sunshine,
+    }
+}

+ 64 - 0
NEIntelligentControl2/Models/PV/SUN2000Info.cs

@@ -0,0 +1,64 @@
+using NEIntelligentControl2.Models.Datas;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.PV
+{
+    /// <summary>
+    /// 光伏SUN2000信息
+    /// </summary>
+    public class SUN2000Info
+    {
+        /// <summary>
+        /// 名称
+        /// </summary>
+        public string Name { get; set; }
+        /// <summary>
+        /// 电流
+        /// </summary>
+        public PVTagInfo I { get; set; }
+        /// <summary>
+        /// 电压
+        /// </summary>
+        public PVTagInfo V { get; set; }
+        /// <summary>
+        /// 电流变化值
+        /// </summary>
+        public double ΔI { get; set; }
+        /// <summary>
+        /// 功率
+        /// </summary>
+        public double P
+        {
+            get
+            {
+                if (I == null || V == null) return 0.0;
+                return I.Value * V.Value / 1000;
+            }
+        }
+        /// <summary>
+        /// 值改变
+        /// </summary>
+        public Action<double, double> ValueChanged { get; set; }
+
+        /// <summary>
+        /// 更新数据
+        /// </summary>
+        /// <param name="vs"></param>
+        internal void UpdateValue(Dictionary<string, TsData> vs)
+        {
+            if (vs == null) return;
+            var bi = I.Value;
+            V.UpdateValue(vs);
+            I.UpdateValue(vs);
+            if (bi != I.Value && bi != 0)
+            {
+                ΔI = Math.Abs(I.Value - bi);
+            }
+            ValueChanged?.Invoke(P, ΔI);
+        }
+    }
+}

+ 48 - 0
NEIntelligentControl2/Models/PageInfo.cs

@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models
+{
+    /// <summary>
+    /// 分页信息
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    internal class PageInfo<T>
+    {
+        /// <summary>
+        /// 元素总数
+        /// </summary>
+        public int TotalElements { get; set; }
+        /// <summary>
+        /// 总页数
+        /// </summary>
+        public int TotalPages { get; set; }
+        /// <summary>
+        /// 是否是第一页
+        /// </summary>
+        public bool Last { get; set; }
+        /// <summary>
+        /// 是否是第一页
+        /// </summary>
+        public bool First { get; set; }
+        /// <summary>
+        /// 页数(从0开始)
+        /// </summary>
+        public int Number { get; set; }
+        /// <summary>
+        /// 每页大小
+        /// </summary>
+        public int Size { get; set; }
+        /// <summary>
+        /// 本页数据数量
+        /// </summary>
+        public int NumberOfElements { get; set; }
+        /// <summary>
+        /// 内容
+        /// </summary>
+        public List<T> Content { get; set; }
+    }
+}

+ 21 - 0
NEIntelligentControl2/Models/Pages/IPageAction.cs

@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+
+namespace NEIntelligentControl2.Models.Pages
+{
+    /// <summary>
+    /// 页面动作
+    /// </summary>
+    public interface IPageAction
+    {
+        /// <summary>
+        /// 获取页面
+        /// </summary>
+        /// <param name="name">页面名称</param>
+        Page this[string name] { get; }
+    }
+}

+ 19 - 0
NEIntelligentControl2/Models/Pages/IPageBase.cs

@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.Pages
+{
+    /// <summary>
+    /// 页面基础
+    /// </summary>
+    interface IPageBase
+    {
+        /// <summary>
+        /// 页面切换
+        /// </summary>
+        void SwitchPage(string name,object value);
+    }
+}

+ 19 - 0
NEIntelligentControl2/Models/Pages/IPageMessage.cs

@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.Pages
+{
+    /// <summary>
+    /// 页面消息
+    /// </summary>
+    internal interface IPageMessage
+    {
+        /// <summary>
+        /// 消息
+        /// </summary>
+        Action<object> OnMessage { get; set; }
+    }
+}

+ 42 - 0
NEIntelligentControl2/Models/Pages/PageManager.cs

@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+
+namespace NEIntelligentControl2.Models.Pages
+{
+
+    /// <summary>
+    /// 页面管理
+    /// </summary>
+    public class PageManager : IPageAction
+    {
+        /// <summary>
+        /// 获取页面
+        /// </summary>
+        /// <param name="name">页面名称</param>
+        /// <returns>页面</returns>
+        public Page this[string name]
+        {
+            get
+            {
+                var tp = Type.GetType($"NEIntelligentControl2.Pages.{name}");
+                if (tp == null)
+                {
+                    throw new Exception($"未发现{name}页面!");
+                }
+                var page = App.ServiceProvider.GetService(tp) as Page;
+                /*
+                 * 如果页面未注册,请在App类里的ConfigureServices方法中注册这个页面(将页面添加到依赖注入框架中)
+                 */
+                if (page == null)
+                {
+                    throw new Exception($"{name}页面未注册!");
+                }
+                return page;
+            }
+        }
+    }
+}

+ 28 - 0
NEIntelligentControl2/Models/Pages/TagManager.cs

@@ -0,0 +1,28 @@
+using NEIntelligentControl2.Models.Station;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.Pages
+{
+    /// <summary>
+    /// 标签管理
+    /// </summary>
+    public class TagManager
+    {
+        /// <summary>
+        /// 标签内容改变
+        /// </summary>
+        public Action<List<StationInfo>> TagChanged { get; set; }
+        /// <summary>
+        /// 标签切换
+        /// </summary>
+        public Action<StationInfo> TagSwitched { get; set; }
+        /// <summary>
+        /// 手动切换标签
+        /// </summary>
+        public Action<string> ChangeTag { get; set; }
+    }
+}

+ 35 - 0
NEIntelligentControl2/Models/Station/StationInfo.cs

@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NEIntelligentControl2.Models.Station
+{
+    /// <summary>
+    /// 场站信息
+    /// </summary>
+    public class StationInfo
+    {
+        /// <summary>
+        /// 场站名称
+        /// </summary>
+        public string Name { get; set; }
+        /// <summary>
+        /// 全名
+        /// </summary>
+        public string FullName { get; set; }
+        /// <summary>
+        /// 场站ID
+        /// </summary>
+        public string Id { get; set; }
+        /// <summary>
+        /// 场站类型
+        /// </summary>
+        public StationType Type { get; set; }
+        /// <summary>
+        /// 附加内容
+        /// </summary>
+        public object Tag { get; set; }
+    }
+}

+ 0 - 0
NEIntelligentControl2/Models/Station/StationType.cs


Some files were not shown because too many files changed in this diff