├── .idea ├── .gitignore ├── vcs.xml ├── modules.xml ├── misc.xml ├── dgiot_dtu.iml └── compiler.xml ├── DD-All.ico ├── renovate.json ├── lib ├── CodeLib.dll ├── Spire.Doc.dll ├── Spire.Pdf.dll ├── Spire.License.dll ├── PLCComHelperProj.dll ├── System.Data.SQLite.dll ├── System.Data.SQLite.EF6.dll └── System.Data.SQLite.Linq.dll ├── Resources └── bridge.jpg ├── component ├── Opc │ ├── cfg.ini │ ├── App.xaml │ ├── Model │ │ ├── Item.cs │ │ ├── HostCollection.cs │ │ ├── GroupEntity.cs │ │ ├── Thing.cs │ │ ├── Header.cs │ │ └── OpcDaService.cs │ ├── Protocol │ │ ├── StartMonitoringItemsRsp.cs │ │ ├── StopMonitoringItemsReq.cs │ │ ├── ReadItemsRsp.cs │ │ ├── StartMonitoringItemsReq.cs │ │ ├── ReadItemsReq.cs │ │ ├── Command.cs │ │ └── WriteNodesValuesReq.cs │ ├── packages.config │ ├── IOPCDa.cs │ ├── app.config │ ├── OPCUAHelper.cs │ ├── app.manifest │ ├── log4net.config │ ├── OPCDAHelper.cs │ ├── Da.csproj │ └── View │ │ └── OPCDAViewHelper.cs ├── Plc │ └── PLCHelper.cs ├── BACnet │ ├── BACnetHelper.cs │ ├── BacProperty.cs │ └── BacDevice.cs ├── Sqlserver │ └── SqlServerHelper.cs ├── Http │ └── HttpClientHelper.cs ├── Udp │ ├── UDPClientHelper.cs │ └── UDPServerHelper.cs ├── Printer │ ├── PrinterHelper.cs │ ├── Knova.cs │ ├── PdfPrinter.cs │ └── BarCodePrinter.cs ├── sqlite │ ├── ManagerInfoDal.cs │ └── SqliteHelper.cs ├── SerialPort │ └── SerialPortHelper.cs ├── Mqtt │ └── MqttServerHelper.cs └── Tcp │ ├── TcpClientHelper.cs │ └── TcpServerHelper.cs ├── .gitignore ├── .github ├── ISSUE_TEMPLATE.md ├── weekly-digest.yml ├── ISSUE_TEMPLATE │ ├── support-needed.md │ ├── feature-request.md │ └── bug-report.md ├── workflows │ ├── docker.yml │ ├── accurics.yaml │ ├── release.yml │ ├── gitee-repos-mirror.yml │ ├── dotnet.yml │ ├── build_slim_packages.yaml │ └── .gitlint └── PULL_REQUEST_TEMPLATE.md ├── app.config ├── FodyWeavers.xml ├── dgiot_dtu.csproj.user ├── Properties ├── Settings.settings ├── Settings.Designer.cs ├── AssemblyInfo.cs ├── Resources.Designer.cs └── Resources.resx ├── opcda.txt ├── stylecop.json ├── Program.cs ├── dgiot_dtu.sln ├── utils ├── ConfigHelper.cs ├── TimerHelper.cs ├── FileHelper.cs ├── IPScanHelper.cs ├── LogHelper.cs ├── JsonArray.cs └── TreeViewHelper.cs ├── .editorconfig ├── README-JP.md ├── README.md ├── README-RU.md ├── syscfg.xml ├── README-CN.md ├── packages.config ├── FodyWeavers.xsd └── LICENSE /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /workspace.xml -------------------------------------------------------------------------------- /DD-All.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgiot/dgiot_dtu/HEAD/DD-All.ico -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /lib/CodeLib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgiot/dgiot_dtu/HEAD/lib/CodeLib.dll -------------------------------------------------------------------------------- /lib/Spire.Doc.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgiot/dgiot_dtu/HEAD/lib/Spire.Doc.dll -------------------------------------------------------------------------------- /lib/Spire.Pdf.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgiot/dgiot_dtu/HEAD/lib/Spire.Pdf.dll -------------------------------------------------------------------------------- /Resources/bridge.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgiot/dgiot_dtu/HEAD/Resources/bridge.jpg -------------------------------------------------------------------------------- /component/Opc/cfg.ini: -------------------------------------------------------------------------------- 1 | [scan] 2 | networkSegments=192.168.1.4 3 | whitelist=SunFull.X2OPC.1 -------------------------------------------------------------------------------- /lib/Spire.License.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgiot/dgiot_dtu/HEAD/lib/Spire.License.dll -------------------------------------------------------------------------------- /component/Plc/PLCHelper.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgiot/dgiot_dtu/HEAD/component/Plc/PLCHelper.cs -------------------------------------------------------------------------------- /lib/PLCComHelperProj.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgiot/dgiot_dtu/HEAD/lib/PLCComHelperProj.dll -------------------------------------------------------------------------------- /lib/System.Data.SQLite.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgiot/dgiot_dtu/HEAD/lib/System.Data.SQLite.dll -------------------------------------------------------------------------------- /lib/System.Data.SQLite.EF6.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgiot/dgiot_dtu/HEAD/lib/System.Data.SQLite.EF6.dll -------------------------------------------------------------------------------- /lib/System.Data.SQLite.Linq.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgiot/dgiot_dtu/HEAD/lib/System.Data.SQLite.Linq.dll -------------------------------------------------------------------------------- /component/BACnet/BACnetHelper.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgiot/dgiot_dtu/HEAD/component/BACnet/BACnetHelper.cs -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .eunit 2 | test-data/ 3 | !deps/.placeholder 4 | _build/ 5 | www/ 6 | obj/ 7 | bin/ 8 | packages/ 9 | .vs/ 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | #### Environment 2 | 3 | - OS: 4 | - Erlang/OTP: 5 | - EMQ: 6 | 7 | #### Description 8 | 9 | *A description of the issue* 10 | 11 | -------------------------------------------------------------------------------- /app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /FodyWeavers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dgiot_dtu.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ShowAllFiles 5 | 6 | -------------------------------------------------------------------------------- /.github/weekly-digest.yml: -------------------------------------------------------------------------------- 1 | # Configuration for weekly-digest - https://github.com/apps/weekly-digest 2 | publishDay: monday 3 | canPublishIssues: true 4 | canPublishPullRequests: true 5 | canPublishContributors: true 6 | canPublishStargazers: true 7 | canPublishCommits: true 8 | -------------------------------------------------------------------------------- /Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /opcda.txt: -------------------------------------------------------------------------------- 1 | GCU331_YJ.SX_PZ96_U_55 2 | GCU331_YJ.SX_PZ96_I_55 3 | GCU331_YJ.SX_PZ96_P_55 4 | GCU331_YJ.SX_PZ96_U_160 5 | GCU331_YJ.SX_PZ96_I_160 6 | GCU331_YJ.SX_PZ96_P_160 7 | GCU331_YJ.p_L_1 8 | GCU331_YJ.p_L_2 9 | GCU331_YJ.p_Q_2 10 | GCU331_YJ.Q_Q_DN65 11 | GCU331_YJ.Q_Q_DN100 12 | GCU331_YJ.Q_Q_DN125 -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/support-needed.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Support Needed 3 | about: Asking a question about usages, docs or anything you're insterested in 4 | title: '' 5 | labels: Support 6 | assignees: h7ml 7 | 8 | --- 9 | 10 | **Please describe your problem in detail, if necessary, you can upload the log file through the attachment**: 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: Feature 6 | assignees: h7ml 7 | 8 | --- 9 | 10 | 11 | 12 | **What would you like to be added/modified**: 13 | 14 | **Why is this needed**: 15 | -------------------------------------------------------------------------------- /component/Opc/App.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/dgiot_dtu.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /component/Opc/Model/Item.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Da 6 | { 7 | public class Item 8 | { 9 | public string ItemId { get; set; } 10 | 11 | public object Data { get; set; } 12 | 13 | public string Type { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /component/Opc/Protocol/StartMonitoringItemsRsp.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Da 6 | { 7 | public class StartMonitoringItemsRsp 8 | { 9 | public string ServiceId { get; set; } 10 | 11 | public string GroupId { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /component/Opc/Protocol/StopMonitoringItemsReq.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Da 6 | { 7 | public class StopMonitoringItemsReq 8 | { 9 | public string ServiceId { get; set; } 10 | 11 | public string Id { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /component/Opc/Model/HostCollection.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | using System.Collections.Generic; 6 | 7 | namespace Da 8 | { 9 | internal class HostCollection 10 | { 11 | public string Host { get; set; } 12 | 13 | public List ServiceIds { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /component/Opc/Model/GroupEntity.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | using System.Collections.Generic; 6 | using System.Windows.Forms; 7 | 8 | namespace Da 9 | { 10 | internal class GroupEntity 11 | { 12 | public string Host { get; set; } 13 | 14 | public string ProgId { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: Continuos Integration with Github 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@master 12 | - name: Publish to Docker Repository 13 | uses: elgohr/Publish-Docker-Github-Action@master 14 | with: 15 | name: ispeakcode/docker-githubaction 16 | username: ${{ secrets.DOCKER_USERNAME }} 17 | password: ${{ secrets.DOCKER_PASSWORD }} 18 | -------------------------------------------------------------------------------- /component/Opc/Model/Thing.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | using System.Collections.Generic; 6 | 7 | namespace Da 8 | { 9 | internal class Thing 10 | { 11 | public string Device { get; set; } 12 | 13 | public string Proctol { get; set; } 14 | 15 | public string Group { get; set; } 16 | 17 | public List Items { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /component/Opc/Protocol/ReadItemsRsp.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | using System.Collections.Generic; 6 | 7 | namespace Da 8 | { 9 | public class ReadItemsRsp 10 | { 11 | public string ServiceId { get; set; } 12 | 13 | public string GroupId { get; set; } 14 | 15 | public string StrMd5 { get; set; } 16 | 17 | public List ItemValues { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.github/workflows/accurics.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | workflow_dispatch: 6 | jobs: 7 | accurics-scan: 8 | runs-on: ubuntu-latest 9 | name: accurics-scan 10 | steps: 11 | - name: Checkout repository 12 | uses: actions/checkout@v2 13 | - name: Accurics Scan 14 | id: accurics-scan 15 | uses: docker://accurics/terrascan-action:latest 16 | with: 17 | only_warn: true 18 | verbose: true 19 | webhook_url: https://app.accurics.com/v1/api/terrascan 20 | webhook_token: a20de3ab-f00e-4e1a-a37f-dbceafe4150e -------------------------------------------------------------------------------- /component/Opc/Model/Header.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Da 6 | { 7 | public struct Header 8 | { 9 | public int Id; 10 | public int Cmd; 11 | public int ErrorCode; 12 | public int ContentSize; 13 | 14 | public Header(int id, int cmd, int errorcode, int payloadLength) 15 | { 16 | Id = id; 17 | Cmd = cmd; 18 | ErrorCode = errorcode; 19 | ContentSize = payloadLength; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /component/Opc/Model/OpcDaService.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Da 6 | { 7 | using System; 8 | using System.Collections.Generic; 9 | using TitaniumAS.Opc.Client.Da; 10 | 11 | public class OpcDaService 12 | { 13 | public string Host { get; set; } 14 | 15 | public string ServiceId { get; set; } 16 | 17 | public OpcDaServer Service { get; set; } 18 | 19 | public Dictionary OpcDaGroupS; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /stylecop.json: -------------------------------------------------------------------------------- 1 | { 2 | // ACTION REQUIRED: This file was automatically added to your project, but it 3 | // will not take effect until additional steps are taken to enable it. See the 4 | // following page for additional information: 5 | // 6 | // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md 7 | 8 | "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", 9 | "settings": { 10 | "documentationRules": { 11 | "companyName": "PlaceholderCompany" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | 2 | # https://github.com/actions/create-release 3 | name: Create Release 4 | 5 | on: 6 | push: 7 | tags: 8 | - 'v*' 9 | 10 | jobs: 11 | build: 12 | name: Create Release 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Checkout code 17 | uses: actions/checkout@master 18 | 19 | - name: Create Release 20 | id: create_release 21 | uses: actions/create-release@latest 22 | env: 23 | GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }} 24 | with: 25 | tag_name: ${{ github.ref }} 26 | release_name: ${{ github.ref }} 27 | draft: false 28 | prerelease: false 29 | -------------------------------------------------------------------------------- /Program.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Dgiot_dtu 6 | { 7 | using System; 8 | using System.Windows.Forms; 9 | 10 | internal static class Program 11 | { 12 | /// 13 | /// The main entry point for the application. 14 | /// 15 | [STAThread] 16 | private static void Main() 17 | { 18 | Application.EnableVisualStyles(); 19 | Application.SetCompatibleTextRenderingDefault(false); 20 | 21 | Application.Run(new MainForm()); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.github/workflows/gitee-repos-mirror.yml: -------------------------------------------------------------------------------- 1 | name: Gitee repos mirror periodic job 2 | 3 | on: 4 | push: 5 | watch: 6 | types: started 7 | schedule: 8 | - cron: "0 23 * * *" 9 | 10 | jobs: 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | 17 | - name: Mirror the Github organization repos to Gitee. 18 | uses: Yikun/hub-mirror-action@v1.0 19 | with: 20 | src: github/dgiot 21 | dst: gitee/dgiiot 22 | dst_key: ${{ secrets.PRIVATE_KEY }} 23 | dst_token: ${{ secrets.TOKEN }} 24 | account_type: org 25 | timeout: '1h' 26 | debug: true 27 | force_update: true 28 | black_list: "issue-generator,dgiot-dashboard" 29 | -------------------------------------------------------------------------------- /component/Opc/Protocol/StartMonitoringItemsReq.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | using System.Collections.Generic; 6 | 7 | namespace Da 8 | { 9 | public class StartMonitoringItemsReq 10 | { 11 | public string ServiceId { get; set; } 12 | 13 | public string StrMd5 { get; set; } 14 | 15 | public List Items { get; set; } 16 | 17 | public StartMonitoringItemsReq(string serviceProgId, List items, string strmd5) 18 | { 19 | ServiceId = serviceProgId; 20 | Items = items; 21 | StrMd5 = strmd5; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: Support 6 | assignees: h7ml 7 | 8 | --- 9 | 10 | 11 | 12 | 13 | **Environment**: 14 | 15 | - dgiot version (e.g. `dgiot_ctl status`): 16 | - Hardware configuration (e.g. `lscpu`): 17 | - OS (e.g. `cat /etc/os-release`): 18 | - Kernel (e.g. `uname -a`): 19 | - Erlang/OTP version (in case you build emqx from source code): 20 | - Others: 21 | 22 | **What happened and what you expected to happen**: 23 | 24 | **How to reproduce it (as minimally and precisely as possible)**: 25 | 26 | **Anything else we need to know?**: 27 | -------------------------------------------------------------------------------- /component/BACnet/BacProperty.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Dgiot_dtu 6 | { 7 | using System.IO.BACnet; 8 | 9 | public class BacProperty 10 | { 11 | #region ObjectId 12 | 13 | public BacnetObjectId ObjectId { get; set; } 14 | 15 | #endregion 16 | 17 | #region PROP_DESCRIPTION 描述 18 | 19 | public string PROP_DESCRIPTION { get; set; } 20 | 21 | #endregion 22 | 23 | #region PROP_OBJECT_NAME 点名 24 | 25 | public string PROP_OBJECT_NAME { get; set; } 26 | 27 | #endregion 28 | 29 | public object PROP_PRESENT_VALUE { get; set; } 30 | } 31 | } -------------------------------------------------------------------------------- /component/Opc/Protocol/ReadItemsReq.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Da 6 | { 7 | using System.Collections.Generic; 8 | 9 | public class ReadItemsReq 10 | { 11 | public string ServiceId { get; set; } 12 | 13 | public string GroupId { get; set; } 14 | 15 | public string StrMd5 { get; set; } 16 | 17 | public List Items { get; set; } 18 | 19 | public ReadItemsReq(string serviceProgId, List items, string groupId, string strmd5) 20 | { 21 | ServiceId = serviceProgId; 22 | GroupId = groupId; 23 | StrMd5 = strmd5; 24 | Items = items; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | Fixes 3 | 4 | **If your build fails** due to your commit message not passing the build checks, please review the guidelines here: https://github.com/emqx/emqx/blob/master/CONTRIBUTING.md. 5 | 6 | ## PR Checklist 7 | Please convert it to a draft if any of the following conditions are not met. Reviewers may skip over until all the items are checked: 8 | 9 | - [ ] Tests for the changes have been added (for bug fixes / features) 10 | - [ ] Docs have been added / updated (for bug fixes / features) 11 | - [ ] In case of non-backward compatible changes, reviewer should check this item as a write-off, and add details in **Backward Compatibility** section 12 | 13 | ## Backward Compatibility 14 | 15 | ## More information 16 | -------------------------------------------------------------------------------- /component/Opc/Protocol/Command.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Da 6 | { 7 | public enum Command 8 | { 9 | Get_Nodes_Req = 0x400000, // 10 | Get_Nodes_Rsp = 0x400001, 11 | 12 | Start_Monitor_Nodes_Req = 0x400002, 13 | Start_Monitor_Nodes_Rsp = 0x400003, 14 | 15 | Stop_Monitor_Nodes_Req = 0x400004, 16 | Stop_Monitor_Nodes_Rsp = 0x400005, 17 | 18 | Read_Nodes_Values_Req = 0x400006, 19 | Read_Nodes_Values_Rsp = 0x400007, 20 | 21 | Write_Nodes_Values_Req = 0x400008, 22 | Write_Nodes_Values_Rsp = 0x400009, 23 | 24 | Notify_Nodes_Values_Ex = 0x400999, 25 | } 26 | 27 | public enum MonitorItemType 28 | { 29 | Initial, 30 | Add, 31 | Remove, 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /component/Opc/Protocol/WriteNodesValuesReq.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | using System.Collections.Generic; 6 | 7 | namespace Da 8 | { 9 | internal class WriteNodesValuesReq 10 | { 11 | public string ServiceId { get; set; } 12 | 13 | public string GroupId { get; set; } 14 | 15 | public string StrMd5 { get; set; } 16 | 17 | public Dictionary ItemValuePairs { get; set; } 18 | 19 | public WriteNodesValuesReq(string serviceProgId, Dictionary items, string groupId, string strmd5) 20 | { 21 | ServiceId = serviceProgId; 22 | GroupId = groupId; 23 | StrMd5 = strmd5; 24 | ItemValuePairs = items; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /component/Sqlserver/SqlServerHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | using System.Configuration; 6 | 7 | namespace Dgiot_dtu 8 | { 9 | public class SqlServerHelper 10 | { 11 | private SqlServerHelper() 12 | { 13 | } 14 | 15 | private static SqlServerHelper instance; 16 | 17 | public static SqlServerHelper GetInstance() 18 | { 19 | if (instance == null) 20 | { 21 | instance = new SqlServerHelper(); 22 | } 23 | 24 | return instance; 25 | } 26 | 27 | public static void Start(KeyValueConfigurationCollection config) 28 | { 29 | Config(config); 30 | } 31 | 32 | public static void Stop() 33 | { 34 | } 35 | 36 | public static void Config(KeyValueConfigurationCollection config) 37 | { 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /component/Opc/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Dgiot_dtu.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /component/Opc/IOPCDa.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Windows.Forms; 8 | using TitaniumAS.Opc.Client.Da; 9 | 10 | namespace Da 11 | { 12 | public interface IOPCDa 13 | { 14 | List ScanOPCDa(string host, bool isClean = true); 15 | 16 | string StartMonitoringItems(string host, string serviceProgId, TreeNode groupNode, int interval, int count); 17 | 18 | void SetItemsValueChangedCallBack(IItemsValueChangedCallBack callBack); 19 | 20 | void StopMonitoringItems(string groupKey); 21 | 22 | List ReadItemsValues(string host, string serviceProgId, string groupKey); 23 | 24 | void WriteValues(string host, string serviceProgId, string groupKey, Dictionary itemValuePairs); 25 | } 26 | 27 | public interface IItemsValueChangedCallBack 28 | { 29 | void ValueChangedCallBack(OpcDaGroup opcGroup, OpcDaItemValue[] values); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /component/BACnet/BacDevice.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Dgiot_dtu 6 | { 7 | using System.Collections.Generic; 8 | using System.IO.BACnet; 9 | 10 | public class BacDevice 11 | { 12 | #region Address 13 | 14 | public BacnetAddress Address { get; set; } 15 | 16 | #endregion 17 | 18 | #region DeviceId 19 | 20 | public uint DeviceId { get; set; } 21 | 22 | public List Properties { get; set; } 23 | 24 | #endregion 25 | 26 | public BacDevice(BacnetAddress adr, uint deviceId) 27 | { 28 | this.Address = adr; 29 | this.DeviceId = deviceId; 30 | } 31 | 32 | public BacnetAddress GetAddr(uint deviceId) 33 | { 34 | if (this.DeviceId == deviceId) 35 | { 36 | return Address; 37 | } 38 | else 39 | { 40 | return null; 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /.github/workflows/dotnet.yml: -------------------------------------------------------------------------------- 1 | name: sync 2 | 3 | on: 4 | push: 5 | branches: [t] 6 | # schedule: 7 | # - cron: '0 21 * * *' 8 | workflow_dispatch: 9 | 10 | jobs: 11 | sync: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Sync to Gitee page 15 | uses: wearerequired/git-mirror-action@master 16 | env: 17 | # 在 Settings->Secrets 配置 GITEE_RSA_PRIVATE_KEY 18 | SSH_PRIVATE_KEY: ${{ secrets.GITEE_PRIVATE_KEY }} 19 | with: 20 | # GitHub 源仓库地址 21 | source-repo: git@github.com:dgiot/dgiot_dtu.git 22 | # Gitee 目标仓库地址 23 | destination-repo: git@gitee.com:dgiot_dtu/dgiot_dtu.git 24 | 25 | # 绕过手机验证码:https://github.com/yanglbme/gitee-pages-action/issues/6#issuecomment-664812675 26 | - name: Build Gitee Pages 27 | uses: yanglbme/gitee-pages-action@main 28 | with: 29 | # Gitee 用户名 30 | gitee-username: ${{ secrets.GITEE_USERNAME }} 31 | # Gitee 密码 32 | gitee-password: ${{ secrets.GITEE_PASSWORD }} 33 | # Gitee 仓库 34 | gitee-repo: dgiot-dashboard/dgiot-dashboard 35 | # 要部署的分支 36 | branch: cdn-pages 37 | 38 | -------------------------------------------------------------------------------- /dgiot_dtu.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31229.75 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dgiot_dtu", "dgiot_dtu.csproj", "{5C46A923-4066-4CE8-89F2-3BAC47BF83ED}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BA722DFE-0FC7-4F15-8372-23B76A694135}" 9 | ProjectSection(SolutionItems) = preProject 10 | .editorconfig = .editorconfig 11 | EndProjectSection 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|x86 = Debug|x86 16 | Release|x86 = Release|x86 17 | EndGlobalSection 18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 19 | {5C46A923-4066-4CE8-89F2-3BAC47BF83ED}.Debug|x86.ActiveCfg = Debug|x86 20 | {5C46A923-4066-4CE8-89F2-3BAC47BF83ED}.Debug|x86.Build.0 = Debug|x86 21 | {5C46A923-4066-4CE8-89F2-3BAC47BF83ED}.Release|x86.ActiveCfg = Release|x86 22 | {5C46A923-4066-4CE8-89F2-3BAC47BF83ED}.Release|x86.Build.0 = Release|x86 23 | EndGlobalSection 24 | GlobalSection(SolutionProperties) = preSolution 25 | HideSolutionNode = FALSE 26 | EndGlobalSection 27 | GlobalSection(ExtensibilityGlobals) = postSolution 28 | SolutionGuid = {A9147353-3F42-4577-8EA2-2AE2B8715DBA} 29 | EndGlobalSection 30 | EndGlobal 31 | -------------------------------------------------------------------------------- /component/Http/HttpClientHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | // https://github.com/titanium-as/TitaniumAS.Opc.Client 6 | // https://github.com/chkr1011/MQTTnet 7 | namespace Dgiot_dtu 8 | { 9 | public class HttpClientHelper 10 | { 11 | private HttpClientHelper() 12 | { 13 | } 14 | 15 | private static HttpClientHelper instance; 16 | private static MainForm mainform = null; 17 | private static bool bIsRunning = false; 18 | private static bool bIsCheck = false; 19 | 20 | public static HttpClientHelper GetInstance() 21 | { 22 | if (instance == null) 23 | { 24 | instance = new HttpClientHelper(); 25 | } 26 | 27 | return instance; 28 | } 29 | 30 | public static void Start(bool bIsRunning, MainForm mainform) 31 | { 32 | HttpClientHelper.bIsRunning = bIsRunning; 33 | HttpClientHelper.mainform = mainform; 34 | } 35 | 36 | public static void Stop() 37 | { 38 | HttpClientHelper.bIsRunning = false; 39 | } 40 | 41 | public static void Check(bool isCheck, MainForm mainform) 42 | { 43 | HttpClientHelper.bIsCheck = isCheck; 44 | HttpClientHelper.mainform = mainform; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /utils/ConfigHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | using System.Configuration; 6 | 7 | namespace Dgiot_dtu 8 | { 9 | public class ConfigHelper 10 | { 11 | private ConfigHelper() 12 | { 13 | } 14 | 15 | private static ConfigHelper instance; 16 | private static Configuration config; 17 | 18 | public static ConfigHelper GetInstance() 19 | { 20 | if (instance == null) 21 | { 22 | instance = new ConfigHelper(); 23 | } 24 | 25 | return instance; 26 | } 27 | 28 | public static void Init(Configuration config) 29 | { 30 | ConfigHelper.config = config; 31 | } 32 | 33 | public static bool Check(string key) 34 | { 35 | return config.AppSettings.Settings[key] != null; 36 | } 37 | 38 | public static void SetConfig(string key, string value) 39 | { 40 | if (config.AppSettings.Settings[key] == null) 41 | { 42 | config.AppSettings.Settings.Add(key, value); 43 | } 44 | else 45 | { 46 | config.AppSettings.Settings[key].Value = value; 47 | } 48 | } 49 | 50 | public static string GetConfig(string key) 51 | { 52 | if (Check(key)) 53 | { 54 | return config.AppSettings.Settings[key].Value; 55 | } 56 | 57 | return ""; 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | using System.Reflection; 6 | using System.Runtime.InteropServices; 7 | 8 | // General Information about an assembly is controlled through the following 9 | // set of attributes. Change these attribute values to modify the information 10 | // associated with an assembly. 11 | [assembly: AssemblyTitle("dgiot_dtu")] 12 | [assembly: AssemblyDescription("dgiot_dtu")] 13 | [assembly: AssemblyConfiguration("")] 14 | [assembly: AssemblyCompany("dgiot Ltd")] 15 | [assembly: AssemblyProduct("dgiot_dtu")] 16 | [assembly: AssemblyCopyright("Copyright © dgiot Ltd 2021")] 17 | [assembly: AssemblyTrademark("")] 18 | [assembly: AssemblyCulture("")] 19 | 20 | // Setting ComVisible to false makes the types in this assembly not visible 21 | // to COM components. If you need to access a type in this assembly from 22 | // COM, set the ComVisible attribute to true on that type. 23 | [assembly: ComVisible(false)] 24 | 25 | // The following GUID is for the ID of the typelib if this project is exposed to COM 26 | [assembly: Guid("790e8dc9-9e65-4d33-8e58-1208a764e66a")] 27 | 28 | // Version information for an assembly consists of the following four values: 29 | // 30 | // Major Version 31 | // Minor Version 32 | // Build Number 33 | // Revision 34 | // 35 | // You can specify all the values or you can default the Build and Revision Numbers 36 | // by using the '*' as shown below: 37 | // [assembly: AssemblyVersion("1.0.*")] 38 | [assembly: AssemblyVersion("1.0.0.0")] 39 | [assembly: AssemblyFileVersion("1.0.0.0")] 40 | -------------------------------------------------------------------------------- /component/Opc/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | 3 | # SA1204: Static elements must appear before instance elements 4 | dotnet_diagnostic.SA1204.severity = none 5 | 6 | # SA1201: Elements must appear in the correct order 7 | dotnet_diagnostic.SA1201.severity = silent 8 | 9 | # SA1101: Prefix local calls with this 10 | dotnet_diagnostic.SA1101.severity = silent 11 | 12 | # Default severity for analyzer diagnostics with category 'StyleCop.CSharp.ReadabilityRules' 13 | dotnet_analyzer_diagnostic.category-StyleCop.CSharp.ReadabilityRules.severity = silent 14 | 15 | # SA1202: Elements must be ordered by access 16 | dotnet_diagnostic.SA1202.severity = silent 17 | 18 | # SA1614: Element parameter documentation must have text 19 | dotnet_diagnostic.SA1614.severity = silent 20 | 21 | # SA1403: File may only contain a single namespace 22 | dotnet_diagnostic.SA1403.severity = silent 23 | 24 | # SA1200: Using directives must be placed correctly 25 | dotnet_diagnostic.SA1200.severity = silent 26 | 27 | # SA1625: Element documentation must not be copied and pasted 28 | dotnet_diagnostic.SA1625.severity = silent 29 | 30 | # SA1401: Fields must be private 31 | dotnet_diagnostic.SA1401.severity = silent 32 | 33 | # SA1652: Enable XML documentation output 34 | dotnet_diagnostic.SA1652.severity = silent 35 | 36 | # SA1611: Element parameters must be documented 37 | dotnet_diagnostic.SA1611.severity = silent 38 | 39 | # SA1009: Closing parenthesis must be spaced correctly 40 | dotnet_diagnostic.SA1009.severity = silent 41 | 42 | # SA1214: Readonly fields must appear before non-readonly fields 43 | dotnet_diagnostic.SA1214.severity = none 44 | 45 | # SA1604: Element documentation must have summary 46 | dotnet_diagnostic.SA1604.severity = none 47 | 48 | # CS0252: 可能非有意的引用比较;左侧需要强制转换 49 | dotnet_diagnostic.CS0252.severity = none 50 | 51 | # Default severity for all analyzer diagnostics 52 | dotnet_analyzer_diagnostic.severity = none 53 | -------------------------------------------------------------------------------- /README-JP.md: -------------------------------------------------------------------------------- 1 | # dgiot_dtu 2 | 3 | [dgiot_dtu](http://dgiot-1253666439.cos.ap-shanghai-fsi.myqcloud.com/dgiot4.0/dgiot_dtu.zip) は、dgiot産業用IoT全体ソリューションのエッジ側にあるデスクトップユーティリティです。 4 | +複数のdgiot_dtumqtt / tcp / udp階層メソッドを介して企業イントラネットにデプロイでき、企業イントラネットとクラウドサーバー間の通信チャネルを開きます 5 | +企業イントラネットのシリアルポート/ PLC / OPC / BACNet / UI / Access / SqlServerなどの古い産業用システムからのデータをクラウドdgiotサービスに統合します 6 | + OPC / OPC / BACNet / UI / Access / SqlServerなどの自動スキャンツールを実現し、リモートの構築および運用と保守サービスを実現します 7 | +クラウドdgiotサーバーのチャネルと協力して、自動データ収集、プロトコル分析、データストレージ、および表示機能を実現します 8 | 9 | # インタラクティブプロセス 10 | 11 | ![dgiot_dtu_bus.png](http://dgiot-1253666439.cos.ap-shanghai-fsi.myqcloud.com/dgiot4.0/dgiot_dtu.png) 12 | 13 | # インターフェースプレビュー 14 | 15 | ![dgiot_dtu_demo.png](http://dgiot-1253666439.cos.ap-shanghai-fsi.myqcloud.com/dgiot4.0/dgiot_dtu_demo.png) 16 | 17 | # 動作環境 18 | dgiot_dtuは、[.net4.5](https://dgiot-dev-1306147891.cos.ap-nanjing.myqcloud.com/dgiot_dtu/dotNetFx45.rar)の動作環境に依存します。 19 | window7以下の環境に.net4.5をインストールする必要があります 20 | 21 | # コンパイラ環境 22 | dgiot_dtuは、[vc2019](https://dgiot-dev-1306147891.cos.ap-nanjing.myqcloud.com/dgiot_dtu/visualstudio2019.zip)を使用してコンパイルおよびデバッグします。 23 | 24 | 25 | # テスト環境 26 | 27 | ## OPCシミュレーションテスト 28 | + [opcserver](https://dgiot-dev-1306147891.cos.ap-nanjing.myqcloud.com/dgiot_dtu/MatrikonOPCSimulation.zip) 29 | 30 | + [opcclient](https://dgiot-dev-1306147891.cos.ap-nanjing.myqcloud.com/dgiot_dtu/MatrikonOPCSimulationV_1.5.zip) 31 | 32 | ##シリアルポートシミュレーションテスト 33 | 34 | + [仮想メーター](https://gitee.com/dgiiot/dgiot/wikis/%E5%BF%AB%E9%80%9F%E6%8E%A5%E5%85%A5/%E8%99%9A%E6%8B%9F%E7%94%B5%E8%A1%A8%E6%8E%A5%E5%85%A5/%E6%A6%82%E8%BF%B0) 35 | + [仮想modbus](https://gitee.com/dgiiot/dgiot/wikis/%E5%BF%AB%E9%80%9F%E6%8E%A5%E5%85%A5/Modbus%E8%AE%BE%E5%A4%87%E6%8E%A5%E5%85%A5/modbus%20slave%E9%85%8D%E7%BD%AE) 36 | 37 | ## Bacnetシミュレーションテスト 38 | 39 | ## PLCシミュレーションテスト 40 | 41 | ##制御シミュレーションテスト 42 | 43 | ##模擬テストにアクセスする 44 | 45 | ## SqlSeverシミュレーションテスト 46 | 47 | ## mqttブリッジテスト 48 | 49 | ## tcpブリッジテスト 50 | 51 | ## udpブリッジテスト 52 | -------------------------------------------------------------------------------- /utils/TimerHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Threading; 8 | 9 | namespace Dgiot_dtu 10 | { 11 | public class TimerHelper 12 | { 13 | private TimerHelper() 14 | { 15 | } 16 | 17 | private static TimerHelper instance; 18 | private static Dictionary timers = new Dictionary { }; 19 | 20 | public static TimerHelper GetInstance() 21 | { 22 | if (instance == null) 23 | { 24 | instance = new TimerHelper(); 25 | } 26 | 27 | return instance; 28 | } 29 | 30 | public static void Start(string key, object state = null, int period = 1000, int dueTime = Timeout.Infinite ) 31 | { 32 | if (timers.ContainsKey(key)) 33 | { 34 | try 35 | { 36 | timers[key].Change(0, 1000); 37 | } 38 | catch 39 | { 40 | } 41 | } 42 | 43 | TimerCallback callback = new TimerCallback(ReadValue); 44 | 45 | Timer timer = new Timer(callback, state, dueTime, period); 46 | timer.InitializeLifetimeService(); 47 | timers.Add(key, timer); 48 | } 49 | 50 | public static void Stop(string key) 51 | { 52 | if (timers.ContainsKey(key)) 53 | { 54 | try 55 | { 56 | timers[key].Change(0, 1000); 57 | } 58 | catch 59 | { 60 | } 61 | } 62 | } 63 | 64 | public static void ReadValue(object state) 65 | { 66 | LogHelper.Log("GetState " + state.ToString()); 67 | GC.Collect(); 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dgiot_dtu 2 | 3 | [dgiot_dtu](http://dgiot-1253666439.cos.ap-shanghai-fsi.myqcloud.com/dgiot4.0/dgiot_dtu.zip) is a desktop utility on the edge side of the dgiot industrial IoT overall solution 4 | + Can be deployed on the corporate intranet, through multiple dgiot_dtu mqtt/tcp/udp hierarchical methods, open up the communication channel between the corporate intranet and the cloud server 5 | + Converge data from old industrial systems such as serial port/PLC/OPC/BACNet/UI/Access/SqlServer in the corporate intranet into the cloud dgiot service 6 | + Realize automatic scanning tools for OPC/OPC/BACNet/UI/Access/SqlServer, etc. to realize remote construction and operation and maintenance services 7 | + Cooperate with the channel in the cloud dgiot server to realize automatic data collection, protocol analysis, data storage and display functions 8 | 9 | # Interactive process 10 | 11 | ![dgiot_dtu_bus.png](http://dgiot-1253666439.cos.ap-shanghai-fsi.myqcloud.com/dgiot4.0/dgiot_dtu.png) 12 | 13 | # Interface preview 14 | 15 | ![dgiot_dtu_demo.png](http://dgiot-1253666439.cos.ap-shanghai-fsi.myqcloud.com/dgiot4.0/dgiot_dtu_demo.png) 16 | 17 | # Operating environment 18 | dgiot_dtu depends on [.net4.5](https://dgiot-dev-1306147891.cos.ap-nanjing.myqcloud.com/dgiot_dtu/dotnetfx45.zip) operating environment, 19 | Need to install .net4.5 in the environment of window7 and below 20 | 21 | # Compiler Environment 22 | dgiot_dtu compile and debug with [vc2019](https://dgiot-dev-1306147891.cos.ap-nanjing.myqcloud.com/dgiot_dtu/visualstudio2019.zip) 23 | 24 | 25 | # test environment 26 | 27 | ## OPC simulation test 28 | + [opcserver](https://dgiot-dev-1306147891.cos.ap-nanjing.myqcloud.com/dgiot_dtu/MatrikonOPCSimulation.zip) 29 | 30 | + [opcclient](https://dgiot-dev-1306147891.cos.ap-nanjing.myqcloud.com/dgiot_dtu/MatrikonOPCSimulationV_1.5.zip) 31 | 32 | ## Serial port simulation test 33 | 34 | + [Virtual Meter](https://gitee.com/dgiiot/dgiot/wikis/%E5%BF%AB%E9%80%9F%E6%8E%A5%E5%85%A5/%E8%99%9A%E6%8B%9F%E7%94%B5%E8%A1%A8%E6%8E%A5%E5%85%A5/%E6%A6%82%E8%BF%B0) 35 | + [Virtual modbus](https://gitee.com/dgiiot/dgiot/wikis/%E5%BF%AB%E9%80%9F%E6%8E%A5%E5%85%A5/Modbus%E8%AE%BE%E5%A4%87%E6%8E%A5%E5%85%A5/modbus%20slave%E9%85%8D%E7%BD%AE) 36 | 37 | ## Bacnet simulation test 38 | 39 | ## PLC simulation test 40 | 41 | ## Control simulation test 42 | 43 | ## Access mock test 44 | 45 | ## SqlSever simulation test 46 | 47 | ## mqtt bridge test 48 | 49 | ## tcp bridge test 50 | 51 | ## udp bridge test 52 | -------------------------------------------------------------------------------- /README-RU.md: -------------------------------------------------------------------------------- 1 | # dgiot_dtu 2 | 3 | [dgiot_dtu](http://dgiot-1253666439.cos.ap-shanghai-fsi.myqcloud.com/dgiot4.0/dgiot_dtu.zip) - это настольная утилита на периферии общего решения dgiot Industrial IoT. 4 | + Может быть развернут в корпоративной интрасети с помощью нескольких иерархических методов dgiot_dtu mqtt / tcp / udp, открывая канал связи между корпоративной интрасетью и облачным сервером 5 | + Преобразование данных из старых промышленных систем, таких как последовательный порт / PLC / OPC / BACNet / UI / Access / SqlServer в корпоративной интрасети, в облачную службу dgiot 6 | + Реализовать инструменты автоматического сканирования для OPC / OPC / BACNet / UI / Access / SqlServer и т. Д. Для реализации удаленного строительства, эксплуатации и обслуживания 7 | + Сотрудничать с каналом в облачном сервере dgiot для реализации автоматического сбора данных, анализа протокола, хранения данных и функций отображения 8 | 9 | # Интерактивный процесс 10 | 11 | ![dgiot_dtu_bus.png](http://dgiot-1253666439.cos.ap-shanghai-fsi.myqcloud.com/dgiot4.0/dgiot_dtu.png) 12 | 13 | # Предварительный просмотр интерфейса 14 | 15 | ![dgiot_dtu_demo.png](http://dgiot-1253666439.cos.ap-shanghai-fsi.myqcloud.com/dgiot4.0/dgiot_dtu_demo.png) 16 | 17 | # Рабочая среда 18 | dgiot_dtu зависит от операционной среды [.net4.5](https://dgiot-dev-1306147891.cos.ap-nanjing.myqcloud.com/dgiot_dtu/dotNetFx45.rar), 19 | Необходимо установить .net4.5 в среде window7 и ниже 20 | 21 | # Среда компилятора 22 | dgiot_dtu компилируется и отлаживается с помощью [vc2019] (https://dgiot-dev-1306147891.cos.ap-nanjing.myqcloud.com/dgiot_dtu/visualstudio2019.zip) 23 | 24 | 25 | # тестовая среда 26 | 27 | ## Тест моделирования OPC 28 | + [opcserver](https://dgiot-dev-1306147891.cos.ap-nanjing.myqcloud.com/dgiot_dtu/MatrikonOPCSimulation.zip) 29 | 30 | + [opcclient](https://dgiot-dev-1306147891.cos.ap-nanjing.myqcloud.com/dgiot_dtu/MatrikonOPCSimulationV_1.5.zip) 31 | 32 | ## Тест имитации последовательного порта 33 | 34 | + [Виртуальный счетчик](https://gitee.com/dgiiot/dgiot/wikis/%E5%BF%AB%E9%80%9F%E6%8E%A5%E5%85%A5/%E8%99%9A%E6%8B%9F%E7%94%B5%E8%A1%A8%E6%8E%A5%E5%85%A5/%E6%A6%82%E8%BF%B0) 35 | + [Виртуальный Modbus](https://gitee.com/dgiiot/dgiot/wikis/%E5%BF%AB%E9%80%9F%E6%8E%A5%E5%85%A5/Modbus%E8%AE%BE%E5%A4%87%E6%8E%A5%E5%85%A5/modbus%20slave%E9%85%8D%E7%BD%AE) 36 | 37 | ## Тест имитации бакнета 38 | 39 | ## Тест моделирования ПЛК 40 | 41 | ## Тест имитации управления 42 | 43 | ## Пробный тест доступа 44 | 45 | ## Тест моделирования SqlSever 46 | 47 | ## Тест моста mqtt 48 | 49 | ## тест моста tcp 50 | 51 | ## тест моста udp 52 | -------------------------------------------------------------------------------- /syscfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /README-CN.md: -------------------------------------------------------------------------------- 1 | # dgiot_dtu 2 | 3 | [dgiot_dtu.exe](https://dgiot-release-1306147891.cos.ap-nanjing.myqcloud.com/v4.4.0/dgiot_dtu.exe) 是dgiot工业物联网整体解决方案中边缘侧的桌面实用工具 4 | + 可以部署在企业内网,通过多个dgiot_dtu的mqtt/tcp/udp等级联的方式,打通企业内网与云端服务器的通讯通道 5 | + 将企业内网中的串口/PLC/OPC/BACNet/UI/Access/SqlServer等老的工业系统中的数据汇聚到云端dgiot服务中 6 | + 对OPC/OPC/BACNet/UI/Access/SqlServer等实现自动扫描工具,实现远程施工与运维服务 7 | + 与云端dgiot服务器中的通道配合实现数据自动采集、协议解析,数据存储和展示功能 8 | 9 | # 交互流程 10 | 11 | ![dgiot_dtu_bus.png](http://dgiot-1253666439.cos.ap-shanghai-fsi.myqcloud.com/dgiot4.0/dgiot_dtu.png) 12 | 13 | # 界面预览 14 | 15 | ![dgiot_dtu_demo.png](http://dgiot-1253666439.cos.ap-shanghai-fsi.myqcloud.com/dgiot4.0/dgiot_dtu_demo.png) 16 | 17 | # 运行环境 18 | dgiot_dtu 依赖[.net4.5](https://dgiot-dev-1306147891.cos.ap-nanjing.myqcloud.com/dgiot_dtu/dotNetFx45.rar)运行环境, 19 | 在window7及以下环境下需要安装.net4.5 20 | 21 | # 编译环境 22 | dgiot_dtu 用[vc2019](https://dgiot-dev-1306147891.cos.ap-nanjing.myqcloud.com/dgiot_dtu/visualstudio2019.zip)编译调试 23 | 24 | # 数据映射 25 | 26 | | TreeNode | TAG | Text | Name | Level | Index | FullPath | Action | 27 | | -------- | ------ | ---- |----- | ----- | ----- | -------- | -------- | 28 | | OPCDA | Proctol | ItemId | Name | Type | {Id} | Path | API | 29 | 30 | 31 | ## 设备树Level映射到设备Type 32 | | TreeNode | Level0 | Level1 | Level2 | Level3 | Level4 | Level5 | Level6 | 33 | | -------- | ------- | ------- | ------- | ------- | ------- | ------ | ------- | 34 | | OPCDA | OPCDA | HOST | Service | Device | Group |Item | Property| 35 | 36 | 37 | # 测试环境 38 | 39 | ## OPC模拟测试 40 | + [opcserver](https://dgiot-dev-1306147891.cos.ap-nanjing.myqcloud.com/dgiot_dtu/MatrikonOPCSimulation.zip) 41 | 42 | + [opcclient](https://dgiot-dev-1306147891.cos.ap-nanjing.myqcloud.com/dgiot_dtu/MatrikonOPCSimulationV_1.5.zip) 43 | 44 | [OPC设备通过dgiot_dtu接入dgiot物联网平台实战教程](https://gitee.com/dgiiot/dgiot/wikis/%E5%BF%AB%E9%80%9F%E6%8E%A5%E5%85%A5/OPC%E8%AE%BE%E5%A4%87%E6%8E%A5%E5%85%A5/%E6%A6%82%E8%BF%B0) 45 | 46 | ## 串口模拟测试 47 | 48 | + [虚拟电表](https://gitee.com/dgiiot/dgiot/wikis/%E5%BF%AB%E9%80%9F%E6%8E%A5%E5%85%A5/%E8%99%9A%E6%8B%9F%E7%94%B5%E8%A1%A8%E6%8E%A5%E5%85%A5/%E6%A6%82%E8%BF%B0) 49 | + [虚拟modbus](https://gitee.com/dgiiot/dgiot/wikis/%E5%BF%AB%E9%80%9F%E6%8E%A5%E5%85%A5/Modbus%E8%AE%BE%E5%A4%87%E6%8E%A5%E5%85%A5/modbus%20slave%E9%85%8D%E7%BD%AE) 50 | 51 | [DLT645虚拟电表通过dgiot_dtu接入dgiot物联网平台实战教程](https://gitee.com/dgiiot/dgiot/wikis/%E5%BF%AB%E9%80%9F%E6%8E%A5%E5%85%A5/%E8%99%9A%E6%8B%9F%E7%94%B5%E8%A1%A8%E6%8E%A5%E5%85%A5/%E6%A6%82%E8%BF%B0) 52 | 53 | ## Bacnet模拟测试 54 | 55 | ## PLC模拟测试 56 | 57 | ## Control模拟测试 58 | 59 | ## Access模拟测试 60 | 61 | ## SqlSever模拟测试 62 | 63 | ## mqtt桥接测试 64 | 65 | ## tcp桥接测试 66 | 67 | ## udp桥接测试 68 | 69 | -------------------------------------------------------------------------------- /component/Opc/OPCUAHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Dgiot_dtu 6 | { 7 | using System; 8 | using System.Configuration; 9 | using System.IO; 10 | using System.Net; 11 | using System.Threading.Tasks; 12 | using Workstation.ServiceModel.Ua; 13 | using Workstation.ServiceModel.Ua.Channels; 14 | 15 | public class OPCUAHelper 16 | { 17 | private OPCUAHelper() 18 | { 19 | } 20 | 21 | private const string EndpointUrl = "opc.tcp://localhost:26543"; // the endpoint of the Workstation.NodeServer. 22 | private static ApplicationDescription localDescription; 23 | private static ICertificateStore certificateStore; 24 | private static OPCUAHelper instance; 25 | private static UaTcpSessionChannel channel; 26 | 27 | public static OPCUAHelper GetInstance() 28 | { 29 | if (instance == null) 30 | { 31 | instance = new OPCUAHelper(); 32 | } 33 | 34 | return instance; 35 | } 36 | 37 | public static void Start(KeyValueConfigurationCollection config) 38 | { 39 | Config(config); 40 | localDescription = new ApplicationDescription 41 | { 42 | ApplicationName = "Workstation.UaClient.UnitTests", 43 | ApplicationUri = $"urn:{Dns.GetHostName()}:Workstation.UaClient.UnitTests", 44 | ApplicationType = ApplicationType.Client 45 | }; 46 | 47 | certificateStore = new DirectoryStore( 48 | Path.Combine( 49 | Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), 50 | "Workstation.UaClient.UnitTests", 51 | "pki")); 52 | 53 | Task.Run(async () => { await ConnectAsync(); }); 54 | } 55 | 56 | public static void Stop() 57 | { 58 | if (channel != null) 59 | { 60 | Task.Run(async () => { await CloseAsync(); }); 61 | } 62 | } 63 | 64 | public static void Config(KeyValueConfigurationCollection config) 65 | { 66 | } 67 | 68 | private static async Task ConnectAsync() 69 | { 70 | channel = new UaTcpSessionChannel( 71 | localDescription, 72 | certificateStore, 73 | null, 74 | EndpointUrl); 75 | 76 | await channel.OpenAsync(); 77 | } 78 | 79 | private static async Task CloseAsync() 80 | { 81 | await channel.CloseAsync(); 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /component/Opc/app.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 51 | 58 | 59 | 60 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /utils/FileHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Dgiot_dtu 6 | { 7 | using System.Collections.Generic; 8 | using System.Configuration; 9 | using System.IO; 10 | using System.Windows.Forms; 11 | 12 | public class FileHelper 13 | { 14 | private FileHelper() 15 | { 16 | } 17 | 18 | private static FileHelper instance = null; 19 | private static OpenFileDialog openFileDialog = null; 20 | 21 | public static FileHelper GetInstance() 22 | { 23 | if (instance == null) 24 | { 25 | instance = new FileHelper(); 26 | } 27 | 28 | return instance; 29 | } 30 | 31 | public static void Init(OpenFileDialog openFileDialog) 32 | { 33 | FileHelper.openFileDialog = openFileDialog; 34 | } 35 | 36 | public static void Config(KeyValueConfigurationCollection config) 37 | { 38 | } 39 | 40 | public static List OpenFile() 41 | { 42 | List files = new List(); 43 | if (openFileDialog.ShowDialog() == DialogResult.OK) 44 | { 45 | string filename = openFileDialog.FileName; 46 | StreamReader sr = new StreamReader(filename); 47 | LogHelper.Log("filename " + filename); 48 | while (!sr.EndOfStream) 49 | { 50 | string line = sr.ReadLine(); 51 | files.Add(line); 52 | LogHelper.Log("line " + line); 53 | } 54 | 55 | sr.Close(); 56 | } 57 | 58 | return files; 59 | } 60 | 61 | /// 62 | /// 替换值 63 | /// 64 | /// txt等文件的路径 65 | /// 索引的字符串,定位到某一行 66 | /// 替换新值 67 | public static void ReplaceValue(string strFilePath, string strIndex, string newValue) 68 | { 69 | if (File.Exists(strFilePath)) 70 | { 71 | string[] lines = System.IO.File.ReadAllLines(strFilePath); 72 | for (int i = 0; i < lines.Length; i++) 73 | { 74 | if (lines[i].Contains(strIndex)) 75 | { 76 | string[] str = lines[i].Split('='); 77 | str[1] = newValue; 78 | lines[i] = str[0] + " = " + str[1]; 79 | } 80 | } 81 | File.WriteAllLines(strFilePath, lines); 82 | } 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /component/Udp/UDPClientHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Dgiot_dtu 6 | { 7 | using System; 8 | using System.Configuration; 9 | using System.Threading; 10 | using LiteNetLib; 11 | 12 | public class UDPClientHelper 13 | { 14 | private const bool V = false; 15 | private static UDPClientHelper instance; 16 | private static NetManager client = null; 17 | private static string server = "prod.iotn2n.com"; 18 | private static int port = 9050; 19 | private static bool bIsCheck = false; 20 | private static bool bAutoReconnect = false; 21 | 22 | public static UDPClientHelper GetInstance() 23 | { 24 | if (instance == null) 25 | { 26 | instance = new UDPClientHelper(); 27 | } 28 | 29 | return instance; 30 | } 31 | 32 | public static void Start() 33 | { 34 | Config(); 35 | 36 | if (bIsCheck) 37 | { 38 | if (client == null) 39 | { 40 | EventBasedNetListener listener = new EventBasedNetListener(); 41 | client = new NetManager(listener); 42 | client.Start(); 43 | client.Connect(server /* host ip or name */, port /* port */, "SomeConnectionKey" /* text key or NetDataWriter */); 44 | listener.NetworkReceiveEvent += (fromPeer, dataReader, deliveryMethod) => 45 | { 46 | Console.WriteLine("We got: {0}", dataReader.GetString(100 /* max length of string */)); 47 | dataReader.Recycle(); 48 | }; 49 | } 50 | 51 | while (!Console.KeyAvailable) 52 | { 53 | client.PollEvents(); 54 | Thread.Sleep(15); 55 | } 56 | } 57 | } 58 | 59 | public static void Stop() 60 | { 61 | if (client != null) 62 | { 63 | if (client.IsRunning) 64 | { 65 | client.Stop(); 66 | } 67 | } 68 | } 69 | 70 | public static void Config() 71 | { 72 | server = ConfigHelper.GetConfig("DgiotSever"); 73 | port = int.Parse(ConfigHelper.GetConfig("DgiotPort")); 74 | bIsCheck = DgiotHelper.StrTobool(ConfigHelper.GetConfig("UDPClientIsCheck")); 75 | bAutoReconnect = DgiotHelper.StrTobool(ConfigHelper.GetConfig("ReconnectChecked")); 76 | } 77 | 78 | public static void Write(byte[] data, int offset, int len) 79 | { 80 | if (bIsCheck) 81 | { 82 | } 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace dgiot_dtu.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// 一个强类型的资源类,用于查找本地化的字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// 返回此类使用的缓存的 ResourceManager 实例。 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("dgiot_dtu.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// 重写当前线程的 CurrentUICulture 属性,对 51 | /// 使用此强类型资源类的所有资源查找执行重写。 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 65 | /// 66 | internal static System.Drawing.Bitmap bridge { 67 | get { 68 | object obj = ResourceManager.GetObject("bridge", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /utils/IPScanHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Dgiot_dtu 6 | { 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Diagnostics; 10 | using System.IO; 11 | using System.Management; 12 | using System.Net; 13 | using System.Net.NetworkInformation; 14 | using System.Net.Sockets; 15 | using System.Runtime.InteropServices; 16 | using System.Security.Cryptography; 17 | using System.Text; 18 | using System.Threading; 19 | 20 | public class IPScanHelper 21 | { 22 | private static IPScanHelper instance = null; 23 | private IPScanHelper() 24 | { 25 | } 26 | public static IPScanHelper GetInstance() 27 | { 28 | if (instance == null) 29 | { 30 | instance = new IPScanHelper(); 31 | } 32 | 33 | return instance; 34 | } 35 | 36 | public static void IPScan() 37 | { 38 | var host = Dns.GetHostEntry(Dns.GetHostName()); 39 | List localIps = new List(); 40 | foreach (var ip in host.AddressList) 41 | { 42 | if (ip.AddressFamily == AddressFamily.InterNetwork) 43 | { 44 | using (Ping p = new Ping()) 45 | { 46 | PingReply pingReply = p.Send(ip, 100); 47 | if (pingReply.Status == IPStatus.Success) 48 | { 49 | PingIP(ip); 50 | } 51 | } 52 | } 53 | } 54 | } 55 | 56 | 57 | private static void PingIP(IPAddress ipa) 58 | { 59 | byte[] ipByte = ipa.GetAddressBytes(); 60 | string ipComm = ipByte[0] + "." + ipByte[1] + "." + ipByte[2] + "."; 61 | string pingIP = ""; 62 | 63 | for (int lastByte = 0; lastByte <= 255; lastByte++) 64 | { 65 | Ping ping = new Ping(); 66 | ping.PingCompleted += new PingCompletedEventHandler(PingComplete); 67 | pingIP = ipComm + lastByte; 68 | ping.SendAsync(pingIP, 2000, null); 69 | } 70 | } 71 | 72 | [DllImport(@"iphlpapi.dll", ExactSpelling = true)] 73 | private static extern int SendARP(int DestIP, int SrcIP, [Out] byte[] pMacAddr, ref int PhyAddrLen); 74 | private static void PingComplete(object sender, PingCompletedEventArgs e) 75 | { 76 | if (e.Reply.Status == IPStatus.Success) 77 | { 78 | IPAddress ip = e.Reply.Address; 79 | // this.listBox.Items.Add("IP:" + ip.ToString()); 80 | byte[] b = new byte[6]; 81 | int len = b.Length; 82 | int r = SendARP(BitConverter.ToInt32(ip.GetAddressBytes(), 0), 0, b, ref len); 83 | string mac = BitConverter.ToString(b, 0, 6); 84 | // this.listBox.Items.Add("Mac:" + mac); 85 | LogHelper.Log(mac + " " + ip.ToString()); 86 | } 87 | } 88 | 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /utils/LogHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | using System.Collections.Generic; 6 | using System.Configuration; 7 | 8 | namespace Dgiot_dtu 9 | { 10 | public class LogHelper 11 | { 12 | private LogHelper() 13 | { 14 | } 15 | 16 | public enum Level 17 | { 18 | DEBUG, 19 | INFO, 20 | NOTICE, 21 | WARN, 22 | ERROR, 23 | CRITICAL, 24 | ALERT, 25 | } 26 | 27 | private static List levelstring = new List 28 | { 29 | "DEBUG", 30 | "INFO", 31 | "NOTICE", 32 | "WARN", 33 | "ERROR", 34 | "CRITICAL", 35 | "ALERT" 36 | }; 37 | 38 | private static bool bDisplayHex = false; 39 | private static int loglevel = (int)Level.DEBUG; 40 | private static LogHelper instance; 41 | private static string login = string.Empty; 42 | private static MainForm mainform = null; 43 | 44 | public static LogHelper GetInstance() 45 | { 46 | if (instance == null) 47 | { 48 | instance = new LogHelper(); 49 | } 50 | 51 | return instance; 52 | } 53 | 54 | public static void Init(MainForm mainform, int level = 0) 55 | { 56 | LogHelper.mainform = mainform; 57 | loglevel = level; 58 | } 59 | 60 | public static List Levels() 61 | { 62 | return levelstring; 63 | } 64 | 65 | public static void SetLevel(int level = 0) 66 | { 67 | loglevel = level; 68 | } 69 | 70 | public static void Log(string text, int level = 0) 71 | { 72 | if (level >= loglevel) 73 | { 74 | mainform.Log(text); 75 | } 76 | } 77 | 78 | public static void Config() 79 | { 80 | bDisplayHex = DgiotHelper.StrTobool(ConfigHelper.GetConfig("DisplayHex")); 81 | } 82 | 83 | public static string Logdata(byte[] data, int offset, int len) 84 | { 85 | var line = bDisplayHex ? DgiotHelper.ToHexString(data, offset, len) : System.Text.Encoding.ASCII.GetString(data, offset, len); 86 | if (line.EndsWith("\r\n")) 87 | { 88 | line = line.Substring(0, line.Length - 2); 89 | } 90 | 91 | return line; 92 | } 93 | 94 | public static byte[] Payload(char[] data) 95 | { 96 | byte[] payload = System.Text.Encoding.UTF8.GetBytes(data); 97 | if (bDisplayHex) 98 | { 99 | byte[] hexPayload = DgiotHelper.ToHexBinary(payload); 100 | return hexPayload; 101 | } 102 | else 103 | { 104 | return payload; 105 | } 106 | } 107 | } 108 | } -------------------------------------------------------------------------------- /component/Opc/log4net.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /component/Printer/PrinterHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Dgiot_dtu 6 | { 7 | using System; 8 | using System.Configuration; 9 | using LitJson; 10 | using Spire.License; 11 | using Spire.Pdf; 12 | using dgiot_dtu.component.Printer; 13 | using System.Drawing.Printing; 14 | using static System.Drawing.Printing.PrinterSettings; 15 | using System.Text; 16 | 17 | internal partial class PrinterHelper 18 | { 19 | private static PrinterHelper instance = null; 20 | private static bool bIsRunning = false; 21 | private static PdfPrinter pdfPriner = null; 22 | private static BarCodePrinter barCodePriner = null; 23 | private static JsonData json = new JsonData(); 24 | private static string productId = string.Empty; 25 | private static string devAddr = string.Empty; 26 | 27 | public static PrinterHelper GetInstance() 28 | { 29 | if (instance == null) 30 | { 31 | instance = new PrinterHelper(); 32 | pdfPriner = new PdfPrinter(); 33 | } 34 | return instance; 35 | } 36 | 37 | public static void Start(KeyValueConfigurationCollection config, bool bIsRunning) 38 | { 39 | Config(config); 40 | PrinterHelper.bIsRunning = bIsRunning; 41 | } 42 | 43 | public static void Stop() 44 | { 45 | PrinterHelper.bIsRunning = false; 46 | } 47 | 48 | public static void Config(KeyValueConfigurationCollection config) 49 | { 50 | } 51 | 52 | public static JsonData GetJson() 53 | { 54 | return json; 55 | } 56 | 57 | private static void SetJson(JsonData jsonData) 58 | { 59 | json.Clear(); 60 | json = jsonData; 61 | } 62 | 63 | public static void PrintBarCode(JsonData jsonData) 64 | { 65 | SetJson(jsonData); 66 | barCodePriner = new BarCodePrinter(); 67 | barCodePriner.doPrint(); 68 | } 69 | 70 | public static void PrintPdf(JsonData jsonData) 71 | { 72 | SetJson(jsonData); 73 | pdfPriner.Print(); 74 | GetPrinter(); 75 | } 76 | 77 | public static void GetPrinter() 78 | { 79 | productId = ConfigHelper.GetConfig("MqttUserName"); 80 | devAddr = ConfigHelper.GetConfig("DtuAddr"); 81 | //sDefault = sys.print_machine;//获取设置的默认打印机 82 | JsonObject Printers = new JsonObject(); 83 | 84 | foreach (string sPrint in PrinterSettings.InstalledPrinters)//获取所有打印机名称 85 | { 86 | // LogHelper.Log("Printers: " + sPrint); 87 | Printers.Add(sPrint, sPrint); 88 | } 89 | StringCollection Printer = PrinterSettings.InstalledPrinters; 90 | 91 | string topic = "$dg/thing/" + productId + "/" + devAddr + "/firmware/report"; 92 | MqttClientHelper.Publish(topic, Encoding.UTF8.GetBytes(Printers.ToString())); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /component/Udp/UDPServerHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Dgiot_dtu 6 | { 7 | using System; 8 | using System.Configuration; 9 | using System.Threading; 10 | 11 | using LiteNetLib; 12 | using LiteNetLib.Utils; 13 | 14 | public class UDPServerHelper 15 | { 16 | private static UDPServerHelper instance; 17 | private static NetManager server = null; 18 | private static int port; 19 | private static bool bIsCheck = false; 20 | 21 | public static UDPServerHelper Instance 22 | { 23 | get 24 | { 25 | if (instance == null) 26 | { 27 | instance = new UDPServerHelper(); 28 | } 29 | 30 | return instance; 31 | } 32 | } 33 | 34 | public static void Start() 35 | { 36 | Config(); 37 | if (bIsCheck) 38 | { 39 | if (server == null) 40 | { 41 | EventBasedNetListener listener = new EventBasedNetListener(); 42 | server = new NetManager(listener); 43 | server.Start(port /* port */); 44 | listener.ConnectionRequestEvent += request => 45 | { 46 | if (server.ConnectedPeersCount < 10 /* max connections */) 47 | { 48 | request.AcceptIfKey("SomeConnectionKey"); 49 | } 50 | else 51 | { 52 | request.Reject(); 53 | } 54 | }; 55 | 56 | listener.PeerConnectedEvent += peer => 57 | { 58 | Console.WriteLine("We got connection: {0}", peer.EndPoint); // Show peer ip 59 | NetDataWriter writer = new NetDataWriter(); // Create writer class 60 | writer.Put("Hello client!"); // Put some string 61 | peer.Send(writer, DeliveryMethod.ReliableOrdered); // Send with reliability 62 | }; 63 | } 64 | 65 | while (!Console.KeyAvailable) 66 | { 67 | server.PollEvents(); 68 | Thread.Sleep(15); 69 | } 70 | } 71 | } 72 | 73 | public static void Stop() 74 | { 75 | if (server != null) 76 | { 77 | if (server.IsRunning) 78 | { 79 | server.Stop(); 80 | } 81 | } 82 | } 83 | 84 | public static void Config() 85 | { 86 | port = int.Parse(ConfigHelper.GetConfig("DgiotPort")); 87 | if (DgiotHelper.StrTobool(ConfigHelper.GetConfig("UDPClient_Checked")) && DgiotHelper.StrTobool(ConfigHelper.GetConfig("Bridge_Checked"))) 88 | { 89 | bIsCheck = true; 90 | } 91 | else 92 | { 93 | bIsCheck = false; 94 | } 95 | } 96 | 97 | public static void Write(byte[] data, int offset, int len) 98 | { 99 | if (bIsCheck) 100 | { 101 | } 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /component/Printer/Knova.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | using System; 6 | 7 | namespace Dgiot_dtu 8 | { 9 | public class Knova 10 | { 11 | public string type { get; set; } 12 | public string text { get; set; } 13 | public string fontFamily { get; set; } 14 | public int fontSize { get; set; } 15 | public int x { get; set; } 16 | public int y { get; set; } 17 | public int width { get; set; } 18 | public int height { get; set; } 19 | 20 | //像素转为100之一英寸 21 | public static int pxToInch(int px) 22 | { 23 | return (int)(px * 100 / 96); 24 | } 25 | 26 | //英寸换算到厘米 27 | public decimal FromInchToCM(decimal inch) 28 | { 29 | return Math.Round((System.Convert.ToDecimal((inch / 100)) * System.Convert.ToDecimal(2.5400)), 2); //Math.Round取两位小数 30 | } 31 | 32 | // 毫米转换成百分之一英寸 33 | public static int GetInch(float mm) 34 | { 35 | return (int)(mm * 0.0393700787402 * 100); 36 | } 37 | } 38 | 39 | //pt 磅或者点数,是point简称 1磅=0.03527厘米=1/72英寸 40 | //inch英寸, 1英寸=2.54厘米=96像素(分辨率为96dpi) 41 | //px 像素, pixel的简称(本表参照显示器96dbi显示进行换算,像素不能出现小数点,一般是取小显示 42 | //--------------------------------------------------- 43 | //|中文字号 | 英文字号(磅)| 毫米 | 像素 | 44 | //--------------------------------------------------- 45 | //| 1英寸 | 72pt | 25.30mm | 95.6px | 46 | //--------------------------------------------------- 47 | //| 大特号 | 63pt | 22.14mm | 83.7px | 48 | //--------------------------------------------------- 49 | //| 特号 | 54pt | 18.97mm | 71.7px | 50 | //--------------------------------------------------- 51 | //| 初号 | 42pt | 14.82mm | 56px | 52 | //--------------------------------------------------- 53 | //| 小初 | 36pt | 12.70mm | 48px | 54 | //--------------------------------------------------- 55 | //| 一号 | 26pt | 9.17mm | 34.7px | 56 | //--------------------------------------------------- 57 | //| 小一 | 24pt | 8.47mm | 32px | 58 | //--------------------------------------------------- 59 | //| 二号 | 22pt | 7.76mm | 29.3px | 60 | //--------------------------------------------------- 61 | //| 小二 | 18pt | 6.35mm | 24px | 62 | //--------------------------------------------------- 63 | //| 三号 | 16pt | 5.64mm | 21.3px | 64 | //--------------------------------------------------- 65 | //| 小三 | 15pt | 5.29mm | 20px | 66 | //--------------------------------------------------- 67 | //| 四号 | 14pt | 4.94mm | 18.7px | 68 | //--------------------------------------------------- 69 | //| 小四 | 12pt | 4.23mm | 16px | 70 | //--------------------------------------------------- 71 | //| 五号 | 10.5pt | 3.70mm | 14px | 72 | //--------------------------------------------------- 73 | //| 小五 | 9pt | 3.18mm | 12px | 74 | //--------------------------------------------------- 75 | //| 六号 | 7.5pt | 2.56mm | 10px | 76 | //--------------------------------------------------- 77 | //| 小六 | 6.5pt | 2.29mm | 8.7px | 78 | //--------------------------------------------------- 79 | //| 七号 | 5.5pt | 1.94mm | 7.3px | 80 | //--------------------------------------------------- 81 | //| 八号 | 5pt | 1.76mm | 6.7px | 82 | //--------------------------------------------------- 83 | 84 | } -------------------------------------------------------------------------------- /utils/JsonArray.cs: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------- 2 | // 3 | // Copyright (c) PlaceholderCompany. All rights reserved. 4 | // 5 | // Nathan Totten (ntotten.com), Jim Zimmerman (jimzimmerman.com) and Prabir Shrestha (prabir.me) 6 | // https://github.com/facebook-csharp-sdk/simple-json 7 | //----------------------------------------------------------------------- 8 | 9 | // VERSION: 0.38.0 10 | 11 | // NOTE: uncomment the following line to make SimpleJson class internal. 12 | // #define SIMPLE_JSON_INTERNAL 13 | 14 | // NOTE: uncomment the following line to make JsonArray and JsonObject class internal. 15 | // #define SIMPLE_JSON_OBJARRAYINTERNAL 16 | 17 | // NOTE: uncomment the following line to enable dynamic support. 18 | // #define SIMPLE_JSON_DYNAMIC 19 | 20 | // NOTE: uncomment the following line to enable DataContract support. 21 | // #define SIMPLE_JSON_DATACONTRACT 22 | 23 | // NOTE: uncomment the following line to enable IReadOnlyCollection and IReadOnlyList support. 24 | // #define SIMPLE_JSON_READONLY_COLLECTIONS 25 | 26 | // NOTE: uncomment the following line to disable linq expressions/compiled lambda (better performance) instead of method.invoke(). 27 | // define if you are using .net framework <= 3.0 or < WP7.5 28 | // #define SIMPLE_JSON_NO_LINQ_EXPRESSION 29 | 30 | // NOTE: uncomment the following line if you are compiling under Window Metro style application/library. 31 | // usually already defined in properties 32 | // #define NETFX_CORE; 33 | 34 | // If you are targetting WinStore, WP8 and NET4.5+ PCL make sure to #define SIMPLE_JSON_TYPEINFO; 35 | 36 | // original json parsing code from http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html 37 | #if NETFX_CORE 38 | #define SIMPLE_JSON_TYPEINFO 39 | #endif 40 | 41 | using System; 42 | using System.CodeDom.Compiler; 43 | using System.Collections; 44 | using System.Collections.Generic; 45 | #if !SIMPLE_JSON_NO_LINQ_EXPRESSION 46 | using System.Linq.Expressions; 47 | #endif 48 | using System.ComponentModel; 49 | using System.Diagnostics.CodeAnalysis; 50 | #if SIMPLE_JSON_DYNAMIC 51 | using System.Dynamic; 52 | #endif 53 | using System.Globalization; 54 | using System.Reflection; 55 | using System.Runtime.Serialization; 56 | using System.Text; 57 | using Dgiot_dtu.Reflection; 58 | 59 | // ReSharper disable LoopCanBeConvertedToQuery 60 | // ReSharper disable RedundantExplicitArrayCreation 61 | // ReSharper disable SuggestUseVarKeywordEvident 62 | namespace Dgiot_dtu 63 | { 64 | /// 65 | /// Represents the json array. 66 | /// 67 | [GeneratedCode("simple-json", "1.0.0")] 68 | [EditorBrowsable(EditorBrowsableState.Never)] 69 | #if SIMPLE_JSON_OBJARRAYINTERNAL 70 | internal 71 | #else 72 | public 73 | #endif 74 | class JsonArray : List 75 | { 76 | /// 77 | /// Initializes a new instance of the class. 78 | /// 79 | public JsonArray() 80 | { 81 | } 82 | 83 | /// 84 | /// Initializes a new instance of the class. 85 | /// 86 | /// The capacity of the json array. 87 | public JsonArray(int capacity) : base(capacity) 88 | { 89 | } 90 | 91 | /// 92 | /// The json representation of the array. 93 | /// 94 | /// The json representation of the array. 95 | public override string ToString() 96 | { 97 | return SimpleJson.SerializeObject(this) ?? string.Empty; 98 | } 99 | } 100 | } 101 | 102 | // ReSharper restore LoopCanBeConvertedToQuery 103 | // ReSharper restore RedundantExplicitArrayCreation 104 | // ReSharper restore SuggestUseVarKeywordEvident 105 | -------------------------------------------------------------------------------- /component/sqlite/ManagerInfoDal.cs: -------------------------------------------------------------------------------- 1 | //using System; 2 | //using System.Collections.Generic; 3 | //using System.Data; 4 | //using System.Data.SQLite; 5 | //using System.Linq; 6 | //using System.Text; 7 | //using System.Threading.Tasks; 8 | 9 | //namespace dgiot_dtu.component.sqlite 10 | //{ 11 | // class ManagerInfoDal 12 | // { 13 | // private int MId; 14 | // private string MName; 15 | // private string MPwd; 16 | // private int MType; 17 | 18 | // /// 19 | // /// select 查询 获取结果集 20 | // /// 21 | // /// 22 | // public List GetList() 23 | // { 24 | // //构造要查询的sql语句 25 | // string sql = "select * from ManagerInfo"; 26 | // //使用helper进行查询,得到结果 27 | // DataTable dt = SqliteHelper.GetDataTable(sql); 28 | // //将dt中的数据转存到list中 29 | // List list = new List(); 30 | // foreach (DataRow row in dt.Rows) 31 | // { 32 | // list.Add(new ManagerInfoDal() 33 | // { 34 | // MId = Convert.ToInt32(row["mid"]), 35 | // MName = row["mname"].ToString(), 36 | // MPwd = row["mpwd"].ToString(), 37 | // MType = Convert.ToInt32(row["mtype"]) 38 | // }); 39 | // } 40 | // //返回集合类型 41 | // return list; 42 | // } 43 | 44 | // /// 45 | // /// 插入数据 46 | // /// 47 | // /// ManagerInfo类型对象 48 | // /// 49 | // public int Insert(ManagerInfoDal mi) 50 | // { 51 | // //构造insert语句 52 | // string sql = "insert into ManagerInfo(mname, mpwd,mtype) values(@name, @pwd, @type)"; 53 | // //构造sql语句参数 54 | // SQLiteParameter[] ps = { //使用数组初始化器 55 | // new SQLiteParameter("@name", mi.MName), 56 | // //将密码进行md5加密 57 | // new SQLiteParameter("@pwd", mi.MPwd), 58 | // new SQLiteParameter("@type", mi.MType) 59 | // }; 60 | // //执行插入操作 61 | // return SqliteHelper.ExecuteNonQuery(sql); 62 | // } 63 | 64 | // /// 65 | // /// 修改管理员,特别注意:密码 66 | // /// 67 | // /// 68 | // /// 69 | // public int Update(ManagerInfoDal mi) 70 | // { 71 | // //为什么要进行密码的判断: 72 | // //答:因为密码值是经过md5加密存储的,当修改时,需要判断用户是否改了密码,如果没有改,则不变,如果改了,则重新进行md5加密 73 | 74 | // //定义参数集合,可以动态添加元素 75 | // List listPs = new List(); 76 | // //构造update的sql语句 77 | // string sql = "update ManagerInfo set mname=@name"; 78 | // listPs.Add(new SQLiteParameter("@name", mi.MName)); 79 | // //判断是否修改密码 80 | // if (!mi.MPwd.Equals("这是原来的密码吗")) 81 | // { 82 | // sql += ",mpwd=@pwd"; 83 | // listPs.Add(new SQLiteParameter("@pwd", mi.MPwd)); 84 | // } 85 | // //继续拼接语句 86 | // sql += ",mtype=@type where mid=@id"; 87 | // listPs.Add(new SQLiteParameter("@type", mi.MType)); 88 | // listPs.Add(new SQLiteParameter("@id", mi.MId)); 89 | 90 | // //执行语句并返回结果 91 | // return SqliteHelper.ExecuteNonQuery(sql); 92 | // } 93 | 94 | // /// 95 | // /// 根据编号删除管理员 96 | // /// 97 | // /// 98 | // /// 99 | // public int Delete(int id) 100 | // { 101 | // //构造删除的sql语句 102 | // string sql = "delete from ManagerInfo where mid=@id"; 103 | // //根据语句构造参数 104 | // SQLiteParameter p = new SQLiteParameter("@id", id); 105 | // //执行操作 106 | // return SqliteHelper.ExecuteNonQuery(sql); 107 | // } 108 | // } 109 | //} -------------------------------------------------------------------------------- /.github/workflows/build_slim_packages.yaml: -------------------------------------------------------------------------------- 1 | name: Build slim packages 2 | 3 | on: 4 | push: 5 | tags: 6 | - v* 7 | - e* 8 | pull_request: 9 | workflow_dispatch: 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-20.04 14 | 15 | strategy: 16 | matrix: 17 | erl_otp: 18 | - erl23.2.7.2-emqx-2 19 | os: 20 | - ubuntu20.04 21 | - centos7 22 | 23 | container: emqx/build-env:${{ matrix.erl_otp }}-${{ matrix.os }} 24 | 25 | steps: 26 | - uses: actions/checkout@v1 27 | - name: prepare 28 | run: | 29 | if make emqx-ee --dry-run > /dev/null 2>&1; then 30 | echo "https://ci%40emqx.io:${{ secrets.CI_GIT_TOKEN }}@github.com" > $HOME/.git-credentials 31 | git config --global credential.helper store 32 | echo "${{ secrets.CI_GIT_TOKEN }}" >> ./scripts/git-token 33 | echo "EMQX_NAME=emqx-ee" >> $GITHUB_ENV 34 | else 35 | echo "EMQX_NAME=emqx" >> $GITHUB_ENV 36 | fi 37 | - name: build zip packages 38 | run: make ${EMQX_NAME}-zip 39 | - name: build deb/rpm packages 40 | run: make ${EMQX_NAME}-pkg 41 | - uses: actions/upload-artifact@v1 42 | if: failure() 43 | with: 44 | name: rebar3.crashdump 45 | path: ./rebar3.crashdump 46 | - name: pakcages test 47 | run: | 48 | export CODE_PATH=$GITHUB_WORKSPACE 49 | .ci/build_packages/tests.sh 50 | - uses: actions/upload-artifact@v2 51 | with: 52 | name: ${{ matrix.os }} 53 | path: _packages/**/*.zip 54 | 55 | mac: 56 | runs-on: macos-10.15 57 | 58 | strategy: 59 | matrix: 60 | erl_otp: 61 | - 23.2.7.2-emqx-2 62 | 63 | steps: 64 | - uses: actions/checkout@v1 65 | - name: prepare 66 | run: | 67 | if make emqx-ee --dry-run > /dev/null 2>&1; then 68 | echo "https://ci%40emqx.io:${{ secrets.CI_GIT_TOKEN }}@github.com" > $HOME/.git-credentials 69 | git config --global credential.helper store 70 | echo "${{ secrets.CI_GIT_TOKEN }}" >> ./scripts/git-token 71 | echo "EMQX_NAME=emqx-ee" >> $GITHUB_ENV 72 | else 73 | echo "EMQX_NAME=emqx" >> $GITHUB_ENV 74 | fi 75 | - name: prepare 76 | run: | 77 | brew update 78 | brew install curl zip unzip gnu-sed kerl unixodbc freetds 79 | echo "/usr/local/bin" >> $GITHUB_PATH 80 | git config --global credential.helper store 81 | - uses: actions/cache@v2 82 | id: cache 83 | with: 84 | path: ~/.kerl 85 | key: erl${{ matrix.erl_otp }}-macos10.15 86 | - name: build erlang 87 | if: steps.cache.outputs.cache-hit != 'true' 88 | timeout-minutes: 60 89 | env: 90 | KERL_BUILD_BACKEND: git 91 | OTP_GITHUB_URL: https://github.com/emqx/otp 92 | run: | 93 | kerl update releases 94 | kerl build ${{ matrix.erl_otp }} 95 | kerl install ${{ matrix.erl_otp }} $HOME/.kerl/${{ matrix.erl_otp }} 96 | - name: build 97 | run: | 98 | . $HOME/.kerl/${{ matrix.erl_otp }}/activate 99 | make ensure-rebar3 100 | sudo cp rebar3 /usr/local/bin/rebar3 101 | make ${EMQX_NAME}-zip 102 | - uses: actions/upload-artifact@v1 103 | if: failure() 104 | with: 105 | name: rebar3.crashdump 106 | path: ./rebar3.crashdump 107 | - name: test 108 | run: | 109 | pkg_name=$(basename _packages/${EMQX_NAME}/emqx-*.zip) 110 | unzip -q _packages/${EMQX_NAME}/$pkg_name 111 | gsed -i '/emqx_telemetry/d' ./emqx/data/loaded_plugins 112 | ./emqx/bin/emqx start || cat emqx/log/erlang.log.1 113 | ready='no' 114 | for i in {1..10}; do 115 | if curl -fs 127.0.0.1:18083 > /dev/null; then 116 | ready='yes' 117 | break 118 | fi 119 | sleep 1 120 | done 121 | if [ "$ready" != "yes" ]; then 122 | echo "Timed out waiting for emqx to be ready" 123 | cat emqx/log/erlang.log.1 124 | exit 1 125 | fi 126 | ./emqx/bin/emqx_ctl status 127 | ./emqx/bin/emqx stop 128 | rm -rf emqx 129 | - uses: actions/upload-artifact@v2 130 | with: 131 | name: macos 132 | path: _packages/**/*.zip 133 | -------------------------------------------------------------------------------- /component/Printer/PdfPrinter.cs: -------------------------------------------------------------------------------- 1 | using Spire.Pdf; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Drawing; 5 | using System.Drawing.Printing; 6 | using System.Linq; 7 | using System.Net; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace dgiot_dtu.component.Printer 12 | { 13 | class PdfPrinter 14 | { 15 | /*页面打印委托*/ 16 | public delegate void DoPrintDelegate(Graphics g, ref bool HasMorePage); 17 | 18 | PrintDocument iSPriner = null; 19 | bool m_bUseDefaultPaperSetting = false; 20 | 21 | DoPrintDelegate DoPrint = null; 22 | 23 | public PdfPrinter() 24 | { 25 | iSPriner = new PrintDocument(); 26 | iSPriner.PrintPage += new PrintPageEventHandler 27 | (this.OnPrintPage); 28 | } 29 | 30 | public void Dispose() 31 | { 32 | if (iSPriner != null) iSPriner.Dispose(); 33 | iSPriner = null; 34 | 35 | } 36 | 37 | /*设置打印机名*/ 38 | public string PrinterName 39 | { 40 | get { return iSPriner.PrinterSettings.PrinterName; } 41 | set { iSPriner.PrinterSettings.PrinterName = value; } 42 | } 43 | 44 | /*设置打印文档名*/ 45 | public string DocumentName 46 | { 47 | get { return iSPriner.DocumentName; } 48 | set { iSPriner.DocumentName = value; } 49 | } 50 | 51 | /*设置是否使用缺省纸张*/ 52 | public bool UseDefaultPaper 53 | { 54 | get { return m_bUseDefaultPaperSetting; } 55 | set 56 | { 57 | m_bUseDefaultPaperSetting = value; 58 | if (!m_bUseDefaultPaperSetting) 59 | { 60 | //如果不适用缺省纸张则创建一个自定义纸张,注意,必须使用这个版本的构造函数才是自定义的纸张 61 | PaperSize ps = new PaperSize("Custom Size 1", 827, 1169); 62 | //将缺省的纸张设置为新建的自定义纸张 63 | iSPriner.DefaultPageSettings.PaperSize = ps; 64 | } 65 | } 66 | } 67 | 68 | /*纸张宽度 单位定义为毫米mm*/ 69 | public float PaperWidth 70 | { 71 | get { return iSPriner.DefaultPageSettings.PaperSize.Width / 100f * 25.4f; } 72 | set 73 | { 74 | //注意,只有自定义纸张才能修改该属性,否则将导致异常 75 | if (iSPriner.DefaultPageSettings.PaperSize.Kind == PaperKind.Custom) 76 | iSPriner.DefaultPageSettings.PaperSize.Width = (int)(value / 25.4 * 100); 77 | } 78 | } 79 | 80 | /*纸张高度 单位定义为毫米mm*/ 81 | public float PaperHeight 82 | { 83 | get { return (int)iSPriner.PrinterSettings.DefaultPageSettings.PaperSize.Height / 100f * 25.4f; } 84 | set 85 | { 86 | //注意,只有自定义纸张才能修改该属性,否则将导致异常 87 | if (iSPriner.DefaultPageSettings.PaperSize.Kind == PaperKind.Custom) 88 | iSPriner.DefaultPageSettings.PaperSize.Height = (int)(value / 25.4 * 100); 89 | } 90 | } 91 | 92 | /*页面打印*/ 93 | private void OnPrintPage(object sender, PrintPageEventArgs ev) 94 | { 95 | //调用委托绘制打印内容 96 | if (DoPrint != null) 97 | { 98 | bool bHadMore = false; 99 | DoPrint(ev.Graphics, ref bHadMore); 100 | ev.HasMorePages = bHadMore; 101 | } 102 | else 103 | { 104 | PdfDocument doc = new PdfDocument(); 105 | doc.LoadFromFile(@"D:\1.pdf"); 106 | doc.PrintDocument.Print(); 107 | } 108 | } 109 | 110 | /* 开始打印*/ 111 | public void Print(DoPrintDelegate doPrint) 112 | { 113 | DoPrint = doPrint; 114 | this.iSPriner.Print(); 115 | } 116 | 117 | /* 开始打印*/ 118 | public void Print() 119 | { 120 | this.iSPriner.Print(); 121 | } 122 | 123 | // public static Image GetImagetable(string url, out string imageStrCookie) 124 | public static Image GetPdf(string url) 125 | { 126 | // HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://121.5.171.21/dgiot_file/device/topo/"); 127 | HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 128 | request.Method = "GET"; 129 | WebResponse response = request.GetResponse(); 130 | return Image.FromStream(response.GetResponseStream()); 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /component/SerialPort/SerialPortHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Dgiot_dtu 6 | { 7 | using System; 8 | using System.IO.Ports; 9 | 10 | public class SerialPortHelper 11 | { 12 | private SerialPortHelper() 13 | { 14 | } 15 | 16 | private static SerialPort port = null; 17 | private static SerialPortHelper instance = null; 18 | private static bool bIsRunning = false; 19 | private static string portName; 20 | private static int baudRate; 21 | private static Parity parity; 22 | private static int dataBits; 23 | private static StopBits stopBits; 24 | 25 | public static SerialPortHelper GetInstance() 26 | { 27 | if (instance == null) 28 | { 29 | instance = new SerialPortHelper(); 30 | } 31 | 32 | return instance; 33 | } 34 | 35 | public static void Start() 36 | { 37 | Config(); 38 | 39 | if (bIsRunning) 40 | { 41 | Stop(); 42 | } 43 | 44 | try 45 | { 46 | port = new SerialPort(portName, baudRate, parity, dataBits, stopBits); 47 | port.DataReceived += Received; 48 | port.ReceivedBytesThreshold = 1; 49 | port.Open(); 50 | LogHelper.Log(@"Open open port " + portName); 51 | } 52 | catch (Exception) 53 | { 54 | LogHelper.Log(@"Couldn't open port " + portName); 55 | return; 56 | } 57 | 58 | bIsRunning = true; 59 | } 60 | 61 | public static void Stop() 62 | { 63 | if (port != null) 64 | { 65 | if (port.IsOpen) 66 | { 67 | bIsRunning = false; 68 | port.Close(); 69 | } 70 | } 71 | } 72 | 73 | public static void Config() 74 | { 75 | portName = ConfigHelper.GetConfig("SerialPort"); 76 | baudRate = int.Parse(ConfigHelper.GetConfig("BaudRate")); 77 | dataBits = int.Parse(ConfigHelper.GetConfig("DataBits")); 78 | parity = StrToParity(ConfigHelper.GetConfig("Parity")); 79 | stopBits = StrToStopBits(ConfigHelper.GetConfig("StopBits")); 80 | } 81 | 82 | public static void Write(byte[] payload, int offset, int len) 83 | { 84 | if (port != null && port.IsOpen) 85 | { 86 | // LogHelper.Log("SerialPort Send: [" + LogHelper.Logdata(payload, 0, len) + "]"); 87 | port.Write(payload, offset, len); 88 | } 89 | } 90 | 91 | private static void Received(object sender, SerialDataReceivedEventArgs e) 92 | { 93 | var rxlen = port.BytesToRead; 94 | var data = new byte[rxlen]; 95 | port.Read(data, 0, rxlen); 96 | LogHelper.Log("SerialPort Recv: [" + LogHelper.Logdata(data, 0, rxlen) + "]"); 97 | TcpClientHelper.Write(data, 0, rxlen); 98 | } 99 | 100 | private static StopBits StrToStopBits(string s) 101 | { 102 | if (s == "1") 103 | { 104 | return StopBits.One; 105 | } 106 | 107 | if (s == "2") 108 | { 109 | return StopBits.Two; 110 | } 111 | 112 | if (s == "1.5") 113 | { 114 | return StopBits.OnePointFive; 115 | } 116 | 117 | return StopBits.None; 118 | } 119 | 120 | private static Parity StrToParity(string s) 121 | { 122 | if (s == "None") 123 | { 124 | return Parity.None; 125 | } 126 | 127 | if (s == "Odd ") 128 | { 129 | return Parity.Odd; 130 | } 131 | 132 | if (s == "Even") 133 | { 134 | return Parity.Even; 135 | } 136 | 137 | if (s == "Mark") 138 | { 139 | return Parity.Mark; 140 | } 141 | 142 | if (s == "Space") 143 | { 144 | return Parity.Space; 145 | } 146 | 147 | return Parity.None; 148 | } 149 | 150 | public static string[] GetPorts() 151 | { 152 | return SerialPort.GetPortNames(); 153 | } 154 | } 155 | } -------------------------------------------------------------------------------- /.github/workflows/.gitlint: -------------------------------------------------------------------------------- 1 | # Edit this file as you like. 2 | # 3 | # All these sections are optional. Each section with the exception of [general] represents 4 | # one rule and each key in it is an option for that specific rule. 5 | # 6 | # Rules and sections can be referenced by their full name or by id. For example 7 | # section "[body-max-line-length]" could also be written as "[B1]". Full section names are 8 | # used in here for clarity. 9 | # 10 | [general] 11 | # Ignore certain rules, this example uses both full name and id 12 | ignore=title-trailing-punctuation, T1, T2, T3, T4, T5, T6, T8, B1, B2, B3, B4, B5, B6, B7, B8 13 | 14 | # verbosity should be a value between 1 and 3, the commandline -v flags take precedence over this 15 | # verbosity = 2 16 | 17 | # By default gitlint will ignore merge, revert, fixup and squash commits. 18 | # ignore-merge-commits=true 19 | # ignore-revert-commits=true 20 | # ignore-fixup-commits=true 21 | # ignore-squash-commits=true 22 | 23 | # Ignore any data send to gitlint via stdin 24 | # ignore-stdin=true 25 | 26 | # Fetch additional meta-data from the local repository when manually passing a 27 | # commit message to gitlint via stdin or --commit-msg. Disabled by default. 28 | # staged=true 29 | 30 | # Enable debug mode (prints more output). Disabled by default. 31 | # debug=true 32 | 33 | # Enable community contributed rules 34 | # See http://jorisroovers.github.io/gitlint/contrib_rules for details 35 | # contrib=contrib-title-conventional-commits,CC1 36 | 37 | # Set the extra-path where gitlint will search for user defined rules 38 | # See http://jorisroovers.github.io/gitlint/user_defined_rules for details 39 | # extra-path=examples/ 40 | 41 | # This is an example of how to configure the "title-max-length" rule and 42 | # set the line-length it enforces to 80 43 | # [title-max-length] 44 | # line-length=50 45 | 46 | # Conversely, you can also enforce minimal length of a title with the 47 | # "title-min-length" rule: 48 | # [title-min-length] 49 | # min-length=5 50 | 51 | # [title-must-not-contain-word] 52 | # Comma-separated list of words that should not occur in the title. Matching is case 53 | # insensitive. It's fine if the keyword occurs as part of a larger word (so "WIPING" 54 | # will not cause a violation, but "WIP: my title" will. 55 | # words=wip 56 | 57 | [title-match-regex] 58 | # python-style regex that the commit-msg title must match 59 | # Note that the regex can contradict with other rules if not used correctly 60 | # (e.g. title-must-not-contain-word). 61 | regex=^(feat|fix|docs|style|refactor|test|build|ci|revert|chore|perf)(\(.+\))*: .+ 62 | 63 | # [body-max-line-length] 64 | # line-length=72 65 | 66 | # [body-min-length] 67 | # min-length=5 68 | 69 | # [body-is-missing] 70 | # Whether to ignore this rule on merge commits (which typically only have a title) 71 | # default = True 72 | # ignore-merge-commits=false 73 | 74 | # [body-changed-file-mention] 75 | # List of files that need to be explicitly mentioned in the body when they are changed 76 | # This is useful for when developers often erroneously edit certain files or git submodules. 77 | # By specifying this rule, developers can only change the file when they explicitly reference 78 | # it in the commit message. 79 | # files=gitlint/rules.py,README.md 80 | 81 | # [body-match-regex] 82 | # python-style regex that the commit-msg body must match. 83 | # E.g. body must end in My-Commit-Tag: foo 84 | # regex=My-Commit-Tag: foo$ 85 | 86 | # [author-valid-email] 87 | # python-style regex that the commit author email address must match. 88 | # For example, use the following regex if you only want to allow email addresses from foo.com 89 | # regex=[^@]+@foo.com 90 | 91 | [ignore-by-title] 92 | # Ignore certain rules for commits of which the title matches a regex 93 | # E.g. Match commit titles that start with "Release" 94 | # regex=^Release(.*) 95 | 96 | # Ignore certain rules, you can reference them by their id or by their full name 97 | # Use 'all' to ignore all rules 98 | # ignore=T1,body-min-length 99 | 100 | [ignore-by-body] 101 | # Ignore certain rules for commits of which the body has a line that matches a regex 102 | # E.g. Match bodies that have a line that that contain "release" 103 | # regex=(.*)release(.*) 104 | # 105 | # Ignore certain rules, you can reference them by their id or by their full name 106 | # Use 'all' to ignore all rules 107 | # ignore=T1,body-min-length 108 | 109 | # [ignore-body-lines] 110 | # Ignore certain lines in a commit body that match a regex. 111 | # E.g. Ignore all lines that start with 'Co-Authored-By' 112 | # regex=^Co-Authored-By 113 | 114 | # This is a contrib rule - a community contributed rule. These are disabled by default. 115 | # You need to explicitly enable them one-by-one by adding them to the "contrib" option 116 | # under [general] section above. 117 | # [contrib-title-conventional-commits] 118 | # Specify allowed commit types. For details see: https://www.conventionalcommits.org/ 119 | # types = bugfix,user-story,epic 120 | -------------------------------------------------------------------------------- /component/sqlite/SqliteHelper.cs: -------------------------------------------------------------------------------- 1 | namespace dgiot_dtu.component.sqlite 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Configuration; 6 | using System.Data; 7 | using System.Data.SQLite; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | using Dgiot_dtu; 12 | 13 | class SqliteHelper 14 | { 15 | //从配置文件中读取连接字符串 16 | private static string connStr = @"data source=D:\dgiot\data.db;Journal Mode=WAL"; 17 | //执行命令的方法,insert、update、delete 18 | //public static int ExecuteNonQuery(string sql, params SQLiteParameter[] ps) 19 | public static string values = ""; 20 | private static string head = ""; 21 | public static long i = 0; 22 | public static void ExecuteNonQuery(string sql) 23 | { 24 | //创建连接对象 25 | using (SQLiteConnection conn = new SQLiteConnection(connStr)) 26 | { 27 | //创建命令对象 28 | string v = sql + ";"; 29 | SQLiteCommand comd = new SQLiteCommand(v, conn); 30 | //添加参数 31 | //comd.Parameters.AddRange(ps); 32 | //打开连接 33 | conn.Open(); 34 | //执行命令,并返回受影响的行数 35 | comd.ExecuteNonQuery(); 36 | conn.Close(); 37 | //return A; 38 | } 39 | } 40 | 41 | //获取首行首列的方法 42 | public static object ExecuteScalar(string sql, params SQLiteParameter[] ps) 43 | { 44 | //创建连接对象 45 | using (SQLiteConnection conn = new SQLiteConnection(connStr)) 46 | { 47 | //创建命令对象 48 | string v = sql + ";"; 49 | SQLiteCommand comd = new SQLiteCommand(v, conn); 50 | //添加参数 51 | comd.Parameters.AddRange(ps); 52 | //打开连接 53 | conn.Open(); 54 | //执行命令,获取查询结果中的首行首列的值 55 | return comd.ExecuteScalar(); 56 | } 57 | } 58 | 59 | //获取结果集select 60 | //public static DataTable GetDataTable(string sql, params SQLiteParameter[] ps) 61 | public static DataTable GetDataTable(string sql) 62 | { 63 | using (SQLiteConnection conn = new SQLiteConnection(connStr)) 64 | { 65 | //构造适配器对象 66 | SQLiteDataAdapter adapter = new SQLiteDataAdapter(sql, conn); 67 | //构造数据表,用于接收查询结果 68 | DataTable dt = new DataTable(); 69 | //添加参数 70 | //adapter.SelectCommand.Parameters.AddRange(ps); 71 | //执行结果 72 | adapter.Fill(dt); 73 | //返回结果集 74 | return dt; 75 | } 76 | } 77 | 78 | public static void Init(string head) 79 | { 80 | string create = "create table if not exists cache(id BIGINT NOT NULL , name TEXT NOT NULL)"; 81 | SqliteHelper.ExecuteNonQuery(create); 82 | // SqliteHelper.head = "INSERT INTO cache (id,name)" 83 | SqliteHelper.head = "INSERT INTO cache " + head; 84 | } 85 | 86 | public static void Insert(string value) 87 | { 88 | long timestamp = DgiotHelper.Ms(); 89 | SqliteHelper.values = SqliteHelper.values + ", (" + timestamp.ToString() +",\'" + value.ToString() + "\')"; 90 | 91 | //list.ToArray().Length; 92 | SqliteHelper.ExecuteNonQuery(SqliteHelper.values); 93 | SqliteHelper.values = ""; 94 | 95 | } 96 | public static void Test(string sqls) 97 | { 98 | using (SQLiteConnection con = new SQLiteConnection(connStr)) 99 | { 100 | 101 | SQLiteCommand cmd = new SQLiteCommand(con); 102 | //添加参数 103 | //comd.Parameters.AddRange(ps); 104 | //打开连接 105 | 106 | con.Open(); 107 | 108 | //cmd.CommandText = "PRAGMA synchronous = OFF"; 109 | //cmd.ExecuteNonQuery(); 110 | 111 | cmd.CommandText = "PRAGMA synchronous = OFF"; 112 | cmd.ExecuteNonQuery(); 113 | // 使用事务测试 114 | IDbTransaction trans = con.BeginTransaction(); 115 | foreach (var sql in sqls) 116 | { 117 | long timestamp = DgiotHelper.Ms(); 118 | string Insert = "INSERT INTO cache (id,name) VALUES (" + timestamp.ToString() + ",\'" + sql.ToString() + "\');"; 119 | LogHelper.Log("Insert: " + Insert); 120 | cmd.CommandText = Insert ; 121 | cmd.ExecuteNonQueryAsync(); 122 | } 123 | trans.Commit(); 124 | //执行命令,并返回受影响的行数 125 | con.Close(); 126 | //return A; 127 | //返回结果集 128 | 129 | } 130 | } 131 | 132 | 133 | 134 | 135 | } 136 | } -------------------------------------------------------------------------------- /packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /component/Mqtt/MqttServerHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Dgiot_dtu 6 | { 7 | using System; 8 | using System.Text; 9 | using System.Text.RegularExpressions; 10 | using System.Threading; 11 | using System.Threading.Tasks; 12 | using MQTTnet; 13 | using MQTTnet.Core; 14 | using MQTTnet.Core.Protocol; 15 | using MQTTnet.Core.Server; 16 | 17 | public class MqttServerHelper 18 | { 19 | private MqttServerHelper() 20 | { 21 | } 22 | 23 | private static MqttServer mqttServer = null; 24 | private static int port = 1883; 25 | private static string pubtopic = "thing/com/post/"; 26 | 27 | private static string clientid = Guid.NewGuid().ToString().Substring(0, 5); 28 | private static MqttServerHelper instance; 29 | private static bool bIsCheck = false; 30 | private static bool bIsRuning = false; 31 | 32 | public static MqttServerHelper GetInstance() 33 | { 34 | if (instance == null) 35 | { 36 | instance = new MqttServerHelper(); 37 | } 38 | 39 | bIsRuning = false; 40 | return instance; 41 | } 42 | 43 | public static void Start() 44 | { 45 | Config(); 46 | bIsRuning = true; 47 | if (bIsCheck) 48 | { 49 | Task.Run(async () => { await ConnectMqttServerAsync(); }); 50 | } 51 | } 52 | 53 | public static void Stop() 54 | { 55 | if (bIsCheck) 56 | { 57 | if (mqttServer != null) 58 | { 59 | if (bIsRuning) 60 | { 61 | Task.Run(async () => 62 | { 63 | await mqttServer.StopAsync(); 64 | bIsRuning = false; 65 | LogHelper.Log("mqtt server:" + clientid + " connected"); 66 | }); 67 | } 68 | } 69 | } 70 | } 71 | 72 | public static void Config() 73 | { 74 | clientid = ConfigHelper.GetConfig("MqttClientId"); 75 | pubtopic = ConfigHelper.GetConfig("MqttPubTopic"); 76 | port = int.Parse(ConfigHelper.GetConfig("DgiotPort")); 77 | if (DgiotHelper.StrTobool(ConfigHelper.GetConfig("MqttClient_Checked")) && DgiotHelper.StrTobool(ConfigHelper.GetConfig("Bridge_Checked"))) 78 | { 79 | bIsCheck = true; 80 | } 81 | else 82 | { 83 | bIsCheck = false; 84 | } 85 | } 86 | 87 | private static async Task ConnectMqttServerAsync() 88 | { 89 | if (mqttServer == null) 90 | { 91 | var serveroptions = new MqttServerOptions 92 | { 93 | DefaultEndpointOptions = { Port = port } 94 | }; 95 | mqttServer = new MqttServerFactory().CreateMqttServer(serveroptions) as MqttServer; 96 | mqttServer.ApplicationMessageReceived += MqttServer_ApplicationMessageReceived; 97 | mqttServer.ClientConnected += MqttServer_Connected; 98 | mqttServer.ClientDisconnected += MqttServer_Disconnected; 99 | } 100 | 101 | try 102 | { 103 | await mqttServer.StartAsync(); 104 | 105 | Thread.Sleep(1000); 106 | } 107 | catch (Exception ex) 108 | { 109 | LogHelper.Log(ex.ToString()); 110 | } 111 | } 112 | 113 | /// 114 | /// 服务器连接成功 115 | /// 116 | /// 117 | /// 118 | private static void MqttServer_Connected(object sender, EventArgs e) 119 | { 120 | LogHelper.Log("mqtt server:" + clientid + " connected"); 121 | } 122 | 123 | /// 124 | /// 断开服务器连接 125 | /// 126 | /// 127 | /// 128 | private static void MqttServer_Disconnected(object sender, EventArgs e) 129 | { 130 | LogHelper.Log("mqtt server:" + clientid + " disconnected"); 131 | } 132 | 133 | /// 134 | /// 接收到消息 135 | /// 136 | /// 137 | /// 138 | private static void MqttServer_ApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e) 139 | { 140 | string data = Encoding.UTF8.GetString(e.ApplicationMessage.Payload); 141 | LogHelper.Log("mqtt server recv :topic: " + e.ApplicationMessage.Topic.ToString() + " payload: " + data + " ClientId " + e.ClientId); 142 | 143 | Regex r_pubtopic = new Regex(pubtopic + clientid); // 定义一个Regex对象实例 144 | Match m_pubtopic = r_pubtopic.Match(e.ApplicationMessage.Topic); // 在字符串中匹配 145 | if (m_pubtopic.Success) 146 | { 147 | MqttClientHelper.Write(e.ApplicationMessage); 148 | } 149 | } 150 | 151 | public static void Write(byte[] data, int offset, int len) 152 | { 153 | if (bIsCheck) 154 | { 155 | var appMsg = new MqttApplicationMessage(pubtopic + clientid, Encoding.UTF8.GetBytes(LogHelper.Logdata(data, offset, len)), MqttQualityOfServiceLevel.AtLeastOnce, false); 156 | LogHelper.Log("mqtt Server publish:" + LogHelper.Logdata(data, offset, len)); 157 | mqttServer.Publish(appMsg); 158 | } 159 | } 160 | 161 | public static void Write(MqttApplicationMessage appMsg) 162 | { 163 | if (bIsCheck) 164 | { 165 | mqttServer.Publish(appMsg); 166 | } 167 | } 168 | } 169 | } -------------------------------------------------------------------------------- /component/Opc/OPCDAHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | // https://github.com/titanium-as/TitaniumAS.Opc.Client 6 | // https://github.com/chkr1011/MQTTnet 7 | namespace Dgiot_dtu 8 | { 9 | using Da; 10 | 11 | using System.Collections.Generic; 12 | using System.Linq; 13 | using System.Text; 14 | using TitaniumAS.Opc.Client.Da; 15 | 16 | public class OPCDAHelper : IItemsValueChangedCallBack 17 | { 18 | private static readonly OPCDaImp OpcDa = new OPCDaImp(); 19 | private static OPCDAHelper instance = null; 20 | private static string productId = string.Empty; 21 | private static string devAddr = string.Empty; 22 | private static string host = "127.0.0.1"; 23 | private static int interval = 1000; 24 | 25 | public OPCDAHelper() 26 | { 27 | OpcDa.SetItemsValueChangedCallBack(this); 28 | } 29 | 30 | public static OPCDAHelper GetInstance() 31 | { 32 | if (instance == null) 33 | { 34 | instance = new OPCDAHelper(); 35 | } 36 | 37 | return instance; 38 | } 39 | 40 | public static void Start() 41 | { 42 | Config(); 43 | OPCDAViewHelper.View(); 44 | View(); 45 | //SqliteHelper.Init("(id,name)"); 46 | } 47 | 48 | public static void Stop() 49 | { 50 | } 51 | 52 | public static void Config() 53 | { 54 | host = ConfigHelper.GetConfig("OPCDAHost"); 55 | interval = int.Parse(ConfigHelper.GetConfig("OPCDAInterval")); 56 | productId = ConfigHelper.GetConfig("MqttUserName"); 57 | devAddr = ConfigHelper.GetConfig("DtuAddr"); 58 | } 59 | 60 | public static void StartMonitor() 61 | { 62 | if (DgiotHelper.StrTobool(ConfigHelper.GetConfig("OPCDACheck"))) 63 | { 64 | interval = int.Parse(ConfigHelper.GetConfig("OPCDAInterval")); 65 | int count = int.Parse(ConfigHelper.GetConfig("OPCDACount")); 66 | OpcDa.StartGroup(OPCDAViewHelper.GetRootNode(), interval, count); 67 | } 68 | else 69 | { 70 | OpcDa.StopGroup(); 71 | } 72 | } 73 | 74 | public static void View() 75 | { 76 | OpcDa.ScanOPCDa(host, true).ForEach(service => 77 | { 78 | OpcDaService server = OpcDa.GetOpcDaService(host, service); 79 | //OPCDAViewHelper.GetTreeNodes(server); 80 | }); 81 | } 82 | 83 | public static void GetTreeNodes(string service) 84 | { 85 | OpcDaService server = OpcDa.GetOpcDaService(host, service); 86 | OPCDAViewHelper.GetTreeNodes(server); 87 | } 88 | 89 | public void ValueChangedCallBack(OpcDaGroup group, OpcDaItemValue[] values) 90 | { 91 | string groupKey = ""; 92 | 93 | JsonObject properties = new JsonObject(); 94 | values.ToList().ForEach(v => 95 | { 96 | if (v.Item != null && v.Value != null) 97 | { 98 | properties.Add(v.Item.ItemId, v.Value); 99 | groupKey = v.Item.UserData as string; 100 | OpcDa.setItems(groupKey, v.Item.ItemId, properties); 101 | } 102 | }); 103 | int i = OpcDa.getItemsCount(groupKey); 104 | if (i <= 0) 105 | { 106 | properties = OpcDa.getItems(group, groupKey); 107 | int flag1 = OpcDa.GetGroupFlag(groupKey); 108 | if (flag1 > 0) 109 | { 110 | properties.Add("dgiotcollectflag", 0); 111 | // LogHelper.Log(" topic: " + topic + " payload: " + properties); 112 | } 113 | else 114 | { 115 | properties.Add("dgiotcollectflag", 1); 116 | } 117 | properties.Add("groupid", groupKey); 118 | LogHelper.Log("send properties: " + properties.ToString()); 119 | string topic = "$dg/thing/" + productId + "/" + devAddr + "/properties/report"; 120 | MqttClientHelper.Publish(topic, Encoding.UTF8.GetBytes(properties.ToString())); 121 | } 122 | } 123 | 124 | public static void Additems(Dictionary json) 125 | { 126 | string groupid = json["groupid"].ToString(); 127 | string opcserver = json["opcserver"].ToString(); 128 | object[] items = (object[])json["items"]; 129 | List itemlist = new List { }; 130 | foreach (object v in items) 131 | { 132 | itemlist.Add((string)v); 133 | } 134 | 135 | OpcDa.StopGroup(); 136 | OpcDa.StartMonitor(groupid, itemlist.Distinct().ToList(), opcserver); 137 | } 138 | 139 | 140 | public static void Readitems(Dictionary json) 141 | { 142 | string groupid = json["groupid"].ToString(); 143 | string opcserver = json["opcserver"].ToString(); 144 | object[] items = (object[])json["items"]; 145 | 146 | List itemlist = new List { }; 147 | foreach (object v in items) 148 | { 149 | itemlist.Add((string)v); 150 | } 151 | 152 | // OpcDa.StopGroup(); 153 | OpcDa.StartMonitor(groupid, itemlist.Distinct().ToList(), opcserver); 154 | // OpcDa.ReadItemsValues1(opcserver, itemlist.Distinct().ToList(), groupid); 155 | // OpcDa.read_group(opcserver, groupid, itemlist.Distinct().ToList()); 156 | } 157 | 158 | public static void Publishvalues(Dictionary json) 159 | { 160 | string groupid = json["groupid"].ToString(); 161 | int duration = (int)json["duration"]; 162 | OpcDa.SetGroupFlag(groupid, duration); 163 | } 164 | } 165 | } -------------------------------------------------------------------------------- /component/Tcp/TcpClientHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Dgiot_dtu 6 | { 7 | using System; 8 | using System.IO; 9 | using System.Net.Sockets; 10 | using System.Threading; 11 | 12 | public class TcpClientHelper 13 | { 14 | private TcpClientHelper() 15 | { 16 | } 17 | 18 | private static TcpClient client; 19 | private static TcpClientHelper instance; 20 | private static string login = string.Empty; 21 | private static NetworkStream stream; 22 | private static string server = "prod.iotn2n.com"; 23 | private static int port; 24 | private static bool bIsRunning = false; 25 | private static bool bIsCheck = false; 26 | private static bool bAutoReconnect = false; 27 | private static byte[] tcpdata = new byte[1024]; 28 | 29 | public static TcpClientHelper GetInstance() 30 | { 31 | if (instance == null) 32 | { 33 | instance = new TcpClientHelper(); 34 | } 35 | 36 | return instance; 37 | } 38 | 39 | public static void Start() 40 | { 41 | Config(); 42 | LogHelper.Log("TcpClient_Checked " + ConfigHelper.GetConfig("TcpClient_Checked")); 43 | if (DgiotHelper.StrTobool(ConfigHelper.GetConfig("TcpClient_Checked"))) 44 | { 45 | CreateConnect(); 46 | } 47 | } 48 | 49 | public static void Stop() 50 | { 51 | if (client != null) 52 | { 53 | if (client.Connected) 54 | { 55 | client.Close(); 56 | } 57 | 58 | client = null; 59 | } 60 | } 61 | 62 | public static void Config() 63 | { 64 | server = ConfigHelper.GetConfig("DgiotSever"); 65 | port = int.Parse(ConfigHelper.GetConfig("DgiotPort")); 66 | bAutoReconnect = DgiotHelper.StrTobool(ConfigHelper.GetConfig("ReconnectChecked")); 67 | bIsCheck = DgiotHelper.StrTobool(ConfigHelper.GetConfig("TcpClient_Checked")); 68 | login = ConfigHelper.GetConfig("TcpClientLogin"); 69 | } 70 | 71 | public static void CreateConnect() 72 | { 73 | client = new TcpClient(); 74 | client.BeginConnect(server, port, Connected, null); 75 | } 76 | 77 | private static void Connected(IAsyncResult result) 78 | { 79 | try 80 | { 81 | client.EndConnect(result); 82 | 83 | stream = client.GetStream(); 84 | 85 | if (stream.CanWrite) 86 | { 87 | Thread.Sleep(1000 * 1); 88 | 89 | byte[] data = new byte[1024]; 90 | 91 | data = System.Text.Encoding.UTF8.GetBytes(login.ToCharArray()); 92 | 93 | LogHelper.Log("TcpClient: login [" + login + "]"); 94 | 95 | stream.Write(data, 0, data.Length); 96 | } 97 | 98 | stream.BeginRead(tcpdata, 0, tcpdata.Length, Read, null); 99 | 100 | bIsRunning = true; 101 | } 102 | catch (Exception e) 103 | { 104 | LogHelper.Log("TcpClient Couldn't connect: " + e.Message); 105 | OnConnectClosed(); 106 | } 107 | } 108 | 109 | private static void Read(IAsyncResult ar) 110 | { 111 | try 112 | { 113 | var offset = 0; 114 | var rxbytes = stream.EndRead(ar); 115 | 116 | if (rxbytes > 0) 117 | { 118 | stream.BeginRead(tcpdata, 0, tcpdata.Length, Read, null); 119 | 120 | LogHelper.Log("TcpClient Recv: [" + LogHelper.Logdata(tcpdata, offset, rxbytes - offset) + "]"); 121 | 122 | TcpServerHelper.Write(tcpdata, offset, rxbytes - offset); 123 | 124 | SerialPortHelper.Write(tcpdata, offset, rxbytes - offset); 125 | } 126 | 127 | if (rxbytes == 0) 128 | { 129 | LogHelper.Log("TcpClient Client closed"); 130 | OnConnectClosed(); 131 | } 132 | } 133 | catch (Exception e) 134 | { 135 | if (e is ObjectDisposedException) 136 | { 137 | LogHelper.Log("TcpClient Connection closed"); 138 | } 139 | else if (e is IOException && e.Message.Contains("closed")) 140 | { 141 | LogHelper.Log("TcpClient Connection closed"); 142 | } 143 | else 144 | { 145 | LogHelper.Log("TcpClient Exception: " + e.Message); 146 | } 147 | 148 | OnConnectClosed(); 149 | } 150 | } 151 | 152 | private static void OnConnectClosed() 153 | { 154 | try 155 | { 156 | if (client != null) 157 | { 158 | client.Close(); 159 | bIsRunning = false; 160 | client = null; 161 | } 162 | } 163 | catch (Exception ex) 164 | { 165 | LogHelper.Log("TcpClient close:" + ex.Message); 166 | } 167 | 168 | if (bAutoReconnect && bIsRunning) 169 | { 170 | try 171 | { 172 | CreateConnect(); 173 | } 174 | catch (Exception ex) 175 | { 176 | LogHelper.Log("TcpClient Problem reconnecting:" + ex.Message); 177 | } 178 | } 179 | } 180 | 181 | public static void Write(byte[] data, int offset, int len) 182 | { 183 | if (bIsCheck) 184 | { 185 | if (stream.CanWrite) 186 | { 187 | LogHelper.Log("TcpClient Send: [" + LogHelper.Logdata(data, 0, len) + "]"); 188 | stream.Write(data, offset, len); 189 | } 190 | } 191 | } 192 | } 193 | } -------------------------------------------------------------------------------- /Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Resources\bridge.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | -------------------------------------------------------------------------------- /component/Tcp/TcpServerHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Dgiot_dtu 6 | { 7 | using System; 8 | using System.Configuration; 9 | using System.IO; 10 | using System.Net; 11 | using System.Net.Sockets; 12 | 13 | public class TcpServerHelper 14 | { 15 | private TcpServerHelper() 16 | { 17 | } 18 | 19 | private static TcpListener server; 20 | private static TcpClient client; 21 | private static NetworkStream stream; 22 | private static byte[] tcpdata = new byte[1024]; 23 | private static TcpServerHelper instance; 24 | private static bool bIsRunning = false; 25 | private static bool bIsCheck = false; 26 | private static int port; 27 | 28 | public static TcpServerHelper GetInstance() 29 | { 30 | if (instance == null) 31 | { 32 | instance = new TcpServerHelper(); 33 | } 34 | 35 | return instance; 36 | } 37 | 38 | public static void Start() 39 | { 40 | bIsRunning = true; 41 | Config(); 42 | if (bIsCheck) 43 | { 44 | CreateConnect(); 45 | } 46 | } 47 | 48 | public static void Stop() 49 | { 50 | if (server != null) 51 | { 52 | TcpServerHelper.bIsRunning = false; 53 | server.Stop(); 54 | server = null; 55 | } 56 | } 57 | 58 | public static void Config() 59 | { 60 | if (DgiotHelper.StrTobool(ConfigHelper.GetConfig("TcpClient_Checked")) && DgiotHelper.StrTobool(ConfigHelper.GetConfig("Bridge_Checked"))) 61 | { 62 | bIsCheck = true; 63 | } 64 | else 65 | { 66 | bIsCheck = false; 67 | } 68 | 69 | port = int.Parse(ConfigHelper.GetConfig("BridgePort")); 70 | } 71 | 72 | public static void CreateConnect() 73 | { 74 | server = new TcpListener(IPAddress.Any, TcpServerHelper.port); 75 | server.Start(); 76 | server.BeginAcceptTcpClient(Connected, null); 77 | } 78 | 79 | private static void Connected(IAsyncResult result) 80 | { 81 | try 82 | { 83 | if (!bIsRunning) 84 | { 85 | LogHelper.Log("TcpConnectedIn: server shutdown"); 86 | goto end; 87 | } 88 | 89 | TcpClient tmp_client = server.EndAcceptTcpClient(result); 90 | NetworkStream tmp_stream = tmp_client.GetStream(); 91 | 92 | if (client != null) 93 | { 94 | LogHelper.Log("tcpServer Already in use, close connected from: " + tmp_client.Client.RemoteEndPoint); 95 | byte[] reject = System.Text.Encoding.ASCII.GetBytes("Already in use!\r\n"); 96 | tmp_stream.Write(reject, 0, reject.Length); 97 | tmp_stream.Close(); 98 | tmp_client.Close(); 99 | goto end; 100 | } 101 | 102 | client = tmp_client; 103 | stream = tmp_stream; 104 | 105 | LogHelper.Log("tcpServer Client Connected: " + client.Client.LocalEndPoint + "<==>" + client.Client.RemoteEndPoint); 106 | stream.BeginRead(tcpdata, 0, tcpdata.Length, Read, null); 107 | 108 | bIsRunning = true; 109 | } 110 | catch (Exception e) 111 | { 112 | if (e is ObjectDisposedException) 113 | { 114 | LogHelper.Log("TCP Server Connection shutdown"); 115 | } 116 | else 117 | { 118 | LogHelper.Log("TCP Server Connection exception: " + e.Message); 119 | } 120 | } 121 | 122 | end: 123 | try 124 | { 125 | if (bIsRunning) 126 | { 127 | /* accept other connection again */ 128 | server.BeginAcceptTcpClient(Connected, null); 129 | } 130 | } 131 | catch (Exception e) 132 | { 133 | LogHelper.Log("TCP Server exception: " + e.Message); 134 | } 135 | } 136 | 137 | private static void Read(IAsyncResult ar) 138 | { 139 | try 140 | { 141 | var rxbytes = stream.EndRead(ar); 142 | if (rxbytes > 0) 143 | { 144 | var offset = 0; 145 | stream.BeginRead(tcpdata, 0, tcpdata.Length, Read, null); 146 | LogHelper.Log("N->S: tcpServer recv [ " + LogHelper.Logdata(tcpdata, offset, rxbytes - offset) + "]"); 147 | TcpClientHelper.Write(tcpdata, offset, rxbytes - offset); 148 | 149 | // Write(tcpdata, offset, rxbytes - offset); 150 | } 151 | 152 | if (rxbytes == 0) 153 | { 154 | LogHelper.Log("Client closed"); 155 | OnConnectClosed(); 156 | } 157 | } 158 | catch (Exception e) 159 | { 160 | if (e is ObjectDisposedException) 161 | { 162 | LogHelper.Log("Connection closed"); 163 | } 164 | else if (e is IOException && e.Message.Contains("closed")) 165 | { 166 | LogHelper.Log("Connection closed"); 167 | } 168 | else 169 | { 170 | LogHelper.Log("Exception: " + e.Message); 171 | } 172 | 173 | OnConnectClosed(); 174 | } 175 | } 176 | 177 | public static void Write(byte[] data, int offset, int len) 178 | { 179 | if (bIsCheck) 180 | { 181 | if (stream != null) 182 | { 183 | stream.Write(data, offset, len); 184 | } 185 | } 186 | } 187 | 188 | private static void OnConnectClosed() 189 | { 190 | try 191 | { 192 | client.Close(); 193 | client = null; 194 | } 195 | catch 196 | { 197 | } 198 | } 199 | } 200 | } -------------------------------------------------------------------------------- /FodyWeavers.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks 13 | 14 | 15 | 16 | 17 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. 18 | 19 | 20 | 21 | 22 | A list of unmanaged 32 bit assembly names to include, delimited with line breaks. 23 | 24 | 25 | 26 | 27 | A list of unmanaged 64 bit assembly names to include, delimited with line breaks. 28 | 29 | 30 | 31 | 32 | The order of preloaded assemblies, delimited with line breaks. 33 | 34 | 35 | 36 | 37 | 38 | This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file. 39 | 40 | 41 | 42 | 43 | Controls if .pdbs for reference assemblies are also embedded. 44 | 45 | 46 | 47 | 48 | Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option. 49 | 50 | 51 | 52 | 53 | As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off. 54 | 55 | 56 | 57 | 58 | Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code. 59 | 60 | 61 | 62 | 63 | Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior. 64 | 65 | 66 | 67 | 68 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with | 69 | 70 | 71 | 72 | 73 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |. 74 | 75 | 76 | 77 | 78 | A list of unmanaged 32 bit assembly names to include, delimited with |. 79 | 80 | 81 | 82 | 83 | A list of unmanaged 64 bit assembly names to include, delimited with |. 84 | 85 | 86 | 87 | 88 | The order of preloaded assemblies, delimited with |. 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. 97 | 98 | 99 | 100 | 101 | A comma-separated list of error codes that can be safely ignored in assembly verification. 102 | 103 | 104 | 105 | 106 | 'false' to turn off automatic generation of the XML Schema file. 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /utils/TreeViewHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Dgiot_dtu 6 | { 7 | using System; 8 | using System.Configuration; 9 | using System.Windows.Forms; 10 | 11 | 12 | public class TreeViewHelper 13 | { 14 | private static readonly string[] NodeTypeValue = new string[] 15 | { 16 | "BACnet", 17 | "OPCDA", 18 | "OPCUA", 19 | "PLC", 20 | "Control", 21 | "Access", 22 | "SqlServer", 23 | }; 24 | 25 | public enum NodeType 26 | { 27 | BACnet = 0, 28 | OPCDA = 1, 29 | OPCUA = 2, 30 | Control = 3, 31 | Access = 4, 32 | SqlServer = 5 33 | } 34 | 35 | private TreeViewHelper() 36 | { 37 | } 38 | 39 | private static TreeViewHelper instance = null; 40 | private static TreeView treeView = null; 41 | 42 | public static TreeViewHelper GetInstance() 43 | { 44 | if (instance == null) 45 | { 46 | instance = new TreeViewHelper(); 47 | } 48 | 49 | return instance; 50 | } 51 | 52 | public static void Init(TreeView treeView) 53 | { 54 | TreeViewHelper.treeView = treeView; 55 | } 56 | 57 | public static void Config(KeyValueConfigurationCollection config) 58 | { 59 | } 60 | 61 | public static string Type(NodeType type) 62 | { 63 | int index = (int)type; 64 | return NodeTypeValue[index]; 65 | } 66 | 67 | public static void AddNode(TreeNode node) 68 | { 69 | treeView.BeginUpdate(); 70 | treeView.Nodes.Remove(node); 71 | treeView.Nodes.Add(node); 72 | treeView.EndUpdate(); 73 | } 74 | 75 | public static void AppendNode(TreeNode node) 76 | { 77 | treeView.BeginUpdate(); 78 | treeView.Nodes.Add(node); 79 | treeView.EndUpdate(); 80 | } 81 | 82 | public static void DeleteNode(TreeNode node) 83 | { 84 | treeView.Nodes.Remove(node); 85 | } 86 | 87 | public static void ClearNodes() 88 | { 89 | treeView.Nodes.Clear(); 90 | } 91 | 92 | /// 93 | /// 通过fullpath 查找treeview节点 节点name属性需要赋过值 94 | /// 95 | /// TreeNodeCollection node集合 96 | /// 要查找的节点的fullPath 97 | /// TreeNode 98 | public static TreeNode GetNode(TreeNodeCollection nodes, string fullPath) 99 | { 100 | string[] paths = fullPath.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries); 101 | TreeNode tn = null; 102 | if (paths.Length > 0) 103 | { 104 | string lastPath = paths[paths.Length - 1]; 105 | var finds = nodes.Find(lastPath, true); 106 | if (finds.Length > 0) 107 | { 108 | foreach (var item in finds) 109 | { 110 | if (item.FullPath == fullPath) 111 | { 112 | tn = item; 113 | break; 114 | } 115 | } 116 | } 117 | } 118 | 119 | return tn; 120 | } 121 | 122 | public static void TreeView_AfterSelect(TreeViewAction action, TreeNode node) 123 | { 124 | // 通过鼠标或者键盘触发事件,防止修改节点的Checked状态时候再次进入 125 | if ((action == TreeViewAction.ByMouse || action == TreeViewAction.ByKeyboard ) && node.Checked) 126 | { 127 | LogHelper.Log("select node " + node.Text + " tag " + node.Tag + " key " + OPCDAViewHelper.Key(node.FullPath.ToString())); 128 | } 129 | } 130 | 131 | public static void TreeView_AfterCheck(TreeViewAction action, TreeNode node) 132 | { 133 | if (action != TreeViewAction.Unknown) 134 | { 135 | LogHelper.Log("check node " + node.Text + " tag " + node.Tag + " Level " + node.Level.ToString()); 136 | 137 | SetChildNodeCheckedState(node, node.Checked); 138 | SetParentNodeCheckedState(node, node.Checked); 139 | } 140 | } 141 | 142 | public static void NodeMouseDoubleClick(MouseButtons buttons, TreeNode node) 143 | { 144 | if (buttons == MouseButtons.Right && node.Checked) // 单击鼠标右键写 145 | { 146 | LogHelper.Log("Right node " + node.Text + " tag " + node.Tag + " Level " + node.Level.ToString()); 147 | if (node.Tag.ToString() == NodeTypeValue[(int)NodeType.OPCDA]) 148 | { 149 | OPCDAViewHelper.AddItems(node); 150 | } 151 | } 152 | else if (buttons == MouseButtons.Left && node.Checked) // 双击鼠标左键读 153 | { 154 | LogHelper.Log("Left node " + node.Text + " ToolTipText " + node.ToolTipText + " Level " + node.Level.ToString()); 155 | OPCDAHelper.GetTreeNodes(node.Text); 156 | } 157 | } 158 | 159 | public static bool CheckLabelEdit(string label, TreeNode node) 160 | { 161 | if (label.IndexOfAny(new char[] { '@', '.', ',', '!' }) == -1) 162 | { 163 | // Stop editing without canceling the label change. 164 | return false; 165 | } 166 | 167 | return false; 168 | } 169 | 170 | // 设置子节点状态 171 | public static void SetChildNodeCheckedState(TreeNode currNode, bool isCheckedOrNot) 172 | { 173 | if (currNode.Nodes == null) 174 | { 175 | return; // 没有子节点返回 176 | } 177 | 178 | foreach (TreeNode tmpNode in currNode.Nodes) 179 | { 180 | tmpNode.Checked = isCheckedOrNot; 181 | SetChildNodeCheckedState(tmpNode, isCheckedOrNot); 182 | } 183 | } 184 | 185 | // 设置父节点状态 186 | public static void SetParentNodeCheckedState(TreeNode currNode, bool isCheckedOrNot) 187 | { 188 | if (currNode.Parent == null) 189 | { 190 | return; // 没有父节点返回 191 | } 192 | 193 | if (isCheckedOrNot) // 如果当前节点被选中,则设置所有父节点都被选中 194 | { 195 | currNode.Parent.Checked = isCheckedOrNot; 196 | SetParentNodeCheckedState(currNode.Parent, isCheckedOrNot); 197 | } 198 | else // 如果当前节点没有被选中,则当其父节点的子节点有一个被选中时,父节点被选中,否则父节点不被选中 199 | { 200 | bool checkedFlag = false; 201 | foreach (TreeNode tmpNode in currNode.Parent.Nodes) 202 | { 203 | if (tmpNode.Checked) 204 | { 205 | checkedFlag = true; 206 | break; 207 | } 208 | } 209 | 210 | currNode.Parent.Checked = checkedFlag; 211 | SetParentNodeCheckedState(currNode.Parent, checkedFlag); 212 | } 213 | } 214 | } 215 | } -------------------------------------------------------------------------------- /component/Opc/Da.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {7B11BB31-8465-4CF2-B39B-097D5AF44213} 8 | Library 9 | Properties 10 | Da 11 | Da 12 | v4.6.1 13 | 512 14 | true 15 | 16 | 17 | true 18 | full 19 | false 20 | ..\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | true 35 | bin\x86\Debug\ 36 | DEBUG;TRACE 37 | full 38 | x86 39 | prompt 40 | MinimumRecommendedRules.ruleset 41 | 42 | 43 | bin\x86\Release\ 44 | TRACE 45 | true 46 | pdbonly 47 | x86 48 | prompt 49 | MinimumRecommendedRules.ruleset 50 | 51 | 52 | 53 | ..\packages\Common.Logging.3.4.1\lib\net40\Common.Logging.dll 54 | 55 | 56 | ..\packages\Common.Logging.Core.3.4.1\lib\net40\Common.Logging.Core.dll 57 | 58 | 59 | ..\packages\ini-parser.2.5.2\lib\net20\INIFileParser.dll 60 | 61 | 62 | ..\packages\log4net.2.0.12\lib\net45\log4net.dll 63 | 64 | 65 | ..\packages\Microsoft.Bcl.AsyncInterfaces.5.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll 66 | 67 | 68 | ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll 69 | 70 | 71 | ..\packages\SuperSocket.1.6.6.1\lib\net45\SuperSocket.Common.dll 72 | 73 | 74 | ..\packages\SuperSocket.1.6.6.1\lib\net45\SuperSocket.Facility.dll 75 | 76 | 77 | ..\packages\SuperSocket.1.6.6.1\lib\net45\SuperSocket.SocketBase.dll 78 | 79 | 80 | ..\packages\SuperSocket.Engine.1.6.6.1\lib\net45\SuperSocket.SocketEngine.dll 81 | 82 | 83 | ..\packages\SuperSocket.Engine.1.6.6.1\lib\net45\SuperSocket.SocketService.exe 84 | 85 | 86 | 87 | 88 | 89 | ..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll 90 | 91 | 92 | ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | ..\packages\TitaniumAS.Opc.Client.1.0.2.0\lib\net40\TitaniumAS.Opc.Client.dll 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | Always 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /component/Printer/BarCodePrinter.cs: -------------------------------------------------------------------------------- 1 | using CodeLib; 2 | using Dgiot_dtu; 3 | using LitJson; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Drawing; 7 | using System.Drawing.Imaging; 8 | using System.Drawing.Printing; 9 | using System.Linq; 10 | using System.Runtime.InteropServices; 11 | using System.Text; 12 | using System.Threading.Tasks; 13 | 14 | namespace dgiot_dtu.component.Printer 15 | { 16 | class BarCodePrinter 17 | { 18 | [DllImport("winspool.drv")] 19 | public static extern bool SetDefaultPrinter(String Name); //调用win api将指定名称的打印机设置为默认打印 20 | /*页面打印委托*/ 21 | public delegate void DoPrintDelegate(Graphics g, ref bool HasMorePage); 22 | 23 | public PrintDocument iSPriner = null; 24 | bool m_bUseDefaultPaperSetting = false; 25 | 26 | DoPrintDelegate DoPrint = null; 27 | 28 | public BarCodePrinter() 29 | { 30 | iSPriner = new PrintDocument(); 31 | iSPriner.PrintPage += new PrintPageEventHandler(this.OnPrintPage); 32 | } 33 | 34 | public void Dispose() 35 | { 36 | if (iSPriner != null) iSPriner.Dispose(); 37 | iSPriner = null; 38 | 39 | } 40 | 41 | /*设置打印机名*/ 42 | public string PrinterName 43 | { 44 | get { return iSPriner.PrinterSettings.PrinterName; } 45 | set { iSPriner.PrinterSettings.PrinterName = value; } 46 | } 47 | 48 | /*设置打印文档名*/ 49 | public string DocumentName 50 | { 51 | get { return iSPriner.DocumentName; } 52 | set { iSPriner.DocumentName = value; } 53 | } 54 | 55 | /*设置是否使用缺省纸张*/ 56 | public bool UseDefaultPaper 57 | { 58 | get { return m_bUseDefaultPaperSetting; } 59 | set 60 | { 61 | m_bUseDefaultPaperSetting = value; 62 | if (!m_bUseDefaultPaperSetting) 63 | { 64 | //如果不适用缺省纸张则创建一个自定义纸张,注意,必须使用这个版本的构造函数才是自定义的纸张 65 | //PaperSize ps = new PaperSize("Custom Size 1", 827, 1169); 66 | //将缺省的纸张设置为新建的自定义纸张 67 | //iSPriner.DefaultPageSettings.PaperSize = ps; 68 | } 69 | } 70 | } 71 | 72 | /*纸张宽度 单位定义为毫米mm*/ 73 | public float PaperWidth 74 | { 75 | get { return iSPriner.DefaultPageSettings.PaperSize.Width / 100f * 25.4f; } 76 | set 77 | { 78 | LogHelper.Log("codeX: " + value); 79 | LogHelper.Log("Kind: " + iSPriner.DefaultPageSettings.PaperSize.Kind); 80 | //注意,只有自定义纸张才能修改该属性,否则将导致异常 81 | if (iSPriner.DefaultPageSettings.PaperSize.Kind == PaperKind.Custom) 82 | iSPriner.DefaultPageSettings.PaperSize.Width = (int)(value / 25.4 * 100); 83 | } 84 | } 85 | 86 | /*纸张高度 单位定义为毫米mm*/ 87 | public float PaperHeight 88 | { 89 | get { return (int)iSPriner.PrinterSettings.DefaultPageSettings.PaperSize.Height / 100f * 25.4f; } 90 | set 91 | { 92 | //注意,只有自定义纸张才能修改该属性,否则将导致异常 93 | if (iSPriner.DefaultPageSettings.PaperSize.Kind == PaperKind.Custom) 94 | iSPriner.DefaultPageSettings.PaperSize.Height = (int)(value / 25.4 * 100); 95 | } 96 | } 97 | 98 | /*页面打印*/ 99 | private void OnPrintPage(object sender, PrintPageEventArgs ev) 100 | { 101 | //调用委托绘制打印内容 102 | if (DoPrint != null) 103 | { 104 | bool bHadMore = false; 105 | DoPrint(ev.Graphics, ref bHadMore); 106 | ev.HasMorePages = bHadMore; 107 | } 108 | else 109 | { 110 | foreach (JsonData item in PrinterHelper.GetJson()) 111 | { 112 | if (item.ContainsKey("type")) 113 | { 114 | String type = item["type"].ToString(); 115 | if (type == "paper" || type == "printer" || type.Equals("scancodetext")) 116 | { 117 | } 118 | else if (item.ContainsKey("text") 119 | && item.ContainsKey("fontFamily") 120 | && item.ContainsKey("fontSize") 121 | && item.ContainsKey("x") 122 | && item.ContainsKey("y") 123 | && item.ContainsKey("width") 124 | && item.ContainsKey("height")) 125 | { 126 | String text = item["text"].ToString(); 127 | String fontFamily = item["fontFamily"].ToString(); 128 | int fontSize = int.Parse(item["fontSize"].ToJson()); 129 | float x = float.Parse(item["x"].ToJson()); 130 | float y = float.Parse(item["y"].ToJson()); 131 | float width = float.Parse(item["width"].ToJson()); 132 | float height = float.Parse(item["height"].ToJson()); 133 | if (type == "scancode") 134 | { 135 | Image image = GetBarCode(text, fontSize, (int)width, (int)height, fontFamily); 136 | ev.Graphics.DrawImage(image, x + 10, y + 10, width, height); //单位1/100英寸 137 | } 138 | else 139 | { 140 | //LogHelper.Log("type11: " + type); 141 | Font font = new Font(new FontFamily(fontFamily), fontSize); 142 | ev.Graphics.DrawString(text, font, Brushes.Black, x, y); 143 | } 144 | } 145 | else 146 | { 147 | 148 | } 149 | } 150 | } 151 | ev.HasMorePages = false; 152 | } 153 | } 154 | 155 | public Image GetBarCode(String Data, int FontSize, int Width, int Height, String familyName) 156 | { 157 | TYPE type = CodeLib.TYPE.CODE128B; 158 | Font Label = new Font(familyName, FontSize * 4); 159 | AlignmentPositions Align = AlignmentPositions.CENTER; 160 | Barcode b = new CodeLib.Barcode(); 161 | b.IncludeLabel = true; 162 | b.LabelFont = Label; 163 | b.Alignment = Align; 164 | b.LabelPosition = LabelPositions.BOTTOMCENTER; 165 | b.Encode(type, Data, Width * 4, Height * 4).Save("./test.jpg", ImageFormat.Jpeg); 166 | return b.Encode(type, Data, Width * 4, Height * 4); //像素 167 | } 168 | 169 | /* 开始打印*/ 170 | public void Print(DoPrintDelegate doPrint) 171 | { 172 | DoPrint = doPrint; 173 | this.iSPriner.Print(); 174 | } 175 | 176 | /* 开始打印*/ 177 | public void doPrint() 178 | { 179 | this.SetPaperSize(); 180 | this.iSPriner.Print(); 181 | } 182 | 183 | /* 设置纸大小*/ 184 | public void SetPaperSize() 185 | { 186 | foreach (JsonData item in PrinterHelper.GetJson()) 187 | { 188 | if (item.ContainsKey("type")) 189 | { 190 | String type = item["type"].ToString(); 191 | if (type == "paper") 192 | { 193 | if (item.ContainsKey("width") && item.ContainsKey("height")) 194 | { 195 | int paperwidth = Knova.pxToInch(int.Parse(item["width"].ToJson())); 196 | int paperheight = Knova.pxToInch(int.Parse(item["height"].ToJson())); 197 | iSPriner.DefaultPageSettings.PaperSize = new PaperSize("Size", paperwidth, paperheight); //单位1/100英寸 198 | } 199 | } 200 | else if (type == "printer") 201 | { 202 | if (item.ContainsKey("text")) 203 | { 204 | String text = item["text"].ToString(); 205 | LogHelper.Log("printer: " + text); 206 | SetDefaultPrinter(text); 207 | } 208 | } 209 | 210 | } 211 | } 212 | } 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /component/Opc/View/OPCDAViewHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) PlaceholderCompany. All rights reserved. 3 | // 4 | 5 | namespace Dgiot_dtu 6 | { 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Windows.Forms; 10 | using Da; 11 | using TitaniumAS.Opc.Client.Da.Browsing; 12 | 13 | public class OPCDAViewHelper 14 | { 15 | public enum NodeType 16 | { 17 | OPCDA = 0, 18 | Host = 1, 19 | Service = 2, 20 | Device = 3, 21 | Group = 4, 22 | Item = 5, 23 | Property = 6 24 | } 25 | 26 | public OPCDAViewHelper() 27 | { 28 | } 29 | 30 | private static OPCDAViewHelper instance = null; 31 | private static TreeNode opcdaNode = new TreeNode(Type(), 0, 0); 32 | 33 | public static OPCDAViewHelper GetInstance() 34 | { 35 | if (instance == null) 36 | { 37 | instance = new OPCDAViewHelper(); 38 | opcdaNode.Tag = Type(); 39 | opcdaNode.ForeColor = System.Drawing.Color.Black; 40 | } 41 | 42 | return instance; 43 | } 44 | 45 | public static string Type() 46 | { 47 | return TreeViewHelper.Type(TreeViewHelper.NodeType.OPCDA); 48 | } 49 | 50 | public static void View() 51 | { 52 | TreeViewHelper.AddNode(opcdaNode); 53 | } 54 | 55 | public static string Key(TreeNode parentNode, string itemid) 56 | { 57 | return DgiotHelper.Md5(parentNode.FullPath + "/" + itemid).Substring(0, 10); 58 | } 59 | 60 | public static string Key(string path) 61 | { 62 | return DgiotHelper.Md5(path).Substring(0, 10); 63 | } 64 | 65 | public static TreeNode GetRootNode() 66 | { 67 | return opcdaNode; 68 | } 69 | 70 | public static TreeNode GetNode(string key) 71 | { 72 | TreeNode[] nodes = opcdaNode.Nodes.Find(key, true); 73 | if (nodes.Length > 0) 74 | { 75 | return nodes[0]; 76 | } 77 | 78 | return null; 79 | } 80 | 81 | // 查询子节点 82 | public static TreeNode FindNode(TreeNode currNode, string key) 83 | { 84 | if (currNode.Nodes == null) 85 | { 86 | return null; // 没有子节点返回 87 | } 88 | else 89 | { 90 | if (key == Key(currNode.FullPath)) 91 | { 92 | return currNode; 93 | } 94 | 95 | foreach (TreeNode tmpNode in currNode.Nodes) 96 | { 97 | TreeNode childNode = FindNode(tmpNode, key); 98 | if (childNode != null) 99 | { 100 | return childNode; 101 | } 102 | } 103 | } 104 | 105 | return null; 106 | } 107 | 108 | public static TreeNode GetTreeNodes(OpcDaService server) 109 | { 110 | TreeNode hostNode = GetNode(Key(opcdaNode.FullPath + "/" + server.Host)); 111 | TreeNode serviceNode = GetNode(Key(hostNode.FullPath + "/" + server.ServiceId)); 112 | try 113 | { 114 | OpcDaBrowserAuto browserAuto = new OpcDaBrowserAuto(server.Service); 115 | BrowseChildren(browserAuto, serviceNode); 116 | } 117 | catch (Exception) 118 | { 119 | return serviceNode; 120 | } 121 | 122 | return serviceNode; 123 | } 124 | 125 | public static void BrowseChildren(IOpcDaBrowser browser, TreeNode node, string itemId = null, int indent = 0) 126 | { 127 | OpcDaBrowseElement[] elements = browser.GetElements(itemId); 128 | foreach (OpcDaBrowseElement element in elements) 129 | { 130 | if (!(element.ItemId.IndexOf('$') == 0)) 131 | { 132 | if (indent > 14) 133 | { 134 | continue; 135 | } 136 | 137 | if (IsItemsfilter(element.Name) || IsItemsfilter(element.ItemId)) 138 | { 139 | continue; 140 | } 141 | 142 | if (element.HasChildren ) 143 | { 144 | TreeNode curNode = AddNode(node, element.Name, element.ItemId); 145 | if (curNode != null) 146 | { 147 | BrowseChildren(browser, curNode, element.ItemId, indent + 2); 148 | } 149 | } 150 | else 151 | { 152 | AddLeafNode(node, element.Name, element.ItemId); 153 | } 154 | } 155 | } 156 | } 157 | 158 | public static void AddItems(TreeNode parentNode) 159 | { 160 | List items = FileHelper.OpenFile(); 161 | items.ForEach(item => 162 | { 163 | AddLeafNode(parentNode, item, item); 164 | LogHelper.Log("item " + item); 165 | }); 166 | } 167 | 168 | public static string GetItemId(string name, string itemid) 169 | { 170 | if (itemid == "" || itemid == null) 171 | { 172 | if (name == "" || name == null) 173 | { 174 | return null; 175 | } 176 | else 177 | { 178 | return name; 179 | } 180 | } 181 | else 182 | { 183 | return itemid; 184 | } 185 | } 186 | 187 | public static TreeNode AddLeafNode(TreeNode parentNode, string name, string itemid) 188 | { 189 | if (null == parentNode || parentNode.Level == 7 || null == GetItemId(name, itemid)) 190 | { 191 | return null; 192 | } 193 | 194 | parentNode.ForeColor = System.Drawing.Color.Blue; 195 | if (parentNode.Parent != null) 196 | { 197 | parentNode.Parent.ForeColor = System.Drawing.Color.Black; 198 | if (parentNode.Parent.Parent != null) 199 | { 200 | parentNode.Parent.Parent.ForeColor = System.Drawing.Color.Black; 201 | if (parentNode.Parent.Parent.Parent != null) 202 | { 203 | parentNode.Parent.Parent.Parent.ForeColor = System.Drawing.Color.Black; 204 | if (parentNode.Parent.Parent.Parent.Parent != null) 205 | { 206 | parentNode.Parent.Parent.Parent.Parent.ForeColor = System.Drawing.Color.Black; 207 | if (parentNode.Parent.Parent.Parent.Parent.Parent != null) 208 | { 209 | parentNode.Parent.Parent.Parent.Parent.Parent.ForeColor = System.Drawing.Color.Black; 210 | } 211 | } 212 | } 213 | } 214 | } 215 | 216 | string newItemId = GetItemId(name, itemid); 217 | 218 | if (!parentNode.Nodes.ContainsKey(Key(parentNode, newItemId))) 219 | { 220 | parentNode.Nodes.Add(Key(parentNode, newItemId), newItemId); 221 | } 222 | 223 | parentNode.Nodes[Key(parentNode, newItemId)].ForeColor = System.Drawing.Color.Green; 224 | parentNode.Nodes[Key(parentNode, newItemId)].Tag = Type(); 225 | parentNode.Nodes[Key(parentNode, newItemId)].ToolTipText = name; 226 | return parentNode.Nodes[Key(parentNode, newItemId)]; 227 | } 228 | 229 | public static TreeNode AddNode(TreeNode parentNode, string name, string itemid) 230 | { 231 | if (null == parentNode || parentNode.Level == 7 || null == GetItemId(name, itemid)) 232 | { 233 | return null; 234 | } 235 | 236 | string newItemId = GetItemId(name, itemid); 237 | if (!parentNode.Nodes.ContainsKey(Key(parentNode, newItemId))) 238 | { 239 | parentNode.Nodes.Add(Key(parentNode, newItemId), newItemId); 240 | } 241 | 242 | parentNode.Nodes[Key(parentNode, newItemId)].Tag = Type(); 243 | parentNode.Nodes[Key(parentNode, newItemId)].ToolTipText = name; 244 | return parentNode.Nodes[Key(parentNode, newItemId)]; 245 | } 246 | 247 | private static readonly List Itemsfilter = new List 248 | { 249 | "_AdvancedTags", 250 | "_ConnectionSharing", 251 | "_CustomAlarms", 252 | "_DataLogger", 253 | "_EFMExporter", 254 | "_IDF_for_Splunk", 255 | "_IoT_Gateway", 256 | "_LocalHistorian", 257 | "_Redundancy", 258 | "_Scheduler", 259 | "_SecurityPolicies", 260 | "_SNMP Agent", 261 | "_System", 262 | "_ThingWorx", 263 | "._Statistics", 264 | "._System", 265 | ".SystemVariable" 266 | }; 267 | 268 | private static bool IsItemsfilter(string group) 269 | { 270 | bool result = false; 271 | foreach (string filter in Itemsfilter) 272 | { 273 | if (-1 != group.LastIndexOf(filter)) 274 | { 275 | return true; 276 | } 277 | } 278 | 279 | return result; 280 | } 281 | } 282 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------