mirror of
				https://gitee.com/ThingsGateway/ThingsGateway.git
				synced 2025-10-31 23:53:58 +08:00 
			
		
		
		
	Compare commits
	
		
			617 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 517bd0394d | ||
|   | 70adb97fb5 | ||
|   | 623d44cabe | ||
|   | 0d479ca00b | ||
|   | 8bc49ef437 | ||
|   | f83fcec786 | ||
|   | 93690ce40d | ||
|   | f82c5f2f27 | ||
|   | a83c1c3899 | ||
|   | 91d6aed109 | ||
|   | db8f8fe51d | ||
|   | 4596004b17 | ||
|   | d5540906cb | ||
|   | 90796a979d | ||
|   | 2190a87772 | ||
|   | c5953b83f8 | ||
|   | 24bc60abf0 | ||
|   | 31eee6b009 | ||
|   | c5da565a8f | ||
|   | 947cd712e1 | ||
|   | edc208f96b | ||
|   | 1fb0296ee7 | ||
|   | 6488d3df87 | ||
|   | 56189d78e0 | ||
|   | bff18127b8 | ||
|   | 363206e0ba | ||
|   | fd3e378501 | ||
|   | 4ba2fe4c9d | ||
|   | 2c499626ad | ||
|   | 2b581a03c3 | ||
|   | 450c15210a | ||
|   | 65fed8cc93 | ||
|   | 4b64771ea2 | ||
|   | f39977a6ff | ||
|   | 933b535caa | ||
|   | 8abc5d2f20 | ||
|   | d8783cd994 | ||
|   | d5d087feb5 | ||
|   | 6ba3399df7 | ||
|   | 65124b3aa8 | ||
|   | 98597f4726 | ||
|   | e7981f0d8e | ||
|   | cf654427c3 | ||
|   | ff2f628282 | ||
|   | ae818ca265 | ||
|   | 0f2aed458e | ||
|   | d486c44ff6 | ||
|   | ca7b9980bf | ||
|   | 3c71e6a8e3 | ||
|   | 542442864c | ||
|   | 5edb64fa85 | ||
|   | 8dc1c898a3 | ||
|   | 1ed35726b0 | ||
|   | 27fae9ebaa | ||
|   | b103f25c94 | ||
|   | abff450274 | ||
|   | c260736a11 | ||
|   | 166ac2307a | ||
|   | b21a4e1a4d | ||
|   | f7dc943fa3 | ||
|   | bfbd2693ec | ||
|   | 819e71c993 | ||
|   | 9fd0b489a2 | ||
|   | f5fe9f8dae | ||
|   | f9ffc18145 | ||
|   | 08db5b983a | ||
|   | 5b3b4c8c50 | ||
|   | 73f914ffc4 | ||
|   | d6bdd73ed6 | ||
|   | 7370ee7349 | ||
|   | 4574596bac | ||
|   | 4d16855e36 | ||
|   | 13a0d4d282 | ||
|   | b9cd06b829 | ||
|   | 5b460e8fa2 | ||
|   | 41087edf17 | ||
|   | 2afcc38e38 | ||
|   | e59ccce25f | ||
|   | d7425890e8 | ||
|   | a989a837fb | ||
|   | db1221da50 | ||
|   | cf794569ed | ||
|   | 51e5bbab0d | ||
|   | 2c197ed2b2 | ||
|   | d8fc6665b3 | ||
|   | c671a79822 | ||
|   | 9d93ce4c41 | ||
|   | a6d99fe227 | ||
|   | 923b8bca31 | ||
|   | e2c30d1c88 | ||
|   | b6d9f2a04e | ||
|   | 57306ea664 | ||
|   | cd7f3fd02f | ||
|   | 0482e077a8 | ||
|   | 5f986a45ca | ||
|   | ca7b49c0d5 | ||
|   | 52dd555e6c | ||
|   | 579b1a59f9 | ||
|   | 5299c5c4be | ||
|   | f7756bccef | ||
|   | a6b874d160 | ||
|   | 3e5fb3ddcf | ||
|   | 5e6bcb12d3 | ||
|   | 14303f1429 | ||
|   | 96711ba022 | ||
|   | cbfc0fdbdc | ||
|   | 6e81886c0e | ||
|   | 2d976bc132 | ||
|   | 57f6a476af | ||
|   | 8491ed296e | ||
|   | cd1288afdc | ||
|   | ec6c830cb0 | ||
|   | 2f86ccc4bf | ||
|   | 8ca445aec0 | ||
|   | 1e1f27c8a5 | ||
|   | 2b84bde367 | ||
|   | b52e58551d | ||
|   | 9aceed00bf | ||
|   | 58814f7f74 | ||
|   | 6a70ef9f31 | ||
|   | 82cc4ca500 | ||
|   | 4567fa04ed | ||
|   | 8b98b5d818 | ||
|   | 176d0351af | ||
|   | d63dc3384b | ||
|   | 1ccd704e30 | ||
|   | f5d23dbe79 | ||
|   | 75bfe53ac3 | ||
|   | 3308f916dd | ||
|   | e7140279ca | ||
|   | 1034719f5e | ||
|   | 2c00043a7f | ||
|   | 65c695d9ce | ||
|   | 57253fe46a | ||
|   | 4e5c443440 | ||
|   | 0b3b73d8ec | ||
|   | 921eabc134 | ||
|   | 0faa428751 | ||
|   | f71a2fdd63 | ||
|   | 4eb9ed8aba | ||
|   | d7b549abb8 | ||
|   | 95d723c578 | ||
|   | 2fcd853e86 | ||
|   | 07eef7c812 | ||
|   | b01e0757fa | ||
|   | 32844a20c6 | ||
|   | 5b6532c601 | ||
|   | 2c5b4b4027 | ||
|   | 72d7ecf195 | ||
|   | 2cfa6b4306 | ||
|   | 6f6ffde0ab | ||
|   | 1694739a16 | ||
|   | 95d1e8bfca | ||
|   | 60dec08e3c | ||
|   | a99d71be93 | ||
|   | f1331b6a0c | ||
|   | 10d66b642b | ||
|   | cd2310e4a8 | ||
|   | 1b399cf6b0 | ||
|   | 877445bc0a | ||
|   | 9a5b345bde | ||
|   | fc9e8ea7b3 | ||
|   | 32be6fcfc1 | ||
|   | 49847236c2 | ||
|   | d8424443e6 | ||
|   | f3b571ec3f | ||
|   | 99318bb5d7 | ||
|   | 1aa154c9aa | ||
|   | c65d8a445b | ||
|   | 80f4f85570 | ||
|   | 5beee43a6b | ||
|   | 8d6ae203a0 | ||
|   | 4353479a5c | ||
|   | 34d7687f9e | ||
|   | b1dc3cf4af | ||
|   | 6a58b95933 | ||
|   | d3badfd02b | ||
|   | 0098be057b | ||
|   | 6f972aa515 | ||
|   | 7407ba6313 | ||
|   | 1c79de207b | ||
|   | 257c79db92 | ||
|   | 9d1934a308 | ||
|   | d70f959902 | ||
|   | e4d810222f | ||
|   | bc1af4ae07 | ||
|   | 6e688ef43f | ||
|   | f0fe1b23dc | ||
|   | aaf2006401 | ||
|   | b821e26935 | ||
|   | 7ae4287157 | ||
|   | c6fcc38a65 | ||
|   | ab2d5c8853 | ||
|   | 5e557ff0bc | ||
|   | 918ca449a1 | ||
|   | 8e73368008 | ||
|   | f3c1faf672 | ||
|   | d6df04dd6a | ||
|   | b1b9e51ab6 | ||
|   | e49d4770ac | ||
|   | 8fa1075511 | ||
|   | 9a70169b94 | ||
|   | fefb928237 | ||
|   | ad7e700d0d | ||
|   | 1699c69147 | ||
|   | 1695f7cece | ||
|   | 052c27f907 | ||
|   | dc46c32b30 | ||
|   | fa63349bb2 | ||
|   | ffe26448a6 | ||
|   | 4af51e8a84 | ||
|   | 1e453cf5a5 | ||
|   | 591282b87d | ||
|   | e87528d520 | ||
|   | d79eb0411d | ||
|   | ac1e0a4cf7 | ||
|   | 9525eab130 | ||
|   | 89b317496c | ||
|   | 13be91e78b | ||
|   | f68c1437f3 | ||
|   | 4c64c969bb | ||
|   | b4bf3b5138 | ||
|   | 083bc4b400 | ||
|   | e8683c5bcc | ||
|   | 80e0d1de91 | ||
|   | dbe841037e | ||
|   | bdd537c33c | ||
|   | c0c3846094 | ||
|   | 9e8710e7d2 | ||
|   | 475553fdf6 | ||
|   | 9d570f5b45 | ||
|   | af7fafd34f | ||
|   | d43130f4fc | ||
|   | 7500194620 | ||
|   | eb27c29144 | ||
|   | 43260b3e24 | ||
|   | f80713f0aa | ||
|   | 0c4bdc7ad1 | ||
|   | 811cff7bd0 | ||
|   | 30269aa75c | ||
|   | e345ef7083 | ||
|   | f559c9b8f7 | ||
|   | f4af0916b2 | ||
|   | f15f14f28d | ||
|   | 834f44f58d | ||
|   | b36f45dcf4 | ||
|   | 11ba21c9a8 | ||
|   | b045557ce1 | ||
|   | 0dd251a3f6 | ||
|   | 793acb1725 | ||
|   | 921243e8bd | ||
|   | bd9d7a90d9 | ||
|   | cc444a4cea | ||
|   | 38ca1fa168 | ||
|   | 7a552b87ec | ||
|   | 36923d3190 | ||
|   | a9d3017123 | ||
|   | 313acd4976 | ||
|   | a4c91bb268 | ||
|   | f9b566984b | ||
|   | 8dd261854d | ||
|   | 7351e62d87 | ||
|   | 0593ae720b | ||
|   | a0a7b08e08 | ||
|   | 9a3bc6b8b3 | ||
|   | 5acae17f71 | ||
|   | f1e5b76ef2 | ||
|   | 53c628fde9 | ||
|   | baca0a70c0 | ||
|   | 3e8d0af404 | ||
|   | cf9a91d9d5 | ||
|   | 02b9e282c6 | ||
|   | 9ce87f235f | ||
|   | e329bea1b2 | ||
|   | 8086e7b54d | ||
|   | f7a875606e | ||
|   | 196eaf85f4 | ||
|   | 876a55668e | ||
|   | 05bd21bdd5 | ||
|   | fb51a08cc6 | ||
|   | dd83d7f4d3 | ||
|   | 842a56f7ce | ||
|   | 9246a6e797 | ||
|   | 8ad693f717 | ||
|   | f4c2ee7cc4 | ||
|   | 6043441faa | ||
|   | 4a065c3710 | ||
|   | 0ef800bdd7 | ||
|   | 56eaa1910d | ||
|   | 201788e286 | ||
|   | 506e0f144f | ||
|   | 72f68bfdd9 | ||
|   | 2f9869b11d | ||
|   | 8ffcf6498c | ||
|   | d224ae1923 | ||
|   | fed2063a19 | ||
|   | db2810cdd7 | ||
|   | 4f1a6781ef | ||
|   | beffa5d5a4 | ||
|   | 7a20f1de07 | ||
|   | cd25cf726b | ||
|   | d6b1bc3842 | ||
|   | a4385fb9bb | ||
|   | 7045f2b8ea | ||
|   | 07ca1a4de8 | ||
|   | 24f289e692 | ||
|   | 01bcdaae2d | ||
|   | 55890008d1 | ||
|   | 5ab9b01879 | ||
|   | e4abb333b3 | ||
|   | 09f476c745 | ||
|   | 8806e68dce | ||
|   | 2ef1e25cd8 | ||
|   | 10e7f202aa | ||
|   | ccd7000c09 | ||
|   | 8ee7b798cf | ||
|   | 7733cf5bf0 | ||
|   | a05ce86dd7 | ||
|   | 91f51c32e8 | ||
|   | f910202bba | ||
|   | 6d77194a8f | ||
|   | 9deb89c15f | ||
|   | 4b62a092b4 | ||
|   | 81c8f626f9 | ||
|   | 3e846c42fb | ||
|   | 63ad7fd766 | ||
|   | 9ff1e9aa34 | ||
|   | 8d162b6f3d | ||
|   | 9844d10bef | ||
|   | b908fa8489 | ||
|   | 15a10643a7 | ||
|   | 299617aca1 | ||
|   | 45647d697a | ||
|   | 48f5105d38 | ||
|   | fe1c741d68 | ||
|   | fa42cc1f00 | ||
|   | 42cf5e7a81 | ||
|   | 47905e1aa1 | ||
|   | 9a8e907df3 | ||
|   | 106fe85582 | ||
|   | 4b3571bd57 | ||
|   | 96b537401a | ||
|   | 721c9eb057 | ||
|   | 51701bf6d6 | ||
|   | dbde68bd56 | ||
|   | ad2c9f585a | ||
|   | 562093c468 | ||
|   | b0295584a3 | ||
|   | 208c54de98 | ||
|   | 63e2d941a1 | ||
|   | 3956838e9c | ||
|   | abeee58bb0 | ||
|   | d5b1b49722 | ||
|   | 564ed03ff8 | ||
|   | 70db4c76b4 | ||
|   | d059f7975b | ||
|   | 4e74e6dc2d | ||
|   | b6deb96658 | ||
|   | 3839e966be | ||
|   | 3dd035849c | ||
|   | 3d6532b5d6 | ||
|   | bf7c175ee7 | ||
|   | f84af35ed6 | ||
|   | 99063b3eb1 | ||
|   | 3bec18f28d | ||
|   | 15de7a7894 | ||
|   | e20e04e677 | ||
|   | 5fc6ae2835 | ||
|   | 7d281b8c96 | ||
|   | 4880b801a7 | ||
|   | 74e354456a | ||
|   | af2e03aa36 | ||
|   | d8fa660ab6 | ||
|   | 1a62d48297 | ||
|   | 7ba01be13d | ||
|   | 1a83d64db7 | ||
|   | 5b53014c40 | ||
|   | 83685340af | ||
|   | 31e0cc4dec | ||
|   | 56b87fc1f5 | ||
|   | 6b956a2dd7 | ||
|   | 1937623d7d | ||
|   | 3b60b10945 | ||
|   | 7173acd350 | ||
|   | 6310d87338 | ||
|   | 49a1ed7c18 | ||
|   | d426e280d9 | ||
|   | 6154fb29f1 | ||
|   | 97d48ef9d6 | ||
|   | 88992625c4 | ||
|   | bc6eb44218 | ||
|   | cf9ccd799d | ||
|   | ffa0e4e771 | ||
|   | 60fa9c196c | ||
|   | df860d22fb | ||
|   | cb46ff326c | ||
|   | f277a853ef | ||
|   | 9ae34f67c3 | ||
|   | c9223218cc | ||
|   | c0dd645aba | ||
|   | 2e948eb5b6 | ||
|   | c3276889cf | ||
|   | a76ca8282d | ||
|   | 8ce6b8362f | ||
|   | 842fb12f05 | ||
|   | d63e1511af | ||
|   | 278783b8e0 | ||
|   | d24e3c922d | ||
|   | 1d02cd2283 | ||
|   | 8edeb82a87 | ||
|   | 146e9279de | ||
|   | 47105f50a9 | ||
|   | 16c9c80f37 | ||
|   | 8e7e4bc95a | ||
|   | 0aa3d2f930 | ||
|   | ce77755a1e | ||
|   | 0f31f20c87 | ||
|   | ee6da2aaa5 | ||
|   | a35f087cd9 | ||
|   | 6e029b44dd | ||
|   | 973c0cff34 | ||
|   | 2027eea6ac | ||
|   | 2f43692f33 | ||
|   | 6d24992f88 | ||
|   | b4388a58d6 | ||
|   | 158aa05fac | ||
|   | f2731bf55e | ||
|   | 7304e99fce | ||
|   | 02700b83eb | ||
|   | 676b25acf9 | ||
|   | 556359ea2d | ||
|   | b72923e0f5 | ||
|   | 115ac9f75e | ||
|   | 32e36f6708 | ||
|   | d949b7a4f9 | ||
|   | eae1171ff5 | ||
|   | 76a1b75a51 | ||
|   | 8882c0daea | ||
|   | 07ebc16d59 | ||
|   | 0ceb109964 | ||
|   | 118b0d0038 | ||
|   | 5e87067792 | ||
|   | c946a252e8 | ||
|   | f9ad2ba1dd | ||
|   | 0d0ecd33bd | ||
|   | e4b98fd05b | ||
|   | 95a5933303 | ||
|   | da3b55fa64 | ||
|   | fbbabfb90e | ||
|   | f13da6830d | ||
|   | f560a8e2f8 | ||
|   | 56f1139c2f | ||
|   | 773bdfc1e2 | ||
|   | f449666628 | ||
|   | 3f282de0ab | ||
|   | 440dd8d22f | ||
|   | dcff9de2f7 | ||
|   | a192866543 | ||
|   | 10081416de | ||
|   | e2bed618f9 | ||
|   | 03ab1f3823 | ||
|   | ac8aeb63d9 | ||
|   | 2e16d822fa | ||
|   | e407d873fa | ||
|   | fd712a1dbe | ||
|   | e9028b40ce | ||
|   | c9da3dee7c | ||
|   | c8c224e202 | ||
|   | f34559daaf | ||
|   | 9fefbf4c27 | ||
|   | 1af9fd73ea | ||
|   | 75ef394eff | ||
|   | ec6cc2c63e | ||
|   | 06bc2e192b | ||
|   | 78701ec7c1 | ||
|   | c925fab7e4 | ||
|   | 42fd72c164 | ||
|   | 7fd160e1a2 | ||
|   | 97a0d940eb | ||
|   | efaa099d81 | ||
|   | 47864a804b | ||
|   | 91136c0e43 | ||
|   | 28c3b1bd61 | ||
|   | 551352bc40 | ||
|   | e73c24c925 | ||
|   | 7ec4c286cc | ||
|   | 6705e2ec4b | ||
|   | 6f0373063b | ||
|   | f64eef60b5 | ||
|   | 89546bf86b | ||
|   | 793678feca | ||
|   | 923cc3019a | ||
|   | 10eb98a5f6 | ||
|   | bd9e89d8dd | ||
|   | 1926b4ce73 | ||
|   | 4ef3062d74 | ||
|   | abb6e0f60f | ||
|   | f204d8d84e | ||
|   | fa301656f1 | ||
|   | 7e1221028f | ||
|   | 41308cb2dd | ||
|   | 130600521c | ||
|   | cd57548a48 | ||
|   | efacc99f76 | ||
|   | f0d236e172 | ||
|   | a8118bd8c6 | ||
|   | 0e58f2ef53 | ||
|   | f4b22b3a0c | ||
|   | df5bd281c7 | ||
|   | a3f23837ce | ||
|   | 612d989b97 | ||
|   | 42c01ee9a2 | ||
|   | 14074db591 | ||
|   | 43dfdd7942 | ||
|   | f397b97ccf | ||
|   | 95f8716144 | ||
|   | 17ba472b2e | ||
|   | 42d82571ab | ||
|   | 9119a28141 | ||
|   | a32263d838 | ||
|   | 208ae2bb88 | ||
|   | 4d85462a85 | ||
|   | f601aa9ca0 | ||
|   | 8aee3ad455 | ||
|   | 6a2a1e9561 | ||
|   | 5f8786c9dc | ||
|   | 73f1d3eead | ||
|   | 2bf21bb3c3 | ||
|   | f80f0dbb11 | ||
|   | 37518c70c4 | ||
|   | e5951b5bef | ||
|   | ab320bd90b | ||
|   | 7bd36b5371 | ||
|   | b882b0f2bc | ||
|   | 38d7ae73cc | ||
|   | 4527c6ee5d | ||
|   | 85829e70c1 | ||
|   | 256c08d82a | ||
|   | c2ce03c047 | ||
|   | f2af19e198 | ||
|   | 930b7c092d | ||
|   | 00757c69c6 | ||
|   | 55f267d0fc | ||
|   | 6b96aff6e8 | ||
|   | 32b773a8fa | ||
|   | 03089adad6 | ||
|   | 4a1fe746ab | ||
|   | aa52c05d2c | ||
|   | 26407a43e7 | ||
|   | a02934bf19 | ||
|   | 09c65fba09 | ||
|   | 4305c727d0 | ||
|   | 188339897f | ||
|   | 4ecff9a707 | ||
|   | 355aed49c6 | ||
|   | 4717b6b0f0 | ||
|   | 45ebe9048d | ||
|   | b2170c49a3 | ||
|   | dc2f4d6115 | ||
|   | 1eb132440f | ||
|   | a464bbc37a | ||
|   | ed995697c2 | ||
|   | 163cd84c7b | ||
|   | 293d7cc292 | ||
|   | 5de1b4e74c | ||
|   | 7b474975da | ||
|   | beab51516b | ||
|   | fe8685a50c | ||
|   | f9af5d0885 | ||
|   | e8136a9720 | ||
|   | 531e5d4556 | ||
|   | e66255963a | ||
|   | 246aac8ee4 | ||
|   | 23cfeff685 | ||
|   | a5e7e0d126 | ||
|   | 5bebc30ba0 | ||
|   | 0e7057f5b9 | ||
|   | 7c6c365ba4 | ||
|   | 424c9bb0c5 | ||
|   | 9d0f26594c | ||
|   | 99c17de079 | ||
|   | b1e3dd0af6 | ||
|   | 261cb89530 | ||
|   | ff6773ba37 | ||
|   | bdfbbfcbbd | ||
|   | 0c4cd56758 | ||
|   | 4a36658321 | ||
|   | 7aae938685 | ||
|   | 3723401e7a | ||
|   | 70631366a9 | ||
|   | 0e40bbda3e | ||
|   | e9aa475398 | ||
|   | 8d2a811184 | ||
|   | dd7f5b6700 | ||
|   | a4f6277737 | ||
|   | c2bfaacbb7 | ||
|   | a17cbfa2d4 | ||
|   | fb9a101555 | ||
|   | e319cf0200 | ||
|   | 0a8395ef6a | ||
|   | 38df5e01be | ||
|   | ebd891a868 | ||
|   | 4ab2395cbe | ||
|   | 5f1f989fc9 | ||
|   | 44b709eee3 | ||
|   | d0d7726597 | ||
|   | 054c342aeb | ||
|   | c79c33baf7 | ||
|   | 23b00e35b2 | ||
|   | fe51079266 | ||
|   | 0791b0bbee | ||
|   | dbf04c8eeb | ||
|   | 6204256df8 | ||
|   | 93cc8c2327 | ||
|   | 68a2e5bbbc | ||
|   | 72792153f2 | ||
|   | 88b6ef1897 | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -363,6 +363,4 @@ MigrationBackup/ | ||||
| FodyWeavers.xsd | ||||
|  | ||||
|  | ||||
| /framework/*pro* | ||||
| /framework/*Pro* | ||||
|  | ||||
|   | ||||
							
								
								
									
										7
									
								
								framework/.editorconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								framework/.editorconfig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| [*.cs] | ||||
|  | ||||
| # CA1848: 使用 LoggerMessage 委托 | ||||
| dotnet_diagnostic.CA1848.severity = none | ||||
|  | ||||
| # CA2254: 模板应为静态表达式 | ||||
| dotnet_diagnostic.CA2254.severity = suggestion | ||||
							
								
								
									
										63
									
								
								framework/.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								framework/.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| ############################################################################### | ||||
| # Set default behavior to automatically normalize line endings. | ||||
| ############################################################################### | ||||
| * text=auto | ||||
|  | ||||
| ############################################################################### | ||||
| # Set default behavior for command prompt diff. | ||||
| # | ||||
| # This is need for earlier builds of msysgit that does not have it on by | ||||
| # default for csharp files. | ||||
| # Note: This is only used by command line | ||||
| ############################################################################### | ||||
| #*.cs     diff=csharp | ||||
|  | ||||
| ############################################################################### | ||||
| # Set the merge driver for project and solution files | ||||
| # | ||||
| # Merging from the command prompt will add diff markers to the files if there | ||||
| # are conflicts (Merging from VS is not affected by the settings below, in VS | ||||
| # the diff markers are never inserted). Diff markers may cause the following  | ||||
| # file extensions to fail to load in VS. An alternative would be to treat | ||||
| # these files as binary and thus will always conflict and require user | ||||
| # intervention with every merge. To do so, just uncomment the entries below | ||||
| ############################################################################### | ||||
| #*.sln       merge=binary | ||||
| #*.csproj    merge=binary | ||||
| #*.vbproj    merge=binary | ||||
| #*.vcxproj   merge=binary | ||||
| #*.vcproj    merge=binary | ||||
| #*.dbproj    merge=binary | ||||
| #*.fsproj    merge=binary | ||||
| #*.lsproj    merge=binary | ||||
| #*.wixproj   merge=binary | ||||
| #*.modelproj merge=binary | ||||
| #*.sqlproj   merge=binary | ||||
| #*.wwaproj   merge=binary | ||||
|  | ||||
| ############################################################################### | ||||
| # behavior for image files | ||||
| # | ||||
| # image files are treated as binary by default. | ||||
| ############################################################################### | ||||
| #*.jpg   binary | ||||
| #*.png   binary | ||||
| #*.gif   binary | ||||
|  | ||||
| ############################################################################### | ||||
| # diff behavior for common document formats | ||||
| #  | ||||
| # Convert binary document formats to text before diffing them. This feature | ||||
| # is only available from the command line. Turn it on by uncommenting the  | ||||
| # entries below. | ||||
| ############################################################################### | ||||
| #*.doc   diff=astextplain | ||||
| #*.DOC   diff=astextplain | ||||
| #*.docx  diff=astextplain | ||||
| #*.DOCX  diff=astextplain | ||||
| #*.dot   diff=astextplain | ||||
| #*.DOT   diff=astextplain | ||||
| #*.pdf   diff=astextplain | ||||
| #*.PDF   diff=astextplain | ||||
| #*.rtf   diff=astextplain | ||||
| #*.RTF   diff=astextplain | ||||
							
								
								
									
										364
									
								
								framework/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										364
									
								
								framework/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,364 @@ | ||||
| ## Ignore Visual Studio temporary files, build results, and | ||||
| ## files generated by popular Visual Studio add-ons. | ||||
| ## | ||||
| ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore | ||||
|  | ||||
| # User-specific files | ||||
| *.rsuser | ||||
| *.suo | ||||
| *.user | ||||
| *.userosscache | ||||
| *.sln.docstates | ||||
|  | ||||
| # User-specific files (MonoDevelop/Xamarin Studio) | ||||
| *.userprefs | ||||
|  | ||||
| # Mono auto generated files | ||||
| mono_crash.* | ||||
|  | ||||
| # Build results | ||||
| [Dd]ebug/ | ||||
| [Dd]ebugPublic/ | ||||
| [Rr]elease/ | ||||
| [Rr]eleases/ | ||||
| x64/ | ||||
| x86/ | ||||
| [Ww][Ii][Nn]32/ | ||||
| [Aa][Rr][Mm]/ | ||||
| [Aa][Rr][Mm]64/ | ||||
| bld/ | ||||
| [Bb]in/ | ||||
| [Oo]bj/ | ||||
| [Oo]ut/ | ||||
| [Ll]og/ | ||||
| [Ll]ogs/ | ||||
|  | ||||
| # Visual Studio 2015/2017 cache/options directory | ||||
| .vs/ | ||||
| # Uncomment if you have tasks that create the project's static files in wwwroot | ||||
| #wwwroot/ | ||||
|  | ||||
| # Visual Studio 2017 auto generated files | ||||
| Generated\ Files/ | ||||
|  | ||||
| # MSTest test Results | ||||
| [Tt]est[Rr]esult*/ | ||||
| [Bb]uild[Ll]og.* | ||||
|  | ||||
| # NUnit | ||||
| *.VisualState.xml | ||||
| TestResult.xml | ||||
| nunit-*.xml | ||||
|  | ||||
| # Build Results of an ATL Project | ||||
| [Dd]ebugPS/ | ||||
| [Rr]eleasePS/ | ||||
| dlldata.c | ||||
|  | ||||
| # Benchmark Results | ||||
| BenchmarkDotNet.Artifacts/ | ||||
|  | ||||
| # .NET Core | ||||
| project.lock.json | ||||
| project.fragment.lock.json | ||||
| artifacts/ | ||||
|  | ||||
| # ASP.NET Scaffolding | ||||
| ScaffoldingReadMe.txt | ||||
|  | ||||
| # StyleCop | ||||
| StyleCopReport.xml | ||||
|  | ||||
| # Files built by Visual Studio | ||||
| *_i.c | ||||
| *_p.c | ||||
| *_h.h | ||||
| *.ilk | ||||
| *.meta | ||||
| *.obj | ||||
| *.iobj | ||||
| *.pch | ||||
| *.pdb | ||||
| *.ipdb | ||||
| *.pgc | ||||
| *.pgd | ||||
| *.rsp | ||||
| *.sbr | ||||
| *.tlb | ||||
| *.tli | ||||
| *.tlh | ||||
| *.tmp | ||||
| *.tmp_proj | ||||
| *_wpftmp.csproj | ||||
| *.log | ||||
| *.vspscc | ||||
| *.vssscc | ||||
| .builds | ||||
| *.pidb | ||||
| *.svclog | ||||
| *.scc | ||||
|  | ||||
| # Chutzpah Test files | ||||
| _Chutzpah* | ||||
|  | ||||
| # Visual C++ cache files | ||||
| ipch/ | ||||
| *.aps | ||||
| *.ncb | ||||
| *.opendb | ||||
| *.opensdf | ||||
| *.sdf | ||||
| *.cachefile | ||||
| *.VC.db | ||||
| *.VC.VC.opendb | ||||
|  | ||||
| # Visual Studio profiler | ||||
| *.psess | ||||
| *.vsp | ||||
| *.vspx | ||||
| *.sap | ||||
|  | ||||
| # Visual Studio Trace Files | ||||
| *.e2e | ||||
|  | ||||
| # TFS 2012 Local Workspace | ||||
| $tf/ | ||||
|  | ||||
| # Guidance Automation Toolkit | ||||
| *.gpState | ||||
|  | ||||
| # ReSharper is a .NET coding add-in | ||||
| _ReSharper*/ | ||||
| *.[Rr]e[Ss]harper | ||||
| *.DotSettings.user | ||||
|  | ||||
| # TeamCity is a build add-in | ||||
| _TeamCity* | ||||
|  | ||||
| # DotCover is a Code Coverage Tool | ||||
| *.dotCover | ||||
|  | ||||
| # AxoCover is a Code Coverage Tool | ||||
| .axoCover/* | ||||
| !.axoCover/settings.json | ||||
|  | ||||
| # Coverlet is a free, cross platform Code Coverage Tool | ||||
| coverage*.json | ||||
| coverage*.xml | ||||
| coverage*.info | ||||
|  | ||||
| # Visual Studio code coverage results | ||||
| *.coverage | ||||
| *.coveragexml | ||||
|  | ||||
| # NCrunch | ||||
| _NCrunch_* | ||||
| .*crunch*.local.xml | ||||
| nCrunchTemp_* | ||||
|  | ||||
| # MightyMoose | ||||
| *.mm.* | ||||
| AutoTest.Net/ | ||||
|  | ||||
| # Web workbench (sass) | ||||
| .sass-cache/ | ||||
|  | ||||
| # Installshield output folder | ||||
| [Ee]xpress/ | ||||
|  | ||||
| # DocProject is a documentation generator add-in | ||||
| DocProject/buildhelp/ | ||||
| DocProject/Help/*.HxT | ||||
| DocProject/Help/*.HxC | ||||
| DocProject/Help/*.hhc | ||||
| DocProject/Help/*.hhk | ||||
| DocProject/Help/*.hhp | ||||
| DocProject/Help/Html2 | ||||
| DocProject/Help/html | ||||
|  | ||||
| # Click-Once directory | ||||
| publish/ | ||||
|  | ||||
| # Publish Web Output | ||||
| *.[Pp]ublish.xml | ||||
| *.azurePubxml | ||||
| # Note: Comment the next line if you want to checkin your web deploy settings, | ||||
| # but database connection strings (with potential passwords) will be unencrypted | ||||
| *.pubxml | ||||
| *.publishproj | ||||
|  | ||||
| # Microsoft Azure Web App publish settings. Comment the next line if you want to | ||||
| # checkin your Azure Web App publish settings, but sensitive information contained | ||||
| # in these scripts will be unencrypted | ||||
| PublishScripts/ | ||||
|  | ||||
| # NuGet Packages | ||||
| *.nupkg | ||||
| # NuGet Symbol Packages | ||||
| *.snupkg | ||||
| # The packages folder can be ignored because of Package Restore | ||||
| **/[Pp]ackages/* | ||||
| # except build/, which is used as an MSBuild target. | ||||
| !**/[Pp]ackages/build/ | ||||
| # Uncomment if necessary however generally it will be regenerated when needed | ||||
| #!**/[Pp]ackages/repositories.config | ||||
| # NuGet v3's project.json files produces more ignorable files | ||||
| *.nuget.props | ||||
| *.nuget.targets | ||||
|  | ||||
| # Microsoft Azure Build Output | ||||
| csx/ | ||||
| *.build.csdef | ||||
|  | ||||
| # Microsoft Azure Emulator | ||||
| ecf/ | ||||
| rcf/ | ||||
|  | ||||
| # Windows Store app package directories and files | ||||
| AppPackages/ | ||||
| BundleArtifacts/ | ||||
| Package.StoreAssociation.xml | ||||
| _pkginfo.txt | ||||
| *.appx | ||||
| *.appxbundle | ||||
| *.appxupload | ||||
|  | ||||
| # Visual Studio cache files | ||||
| # files ending in .cache can be ignored | ||||
| *.[Cc]ache | ||||
| # but keep track of directories ending in .cache | ||||
| !?*.[Cc]ache/ | ||||
|  | ||||
| # Others | ||||
| ClientBin/ | ||||
| ~$* | ||||
| *~ | ||||
| *.dbmdl | ||||
| *.dbproj.schemaview | ||||
| *.jfm | ||||
| *.pfx | ||||
| *.publishsettings | ||||
| orleans.codegen.cs | ||||
|  | ||||
| # Including strong name files can present a security risk | ||||
| # (https://github.com/github/gitignore/pull/2483#issue-259490424) | ||||
| #*.snk | ||||
|  | ||||
| # Since there are multiple workflows, uncomment next line to ignore bower_components | ||||
| # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) | ||||
| #bower_components/ | ||||
|  | ||||
| # RIA/Silverlight projects | ||||
| Generated_Code/ | ||||
|  | ||||
| # Backup & report files from converting an old project file | ||||
| # to a newer Visual Studio version. Backup files are not needed, | ||||
| # because we have git ;-) | ||||
| _UpgradeReport_Files/ | ||||
| Backup*/ | ||||
| UpgradeLog*.XML | ||||
| UpgradeLog*.htm | ||||
| ServiceFabricBackup/ | ||||
| *.rptproj.bak | ||||
|  | ||||
| # SQL Server files | ||||
| *.mdf | ||||
| *.ldf | ||||
| *.ndf | ||||
|  | ||||
| # Business Intelligence projects | ||||
| *.rdl.data | ||||
| *.bim.layout | ||||
| *.bim_*.settings | ||||
| *.rptproj.rsuser | ||||
| *- [Bb]ackup.rdl | ||||
| *- [Bb]ackup ([0-9]).rdl | ||||
| *- [Bb]ackup ([0-9][0-9]).rdl | ||||
|  | ||||
| # Microsoft Fakes | ||||
| FakesAssemblies/ | ||||
|  | ||||
| # GhostDoc plugin setting file | ||||
| *.GhostDoc.xml | ||||
|  | ||||
| # Node.js Tools for Visual Studio | ||||
| .ntvs_analysis.dat | ||||
| node_modules/ | ||||
|  | ||||
| # Visual Studio 6 build log | ||||
| *.plg | ||||
|  | ||||
| # Visual Studio 6 workspace options file | ||||
| *.opt | ||||
|  | ||||
| # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) | ||||
| *.vbw | ||||
|  | ||||
| # Visual Studio LightSwitch build output | ||||
| **/*.HTMLClient/GeneratedArtifacts | ||||
| **/*.DesktopClient/GeneratedArtifacts | ||||
| **/*.DesktopClient/ModelManifest.xml | ||||
| **/*.Server/GeneratedArtifacts | ||||
| **/*.Server/ModelManifest.xml | ||||
| _Pvt_Extensions | ||||
|  | ||||
| # Paket dependency manager | ||||
| .paket/paket.exe | ||||
| paket-files/ | ||||
|  | ||||
| # FAKE - F# Make | ||||
| .fake/ | ||||
|  | ||||
| # CodeRush personal settings | ||||
| .cr/personal | ||||
|  | ||||
| # Python Tools for Visual Studio (PTVS) | ||||
| __pycache__/ | ||||
| *.pyc | ||||
|  | ||||
| # Cake - Uncomment if you are using it | ||||
| # tools/** | ||||
| # !tools/packages.config | ||||
|  | ||||
| # Tabs Studio | ||||
| *.tss | ||||
|  | ||||
| # Telerik's JustMock configuration file | ||||
| *.jmconfig | ||||
|  | ||||
| # BizTalk build output | ||||
| *.btp.cs | ||||
| *.btm.cs | ||||
| *.odx.cs | ||||
| *.xsd.cs | ||||
|  | ||||
| # OpenCover UI analysis results | ||||
| OpenCover/ | ||||
|  | ||||
| # Azure Stream Analytics local run output | ||||
| ASALocalRun/ | ||||
|  | ||||
| # MSBuild Binary and Structured Log | ||||
| *.binlog | ||||
|  | ||||
| # NVidia Nsight GPU debugger configuration file | ||||
| *.nvuser | ||||
|  | ||||
| # MFractors (Xamarin productivity tool) working folder | ||||
| .mfractor/ | ||||
|  | ||||
| # Local History for Visual Studio | ||||
| .localhistory/ | ||||
|  | ||||
| # BeatPulse healthcheck temp database | ||||
| healthchecksdb | ||||
|  | ||||
| # Backup folder for Package Reference Convert tool in Visual Studio 2017 | ||||
| MigrationBackup/ | ||||
|  | ||||
| # Ionide (cross platform F# VS Code tools) working folder | ||||
| .ionide/ | ||||
|  | ||||
| # Fody - auto-generated XML schema | ||||
| FodyWeavers.xsd | ||||
|  | ||||
							
								
								
									
										15
									
								
								framework/Demo/Directory.Build.props
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								framework/Demo/Directory.Build.props
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| <Project> | ||||
| 	<PropertyGroup> | ||||
| 		<Version>3.0.0.8</Version> | ||||
| 		<LangVersion>latest</LangVersion> | ||||
| 		<TargetFrameworks>net6.0;net7.0</TargetFrameworks> | ||||
| 		<Authors>Diego</Authors> | ||||
| 		<Product>ThingsGateway</Product> | ||||
| 		<Copyright>© 2023-present Diego</Copyright> | ||||
| 		<RepositoryUrl>https://gitee.com/diego2098/ThingsGateway</RepositoryUrl> | ||||
| 		<SatelliteResourceLanguages>zh-Hans</SatelliteResourceLanguages> | ||||
| 		<GenerateDocumentationFile>False</GenerateDocumentationFile> | ||||
| 	</PropertyGroup> | ||||
|  | ||||
|  | ||||
| </Project> | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,8 +8,9 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| global using System; | ||||
| global using System.Threading.Tasks; | ||||
| 
 | ||||
| global using ThingsGateway.Components; | ||||
| 
 | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,13 +8,10 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using Photino.Blazor; | ||||
| 
 | ||||
| using ThingsGateway.Core; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Demo; | ||||
| 
 | ||||
| internal class Program | ||||
| @@ -30,13 +26,13 @@ internal class Program | ||||
|         appBuilder.RootComponents.Add<App>("#app"); | ||||
| 
 | ||||
|         appBuilder.Services.ThingsGatewayComponentsConfigureServices(); | ||||
|         appBuilder.Services.ThingsGatewayCoreConfigureServices(); | ||||
|         var app = appBuilder.Build(); | ||||
|         app.MainWindow.SetTitle("ThingsGateway.Foundation.Demo"); | ||||
|         app.MainWindow.SetIconFile("wwwroot/favicon.ico"); | ||||
|         AppDomain.CurrentDomain.UnhandledException += (sender, error) => | ||||
|         { | ||||
|         }; | ||||
| 
 | ||||
|         app.Run(); | ||||
|     } | ||||
| } | ||||
| @@ -2,7 +2,6 @@ | ||||
| 
 | ||||
| 	<PropertyGroup> | ||||
| 		<OutputType>WinExe</OutputType> | ||||
| 		<TargetFrameworks>net6.0;net8.0;</TargetFrameworks> | ||||
| 		<ApplicationIcon>favicon.ico</ApplicationIcon> | ||||
| 	</PropertyGroup> | ||||
| 
 | ||||
| @@ -29,18 +28,5 @@ | ||||
| 	</ItemGroup> | ||||
| 
 | ||||
| 
 | ||||
| 	<ItemGroup> | ||||
| 	  <Content Update="wwwroot\favicon.ico"> | ||||
| 	    <CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||||
| 	  </Content> | ||||
| 	  <Content Update="wwwroot\favicon.png"> | ||||
| 	    <CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||||
| 	  </Content> | ||||
| 	  <Content Update="wwwroot\index.html"> | ||||
| 	    <CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||||
| 	  </Content> | ||||
| 	</ItemGroup> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| </Project> | ||||
| Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB | 
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using Microsoft.AspNetCore.Components; | ||||
| @@ -17,9 +15,7 @@ using Microsoft.AspNetCore.Components; | ||||
| using ThingsGateway.Components; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Demo; | ||||
| 
 | ||||
| using LogLevel = Microsoft.Extensions.Logging.LogLevel; | ||||
| 
 | ||||
| /// <summary> | ||||
| /// 调试UI | ||||
| /// </summary> | ||||
| @@ -38,17 +34,12 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable | ||||
|         this.SafeDispose(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 变量地址 | ||||
|     /// </summary> | ||||
|     public virtual string Address { get; set; } = "40001"; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     [Inject] | ||||
|     public InitTimezone InitTimezone { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 长度 | ||||
|     /// </summary> | ||||
| @@ -58,7 +49,6 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable | ||||
|     /// 默认读写设备 | ||||
|     /// </summary> | ||||
|     public virtual IReadWrite Plc { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 写入值 | ||||
|     /// </summary> | ||||
| @@ -69,12 +59,17 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable | ||||
|     /// </summary> | ||||
|     protected virtual DataTypeEnum DataTypeEnum { get; set; } = DataTypeEnum.Int16; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     [Inject] | ||||
|     public InitTimezone InitTimezone { get; set; } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public virtual void Dispose() | ||||
|     { | ||||
|         _periodicTimer?.Dispose(); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public void LogOut(ThingsGateway.Foundation.Core.LogLevel logLevel, object source, string message, Exception exception) | ||||
|     { | ||||
| @@ -106,8 +101,9 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             Messages.Add((LogLevel.Error, | ||||
|             $"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 错误:{ex}")); | ||||
|             $"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 错误:{ex.Message}")); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
| @@ -130,7 +126,7 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             Messages.Add((LogLevel.Error, | ||||
|             $"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 写入前失败:{ex}")); | ||||
|             $"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 写入前失败:{ex.Message}")); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @@ -140,7 +136,6 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable | ||||
|         _ = RunTimerAsync(); | ||||
|         base.OnInitialized(); | ||||
|     } | ||||
| 
 | ||||
|     private async Task RunTimerAsync() | ||||
|     { | ||||
|         while (await _periodicTimer.WaitForNextTickAsync()) | ||||
| @@ -148,4 +143,6 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable | ||||
|             await InvokeAsync(StateHasChanged); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @@ -47,7 +47,7 @@ | ||||
|                                 <MRow Class="my-1" Justify="JustifyTypes.Start" Align="AlignTypes.Start" NoGutters> | ||||
|                                 <MTextField Class="mx-1 my-1" Style="max-width:200px" Label="读取长度" Dense Outlined HideDetails="@("auto")" @bind-Value=@Length /> | ||||
|                                     <MSelect Class="mx-1 my-1" Style="max-width:200px" @bind-Value="DataTypeEnum" Outlined Label="数据类型" | ||||
|                                              Items=@(typeof(DataTypeEnum).GetEnumList()) | ||||
|                                              Items=@(typeof(DataTypeEnum).GetEnumListWithOutSugar()) | ||||
|                                              MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })" | ||||
|                                              ItemText=@((u) =>u.Description) | ||||
|                                              ItemValue=@(u =>(DataTypeEnum)u.Value) | ||||
| @@ -87,9 +87,9 @@ | ||||
|                                 @foreach (var item in DeviceVariableRunTimes) | ||||
|                                 { | ||||
|                                     <MRow Dense Align="AlignTypes.Center"> | ||||
|                                         <MTextField Class="ma-1" Outlined Style="min-width:100px" Label=@(item.Description(x => x.Address)) Dense HideDetails="@("auto")" @bind-Value=@item.Address></MTextField> | ||||
|                                         <MSelect Class="mx-1 my-1" Style="max-width:120px" @bind-Value="item.DataTypeEnum" Outlined Label=@(item.Description(x => x.DataTypeEnum)) | ||||
|                                                  Items=@(typeof(DataTypeEnum).GetEnumList()) | ||||
|                                         <MTextField Class="ma-1" Outlined Style="min-width:100px" Label=@(item.DescriptionWithOutSugar(x => x.VariableAddress)) Dense HideDetails="@("auto")" @bind-Value=@item.VariableAddress></MTextField> | ||||
|                                         <MSelect Class="mx-1 my-1" Style="max-width:120px" @bind-Value="item.DataTypeEnum" Outlined Label=@(item.DescriptionWithOutSugar(x => x.DataTypeEnum)) | ||||
|                                                  Items=@(typeof(DataTypeEnum).GetEnumListWithOutSugar()) | ||||
|                                                  MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })" | ||||
|                                                  ItemText=@((u) =>u.Description) | ||||
|                                                  ItemValue=@(u =>(DataTypeEnum)u.Value) | ||||
| @@ -97,7 +97,7 @@ | ||||
|                                               Dense> | ||||
|                                     </MSelect> | ||||
| 
 | ||||
|                                     <MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(item.Description(x => x.IntervalTime)) Dense HideDetails="@("auto")" @bind-Value=@item.IntervalTime></MTextField> | ||||
|                                     <MTextField Class="ma-1" Outlined Style="max-width:100px" Label=@(item.DescriptionWithOutSugar(x => x.IntervalTime)) Dense HideDetails="@("auto")" @bind-Value=@item.IntervalTime></MTextField> | ||||
| 
 | ||||
|                                         <MTextField Class="ma-1" Outlined Style="max-width:100px" Label=实时值 Readonly ClearIcon="" Dense HideDetails="@("auto")" Value=item.Value?.ToJsonString()></MTextField> | ||||
| 
 | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,15 +8,17 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using BlazorComponent; | ||||
| 
 | ||||
| using Microsoft.AspNetCore.Components; | ||||
| 
 | ||||
| using System.Collections.Generic; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Demo; | ||||
| 
 | ||||
| 
 | ||||
| /// <inheritdoc/> | ||||
| public partial class DriverDebugUIPage : DriverDebugUIBase | ||||
| { | ||||
| @@ -25,43 +26,39 @@ public partial class DriverDebugUIPage : DriverDebugUIBase | ||||
|     /// DeviceVariableRunTimes | ||||
|     /// </summary> | ||||
|     public List<DeviceVariableRunTime> DeviceVariableRunTimes; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// MaxPack | ||||
|     /// </summary> | ||||
|     public int MaxPack = 100; | ||||
| 
 | ||||
|     private StringNumber _selected = 0; | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     ~DriverDebugUIPage() | ||||
|     /// <summary> | ||||
|     /// MulReadAsync | ||||
|     /// </summary> | ||||
|     /// <returns></returns> | ||||
|     public async Task MulReadAsync() | ||||
|     { | ||||
|         this.SafeDispose(); | ||||
|         var deviceVariableSourceReads = Plc.LoadSourceRead<DeviceVariableSourceRead, DeviceVariableRunTime>(DeviceVariableRunTimes, MaxPack); | ||||
|         foreach (var item in deviceVariableSourceReads) | ||||
|         { | ||||
|             var result = await Plc.ReadAsync(item.VariableAddress, item.Length); | ||||
|             if (result.IsSuccess) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     item.DeviceVariableRunTimes.PraseStructContent(Plc, result.Content); | ||||
|                     Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + result.Content.ToHexString(' '))); | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
|                 { | ||||
|                     Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + ex.Message)); | ||||
|                 } | ||||
| 
 | ||||
|             } | ||||
|             else | ||||
|                 Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + result.Message)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 自定义模板 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public RenderFragment CodeContent { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 自定义模板 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public RenderFragment OtherContent { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     public override IReadWrite Plc { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 自定义模板 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public RenderFragment ReadWriteContent { get; set; } | ||||
| 
 | ||||
|     private StringNumber _selected = 0; | ||||
|     /// <summary> | ||||
|     /// Sections | ||||
|     /// </summary> | ||||
| @@ -74,48 +71,6 @@ public partial class DriverDebugUIPage : DriverDebugUIBase | ||||
|     [Parameter] | ||||
|     public bool ShowDefaultOtherContent { get; set; } = true; | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override void Dispose() | ||||
|     { | ||||
|         Plc?.SafeDispose(); | ||||
|         base.Dispose(); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// MulReadAsync | ||||
|     /// </summary> | ||||
|     /// <returns></returns> | ||||
|     public async Task MulReadAsync() | ||||
|     { | ||||
|         var deviceVariableSourceReads = Plc.LoadSourceRead<DeviceVariableSourceRead, DeviceVariableRunTime>(DeviceVariableRunTimes, MaxPack, 1000); | ||||
|         foreach (var item in deviceVariableSourceReads) | ||||
|         { | ||||
|             var result = await Plc.ReadAsync(item.Address, item.Length); | ||||
|             if (result.IsSuccess) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     item.DeviceVariableRunTimes.PraseStructContent(Plc, result.Content); | ||||
|                     Messages.Add((Microsoft.Extensions.Logging.LogLevel.Information, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + result.Content.ToHexString(' '))); | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
|                 { | ||||
|                     Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + ex)); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|                 Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + result.Message)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     /// <param name="firstRender"></param> | ||||
|     protected override void OnAfterRender(bool firstRender) | ||||
|     { | ||||
|         base.OnAfterRender(firstRender); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     protected override void OnInitialized() | ||||
| @@ -125,25 +80,25 @@ public partial class DriverDebugUIPage : DriverDebugUIBase | ||||
|                                 new DeviceVariableRunTime() | ||||
|                                 { | ||||
|                                     DataTypeEnum=DataTypeEnum.Int16, | ||||
|                                     Address="40001", | ||||
|                                     VariableAddress="40001", | ||||
|                                     IntervalTime=1000, | ||||
|                                 }, | ||||
|                                    new DeviceVariableRunTime() | ||||
|                                 { | ||||
|                                     DataTypeEnum=DataTypeEnum.Int16, | ||||
|                                     Address="40011", | ||||
|                                     VariableAddress="40011", | ||||
|                                     IntervalTime=1000, | ||||
|                                 }, | ||||
|                                    new DeviceVariableRunTime() | ||||
|                                 { | ||||
|                                     DataTypeEnum=DataTypeEnum.Int16, | ||||
|                                     Address="40031", | ||||
|                                     VariableAddress="40031", | ||||
|                                     IntervalTime=1000, | ||||
|                                 }, | ||||
|                                    new DeviceVariableRunTime() | ||||
|                                 { | ||||
|                                     DataTypeEnum=DataTypeEnum.Int16, | ||||
|                                     Address="40101", | ||||
|                                     VariableAddress="40101", | ||||
|                                     IntervalTime=1000, | ||||
|                                 }, | ||||
|             }; | ||||
| @@ -155,7 +110,7 @@ public partial class DriverDebugUIPage : DriverDebugUIBase | ||||
|                     /// <inheritdoc/> | ||||
|                     public TimerTick TimerTick { get; set; } | ||||
|                     /// <inheritdoc/> | ||||
|                     public string Address { get; set; } | ||||
|                     public string VariableAddress { get; set; } | ||||
|                     /// <inheritdoc/> | ||||
|                     public int Length { get; set; } | ||||
|                     /// <inheritdoc/> | ||||
| @@ -169,7 +124,7 @@ public partial class DriverDebugUIPage : DriverDebugUIBase | ||||
|                     public int IntervalTime { get; set; } | ||||
|                     /// <inheritdoc/> | ||||
|                     [Description("变量地址")] | ||||
|                     public string Address { get; set; } | ||||
|                     public string VariableAddress { get; set; } | ||||
|                     /// <inheritdoc/> | ||||
|                     public int Index { get; set; } | ||||
|                     /// <inheritdoc/> | ||||
| @@ -188,7 +143,7 @@ public partial class DriverDebugUIPage : DriverDebugUIBase | ||||
|                     } | ||||
|                 } | ||||
|                 public List<DeviceVariableRunTime> DeviceVariableRunTimes; | ||||
| 
 | ||||
|                                  | ||||
|                 private static async Task ModbusClientAsync(IReadWrite plc) | ||||
|                 { | ||||
|                 DeviceVariableRunTimes = new() | ||||
| @@ -196,45 +151,86 @@ public partial class DriverDebugUIPage : DriverDebugUIBase | ||||
|                                 new DeviceVariableRunTime() | ||||
|                                 { | ||||
|                                     DataTypeEnum=DataTypeEnum.Int16, | ||||
|                                     Address="40001", | ||||
|                                     VariableAddress="40001", | ||||
|                                     IntervalTime=1000, | ||||
|                                 }, | ||||
|                                    new DeviceVariableRunTime() | ||||
|                                 { | ||||
|                                     DataTypeEnum=DataTypeEnum.Int16, | ||||
|                                     Address="40011", | ||||
|                                     VariableAddress="40011", | ||||
|                                     IntervalTime=1000, | ||||
|                                 }, | ||||
|                                    new DeviceVariableRunTime() | ||||
|                                 { | ||||
|                                     DataTypeEnum=DataTypeEnum.Int16, | ||||
|                                     Address="40031", | ||||
|                                     VariableAddress="40031", | ||||
|                                     IntervalTime=1000, | ||||
|                                 }, | ||||
|                                    new DeviceVariableRunTime() | ||||
|                                 { | ||||
|                                     DataTypeEnum=DataTypeEnum.Int16, | ||||
|                                     Address="40101", | ||||
|                                     VariableAddress="40101", | ||||
|                                     IntervalTime=1000, | ||||
|                                 }, | ||||
|                 }; | ||||
| 
 | ||||
|                     #region 连读 | ||||
| 
 | ||||
|                 var deviceVariableSourceReads = Plc.LoadSourceRead<DeviceVariableSourceRead, DeviceVariableRunTime>(DeviceVariableRunTimes, MaxPack); | ||||
|                 foreach (var item in deviceVariableSourceReads) | ||||
|                 { | ||||
|                     var result = await Plc.ReadAsync(item.Address, item.Length); | ||||
|                     var result = await Plc.ReadAsync(item.VariableAddress, item.Length); | ||||
|                     if (result.IsSuccess) | ||||
|                     { | ||||
|                         item.DeviceVariableRunTimes.PraseStructContent(result.Content); | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                     #endregion | ||||
|                 } | ||||
| 
 | ||||
|                 } | ||||
|                  | ||||
| """, "csharp"));
 | ||||
|         base.OnInitialized(); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 自定义模板 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public RenderFragment ReadWriteContent { get; set; } | ||||
|     /// <summary> | ||||
|     /// 自定义模板 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public RenderFragment OtherContent { get; set; } | ||||
|     /// <summary> | ||||
|     /// 自定义模板 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public RenderFragment CodeContent { get; set; } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     ~DriverDebugUIPage() | ||||
|     { | ||||
|         this.SafeDispose(); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     public override IReadWrite Plc { get; set; } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override void Dispose() | ||||
|     { | ||||
|         Plc?.SafeDispose(); | ||||
|         base.Dispose(); | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     /// <param name="firstRender"></param> | ||||
|     protected override void OnAfterRender(bool firstRender) | ||||
|     { | ||||
|         base.OnAfterRender(firstRender); | ||||
|     } | ||||
| } | ||||
| @@ -15,22 +15,22 @@ | ||||
| @using Microsoft.AspNetCore.Components.Web; | ||||
| @using System.IO.Ports; | ||||
| @using Masa.Blazor | ||||
| <MCard Flat Class="pa-2 my-1" Style="width:100%"> | ||||
| <MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%"> | ||||
|     <div class="mb-4">通道配置</div> | ||||
|     <MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center"> | ||||
|         <MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialPortOption.Description(x => x.PortName)) Dense HideDetails="@("auto")" @bind-Value=@_serialPortOption.PortName /> | ||||
|         <MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialPortOption.Description(x => x.BaudRate)) Dense HideDetails="@("auto")" @bind-Value=@_serialPortOption.BaudRate /> | ||||
|         <MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialPortOption.Description(x => x.DataBits)) Dense HideDetails="@("auto")" @bind-Value=@_serialPortOption.DataBits /> | ||||
|         <MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="_serialPortOption.Parity" Label="@(_serialPortOption.Description(x => x.Parity))" | ||||
|                  Items=@(typeof(Parity).GetEnumList()) | ||||
|         <MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(serialProperty.DescriptionWithOutSugar(x => x.PortName)) Dense HideDetails="@("auto")" @bind-Value=@serialProperty.PortName /> | ||||
|         <MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(serialProperty.DescriptionWithOutSugar(x => x.BaudRate)) Dense HideDetails="@("auto")" @bind-Value=@serialProperty.BaudRate /> | ||||
|         <MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(serialProperty.DescriptionWithOutSugar(x => x.DataBits)) Dense HideDetails="@("auto")" @bind-Value=@serialProperty.DataBits /> | ||||
|         <MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="serialProperty.Parity" Label="@(serialProperty.DescriptionWithOutSugar(x => x.Parity))" | ||||
|                  Items=@(typeof(Parity).GetEnumListWithOutSugar()) | ||||
|                  MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })" | ||||
|                  ItemText=@((u) =>u.Description) | ||||
|                  ItemValue=@(u =>(Parity)u.Value) | ||||
|                  HideDetails=@("auto") Height="30" | ||||
|                  Dense> | ||||
|         </MSelect> | ||||
|         <MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="_serialPortOption.StopBits" Label="@(_serialPortOption.Description(x => x.StopBits))" | ||||
|                  Items=@(typeof(StopBits).GetEnumList()) | ||||
|         <MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="serialProperty.StopBits" Label="@(serialProperty.DescriptionWithOutSugar(x => x.StopBits))" | ||||
|                  Items=@(typeof(StopBits).GetEnumListWithOutSugar()) | ||||
|                  MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })" | ||||
|                  ItemText=@((u) =>u.Description) | ||||
|                  ItemValue=@(u =>(StopBits)u.Value) | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,52 +8,73 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Demo; | ||||
| 
 | ||||
| /// <inheritdoc/> | ||||
| public partial class SerialPortClientPage : IDisposable | ||||
| public partial class SerialSessionPage : IDisposable | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 日志输出 | ||||
|     /// </summary> | ||||
|     public Action<LogLevel, object, string, Exception> LogAction; | ||||
| 
 | ||||
|     private readonly SerialPortOption _serialPortOption = new(); | ||||
|     private TouchSocketConfig _config; | ||||
|     private SerialPortClient _serialPortClient { get; set; } = new(); | ||||
|     private TouchSocketConfig config; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     public void Dispose() | ||||
|     { | ||||
|         _serialPortClient.SafeDispose(); | ||||
|     } | ||||
|     private readonly SerialProperty serialProperty = new(); | ||||
| 
 | ||||
|     private SerialSession SerialSession { get; set; } = new(); | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 获取对象 | ||||
|     /// </summary> | ||||
|     /// <returns></returns> | ||||
|     public SerialPortClient GetSerialPortClient() | ||||
|     public SerialSession GetSerialSession() | ||||
|     { | ||||
|         _config ??= new TouchSocketConfig(); | ||||
|         config ??= new TouchSocketConfig(); | ||||
|         var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace }; | ||||
|         LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace }); | ||||
|         _config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage)); | ||||
|         _config.SetSerialPortOption(_serialPortOption); | ||||
|         config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage)); | ||||
|         config.SetSerialProperty(serialProperty); | ||||
|         //载入配置 | ||||
|         _serialPortClient.Setup(_config); | ||||
|         return _serialPortClient; | ||||
|         SerialSession.Setup(config); | ||||
|         return SerialSession; | ||||
|     } | ||||
|     private async Task ConnectAsync() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             SerialSession.Close(); | ||||
|             await GetSerialSession().ConnectAsync(); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             LogAction?.Invoke(LogLevel.Error, null, null, ex); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
|     private void DisConnect() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             SerialSession.Close(); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             LogAction?.Invoke(LogLevel.Error, null, null, ex); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     internal void StateHasChangedAsync() | ||||
|     /// <inheritdoc/> | ||||
|     protected override void OnInitialized() | ||||
|     { | ||||
|         StateHasChanged(); | ||||
|         config ??= new TouchSocketConfig(); | ||||
| 
 | ||||
|         base.OnInitialized(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
| @@ -65,44 +85,22 @@ public partial class SerialPortClientPage : IDisposable | ||||
|         { | ||||
|             var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace }; | ||||
|             LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace }); | ||||
|             _config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage)); | ||||
|             _serialPortClient.Setup(_config); | ||||
|             config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage)); | ||||
|             SerialSession.Setup(config); | ||||
|         } | ||||
|         base.OnAfterRender(firstRender); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     protected override void OnInitialized() | ||||
|     { | ||||
|         _config ??= new TouchSocketConfig(); | ||||
| 
 | ||||
|         base.OnInitialized(); | ||||
|     } | ||||
| 
 | ||||
|     private async Task ConnectAsync() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             _serialPortClient.Close(); | ||||
|             await GetSerialPortClient().ConnectAsync(); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             LogAction?.Invoke(LogLevel.Error, null, null, ex); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void DisConnect() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             _serialPortClient.Close(); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             LogAction?.Invoke(LogLevel.Error, null, null, ex); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void LogOut(LogLevel logLevel, object source, string message, Exception exception) => LogAction?.Invoke(logLevel, source, message, exception); | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     public void Dispose() | ||||
|     { | ||||
|         SerialSession.SafeDispose(); | ||||
|     } | ||||
|     internal void StateHasChangedAsync() | ||||
|     { | ||||
|         StateHasChanged(); | ||||
|     } | ||||
| } | ||||
| @@ -17,12 +17,12 @@ | ||||
| @using System.Collections.Concurrent; | ||||
| @using ThingsGateway.Foundation.Core; | ||||
| @using Masa.Blazor | ||||
| <MCard Flat Class="pa-2 my-1" Style="width:100%"> | ||||
| <MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%"> | ||||
|     <div class="mb-4">通道配置</div> | ||||
|     <MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center"> | ||||
| 
 | ||||
|         <MTextField Class="ma-1" Style="max-width:100px" Label="IP地址" Dense Outlined HideDetails="@("auto")" @bind-Value=@_ip /> | ||||
|         <MTextField Class="ma-1" Style="max-width:100px" Label="端口" Dense Outlined HideDetails="@("auto")" @bind-Value=@_port /> | ||||
|         <MTextField Class="ma-1" Style="max-width:100px" Label="IP地址" Dense Outlined HideDetails="@("auto")" @bind-Value=@IP /> | ||||
|         <MTextField Class="ma-1" Style="max-width:100px" Label="端口" Dense Outlined HideDetails="@("auto")" @bind-Value=@Port /> | ||||
| 
 | ||||
|         <MButton Class="ma-1" OnClick=@ConnectAsync Color="primary"> | ||||
|             连接 | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Demo; | ||||
| @@ -22,47 +20,66 @@ public partial class TcpClientPage : IDisposable | ||||
|     /// </summary> | ||||
|     public Action<LogLevel, object, string, Exception> LogAction; | ||||
| 
 | ||||
|     private TouchSocketConfig _config; | ||||
| 
 | ||||
|     private TouchSocketConfig config; | ||||
|     /// <summary> | ||||
|     /// IP | ||||
|     /// </summary> | ||||
|     private string _ip = "127.0.0.1"; | ||||
| 
 | ||||
|     private string IP = "127.0.0.1"; | ||||
|     /// <summary> | ||||
|     /// Port | ||||
|     /// </summary> | ||||
|     public int _port { get; set; } = 502; | ||||
|     public int Port { get; set; } = 502; | ||||
| 
 | ||||
|     private TcpClient _tcpClient { get; set; } = new(); | ||||
|     private TcpClient TcpClient { get; set; } = new(); | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     public void Dispose() | ||||
|     private async Task ConnectAsync() | ||||
|     { | ||||
|         _tcpClient.SafeDispose(); | ||||
|     } | ||||
|         try | ||||
|         { | ||||
|             TcpClient.Close(); | ||||
|             await GetTcpClient().ConnectAsync(); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| 
 | ||||
|             LogAction?.Invoke(LogLevel.Error, null, null, ex); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
|     private void DisConnect() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             TcpClient.Close(); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| 
 | ||||
|             LogAction?.Invoke(LogLevel.Error, null, null, ex); | ||||
|         } | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// 获取对象 | ||||
|     /// </summary> | ||||
|     /// <returns></returns> | ||||
|     public TcpClient GetTcpClient() | ||||
|     { | ||||
|         _config ??= new TouchSocketConfig(); | ||||
|         config ??= new TouchSocketConfig(); | ||||
|         var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace }; | ||||
|         LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace }); | ||||
|         _config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage)); | ||||
|         _config.SetRemoteIPHost(new IPHost(_ip + ":" + _port)); | ||||
|         config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage)); | ||||
|         config.SetRemoteIPHost(new IPHost(IP + ":" + Port)); | ||||
|         //载入配置 | ||||
|         _tcpClient.Setup(_config); | ||||
|         return _tcpClient; | ||||
|         TcpClient.Setup(config); | ||||
|         return TcpClient; | ||||
|     } | ||||
| 
 | ||||
|     internal void StateHasChangedAsync() | ||||
|     /// <inheritdoc/> | ||||
|     protected override void OnInitialized() | ||||
|     { | ||||
|         StateHasChanged(); | ||||
|         config ??= new TouchSocketConfig(); | ||||
| 
 | ||||
|         base.OnInitialized(); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
| @@ -75,45 +92,25 @@ public partial class TcpClientPage : IDisposable | ||||
|         { | ||||
|             var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace }; | ||||
|             LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace }); | ||||
|             _config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage)); | ||||
|             _config.SetRemoteIPHost(new IPHost(_ip + ":" + _port)); | ||||
|             _tcpClient.Setup(_config); | ||||
|             config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage)); | ||||
|             config.SetRemoteIPHost(new IPHost(IP + ":" + Port)); | ||||
|             TcpClient.Setup(config); | ||||
|         } | ||||
|         base.OnAfterRender(firstRender); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     protected override void OnInitialized() | ||||
|     { | ||||
|         _config ??= new TouchSocketConfig(); | ||||
| 
 | ||||
|         base.OnInitialized(); | ||||
|     } | ||||
| 
 | ||||
|     private async Task ConnectAsync() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             _tcpClient.Close(); | ||||
|             await GetTcpClient().ConnectAsync(); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             LogAction?.Invoke(LogLevel.Error, null, null, ex); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void DisConnect() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             _tcpClient.Close(); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             LogAction?.Invoke(LogLevel.Error, null, null, ex); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void LogOut(LogLevel logLevel, object source, string message, Exception exception) => LogAction?.Invoke(logLevel, source, message, exception); | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     public void Dispose() | ||||
|     { | ||||
|         TcpClient.SafeDispose(); | ||||
|     } | ||||
| 
 | ||||
|     internal void StateHasChangedAsync() | ||||
|     { | ||||
|         StateHasChanged(); | ||||
|     } | ||||
| } | ||||
| @@ -18,18 +18,18 @@ | ||||
| @using ThingsGateway.Foundation.Core; | ||||
| @using Masa.Blazor | ||||
| 
 | ||||
| <MCard Flat Class="pa-2 my-1" Style="width:100%"> | ||||
| <MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%"> | ||||
|     <div class="mb-4">通道配置</div> | ||||
|     <MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center"> | ||||
| 
 | ||||
|         <MTextField Class="ma-1" Style="max-width:100px" Label="IP地址" Dense Outlined HideDetails="@("auto")" @bind-Value=@_ip /> | ||||
|          <MTextField Class="ma-1" Style="max-width:100px" Label="端口" Dense Outlined HideDetails="@("auto")" @bind-Value=@_port /> | ||||
|         <MTextField Class="ma-1" Style="max-width:100px" Label="IP地址" Dense Outlined HideDetails="@("auto")" @bind-Value=@ip /> | ||||
|         <MTextField Class="ma-1" Style="max-width:100px" Label="端口" Dense Outlined HideDetails="@("auto")" @bind-Value=@port /> | ||||
| 
 | ||||
|         <MButton Class="ma-1" OnClick=@Connect Color="primary"> | ||||
|             启动 | ||||
|             连接 | ||||
|         </MButton> | ||||
|         <MButton Class="ma-1" OnClick=@DisConnect Color="red"> | ||||
|             停止 | ||||
|             断开 | ||||
|         </MButton> | ||||
| 
 | ||||
| 
 | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Demo; | ||||
| @@ -22,43 +20,62 @@ public partial class TcpServerPage : IDisposable | ||||
|     /// </summary> | ||||
|     public Action<LogLevel, object, string, Exception> LogAction; | ||||
| 
 | ||||
|     private TouchSocketConfig _config; | ||||
|     private TouchSocketConfig config; | ||||
| 
 | ||||
|     private string _ip = "127.0.0.1"; | ||||
|     private string ip = "127.0.0.1"; | ||||
| 
 | ||||
|     private int _port = 502; | ||||
|     private int port = 502; | ||||
| 
 | ||||
|     private TcpService _tcpServer { get; set; } = new(); | ||||
|     private TcpService TcpServer { get; set; } = new(); | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     public void Dispose() | ||||
|     private void Connect() | ||||
|     { | ||||
|         _tcpServer.SafeDispose(); | ||||
|     } | ||||
|         try | ||||
|         { | ||||
|             TcpServer.Stop(); | ||||
|             GetTcpServer().Start(); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| 
 | ||||
|             LogAction?.Invoke(LogLevel.Error, null, null, ex); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
|     private void DisConnect() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             TcpServer.Stop(); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             LogAction?.Invoke(LogLevel.Error, null, null, ex); | ||||
|         } | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// 获取对象 | ||||
|     /// </summary> | ||||
|     /// <returns></returns> | ||||
|     public TcpService GetTcpServer() | ||||
|     { | ||||
|         _config ??= new TouchSocketConfig(); | ||||
|         config ??= new TouchSocketConfig(); | ||||
|         var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace }; | ||||
|         LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace }); | ||||
|         _config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage)); | ||||
|         _config.SetListenIPHosts(new IPHost[] { new IPHost(_ip + ":" + _port) }); | ||||
|         config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage)); | ||||
|         config.SetListenIPHosts(new IPHost[] { new IPHost(ip + ":" + port) }); | ||||
|         //载入配置 | ||||
|         _tcpServer.Setup(_config); | ||||
|         return _tcpServer; | ||||
|         TcpServer.Setup(config); | ||||
|         return TcpServer; | ||||
|     } | ||||
| 
 | ||||
|     internal void StateHasChangedAsync() | ||||
|     /// <inheritdoc/> | ||||
|     protected override void OnInitialized() | ||||
|     { | ||||
|         StateHasChanged(); | ||||
|     } | ||||
|         config ??= new TouchSocketConfig(); | ||||
| 
 | ||||
|         base.OnInitialized(); | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
| @@ -69,45 +86,23 @@ public partial class TcpServerPage : IDisposable | ||||
|         { | ||||
|             var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace }; | ||||
|             LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace }); | ||||
|             _config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage)); | ||||
|             _config.SetListenIPHosts(new IPHost[] { new IPHost(_ip + ":" + _port) }); | ||||
|             _tcpServer.Setup(_config); | ||||
|             config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage)); | ||||
|             config.SetListenIPHosts(new IPHost[] { new IPHost(ip + ":" + port) }); | ||||
|             TcpServer.Setup(config); | ||||
|         } | ||||
|         base.OnAfterRender(firstRender); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     protected override void OnInitialized() | ||||
|     { | ||||
|         _config ??= new TouchSocketConfig(); | ||||
| 
 | ||||
|         base.OnInitialized(); | ||||
|     } | ||||
| 
 | ||||
|     private void Connect() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             _tcpServer.Stop(); | ||||
|             GetTcpServer().Start(); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             LogAction?.Invoke(LogLevel.Error, null, null, ex); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void DisConnect() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             _tcpServer.Stop(); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             LogAction?.Invoke(LogLevel.Error, null, null, ex); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void LogOut(LogLevel logLevel, object source, string message, Exception exception) => LogAction?.Invoke(logLevel, source, message, exception); | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     public void Dispose() | ||||
|     { | ||||
|         TcpServer.SafeDispose(); | ||||
|     } | ||||
|     internal void StateHasChangedAsync() | ||||
|     { | ||||
|         StateHasChanged(); | ||||
|     } | ||||
| } | ||||
| @@ -18,12 +18,12 @@ | ||||
| @using ThingsGateway.Foundation.Core; | ||||
| @using Masa.Blazor | ||||
| 
 | ||||
| <MCard Flat Class="pa-2 my-1" Style="width:100%"> | ||||
| <MCard Elevation="1" Rounded="false" Class="pa-2" Style="width:100%"> | ||||
|     <div class="mb-4">通道配置</div> | ||||
|     <MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center"> | ||||
| 
 | ||||
|         <MTextField Class="ma-1" Style="max-width:100px" Label="IP地址" Dense Outlined HideDetails="@("auto")" @bind-Value=@_ip /> | ||||
|         <MTextField Class="ma-1" Style="max-width:100px" Label="端口" Dense Outlined HideDetails="@("auto")" @bind-Value=@_port /> | ||||
|         <MTextField Class="ma-1" Style="max-width:100px" Label="IP地址" Dense Outlined HideDetails="@("auto")" @bind-Value=@IP /> | ||||
|         <MTextField Class="ma-1" Style="max-width:100px" Label="端口" Dense Outlined HideDetails="@("auto")" @bind-Value=@Port /> | ||||
| 
 | ||||
|         <MButton Class="ma-1" OnClick=Connect Color="primary"> | ||||
|             连接 | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Demo; | ||||
| @@ -17,54 +15,71 @@ namespace ThingsGateway.Foundation.Demo; | ||||
| /// <inheritdoc/> | ||||
| public partial class UdpSessionPage : IDisposable | ||||
| { | ||||
|     /// <summary> | ||||
|     /// IP | ||||
|     /// </summary> | ||||
|     public string _ip = "127.0.0.1"; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// Port | ||||
|     /// </summary> | ||||
|     public int _port = 502; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 日志输出 | ||||
|     /// </summary> | ||||
|     public Action<LogLevel, object, string, Exception> LogAction; | ||||
| 
 | ||||
|     private TouchSocketConfig _config; | ||||
|     private UdpSession _udpSession { get; set; } = new(); | ||||
| 
 | ||||
|     private TouchSocketConfig config; | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// IP | ||||
|     /// </summary> | ||||
|     public void Dispose() | ||||
|     { | ||||
|         _udpSession.SafeDispose(); | ||||
|     } | ||||
|     public string IP = "127.0.0.1"; | ||||
|     /// <summary> | ||||
|     /// Port | ||||
|     /// </summary> | ||||
|     public int Port = 502; | ||||
| 
 | ||||
|     private UdpSession UdpSession { get; set; } = new(); | ||||
| 
 | ||||
|     private void Connect() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             UdpSession.Stop(); | ||||
|             GetUdpSession().Start(); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             LogAction?.Invoke(LogLevel.Error, null, null, ex); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
|     private void DisConnect() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             UdpSession.Stop(); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| 
 | ||||
|             LogAction?.Invoke(LogLevel.Error, null, null, ex); | ||||
|         } | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// 获取对象 | ||||
|     /// </summary> | ||||
|     /// <returns></returns> | ||||
|     public UdpSession GetUdpSession() | ||||
|     { | ||||
|         _config ??= new TouchSocketConfig(); | ||||
|         config ??= new TouchSocketConfig(); | ||||
|         var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace }; | ||||
|         LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace }); | ||||
|         _config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage)); | ||||
|         _config.SetRemoteIPHost(new IPHost(_ip + ":" + _port)); | ||||
|         _config.SetBindIPHost(new IPHost(0)); | ||||
|         config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage)); | ||||
|         config.SetRemoteIPHost(new IPHost(IP + ":" + Port)); | ||||
|         config.SetBindIPHost(new IPHost(0)); | ||||
|         //载入配置 | ||||
|         _udpSession.Setup(_config); | ||||
|         return _udpSession; | ||||
|         UdpSession.Setup(config); | ||||
|         return UdpSession; | ||||
|     } | ||||
| 
 | ||||
|     internal void StateHasChangedAsync() | ||||
|     /// <inheritdoc/> | ||||
|     protected override void OnInitialized() | ||||
|     { | ||||
|         StateHasChanged(); | ||||
|     } | ||||
|         config ??= new TouchSocketConfig(); | ||||
| 
 | ||||
|         base.OnInitialized(); | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
| @@ -75,46 +90,24 @@ public partial class UdpSessionPage : IDisposable | ||||
|         { | ||||
|             var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace }; | ||||
|             LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace }); | ||||
|             _config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage)); | ||||
|             _config.SetRemoteIPHost(new IPHost(_ip + ":" + _port)); | ||||
|             _config.SetBindIPHost(new IPHost(0)); | ||||
|             _udpSession.Setup(_config); | ||||
|             config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage)); | ||||
|             config.SetRemoteIPHost(new IPHost(IP + ":" + Port)); | ||||
|             config.SetBindIPHost(new IPHost(0)); | ||||
|             UdpSession.Setup(config); | ||||
|         } | ||||
|         base.OnAfterRender(firstRender); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     protected override void OnInitialized() | ||||
|     { | ||||
|         _config ??= new TouchSocketConfig(); | ||||
| 
 | ||||
|         base.OnInitialized(); | ||||
|     } | ||||
| 
 | ||||
|     private void Connect() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             _udpSession.Stop(); | ||||
|             GetUdpSession().Start(); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             LogAction?.Invoke(LogLevel.Error, null, null, ex); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void DisConnect() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             _udpSession.Stop(); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             LogAction?.Invoke(LogLevel.Error, null, null, ex); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void LogOut(LogLevel logLevel, object source, string message, Exception exception) => LogAction?.Invoke(logLevel, source, message, exception); | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     public void Dispose() | ||||
|     { | ||||
|         UdpSession.SafeDispose(); | ||||
|     } | ||||
|     internal void StateHasChangedAsync() | ||||
|     { | ||||
|         StateHasChanged(); | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.ComponentModel; | ||||
| @@ -21,34 +19,24 @@ public class DeviceVariableRunTime : IDeviceVariableRunTime | ||||
| { | ||||
|     /// <inheritdoc/> | ||||
|     [Description("读取间隔")] | ||||
|     public int? IntervalTime { get; set; } | ||||
| 
 | ||||
|     public int IntervalTime { get; set; } | ||||
|     /// <inheritdoc/> | ||||
|     [Description("变量地址")] | ||||
|     public string Address { get; set; } | ||||
| 
 | ||||
|     public string VariableAddress { get; set; } | ||||
|     /// <inheritdoc/> | ||||
|     public int Index { get; set; } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public IThingsGatewayBitConverter ThingsGatewayBitConverter { get; set; } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     [Description("数据类型")] | ||||
|     public DataTypeEnum DataTypeEnum { get; set; } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     [Description("实时值")] | ||||
|     public object Value { get; set; } | ||||
| 
 | ||||
|     public bool IsOnline { get; set; } | ||||
| 
 | ||||
|     public string LastErrorMessage { get; set; } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public OperResult SetValue(object value, DateTime dateTime = default, string lastErrorMessage = null) | ||||
|     public OperResult SetValue(object value, DateTime dateTime = default, bool isOnline = true) | ||||
|     { | ||||
|         Value = value; | ||||
|         return OperResult.CreateSuccessResult(); | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,23 +8,21 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.Collections.Generic; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Demo; | ||||
| 
 | ||||
| /// <inheritdoc/> | ||||
| public class DeviceVariableSourceRead : IDeviceVariableSourceRead<IDeviceVariableRunTime> | ||||
| { | ||||
|     /// <inheritdoc/> | ||||
|     public TimerTick IntervalTimeTick { get; set; } | ||||
| 
 | ||||
|     public TimerTick TimerTick { get; set; } | ||||
|     /// <inheritdoc/> | ||||
|     public string Address { get; set; } | ||||
| 
 | ||||
|     public string VariableAddress { get; set; } | ||||
|     /// <inheritdoc/> | ||||
|     public int Length { get; set; } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public List<IDeviceVariableRunTime> DeviceVariableRunTimes { get; set; } = new List<IDeviceVariableRunTime>(); | ||||
| } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| global using System; | ||||
| @@ -18,5 +16,6 @@ global using System.Threading.Tasks; | ||||
| 
 | ||||
| global using ThingsGateway.Components; | ||||
| global using ThingsGateway.Foundation.Core; | ||||
| global using ThingsGateway.Foundation.SerialPorts; | ||||
| global using ThingsGateway.Foundation.Sockets; | ||||
| global using ThingsGateway.Foundation.Serial; | ||||
| global using ThingsGateway.Foundation.Sockets; | ||||
| 
 | ||||
| @@ -24,7 +24,7 @@ | ||||
|                 <Logo CONFIG_COPYRIGHT=@CONFIG_COPYRIGHT  CONFIG_TITLE=@CONFIG_TITLE HeightInt=@(IsMobile?BlazorResourceConst.AppBarHeight:BlazorResourceConst.AppBarHeight+BlazorResourceConst.PageTabsHeight) /> | ||||
|                 <AppList ClassString="overflow-y-auto" Routable | ||||
|                          StyleString=@($"height: calc(100vh - {BlazorResourceConst.AppBarHeight+BlazorResourceConst.PageTabsHeight}px);") | ||||
|                          Items="_navs" /> | ||||
|                          Items="Navs" /> | ||||
|             </MNavigationDrawer> | ||||
| 
 | ||||
|             <MAppBar Color="barcolor" Style=@($"{(!(IsMobile||_drawerOpen!=true)? "left:200px;":"")}") Elevation="1" App Flat ClippedRight Dense ElevateOnScroll | ||||
| @@ -37,7 +37,7 @@ | ||||
| 
 | ||||
|             <MMain Style=@($"{(!(IsMobile||_drawerOpen!=true)? "padding-left:200px;":"")}")> | ||||
|                 <div class="full-width"> | ||||
|                     <PageTabs @ref="_pageTabs" PageTabItems="_pageTabItems" /> | ||||
|                     <PageTabs @ref="_pageTabs" PageTabItems="pageTabItems" /> | ||||
|                 </div> | ||||
|                 <MDivider Center></MDivider> | ||||
|                 <MCard Flat Class="overflow-y-auto overflow-x-hidden ma-auto pa-0 rounded-0" Style=@($"height: calc(100vh - {BlazorResourceConst.AppBarHeight+BlazorResourceConst.PageTabsHeight+BlazorResourceConst.FooterHeight}px);")> | ||||
| @@ -1,24 +1,24 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.Collections.Generic; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Demo; | ||||
| 
 | ||||
| public partial class MainLayout | ||||
| { | ||||
|     private List<NavItem> _navs { get; set; } = new(); | ||||
|     private List<PageTabItem> _pageTabItems { get; set; } = new(); | ||||
| 
 | ||||
|     private List<NavItem> Navs { get; set; } = new(); | ||||
|     private List<PageTabItem> pageTabItems { get; set; } = new(); | ||||
|     protected override void OnInitialized() | ||||
|     { | ||||
|         var dataString = | ||||
| @@ -26,7 +26,7 @@ public partial class MainLayout | ||||
| [ | ||||
|   { | ||||
|     "Href": "/index", | ||||
|     "Title": "首页" | ||||
|     "Title": "首页" | ||||
|   }, | ||||
|   { | ||||
|     "Title": "Modbus", | ||||
| @@ -69,8 +69,28 @@ public partial class MainLayout | ||||
|     "Title": "Siemens", | ||||
|     "Children": [ | ||||
|       { | ||||
|         "Href": "/Siemens", | ||||
|         "Title": "Siemens" | ||||
|         "Href": "/S7_1500", | ||||
|         "Title": "S7_1500" | ||||
|       }, | ||||
|       { | ||||
|         "Href": "/S7_1200", | ||||
|         "Title": "S7_1200" | ||||
|       }, | ||||
|       { | ||||
|         "Href": "/S7_200", | ||||
|         "Title": "S7_200" | ||||
|       }, | ||||
|       { | ||||
|         "Href": "/S7_200SMART", | ||||
|         "Title": "S7_200SMART" | ||||
|       }, | ||||
|       { | ||||
|         "Href": "/S7_300", | ||||
|         "Title": "S7_400" | ||||
|       }, | ||||
|       { | ||||
|         "Href": "/S7_400", | ||||
|         "Title": "S7_400" | ||||
|       } | ||||
|     ] | ||||
|   }, | ||||
| @@ -104,20 +124,21 @@ public partial class MainLayout | ||||
|         "Title": "OPCUAClient" | ||||
|       } | ||||
|     ] | ||||
|   }, | ||||
|   { | ||||
|     "Title": "Mqtt", | ||||
|     "Children": [ | ||||
|       { | ||||
|         "Href": "/MqttClient", | ||||
|         "Title": "MqttClient" | ||||
|       } | ||||
|     ] | ||||
|   } | ||||
|   //{ | ||||
|   //  "Title": "Mqtt", | ||||
|   //  "Children": [ | ||||
|   //    { | ||||
|   //      "Href": "/MqttClient", | ||||
|   //      "Title": "MqttClient" | ||||
|   //    } | ||||
|   //  ] | ||||
|   //} | ||||
| ] | ||||
| 
 | ||||
| 
 | ||||
| """;
 | ||||
|         _navs = dataString.FromJsonString<List<NavItem>>(); | ||||
|         Navs = dataString.FromJsonString<List<NavItem>>(); | ||||
| 
 | ||||
| #if Pro | ||||
|         var dataStringPro = | ||||
| @@ -186,46 +207,26 @@ public partial class MainLayout | ||||
|     ] | ||||
|   }, | ||||
|   { | ||||
|     "Title": "HZW_QTJC_01", | ||||
|     "Title": "GasCustom", | ||||
|     "Children": [ | ||||
|       { | ||||
|         "Href": "/HZW_QTJC_01Serial", | ||||
|         "Title": "HZW_QTJC_01Serial" | ||||
|         "Href": "/GasCustomSerial", | ||||
|         "Title": "GasCustomSerial" | ||||
|       }, | ||||
|       { | ||||
|         "Href": "/HZW_QTJC_01SerialOverTcp", | ||||
|         "Title": "HZW_QTJC_01SerialOverTcp" | ||||
|         "Href": "/GasCustomSerialOverTcp", | ||||
|         "Title": "GasCustomSerialOverTcp" | ||||
|       } | ||||
|     ] | ||||
|   }, | ||||
|   { | ||||
|     "Title": "LQTCP", | ||||
|     "Children": [ | ||||
|       { | ||||
|         "Href": "/LQTCP", | ||||
|         "Title": "LQTCP" | ||||
|       } | ||||
|     ] | ||||
|   }, | ||||
|   { | ||||
|     "Title": "KELID2008", | ||||
|     "Children": [ | ||||
|       { | ||||
|         "Href": "/KELID2008", | ||||
|         "Title": "KELID2008" | ||||
|       }, | ||||
|       { | ||||
|         "Href": "/KELID2008OverTcp", | ||||
|         "Title": "KELID2008OverTcp" | ||||
|       } | ||||
|     ] | ||||
|   }, | ||||
|   } | ||||
| 
 | ||||
| ] | ||||
| 
 | ||||
| 
 | ||||
| """;
 | ||||
|         Navs.AddRange(dataStringPro.FromJsonString<List<NavItem>>()); | ||||
| #endif | ||||
|         _pageTabItems = _navs.PasePageTabItem(); | ||||
|         pageTabItems = Navs.PasePageTabItem(); | ||||
|         base.OnInitialized(); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,148 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk.Razor"> | ||||
|  | ||||
| 	<PropertyGroup Condition="'$(SolutionName)'=='ThingsGateway - Pro'"> | ||||
| 		<DefineConstants>Pro</DefineConstants> | ||||
| 	</PropertyGroup> | ||||
| 	<ItemGroup Condition="'$(SolutionName)'=='ThingsGateway - Pro'"> | ||||
|  | ||||
|  | ||||
|  | ||||
| 		<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.Melsec\Page\QnA3E_BinaryDebugPage.razor.cs" Link="Pages\Melsec\QnA3E_BinaryDebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\PluginPro\ThingsGateway.Plugin.Melsec\Page\QnA3E_BinaryDebugPage.razor" Link="Pages\Melsec\QnA3E_BinaryDebugPage.razor" /> | ||||
| 		<ProjectReference Include="..\..\FoundationPro\ThingsGateway.Foundation.Adapter.Melsec\ThingsGateway.Foundation.Adapter.Melsec.csproj" /> | ||||
|  | ||||
| 		 | ||||
| 		 | ||||
| 		<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.AllenBradleyCip\Page\AllenBradleyCipTcpDebugPage.razor.cs" Link="Pages\ABCIP\AllenBradleyCipTcpDebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\PluginPro\ThingsGateway.Plugin.AllenBradleyCip\Page\AllenBradleyCipTcpDebugPage.razor" Link="Pages\ABCIP\AllenBradleyCipTcpDebugPage.razor" /> | ||||
| 		<ProjectReference Include="..\..\FoundationPro\ThingsGateway.Foundation.Adapter.AllenBradleyCip\ThingsGateway.Foundation.Adapter.AllenBradleyCip.csproj" /> | ||||
|  | ||||
| 		<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.Omron\Page\OmronFinsTcpDebugPage.razor.cs" Link="Pages\OmronFins\OmronFinsTcpDebugPage.razor.cs" /> | ||||
| 		<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.Omron\Page\OmronFinsUdpDebugPage.razor.cs" Link="Pages\OmronFins\OmronFinsUdpDebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\PluginPro\ThingsGateway.Plugin.Omron\Page\OmronFinsTcpDebugPage.razor" Link="Pages\OmronFins\OmronFinsTcpDebugPage.razor" /> | ||||
| 		<Content Include="..\..\PluginPro\ThingsGateway.Plugin.Omron\Page\OmronFinsUdpDebugPage.razor" Link="Pages\OmronFins\OmronFinsUdpDebugPage.razor" /> | ||||
| 		<ProjectReference Include="..\..\FoundationPro\ThingsGateway.Foundation.Adapter.Omron\ThingsGateway.Foundation.Adapter.Omron.csproj" /> | ||||
|  | ||||
| 		<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.Secs\Page\SecsHsmsTcpDebugPage.razor.cs" Link="Pages\Secs\SecsHsmsTcpDebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\PluginPro\ThingsGateway.Plugin.Secs\Page\SecsHsmsTcpDebugPage.razor" Link="Pages\Secs\SecsHsmsTcpDebugPage.razor" /> | ||||
| 		<ProjectReference Include="..\..\FoundationPro\ThingsGateway.Foundation.Adapter.Secs\ThingsGateway.Foundation.Adapter.Secs.csproj" /> | ||||
|  | ||||
|  | ||||
| 		<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.TS550\Page\TS550DebugPage.razor.cs" Link="Pages\TS550\TS550DebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\PluginPro\ThingsGateway.Plugin.TS550\Page\TS550DebugPage.razor" Link="Pages\TS550\TS550DebugPage.razor" /> | ||||
| 		<ProjectReference Include="..\..\FoundationPro\ThingsGateway.Foundation.Adapter.TS550\ThingsGateway.Foundation.Adapter.TS550.csproj" /> | ||||
|  | ||||
| 		<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.Vigor\Page\VigorSerialDebugPage.razor.cs" Link="Pages\Vigor\VigorSerialDebugPage.razor.cs" /> | ||||
| 		<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.Vigor\Page\VigorSerialOverTcpDebugPage.razor.cs" Link="Pages\Vigor\VigorSerialOverTcpDebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\PluginPro\ThingsGateway.Plugin.Vigor\Page\VigorSerialDebugPage.razor" Link="Pages\Vigor\VigorSerialDebugPage.razor" /> | ||||
| 		<Content Include="..\..\PluginPro\ThingsGateway.Plugin.Vigor\Page\VigorSerialOverTcpDebugPage.razor" Link="Pages\Vigor\VigorSerialOverTcpDebugPage.razor" /> | ||||
| 		<ProjectReference Include="..\..\FoundationPro\ThingsGateway.Foundation.Adapter.Vigor\ThingsGateway.Foundation.Adapter.Vigor.csproj" /> | ||||
|  | ||||
|  | ||||
| 		<Compile Include="..\..\PluginProAF2021\ThingsGateway.Plugin.HZW_QTJC_01\Page\HZW_QTJC_01SerialDebugPage.razor.cs" Link="Pages\HZW_QTJC_01\HZW_QTJC_01SerialDebugPage.razor.cs" /> | ||||
| 		<Compile Include="..\..\PluginProAF2021\ThingsGateway.Plugin.HZW_QTJC_01\Page\HZW_QTJC_01SerialOverTcpDebugPage.razor.cs" Link="Pages\HZW_QTJC_01\HZW_QTJC_01SerialOverTcpDebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\PluginProAF2021\ThingsGateway.Plugin.HZW_QTJC_01\Page\HZW_QTJC_01SerialDebugPage.razor" Link="Pages\HZW_QTJC_01\HZW_QTJC_01SerialDebugPage.razor" /> | ||||
| 		<Content Include="..\..\PluginProAF2021\ThingsGateway.Plugin.HZW_QTJC_01\Page\HZW_QTJC_01SerialOverTcpDebugPage.razor" Link="Pages\HZW_QTJC_01\HZW_QTJC_01SerialOverTcpDebugPage.razor" /> | ||||
| 		<ProjectReference Include="..\..\PluginProAF2021\ThingsGateway.Foundation.Adapter.HZW_QTJC_01\ThingsGateway.Foundation.Adapter.HZW_QTJC_01.csproj" /> | ||||
|  | ||||
|  | ||||
| 		 | ||||
| 	</ItemGroup> | ||||
|  | ||||
|  | ||||
|  | ||||
| 	<ItemGroup> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.DLT645\Page\DLT645_2007DebugPage.razor.cs" Link="Pages\DLT645\DLT645_2007DebugPage.razor.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\MqttRpcNameVaueWithId.cs" Link="Pages\Mqtt\MqttRpcNameVaueWithId.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\MqttClientDebugPage.razor.cs" Link="Pages\Mqtt\MqttClientDebugPage.razor.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\MqttClientPage.razor.cs" Link="Pages\Mqtt\MqttClientPage.razor.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\PrivateLogger.cs" Link="Pages\Mqtt\PrivateLogger.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\RpcClass\MqttRpcClient.cs" Link="Pages\Mqtt\MqttRpcClient.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\RpcClass\MqttRpcClientExtensions.cs" Link="Pages\Mqtt\MqttRpcClientExtensions.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\RpcClass\MqttRpcTopicPair.cs" Link="Pages\Mqtt\MqttRpcTopicPair.cs" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.DLT645\Page\DLT645_2007DebugPage.razor" Link="Pages\DLT645\DLT645_2007DebugPage.razor" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.DLT645\Page\DLT645_2007OverTcpDebugPage.razor.cs" Link="Pages\DLT645\DLT645_2007OverTcpDebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.DLT645\Page\DLT645_2007OverTcpDebugPage.razor" Link="Pages\DLT645\DLT645_2007OverTcpDebugPage.razor" /> | ||||
|  | ||||
| 		 | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusRtuDebugPage.razor.cs" Link="Pages\Modbus\ModbusRtuDebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusRtuDebugPage.razor" Link="Pages\Modbus\ModbusRtuDebugPage.razor" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusRtuOverTcpDebugPage.razor.cs" Link="Pages\Modbus\ModbusRtuOverTcpDebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusRtuOverTcpDebugPage.razor" Link="Pages\Modbus\ModbusRtuOverTcpDebugPage.razor" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusRtuOverUdpDebugPage.razor.cs" Link="Pages\Modbus\ModbusRtuOverUdpDebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusRtuOverUdpDebugPage.razor" Link="Pages\Modbus\ModbusRtuOverUdpDebugPage.razor" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusSerialServerDebugPage.razor.cs" Link="Pages\Modbus\ModbusSerialServerDebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusSerialServerDebugPage.razor" Link="Pages\Modbus\ModbusSerialServerDebugPage.razor" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusTcpDebugPage.razor.cs" Link="Pages\Modbus\ModbusTcpDebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusTcpDebugPage.razor" Link="Pages\Modbus\ModbusTcpDebugPage.razor" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusTcpDtuDebugPage.razor.cs" Link="Pages\Modbus\ModbusTcpDtuDebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusTcpDtuDebugPage.razor" Link="Pages\Modbus\ModbusTcpDtuDebugPage.razor" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusTcpServerDebugPage.razor.cs" Link="Pages\Modbus\ModbusTcpServerDebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusTcpServerDebugPage.razor" Link="Pages\Modbus\ModbusTcpServerDebugPage.razor" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusUdpDebugPage.razor.cs" Link="Pages\Modbus\ModbusUdpDebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusUdpDebugPage.razor" Link="Pages\Modbus\ModbusUdpDebugPage.razor" /> | ||||
|  | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.OPCDA\Page\OPCDAClientDebugPage.razor.cs" Link="Pages\OPCDA\OPCDAClientDebugPage.razor.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.OPCDA\Page\OPCDAClientPage.razor.cs" Link="Pages\OPCDA\OPCDAClientPage.razor.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.OPCDA\Page\OPCDAImportVariable.razor.cs" Link="Pages\OPCDA\OPCDAImportVariable.razor.cs" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.OPCDA\Page\OPCDAClientDebugPage.razor" Link="Pages\OPCDA\OPCDAClientDebugPage.razor" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.OPCDA\Page\OPCDAClientPage.razor" Link="Pages\OPCDA\OPCDAClientPage.razor" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.OPCDA\Page\OPCDAImportVariable.razor" Link="Pages\OPCDA\OPCDAImportVariable.razor" /> | ||||
|  | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.OPCUA\Page\OPCUAClientDebugPage.razor" Link="Pages\OPCUA\OPCUAClientDebugPage.razor" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.OPCUA\Page\OPCUAClientPage.razor" Link="Pages\OPCUA\OPCUAClientPage.razor" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.OPCUA\Page\OPCUAImportVariable.razor" Link="Pages\OPCUA\OPCUAImportVariable.razor" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.OPCUA\Page\OPCUAClientDebugPage.razor.cs" Link="Pages\OPCUA\OPCUAClientDebugPage.razor.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.OPCUA\Page\OPCUAClientPage.razor.cs" Link="Pages\OPCUA\OPCUAClientPage.razor.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.OPCUA\Page\OPCUAImportVariable.razor.cs" Link="Pages\OPCUA\OPCUAImportVariable.razor.cs" /> | ||||
|  | ||||
|  | ||||
|  | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_1200DebugPage.razor" Link="Pages\Siemens\S7_1200DebugPage.razor" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_1500DebugPage.razor" Link="Pages\Siemens\S7_1500DebugPage.razor" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_200DebugPage.razor" Link="Pages\Siemens\S7_200DebugPage.razor" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_200SMARTDebugPage.razor" Link="Pages\Siemens\S7_200SMARTDebugPage.razor" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_300DebugPage.razor" Link="Pages\Siemens\S7_300DebugPage.razor" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_400DebugPage.razor" Link="Pages\Siemens\S7_400DebugPage.razor" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_1200DebugPage.razor.cs" Link="Pages\Siemens\S7_1200DebugPage.razor.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_1500DebugPage.razor.cs" Link="Pages\Siemens\S7_1500DebugPage.razor.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_200DebugPage.razor.cs" Link="Pages\Siemens\S7_200DebugPage.razor.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_200SMARTDebugPage.razor.cs" Link="Pages\Siemens\S7_200SMARTDebugPage.razor.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_300DebugPage.razor.cs" Link="Pages\Siemens\S7_300DebugPage.razor.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Siemens\Page\S7_400DebugPage.razor.cs" Link="Pages\Siemens\S7_400DebugPage.razor.cs" /> | ||||
|  | ||||
|  | ||||
| 	</ItemGroup> | ||||
|  | ||||
|  | ||||
| 	<ItemGroup> | ||||
| 		<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.DLT645\ThingsGateway.Foundation.Adapter.DLT645.csproj" /> | ||||
| 		<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.Modbus\ThingsGateway.Foundation.Adapter.Modbus.csproj" /> | ||||
| 		<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.OPCDA\ThingsGateway.Foundation.Adapter.OPCDA.csproj" /> | ||||
| 		<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.OPCUA\ThingsGateway.Foundation.Adapter.OPCUA.csproj" /> | ||||
| 		<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.Siemens\ThingsGateway.Foundation.Adapter.Siemens.csproj" /> | ||||
| 		<ProjectReference Include="..\..\Web\ThingsGateway.Components\ThingsGateway.Components.csproj" /> | ||||
| 	</ItemGroup> | ||||
|  | ||||
|  | ||||
| 	<ItemGroup> | ||||
| 		<Content Update="wwwroot\**"> | ||||
| 			<CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||||
| 		</Content> | ||||
| 	</ItemGroup> | ||||
|  | ||||
|  | ||||
| 	<ItemGroup> | ||||
| 	  <Folder Include="Pages\Mqtt\" /> | ||||
| 	</ItemGroup> | ||||
|  | ||||
|  | ||||
| 	<ItemGroup> | ||||
| 	  <Content Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\MqttClientDebugPage.razor" Link="Pages\Mqtt\MqttClientDebugPage.razor" /> | ||||
| 	  <Content Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\MqttClientPage.razor" Link="Pages\Mqtt\MqttClientPage.razor" /> | ||||
| 		<PackageReference Include="MQTTnet" Version="4.3.1.873" /> | ||||
| 	</ItemGroup> | ||||
|  | ||||
|  | ||||
|  | ||||
| </Project> | ||||
| @@ -25,5 +25,5 @@ | ||||
| @using System.Net.Http.Json | ||||
| @using System.IO; | ||||
| @using System.Text.Json; | ||||
| @using ThingsGateway.Foundation.SerialPorts; | ||||
| @using ThingsGateway.Foundation.Serial; | ||||
| @using ThingsGateway.Foundation.Sockets; | ||||
| Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB | 
| Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB | 
| @@ -8,6 +8,7 @@ | ||||
| 
 | ||||
|     <link rel="icon" href="favicon.ico" type="image/x-icon"> | ||||
| 
 | ||||
| 
 | ||||
|     <link href="_content/Masa.Blazor/css/masa-blazor.min.css" rel="stylesheet" /> | ||||
|     <link href="_content/ThingsGateway.Components/css/materialdesign/v7.1.96/css/materialdesignicons.min.css" rel="stylesheet"> | ||||
|     <link href="_content/ThingsGateway.Components/css/material/icons.css" rel="stylesheet"> | ||||
| @@ -1,14 +1,13 @@ | ||||
| <Project> | ||||
| 	<Import Project="$(SolutionDir)\Directory.Build.props" /> | ||||
| 	<!--如果编译net45报错无支持,用一下方法添加net45包--> | ||||
| 	<!--VS顶部菜单栏 -> 视图 -> 其他 -> 程序包控制台 | ||||
| 	Install-Package Microsoft.NETFramework.ReferenceAssemblies.net45 | ||||
| 	--> | ||||
| 	<PropertyGroup> | ||||
| 		<TargetFrameworks>net45;netstandard2.0;net6.0;net8.0;</TargetFrameworks> | ||||
| 		<Description> | ||||
| 			ThingsGateway.Foundation是工业设备通讯类库,归属于ThingsGateway边缘网关项目,说明文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| 		</Description> | ||||
| 		<Version>3.0.0.8</Version> | ||||
| 		<GenerateDocumentationFile>True</GenerateDocumentationFile> | ||||
| 		<LangVersion>latest</LangVersion> | ||||
| 		<TargetFrameworks>net45;netstandard2.0;net6.0;net7.0</TargetFrameworks> | ||||
| 		<Authors>Diego</Authors> | ||||
| 		<Product>ThingsGateway</Product> | ||||
| 		<Copyright>© 2023-present Diego</Copyright> | ||||
| 		<RepositoryUrl>https://gitee.com/diego2098/ThingsGateway</RepositoryUrl> | ||||
| 		<PublishRepositoryUrl>true</PublishRepositoryUrl> | ||||
| 		<EmbedUntrackedSource>true</EmbedUntrackedSource> | ||||
| 		<EmbedAllSources>true</EmbedAllSources> | ||||
| @@ -17,14 +16,21 @@ | ||||
| 		<PackageReadmeFile>README.md</PackageReadmeFile> | ||||
| 		<PackageIcon>icon.png</PackageIcon> | ||||
| 		<IncludeSymbols>true</IncludeSymbols> | ||||
| 		<SymbolPackageFormat>snupkg</SymbolPackageFormat> | ||||
| 		<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression> | ||||
| 		<PackageProjectUrl>https://diego2098.gitee.io/thingsgateway-docs/</PackageProjectUrl> | ||||
| 		<PackageTags>ThingsGateway;Diego;dotNET China;Blazor;设备采集;边缘网关</PackageTags> | ||||
| 		<PackageOutputPath>..\..\nupkgs</PackageOutputPath> | ||||
| 		<AssemblyOriginatorKeyFile>..\..\..\snks/ThingsGateway.snk</AssemblyOriginatorKeyFile> | ||||
| 		<GenerateDocumentationFile>True</GenerateDocumentationFile> | ||||
| 		<SignAssembly>True</SignAssembly> | ||||
| 		<DelaySign>False</DelaySign> | ||||
| 		<SatelliteResourceLanguages>zh-Hans</SatelliteResourceLanguages> | ||||
| 		<PackageOutputPath>../../nupkgs</PackageOutputPath> | ||||
| 		<AssemblyOriginatorKeyFile>../../../snks/ThingsGateway.snk</AssemblyOriginatorKeyFile> | ||||
| 	</PropertyGroup> | ||||
| 
 | ||||
| 	<PropertyGroup> | ||||
| 	</PropertyGroup> | ||||
| 
 | ||||
| 
 | ||||
| 	<ItemGroup> | ||||
| 		<None Include="..\..\..\README.md" Pack="true" PackagePath="\" /> | ||||
| 	</ItemGroup> | ||||
| @@ -41,5 +47,4 @@ | ||||
| 		<DebugType>Embedded</DebugType> | ||||
| 		<EmbedAllSources>True</EmbedAllSources> | ||||
| 	</PropertyGroup> | ||||
| 	 | ||||
| </Project> | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.DLT645; | ||||
| @@ -17,48 +15,40 @@ namespace ThingsGateway.Foundation.Adapter.DLT645; | ||||
| /// <summary> | ||||
| /// 控制码 | ||||
| /// </summary> | ||||
| internal enum ControlCode : byte | ||||
| public enum ControlCode : byte | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 读数据 | ||||
|     /// </summary> | ||||
|     Read = 0x11, | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 读后续数据 | ||||
|     /// </summary> | ||||
|     ReadSub = 0x12, | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 读站号 | ||||
|     /// </summary> | ||||
|     ReadStation = 0x13, | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 写数据 | ||||
|     /// </summary> | ||||
|     Write = 0x14, | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 写站号 | ||||
|     /// </summary> | ||||
|     WriteStation = 0x15, | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 广播校时 | ||||
|     /// </summary> | ||||
|     BroadcastTime = 0x08, | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 冻结 | ||||
|     /// </summary> | ||||
|     Freeze = 0x16, | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 更新波特率 | ||||
|     /// </summary> | ||||
|     WriteBaudRate = 0x17, | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 更新密码 | ||||
|     /// </summary> | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.Text; | ||||
| @@ -17,30 +15,33 @@ using System.Text; | ||||
| using ThingsGateway.Foundation.Extension.Generic; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.DLT645; | ||||
| 
 | ||||
| /// <summary> | ||||
| /// 解析参数 | ||||
| /// </summary> | ||||
| internal class DataInfo | ||||
| public class DataInfo | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 解析长度 | ||||
|     /// </summary> | ||||
|     public int ByteLength { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 小数位 | ||||
|     /// </summary> | ||||
|     public int Digtal { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 有符号解析 | ||||
|     /// </summary> | ||||
|     public bool IsSigned { get; set; } | ||||
| } | ||||
| 
 | ||||
| internal static class DLT645Helper | ||||
| { | ||||
|     internal static byte[] BytesAdd(this byte[] bytes, int value) | ||||
|     { | ||||
|         for (int index = 0; index < bytes.Length; ++index) | ||||
|             bytes[index] = (byte)(bytes[index] + value); | ||||
|         return bytes; | ||||
|     } | ||||
| 
 | ||||
|     internal static string Get2007ErrorMessage(byte buffer) | ||||
|     { | ||||
|         string error = buffer switch | ||||
| @@ -80,7 +81,6 @@ internal static class DLT645Helper | ||||
|                             new(){ ByteLength=4,Digtal=2,IsSigned=true}, | ||||
|                         }); | ||||
|                         break; | ||||
| 
 | ||||
|                     default: | ||||
|                         //正向有功总电能 | ||||
|                         //反向有功总电能 | ||||
| @@ -104,7 +104,6 @@ internal static class DLT645Helper | ||||
|                             new(){ ByteLength=5,Digtal=0,IsSigned=false}, | ||||
|                         }); | ||||
|                         break; | ||||
| 
 | ||||
|                     default: | ||||
|                         dataInfos.AddRange(new DataInfo[] | ||||
|                         { | ||||
| @@ -127,14 +126,12 @@ internal static class DLT645Helper | ||||
| }); | ||||
| 
 | ||||
|                         break; | ||||
| 
 | ||||
|                     case 2://电流 | ||||
|                         dataInfos.AddRange(new DataInfo[] | ||||
| { | ||||
|                            new(){ ByteLength=3,Digtal=3,IsSigned=true}, | ||||
| }); | ||||
|                         break; | ||||
| 
 | ||||
|                     case < 6: | ||||
|                         //瞬时总有功功率 | ||||
|                         //瞬时A相有功功率 | ||||
| @@ -157,14 +154,12 @@ internal static class DLT645Helper | ||||
| }); | ||||
| 
 | ||||
|                         break; | ||||
| 
 | ||||
|                     case 6://功率因数 | ||||
|                         dataInfos.AddRange(new DataInfo[] | ||||
| { | ||||
|                            new(){ ByteLength=2,Digtal=3,IsSigned=true}, | ||||
| }); | ||||
|                         break; | ||||
| 
 | ||||
|                     case 7://相角 | ||||
| 
 | ||||
|                         dataInfos.AddRange(new DataInfo[] | ||||
| @@ -172,8 +167,8 @@ internal static class DLT645Helper | ||||
|                            new(){ ByteLength=2,Digtal=1,IsSigned=false}, | ||||
| }); | ||||
| 
 | ||||
|                         break; | ||||
| 
 | ||||
|                         break; | ||||
|                     case < 0x80: | ||||
|                         { | ||||
|                             //A相电压波形失真度 | ||||
| @@ -226,21 +221,18 @@ internal static class DLT645Helper | ||||
|                            new(){ ByteLength=3,Digtal=3,IsSigned=true}, | ||||
| }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 2://电网频率 | ||||
|                                 dataInfos.AddRange(new DataInfo[] | ||||
| { | ||||
|                            new(){ ByteLength=2,Digtal=2,IsSigned=false}, | ||||
| }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 3://一分钟有功总平均功率 | ||||
|                                 dataInfos.AddRange(new DataInfo[] | ||||
| { | ||||
|                            new(){ ByteLength=3,Digtal=4,IsSigned=false}, | ||||
| }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 4://当前有功需量 | ||||
|                             case 5://当前无功需量 | ||||
|                             case 6://当前视在需量 | ||||
| @@ -249,14 +241,12 @@ internal static class DLT645Helper | ||||
|                            new(){ ByteLength=3,Digtal=4,IsSigned=true}, | ||||
| }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 7://表内温度 | ||||
|                                 dataInfos.AddRange(new DataInfo[] | ||||
| { | ||||
|                            new(){ ByteLength=2,Digtal=1,IsSigned=false}, | ||||
| }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 8://时钟电池电压(内部) | ||||
|                             case 9://停电抄表电池电压(外部) | ||||
|                                 dataInfos.AddRange(new DataInfo[] | ||||
| @@ -264,14 +254,12 @@ internal static class DLT645Helper | ||||
|                            new(){ ByteLength=2,Digtal=2,IsSigned=false}, | ||||
| }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 10://内部电池工作时间 | ||||
|                                 dataInfos.AddRange(new DataInfo[] | ||||
| { | ||||
|                            new(){ ByteLength=4,Digtal=0,IsSigned=false}, | ||||
| }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 11://当前阶梯电价 | ||||
|                                 dataInfos.AddRange(new DataInfo[] | ||||
| { | ||||
| @@ -280,7 +268,6 @@ internal static class DLT645Helper | ||||
|                                 break; | ||||
|                         } | ||||
|                         break; | ||||
| 
 | ||||
|                     default: | ||||
|                         break; | ||||
|                 } | ||||
| @@ -344,8 +331,10 @@ internal static class DLT645Helper | ||||
|                             new DataInfo() { ByteLength = 4, Digtal = 2}, | ||||
|                             new DataInfo() { ByteLength = 4, Digtal = 2}, | ||||
|                             new DataInfo() { ByteLength = 4, Digtal = 2}, | ||||
| 
 | ||||
| }); | ||||
|                             break; | ||||
| 
 | ||||
|                         } | ||||
| 
 | ||||
|                     case 5://全失压总次数,总累计时间 | ||||
| @@ -368,10 +357,13 @@ internal static class DLT645Helper | ||||
| }); | ||||
| 
 | ||||
|                             break; | ||||
| 
 | ||||
|                         } | ||||
| 
 | ||||
| 
 | ||||
|                         break; | ||||
| 
 | ||||
| 
 | ||||
|                     case 6://辅助电源失电总次数,总累计时间 | ||||
| 
 | ||||
|                         if (buffer[1] == 0 && buffer[0] == 0) | ||||
| @@ -392,10 +384,10 @@ internal static class DLT645Helper | ||||
|                            new(){ ByteLength=6,Digtal=0,IsSigned=false}, | ||||
| }); | ||||
|                             break; | ||||
| 
 | ||||
|                         } | ||||
| 
 | ||||
|                         break; | ||||
| 
 | ||||
|                     case 7://电压逆相序总次数,总累计时间 | ||||
|                     case 8://电流逆相序总次数,总累计时间 | ||||
|                         if (buffer[1] == 0 && buffer[0] == 0) | ||||
| @@ -423,10 +415,11 @@ internal static class DLT645Helper | ||||
|                             }); | ||||
|                             } | ||||
|                             break; | ||||
| 
 | ||||
|                         } | ||||
| 
 | ||||
|                         break; | ||||
| 
 | ||||
|                         break; | ||||
|                     case 9://电压不平衡总次数,总累计时间 | ||||
|                     case 0x0A://电流不平衡总次数,总累计时间 | ||||
|                         if (buffer[1] == 0 && buffer[0] == 0) | ||||
| @@ -446,6 +439,7 @@ internal static class DLT645Helper | ||||
|                                 new DataInfo(){ByteLength=6, Digtal=0}, | ||||
|                                 new DataInfo(){ByteLength=2, Digtal=2}, | ||||
|                                 new DataInfo(){ByteLength=2, Digtal=2}, | ||||
| 
 | ||||
|                             }); | ||||
|                             for (int i = 0; i < 16; i++) | ||||
|                             { | ||||
| @@ -455,8 +449,10 @@ internal static class DLT645Helper | ||||
|                             }); | ||||
|                             } | ||||
|                             break; | ||||
| 
 | ||||
|                         } | ||||
| 
 | ||||
| 
 | ||||
|                         break; | ||||
| 
 | ||||
|                     case 0x0B: | ||||
| @@ -512,8 +508,10 @@ internal static class DLT645Helper | ||||
|                                 new DataInfo(){ByteLength=3, Digtal=4}, | ||||
|                                 new DataInfo(){ByteLength=3, Digtal=4}, | ||||
|                                 new DataInfo(){ByteLength=2, Digtal=3}, | ||||
| 
 | ||||
|                             }); | ||||
|                             break; | ||||
| 
 | ||||
|                         } | ||||
| 
 | ||||
|                     case 0x0E: | ||||
| @@ -537,6 +535,7 @@ internal static class DLT645Helper | ||||
|                             { | ||||
|                                 new DataInfo(){ByteLength=6, Digtal=0}, | ||||
|                                 new DataInfo(){ByteLength=6, Digtal=0}, | ||||
| 
 | ||||
|                             }); | ||||
|                             for (int i = 0; i < 16; i++) | ||||
|                             { | ||||
| @@ -546,6 +545,7 @@ internal static class DLT645Helper | ||||
|                             }); | ||||
|                             } | ||||
|                             break; | ||||
| 
 | ||||
|                         } | ||||
| 
 | ||||
|                     case 0x10: | ||||
| @@ -560,9 +560,11 @@ internal static class DLT645Helper | ||||
|                                 new DataInfo(){ByteLength=4, Digtal=0}, | ||||
|                                 new DataInfo(){ByteLength=2, Digtal=1}, | ||||
|                                 new DataInfo(){ByteLength=4, Digtal=0}, | ||||
| 
 | ||||
|                             }); | ||||
|                         break; | ||||
| 
 | ||||
| 
 | ||||
|                     case 0x11: | ||||
|                         if (buffer[1] == 0 && buffer[0] == 0) | ||||
|                         { | ||||
| @@ -580,9 +582,11 @@ internal static class DLT645Helper | ||||
|                                 new DataInfo(){ByteLength=6, Digtal=0}, | ||||
|                             }); | ||||
|                             break; | ||||
| 
 | ||||
|                         } | ||||
|                         break; | ||||
| 
 | ||||
| 
 | ||||
|                     case 0x12: | ||||
|                         if (buffer[1] == 0 && buffer[0] == 0) | ||||
|                         { | ||||
| @@ -608,8 +612,10 @@ internal static class DLT645Helper | ||||
|                                 new DataInfo(){ByteLength=5, Digtal=0}, | ||||
|                             }); | ||||
|                             break; | ||||
| 
 | ||||
|                         } | ||||
| 
 | ||||
| 
 | ||||
|                     case 0x30: | ||||
| 
 | ||||
|                         switch (buffer[1]) | ||||
| @@ -639,7 +645,6 @@ internal static class DLT645Helper | ||||
|                                 } | ||||
| 
 | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 1://电表清零记录 | ||||
| 
 | ||||
|                                 if (buffer[0] == 0) | ||||
| @@ -665,7 +670,6 @@ internal static class DLT645Helper | ||||
|                                     } | ||||
|                                 } | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 2://编程记录 | ||||
| 
 | ||||
|                                 if (buffer[0] == 0) | ||||
| @@ -677,6 +681,7 @@ internal static class DLT645Helper | ||||
|                                 } | ||||
|                                 else | ||||
|                                 { | ||||
| 
 | ||||
|                                     dataInfos.AddRange(new List<DataInfo>() | ||||
|                                     { | ||||
|                                         new DataInfo { ByteLength = 6, Digtal = 0 }, | ||||
| @@ -693,7 +698,6 @@ internal static class DLT645Helper | ||||
|                                     } | ||||
|                                 } | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 3://事件清零记录 | ||||
|                                 if (buffer[0] == 0) | ||||
|                                 { | ||||
| @@ -712,7 +716,6 @@ internal static class DLT645Helper | ||||
|                                     }); | ||||
|                                 } | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 4://校时记录 | ||||
|                                 if (buffer[0] == 0) | ||||
|                                 { | ||||
| @@ -731,7 +734,6 @@ internal static class DLT645Helper | ||||
|                                     }); | ||||
|                                 } | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 5://时段表编程记录 | ||||
|                                 if (buffer[0] == 0) | ||||
|                                 { | ||||
| @@ -756,7 +758,6 @@ internal static class DLT645Helper | ||||
|                                     } | ||||
|                                 } | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 6://时区表编程记录 | ||||
|                                 if (buffer[0] == 0) | ||||
|                                 { | ||||
| @@ -781,7 +782,6 @@ internal static class DLT645Helper | ||||
|                                     } | ||||
|                                 } | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 7://周休日编程记录 | ||||
|                                 if (buffer[0] == 0) | ||||
|                                 { | ||||
| @@ -826,7 +826,6 @@ internal static class DLT645Helper | ||||
|                                     } | ||||
|                                 } | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 9: | ||||
|                             case 10: | ||||
|                             case 11://有功组合方式编程记录 | ||||
| @@ -847,7 +846,6 @@ internal static class DLT645Helper | ||||
|                                     }); | ||||
|                                 } | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 12://结算日编程记录 | ||||
|                                 if (buffer[0] == 0) | ||||
|                                 { | ||||
| @@ -868,7 +866,6 @@ internal static class DLT645Helper | ||||
|                                     }); | ||||
|                                 } | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 13: | ||||
|                             case 14: | ||||
|                                 if (buffer[0] == 0) | ||||
| @@ -894,8 +891,10 @@ internal static class DLT645Helper | ||||
|                                     } | ||||
|                                 } | ||||
|                                 break; | ||||
| 
 | ||||
|                         } | ||||
|                         break; | ||||
| 
 | ||||
|                 } | ||||
|                 break; | ||||
| 
 | ||||
| @@ -915,55 +914,44 @@ internal static class DLT645Helper | ||||
|                             new(){ ByteLength=4,Digtal=0,IsSigned=false}, | ||||
| }); | ||||
|                                         break; | ||||
| 
 | ||||
|                                     case 2: | ||||
|                                         dataInfos.AddRange(new DataInfo[] | ||||
| { | ||||
|                             new(){ ByteLength=3,Digtal=0,IsSigned=false}, | ||||
| }); | ||||
|                                         break; | ||||
| 
 | ||||
|                                     case 3: | ||||
|                                         dataInfos.AddRange(new DataInfo[] { new() { ByteLength = 1, Digtal = 0, IsSigned = false } }); | ||||
|                                         break; | ||||
| 
 | ||||
|                                     case 4: | ||||
|                                         dataInfos.AddRange(new DataInfo[] { new() { ByteLength = 1, Digtal = 0, IsSigned = false } }); | ||||
|                                         break; | ||||
| 
 | ||||
|                                     case 5: | ||||
|                                         dataInfos.AddRange(new DataInfo[] { new() { ByteLength = 2, Digtal = 0, IsSigned = false } }); | ||||
|                                         break; | ||||
| 
 | ||||
|                                     case 6: | ||||
|                                         dataInfos.AddRange(new DataInfo[] { new() { ByteLength = 5, Digtal = 0, IsSigned = false } }); | ||||
|                                         break; | ||||
| 
 | ||||
|                                     case 7: | ||||
|                                         dataInfos.AddRange(new DataInfo[] { new() { ByteLength = 5, Digtal = 0, IsSigned = false } }); | ||||
|                                         break; | ||||
| 
 | ||||
|                                     default: | ||||
|                                         break; | ||||
|                                 } | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 2: | ||||
|                                 switch (buffer[0]) | ||||
|                                 { | ||||
|                                     case 5: | ||||
|                                         dataInfos.AddRange(new DataInfo[] { new() { ByteLength = 2, Digtal = 0, IsSigned = false } }); | ||||
|                                         break; | ||||
| 
 | ||||
|                                     default: | ||||
|                                         break; | ||||
|                                 } | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 3: | ||||
|                                 dataInfos.AddRange(new DataInfo[] { new() { ByteLength = 1, Digtal = 0, IsSigned = false } }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 4: | ||||
|                                 if (buffer[0] <= 2) | ||||
|                                     dataInfos.AddRange(new DataInfo[] | ||||
| @@ -986,27 +974,21 @@ internal static class DLT645Helper | ||||
|                                 else if (buffer[0] == 13) | ||||
|                                     dataInfos.AddRange(new DataInfo[] { new() { ByteLength = 16, Digtal = -1, IsSigned = false } }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 5: | ||||
|                                 dataInfos.AddRange(new DataInfo[] { new() { ByteLength = 2, Digtal = 0, IsSigned = false } }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 6: | ||||
|                                 dataInfos.AddRange(new DataInfo[] { new() { ByteLength = 1, Digtal = 0, IsSigned = false } }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 7: | ||||
|                                 dataInfos.AddRange(new DataInfo[] { new() { ByteLength = 1, Digtal = 0, IsSigned = false } }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 8: | ||||
|                                 dataInfos.AddRange(new DataInfo[] { new() { ByteLength = 1, Digtal = 0, IsSigned = false } }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 9: | ||||
|                                 dataInfos.AddRange(new DataInfo[] { new() { ByteLength = 1, Digtal = 0, IsSigned = false } }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 10: | ||||
|                                 switch (buffer[0]) | ||||
|                                 { | ||||
| @@ -1016,7 +998,6 @@ internal static class DLT645Helper | ||||
|                             new(){ ByteLength=4,Digtal=0,IsSigned=false}, | ||||
| }); | ||||
|                                         break; | ||||
| 
 | ||||
|                                     default: | ||||
|                                         dataInfos.AddRange(new DataInfo[] | ||||
| { | ||||
| @@ -1025,22 +1006,18 @@ internal static class DLT645Helper | ||||
|                                         break; | ||||
|                                 } | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 11: | ||||
|                                 dataInfos.AddRange(new DataInfo[] { new() { ByteLength = 2, Digtal = 0, IsSigned = false } }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 12: | ||||
|                                 dataInfos.AddRange(new DataInfo[] { new() { ByteLength = 4, Digtal = 0, IsSigned = false } }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 13: | ||||
|                                 dataInfos.AddRange(new DataInfo[] | ||||
| { | ||||
|                             new(){ ByteLength=2,Digtal=3,IsSigned=false}, | ||||
| }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 14: | ||||
|                                 if (buffer[0] < 3) | ||||
|                                     dataInfos.AddRange(new DataInfo[] | ||||
| @@ -1055,7 +1032,6 @@ internal static class DLT645Helper | ||||
|                                 break; | ||||
|                         } | ||||
|                         break; | ||||
| 
 | ||||
|                     case 1: | ||||
|                     case 2: | ||||
|                         if (buffer[1] == 0) | ||||
| @@ -1066,12 +1042,10 @@ internal static class DLT645Helper | ||||
|                             } | ||||
|                         } | ||||
|                         break; | ||||
| 
 | ||||
|                     case 3: | ||||
|                     case 4: | ||||
|                         dataInfos.AddRange(new DataInfo[] { new() { ByteLength = 4, Digtal = 0, IsSigned = false } }); | ||||
|                         break; | ||||
| 
 | ||||
|                     case 0x80: | ||||
|                         dataInfos.AddRange(new DataInfo[] { new() { ByteLength = 32, Digtal = -1, IsSigned = false } }); | ||||
|                         break; | ||||
| @@ -1096,7 +1070,6 @@ internal static class DLT645Helper | ||||
|                                         break; | ||||
|                                 } | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 1: | ||||
|                             case 2: | ||||
|                             case 3: | ||||
| @@ -1119,7 +1092,6 @@ internal static class DLT645Helper | ||||
|                             new(){ ByteLength=5,Digtal=0,IsSigned=false}, | ||||
| }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 16: | ||||
|                                 for (int i = 0; i < 8; i++) | ||||
|                                 { | ||||
| @@ -1146,7 +1118,6 @@ internal static class DLT645Helper | ||||
|                             new(){ ByteLength=1,Digtal=0,IsSigned=false}, | ||||
| }); | ||||
|                                 break; | ||||
| 
 | ||||
|                             case 1: | ||||
|                                 dataInfos.AddRange(new DataInfo[] | ||||
| { | ||||
| @@ -1155,7 +1126,6 @@ internal static class DLT645Helper | ||||
|                                 break; | ||||
|                         } | ||||
|                         break; | ||||
| 
 | ||||
|                     default: | ||||
|                         if (buffer[0] == 2) | ||||
|                             dataInfos.AddRange(new DataInfo[] | ||||
| @@ -1170,6 +1140,8 @@ internal static class DLT645Helper | ||||
|         return dataInfos; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 获取DLT645报文 | ||||
|     /// </summary> | ||||
| @@ -1239,9 +1211,12 @@ internal static class DLT645Helper | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
| 
 | ||||
|                 buffer = buffer.SpliceArray(codes, buffers.ToArray()); | ||||
| 
 | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|             byte[] stationBytes; | ||||
|             if (operResult.Station.Length == 0) | ||||
|             { | ||||
| @@ -1256,13 +1231,14 @@ internal static class DLT645Helper | ||||
|             } | ||||
| 
 | ||||
|             return GetDLT645_2007Command(control, buffer, stationBytes); | ||||
| 
 | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new(ex); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     } | ||||
|     internal static OperResult<byte[]> GetDLT645_2007Command(byte control, byte[] buffer, byte[] stationBytes) | ||||
|     { | ||||
|         buffer ??= new byte[0]; | ||||
| @@ -1286,4 +1262,4 @@ internal static class DLT645Helper | ||||
|         array[array.Length - 1] = 0x16;//	结束符 | ||||
|         return OperResult.CreateSuccessResult(array); | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -0,0 +1,480 @@ | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| using System.ComponentModel; | ||||
|  | ||||
| using ThingsGateway.Foundation.Extension.Generic; | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Adapter.DLT645; | ||||
| /// <summary> | ||||
| /// DLT645_2007 | ||||
| /// </summary> | ||||
| public class DLT645_2007 : ReadWriteDevicesSerialSessionBase | ||||
| { | ||||
|     /// <summary> | ||||
|     /// DLT645_2007 | ||||
|     /// </summary> | ||||
|     /// <param name="serialSession"></param> | ||||
|     public DLT645_2007(SerialSession serialSession) : base(serialSession) | ||||
|     { | ||||
|         ThingsGatewayBitConverter = new DLT645_2007BitConverter(EndianType.Big); | ||||
|         RegisterByteLength = 2; | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 增加FE FE FE FE的报文头部 | ||||
|     /// </summary> | ||||
|     [Description("前导符报文头")] | ||||
|     public bool EnableFEHead { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 写入需操作员代码 | ||||
|     /// </summary> | ||||
|     [Description("操作员代码")] | ||||
|     public string OperCode { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 写入密码 | ||||
|     /// </summary> | ||||
|     [Description("写入密码")] | ||||
|     public string Password { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 通讯地址BCD码,一般应该是12个字符 | ||||
|     /// </summary> | ||||
|     [Description("通讯地址")] | ||||
|     public string Station { get; set; } | ||||
|     /// <inheritdoc/> | ||||
|     public override string GetAddressDescription() | ||||
|     { | ||||
|  | ||||
|         var str = """ | ||||
|             查看附带文档或者相关资料,下面列举一下常见的数据标识地址  | ||||
|              | ||||
|             地址                       说明                     | ||||
|             ----------------------------------------- | ||||
|             02010100    A相电压 | ||||
|             02020100    A相电流 | ||||
|             02030000    瞬时总有功功率 | ||||
|             00000000    (当前)组合有功总电能 | ||||
|             00010000    (当前)正向有功总电能 | ||||
|              | ||||
|             """; | ||||
|         return base.GetAddressDescription() + Environment.NewLine + str; | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack) | ||||
|     { | ||||
|         return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Read, Station); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = WaitingClientEx.SendThenResponse(commandResult.Content, TimeOut, cancellationToken); | ||||
|                 return (MessageBase)result.RequestInfo; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult<byte[]>(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<byte[]>(ex); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override async Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Read, Station); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken); | ||||
|                 return (MessageBase)result.RequestInfo; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult<byte[]>(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<byte[]>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public override void SetDataAdapter(object socketClient = null) | ||||
|     { | ||||
|         var dataHandleAdapter = new DLT645_2007DataHandleAdapter | ||||
|         { | ||||
|             EnableFEHead = EnableFEHead | ||||
|         }; | ||||
|         SerialSession.SetDataHandlingAdapter(dataHandleAdapter); | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult Write(string address, string value, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|  | ||||
|         try | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             Password ??= string.Empty; | ||||
|             OperCode ??= string.Empty; | ||||
|             if (Password.Length < 8) | ||||
|                 Password = Password.PadLeft(8, '0'); | ||||
|             if (OperCode.Length < 8) | ||||
|                 OperCode = OperCode.PadLeft(8, '0'); | ||||
|             var data = DataTransUtil.SpliceArray(Password.ByHexStringToBytes(), OperCode.ByHexStringToBytes()); | ||||
|             string[] strArray = value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Write, Station, data, strArray); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = WaitingClientEx.SendThenResponse(commandResult.Content, TimeOut, cancellationToken); | ||||
|                 return (MessageBase)result.RequestInfo; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<byte[]>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult Write(string address, byte[] value, CancellationToken cancellationToken = default) => Write(address, value.ToString(), cancellationToken); | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default) => Write(address, value.ToString(), cancellationToken); | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override async Task<OperResult> WriteAsync(string address, string value, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|  | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             Password ??= string.Empty; | ||||
|             OperCode ??= string.Empty; | ||||
|             if (Password.Length < 8) | ||||
|                 Password = Password.PadLeft(8, '0'); | ||||
|             if (OperCode.Length < 8) | ||||
|                 OperCode = OperCode.PadLeft(8, '0'); | ||||
|             var data = DataTransUtil.SpliceArray(Password.ByHexStringToBytes(), OperCode.ByHexStringToBytes()); | ||||
|             string[] strArray = value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Write, Station, data, strArray); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken); | ||||
|                 return (MessageBase)result.RequestInfo; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<byte[]>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, uint value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, double value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, float value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, long value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, ulong value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, ushort value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, short value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, int value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|  | ||||
|  | ||||
|     #region 其他方法 | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 广播校时 | ||||
|     /// </summary> | ||||
|     /// <param name="dateTime"></param> | ||||
|     /// <param name="cancellationToken"></param> | ||||
|     /// <returns></returns> | ||||
|     public OperResult BroadcastTime(DateTime dateTime, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             string str = $"{dateTime.Second:D2}{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}{dateTime.Year % 100:D2}"; | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.BroadcastTime, str.ByHexStringToBytes().ToArray(), "999999999999".ByHexStringToBytes()); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 SerialSession.Send(commandResult.Content); | ||||
|                 return OperResult.CreateSuccessResult(); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<string>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 冻结 | ||||
|     /// </summary> | ||||
|     /// <param name="dateTime"></param> | ||||
|     /// <param name="cancellationToken"></param> | ||||
|     /// <returns></returns> | ||||
|     public async Task<OperResult> FreezeAsync(DateTime dateTime, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             string str = $"{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}"; | ||||
|             if (Station.IsNullOrEmpty()) Station = string.Empty; | ||||
|             if (Station.Length < 12) Station = Station.PadLeft(12, '0'); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.Freeze, str.ByHexStringToBytes().ToArray(), Station.ByHexStringToBytes().Reverse().ToArray()); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken); | ||||
|                 var result1 = ((MessageBase)result.RequestInfo); | ||||
|                 if (result1.IsSuccess) | ||||
|                 { | ||||
|                     return OperResult.CreateSuccessResult(); | ||||
|  | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return new OperResult(result1); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<string>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 读取通信地址 | ||||
|     /// </summary> | ||||
|     /// <param name="cancellationToken"></param> | ||||
|     /// <returns></returns> | ||||
|     public async Task<OperResult<string>> ReadDeviceStationAsync(CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.ReadStation, null, "AAAAAAAAAAAA".ByHexStringToBytes()); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken); | ||||
|                 var result1 = ((MessageBase)result.RequestInfo); | ||||
|                 if (result1.IsSuccess) | ||||
|                 { | ||||
|                     var buffer = result1.Content.SelectMiddle(0, 6).BytesAdd(-0x33); | ||||
|                     return OperResult.CreateSuccessResult(buffer.Reverse().ToArray().ToHexString()); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return new OperResult<string>(result1); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult<string>(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<string>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 修改波特率 | ||||
|     /// </summary> | ||||
|     /// <param name="baudRate"></param> | ||||
|     /// <param name="cancellationToken"></param> | ||||
|     /// <returns></returns> | ||||
|     public async Task<OperResult> WriteBaudRateAsync(int baudRate, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             byte baudRateByte; | ||||
|             switch (baudRate) | ||||
|             { | ||||
|                 case 600: baudRateByte = 0x02; break; | ||||
|                 case 1200: baudRateByte = 0x04; break; | ||||
|                 case 2400: baudRateByte = 0x08; break; | ||||
|                 case 4800: baudRateByte = 0x10; break; | ||||
|                 case 9600: baudRateByte = 0x20; break; | ||||
|                 case 19200: baudRateByte = 0x40; break; | ||||
|                 default: return new OperResult<string>($"不支持此波特率:{baudRate}"); | ||||
|             } | ||||
|             if (Station.IsNullOrEmpty()) Station = string.Empty; | ||||
|             if (Station.Length < 12) Station = Station.PadLeft(12, '0'); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteBaudRate, new byte[] { baudRateByte }, Station.ByHexStringToBytes().Reverse().ToArray()); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken); | ||||
|                 var result1 = ((MessageBase)result.RequestInfo); | ||||
|                 if (result1.IsSuccess) | ||||
|                 { | ||||
|                     return OperResult.CreateSuccessResult(); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return new OperResult(result1); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<string>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 更新通信地址 | ||||
|     /// </summary> | ||||
|     /// <param name="station"></param> | ||||
|     /// <param name="cancellationToken"></param> | ||||
|     /// <returns></returns> | ||||
|     public async Task<OperResult> WriteDeviceStationAsync(string station, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteStation, station.ByHexStringToBytes().Reverse().ToArray(), "AAAAAAAAAAAA".ByHexStringToBytes()); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken); | ||||
|                 var result1 = ((MessageBase)result.RequestInfo); | ||||
|                 if (result1.IsSuccess) | ||||
|                 { | ||||
|                     return OperResult.CreateSuccessResult(); | ||||
|  | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return new OperResult(result1); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<string>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// 修改密码 | ||||
|     /// </summary> | ||||
|     /// <param name="level"></param> | ||||
|     /// <param name="oldPassword"></param> | ||||
|     /// <param name="newPassword"></param> | ||||
|     /// <param name="cancellationToken"></param> | ||||
|     /// <returns></returns> | ||||
|     public async Task<OperResult> WritePasswordAsync(byte level, string oldPassword, string newPassword, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|  | ||||
|             if (Station.IsNullOrEmpty()) Station = string.Empty; | ||||
|             if (Station.Length < 12) Station = Station.PadLeft(12, '0'); | ||||
|             string str = $"04000C{(level + 1):D2}"; | ||||
|  | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WritePassword, | ||||
|                 str.ByHexStringToBytes().Reverse().ToArray() | ||||
|                 .SpliceArray(oldPassword.ByHexStringToBytes().Reverse().ToArray()) | ||||
|                 .SpliceArray(newPassword.ByHexStringToBytes().Reverse().ToArray()) | ||||
|                 , Station.ByHexStringToBytes().Reverse().ToArray()); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken); | ||||
|                 var result1 = ((MessageBase)result.RequestInfo); | ||||
|                 if (result1.IsSuccess) | ||||
|                 { | ||||
|                     return OperResult.CreateSuccessResult(); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return new OperResult(result1); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<string>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|     #endregion | ||||
|  | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.Text; | ||||
| @@ -28,23 +26,23 @@ public class DLT645_2007Address : DeviceAddressBase | ||||
|     /// </summary> | ||||
|     public DLT645_2007Address() | ||||
|     { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 数据标识 | ||||
|     /// </summary> | ||||
|     public byte[] DataId { get; set; } = new byte[0]; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 反转解析 | ||||
|     /// </summary> | ||||
|     public bool Reverse { get; set; } = true; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 站号信息 | ||||
|     /// </summary> | ||||
|     public byte[] Station { get; set; } = new byte[0]; | ||||
| 
 | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 解析地址 | ||||
|     /// </summary> | ||||
| @@ -52,7 +50,7 @@ public class DLT645_2007Address : DeviceAddressBase | ||||
|     /// <returns></returns> | ||||
|     public static DLT645_2007Address ParseFrom(string address) | ||||
|     { | ||||
|         DLT645_2007Address dlt645_2007Address = new(); | ||||
|         DLT645_2007Address dLT645_2007Address = new(); | ||||
|         byte[] array; | ||||
|         array = new byte[0]; | ||||
|         if (address.IndexOf(';') < 0) | ||||
| @@ -61,7 +59,7 @@ public class DLT645_2007Address : DeviceAddressBase | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             string[] strArray = address.SplitStringBySemicolon(); | ||||
|             string[] strArray = address.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); | ||||
| 
 | ||||
|             for (int index = 0; index < strArray.Length; ++index) | ||||
|             { | ||||
| @@ -71,11 +69,11 @@ public class DLT645_2007Address : DeviceAddressBase | ||||
|                     if (station.IsNullOrEmpty()) station = string.Empty; | ||||
|                     if (station.Length < 12) | ||||
|                         station = station.PadLeft(12, '0'); | ||||
|                     dlt645_2007Address.Station = station.ByHexStringToBytes().Reverse().ToArray(); | ||||
|                     dLT645_2007Address.Station = station.ByHexStringToBytes().Reverse().ToArray(); | ||||
|                 } | ||||
|                 else if (strArray[index].Contains("r=")) | ||||
|                 { | ||||
|                     dlt645_2007Address.Reverse = strArray[index].Substring(2).ToBool(false); | ||||
|                     dLT645_2007Address.Reverse = strArray[index].Substring(2).GetBoolValue(); | ||||
|                 } | ||||
|                 else if (!strArray[index].Contains("=")) | ||||
|                 { | ||||
| @@ -83,8 +81,9 @@ public class DLT645_2007Address : DeviceAddressBase | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         dlt645_2007Address.DataId = array; | ||||
|         return dlt645_2007Address; | ||||
|         dLT645_2007Address.DataId = array; | ||||
|         return dLT645_2007Address; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
| @@ -93,16 +92,18 @@ public class DLT645_2007Address : DeviceAddressBase | ||||
|         StringBuilder stringGeter = new(); | ||||
|         if (Station.Length > 0) | ||||
|         { | ||||
|             stringGeter.Append($"s={Station.Reverse().ToArray().ToHexString()};"); | ||||
|             stringGeter.Append("s=" + Station.Reverse().ToArray().ToHexString() + ";"); | ||||
|         } | ||||
|         if (DataId.Length > 0) | ||||
|         { | ||||
|             stringGeter.Append($"{DataId.Reverse().ToArray().ToHexString()};"); | ||||
|             stringGeter.Append(DataId.Reverse().ToArray().ToHexString() + ";"); | ||||
|         } | ||||
|         if (!Reverse) | ||||
|         { | ||||
|             stringGeter.Append($"s={Reverse};"); | ||||
|             stringGeter.Append("s=" + Reverse.ToString() + ";"); | ||||
|         } | ||||
|         return stringGeter.ToString(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.Text; | ||||
| @@ -17,7 +15,6 @@ using System.Text; | ||||
| using ThingsGateway.Foundation.Extension.Generic; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.DLT645; | ||||
| 
 | ||||
| /// <summary> | ||||
| /// DLT645_2007 | ||||
| /// </summary> | ||||
| @@ -30,48 +27,6 @@ public class DLT645_2007BitConverter : ThingsGatewayBitConverter | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override short ToInt16(byte[] buffer, int offset) | ||||
|     { | ||||
|         return Convert.ToInt16(this.ToString(buffer, offset, buffer.Length)); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override ushort ToUInt16(byte[] buffer, int offset) | ||||
|     { | ||||
|         return Convert.ToUInt16(this.ToString(buffer, offset, buffer.Length)); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override float ToSingle(byte[] buffer, int offset) | ||||
|     { | ||||
|         return Convert.ToSingle(this.ToString(buffer, offset, buffer.Length)); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override long ToInt64(byte[] buffer, int offset) | ||||
|     { | ||||
|         return Convert.ToInt64(this.ToString(buffer, offset, buffer.Length)); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override int ToInt32(byte[] buffer, int offset) | ||||
|     { | ||||
|         return Convert.ToInt32(this.ToString(buffer, offset, buffer.Length)); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override uint ToUInt32(byte[] buffer, int offset) | ||||
|     { | ||||
|         return Convert.ToUInt32(this.ToString(buffer, offset, buffer.Length)); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override ulong ToUInt64(byte[] buffer, int offset) | ||||
|     { | ||||
|         return Convert.ToUInt64(this.ToString(buffer, offset, buffer.Length)); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// DLT645协议转换double | ||||
|     /// </summary> | ||||
| @@ -96,6 +51,7 @@ public class DLT645_2007BitConverter : ThingsGatewayBitConverter | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override string ToString(byte[] buffer) | ||||
|     { | ||||
| @@ -156,4 +112,6 @@ public class DLT645_2007BitConverter : ThingsGatewayBitConverter | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.ComponentModel; | ||||
| @@ -21,7 +19,7 @@ namespace ThingsGateway.Foundation.Adapter.DLT645; | ||||
| /// <summary> | ||||
| /// DLT645_2007DataHandleAdapter | ||||
| /// </summary> | ||||
| internal class DLT645_2007DataHandleAdapter : ReadWriteDevicesSingleStreamDataHandleAdapter<DLT645_2007Message> | ||||
| public class DLT645_2007DataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter<DLT645_2007Message> | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 增加FE FE FE FE的报文头部 | ||||
| @@ -46,6 +44,7 @@ internal class DLT645_2007DataHandleAdapter : ReadWriteDevicesSingleStreamDataHa | ||||
|         return new DLT645_2007Message(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     protected override FilterResult UnpackResponse(DLT645_2007Message request, byte[] send, byte[] body, byte[] response) | ||||
|     { | ||||
| @@ -79,6 +78,7 @@ internal class DLT645_2007DataHandleAdapter : ReadWriteDevicesSingleStreamDataHa | ||||
|         if (headCodeIndex < 0 || headCodeIndex + 10 > response.Length) | ||||
|             return FilterResult.Cache; | ||||
| 
 | ||||
| 
 | ||||
|         var len = 10 + response[headCodeIndex + 9] + 2; | ||||
| 
 | ||||
|         if (response.Length - headCodeIndex < len) | ||||
| @@ -87,6 +87,7 @@ internal class DLT645_2007DataHandleAdapter : ReadWriteDevicesSingleStreamDataHa | ||||
|         } | ||||
|         if (response.Length - headCodeIndex >= len && response[len + headCodeIndex - 1] == 0x16) | ||||
|         { | ||||
| 
 | ||||
|             //检查校验码 | ||||
|             int sumCheck = 0; | ||||
|             for (int i = headCodeIndex; i < len + headCodeIndex - 2; i++) | ||||
| @@ -108,6 +109,7 @@ internal class DLT645_2007DataHandleAdapter : ReadWriteDevicesSingleStreamDataHa | ||||
|                 (response[headCodeIndex + 6] != send[sendHeadCodeIndex + 6]) | ||||
|                 )//设备地址不符合时,返回错误 | ||||
|             { | ||||
| 
 | ||||
|                 if ( | ||||
|                 (send[sendHeadCodeIndex + 1] == 0xAA) && | ||||
|                 (send[sendHeadCodeIndex + 2] == 0xAA) && | ||||
| @@ -117,6 +119,7 @@ internal class DLT645_2007DataHandleAdapter : ReadWriteDevicesSingleStreamDataHa | ||||
|                 (send[sendHeadCodeIndex + 6] == 0xAA) | ||||
|                 )//读写通讯地址例外 | ||||
|                 { | ||||
| 
 | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
| @@ -124,20 +127,26 @@ internal class DLT645_2007DataHandleAdapter : ReadWriteDevicesSingleStreamDataHa | ||||
|                     request.ErrorCode = 999; | ||||
|                     return FilterResult.Success; | ||||
|                 } | ||||
| 
 | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|             if ((response[headCodeIndex + 8] != send[sendHeadCodeIndex + 8] + 0x80))//控制码不符合时,返回错误 | ||||
|             { | ||||
|                 request.Message = $"返回控制码:0x{response[headCodeIndex + 8]:X2},请求控制码:0x{send[sendHeadCodeIndex + 8]:X2},不符合规则"; | ||||
|                 request.Message = "返回控制码:" + $"0x{response[headCodeIndex + 8]:X2},请求控制码:" + $"0x{send[sendHeadCodeIndex + 8]:X2},不符合规则"; | ||||
|                 request.ErrorCode = 999; | ||||
|                 return FilterResult.Success; | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|             if ((response[headCodeIndex + 8] & 0x40) == 0x40)//控制码bit6为1时,返回错误 | ||||
|             { | ||||
|                 byte byte1 = (byte)(response[headCodeIndex + 10] - 0x33); | ||||
|                 var error = DLT645Helper.Get2007ErrorMessage(byte1); | ||||
|                 request.Message = $"异常控制码:0x{response[headCodeIndex + 8]:X2},错误信息:{error}"; | ||||
|                 request.Message = "异常控制码:" + $"0x{response[headCodeIndex + 8]:X2},错误信息:{error}"; | ||||
|                 request.ErrorCode = 999; | ||||
|                 return FilterResult.Success; | ||||
|             } | ||||
| @@ -154,6 +163,7 @@ internal class DLT645_2007DataHandleAdapter : ReadWriteDevicesSingleStreamDataHa | ||||
|                 (response[headCodeIndex + 13] == send[sendHeadCodeIndex + 13]) | ||||
|                 ) | ||||
|                 { | ||||
| 
 | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
| @@ -161,16 +171,21 @@ internal class DLT645_2007DataHandleAdapter : ReadWriteDevicesSingleStreamDataHa | ||||
|                     request.ErrorCode = 999; | ||||
|                     return FilterResult.Success; | ||||
|                 } | ||||
| 
 | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|             request.Content = response.RemoveBegin(headCodeIndex + 10).RemoveLast(response.Length + 2 - len - headCodeIndex); | ||||
|             request.ErrorCode = 0; | ||||
|             return FilterResult.Success; | ||||
| 
 | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             request.ErrorCode = 999; | ||||
|             return FilterResult.Success; | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,15 +8,13 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.DLT645; | ||||
| 
 | ||||
| /// <summary> | ||||
| /// <inheritdoc/> | ||||
| /// </summary> | ||||
| internal class DLT645_2007Message : MessageBase, IMessage | ||||
| public class DLT645_2007Message : MessageBase, IMessage | ||||
| { | ||||
|     /// <inheritdoc/> | ||||
|     public override int HeadBytesLength => -1; | ||||
| @@ -28,4 +25,7 @@ internal class DLT645_2007Message : MessageBase, IMessage | ||||
|         BodyLength = -1; | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @@ -0,0 +1,480 @@ | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| using System.ComponentModel; | ||||
|  | ||||
| using ThingsGateway.Foundation.Extension.Generic; | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Adapter.DLT645; | ||||
| /// <summary> | ||||
| /// DLT645_2007 | ||||
| /// </summary> | ||||
| public class DLT645_2007OverTcp : ReadWriteDevicesTcpClientBase | ||||
| { | ||||
|     /// <summary> | ||||
|     /// DLT645_2007 | ||||
|     /// </summary> | ||||
|     /// <param name="tcpClient"></param> | ||||
|     public DLT645_2007OverTcp(TcpClient tcpClient) : base(tcpClient) | ||||
|     { | ||||
|         ThingsGatewayBitConverter = new DLT645_2007BitConverter(EndianType.Big); | ||||
|         RegisterByteLength = 2; | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 增加FE FE FE FE的报文头部 | ||||
|     /// </summary> | ||||
|     [Description("前导符报文头")] | ||||
|     public bool EnableFEHead { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 写入需操作员代码 | ||||
|     /// </summary> | ||||
|     [Description("操作员代码")] | ||||
|     public string OperCode { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 写入密码 | ||||
|     /// </summary> | ||||
|     [Description("写入密码")] | ||||
|     public string Password { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 通讯地址BCD码,一般应该是12个字符 | ||||
|     /// </summary> | ||||
|     [Description("通讯地址")] | ||||
|     public string Station { get; set; } | ||||
|     /// <inheritdoc/> | ||||
|     public override string GetAddressDescription() | ||||
|     { | ||||
|  | ||||
|         var str = """ | ||||
|             查看附带文档或者相关资料,下面列举一下常见的数据标识地址  | ||||
|              | ||||
|             地址                       说明                     | ||||
|             ----------------------------------------- | ||||
|             02010100    A相电压 | ||||
|             02020100    A相电流 | ||||
|             02030000    瞬时总有功功率 | ||||
|             00000000    (当前)组合有功总电能 | ||||
|             00010000    (当前)正向有功总电能 | ||||
|              | ||||
|             """; | ||||
|         return base.GetAddressDescription() + Environment.NewLine + str; | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack) | ||||
|     { | ||||
|         return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Read, Station); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = WaitingClientEx.SendThenResponse(commandResult.Content, TimeOut, cancellationToken); | ||||
|                 return (MessageBase)result.RequestInfo; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult<byte[]>(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<byte[]>(ex); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override async Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Read, Station); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken); | ||||
|                 return (MessageBase)result.RequestInfo; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult<byte[]>(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<byte[]>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public override void SetDataAdapter(object socketClient = null) | ||||
|     { | ||||
|         var dataHandleAdapter = new DLT645_2007DataHandleAdapter | ||||
|         { | ||||
|             EnableFEHead = EnableFEHead | ||||
|         }; | ||||
|         TcpClient.SetDataHandlingAdapter(dataHandleAdapter); | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult Write(string address, string value, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|  | ||||
|         try | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             Password ??= string.Empty; | ||||
|             OperCode ??= string.Empty; | ||||
|             if (Password.Length < 8) | ||||
|                 Password = Password.PadLeft(8, '0'); | ||||
|             if (OperCode.Length < 8) | ||||
|                 OperCode = OperCode.PadLeft(8, '0'); | ||||
|             var data = DataTransUtil.SpliceArray(Password.ByHexStringToBytes(), OperCode.ByHexStringToBytes()); | ||||
|             string[] strArray = value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Write, Station, data, strArray); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = WaitingClientEx.SendThenResponse(commandResult.Content, TimeOut, cancellationToken); | ||||
|                 return (MessageBase)result.RequestInfo; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<byte[]>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult Write(string address, byte[] value, CancellationToken cancellationToken = default) => Write(address, value.ToString(), cancellationToken); | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default) => Write(address, value.ToString(), cancellationToken); | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override async Task<OperResult> WriteAsync(string address, string value, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|  | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             Password ??= string.Empty; | ||||
|             OperCode ??= string.Empty; | ||||
|             if (Password.Length < 8) | ||||
|                 Password = Password.PadLeft(8, '0'); | ||||
|             if (OperCode.Length < 8) | ||||
|                 OperCode = OperCode.PadLeft(8, '0'); | ||||
|             var data = DataTransUtil.SpliceArray(Password.ByHexStringToBytes(), OperCode.ByHexStringToBytes()); | ||||
|             string[] strArray = value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command(address, (byte)ControlCode.Write, Station, data, strArray); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken); | ||||
|                 return (MessageBase)result.RequestInfo; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<byte[]>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, uint value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, double value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, float value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, long value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, ulong value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, ushort value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, short value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, int value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default) => WriteAsync(address, value.ToString(), cancellationToken); | ||||
|  | ||||
|  | ||||
|     #region 其他方法 | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 广播校时 | ||||
|     /// </summary> | ||||
|     /// <param name="dateTime"></param> | ||||
|     /// <param name="cancellationToken"></param> | ||||
|     /// <returns></returns> | ||||
|     public OperResult BroadcastTime(DateTime dateTime, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             string str = $"{dateTime.Second:D2}{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}{dateTime.Year % 100:D2}"; | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.BroadcastTime, str.ByHexStringToBytes().Reverse().ToArray(), "999999999999".ByHexStringToBytes()); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 TcpClient.Send(commandResult.Content); | ||||
|                 return OperResult.CreateSuccessResult(); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<string>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 冻结 | ||||
|     /// </summary> | ||||
|     /// <param name="dateTime"></param> | ||||
|     /// <param name="cancellationToken"></param> | ||||
|     /// <returns></returns> | ||||
|     public async Task<OperResult> FreezeAsync(DateTime dateTime, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             string str = $"{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}"; | ||||
|             if (Station.IsNullOrEmpty()) Station = string.Empty; | ||||
|             if (Station.Length < 12) Station = Station.PadLeft(12, '0'); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.Freeze, str.ByHexStringToBytes().Reverse().ToArray(), Station.ByHexStringToBytes().Reverse().ToArray()); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken); | ||||
|                 var result1 = ((MessageBase)result.RequestInfo); | ||||
|                 if (result1.IsSuccess) | ||||
|                 { | ||||
|                     return OperResult.CreateSuccessResult(); | ||||
|  | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return new OperResult(result1); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<string>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 读取通信地址 | ||||
|     /// </summary> | ||||
|     /// <param name="cancellationToken"></param> | ||||
|     /// <returns></returns> | ||||
|     public async Task<OperResult<string>> ReadDeviceStationAsync(CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.ReadStation, null, "AAAAAAAAAAAA".ByHexStringToBytes()); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken); | ||||
|                 var result1 = ((MessageBase)result.RequestInfo); | ||||
|                 if (result1.IsSuccess) | ||||
|                 { | ||||
|                     var buffer = result1.Content.SelectMiddle(0, 6).BytesAdd(-0x33); | ||||
|                     return OperResult.CreateSuccessResult(buffer.Reverse().ToArray().ToHexString()); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return new OperResult<string>(result1); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult<string>(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<string>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 修改波特率 | ||||
|     /// </summary> | ||||
|     /// <param name="baudRate"></param> | ||||
|     /// <param name="cancellationToken"></param> | ||||
|     /// <returns></returns> | ||||
|     public async Task<OperResult> WriteBaudRateAsync(int baudRate, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             byte baudRateByte; | ||||
|             switch (baudRate) | ||||
|             { | ||||
|                 case 600: baudRateByte = 0x02; break; | ||||
|                 case 1200: baudRateByte = 0x04; break; | ||||
|                 case 2400: baudRateByte = 0x08; break; | ||||
|                 case 4800: baudRateByte = 0x10; break; | ||||
|                 case 9600: baudRateByte = 0x20; break; | ||||
|                 case 19200: baudRateByte = 0x40; break; | ||||
|                 default: return new OperResult<string>($"不支持此波特率:{baudRate}"); | ||||
|             } | ||||
|             if (Station.IsNullOrEmpty()) Station = string.Empty; | ||||
|             if (Station.Length < 12) Station = Station.PadLeft(12, '0'); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteBaudRate, new byte[] { baudRateByte }, Station.ByHexStringToBytes().Reverse().ToArray()); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken); | ||||
|                 var result1 = ((MessageBase)result.RequestInfo); | ||||
|                 if (result1.IsSuccess) | ||||
|                 { | ||||
|                     return OperResult.CreateSuccessResult(); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return new OperResult(result1); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<string>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 更新通信地址 | ||||
|     /// </summary> | ||||
|     /// <param name="station"></param> | ||||
|     /// <param name="cancellationToken"></param> | ||||
|     /// <returns></returns> | ||||
|     public async Task<OperResult> WriteDeviceStationAsync(string station, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteStation, station.ByHexStringToBytes().Reverse().ToArray(), "AAAAAAAAAAAA".ByHexStringToBytes()); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken); | ||||
|                 var result1 = ((MessageBase)result.RequestInfo); | ||||
|                 if (result1.IsSuccess) | ||||
|                 { | ||||
|                     return OperResult.CreateSuccessResult(); | ||||
|  | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return new OperResult(result1); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<string>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// 修改密码 | ||||
|     /// </summary> | ||||
|     /// <param name="level"></param> | ||||
|     /// <param name="oldPassword"></param> | ||||
|     /// <param name="newPassword"></param> | ||||
|     /// <param name="cancellationToken"></param> | ||||
|     /// <returns></returns> | ||||
|     public async Task<OperResult> WritePasswordAsync(byte level, string oldPassword, string newPassword, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|  | ||||
|             if (Station.IsNullOrEmpty()) Station = string.Empty; | ||||
|             if (Station.Length < 12) Station = Station.PadLeft(12, '0'); | ||||
|             string str = $"04000C{level:D2}"; | ||||
|  | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WritePassword, | ||||
|                 str.ByHexStringToBytes().Reverse().ToArray() | ||||
|                 .SpliceArray(oldPassword.ByHexStringToBytes().Reverse().ToArray()) | ||||
|                 .SpliceArray(newPassword.ByHexStringToBytes().Reverse().ToArray()) | ||||
|                 , Station.ByHexStringToBytes().Reverse().ToArray()); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, cancellationToken); | ||||
|                 var result1 = ((MessageBase)result.RequestInfo); | ||||
|                 if (result1.IsSuccess) | ||||
|                 { | ||||
|                     return OperResult.CreateSuccessResult(); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return new OperResult(result1); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<string>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|     #endregion | ||||
|  | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,43 +8,36 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.DLT645; | ||||
| 
 | ||||
| internal static class PackHelper | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 打包变量,添加到<see href="deviceVariableSourceReads"></see> | ||||
|     /// </summary> | ||||
|     /// <param name="device"></param> | ||||
|     /// <param name="deviceVariables"></param> | ||||
|     /// <param name="maxPack">最大打包长度</param> | ||||
|     /// <param name="defaultIntervalTime">默认间隔时间</param> | ||||
|     /// <returns></returns> | ||||
|     public static List<T> LoadSourceRead<T, T2>(IReadWrite device, List<T2> deviceVariables, int maxPack, int defaultIntervalTime) where T : IDeviceVariableSourceRead<IDeviceVariableRunTime>, new() where T2 : IDeviceVariableRunTime, new() | ||||
|     public static List<T> LoadSourceRead<T, T2>(IReadWrite device, List<T2> deviceVariables, int maxPack) where T : IDeviceVariableSourceRead<IDeviceVariableRunTime>, new() where T2 : IDeviceVariableRunTime, new() | ||||
|     { | ||||
|         var byteConverter = device.ThingsGatewayBitConverter; | ||||
|         var result = new List<T>(); | ||||
|         //需要先剔除额外信息,比如dataformat等 | ||||
|         foreach (var item in deviceVariables) | ||||
|         { | ||||
|             var address = item.Address; | ||||
|             var address = item.VariableAddress; | ||||
| 
 | ||||
|             IThingsGatewayBitConverter transformParameter = ByteTransformUtil.GetTransByAddress(ref address, byteConverter); | ||||
|             item.ThingsGatewayBitConverter = transformParameter; | ||||
|             //item.Address = address; | ||||
|             item.Index = device.GetBitOffset(item.Address); | ||||
|             //item.VariableAddress = address; | ||||
|             item.Index = device.GetBitOffset(item.VariableAddress); | ||||
| 
 | ||||
|             result.Add(new() | ||||
|             { | ||||
|                 DeviceVariableRunTimes = new() { item }, | ||||
|                 Address = address, | ||||
|                 VariableAddress = address, | ||||
|                 Length = 1, | ||||
|                 IntervalTimeTick = new(item.IntervalTime ?? defaultIntervalTime) | ||||
|             }); | ||||
|         } | ||||
|         return result; | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| global using System; | ||||
| @@ -19,5 +17,5 @@ global using System.Threading; | ||||
| global using System.Threading.Tasks; | ||||
| 
 | ||||
| global using ThingsGateway.Foundation.Core; | ||||
| global using ThingsGateway.Foundation.SerialPorts; | ||||
| global using ThingsGateway.Foundation.Sockets; | ||||
| global using ThingsGateway.Foundation.Serial; | ||||
| global using ThingsGateway.Foundation.Sockets; | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| global using System; | ||||
| @@ -19,5 +17,5 @@ global using System.Threading; | ||||
| global using System.Threading.Tasks; | ||||
| 
 | ||||
| global using ThingsGateway.Foundation.Core; | ||||
| global using ThingsGateway.Foundation.SerialPorts; | ||||
| global using ThingsGateway.Foundation.Sockets; | ||||
| global using ThingsGateway.Foundation.Serial; | ||||
| global using ThingsGateway.Foundation.Sockets; | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,11 +8,11 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.Text; | ||||
| 
 | ||||
| using ThingsGateway.Foundation.Extension; | ||||
| using ThingsGateway.Foundation.Extension.String; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| @@ -28,13 +27,12 @@ public class ModbusAddress : DeviceAddressBase | ||||
|     /// </summary> | ||||
|     public ModbusAddress() | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// 读取功能码 | ||||
|     /// </summary> | ||||
|     public ushort AddressStart => Address.ToUShort(); | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 读取功能码 | ||||
|     /// </summary> | ||||
| @@ -49,16 +47,14 @@ public class ModbusAddress : DeviceAddressBase | ||||
|     /// 写入功能码 | ||||
|     /// </summary> | ||||
|     public byte WriteFunction { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 打包临时写入,需要读取的字节长度 | ||||
|     /// </summary> | ||||
|     public int ByteLength { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// BitIndex | ||||
|     /// </summary> | ||||
|     public int BitIndex => (int)(Address.SplitStringByDelimiter().LastOrDefault().ToInt()); | ||||
|     public int BitIndex => (int)(Address.SplitDot().LastOrDefault().ToInt()); | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 读取功能码 | ||||
| @@ -69,7 +65,6 @@ public class ModbusAddress : DeviceAddressBase | ||||
|     /// 作为Slave时需提供的SocketId,用于分辨Socket客户端,通常对比的是初始链接时的注册包 | ||||
|     /// </summary> | ||||
|     public string SocketId { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 解析地址 | ||||
|     /// </summary> | ||||
| @@ -81,7 +76,6 @@ public class ModbusAddress : DeviceAddressBase | ||||
|         }; | ||||
|         return ParseFrom(address, modbusAddress); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 解析地址 | ||||
|     /// </summary> | ||||
| @@ -94,7 +88,7 @@ public class ModbusAddress : DeviceAddressBase | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             string[] strArray = address.SplitStringBySemicolon(); | ||||
|             string[] strArray = address.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); | ||||
|             for (int index = 0; index < strArray.Length; ++index) | ||||
|             { | ||||
|                 if (strArray[index].ToUpper().StartsWith("S=")) | ||||
| @@ -130,38 +124,38 @@ public class ModbusAddress : DeviceAddressBase | ||||
|                 case 0: | ||||
|                     modbusAddress.ReadFunction = 1; | ||||
|                     break; | ||||
| 
 | ||||
|                 case 1: | ||||
|                     modbusAddress.ReadFunction = 2; | ||||
|                     break; | ||||
| 
 | ||||
|                 case 3: | ||||
|                     modbusAddress.ReadFunction = 4; | ||||
|                     break; | ||||
| 
 | ||||
|                 case 4: | ||||
|                     modbusAddress.ReadFunction = 3; | ||||
|                     break; | ||||
|             } | ||||
|             modbusAddress.Address = (double.Parse(address.Substring(1)) - 1).ToString(); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override string ToString() | ||||
|     { | ||||
|         StringBuilder stringGeter = new(); | ||||
|         if (Station > 0) | ||||
|         { | ||||
|             stringGeter.Append($"s={Station.ToString()};"); | ||||
|             stringGeter.Append("s=" + Station.ToString() + ";"); | ||||
|         } | ||||
|         if (WriteFunction > 0) | ||||
|         { | ||||
|             stringGeter.Append($"w={WriteFunction.ToString()};"); | ||||
|             stringGeter.Append("w=" + WriteFunction.ToString() + ";"); | ||||
|         } | ||||
|         if (!string.IsNullOrEmpty(SocketId)) | ||||
|         { | ||||
|             stringGeter.Append($"id={SocketId};"); | ||||
|             stringGeter.Append("id=" + SocketId + ";"); | ||||
|         } | ||||
|         stringGeter.Append(GetFunctionString(ReadFunction) + (AddressStart + 1).ToString()); | ||||
|         return stringGeter.ToString(); | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.Text; | ||||
| @@ -26,7 +24,7 @@ internal class ModbusHelper | ||||
|     /// </summary> | ||||
|     internal static byte[] AddCrc(byte[] command) | ||||
|     { | ||||
|         return CRC16Utils.CRC16(command); | ||||
|         return EasyCRC16.CRC16(command); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
| @@ -62,7 +60,6 @@ internal class ModbusHelper | ||||
|         stringBuilder.AppendLine("写入功能码 ,比如40001;w=16; ,代表保持寄存器第一个寄存器,写入值时采用0x10功能码,而不是默认的0x06功能码"); | ||||
|         return stringBuilder.ToString(); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 通过错误码来获取到对应的文本消息 | ||||
|     /// </summary> | ||||
| @@ -91,6 +88,7 @@ internal class ModbusHelper | ||||
|             if (response.Length < 3) | ||||
|                 return new OperResult<byte[], FilterResult>("数据长度不足" + response.ToHexString()) { Content2 = FilterResult.Cache }; | ||||
| 
 | ||||
| 
 | ||||
|             if (response[1] >= 0x80)//错误码 | ||||
|                 return new OperResult<byte[], FilterResult>(GetDescriptionByErrorCode(response[2])) { Content2 = FilterResult.Success }; | ||||
|             if (response[1] <= 0x05) | ||||
| @@ -102,6 +100,7 @@ internal class ModbusHelper | ||||
|             { | ||||
|                 if ((response.Length < 6)) | ||||
|                     return new OperResult<byte[], FilterResult>("数据长度不足" + response.ToHexString()) { Content2 = FilterResult.Cache }; | ||||
| 
 | ||||
|             } | ||||
| 
 | ||||
|             if (send.Length == 0) | ||||
| @@ -118,10 +117,9 @@ internal class ModbusHelper | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<byte[], FilterResult>(ex) { Content2 = FilterResult.Success }; | ||||
|             return new OperResult<byte[], FilterResult>(ex.Message) { Content2 = FilterResult.Success }; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 去除Crc,返回modbus数据区 | ||||
|     /// </summary> | ||||
| @@ -136,23 +134,25 @@ internal class ModbusHelper | ||||
| 
 | ||||
|         if (response[1] >= 0x80)//错误码 | ||||
|             return new OperResult<byte[], FilterResult>(GetDescriptionByErrorCode(response[2])) { Content2 = FilterResult.Success }; | ||||
|         if (response[1] <= 0x04) | ||||
|         if (response[1] <= 0x05) | ||||
|         { | ||||
|             if ((response.Length < response[2] + 5)) | ||||
|                 return new OperResult<byte[], FilterResult>("数据长度不足" + response.ToHexString()) { Content2 = FilterResult.Cache }; | ||||
| 
 | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             if ((response.Length < 8)) | ||||
|                 return new OperResult<byte[], FilterResult>("数据长度不足" + response.ToHexString()) { Content2 = FilterResult.Cache }; | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         var data = response.SelectMiddle(0, response[1] <= 0x04 ? response[2] != 0 ? response[2] + 5 : 8 : 8); | ||||
|         if (crcCheck && !CRC16Utils.CheckCRC16(data)) | ||||
| 
 | ||||
|         var data = response.SelectMiddle(0, response[2] != 0 ? response[2] + 5 : 8); | ||||
|         if (crcCheck && !EasyCRC16.CheckCRC16(data)) | ||||
|             return new OperResult<byte[], FilterResult>("Crc校验失败" + DataTransUtil.ByteToHexString(data, ' ')) { Content2 = FilterResult.Success }; | ||||
|         return GetModbusData(send, data.RemoveLast(2)); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 获取读取报文 | ||||
|     /// </summary> | ||||
| @@ -165,10 +165,9 @@ internal class ModbusHelper | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<byte[]>(ex); | ||||
|             return new OperResult<byte[]>(ex.Message); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 获取写入布尔量报文,根据地址识别功能码 | ||||
|     /// </summary> | ||||
| @@ -186,7 +185,7 @@ internal class ModbusHelper | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<byte[]>(ex); | ||||
|             return new OperResult<byte[]>(ex.Message); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @@ -204,13 +203,13 @@ internal class ModbusHelper | ||||
|                 return OperResult.CreateSuccessResult(GetWriteModbusCommand(mAddress, value)); | ||||
|             else | ||||
|                 return OperResult.CreateSuccessResult(GetWriteOneModbusCommand(mAddress, value)); | ||||
| 
 | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<byte[]>(ex); | ||||
|             return new OperResult<byte[]>(ex.Message); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 获取读取报文 | ||||
|     /// </summary> | ||||
| @@ -245,7 +244,7 @@ internal class ModbusHelper | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<byte[]>(ex); | ||||
|             return new OperResult<byte[]>(ex.Message); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @@ -297,7 +296,7 @@ internal class ModbusHelper | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<byte[]>(ex); | ||||
|             return new OperResult<byte[]>(ex.Message); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @@ -331,4 +330,5 @@ internal class ModbusHelper | ||||
|         values.CopyTo(numArray, 4); | ||||
|         return numArray; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,23 +8,22 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.ComponentModel; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| 
 | ||||
| /// <summary> | ||||
| /// ModbusRtu | ||||
| /// </summary> | ||||
| public class ModbusRtu : ReadWriteDevicesSerialPortClientBase | ||||
| public class ModbusRtu : ReadWriteDevicesSerialSessionBase | ||||
| { | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// ModbusRtu | ||||
|     /// </summary> | ||||
|     /// <param name="serialPortClient"></param> | ||||
|     public ModbusRtu(SerialPortClient serialPortClient) : base(serialPortClient) | ||||
|     /// <param name="serialSession"></param> | ||||
|     public ModbusRtu(SerialSession serialSession) : base(serialSession) | ||||
|     { | ||||
|         ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big); | ||||
|         RegisterByteLength = 2; | ||||
| @@ -43,26 +41,30 @@ public class ModbusRtu : ReadWriteDevicesSerialPortClientBase | ||||
|     [Description("站号")] | ||||
|     public byte Station { get; set; } = 1; | ||||
| 
 | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override string GetAddressDescription() | ||||
|     { | ||||
|         return $"{base.GetAddressDescription()}{Environment.NewLine}{ModbusHelper.GetAddressDescription()}"; | ||||
|         return base.GetAddressDescription() + Environment.NewLine + ModbusHelper.GetAddressDescription(); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack, int defaultIntervalTime) | ||||
|     public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack) | ||||
|     { | ||||
|         return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack, defaultIntervalTime); | ||||
|         return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
| 
 | ||||
|             return ModbusHelper.GetReadModbusCommand(address, length, Station).Then(a => SendThenReturn<ModbusRtuMessage>(a, cancellationToken)); | ||||
|             var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station); | ||||
|             return SendThenReturn(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -77,8 +79,7 @@ public class ModbusRtu : ReadWriteDevicesSerialPortClientBase | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return await SendThenReturnAsync<ModbusRtuMessage>(commandResult.Content, cancellationToken); | ||||
|             return await SendThenReturnAsync(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -87,14 +88,14 @@ public class ModbusRtu : ReadWriteDevicesSerialPortClientBase | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override void SetDataAdapter(ISocketClient socketClient = default) | ||||
|     public override void SetDataAdapter(object socketClient = null) | ||||
|     { | ||||
|         ModbusRtuDataHandleAdapter dataHandleAdapter = new() | ||||
|         { | ||||
|             Crc16CheckEnable = Crc16CheckEnable, | ||||
|             CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout) | ||||
|         }; | ||||
|         SerialPortClient.SetDataHandlingAdapter(dataHandleAdapter); | ||||
|         SerialSession.SetDataHandlingAdapter(dataHandleAdapter); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
| @@ -104,8 +105,7 @@ public class ModbusRtu : ReadWriteDevicesSerialPortClientBase | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return SendThenReturn<ModbusRtuMessage>(commandResult.Content, cancellationToken); | ||||
|             return SendThenReturn(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -120,8 +120,7 @@ public class ModbusRtu : ReadWriteDevicesSerialPortClientBase | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return SendThenReturn<ModbusRtuMessage>(commandResult.Content, cancellationToken); | ||||
|             return SendThenReturn(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -136,8 +135,7 @@ public class ModbusRtu : ReadWriteDevicesSerialPortClientBase | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return await SendThenReturnAsync<ModbusRtuMessage>(commandResult.Content, cancellationToken); | ||||
|             return await SendThenReturnAsync(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -152,12 +150,42 @@ public class ModbusRtu : ReadWriteDevicesSerialPortClientBase | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return await SendThenReturnAsync<ModbusRtuMessage>(commandResult.Content, cancellationToken); | ||||
|             return await SendThenReturnAsync(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult(ex); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|     private OperResult<byte[]> SendThenReturn(OperResult<byte[]> commandResult, CancellationToken cancellationToken) | ||||
|     { | ||||
|         if (commandResult.IsSuccess) | ||||
|         { | ||||
|             var item = commandResult.Content; | ||||
|             if (FrameTime != 0) | ||||
|                 Thread.Sleep(FrameTime); | ||||
|             var result = WaitingClientEx.SendThenResponse(item, TimeOut, cancellationToken); | ||||
|             return (MessageBase)result.RequestInfo; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return new OperResult<byte[]>(commandResult.Message); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private async Task<OperResult<byte[]>> SendThenReturnAsync(OperResult<byte[]> commandResult, CancellationToken cancellationToken) | ||||
|     { | ||||
|         if (commandResult.IsSuccess) | ||||
|         { | ||||
|             var item = commandResult.Content; | ||||
|             await Task.Delay(FrameTime, cancellationToken); | ||||
|             var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, cancellationToken); | ||||
|             return (MessageBase)result.RequestInfo; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return new OperResult<byte[]>(commandResult.Message); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using ThingsGateway.Foundation.Extension.Generic; | ||||
| @@ -19,13 +17,12 @@ namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| /// <summary> | ||||
| /// Rtu适配器 | ||||
| /// </summary> | ||||
| internal class ModbusRtuDataHandleAdapter : ReadWriteDevicesSingleStreamDataHandleAdapter<ModbusRtuMessage> | ||||
| public class ModbusRtuDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter<ModbusRtuMessage> | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 检测CRC | ||||
|     /// </summary> | ||||
|     public bool Crc16CheckEnable { get; set; } = true; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
| @@ -42,6 +39,7 @@ internal class ModbusRtuDataHandleAdapter : ReadWriteDevicesSingleStreamDataHand | ||||
|         return new ModbusRtuMessage(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     protected override FilterResult UnpackResponse(ModbusRtuMessage request, byte[] send, byte[] body, byte[] response) | ||||
|     { | ||||
| @@ -82,4 +80,6 @@ internal class ModbusRtuDataHandleAdapter : ReadWriteDevicesSingleStreamDataHand | ||||
|             return FilterResult.Success; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,15 +8,13 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| 
 | ||||
| /// <summary> | ||||
| /// <inheritdoc/> | ||||
| /// </summary> | ||||
| internal class ModbusRtuMessage : MessageBase, IMessage | ||||
| public class ModbusRtuMessage : MessageBase, IMessage | ||||
| { | ||||
|     /// <inheritdoc/> | ||||
|     public override int HeadBytesLength => -1; | ||||
| @@ -28,4 +25,7 @@ internal class ModbusRtuMessage : MessageBase, IMessage | ||||
|         BodyLength = -1; | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,16 +8,17 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.ComponentModel; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| /// <inheritdoc/> | ||||
| public class ModbusRtuOverTcp : ReadWriteDevicesTcpClientBase | ||||
| { | ||||
| 
 | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public ModbusRtuOverTcp(TcpClient tcpClient) : base(tcpClient) | ||||
|     { | ||||
| @@ -37,13 +37,13 @@ public class ModbusRtuOverTcp : ReadWriteDevicesTcpClientBase | ||||
|     /// </summary> | ||||
|     [Description("站号")] | ||||
|     public byte Station { get; set; } = 1; | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override string GetAddressDescription() | ||||
|     { | ||||
|         return $"{base.GetAddressDescription()}{Environment.NewLine}{ModbusHelper.GetAddressDescription()}"; | ||||
|         return base.GetAddressDescription() + Environment.NewLine + ModbusHelper.GetAddressDescription(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default) | ||||
|     { | ||||
| @@ -51,8 +51,7 @@ public class ModbusRtuOverTcp : ReadWriteDevicesTcpClientBase | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return SendThenReturn<ModbusRtuMessage>(commandResult.Content, cancellationToken); | ||||
|             return SendThenReturn(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -67,8 +66,7 @@ public class ModbusRtuOverTcp : ReadWriteDevicesTcpClientBase | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return await SendThenReturnAsync<ModbusRtuMessage>(commandResult.Content, cancellationToken); | ||||
|             return await SendThenReturnAsync(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -77,13 +75,14 @@ public class ModbusRtuOverTcp : ReadWriteDevicesTcpClientBase | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack, int defaultIntervalTime) | ||||
|     public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack) | ||||
|     { | ||||
|         return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack, defaultIntervalTime); | ||||
|         return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override void SetDataAdapter(ISocketClient socketClient = default) | ||||
|     public override void SetDataAdapter(object socketClient = null) | ||||
|     { | ||||
|         ModbusRtuDataHandleAdapter dataHandleAdapter = new() | ||||
|         { | ||||
| @@ -100,8 +99,7 @@ public class ModbusRtuOverTcp : ReadWriteDevicesTcpClientBase | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return SendThenReturn<ModbusRtuMessage>(commandResult.Content, cancellationToken); | ||||
|             return SendThenReturn(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -116,8 +114,7 @@ public class ModbusRtuOverTcp : ReadWriteDevicesTcpClientBase | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return SendThenReturn<ModbusRtuMessage>(commandResult.Content, cancellationToken); | ||||
|             return SendThenReturn(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -132,8 +129,7 @@ public class ModbusRtuOverTcp : ReadWriteDevicesTcpClientBase | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return await SendThenReturnAsync<ModbusRtuMessage>(commandResult.Content, cancellationToken); | ||||
|             return await SendThenReturnAsync(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -148,12 +144,42 @@ public class ModbusRtuOverTcp : ReadWriteDevicesTcpClientBase | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return await SendThenReturnAsync<ModbusRtuMessage>(commandResult.Content, cancellationToken); | ||||
|             return await SendThenReturnAsync(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult(ex); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|     private OperResult<byte[]> SendThenReturn(OperResult<byte[]> commandResult, CancellationToken cancellationToken) | ||||
|     { | ||||
|         if (commandResult.IsSuccess) | ||||
|         { | ||||
|             var item = commandResult.Content; | ||||
|             if (FrameTime != 0) | ||||
|                 Thread.Sleep(FrameTime); | ||||
|             var result = WaitingClientEx.SendThenResponse(item, TimeOut, cancellationToken); | ||||
|             return (MessageBase)result.RequestInfo; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return new OperResult<byte[]>(commandResult.Message); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private async Task<OperResult<byte[]>> SendThenReturnAsync(OperResult<byte[]> commandResult, CancellationToken cancellationToken) | ||||
|     { | ||||
|         if (commandResult.IsSuccess) | ||||
|         { | ||||
|             var item = commandResult.Content; | ||||
|             await Task.Delay(FrameTime, cancellationToken); | ||||
|             var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, cancellationToken); | ||||
|             return (MessageBase)result.RequestInfo; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return new OperResult<byte[]>(commandResult.Message); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.ComponentModel; | ||||
| @@ -37,13 +35,11 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase | ||||
|     /// </summary> | ||||
|     [Description("站号")] | ||||
|     public byte Station { get; set; } = 1; | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override string GetAddressDescription() | ||||
|     { | ||||
|         return $"{base.GetAddressDescription()}{Environment.NewLine}{ModbusHelper.GetAddressDescription()}"; | ||||
|         return base.GetAddressDescription() + Environment.NewLine + ModbusHelper.GetAddressDescription(); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default) | ||||
|     { | ||||
| @@ -51,8 +47,7 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return SendThenReturn<ModbusRtuMessage>(commandResult.Content, cancellationToken); | ||||
|             return SendThenReturn(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -67,8 +62,7 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return await SendThenReturnAsync<ModbusRtuMessage>(commandResult.Content, cancellationToken); | ||||
|             return await SendThenReturnAsync(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -77,7 +71,7 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override void SetDataAdapter(ISocketClient socketClient = default) | ||||
|     public override void SetDataAdapter(object socketClient = null) | ||||
|     { | ||||
|         ModbusRtuOverUdpDataHandleAdapter dataHandleAdapter = new() | ||||
|         { | ||||
| @@ -91,9 +85,10 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack, int defaultIntervalTime) | ||||
|     public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack) | ||||
|     { | ||||
|         return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack, defaultIntervalTime); | ||||
|         return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
| @@ -103,8 +98,7 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return SendThenReturn<ModbusRtuMessage>(commandResult.Content, cancellationToken); | ||||
|             return SendThenReturn(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -119,8 +113,7 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return SendThenReturn<ModbusRtuMessage>(commandResult.Content, cancellationToken); | ||||
|             return SendThenReturn(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -135,8 +128,7 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return await SendThenReturnAsync<ModbusRtuMessage>(commandResult.Content, cancellationToken); | ||||
|             return await SendThenReturnAsync(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -151,12 +143,42 @@ public class ModbusRtuOverUdp : ReadWriteDevicesUdpSessionBase | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return await SendThenReturnAsync<ModbusRtuMessage>(commandResult.Content, cancellationToken); | ||||
|             return await SendThenReturnAsync(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult(ex); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|     private OperResult<byte[]> SendThenReturn(OperResult<byte[]> commandResult, CancellationToken cancellationToken) | ||||
|     { | ||||
|         if (commandResult.IsSuccess) | ||||
|         { | ||||
|             var item = commandResult.Content; | ||||
|             if (FrameTime != 0) | ||||
|                 Thread.Sleep(FrameTime); | ||||
|             var result = WaitingClientEx.SendThenResponse(item, TimeOut, cancellationToken); | ||||
|             return (MessageBase)result.RequestInfo; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return new OperResult<byte[]>(commandResult.Message); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private async Task<OperResult<byte[]>> SendThenReturnAsync(OperResult<byte[]> commandResult, CancellationToken cancellationToken) | ||||
|     { | ||||
|         if (commandResult.IsSuccess) | ||||
|         { | ||||
|             var item = commandResult.Content; | ||||
|             await Task.Delay(FrameTime, cancellationToken); | ||||
|             var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, cancellationToken); | ||||
|             return (MessageBase)result.RequestInfo; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return new OperResult<byte[]>(commandResult.Message); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| @@ -17,7 +15,7 @@ namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| /// <summary> | ||||
| /// <inheritdoc/> | ||||
| /// </summary> | ||||
| internal class ModbusRtuOverUdpDataHandleAdapter : ReadWriteDevicesUdpDataHandleAdapter<ModbusRtuMessage> | ||||
| public class ModbusRtuOverUdpDataHandleAdapter : ReadWriteDevicesUdpDataHandleAdapter<ModbusRtuMessage> | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 检测CRC | ||||
| @@ -42,4 +40,4 @@ internal class ModbusRtuOverUdpDataHandleAdapter : ReadWriteDevicesUdpDataHandle | ||||
|         var result = ModbusHelper.GetModbusRtuData(send, response, Crc16CheckEnable); | ||||
|         return result; | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -0,0 +1,421 @@ | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| using System.Collections.Concurrent; | ||||
|  | ||||
| using ThingsGateway.Foundation.Extension.Bool; | ||||
| using ThingsGateway.Foundation.Extension.Generic; | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| /// <summary> | ||||
| /// <inheritdoc/> | ||||
| /// </summary> | ||||
| public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端 | ||||
|     /// </summary> | ||||
|     public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, SerialSession, Task<OperResult>> WriteData; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 继电器 | ||||
|     /// </summary> | ||||
|     private ConcurrentDictionary<byte, ByteBlock> ModbusServer01ByteBlocks = new(); | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 开关输入 | ||||
|     /// </summary> | ||||
|     private ConcurrentDictionary<byte, ByteBlock> ModbusServer02ByteBlocks = new(); | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 输入寄存器 | ||||
|     /// </summary> | ||||
|     private ConcurrentDictionary<byte, ByteBlock> ModbusServer03ByteBlocks = new(); | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 保持寄存器 | ||||
|     /// </summary> | ||||
|     private ConcurrentDictionary<byte, ByteBlock> ModbusServer04ByteBlocks = new(); | ||||
|     /// <inheritdoc/> | ||||
|     public ModbusSerialServer(SerialSession serialSession) : base(serialSession) | ||||
|     { | ||||
|         ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big); | ||||
|         RegisterByteLength = 2; | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 多站点 | ||||
|     /// </summary> | ||||
|     public bool MulStation { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 默认站点 | ||||
|     /// </summary> | ||||
|     public byte Station { get; set; } = 1; | ||||
|  | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override void Dispose() | ||||
|     { | ||||
|         foreach (var item in ModbusServer01ByteBlocks) | ||||
|         { | ||||
|             item.Value.SafeDispose(); | ||||
|         } | ||||
|         foreach (var item in ModbusServer02ByteBlocks) | ||||
|         { | ||||
|             item.Value.SafeDispose(); | ||||
|         } | ||||
|         foreach (var item in ModbusServer03ByteBlocks) | ||||
|         { | ||||
|             item.Value.SafeDispose(); | ||||
|         } | ||||
|         foreach (var item in ModbusServer04ByteBlocks) | ||||
|         { | ||||
|             item.Value.SafeDispose(); | ||||
|         } | ||||
|         ModbusServer01ByteBlocks.Clear(); | ||||
|         ModbusServer02ByteBlocks.Clear(); | ||||
|         ModbusServer03ByteBlocks.Clear(); | ||||
|         ModbusServer04ByteBlocks.Clear(); | ||||
|         base.Dispose(); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override string GetAddressDescription() | ||||
|     { | ||||
|         return base.GetAddressDescription() + Environment.NewLine + ModbusHelper.GetAddressDescription(); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack) | ||||
|     { | ||||
|         return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack); | ||||
|  | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         ModbusAddress mAddress; | ||||
|         try | ||||
|         { | ||||
|             mAddress = ModbusAddress.ParseFrom(address, Station); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<byte[]>(ex); | ||||
|         } | ||||
|         if (MulStation) | ||||
|         { | ||||
|             Init(mAddress); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             if (Station != mAddress.Station) | ||||
|             { | ||||
|                 return new OperResult<byte[]>("地址错误"); | ||||
|             } | ||||
|             Init(mAddress); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station]; | ||||
|         var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station]; | ||||
|         var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station]; | ||||
|         var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station]; | ||||
|         int len = mAddress.ReadFunction == 2 || mAddress.ReadFunction == 1 ? length : length * RegisterByteLength; | ||||
|         switch (mAddress.ReadFunction) | ||||
|         { | ||||
|             case 1: | ||||
|                 byte[] bytes0 = new byte[len]; | ||||
|                 ModbusServer01ByteBlock.Pos = mAddress.AddressStart; | ||||
|                 ModbusServer01ByteBlock.Read(bytes0); | ||||
|                 return OperResult.CreateSuccessResult(bytes0); | ||||
|             case 2: | ||||
|                 byte[] bytes1 = new byte[len]; | ||||
|                 ModbusServer02ByteBlock.Pos = mAddress.AddressStart; | ||||
|                 ModbusServer02ByteBlock.Read(bytes1); | ||||
|                 return OperResult.CreateSuccessResult(bytes1); | ||||
|             case 3: | ||||
|  | ||||
|                 byte[] bytes3 = new byte[len]; | ||||
|                 ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength; | ||||
|                 ModbusServer03ByteBlock.Read(bytes3); | ||||
|                 return OperResult.CreateSuccessResult(bytes3); | ||||
|             case 4: | ||||
|                 byte[] bytes4 = new byte[len]; | ||||
|                 ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength; | ||||
|                 ModbusServer04ByteBlock.Read(bytes4); | ||||
|                 return OperResult.CreateSuccessResult(bytes4); | ||||
|         } | ||||
|         return new OperResult<byte[]>("功能码错误"); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         return Task.FromResult(Read(address, length)); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override void SetDataAdapter(object socketClient) | ||||
|     { | ||||
|         ModbusSerialServerDataHandleAdapter dataHandleAdapter = new(); | ||||
|         dataHandleAdapter.CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout); | ||||
|         SerialSession.SetDataHandlingAdapter(dataHandleAdapter); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult Write(string address, byte[] value, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         ModbusAddress mAddress; | ||||
|         try | ||||
|         { | ||||
|             mAddress = ModbusAddress.ParseFrom(address, Station); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult(ex); | ||||
|         } | ||||
|         if (MulStation) | ||||
|         { | ||||
|             Init(mAddress); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             if (Station != mAddress.Station) | ||||
|             { | ||||
|                 return new OperResult("地址错误"); | ||||
|             } | ||||
|             Init(mAddress); | ||||
|         } | ||||
|         var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station]; | ||||
|         var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station]; | ||||
|         switch (mAddress.ReadFunction) | ||||
|         { | ||||
|             case 3: | ||||
|                 ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength; | ||||
|                 ModbusServer03ByteBlock.Write(value); | ||||
|                 return OperResult.CreateSuccessResult(); | ||||
|             case 4: | ||||
|                 ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength; | ||||
|                 ModbusServer04ByteBlock.Write(value); | ||||
|                 return OperResult.CreateSuccessResult(); | ||||
|         } | ||||
|         return new OperResult("功能码错误"); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         ModbusAddress mAddress; | ||||
|         try | ||||
|         { | ||||
|             mAddress = ModbusAddress.ParseFrom(address, Station); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return (new OperResult(ex)); | ||||
|         } | ||||
|         if (MulStation) | ||||
|         { | ||||
|             Init(mAddress); | ||||
|  | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             if (Station != mAddress.Station) | ||||
|             { | ||||
|                 return (new OperResult("地址错误")); | ||||
|             } | ||||
|             Init(mAddress); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station]; | ||||
|         var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station]; | ||||
|         switch (mAddress.ReadFunction) | ||||
|         { | ||||
|             case 1: | ||||
|                 ModbusServer01ByteBlock.Pos = mAddress.AddressStart; | ||||
|                 ModbusServer01ByteBlock.Write(value.BoolArrayToByte()); | ||||
|                 return (OperResult.CreateSuccessResult()); | ||||
|             case 2: | ||||
|                 ModbusServer02ByteBlock.Pos = mAddress.AddressStart; | ||||
|                 ModbusServer02ByteBlock.Write(value.BoolArrayToByte()); | ||||
|                 return (OperResult.CreateSuccessResult()); | ||||
|         } | ||||
|         return new OperResult("功能码错误"); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         return Task.FromResult(Write(address, value)); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         return Task.FromResult(Write(address, value)); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     protected override async Task Received(SerialSession client, ReceivedDataEventArgs e) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             var requestInfo = e.RequestInfo; | ||||
|             //接收外部报文 | ||||
|             if (requestInfo is ModbusSerialServerMessage modbusServerMessage) | ||||
|             { | ||||
|                 if (modbusServerMessage.CurModbusAddress == null) | ||||
|                 { | ||||
|                     return;//无法解析直接返回 | ||||
|                 } | ||||
|                 if (!modbusServerMessage.IsSuccess) | ||||
|                 { | ||||
|                     return;//无法解析直接返回 | ||||
|                 } | ||||
|  | ||||
|                 if (modbusServerMessage.CurModbusAddress.WriteFunction == 0)//读取 | ||||
|                 { | ||||
|                     var data = Read(modbusServerMessage.CurModbusAddress.ToString(), modbusServerMessage.Length); | ||||
|                     if (data.IsSuccess) | ||||
|                     { | ||||
|                         var coreData = data.Content; | ||||
|                         if (modbusServerMessage.CurModbusAddress.ReadFunction == 1 || modbusServerMessage.CurModbusAddress.ReadFunction == 2) | ||||
|                         { | ||||
|                             coreData = data.Content.Select(m => m > 0).ToArray().BoolArrayToByte().SelectMiddle(0, (int)Math.Ceiling(modbusServerMessage.Length / 8.0)); | ||||
|                         } | ||||
|                         var sendData = modbusServerMessage.ReceivedBytes.SelectMiddle(0, 2).SpliceArray(new byte[] { (byte)coreData.Length }, coreData); | ||||
|                         SerialSession.Send(sendData); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         WriteError(SerialSession, modbusServerMessage);//返回错误码 | ||||
|                     } | ||||
|                 } | ||||
|                 else//写入 | ||||
|                 { | ||||
|                     var coreData = modbusServerMessage.Content; | ||||
|                     if (modbusServerMessage.CurModbusAddress.ReadFunction == 1 || modbusServerMessage.CurModbusAddress.ReadFunction == 2) | ||||
|                     { | ||||
|                         //写入继电器 | ||||
|                         if (WriteData != null) | ||||
|                         { | ||||
|                             // 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端 | ||||
|                             if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, SerialSession)).IsSuccess) | ||||
|                             { | ||||
|                                 var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData.ByteToBoolArray(modbusServerMessage.Length)); | ||||
|                                 if (result.IsSuccess) | ||||
|                                 { | ||||
|                                     WriteSuccess03(SerialSession, modbusServerMessage); | ||||
|                                 } | ||||
|                                 else | ||||
|                                 { | ||||
|                                     WriteError(SerialSession, modbusServerMessage); | ||||
|                                 } | ||||
|                             } | ||||
|                             else | ||||
|                             { | ||||
|                                 WriteError(SerialSession, modbusServerMessage); | ||||
|                             } | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             //写入内存区 | ||||
|                             var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData.ByteToBoolArray(modbusServerMessage.Length)); | ||||
|                             if (result.IsSuccess) | ||||
|                             { | ||||
|                                 WriteSuccess03(SerialSession, modbusServerMessage); | ||||
|                             } | ||||
|                             else | ||||
|                             { | ||||
|                                 WriteError(SerialSession, modbusServerMessage); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         //写入寄存器 | ||||
|                         if (WriteData != null) | ||||
|                         { | ||||
|  | ||||
|                             if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, SerialSession)).IsSuccess) | ||||
|                             { | ||||
|                                 var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData); | ||||
|                                 if (result.IsSuccess) | ||||
|                                 { | ||||
|                                     WriteSuccess03(SerialSession, modbusServerMessage); | ||||
|                                 } | ||||
|                                 else | ||||
|                                 { | ||||
|                                     WriteError(SerialSession, modbusServerMessage); | ||||
|                                 } | ||||
|                             } | ||||
|                             else | ||||
|                             { | ||||
|                                 WriteError(SerialSession, modbusServerMessage); | ||||
|                             } | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData); | ||||
|                             if (result.IsSuccess) | ||||
|                             { | ||||
|                                 WriteSuccess03(SerialSession, modbusServerMessage); | ||||
|  | ||||
|                             } | ||||
|                             else | ||||
|                             { | ||||
|                                 WriteError(SerialSession, modbusServerMessage); | ||||
|  | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             Logger.LogError(ex, ToString()); | ||||
|         } | ||||
|         //返回错误码 | ||||
|         static void WriteError(SerialSession SerialSession, ModbusSerialServerMessage modbusServerMessage) | ||||
|         { | ||||
|             var sendData = modbusServerMessage.ReceivedBytes.SelectMiddle(0, 2) | ||||
| .SpliceArray(new byte[] { (byte)1 });//01 lllegal function | ||||
|             sendData[1] = (byte)(sendData[1] + 128); | ||||
|             SerialSession.Send(sendData); | ||||
|  | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static void WriteSuccess03(SerialSession SerialSession, ModbusSerialServerMessage modbusServerMessage) | ||||
|     { | ||||
|         var sendData = modbusServerMessage.ReceivedBytes.SelectMiddle(0, 6); | ||||
|         SerialSession.Send(sendData); | ||||
|     } | ||||
|  | ||||
|     private void Init(ModbusAddress mAddress) | ||||
|     { | ||||
|         if (ModbusServer01ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128))) | ||||
|             ModbusServer01ByteBlocks[mAddress.Station].SetLength(1024 * 128); | ||||
|         if (ModbusServer02ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128))) | ||||
|             ModbusServer02ByteBlocks[mAddress.Station].SetLength(1024 * 128); | ||||
|         if (ModbusServer03ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128))) | ||||
|             ModbusServer03ByteBlocks[mAddress.Station].SetLength(1024 * 128); | ||||
|         if (ModbusServer04ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128))) | ||||
|             ModbusServer04ByteBlocks[mAddress.Station].SetLength(1024 * 128); | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using ThingsGateway.Foundation.Extension.Generic; | ||||
| @@ -17,7 +15,7 @@ using ThingsGateway.Foundation.Extension.Generic; | ||||
| namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| 
 | ||||
| /// <inheritdoc/> | ||||
| internal class ModbusSerialServerDataHandleAdapter : ReadWriteDevicesSingleStreamDataHandleAdapter<ModbusSerialServerMessage> | ||||
| public class ModbusSerialServerDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter<ModbusSerialServerMessage> | ||||
| { | ||||
|     private readonly ThingsGatewayBitConverter ThingsGatewayBitConverter = new(EndianType.Big); | ||||
| 
 | ||||
| @@ -36,7 +34,7 @@ internal class ModbusSerialServerDataHandleAdapter : ReadWriteDevicesSingleStrea | ||||
|     /// </summary> | ||||
|     /// <param name="response">返回数据</param> | ||||
|     /// <returns></returns> | ||||
|     internal OperResult<byte[], FilterResult> GetModbusData(byte[] response) | ||||
|     internal OperResult<byte[]> GetModbusData(byte[] response) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
| @@ -44,30 +42,22 @@ internal class ModbusSerialServerDataHandleAdapter : ReadWriteDevicesSingleStrea | ||||
|             if (func == 1 || func == 2 || func == 3 || func == 4 || func == 5 || func == 6) | ||||
|             { | ||||
|                 if (response.Length == 6) | ||||
|                     return OperResult.CreateSuccessResult(response, FilterResult.Success); | ||||
|                     return OperResult.CreateSuccessResult(response); | ||||
|             } | ||||
|             else if (func == 15 || func == 16) | ||||
|             { | ||||
|                 var length = ThingsGatewayBitConverter.ToByte(response, 6); | ||||
|                 if (response.Length == 7 + length) | ||||
|                 { | ||||
|                     return OperResult.CreateSuccessResult(response, FilterResult.Success); | ||||
|                 } | ||||
|                 if (response.Length > 7 + length) | ||||
|                 { | ||||
|                     return new() { Content2 = FilterResult.Success, Message = $"数据长度{response.Length}错误" }; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return new() { Content2 = FilterResult.Cache, Message = $"数据长度{response.Length}错误" }; | ||||
|                     return OperResult.CreateSuccessResult(response); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return new() { Content2 = FilterResult.Success, Message = $"数据长度{response.Length}错误" }; | ||||
|             return new OperResult<byte[]>() { Message = $"数据长度{response.Length}错误" }; | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new(ex) { Content2 = FilterResult.Success }; | ||||
|             return new OperResult<byte[]>(ex.Message); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @@ -98,7 +88,7 @@ internal class ModbusSerialServerDataHandleAdapter : ReadWriteDevicesSingleStrea | ||||
|                 { | ||||
|                     if (function > 6) | ||||
|                     { | ||||
|                         request.ModbusAddress = new ModbusAddress() | ||||
|                         request.CurModbusAddress = new ModbusAddress() | ||||
|                         { | ||||
|                             Station = station, | ||||
|                             Address = addressStart.ToString(), | ||||
| @@ -110,7 +100,7 @@ internal class ModbusSerialServerDataHandleAdapter : ReadWriteDevicesSingleStrea | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         request.ModbusAddress = new ModbusAddress() | ||||
|                         request.CurModbusAddress = new ModbusAddress() | ||||
|                         { | ||||
|                             Station = station, | ||||
|                             Address = addressStart.ToString(), | ||||
| @@ -123,7 +113,7 @@ internal class ModbusSerialServerDataHandleAdapter : ReadWriteDevicesSingleStrea | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     request.ModbusAddress = new ModbusAddress() | ||||
|                     request.CurModbusAddress = new ModbusAddress() | ||||
|                     { | ||||
|                         Station = station, | ||||
|                         Address = addressStart.ToString(), | ||||
| @@ -139,12 +129,13 @@ internal class ModbusSerialServerDataHandleAdapter : ReadWriteDevicesSingleStrea | ||||
|             { | ||||
|                 request.ErrorCode = result.ErrorCode; | ||||
|                 request.Message = result.Message; | ||||
|                 return result.Content2; | ||||
|                 return FilterResult.Cache; | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return result1.Content2; | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| @@ -17,12 +15,15 @@ namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| /// <summary> | ||||
| /// <inheritdoc/> | ||||
| /// </summary> | ||||
| internal class ModbusSerialServerMessage : MessageBase, IMessage, IModbusServerMessage | ||||
| public class ModbusSerialServerMessage : MessageBase, IMessage | ||||
| { | ||||
|     /// <inheritdoc/> | ||||
|     public ModbusAddress ModbusAddress { get; set; } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     /// <summary> | ||||
|     /// 当前关联的地址 | ||||
|     /// </summary> | ||||
|     public ModbusAddress CurModbusAddress { get; set; } | ||||
|     /// <summary> | ||||
|     /// 当前读写的数据长度 | ||||
|     /// </summary> | ||||
|     public int Length { get; set; } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
| @@ -34,4 +35,6 @@ internal class ModbusSerialServerMessage : MessageBase, IMessage, IModbusServerM | ||||
|         BodyLength = -1; | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,29 +8,26 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.ComponentModel; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| 
 | ||||
| /// <inheritdoc/> | ||||
| public class ModbusTcp : ReadWriteDevicesTcpClientBase | ||||
| { | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public ModbusTcp(TcpClient tcpClient) : base(tcpClient) | ||||
|     { | ||||
|         ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big); | ||||
|         RegisterByteLength = 2; | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 检测事务标识符 | ||||
|     /// </summary> | ||||
|     [Description("检测事务标识符")] | ||||
|     public bool IsCheckMessageId { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 站号 | ||||
|     /// </summary> | ||||
| @@ -41,13 +37,13 @@ public class ModbusTcp : ReadWriteDevicesTcpClientBase | ||||
|     /// <inheritdoc/> | ||||
|     public override string GetAddressDescription() | ||||
|     { | ||||
|         return $"{base.GetAddressDescription()}{Environment.NewLine}{ModbusHelper.GetAddressDescription()}"; | ||||
|         return base.GetAddressDescription() + Environment.NewLine + ModbusHelper.GetAddressDescription(); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack, int defaultIntervalTime) | ||||
|     public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack) | ||||
|     { | ||||
|         return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack, defaultIntervalTime); | ||||
|         return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
| @@ -57,8 +53,8 @@ public class ModbusTcp : ReadWriteDevicesTcpClientBase | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return SendThenReturn<ModbusTcpMessage>(commandResult.Content, cancellationToken); | ||||
|             var data = SendThenReturn(commandResult, cancellationToken); | ||||
|             return data; | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -74,8 +70,8 @@ public class ModbusTcp : ReadWriteDevicesTcpClientBase | ||||
|             await ConnectAsync(cancellationToken); | ||||
| 
 | ||||
|             var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return await SendThenReturnAsync<ModbusTcpMessage>(commandResult.Content, cancellationToken); | ||||
|             var data = await SendThenReturnAsync(commandResult, cancellationToken); | ||||
|             return data; | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -83,8 +79,9 @@ public class ModbusTcp : ReadWriteDevicesTcpClientBase | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override void SetDataAdapter(ISocketClient socketClient = default) | ||||
|     public override void SetDataAdapter(object socketClient = null) | ||||
|     { | ||||
|         ModbusTcpDataHandleAdapter dataHandleAdapter = new() | ||||
|         { | ||||
| @@ -101,8 +98,7 @@ public class ModbusTcp : ReadWriteDevicesTcpClientBase | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return SendThenReturn<ModbusTcpMessage>(commandResult.Content, cancellationToken); | ||||
|             return SendThenReturn(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -117,8 +113,7 @@ public class ModbusTcp : ReadWriteDevicesTcpClientBase | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return SendThenReturn<ModbusTcpMessage>(commandResult.Content, cancellationToken); | ||||
|             return SendThenReturn(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -133,8 +128,7 @@ public class ModbusTcp : ReadWriteDevicesTcpClientBase | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return await SendThenReturnAsync<ModbusTcpMessage>(commandResult.Content, cancellationToken); | ||||
|             return await SendThenReturnAsync(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -149,12 +143,42 @@ public class ModbusTcp : ReadWriteDevicesTcpClientBase | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return await SendThenReturnAsync<ModbusTcpMessage>(commandResult.Content, cancellationToken); | ||||
|             return await SendThenReturnAsync(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult(ex); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|     private OperResult<byte[]> SendThenReturn(OperResult<byte[]> commandResult, CancellationToken cancellationToken) | ||||
|     { | ||||
|         if (commandResult.IsSuccess) | ||||
|         { | ||||
|             var item = commandResult.Content; | ||||
|             if (FrameTime != 0) | ||||
|                 Thread.Sleep(FrameTime); | ||||
|             var result = WaitingClientEx.SendThenResponse(item, TimeOut, cancellationToken); | ||||
|             return (MessageBase)result.RequestInfo; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return new OperResult<byte[]>(commandResult.Message); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private async Task<OperResult<byte[]>> SendThenReturnAsync(OperResult<byte[]> commandResult, CancellationToken cancellationToken) | ||||
|     { | ||||
|         if (commandResult.IsSuccess) | ||||
|         { | ||||
|             var item = commandResult.Content; | ||||
|             await Task.Delay(FrameTime, cancellationToken); | ||||
|             var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, cancellationToken); | ||||
|             return (MessageBase)result.RequestInfo; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return new OperResult<byte[]>(commandResult.Message); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using ThingsGateway.Foundation.Extension.Generic; | ||||
| @@ -19,9 +17,9 @@ namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| /// <summary> | ||||
| /// ModbusTcpDataHandleAdapter | ||||
| /// </summary> | ||||
| internal class ModbusTcpDataHandleAdapter : ReadWriteDevicesSingleStreamDataHandleAdapter<ModbusTcpMessage> | ||||
| public class ModbusTcpDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter<ModbusTcpMessage> | ||||
| { | ||||
|     private readonly IncrementCount _incrementCount = new(ushort.MaxValue); | ||||
|     private readonly EasyIncrementCount easyIncrementCount = new(ushort.MaxValue); | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 检测事务标识符 | ||||
| @@ -41,7 +39,7 @@ internal class ModbusTcpDataHandleAdapter : ReadWriteDevicesSingleStreamDataHand | ||||
|     /// <inheritdoc/> | ||||
|     public override byte[] PackCommand(byte[] command) | ||||
|     { | ||||
|         return ModbusHelper.AddModbusTcpHead(command, (ushort)_incrementCount.GetCurrentValue()); | ||||
|         return ModbusHelper.AddModbusTcpHead(command, (ushort)easyIncrementCount.GetCurrentValue()); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
| @@ -67,5 +65,6 @@ internal class ModbusTcpDataHandleAdapter : ReadWriteDevicesSingleStreamDataHand | ||||
|             request.Message = result.Message; | ||||
|         } | ||||
|         return result.Content2; | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,24 +8,20 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| 
 | ||||
| /// <summary> | ||||
| /// <inheritdoc/> | ||||
| /// </summary> | ||||
| internal class ModbusTcpMessage : MessageBase, IMessage | ||||
| public class ModbusTcpMessage : MessageBase, IMessage | ||||
| { | ||||
|     /// <inheritdoc/> | ||||
|     public override int HeadBytesLength => 6; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 检测事务标识符 | ||||
|     /// </summary> | ||||
|     public bool IsCheckMessageId { get; set; } = false; | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override bool CheckHeadBytes(byte[] heads) | ||||
|     { | ||||
| @@ -34,7 +29,6 @@ internal class ModbusTcpMessage : MessageBase, IMessage | ||||
|         HeadBytes = heads; | ||||
| 
 | ||||
|         int num = (HeadBytes[4] * 256) + HeadBytes[5]; | ||||
|         if (num > 0xff + 3) return false; | ||||
|         BodyLength = num; | ||||
| 
 | ||||
|         if (!IsCheckMessageId) | ||||
| @@ -42,4 +36,6 @@ internal class ModbusTcpMessage : MessageBase, IMessage | ||||
|         else | ||||
|             return SendBytes[0] == HeadBytes[0] && SendBytes[1] == HeadBytes[1] && HeadBytes[2] == 0 && HeadBytes[3] == 0; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,22 +8,20 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.ComponentModel; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| 
 | ||||
| /// <inheritdoc/> | ||||
| public class ModbusDtu : ReadWriteDevicesTcpServerBase | ||||
| public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase | ||||
| { | ||||
|     /// <inheritdoc/> | ||||
|     public ModbusDtu(TcpService tcpService) : base(tcpService) | ||||
|     public ModbusTcpDtu(TcpService tcpService) : base(tcpService) | ||||
|     { | ||||
|         ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big); | ||||
|         RegisterByteLength = 2; | ||||
|         ModbusDtuPlugin modbusTcpSalvePlugin = new ModbusDtuPlugin(); | ||||
|         ModbusTcpDtuPlugin modbusTcpSalvePlugin = new ModbusTcpDtuPlugin(); | ||||
|         tcpService.Config.ConfigurePlugins(a => | ||||
|          { | ||||
|              a.Add(modbusTcpSalvePlugin); | ||||
| @@ -38,18 +35,6 @@ public class ModbusDtu : ReadWriteDevicesTcpServerBase | ||||
|     [Description("检测事务标识符")] | ||||
|     public bool IsCheckMessageId { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 是否Rtu格式 | ||||
|     /// </summary> | ||||
|     [Description("是否Rtu格式")] | ||||
|     public bool IsRtu { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// Crc校验 | ||||
|     /// </summary> | ||||
|     [Description("Crc校验")] | ||||
|     public bool Crc16CheckEnable { get; set; } = true; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 站号 | ||||
|     /// </summary> | ||||
| @@ -59,13 +44,13 @@ public class ModbusDtu : ReadWriteDevicesTcpServerBase | ||||
|     /// <inheritdoc/> | ||||
|     public override string GetAddressDescription() | ||||
|     { | ||||
|         return $"{base.GetAddressDescription()}{Environment.NewLine}{ModbusHelper.GetAddressDescription()}"; | ||||
|         return base.GetAddressDescription() + Environment.NewLine + ModbusHelper.GetAddressDescription(); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack, int defaultIntervalTime) | ||||
|     public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack) | ||||
|     { | ||||
|         return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack, defaultIntervalTime); | ||||
|         return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
| @@ -76,8 +61,7 @@ public class ModbusDtu : ReadWriteDevicesTcpServerBase | ||||
|             Connect(cancellationToken); | ||||
|             var mAddress = ModbusAddress.ParseFrom(address, Station); | ||||
|             var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return SendThenReturn(mAddress.SocketId, commandResult.Content, cancellationToken); | ||||
|             return SendThenReturn(mAddress.SocketId, commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -93,8 +77,7 @@ public class ModbusDtu : ReadWriteDevicesTcpServerBase | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var mAddress = ModbusAddress.ParseFrom(address, Station); | ||||
|             var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return await SendThenReturnAsync(mAddress.SocketId, commandResult.Content, cancellationToken); | ||||
|             return await SendThenReturnAsync(mAddress.SocketId, commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -103,53 +86,27 @@ public class ModbusDtu : ReadWriteDevicesTcpServerBase | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override void SetDataAdapter(ISocketClient socketClient = default) | ||||
|     public override void SetDataAdapter(object socketClient = null) | ||||
|     { | ||||
|         if (socketClient != default) | ||||
|         if (socketClient is SocketClient client) | ||||
|         { | ||||
|             if (!IsRtu) | ||||
|             ModbusTcpDataHandleAdapter dataHandleAdapter = new() | ||||
|             { | ||||
|                 IsCheckMessageId = IsCheckMessageId, | ||||
|                 CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout) | ||||
|             }; | ||||
|             client.SetDataHandlingAdapter(dataHandleAdapter); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             foreach (var item in TcpService.GetClients()) | ||||
|             { | ||||
|                 ModbusTcpDataHandleAdapter dataHandleAdapter = new() | ||||
|                 { | ||||
|                     IsCheckMessageId = IsCheckMessageId, | ||||
|                     CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout) | ||||
|                 }; | ||||
|                 socketClient.SetDataHandlingAdapter(dataHandleAdapter); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 ModbusRtuDataHandleAdapter dataHandleAdapter = new() | ||||
|                 { | ||||
|                     Crc16CheckEnable = Crc16CheckEnable, | ||||
|                     CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout) | ||||
|                 }; | ||||
|                 socketClient.SetDataHandlingAdapter(dataHandleAdapter); | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             //只适配第一个 | ||||
|             var item = TcpService.GetClients().FirstOrDefault(); | ||||
|             if (item != null) | ||||
|             { | ||||
|                 if (!IsRtu) | ||||
|                 { | ||||
|                     ModbusTcpDataHandleAdapter dataHandleAdapter = new() | ||||
|                     { | ||||
|                         IsCheckMessageId = IsCheckMessageId, | ||||
|                         CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout) | ||||
|                     }; | ||||
|                     item.SetDataHandlingAdapter(dataHandleAdapter); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     ModbusRtuDataHandleAdapter dataHandleAdapter = new() | ||||
|                     { | ||||
|                         Crc16CheckEnable = Crc16CheckEnable, | ||||
|                         CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout) | ||||
|                     }; | ||||
|                     item.SetDataHandlingAdapter(dataHandleAdapter); | ||||
|                 } | ||||
|                 item.SetDataHandlingAdapter(dataHandleAdapter); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -162,8 +119,7 @@ public class ModbusDtu : ReadWriteDevicesTcpServerBase | ||||
|             Connect(cancellationToken); | ||||
|             var mAddress = ModbusAddress.ParseFrom(address, Station); | ||||
|             var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return SendThenReturn(mAddress.SocketId, commandResult.Content, cancellationToken); | ||||
|             return SendThenReturn(mAddress.SocketId, commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -179,8 +135,7 @@ public class ModbusDtu : ReadWriteDevicesTcpServerBase | ||||
|             Connect(cancellationToken); | ||||
|             var mAddress = ModbusAddress.ParseFrom(address, Station); | ||||
|             var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return SendThenReturn(mAddress.SocketId, commandResult.Content, cancellationToken); | ||||
|             return SendThenReturn(mAddress.SocketId, commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -196,8 +151,7 @@ public class ModbusDtu : ReadWriteDevicesTcpServerBase | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var mAddress = ModbusAddress.ParseFrom(address, Station); | ||||
|             var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return await SendThenReturnAsync(mAddress.SocketId, commandResult.Content, cancellationToken); | ||||
|             return await SendThenReturnAsync(mAddress.SocketId, commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -213,8 +167,7 @@ public class ModbusDtu : ReadWriteDevicesTcpServerBase | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var mAddress = ModbusAddress.ParseFrom(address, Station); | ||||
|             var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return await SendThenReturnAsync(mAddress.SocketId, commandResult.Content, cancellationToken); | ||||
|             return await SendThenReturnAsync(mAddress.SocketId, commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -222,41 +175,64 @@ public class ModbusDtu : ReadWriteDevicesTcpServerBase | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private OperResult<byte[]> SendThenReturn(string id, byte[] command, CancellationToken cancellationToken) | ||||
|     private OperResult<byte[]> SendThenReturn(string id, OperResult<byte[]> commandResult, CancellationToken cancellationToken) | ||||
|     { | ||||
|         if (TcpService.TryGetSocketClient($"ID={id}", out var client)) | ||||
|         if (commandResult.IsSuccess) | ||||
|         { | ||||
|             SetDataAdapter(client); | ||||
|             return SendThenReturn<MessageBase>(command, cancellationToken, client); | ||||
|             if (TcpService.TryGetSocketClient($"ID={id}", out var client)) | ||||
|             { | ||||
|                 SetDataAdapter(client); | ||||
| 
 | ||||
|                 var item = commandResult.Content; | ||||
|                 if (FrameTime != 0) | ||||
|                     Thread.Sleep(FrameTime); | ||||
|                 var WaitingClientEx = client.GetWaitingClient(new() { ThrowBreakException = true }); | ||||
|                 var result = WaitingClientEx.SendThenResponse(item, TimeOut, cancellationToken); | ||||
|                 return (MessageBase)result.RequestInfo; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult<byte[]>("客户端未连接"); | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return new OperResult<byte[]>("客户端未连接"); | ||||
|             return commandResult; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private async Task<OperResult<byte[]>> SendThenReturnAsync(string id, byte[] command, CancellationToken cancellationToken) | ||||
|     private async Task<OperResult<byte[]>> SendThenReturnAsync(string id, OperResult<byte[]> commandResult, CancellationToken cancellationToken) | ||||
|     { | ||||
|         if (TcpService.TryGetSocketClient($"ID={id}", out var client)) | ||||
|         if (commandResult.IsSuccess) | ||||
|         { | ||||
|             SetDataAdapter(client); | ||||
|             return await SendThenReturnAsync<MessageBase>(command, cancellationToken, client); | ||||
|         } | ||||
|         else if (TcpService.SocketClients.Count == 1) | ||||
|         { | ||||
|             var client1 = TcpService.SocketClients.GetClients().FirstOrDefault(); | ||||
|             if (client1 != null) | ||||
|             if (TcpService.TryGetSocketClient($"ID={id}", out var client)) | ||||
|             { | ||||
|                 SetDataAdapter(client1); | ||||
|                 return await SendThenReturnAsync<MessageBase>(command, cancellationToken, client1); | ||||
|                 SetDataAdapter(client); | ||||
| 
 | ||||
|                 var item = commandResult.Content; | ||||
|                 await Task.Delay(FrameTime, cancellationToken); | ||||
|                 var WaitingClientEx = client.GetWaitingClient(new() { ThrowBreakException = true }); | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, cancellationToken); | ||||
|                 return (MessageBase)result.RequestInfo; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return new OperResult<byte[]>("客户端未连接"); | ||||
|             } | ||||
|         } | ||||
|         return new OperResult<byte[]>("客户端未连接"); | ||||
|         else | ||||
|         { | ||||
|             return commandResult; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     internal class ModbusDtuPlugin : PluginBase, ITcpReceivingPlugin | ||||
|     internal class ModbusTcpDtuPlugin : PluginBase, ITcpReceivingPlugin | ||||
|     { | ||||
|         public async Task OnTcpReceiving(ITcpClientBase client, ByteBlockEventArgs e) | ||||
|         public Task OnTcpReceiving(ITcpClientBase client, ByteBlockEventArgs e) | ||||
|         { | ||||
|             if (client is ISocketClient socket) | ||||
|             { | ||||
| @@ -267,7 +243,7 @@ public class ModbusDtu : ReadWriteDevicesTcpServerBase | ||||
|                     socket.ResetId(id); | ||||
|                 } | ||||
|             } | ||||
|             await e.InvokeNext();//如果本插件无法处理当前数据,请将数据转至下一个插件。 | ||||
|             return e.InvokeNext();//如果本插件无法处理当前数据,请将数据转至下一个插件。 | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -0,0 +1,441 @@ | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| using System.Collections.Concurrent; | ||||
| using System.ComponentModel; | ||||
|  | ||||
| using ThingsGateway.Foundation.Extension.Bool; | ||||
| using ThingsGateway.Foundation.Extension.Generic; | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| /// <summary> | ||||
| /// <inheritdoc/> | ||||
| /// </summary> | ||||
| public class ModbusTcpServer : ReadWriteDevicesTcpServerBase | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端 | ||||
|     /// </summary> | ||||
|     public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, SocketClient, Task<OperResult>> WriteData; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 继电器 | ||||
|     /// </summary> | ||||
|     private ConcurrentDictionary<byte, ByteBlock> ModbusServer01ByteBlocks = new(); | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 开关输入 | ||||
|     /// </summary> | ||||
|     private ConcurrentDictionary<byte, ByteBlock> ModbusServer02ByteBlocks = new(); | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 输入寄存器 | ||||
|     /// </summary> | ||||
|     private ConcurrentDictionary<byte, ByteBlock> ModbusServer03ByteBlocks = new(); | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 保持寄存器 | ||||
|     /// </summary> | ||||
|     private ConcurrentDictionary<byte, ByteBlock> ModbusServer04ByteBlocks = new(); | ||||
|     /// <inheritdoc/> | ||||
|     public ModbusTcpServer(TcpService tcpService) : base(tcpService) | ||||
|     { | ||||
|         ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big); | ||||
|         RegisterByteLength = 2; | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 多站点 | ||||
|     /// </summary> | ||||
|     [Description("多站点")] | ||||
|     public bool MulStation { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 默认站点 | ||||
|     /// </summary> | ||||
|     [Description("默认站点")] | ||||
|     public byte Station { get; set; } = 1; | ||||
|  | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override void Dispose() | ||||
|     { | ||||
|         foreach (var item in ModbusServer01ByteBlocks) | ||||
|         { | ||||
|             item.Value.SafeDispose(); | ||||
|         } | ||||
|         foreach (var item in ModbusServer02ByteBlocks) | ||||
|         { | ||||
|             item.Value.SafeDispose(); | ||||
|         } | ||||
|         foreach (var item in ModbusServer03ByteBlocks) | ||||
|         { | ||||
|             item.Value.SafeDispose(); | ||||
|         } | ||||
|         foreach (var item in ModbusServer04ByteBlocks) | ||||
|         { | ||||
|             item.Value.SafeDispose(); | ||||
|         } | ||||
|         ModbusServer01ByteBlocks.Clear(); | ||||
|         ModbusServer02ByteBlocks.Clear(); | ||||
|         ModbusServer03ByteBlocks.Clear(); | ||||
|         ModbusServer04ByteBlocks.Clear(); | ||||
|         base.Dispose(); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override string GetAddressDescription() | ||||
|     { | ||||
|         return base.GetAddressDescription() + Environment.NewLine + ModbusHelper.GetAddressDescription(); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack) | ||||
|     { | ||||
|         return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack); | ||||
|  | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         ModbusAddress mAddress; | ||||
|         try | ||||
|         { | ||||
|             mAddress = ModbusAddress.ParseFrom(address, Station); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<byte[]>(ex); | ||||
|         } | ||||
|         if (MulStation) | ||||
|         { | ||||
|             Init(mAddress); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             if (Station != mAddress.Station) | ||||
|             { | ||||
|                 return new OperResult<byte[]>("地址错误"); | ||||
|             } | ||||
|             Init(mAddress); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station]; | ||||
|         var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station]; | ||||
|         var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station]; | ||||
|         var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station]; | ||||
|         int len = mAddress.ReadFunction == 2 || mAddress.ReadFunction == 1 ? length : length * RegisterByteLength; | ||||
|         switch (mAddress.ReadFunction) | ||||
|         { | ||||
|             case 1: | ||||
|                 byte[] bytes0 = new byte[len]; | ||||
|                 ModbusServer01ByteBlock.Pos = mAddress.AddressStart; | ||||
|                 ModbusServer01ByteBlock.Read(bytes0); | ||||
|                 return OperResult.CreateSuccessResult(bytes0); | ||||
|             case 2: | ||||
|                 byte[] bytes1 = new byte[len]; | ||||
|                 ModbusServer02ByteBlock.Pos = mAddress.AddressStart; | ||||
|                 ModbusServer02ByteBlock.Read(bytes1); | ||||
|                 return OperResult.CreateSuccessResult(bytes1); | ||||
|             case 3: | ||||
|  | ||||
|                 byte[] bytes3 = new byte[len]; | ||||
|                 ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength; | ||||
|                 ModbusServer03ByteBlock.Read(bytes3); | ||||
|                 return OperResult.CreateSuccessResult(bytes3); | ||||
|             case 4: | ||||
|                 byte[] bytes4 = new byte[len]; | ||||
|                 ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength; | ||||
|                 ModbusServer04ByteBlock.Read(bytes4); | ||||
|                 return OperResult.CreateSuccessResult(bytes4); | ||||
|         } | ||||
|         return new OperResult<byte[]>("功能码错误"); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         return Task.FromResult(Read(address, length)); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override void SetDataAdapter(object socketClient) | ||||
|     { | ||||
|         if (socketClient is SocketClient client) | ||||
|         { | ||||
|             ModbusTcpServerDataHandleAdapter dataHandleAdapter = new(); | ||||
|             dataHandleAdapter.CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout); | ||||
|             client.SetDataHandlingAdapter(dataHandleAdapter); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             foreach (var item in TcpService.GetClients()) | ||||
|             { | ||||
|                 ModbusTcpDataHandleAdapter dataHandleAdapter = new() | ||||
|                 { | ||||
|                     CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout) | ||||
|                 }; | ||||
|                 item.SetDataHandlingAdapter(dataHandleAdapter); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult Write(string address, byte[] value, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         ModbusAddress mAddress; | ||||
|         try | ||||
|         { | ||||
|             mAddress = ModbusAddress.ParseFrom(address, Station); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult(ex); | ||||
|         } | ||||
|         if (MulStation) | ||||
|         { | ||||
|             Init(mAddress); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             if (Station != mAddress.Station) | ||||
|             { | ||||
|                 return new OperResult("地址错误"); | ||||
|             } | ||||
|             Init(mAddress); | ||||
|         } | ||||
|         var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station]; | ||||
|         var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station]; | ||||
|         switch (mAddress.ReadFunction) | ||||
|         { | ||||
|             case 3: | ||||
|                 ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength; | ||||
|                 ModbusServer03ByteBlock.Write(value); | ||||
|                 return OperResult.CreateSuccessResult(); | ||||
|             case 4: | ||||
|                 ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength; | ||||
|                 ModbusServer04ByteBlock.Write(value); | ||||
|                 return OperResult.CreateSuccessResult(); | ||||
|         } | ||||
|         return new OperResult("功能码错误"); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         ModbusAddress mAddress; | ||||
|         try | ||||
|         { | ||||
|             mAddress = ModbusAddress.ParseFrom(address, Station); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return (new OperResult(ex)); | ||||
|         } | ||||
|         if (MulStation) | ||||
|         { | ||||
|             Init(mAddress); | ||||
|  | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             if (Station != mAddress.Station) | ||||
|             { | ||||
|                 return (new OperResult("地址错误")); | ||||
|             } | ||||
|             Init(mAddress); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station]; | ||||
|         var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station]; | ||||
|         switch (mAddress.ReadFunction) | ||||
|         { | ||||
|             case 1: | ||||
|                 ModbusServer01ByteBlock.Pos = mAddress.AddressStart; | ||||
|                 ModbusServer01ByteBlock.Write(value.BoolArrayToByte()); | ||||
|                 return (OperResult.CreateSuccessResult()); | ||||
|             case 2: | ||||
|                 ModbusServer02ByteBlock.Pos = mAddress.AddressStart; | ||||
|                 ModbusServer02ByteBlock.Write(value.BoolArrayToByte()); | ||||
|                 return (OperResult.CreateSuccessResult()); | ||||
|         } | ||||
|         return new OperResult("功能码错误"); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         return Task.FromResult(Write(address, value)); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         return Task.FromResult(Write(address, value)); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     protected override async Task Received(SocketClient client, ReceivedDataEventArgs e) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             var requestInfo = e.RequestInfo; | ||||
|             //接收外部报文 | ||||
|             if (requestInfo is ModbusTcpServerMessage modbusServerMessage) | ||||
|             { | ||||
|                 if (modbusServerMessage.CurModbusAddress == null) | ||||
|                 { | ||||
|                     return;//无法解析直接返回 | ||||
|                 } | ||||
|                 if (!modbusServerMessage.IsSuccess) | ||||
|                 { | ||||
|                     return;//无法解析直接返回 | ||||
|                 } | ||||
|  | ||||
|                 if (modbusServerMessage.CurModbusAddress.WriteFunction == 0)//读取 | ||||
|                 { | ||||
|                     var data = Read(modbusServerMessage.CurModbusAddress.ToString(), modbusServerMessage.Length); | ||||
|                     if (data.IsSuccess) | ||||
|                     { | ||||
|                         var coreData = data.Content; | ||||
|                         if (modbusServerMessage.CurModbusAddress.ReadFunction == 1 || modbusServerMessage.CurModbusAddress.ReadFunction == 2) | ||||
|                         { | ||||
|                             coreData = data.Content.Select(m => m > 0).ToArray().BoolArrayToByte().SelectMiddle(0, (int)Math.Ceiling(modbusServerMessage.Length / 8.0)); | ||||
|                         } | ||||
|                         var sendData = modbusServerMessage.ReceivedBytes.SelectMiddle(0, 8).SpliceArray(new byte[] { (byte)coreData.Length }, coreData); | ||||
|                         sendData[5] = (byte)(sendData.Length - 6); | ||||
|                         client.Send(sendData); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         WriteError(client, modbusServerMessage);//返回错误码 | ||||
|                     } | ||||
|                 } | ||||
|                 else//写入 | ||||
|                 { | ||||
|                     var coreData = modbusServerMessage.Content; | ||||
|                     if (modbusServerMessage.CurModbusAddress.ReadFunction == 1 || modbusServerMessage.CurModbusAddress.ReadFunction == 2) | ||||
|                     { | ||||
|                         //写入继电器 | ||||
|                         if (WriteData != null) | ||||
|                         { | ||||
|                             // 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端 | ||||
|                             if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, client)).IsSuccess) | ||||
|                             { | ||||
|                                 var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData.ByteToBoolArray(modbusServerMessage.Length)); | ||||
|                                 if (result.IsSuccess) | ||||
|                                 { | ||||
|                                     WriteSuccess03(client, modbusServerMessage); | ||||
|                                 } | ||||
|                                 else | ||||
|                                 { | ||||
|                                     WriteError(client, modbusServerMessage); | ||||
|                                 } | ||||
|                             } | ||||
|                             else | ||||
|                             { | ||||
|                                 WriteError(client, modbusServerMessage); | ||||
|                             } | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             //写入内存区 | ||||
|                             var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData.ByteToBoolArray(modbusServerMessage.Length)); | ||||
|                             if (result.IsSuccess) | ||||
|                             { | ||||
|                                 WriteSuccess03(client, modbusServerMessage); | ||||
|                             } | ||||
|                             else | ||||
|                             { | ||||
|                                 WriteError(client, modbusServerMessage); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         //写入寄存器 | ||||
|                         if (WriteData != null) | ||||
|                         { | ||||
|  | ||||
|                             if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, client)).IsSuccess) | ||||
|                             { | ||||
|                                 var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData); | ||||
|                                 if (result.IsSuccess) | ||||
|                                 { | ||||
|                                     WriteSuccess03(client, modbusServerMessage); | ||||
|                                 } | ||||
|                                 else | ||||
|                                 { | ||||
|                                     WriteError(client, modbusServerMessage); | ||||
|                                 } | ||||
|                             } | ||||
|                             else | ||||
|                             { | ||||
|                                 WriteError(client, modbusServerMessage); | ||||
|                             } | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData); | ||||
|                             if (result.IsSuccess) | ||||
|                             { | ||||
|                                 WriteSuccess03(client, modbusServerMessage); | ||||
|  | ||||
|                             } | ||||
|                             else | ||||
|                             { | ||||
|                                 WriteError(client, modbusServerMessage); | ||||
|  | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             Logger.LogError(ex, ToString()); | ||||
|         } | ||||
|         //返回错误码 | ||||
|         static void WriteError(SocketClient client, ModbusTcpServerMessage modbusServerMessage) | ||||
|         { | ||||
|             var sendData = modbusServerMessage.ReceivedBytes.SelectMiddle(0, 8) | ||||
| .SpliceArray(new byte[] { (byte)1 });//01 lllegal function | ||||
|             sendData[5] = (byte)(sendData.Length - 6); | ||||
|             sendData[7] = (byte)(sendData[7] + 128); | ||||
|             client.Send(sendData); | ||||
|  | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static void WriteSuccess03(SocketClient client, ModbusTcpServerMessage modbusServerMessage) | ||||
|     { | ||||
|         var sendData = modbusServerMessage.ReceivedBytes.SelectMiddle(0, 12); | ||||
|         sendData[5] = (byte)(sendData.Length - 6); | ||||
|         client.Send(sendData); | ||||
|     } | ||||
|  | ||||
|     private void Init(ModbusAddress mAddress) | ||||
|     { | ||||
|         if (ModbusServer01ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128))) | ||||
|             ModbusServer01ByteBlocks[mAddress.Station].SetLength(1024 * 128); | ||||
|         if (ModbusServer02ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128))) | ||||
|             ModbusServer02ByteBlocks[mAddress.Station].SetLength(1024 * 128); | ||||
|         if (ModbusServer03ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128))) | ||||
|             ModbusServer03ByteBlocks[mAddress.Station].SetLength(1024 * 128); | ||||
|         if (ModbusServer04ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128))) | ||||
|             ModbusServer04ByteBlocks[mAddress.Station].SetLength(1024 * 128); | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using ThingsGateway.Foundation.Extension.Generic; | ||||
| @@ -17,7 +15,7 @@ using ThingsGateway.Foundation.Extension.Generic; | ||||
| namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| 
 | ||||
| /// <inheritdoc/> | ||||
| internal class ModbusTcpServerDataHandleAdapter : ReadWriteDevicesSingleStreamDataHandleAdapter<ModbusTcpServerMessage> | ||||
| public class ModbusTcpServerDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter<ModbusTcpServerMessage> | ||||
| { | ||||
|     private readonly ThingsGatewayBitConverter ThingsGatewayBitConverter = new(EndianType.Big); | ||||
| 
 | ||||
| @@ -36,7 +34,7 @@ internal class ModbusTcpServerDataHandleAdapter : ReadWriteDevicesSingleStreamDa | ||||
|     /// </summary> | ||||
|     /// <param name="response">返回数据</param> | ||||
|     /// <returns></returns> | ||||
|     internal OperResult<byte[], FilterResult> GetModbusData(byte[] response) | ||||
|     internal OperResult<byte[]> GetModbusData(byte[] response) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
| @@ -44,30 +42,22 @@ internal class ModbusTcpServerDataHandleAdapter : ReadWriteDevicesSingleStreamDa | ||||
|             if (func == 1 || func == 2 || func == 3 || func == 4 || func == 5 || func == 6) | ||||
|             { | ||||
|                 if (response.Length == 6) | ||||
|                     return OperResult.CreateSuccessResult(response, FilterResult.Success); | ||||
|                     return OperResult.CreateSuccessResult(response); | ||||
|             } | ||||
|             else if (func == 15 || func == 16) | ||||
|             { | ||||
|                 var length = ThingsGatewayBitConverter.ToByte(response, 6); | ||||
|                 if (response.Length == 7 + length) | ||||
|                 { | ||||
|                     return OperResult.CreateSuccessResult(response, FilterResult.Success); | ||||
|                 } | ||||
|                 if (response.Length > 7 + length) | ||||
|                 { | ||||
|                     return new() { Content2 = FilterResult.Success, Message = $"数据长度{response.Length}错误" }; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return new() { Content2 = FilterResult.Cache, Message = $"数据长度{response.Length}错误" }; | ||||
|                     return OperResult.CreateSuccessResult(response); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return new() { Content2 = FilterResult.Success, Message = $"数据长度{response.Length}错误" }; | ||||
|             return new OperResult<byte[]>() { Message = $"数据长度{response.Length}错误" }; | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new(ex) { Content2 = FilterResult.Success }; | ||||
|             return new OperResult<byte[]>(ex.Message); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @@ -95,7 +85,7 @@ internal class ModbusTcpServerDataHandleAdapter : ReadWriteDevicesSingleStreamDa | ||||
|             { | ||||
|                 if (function > 6) | ||||
|                 { | ||||
|                     request.ModbusAddress = new ModbusAddress() | ||||
|                     request.CurModbusAddress = new ModbusAddress() | ||||
|                     { | ||||
|                         Station = station, | ||||
|                         Address = addressStart.ToString(), | ||||
| @@ -107,7 +97,7 @@ internal class ModbusTcpServerDataHandleAdapter : ReadWriteDevicesSingleStreamDa | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     request.ModbusAddress = new ModbusAddress() | ||||
|                     request.CurModbusAddress = new ModbusAddress() | ||||
|                     { | ||||
|                         Station = station, | ||||
|                         Address = addressStart.ToString(), | ||||
| @@ -120,7 +110,7 @@ internal class ModbusTcpServerDataHandleAdapter : ReadWriteDevicesSingleStreamDa | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 request.ModbusAddress = new ModbusAddress() | ||||
|                 request.CurModbusAddress = new ModbusAddress() | ||||
|                 { | ||||
|                     Station = station, | ||||
|                     Address = addressStart.ToString(), | ||||
| @@ -136,7 +126,7 @@ internal class ModbusTcpServerDataHandleAdapter : ReadWriteDevicesSingleStreamDa | ||||
|         { | ||||
|             request.ErrorCode = result.ErrorCode; | ||||
|             request.Message = result.Message; | ||||
|             return result.Content2; | ||||
|             return FilterResult.Cache; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.Modbus | ||||
| @@ -17,13 +15,12 @@ namespace ThingsGateway.Foundation.Adapter.Modbus | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     internal class ModbusTcpServerMessage : MessageBase, IMessage, IModbusServerMessage | ||||
|     public class ModbusTcpServerMessage : MessageBase, IMessage | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 当前关联的地址 | ||||
|         /// </summary> | ||||
|         public ModbusAddress ModbusAddress { get; set; } | ||||
| 
 | ||||
|         public ModbusAddress CurModbusAddress { get; set; } | ||||
|         /// <summary> | ||||
|         /// 当前读写的数据长度 | ||||
|         /// </summary> | ||||
| @@ -31,7 +28,6 @@ namespace ThingsGateway.Foundation.Adapter.Modbus | ||||
| 
 | ||||
|         /// <inheritdoc/> | ||||
|         public override int HeadBytesLength => 6; | ||||
| 
 | ||||
|         /// <inheritdoc/> | ||||
|         public override bool CheckHeadBytes(byte[] heads) | ||||
|         { | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.ComponentModel; | ||||
| @@ -19,6 +17,7 @@ namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| /// <inheritdoc/> | ||||
| public class ModbusUdp : ReadWriteDevicesUdpSessionBase | ||||
| { | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public ModbusUdp(UdpSession udpSession) : base(udpSession) | ||||
|     { | ||||
| @@ -26,30 +25,31 @@ public class ModbusUdp : ReadWriteDevicesUdpSessionBase | ||||
|         RegisterByteLength = 2; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 检测事务标识符 | ||||
|     /// </summary> | ||||
|     [Description("检测事务标识符")] | ||||
|     public bool IsCheckMessageId { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 站号 | ||||
|     /// </summary> | ||||
|     [Description("站号")] | ||||
|     public byte Station { get; set; } = 1; | ||||
| 
 | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack, int defaultIntervalTime) | ||||
|     public override List<T> LoadSourceRead<T, T2>(List<T2> deviceVariables, int maxPack) | ||||
|     { | ||||
|         return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack, defaultIntervalTime); | ||||
|         return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override string GetAddressDescription() | ||||
|     { | ||||
|         return $"{base.GetAddressDescription()}{Environment.NewLine}{ModbusHelper.GetAddressDescription()}"; | ||||
|         return base.GetAddressDescription() + Environment.NewLine + ModbusHelper.GetAddressDescription(); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default) | ||||
|     { | ||||
| @@ -57,8 +57,7 @@ public class ModbusUdp : ReadWriteDevicesUdpSessionBase | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return SendThenReturn<ModbusTcpMessage>(commandResult.Content, cancellationToken); | ||||
|             return SendThenReturn(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -73,8 +72,7 @@ public class ModbusUdp : ReadWriteDevicesUdpSessionBase | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetReadModbusCommand(address, length, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return await SendThenReturnAsync<ModbusTcpMessage>(commandResult.Content, cancellationToken); | ||||
|             return await SendThenReturnAsync(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -83,7 +81,7 @@ public class ModbusUdp : ReadWriteDevicesUdpSessionBase | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override void SetDataAdapter(ISocketClient socketClient = default) | ||||
|     public override void SetDataAdapter(object socketClient = null) | ||||
|     { | ||||
|         ModbusUdpDataHandleAdapter dataHandleAdapter = new() | ||||
|         { | ||||
| @@ -103,8 +101,7 @@ public class ModbusUdp : ReadWriteDevicesUdpSessionBase | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return SendThenReturn<ModbusTcpMessage>(commandResult.Content, cancellationToken); | ||||
|             return SendThenReturn(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -119,8 +116,7 @@ public class ModbusUdp : ReadWriteDevicesUdpSessionBase | ||||
|         { | ||||
|             Connect(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return SendThenReturn<ModbusTcpMessage>(commandResult.Content, cancellationToken); | ||||
|             return SendThenReturn(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -135,8 +131,7 @@ public class ModbusUdp : ReadWriteDevicesUdpSessionBase | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return await SendThenReturnAsync<ModbusTcpMessage>(commandResult.Content, cancellationToken); | ||||
|             return await SendThenReturnAsync(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -151,12 +146,42 @@ public class ModbusUdp : ReadWriteDevicesUdpSessionBase | ||||
|         { | ||||
|             await ConnectAsync(cancellationToken); | ||||
|             var commandResult = ModbusHelper.GetWriteBoolModbusCommand(address, value, Station); | ||||
|             if (!commandResult.IsSuccess) return commandResult; | ||||
|             return await SendThenReturnAsync<ModbusTcpMessage>(commandResult.Content, cancellationToken); | ||||
|             return await SendThenReturnAsync(commandResult, cancellationToken); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult(ex); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|     private OperResult<byte[]> SendThenReturn(OperResult<byte[]> commandResult, CancellationToken cancellationToken) | ||||
|     { | ||||
|         if (commandResult.IsSuccess) | ||||
|         { | ||||
|             var item = commandResult.Content; | ||||
|             if (FrameTime != 0) | ||||
|                 Thread.Sleep(FrameTime); | ||||
|             var result = WaitingClientEx.SendThenResponse(item, TimeOut, cancellationToken); | ||||
|             return (MessageBase)result.RequestInfo; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return new OperResult<byte[]>(commandResult.Message); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private async Task<OperResult<byte[]>> SendThenReturnAsync(OperResult<byte[]> commandResult, CancellationToken cancellationToken) | ||||
|     { | ||||
|         if (commandResult.IsSuccess) | ||||
|         { | ||||
|             var item = commandResult.Content; | ||||
|             await Task.Delay(FrameTime, cancellationToken); | ||||
|             var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, cancellationToken); | ||||
|             return (MessageBase)result.RequestInfo; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return new OperResult<byte[]>(commandResult.Message); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,19 +8,17 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using ThingsGateway.Foundation.Extension.Generic; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.Modbus; | ||||
| 
 | ||||
| /// <summary> | ||||
| /// <inheritdoc/> | ||||
| /// </summary> | ||||
| internal class ModbusUdpDataHandleAdapter : ReadWriteDevicesUdpDataHandleAdapter<ModbusTcpMessage> | ||||
| public class ModbusUdpDataHandleAdapter : ReadWriteDevicesUdpDataHandleAdapter<ModbusTcpMessage> | ||||
| { | ||||
|     private readonly IncrementCount _incrementCount = new(ushort.MaxValue); | ||||
|     private readonly EasyIncrementCount easyIncrementCount = new(ushort.MaxValue); | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 检测事务标识符 | ||||
| @@ -41,7 +38,7 @@ internal class ModbusUdpDataHandleAdapter : ReadWriteDevicesUdpDataHandleAdapter | ||||
|     /// <inheritdoc/> | ||||
|     public override byte[] PackCommand(byte[] command) | ||||
|     { | ||||
|         return ModbusHelper.AddModbusTcpHead(command, (ushort)_incrementCount.GetCurrentValue()); | ||||
|         return ModbusHelper.AddModbusTcpHead(command, (ushort)easyIncrementCount.GetCurrentValue()); | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
| @@ -56,4 +53,4 @@ internal class ModbusUdpDataHandleAdapter : ReadWriteDevicesUdpDataHandleAdapter | ||||
|         var result = ModbusHelper.GetModbusData(send.RemoveBegin(6), response.RemoveBegin(6)); | ||||
|         return result; | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using ThingsGateway.Foundation.Extension.Generic; | ||||
| @@ -28,9 +26,8 @@ public class PackHelper | ||||
|     /// <param name="device"></param> | ||||
|     /// <param name="deviceVariables"></param> | ||||
|     /// <param name="maxPack">最大打包长度</param> | ||||
|     /// <param name="defaultIntervalTime">默认间隔时间</param> | ||||
|     /// <returns></returns> | ||||
|     public static List<T> LoadSourceRead<T, T2>(IReadWrite device, List<T2> deviceVariables, int maxPack, int defaultIntervalTime) where T : IDeviceVariableSourceRead<IDeviceVariableRunTime>, new() where T2 : IDeviceVariableRunTime, new() | ||||
|     public static List<T> LoadSourceRead<T, T2>(IReadWrite device, List<T2> deviceVariables, int maxPack) where T : IDeviceVariableSourceRead<IDeviceVariableRunTime>, new() where T2 : IDeviceVariableRunTime, new() | ||||
|     { | ||||
|         if (deviceVariables == null) | ||||
|             throw new ArgumentNullException(nameof(deviceVariables)); | ||||
| @@ -40,13 +37,13 @@ public class PackHelper | ||||
|         //需要先剔除额外信息,比如dataformat等 | ||||
|         foreach (var item in deviceVariables) | ||||
|         { | ||||
|             var address = item.Address; | ||||
|             var address = item.VariableAddress; | ||||
|             IThingsGatewayBitConverter transformParameter = ByteTransformUtil.GetTransByAddress(ref address, byteConverter); | ||||
|             item.ThingsGatewayBitConverter = transformParameter; | ||||
|             //item.Address = address; | ||||
|             item.Index = device.GetBitOffset(item.Address); | ||||
|             //item.VariableAddress = address; | ||||
|             item.Index = device.GetBitOffset(item.VariableAddress); | ||||
|         } | ||||
|         var deviceVariableRunTimeGroups = deviceVariables.GroupBy(it => it.IntervalTime ?? defaultIntervalTime); | ||||
|         var deviceVariableRunTimeGroups = deviceVariables.GroupBy(it => it.IntervalTime); | ||||
|         foreach (var group in deviceVariableRunTimeGroups) | ||||
|         { | ||||
|             Dictionary<ModbusAddress, T2> map = group.ToDictionary(it => | ||||
| @@ -59,7 +56,6 @@ public class PackHelper | ||||
|                         case DataTypeEnum.String: | ||||
|                             lastLen = it.ThingsGatewayBitConverter.Length == null ? throw new("数据类型为字符串时,必须指定字符串长度,才能进行打包") : it.ThingsGatewayBitConverter.Length.Value; | ||||
|                             break; | ||||
| 
 | ||||
|                         default: | ||||
|                             lastLen = 2; | ||||
|                             break; | ||||
| @@ -70,10 +66,10 @@ public class PackHelper | ||||
|                     lastLen *= it.ThingsGatewayBitConverter.Length.Value; | ||||
|                 } | ||||
| 
 | ||||
|                 var address = it.Address; | ||||
|                 var address = it.VariableAddress; | ||||
|                 if (address.IndexOf('.') > 0) | ||||
|                 { | ||||
|                     var addressSplits = address.SplitStringByDelimiter(); | ||||
|                     var addressSplits = address.SplitDot(); | ||||
|                     address = addressSplits.RemoveLast(1).ArrayToString("."); | ||||
|                 } | ||||
|                 var result = ModbusAddress.ParseFrom(address); | ||||
| @@ -100,6 +96,7 @@ public class PackHelper | ||||
|                     deviceVariableSourceReads.AddRange(tempResult); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         return deviceVariableSourceReads; | ||||
| @@ -126,6 +123,7 @@ public class PackHelper | ||||
|                 readLength = maxPack * 8 * 2; | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|             //获取当前的一组打包地址信息, | ||||
|             var tempAddressEnd = orderByAddressEnd.Where(t => t.AddressEnd <= minAddress + readLength).ToList(); | ||||
|             //起始地址 | ||||
| @@ -135,9 +133,9 @@ public class PackHelper | ||||
| 
 | ||||
|             T sourceRead = new() | ||||
|             { | ||||
|                 IntervalTimeTick = new TimerTick(intervalTime), | ||||
|                 TimerTick = new TimerTick(intervalTime), | ||||
|                 //这里只需要根据地址排序的第一个地址,作为实际打包报文中的起始地址 | ||||
|                 Address = startAddress.ToString(), | ||||
|                 VariableAddress = startAddress.ToString(), | ||||
|                 Length = sourceLen | ||||
|             }; | ||||
|             foreach (var item in tempAddressEnd) | ||||
| @@ -167,4 +165,5 @@ public class PackHelper | ||||
|         } | ||||
|         return sourceReads; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| } | ||||
| @@ -11,7 +11,7 @@ | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusAddress.#ctor"> | ||||
|             <summary> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Modbus.ModbusAddress.AddressStart"> | ||||
| @@ -45,7 +45,7 @@ | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusAddress.Parse(System.String)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusAddress.ParseFrom(System.String,System.Byte)"> | ||||
|             <summary> | ||||
| @@ -58,7 +58,7 @@ | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusAddress.ToString"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusHelper.AddCrc(System.Byte[])"> | ||||
|             <summary> | ||||
| @@ -144,10 +144,10 @@ | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverTcp"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverTcp.#ctor(ThingsGateway.Foundation.Sockets.TcpClient)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverTcp.Crc16CheckEnable"> | ||||
|             <summary> | ||||
| @@ -160,37 +160,37 @@ | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverTcp.GetAddressDescription"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverTcp.Read(System.String,System.Int32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverTcp.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverTcp.LoadSourceRead``2(System.Collections.Generic.List{``1},System.Int32)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverTcp.SetDataAdapter(System.Object)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverTcp.Write(System.String,System.Byte[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverTcp.Write(System.String,System.Boolean[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverTcp.WriteAsync(System.String,System.Byte[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverTcp.WriteAsync(System.String,System.Boolean[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdp"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdp.#ctor(ThingsGateway.Foundation.Sockets.UdpSession)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdp.Crc16CheckEnable"> | ||||
|             <summary> | ||||
| @@ -203,35 +203,35 @@ | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdp.GetAddressDescription"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdp.Read(System.String,System.Int32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdp.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdp.SetDataAdapter(System.Object)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdp.LoadSourceRead``2(System.Collections.Generic.List{``1},System.Int32)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdp.Write(System.String,System.Byte[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdp.Write(System.String,System.Boolean[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdp.WriteAsync(System.String,System.Byte[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdp.WriteAsync(System.String,System.Boolean[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdpDataHandleAdapter"> | ||||
|             <summary> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdpDataHandleAdapter.Crc16CheckEnable"> | ||||
| @@ -240,24 +240,24 @@ | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdpDataHandleAdapter.PackCommand(System.Byte[])"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdpDataHandleAdapter.GetInstance"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuOverUdpDataHandleAdapter.UnpackResponse(System.Byte[],System.Byte[])"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu"> | ||||
|             <summary> | ||||
|             ModbusRtu | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.#ctor(ThingsGateway.Foundation.SerialPorts.SerialPortClient)"> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.#ctor(ThingsGateway.Foundation.Serial.SerialSession)"> | ||||
|             <summary> | ||||
|             ModbusRtu | ||||
|             </summary> | ||||
|             <param name="serialPortClient"></param> | ||||
|             <param name="serialSession"></param> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.Crc16CheckEnable"> | ||||
|             <summary> | ||||
| @@ -270,31 +270,31 @@ | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.GetAddressDescription"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.LoadSourceRead``2(System.Collections.Generic.List{``1},System.Int32)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.Read(System.String,System.Int32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.SetDataAdapter(System.Object)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.Write(System.String,System.Byte[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.Write(System.String,System.Boolean[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.WriteAsync(System.String,System.Byte[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.WriteAsync(System.String,System.Boolean[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuDataHandleAdapter"> | ||||
|             <summary> | ||||
| @@ -308,34 +308,34 @@ | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuDataHandleAdapter.PackCommand(System.Byte[])"> | ||||
|             <summary> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|             </summary> | ||||
|             <param name="command"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuDataHandleAdapter.GetInstance"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuDataHandleAdapter.UnpackResponse(ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuMessage,System.Byte[],System.Byte[],System.Byte[])"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuMessage"> | ||||
|             <summary> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuMessage.HeadBytesLength"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuMessage.CheckHeadBytes(System.Byte[])"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtuMessage.SendBytesThen"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer"> | ||||
|             <summary> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.ModbusServer01ByteBlocks"> | ||||
| @@ -364,7 +364,7 @@ | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.#ctor(ThingsGateway.Foundation.Sockets.TcpService)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.MulStation"> | ||||
|             <summary> | ||||
| @@ -377,44 +377,44 @@ | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.LoadSourceRead``2(System.Collections.Generic.List{``1},System.Int32)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.Dispose"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.GetAddressDescription"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.Read(System.String,System.Int32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.SetDataAdapter(System.Object)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.Write(System.String,System.Byte[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.Write(System.String,System.Boolean[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.WriteAsync(System.String,System.Byte[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.WriteAsync(System.String,System.Boolean[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.Received(ThingsGateway.Foundation.Sockets.SocketClient,ThingsGateway.Foundation.Core.IRequestInfo)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Modbus.ModbusServerDataHandleAdapter"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServerDataHandleAdapter.PackCommand(System.Byte[])"> | ||||
|             <summary> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|             </summary> | ||||
|             <param name="command"></param> | ||||
|             <returns></returns> | ||||
| @@ -427,14 +427,14 @@ | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServerDataHandleAdapter.GetInstance"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServerDataHandleAdapter.UnpackResponse(ThingsGateway.Foundation.Adapter.Modbus.ModbusServerMessage,System.Byte[],System.Byte[],System.Byte[])"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Modbus.ModbusServerMessage"> | ||||
|             <summary> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Modbus.ModbusServerMessage.CurModbusAddress"> | ||||
| @@ -448,16 +448,16 @@ | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Modbus.ModbusServerMessage.HeadBytesLength"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServerMessage.CheckHeadBytes(System.Byte[])"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp.#ctor(ThingsGateway.Foundation.Sockets.TcpClient)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp.IsCheckMessageId"> | ||||
|             <summary> | ||||
| @@ -470,31 +470,31 @@ | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp.GetAddressDescription"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp.LoadSourceRead``2(System.Collections.Generic.List{``1},System.Int32)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp.Read(System.String,System.Int32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp.SetDataAdapter(System.Object)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp.Write(System.String,System.Byte[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp.Write(System.String,System.Boolean[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp.WriteAsync(System.String,System.Byte[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp.WriteAsync(System.String,System.Boolean[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpDataHandleAdapter"> | ||||
|             <summary> | ||||
| @@ -507,21 +507,21 @@ | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpDataHandleAdapter.PackCommand(System.Byte[])"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpDataHandleAdapter.GetInstance"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpDataHandleAdapter.UnpackResponse(ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpMessage,System.Byte[],System.Byte[],System.Byte[])"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpMessage"> | ||||
|             <summary> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpMessage.HeadBytesLength"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpMessage.IsCheckMessageId"> | ||||
|             <summary> | ||||
| @@ -529,13 +529,13 @@ | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusTcpMessage.CheckHeadBytes(System.Byte[])"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Modbus.ModbusUdp"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusUdp.#ctor(ThingsGateway.Foundation.Sockets.UdpSession)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Modbus.ModbusUdp.IsCheckMessageId"> | ||||
|             <summary> | ||||
| @@ -548,35 +548,35 @@ | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusUdp.LoadSourceRead``2(System.Collections.Generic.List{``1},System.Int32)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusUdp.GetAddressDescription"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusUdp.Read(System.String,System.Int32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusUdp.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusUdp.SetDataAdapter(System.Object)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusUdp.Write(System.String,System.Byte[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusUdp.Write(System.String,System.Boolean[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusUdp.WriteAsync(System.String,System.Byte[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusUdp.WriteAsync(System.String,System.Boolean[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Modbus.ModbusUdpDataHandleAdapter"> | ||||
|             <summary> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Modbus.ModbusUdpDataHandleAdapter.IsCheckMessageId"> | ||||
| @@ -585,13 +585,13 @@ | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusUdpDataHandleAdapter.PackCommand(System.Byte[])"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusUdpDataHandleAdapter.GetInstance"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusUdpDataHandleAdapter.UnpackResponse(System.Byte[],System.Byte[])"> | ||||
|             <inheritdoc /> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Modbus.PackHelper"> | ||||
|             <summary> | ||||
| @@ -608,4 +608,4 @@ | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|     </members> | ||||
| </doc> | ||||
| </doc> | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.Runtime.InteropServices; | ||||
| @@ -35,7 +33,6 @@ internal class ComInterop | ||||
|     private const uint EOAC_NONE = 0x00; | ||||
|     private const uint EOAC_SECURE_REFS = 0x02; | ||||
|     private const uint EOAC_STATIC_CLOAKING = 0x20; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// The WIN32 system default locale. | ||||
|     /// </summary> | ||||
| @@ -74,7 +71,6 @@ internal class ComInterop | ||||
|     private const uint RPC_C_IMP_LEVEL_DELEGATE = 4; | ||||
|     private const uint RPC_C_IMP_LEVEL_IDENTIFY = 2; | ||||
|     private const uint RPC_C_IMP_LEVEL_IMPERSONATE = 3; | ||||
| 
 | ||||
|     #endregion const | ||||
| 
 | ||||
|     #region struct | ||||
| @@ -151,7 +147,6 @@ internal class ComInterop | ||||
| 
 | ||||
|     [DllImport("Kernel32.dll")] | ||||
|     private static extern int GetUserDefaultLangID(); | ||||
| 
 | ||||
|     #endregion win32 api | ||||
| 
 | ||||
|     /// <summary> | ||||
| @@ -261,7 +256,6 @@ internal class ComInterop | ||||
|             throw new ExternalException("COM初始化安全: " + GetSystemMessage(error), error); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 从枚举器读取guid。 | ||||
|     /// </summary> | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.OPCDA.Comn; | ||||
| @@ -56,7 +54,6 @@ internal static class Convert | ||||
|             throw new NotSupportedException("Object cannot be cloned."); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     internal static DateTime FileTimeToDateTime(System.Runtime.InteropServices.ComTypes.FILETIME filetime) | ||||
|     { | ||||
|         long num = filetime.dwHighDateTime; | ||||
| @@ -83,4 +80,4 @@ internal static class Convert | ||||
|         DateTime fILETIME_BaseTime2 = FILETIME_BaseTime; | ||||
|         return fILETIME_BaseTime2.Add(new TimeSpan(num2)).ToLocalTime(); | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.OPCDA.Da; | ||||
| @@ -19,19 +17,16 @@ namespace ThingsGateway.Foundation.Adapter.OPCDA.Da; | ||||
| /// </summary> | ||||
| /// <param name="opcItems"></param> | ||||
| public delegate void OnDataChangedHandler(List<ItemReadResult> opcItems); | ||||
| 
 | ||||
| /// <summary> | ||||
| /// 读取 | ||||
| /// </summary> | ||||
| /// <param name="opcItems"></param> | ||||
| public delegate void OnReadCompletedHandler(List<ItemReadResult> opcItems); | ||||
| 
 | ||||
| /// <summary> | ||||
| /// 写入 | ||||
| /// </summary> | ||||
| /// <param name="opcItems"></param> | ||||
| internal delegate void OnWriteCompletedHandler(List<ItemWriteResult> opcItems); | ||||
| 
 | ||||
| /// <summary> | ||||
| /// 返回结果 | ||||
| /// </summary> | ||||
| @@ -41,17 +36,14 @@ public class ItemReadResult | ||||
|     /// ID | ||||
|     /// </summary> | ||||
|     public string Name { get; set; } = ""; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// Quality | ||||
|     /// </summary> | ||||
|     public short Quality { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// TimeStamp | ||||
|     /// </summary> | ||||
|     public DateTime TimeStamp { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// Value | ||||
|     /// </summary> | ||||
| @@ -62,4 +54,4 @@ internal class ItemWriteResult | ||||
| { | ||||
|     internal int Exception { get; set; } = 0; | ||||
|     internal string Name { get; set; } = ""; | ||||
| } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.Runtime.InteropServices; | ||||
| @@ -37,7 +35,6 @@ internal class OpcGroup : IOPCDataCallback, IDisposable | ||||
|     private IOPCSyncIO m_SyncIO = null; | ||||
|     private GCHandle percendDeadBand = GCHandle.Alloc(0, GCHandleType.Pinned); | ||||
|     private GCHandle timeBias = GCHandle.Alloc(0, GCHandleType.Pinned); | ||||
| 
 | ||||
|     internal OpcGroup(string name) | ||||
|     { | ||||
|         Name = name; | ||||
| @@ -81,7 +78,6 @@ internal class OpcGroup : IOPCDataCallback, IDisposable | ||||
|     internal object GroupPointer => groupPointer; | ||||
| 
 | ||||
|     internal bool IsActive { get; set; } = true; | ||||
| 
 | ||||
|     internal int LCID | ||||
|     { | ||||
|         get => lcid; | ||||
| @@ -90,7 +86,6 @@ internal class OpcGroup : IOPCDataCallback, IDisposable | ||||
| 
 | ||||
|     internal string Name { get; private set; } = string.Empty; | ||||
|     internal List<OpcItem> OpcItems { get; private set; } = new List<OpcItem> { }; | ||||
| 
 | ||||
|     internal GCHandle PercendDeadBand | ||||
|     { | ||||
|         get => percendDeadBand; | ||||
| @@ -100,13 +95,11 @@ internal class OpcGroup : IOPCDataCallback, IDisposable | ||||
|     internal int RequestUpdateRate { get; set; } = 1000; | ||||
|     internal int RevisedUpdateRate => revisedUpdateRate; | ||||
|     internal int ServerGroupHandle => serverGroupHandle; | ||||
| 
 | ||||
|     internal GCHandle TimeBias | ||||
|     { | ||||
|         get => timeBias; | ||||
|         set => timeBias = value; | ||||
|     } | ||||
| 
 | ||||
|     public void Dispose() | ||||
|     { | ||||
|         Dispose(disposing: true); | ||||
| @@ -271,7 +264,6 @@ internal class OpcGroup : IOPCDataCallback, IDisposable | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 建立连接 | ||||
|     /// </summary> | ||||
| @@ -289,7 +281,6 @@ internal class OpcGroup : IOPCDataCallback, IDisposable | ||||
|         //创建客户端与服务端之间的连接 | ||||
|         m_ConnectionPoint.Advise(this, out m_connectionpoint_cookie); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 组读取 | ||||
|     /// </summary> | ||||
| @@ -362,6 +353,7 @@ internal class OpcGroup : IOPCDataCallback, IDisposable | ||||
|         return results; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     internal List<Tuple<int, int>> Write(object[] values, int[] serverHandle) | ||||
|     { | ||||
|         IntPtr pErrors = IntPtr.Zero; | ||||
| @@ -393,7 +385,6 @@ internal class OpcGroup : IOPCDataCallback, IDisposable | ||||
|         else | ||||
|             throw new("连接无效"); | ||||
|     } | ||||
| 
 | ||||
|     protected virtual void Dispose(bool disposing) | ||||
|     { | ||||
|         if (!disposedValue) | ||||
| @@ -463,4 +454,4 @@ internal class OpcGroup : IOPCDataCallback, IDisposable | ||||
|             hActive.Free(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,20 +8,17 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using ThingsGateway.Foundation.Adapter.OPCDA.Rcw; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.OPCDA.Da; | ||||
| 
 | ||||
| /// <summary> | ||||
| /// OpcItem | ||||
| /// </summary> | ||||
| public class OpcItem | ||||
| { | ||||
|     private static int _hanle = 0; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// OpcItem | ||||
|     /// </summary> | ||||
| @@ -32,22 +28,18 @@ public class OpcItem | ||||
|         ItemID = itemId; | ||||
|         ClientHandle = ++_hanle; | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// AccessPath | ||||
|     /// </summary> | ||||
|     public string AccessPath { get; private set; } = ""; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// Blob | ||||
|     /// </summary> | ||||
|     public IntPtr Blob { get; set; } = IntPtr.Zero; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// BlobSize | ||||
|     /// </summary> | ||||
|     public int BlobSize { get; set; } = 0; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// ClientHandle | ||||
|     /// </summary> | ||||
| @@ -62,29 +54,24 @@ public class OpcItem | ||||
|     /// 数据项在opc server的完全名称 | ||||
|     /// </summary> | ||||
|     public string ItemID { get; private set; } = String.Empty; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// Quality | ||||
|     /// </summary> | ||||
|     public int Quality { get; set; } = Qualities.OPC_QUALITY_BAD; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// RunTimeDataType | ||||
|     /// </summary> | ||||
|     public short RunTimeDataType { get; set; } = 0; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// ServerHandle | ||||
|     /// </summary> | ||||
|     public int ServerHandle { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// TimeStamp | ||||
|     /// </summary> | ||||
|     public DateTime TimeStamp { get; set; } = new DateTime(0); | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// Value | ||||
|     /// </summary> | ||||
|     public object Value { get; set; } | ||||
| } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.Runtime.InteropServices; | ||||
| @@ -21,6 +19,7 @@ namespace ThingsGateway.Foundation.Adapter.OPCDA.Da; | ||||
| 
 | ||||
| internal class OpcServer : IDisposable | ||||
| { | ||||
| 
 | ||||
|     private bool disposedValue; | ||||
| 
 | ||||
|     private IOPCServer m_OpcServer = null; | ||||
| @@ -83,6 +82,7 @@ internal class OpcServer : IDisposable | ||||
|             throw new("添加OPC组错误,OPC服务器返回null"); | ||||
|         } | ||||
|         return group; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
| @@ -110,6 +110,7 @@ internal class OpcServer : IDisposable | ||||
|                            new PropertyID(101), | ||||
|                          }; | ||||
| 
 | ||||
| 
 | ||||
|             var server = m_OpcServer as IOPCBrowse; | ||||
|             server.Browse( | ||||
|                      string.IsNullOrEmpty(itemId) ? "" : itemId, | ||||
| @@ -166,6 +167,7 @@ internal class OpcServer : IDisposable | ||||
|             OPCSERVERSTATUS status; | ||||
|             if (statusPtr != IntPtr.Zero) | ||||
|             { | ||||
| 
 | ||||
|                 object o = Marshal.PtrToStructure(statusPtr, typeof(OPCSERVERSTATUS)); | ||||
| 
 | ||||
|                 Marshal.FreeCoTaskMem(statusPtr); | ||||
| @@ -174,7 +176,7 @@ internal class OpcServer : IDisposable | ||||
|                 { | ||||
|                     status = (OPCSERVERSTATUS)o; | ||||
|                     serverStatus = new(); | ||||
|                     serverStatus.Version = $"{status.wMajorVersion.ToString()}.{status.wMinorVersion.ToString()}.{status.wBuildNumber.ToString()}"; | ||||
|                     serverStatus.Version = status.wMajorVersion.ToString() + "." + status.wMinorVersion.ToString() + "." + status.wBuildNumber.ToString(); | ||||
|                     serverStatus.ServerState = status.dwServerState; | ||||
|                     serverStatus.StartTime = Comn.Convert.FileTimeToDateTime(status.ftStartTime); | ||||
|                     serverStatus.CurrentTime = Comn.Convert.FileTimeToDateTime(status.ftCurrentTime); | ||||
| @@ -188,7 +190,9 @@ internal class OpcServer : IDisposable | ||||
|                 { | ||||
|                     IsConnected = false; | ||||
|                     throw new("未知错误"); | ||||
| 
 | ||||
|                 } | ||||
| 
 | ||||
|             } | ||||
|             else | ||||
|             { | ||||
| @@ -204,6 +208,8 @@ internal class OpcServer : IDisposable | ||||
|                 IsConnected = false; | ||||
|             ServerStatus = serverStatus; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     internal void RemoveGroup(OpcGroup group) | ||||
| @@ -226,6 +232,7 @@ internal class OpcServer : IDisposable | ||||
|             } | ||||
|             catch | ||||
|             { | ||||
| 
 | ||||
|             } | ||||
|             if (m_OpcServer != null) | ||||
|             { | ||||
| @@ -265,4 +272,4 @@ internal class OpcServer : IDisposable | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,13 +8,11 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using ThingsGateway.Foundation.Adapter.OPCDA.Rcw; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.OPCDA.Da; | ||||
| 
 | ||||
| /// <summary> | ||||
| /// ServerStatus | ||||
| /// </summary> | ||||
| @@ -25,29 +22,24 @@ public class ServerStatus | ||||
|     /// CurrentTime | ||||
|     /// </summary> | ||||
|     public DateTime CurrentTime { get; internal set; } = new DateTime(0); | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// LastUpdateTime | ||||
|     /// </summary> | ||||
|     public DateTime LastUpdateTime { get; internal set; } = new DateTime(0); | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// ServerState | ||||
|     /// </summary> | ||||
|     public OPCSERVERSTATE ServerState { get; internal set; } = OPCSERVERSTATE.OPC_STATUS_NOCONFIG; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// StartTime | ||||
|     /// </summary> | ||||
|     public DateTime StartTime { get; internal set; } = new DateTime(0); | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// VendorInfo | ||||
|     /// </summary> | ||||
|     public string VendorInfo { get; internal set; } = "UNKOWN"; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// Version | ||||
|     /// </summary> | ||||
|     public string Version { get; internal set; } = "UNKOWN"; | ||||
| } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.Collections; | ||||
| @@ -18,11 +16,10 @@ using System.Text; | ||||
| using ThingsGateway.Foundation.Adapter.OPCDA.Rcw; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.OPCDA.Discovery; | ||||
| 
 | ||||
| /// <summary> | ||||
| /// OpcDiscovery | ||||
| /// </summary> | ||||
| internal class OpcDiscovery | ||||
| public class OpcDiscovery | ||||
| { | ||||
|     private static readonly Guid CATID_OPC_DA10 = new("63D5F430-CFE4-11d1-B2C8-0060083BA1FB"); | ||||
| 
 | ||||
| @@ -31,7 +28,6 @@ internal class OpcDiscovery | ||||
|     private static readonly Guid CATID_OPC_DA30 = new("CC603642-66D7-48f1-B69A-B625E73652D7"); | ||||
| 
 | ||||
|     private static readonly Guid OPCEnumCLSID = new("13486D51-4821-11D2-A494-3CB306C10000"); | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// GetOpcServer | ||||
|     /// </summary> | ||||
| @@ -40,6 +36,7 @@ internal class OpcDiscovery | ||||
|     /// <returns></returns> | ||||
|     internal static ServerInfo GetOpcServer(string serverName, string host) | ||||
|     { | ||||
| 
 | ||||
|         if (string.IsNullOrEmpty(serverName)) | ||||
|         { | ||||
|             throw new("检索失败,需提供OPCName"); | ||||
| @@ -88,6 +85,7 @@ internal class OpcDiscovery | ||||
|             Comn.ComInterop.RealseComServer(o_Server); | ||||
|             o_Server = null; | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private static void GetIOPCServerList(ref ServerInfo result, ref ServerInfo[] serverInfos, string serverName, string host, IOPCServerList m_server, Guid catid) | ||||
| @@ -116,6 +114,7 @@ internal class OpcDiscovery | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private static void GetIOPCServerList(ref ServerInfo result, ref ServerInfo[] serverInfos, string serverName, string host, IOPCServerList2 m_server, Guid catid) | ||||
| @@ -144,8 +143,10 @@ internal class OpcDiscovery | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     private static ServerInfo[] GetServerDetails(Guid[] clsids, string host, IOPCServerList m_server) | ||||
|     { | ||||
|         ArrayList servers = new ArrayList(); | ||||
| @@ -229,8 +230,11 @@ internal class OpcDiscovery | ||||
|         } | ||||
|         return (ServerInfo[])servers.ToArray(typeof(ServerInfo)); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| internal class ServerInfo | ||||
| { | ||||
|     internal Guid CLSID { get; set; } | ||||
| @@ -249,4 +253,4 @@ internal class ServerInfo | ||||
|         stringBuilder.AppendLine($"{nameof(VerIndProgID)}:{VerIndProgID}"); | ||||
|         return stringBuilder.ToString(); | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.OPCDA.Rcw; | ||||
| @@ -84,7 +82,6 @@ public class BrowseElement : ICloneable | ||||
|             m_name = value; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public ItemProperty[] Properties | ||||
|     { | ||||
|         get | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System. | ||||
| @@ -19,7 +17,6 @@ Runtime.InteropServices; | ||||
| namespace ThingsGateway.Foundation.Adapter.OPCDA.Rcw; | ||||
| 
 | ||||
| #pragma warning disable CS1591 // 缺少对公共可见类型或成员的 XML 注释 | ||||
| 
 | ||||
| /// <exclude /> | ||||
| [ComImport] | ||||
| [GuidAttribute("B196B286-BAB4-101A-B69C-00AA00341D07")] | ||||
| @@ -330,8 +327,7 @@ public interface IOPCShutdown | ||||
| public struct CONNECTDATA | ||||
| { | ||||
|     [MarshalAs(UnmanagedType.IUnknown)] | ||||
|     private object pUnk; | ||||
| 
 | ||||
|     object pUnk; | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     private int dwCookie; | ||||
| } | ||||
|     int dwCookie; | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,13 +8,13 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System. | ||||
| 
 | ||||
| Runtime.InteropServices; | ||||
| 
 | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.OPCDA.Rcw; | ||||
| 
 | ||||
| #pragma warning disable CS1591 // 缺少对公共可见类型或成员的 XML 注释 | ||||
| @@ -92,30 +91,25 @@ public enum OPCSERVERSTATE | ||||
| [ComImport] | ||||
| [GuidAttribute("63D5F430-CFE4-11d1-B2C8-0060083BA1FB")] | ||||
| [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] | ||||
| public interface CATID_OPCDAServer10 | ||||
| { } | ||||
| public interface CATID_OPCDAServer10 { } | ||||
| 
 | ||||
| /// <exclude /> | ||||
| [ComImport] | ||||
| [GuidAttribute("63D5F432-CFE4-11d1-B2C8-0060083BA1FB")] | ||||
| [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] | ||||
| public interface CATID_OPCDAServer20 | ||||
| { } | ||||
| public interface CATID_OPCDAServer20 { } | ||||
| 
 | ||||
| /// <exclude /> | ||||
| [ComImport] | ||||
| [GuidAttribute("CC603642-66D7-48f1-B69A-B625E73652D7")] | ||||
| [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] | ||||
| public interface CATID_OPCDAServer30 | ||||
| { } | ||||
| public interface CATID_OPCDAServer30 { } | ||||
| 
 | ||||
| /// <exclude /> | ||||
| [ComImport] | ||||
| [GuidAttribute("3098EDA4-A006-48b2-A27F-247453959408")] | ||||
| [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] | ||||
| public interface CATID_XMLDAServer10 | ||||
| { } | ||||
| 
 | ||||
| public interface CATID_XMLDAServer10 { } | ||||
| /// <exclude /> | ||||
| [ComImport] | ||||
| [GuidAttribute("39c13a55-011e-11d0-9675-0020afd8adb3")] | ||||
| @@ -1008,16 +1002,12 @@ public struct OPCBROWSEELEMENT | ||||
| { | ||||
|     [MarshalAs(UnmanagedType.LPWStr)] | ||||
|     public string szName; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.LPWStr)] | ||||
|     public string szItemID; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwFlagValue; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwReserved; | ||||
| 
 | ||||
|     public OPCITEMPROPERTIES ItemProperties; | ||||
| } | ||||
| 
 | ||||
| @@ -1027,16 +1017,12 @@ public struct OPCGROUPHEADER | ||||
| { | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwSize; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwItemCount; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int hClientGroup; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwTransactionID; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int hrStatus; | ||||
| } | ||||
| @@ -1047,13 +1033,10 @@ public struct OPCGROUPHEADERWRITE | ||||
| { | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwItemCount; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int hClientGroup; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwTransactionID; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int hrStatus; | ||||
| } | ||||
| @@ -1064,35 +1047,24 @@ public struct OPCITEMATTRIBUTES | ||||
| { | ||||
|     [MarshalAs(UnmanagedType.LPWStr)] | ||||
|     public string szAccessPath; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.LPWStr)] | ||||
|     public string szItemID; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int bActive; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int hClient; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int hServer; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwAccessRights; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwBlobSize; | ||||
| 
 | ||||
|     public IntPtr pBlob; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short vtRequestedDataType; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short vtCanonicalDataType; | ||||
| 
 | ||||
|     public OPCEUTYPE dwEUType; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.Struct)] | ||||
|     public object vEUInfo; | ||||
| } | ||||
| @@ -1103,24 +1075,17 @@ public struct OPCITEMDEF | ||||
| { | ||||
|     [MarshalAs(UnmanagedType.LPWStr)] | ||||
|     public string szAccessPath; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.LPWStr)] | ||||
|     public string szItemID; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int bActive; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int hClient; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwBlobSize; | ||||
| 
 | ||||
|     public IntPtr pBlob; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short vtRequestedDataType; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short wReserved; | ||||
| }; | ||||
| @@ -1131,16 +1096,12 @@ public struct OPCITEMHEADER1 | ||||
| { | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int hClient; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwValueOffset; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short wQuality; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short wReserved; | ||||
| 
 | ||||
|     public System.Runtime.InteropServices.ComTypes.FILETIME ftTimeStampItem; | ||||
| } | ||||
| 
 | ||||
| @@ -1150,24 +1111,19 @@ public struct OPCITEMHEADER2 | ||||
| { | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int hClient; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwValueOffset; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short wQuality; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short wReserved; | ||||
| } | ||||
| 
 | ||||
| /// <exclude /> | ||||
| [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] | ||||
| public struct OPCITEMHEADERWRITE | ||||
| { | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int hClient; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwError; | ||||
| } | ||||
| @@ -1178,12 +1134,9 @@ public struct OPCITEMPROPERTIES | ||||
| { | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int hrErrorID; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwNumProperties; | ||||
| 
 | ||||
|     public IntPtr pItemProperties; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwReserved; | ||||
| } | ||||
| @@ -1194,25 +1147,18 @@ public struct OPCITEMPROPERTY | ||||
| { | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short vtDataType; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short wReserved; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwPropertyID; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.LPWStr)] | ||||
|     public string szItemID; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.LPWStr)] | ||||
|     public string szDescription; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.Struct)] | ||||
|     public object vValue; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int hrErrorID; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwReserved; | ||||
| } | ||||
| @@ -1223,19 +1169,14 @@ public struct OPCITEMRESULT | ||||
| { | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int hServer; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short vtCanonicalDataType; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short wReserved; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwAccessRights; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwBlobSize; | ||||
| 
 | ||||
|     public IntPtr pBlob; | ||||
| } | ||||
| 
 | ||||
| @@ -1245,15 +1186,11 @@ public struct OPCITEMSTATE | ||||
| { | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int hClient; | ||||
| 
 | ||||
|     public System.Runtime.InteropServices.ComTypes.FILETIME ftTimeStamp; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short wQuality; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short wReserved; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.Struct)] | ||||
|     public object vDataValue; | ||||
| } | ||||
| @@ -1264,22 +1201,16 @@ public struct OPCITEMVQT | ||||
| { | ||||
|     [MarshalAs(UnmanagedType.Struct)] | ||||
|     public object vDataValue; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int bQualitySpecified; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short wQuality; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short wReserved; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int bTimeStampSpecified; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwReserved; | ||||
| 
 | ||||
|     public System.Runtime.InteropServices.ComTypes.FILETIME ftTimeStamp; | ||||
| } | ||||
| 
 | ||||
| @@ -1291,29 +1222,21 @@ public struct OPCSERVERSTATUS | ||||
|     public System.Runtime.InteropServices.ComTypes.FILETIME ftCurrentTime; | ||||
|     public System.Runtime.InteropServices.ComTypes.FILETIME ftLastUpdateTime; | ||||
|     public OPCSERVERSTATE dwServerState; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwGroupCount; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I4)] | ||||
|     public int dwBandWidth; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short wMajorVersion; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short wMinorVersion; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short wBuildNumber; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.I2)] | ||||
|     public short wReserved; | ||||
| 
 | ||||
|     [MarshalAs(UnmanagedType.LPWStr)] | ||||
|     public string szVendorInfo; | ||||
| } | ||||
| 
 | ||||
| /// <exclude /> | ||||
| public static class Constants | ||||
| { | ||||
| @@ -1324,7 +1247,6 @@ public static class Constants | ||||
| 
 | ||||
|     // category description strings. | ||||
|     public const string OPC_CATEGORY_DESCRIPTION_DA10 = "OPC Data Access Servers Version 1.0"; | ||||
| 
 | ||||
|     public const string OPC_CATEGORY_DESCRIPTION_DA20 = "OPC Data Access Servers Version 2.0"; | ||||
|     public const string OPC_CATEGORY_DESCRIPTION_DA30 = "OPC Data Access Servers Version 3.0"; | ||||
|     public const string OPC_CATEGORY_DESCRIPTION_XMLDA10 = "OPC XML Data Access Servers Version 1.0"; | ||||
| @@ -1336,13 +1258,11 @@ public static class Constants | ||||
| 
 | ||||
|     // values for access rights mask. | ||||
|     public const int OPC_READABLE = 0x01; | ||||
| 
 | ||||
|     // well known complex type description systems. | ||||
|     // well known complex type description systems.    | ||||
|     public const string OPC_TYPE_SYSTEM_OPCBINARY = "OPCBinary"; | ||||
| 
 | ||||
|     public const string OPC_TYPE_SYSTEM_XMLSCHEMA = "XMLSchema"; | ||||
|     public const string OPC_WRITE_BEHAVIOR_ALL_OR_NOTHING = "All or Nothing"; | ||||
| 
 | ||||
|     // complex data write behavior values. | ||||
|     public const string OPC_WRITE_BEHAVIOR_BEST_EFFORT = "Best Effort"; | ||||
| 
 | ||||
| @@ -1360,7 +1280,7 @@ public static class Qualities | ||||
| 
 | ||||
|     public const short OPC_LIMIT_MASK = 0x03; | ||||
| 
 | ||||
|     // Values for Limit Bitfield | ||||
|     // Values for Limit Bitfield  | ||||
|     public const short OPC_LIMIT_OK = 0x00; | ||||
| 
 | ||||
|     // Values for QUALITY_MASK bit field | ||||
| @@ -1387,7 +1307,6 @@ public static class Qualities | ||||
| 
 | ||||
|     // Values for fields in the quality word | ||||
|     public const short OPC_QUALITY_MASK = 0xC0; | ||||
| 
 | ||||
|     public const short OPC_QUALITY_NOT_CONNECTED = 0x08; | ||||
|     public const short OPC_QUALITY_OUT_OF_SERVICE = 0x1C; | ||||
|     public const short OPC_QUALITY_SENSOR_CAL = 0x50; | ||||
| @@ -1421,7 +1340,6 @@ public static class Properties | ||||
| 
 | ||||
|     // property ids. | ||||
|     public const int OPC_PROPERTY_DATATYPE = 1; | ||||
| 
 | ||||
|     public const int OPC_PROPERTY_DEADBAND = 306; | ||||
|     public const string OPC_PROPERTY_DESC_ACCESS_RIGHTS = "Item Access Rights"; | ||||
|     public const string OPC_PROPERTY_DESC_ALARM_AREA_LIST = "Alarm Area List"; | ||||
| @@ -1432,7 +1350,6 @@ public static class Properties | ||||
|     public const string OPC_PROPERTY_DESC_CONDITION_STATUS = "Condition Status"; | ||||
|     public const string OPC_PROPERTY_DESC_CONSISTENCY_WINDOW = "Consistency Window"; | ||||
|     public const string OPC_PROPERTY_DESC_DATA_FILTER_VALUE = "Data Filter Value"; | ||||
| 
 | ||||
|     // property descriptions. | ||||
|     public const string OPC_PROPERTY_DESC_DATATYPE = "Item Canonical Data Type"; | ||||
| 
 | ||||
| @@ -1462,7 +1379,6 @@ public static class Properties | ||||
|     public const string OPC_PROPERTY_DESC_TIMEZONE = "Item Timezone"; | ||||
|     public const string OPC_PROPERTY_DESC_TYPE_DESCRIPTION = "Type Description"; | ||||
|     public const string OPC_PROPERTY_DESC_TYPE_ID = "Type ID"; | ||||
| 
 | ||||
|     // complex data properties. | ||||
|     public const string OPC_PROPERTY_DESC_TYPE_SYSTEM_ID = "Type System ID"; | ||||
| 
 | ||||
| @@ -1495,7 +1411,6 @@ public static class Properties | ||||
|     public const int OPC_PROPERTY_TIMEZONE = 108; | ||||
|     public const int OPC_PROPERTY_TYPE_DESCRIPTION = 604; | ||||
|     public const int OPC_PROPERTY_TYPE_ID = 602; | ||||
| 
 | ||||
|     // complex data properties. | ||||
|     public const int OPC_PROPERTY_TYPE_SYSTEM_ID = 600; | ||||
| 
 | ||||
| @@ -1503,4 +1418,4 @@ public static class Properties | ||||
|     public const int OPC_PROPERTY_UNFILTERED_ITEM_ID = 608; | ||||
|     public const int OPC_PROPERTY_VALUE = 2; | ||||
|     public const int OPC_PROPERTY_WRITE_BEHAVIOR = 606; | ||||
| } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.Collections; | ||||
| @@ -111,7 +109,6 @@ public class Interop | ||||
|         } | ||||
|         return browseElements; | ||||
|     } | ||||
| 
 | ||||
|     internal static ItemProperty[] GetItemProperties( | ||||
|       ref OPCITEMPROPERTIES input, | ||||
|       bool deallocate) | ||||
| @@ -191,7 +188,6 @@ public class Interop | ||||
|         } | ||||
|         return itemProperty; | ||||
|     } | ||||
| 
 | ||||
|     internal static OPCITEMPROPERTY GetItemProperty(ItemProperty input) | ||||
|     { | ||||
|         OPCITEMPROPERTY itemProperty = new OPCITEMPROPERTY(); | ||||
| @@ -229,302 +225,204 @@ public class Interop | ||||
|         { | ||||
|             case -2147467262: | ||||
|                 return new ResultID(ResultID.E_NOTSUPPORTED, (long)input); | ||||
| 
 | ||||
|             case -2147467259: | ||||
|                 return new ResultID(ResultID.E_FAIL, (long)input); | ||||
| 
 | ||||
|             case -2147352571: | ||||
|                 return new ResultID(ResultID.Da.E_BADTYPE, (long)input); | ||||
| 
 | ||||
|             case -2147352566: | ||||
|                 return new ResultID(ResultID.Da.E_RANGE, (long)input); | ||||
| 
 | ||||
|             case -2147217401: | ||||
|                 return new ResultID(ResultID.Hda.W_NOFILTER, (long)input); | ||||
| 
 | ||||
|             case -2147024882: | ||||
|                 return new ResultID(ResultID.E_OUTOFMEMORY, (long)input); | ||||
| 
 | ||||
|             case -2147024809: | ||||
|                 return new ResultID(ResultID.E_INVALIDARG, (long)input); | ||||
| 
 | ||||
|             case -1073479679: | ||||
|                 return new ResultID(ResultID.Da.E_INVALIDHANDLE, (long)input); | ||||
| 
 | ||||
|             case -1073479676: | ||||
|                 return new ResultID(ResultID.Da.E_BADTYPE, (long)input); | ||||
| 
 | ||||
|             case -1073479673: | ||||
|                 return new ResultID(ResultID.Da.E_UNKNOWN_ITEM_NAME, (long)input); | ||||
| 
 | ||||
|             case -1073479672: | ||||
|                 return new ResultID(ResultID.Da.E_INVALID_ITEM_NAME, (long)input); | ||||
| 
 | ||||
|             case -1073479671: | ||||
|                 return new ResultID(ResultID.Da.E_INVALID_FILTER, (long)input); | ||||
| 
 | ||||
|             case -1073479670: | ||||
|                 return new ResultID(ResultID.Da.E_UNKNOWN_ITEM_PATH, (long)input); | ||||
| 
 | ||||
|             case -1073479669: | ||||
|                 return new ResultID(ResultID.Da.E_RANGE, (long)input); | ||||
| 
 | ||||
|             case -1073479165: | ||||
|                 return new ResultID(ResultID.Da.E_INVALID_PID, (long)input); | ||||
| 
 | ||||
|             case -1073479164: | ||||
|                 return new ResultID(ResultID.Ae.E_INVALIDTIME, (long)input); | ||||
| 
 | ||||
|             case -1073479163: | ||||
|                 return new ResultID(ResultID.Ae.E_BUSY, (long)input); | ||||
| 
 | ||||
|             case -1073479162: | ||||
|                 return new ResultID(ResultID.Ae.E_NOINFO, (long)input); | ||||
| 
 | ||||
|             case -1073478655: | ||||
|                 return new ResultID(ResultID.Da.E_NO_ITEM_DEADBAND, (long)input); | ||||
| 
 | ||||
|             case -1073478654: | ||||
|                 return new ResultID(ResultID.Da.E_NO_ITEM_BUFFERING, (long)input); | ||||
| 
 | ||||
|             case -1073478653: | ||||
|                 return new ResultID(ResultID.Da.E_INVALIDCONTINUATIONPOINT, (long)input); | ||||
| 
 | ||||
|             case -1073478650: | ||||
|                 return new ResultID(ResultID.Da.E_NO_WRITEQT, (long)input); | ||||
| 
 | ||||
|             case -1073478649: | ||||
|                 return new ResultID(ResultID.Cpx.E_TYPE_CHANGED, (long)input); | ||||
| 
 | ||||
|             case -1073478648: | ||||
|                 return new ResultID(ResultID.Cpx.E_FILTER_DUPLICATE, (long)input); | ||||
| 
 | ||||
|             case -1073478647: | ||||
|                 return new ResultID(ResultID.Cpx.E_FILTER_INVALID, (long)input); | ||||
| 
 | ||||
|             case -1073478646: | ||||
|                 return new ResultID(ResultID.Cpx.E_FILTER_ERROR, (long)input); | ||||
| 
 | ||||
|             case -1073477888: | ||||
|                 return new ResultID(ResultID.Dx.E_PERSISTING, (long)input); | ||||
| 
 | ||||
|             case -1073477887: | ||||
|                 return new ResultID(ResultID.Dx.E_NOITEMLIST, (long)input); | ||||
| 
 | ||||
|             case -1073477886: | ||||
|                 return new ResultID(ResultID.Dx.E_VERSION_MISMATCH, (long)input); | ||||
| 
 | ||||
|             case -1073477885: | ||||
|                 return new ResultID(ResultID.Dx.E_VERSION_MISMATCH, (long)input); | ||||
| 
 | ||||
|             case -1073477884: | ||||
|                 return new ResultID(ResultID.Dx.E_UNKNOWN_ITEM_PATH, (long)input); | ||||
| 
 | ||||
|             case -1073477883: | ||||
|                 return new ResultID(ResultID.Dx.E_UNKNOWN_ITEM_NAME, (long)input); | ||||
| 
 | ||||
|             case -1073477882: | ||||
|                 return new ResultID(ResultID.Dx.E_INVALID_ITEM_PATH, (long)input); | ||||
| 
 | ||||
|             case -1073477881: | ||||
|                 return new ResultID(ResultID.Dx.E_INVALID_ITEM_NAME, (long)input); | ||||
| 
 | ||||
|             case -1073477880: | ||||
|                 return new ResultID(ResultID.Dx.E_INVALID_NAME, (long)input); | ||||
| 
 | ||||
|             case -1073477879: | ||||
|                 return new ResultID(ResultID.Dx.E_DUPLICATE_NAME, (long)input); | ||||
| 
 | ||||
|             case -1073477878: | ||||
|                 return new ResultID(ResultID.Dx.E_INVALID_BROWSE_PATH, (long)input); | ||||
| 
 | ||||
|             case -1073477877: | ||||
|                 return new ResultID(ResultID.Dx.E_INVALID_SERVER_URL, (long)input); | ||||
| 
 | ||||
|             case -1073477876: | ||||
|                 return new ResultID(ResultID.Dx.E_INVALID_SERVER_TYPE, (long)input); | ||||
| 
 | ||||
|             case -1073477875: | ||||
|                 return new ResultID(ResultID.Dx.E_UNSUPPORTED_SERVER_TYPE, (long)input); | ||||
| 
 | ||||
|             case -1073477874: | ||||
|                 return new ResultID(ResultID.Dx.E_CONNECTIONS_EXIST, (long)input); | ||||
| 
 | ||||
|             case -1073477873: | ||||
|                 return new ResultID(ResultID.Dx.E_TOO_MANY_CONNECTIONS, (long)input); | ||||
| 
 | ||||
|             case -1073477872: | ||||
|                 return new ResultID(ResultID.Dx.E_OVERRIDE_BADTYPE, (long)input); | ||||
| 
 | ||||
|             case -1073477871: | ||||
|                 return new ResultID(ResultID.Dx.E_OVERRIDE_RANGE, (long)input); | ||||
| 
 | ||||
|             case -1073477870: | ||||
|                 return new ResultID(ResultID.Dx.E_SUBSTITUTE_BADTYPE, (long)input); | ||||
| 
 | ||||
|             case -1073477869: | ||||
|                 return new ResultID(ResultID.Dx.E_SUBSTITUTE_RANGE, (long)input); | ||||
| 
 | ||||
|             case -1073477868: | ||||
|                 return new ResultID(ResultID.Dx.E_INVALID_TARGET_ITEM, (long)input); | ||||
| 
 | ||||
|             case -1073477867: | ||||
|                 return new ResultID(ResultID.Dx.E_UNKNOWN_TARGET_ITEM, (long)input); | ||||
| 
 | ||||
|             case -1073477866: | ||||
|                 return new ResultID(ResultID.Dx.E_TARGET_ALREADY_CONNECTED, (long)input); | ||||
| 
 | ||||
|             case -1073477865: | ||||
|                 return new ResultID(ResultID.Dx.E_UNKNOWN_SERVER_NAME, (long)input); | ||||
| 
 | ||||
|             case -1073477864: | ||||
|                 return new ResultID(ResultID.Dx.E_UNKNOWN_SOURCE_ITEM, (long)input); | ||||
| 
 | ||||
|             case -1073477863: | ||||
|                 return new ResultID(ResultID.Dx.E_INVALID_SOURCE_ITEM, (long)input); | ||||
| 
 | ||||
|             case -1073477862: | ||||
|                 return new ResultID(ResultID.Dx.E_INVALID_QUEUE_SIZE, (long)input); | ||||
| 
 | ||||
|             case -1073477861: | ||||
|                 return new ResultID(ResultID.Dx.E_INVALID_DEADBAND, (long)input); | ||||
| 
 | ||||
|             case -1073477860: | ||||
|                 return new ResultID(ResultID.Dx.E_INVALID_CONFIG_FILE, (long)input); | ||||
| 
 | ||||
|             case -1073477859: | ||||
|                 return new ResultID(ResultID.Dx.E_PERSIST_FAILED, (long)input); | ||||
| 
 | ||||
|             case -1073477858: | ||||
|                 return new ResultID(ResultID.Dx.E_TARGET_FAULT, (long)input); | ||||
| 
 | ||||
|             case -1073477857: | ||||
|                 return new ResultID(ResultID.Dx.E_TARGET_NO_ACCESSS, (long)input); | ||||
| 
 | ||||
|             case -1073477856: | ||||
|                 return new ResultID(ResultID.Dx.E_SOURCE_SERVER_FAULT, (long)input); | ||||
| 
 | ||||
|             case -1073477855: | ||||
|                 return new ResultID(ResultID.Dx.E_SOURCE_SERVER_NO_ACCESSS, (long)input); | ||||
| 
 | ||||
|             case -1073477854: | ||||
|                 return new ResultID(ResultID.Dx.E_SUBSCRIPTION_FAULT, (long)input); | ||||
| 
 | ||||
|             case -1073477853: | ||||
|                 return new ResultID(ResultID.Dx.E_SOURCE_ITEM_BADRIGHTS, (long)input); | ||||
| 
 | ||||
|             case -1073477852: | ||||
|                 return new ResultID(ResultID.Dx.E_SOURCE_ITEM_BAD_QUALITY, (long)input); | ||||
| 
 | ||||
|             case -1073477851: | ||||
|                 return new ResultID(ResultID.Dx.E_SOURCE_ITEM_BADTYPE, (long)input); | ||||
| 
 | ||||
|             case -1073477850: | ||||
|                 return new ResultID(ResultID.Dx.E_SOURCE_ITEM_RANGE, (long)input); | ||||
| 
 | ||||
|             case -1073477849: | ||||
|                 return new ResultID(ResultID.Dx.E_SOURCE_SERVER_NOT_CONNECTED, (long)input); | ||||
| 
 | ||||
|             case -1073477848: | ||||
|                 return new ResultID(ResultID.Dx.E_SOURCE_SERVER_TIMEOUT, (long)input); | ||||
| 
 | ||||
|             case -1073477847: | ||||
|                 return new ResultID(ResultID.Dx.E_TARGET_ITEM_DISCONNECTED, (long)input); | ||||
| 
 | ||||
|             case -1073477846: | ||||
|                 return new ResultID(ResultID.Dx.E_TARGET_NO_WRITES_ATTEMPTED, (long)input); | ||||
| 
 | ||||
|             case -1073477845: | ||||
|                 return new ResultID(ResultID.Dx.E_TARGET_ITEM_BADTYPE, (long)input); | ||||
| 
 | ||||
|             case -1073477844: | ||||
|                 return new ResultID(ResultID.Dx.E_TARGET_ITEM_RANGE, (long)input); | ||||
| 
 | ||||
|             case -1073475583: | ||||
|                 return new ResultID(ResultID.Hda.E_MAXEXCEEDED, (long)input); | ||||
| 
 | ||||
|             case -1073475580: | ||||
|                 return new ResultID(ResultID.Hda.E_INVALIDAGGREGATE, (long)input); | ||||
| 
 | ||||
|             case -1073475576: | ||||
|                 return new ResultID(ResultID.Hda.E_UNKNOWNATTRID, (long)input); | ||||
| 
 | ||||
|             case -1073475575: | ||||
|                 return new ResultID(ResultID.Hda.E_NOT_AVAIL, (long)input); | ||||
| 
 | ||||
|             case -1073475574: | ||||
|                 return new ResultID(ResultID.Hda.E_INVALIDDATATYPE, (long)input); | ||||
| 
 | ||||
|             case -1073475573: | ||||
|                 return new ResultID(ResultID.Hda.E_DATAEXISTS, (long)input); | ||||
| 
 | ||||
|             case -1073475572: | ||||
|                 return new ResultID(ResultID.Hda.E_INVALIDATTRID, (long)input); | ||||
| 
 | ||||
|             case -1073475571: | ||||
|                 return new ResultID(ResultID.Hda.E_NODATAEXISTS, (long)input); | ||||
| 
 | ||||
|             case 0: | ||||
|                 return new ResultID(ResultID.S_OK, (long)input); | ||||
| 
 | ||||
|             case 262157: | ||||
|                 return new ResultID(ResultID.Da.S_UNSUPPORTEDRATE, (long)input); | ||||
| 
 | ||||
|             case 262158: | ||||
|                 return new ResultID(ResultID.Da.S_CLAMP, (long)input); | ||||
| 
 | ||||
|             case 262656: | ||||
|                 return new ResultID(ResultID.Ae.S_ALREADYACKED, (long)input); | ||||
| 
 | ||||
|             case 262657: | ||||
|                 return new ResultID(ResultID.Ae.S_INVALIDBUFFERTIME, (long)input); | ||||
| 
 | ||||
|             case 262658: | ||||
|                 return new ResultID(ResultID.Ae.S_INVALIDMAXSIZE, (long)input); | ||||
| 
 | ||||
|             case 262659: | ||||
|                 return new ResultID(ResultID.Ae.S_INVALIDKEEPALIVETIME, (long)input); | ||||
| 
 | ||||
|             case 263172: | ||||
|                 return new ResultID(ResultID.Da.S_DATAQUEUEOVERFLOW, (long)input); | ||||
| 
 | ||||
|             case 263179: | ||||
|                 return new ResultID(ResultID.Cpx.S_FILTER_NO_DATA, (long)input); | ||||
| 
 | ||||
|             case 264064: | ||||
|                 return new ResultID(ResultID.Dx.S_TARGET_SUBSTITUTED, (long)input); | ||||
| 
 | ||||
|             case 264065: | ||||
|                 return new ResultID(ResultID.Dx.S_TARGET_OVERRIDEN, (long)input); | ||||
| 
 | ||||
|             case 264066: | ||||
|                 return new ResultID(ResultID.Dx.S_CLAMP, (long)input); | ||||
| 
 | ||||
|             case 1074008066: | ||||
|                 return new ResultID(ResultID.Hda.S_NODATA, (long)input); | ||||
| 
 | ||||
|             case 1074008067: | ||||
|                 return new ResultID(ResultID.Hda.S_MOREDATA, (long)input); | ||||
| 
 | ||||
|             case 1074008069: | ||||
|                 return new ResultID(ResultID.Hda.S_CURRENTVALUE, (long)input); | ||||
| 
 | ||||
|             case 1074008070: | ||||
|                 return new ResultID(ResultID.Hda.S_EXTRADATA, (long)input); | ||||
| 
 | ||||
|             case 1074008078: | ||||
|                 return new ResultID(ResultID.Hda.S_INSERTED, (long)input); | ||||
| 
 | ||||
|             case 1074008079: | ||||
|                 return new ResultID(ResultID.Hda.S_REPLACED, (long)input); | ||||
| 
 | ||||
|             default: | ||||
|                 if ((input & 2147418112) == 65536) | ||||
|                     return new ResultID(ResultID.E_NETWORK_ERROR, (long)input); | ||||
|                 return input >= 0 ? new ResultID(ResultID.S_FALSE, (long)input) : new ResultID(ResultID.E_FAIL, (long)input); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     internal static int GetResultID(ResultID input) | ||||
|     { | ||||
|         if (input.Name != (XmlQualifiedName)null && input.Name.Namespace == "http://opcfoundation.org/DataAccess/") | ||||
| @@ -788,106 +686,74 @@ public class Interop | ||||
|             return VarEnum.VT_I2; | ||||
|         return input == typeof(accessRights) || input == typeof(euType) ? VarEnum.VT_I4 : VarEnum.VT_EMPTY; | ||||
|     } | ||||
| 
 | ||||
|     internal static System.Type GetType(VarEnum input) | ||||
|     { | ||||
|         switch (input) | ||||
|         { | ||||
|             case VarEnum.VT_EMPTY: | ||||
|                 return (System.Type)null; | ||||
| 
 | ||||
|             case VarEnum.VT_I2: | ||||
|                 return typeof(short); | ||||
| 
 | ||||
|             case VarEnum.VT_I4: | ||||
|                 return typeof(int); | ||||
| 
 | ||||
|             case VarEnum.VT_R4: | ||||
|                 return typeof(float); | ||||
| 
 | ||||
|             case VarEnum.VT_R8: | ||||
|                 return typeof(double); | ||||
| 
 | ||||
|             case VarEnum.VT_CY: | ||||
|                 return typeof(Decimal); | ||||
| 
 | ||||
|             case VarEnum.VT_DATE: | ||||
|                 return typeof(DateTime); | ||||
| 
 | ||||
|             case VarEnum.VT_BSTR: | ||||
|                 return typeof(string); | ||||
| 
 | ||||
|             case VarEnum.VT_BOOL: | ||||
|                 return typeof(bool); | ||||
| 
 | ||||
|             case VarEnum.VT_I1: | ||||
|                 return typeof(sbyte); | ||||
| 
 | ||||
|             case VarEnum.VT_UI1: | ||||
|                 return typeof(byte); | ||||
| 
 | ||||
|             case VarEnum.VT_UI2: | ||||
|                 return typeof(ushort); | ||||
| 
 | ||||
|             case VarEnum.VT_UI4: | ||||
|                 return typeof(uint); | ||||
| 
 | ||||
|             case VarEnum.VT_I8: | ||||
|                 return typeof(long); | ||||
| 
 | ||||
|             case VarEnum.VT_UI8: | ||||
|                 return typeof(ulong); | ||||
| 
 | ||||
|             case VarEnum.VT_I2 | VarEnum.VT_ARRAY: | ||||
|                 return typeof(short[]); | ||||
| 
 | ||||
|             case VarEnum.VT_I4 | VarEnum.VT_ARRAY: | ||||
|                 return typeof(int[]); | ||||
| 
 | ||||
|             case VarEnum.VT_R4 | VarEnum.VT_ARRAY: | ||||
|                 return typeof(float[]); | ||||
| 
 | ||||
|             case VarEnum.VT_R8 | VarEnum.VT_ARRAY: | ||||
|                 return typeof(double[]); | ||||
| 
 | ||||
|             case VarEnum.VT_CY | VarEnum.VT_ARRAY: | ||||
|                 return typeof(Decimal[]); | ||||
| 
 | ||||
|             case VarEnum.VT_DATE | VarEnum.VT_ARRAY: | ||||
|                 return typeof(DateTime[]); | ||||
| 
 | ||||
|             case VarEnum.VT_BSTR | VarEnum.VT_ARRAY: | ||||
|                 return typeof(string[]); | ||||
| 
 | ||||
|             case VarEnum.VT_BOOL | VarEnum.VT_ARRAY: | ||||
|                 return typeof(bool[]); | ||||
| 
 | ||||
|             case VarEnum.VT_VARIANT | VarEnum.VT_ARRAY: | ||||
|                 return typeof(object[]); | ||||
| 
 | ||||
|             case VarEnum.VT_I1 | VarEnum.VT_ARRAY: | ||||
|                 return typeof(sbyte[]); | ||||
| 
 | ||||
|             case VarEnum.VT_UI1 | VarEnum.VT_ARRAY: | ||||
|                 return typeof(byte[]); | ||||
| 
 | ||||
|             case VarEnum.VT_UI2 | VarEnum.VT_ARRAY: | ||||
|                 return typeof(ushort[]); | ||||
| 
 | ||||
|             case VarEnum.VT_UI4 | VarEnum.VT_ARRAY: | ||||
|                 return typeof(uint[]); | ||||
| 
 | ||||
|             case VarEnum.VT_I8 | VarEnum.VT_ARRAY: | ||||
|                 return typeof(long[]); | ||||
| 
 | ||||
|             case VarEnum.VT_UI8 | VarEnum.VT_ARRAY: | ||||
|                 return typeof(ulong[]); | ||||
| 
 | ||||
|             default: | ||||
|                 return Type.ILLEGAL_TYPE; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     internal static object MarshalPropertyValue(PropertyID propertyID, object input) | ||||
|     { | ||||
|         if (input == null) | ||||
| @@ -902,13 +768,10 @@ public class Interop | ||||
|                 { | ||||
|                     case accessRights.readable: | ||||
|                         return (object)1; | ||||
| 
 | ||||
|                     case accessRights.writable: | ||||
|                         return (object)2; | ||||
| 
 | ||||
|                     case accessRights.readWritable: | ||||
|                         return (object)3; | ||||
| 
 | ||||
|                     default: | ||||
|                         return (object)null; | ||||
|                 } | ||||
| @@ -919,13 +782,10 @@ public class Interop | ||||
|                 { | ||||
|                     case euType.noEnum: | ||||
|                         return (object)OPCEUTYPE.OPC_NOENUM; | ||||
| 
 | ||||
|                     case euType.analog: | ||||
|                         return (object)OPCEUTYPE.OPC_ANALOG; | ||||
| 
 | ||||
|                     case euType.enumerated: | ||||
|                         return (object)OPCEUTYPE.OPC_ENUMERATED; | ||||
| 
 | ||||
|                     default: | ||||
|                         return (object)null; | ||||
|                 } | ||||
| @@ -964,13 +824,10 @@ public class Interop | ||||
|                 { | ||||
|                     case 1: | ||||
|                         return (object)accessRights.readable; | ||||
| 
 | ||||
|                     case 2: | ||||
|                         return (object)accessRights.writable; | ||||
| 
 | ||||
|                     case 3: | ||||
|                         return (object)accessRights.readWritable; | ||||
| 
 | ||||
|                     default: | ||||
|                         return (object)null; | ||||
|                 } | ||||
| @@ -981,13 +838,10 @@ public class Interop | ||||
|                 { | ||||
|                     case OPCEUTYPE.OPC_NOENUM: | ||||
|                         return (object)euType.noEnum; | ||||
| 
 | ||||
|                     case OPCEUTYPE.OPC_ANALOG: | ||||
|                         return (object)euType.analog; | ||||
| 
 | ||||
|                     case OPCEUTYPE.OPC_ENUMERATED: | ||||
|                         return (object)euType.enumerated; | ||||
| 
 | ||||
|                     default: | ||||
|                         return (object)null; | ||||
|                 } | ||||
| @@ -1011,4 +865,4 @@ public class Interop | ||||
|         } | ||||
|         return input; | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.Collections; | ||||
| @@ -17,6 +15,7 @@ using System.Reflection; | ||||
| using System.Runtime.Serialization; | ||||
| using System.Xml; | ||||
| 
 | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.OPCDA.Rcw; | ||||
| #pragma warning disable CS1591 // 缺少对公共可见类型或成员的 XML 注释 | ||||
| 
 | ||||
| @@ -211,7 +210,6 @@ public struct Quality | ||||
|     private limitBits m_limitBits; | ||||
|     private qualityBits m_qualityBits; | ||||
|     private byte m_vendorBits; | ||||
| 
 | ||||
|     public Quality(qualityBits quality) | ||||
|     { | ||||
|         m_qualityBits = quality; | ||||
| @@ -249,7 +247,6 @@ public struct Quality | ||||
|             m_qualityBits = value; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public byte VendorBits | ||||
|     { | ||||
|         get | ||||
| @@ -323,7 +320,6 @@ public struct Quality | ||||
|         m_limitBits = (limitBits)(code & 3); | ||||
|         m_vendorBits = (byte)((code & -253) >> 8); | ||||
|     } | ||||
| 
 | ||||
|     public override string ToString() | ||||
|     { | ||||
|         string text = QualityBits.ToString(); | ||||
| @@ -630,7 +626,6 @@ public struct ResultID : ISerializable | ||||
|         internal const string NAMESPACE = "NS"; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| [Serializable] | ||||
| public class ItemProperty : ICloneable, IResult | ||||
| { | ||||
| @@ -642,7 +637,6 @@ public class ItemProperty : ICloneable, IResult | ||||
|     private string m_itemPath; | ||||
|     private ResultID m_resultID = ResultID.S_OK; | ||||
|     private object m_value; | ||||
| 
 | ||||
|     public System.Type DataType | ||||
|     { | ||||
|         get | ||||
| @@ -690,7 +684,6 @@ public class ItemProperty : ICloneable, IResult | ||||
|             m_id = value; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public string ItemName | ||||
|     { | ||||
|         get | ||||
| @@ -747,7 +740,6 @@ public class ItemProperty : ICloneable, IResult | ||||
|         return obj; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| public class Property | ||||
| { | ||||
|     public static readonly PropertyID ACCESSRIGHTS = new PropertyID("accessRights", 5, "http://opcfoundation.org/DataAccess/"); | ||||
| @@ -796,7 +788,6 @@ public class Property | ||||
|     public static readonly PropertyID VALUE_PRECISION = new PropertyID("valuePrecision", 111, "http://opcfoundation.org/DataAccess/"); | ||||
|     public static readonly PropertyID WRITE_BEHAVIOR = new PropertyID("writeBehavior", 606, "http://opcfoundation.org/DataAccess/"); | ||||
| } | ||||
| 
 | ||||
| public class Type | ||||
| { | ||||
|     public static System.Type ANY_TYPE = typeof(object); | ||||
| @@ -831,7 +822,6 @@ public class Type | ||||
|     public static System.Type UINT = typeof(uint); | ||||
|     public static System.Type ULONG = typeof(ulong); | ||||
|     public static System.Type USHORT = typeof(ushort); | ||||
| 
 | ||||
|     public static System.Type[] Enumerate() | ||||
|     { | ||||
|         ArrayList arrayList = new ArrayList(); | ||||
| @@ -844,7 +834,6 @@ public class Type | ||||
|         return (System.Type[])arrayList.ToArray(typeof(System.Type)); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| [Serializable] | ||||
| public class PropertyDescription | ||||
| { | ||||
| @@ -896,7 +885,6 @@ public class PropertyDescription | ||||
| 
 | ||||
|     private string m_name; | ||||
|     private System.Type m_type; | ||||
| 
 | ||||
|     public PropertyDescription(PropertyID id, System.Type type, string name) | ||||
|     { | ||||
|         ID = id; | ||||
| @@ -939,7 +927,6 @@ public class PropertyDescription | ||||
|             m_type = value; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static PropertyDescription[] Enumerate() | ||||
|     { | ||||
|         ArrayList arrayList = new ArrayList(); | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.OPCDA; | ||||
| @@ -29,7 +27,6 @@ internal static class CollectionExtensions | ||||
|             @this.Remove(obj); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 将项目列表分解为特定大小的块 | ||||
|     /// </summary> | ||||
| @@ -48,4 +45,5 @@ internal static class CollectionExtensions | ||||
|         } | ||||
|         return n; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| @@ -121,6 +119,5 @@ internal static class DictionaryExtension | ||||
|     { | ||||
|         return dictionary.TryGetValue(tkey, out var value) ? value : default; | ||||
|     } | ||||
| 
 | ||||
|     #endregion 字典扩展 | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,10 +8,10 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| global using System; | ||||
| global using System.Collections.Generic; | ||||
| global using System.Linq; | ||||
| global using System.Threading; | ||||
| global using System.Threading; | ||||
| 
 | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.Runtime.InteropServices; | ||||
| @@ -24,13 +22,11 @@ using Timer = System.Timers.Timer; | ||||
| //部分非托管交互代码来自https://gitee.com/Zer0Day/opc-client与OPC基金会opcnet库,更改部分逻辑 | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.OPCDA; | ||||
| 
 | ||||
| /// <summary> | ||||
| /// 订阅变化项 | ||||
| /// </summary> | ||||
| /// <param name="values"></param> | ||||
| public delegate void DataChangedEventHandler(List<ItemReadResult> values); | ||||
| 
 | ||||
| /// <summary> | ||||
| /// OPCDAClient | ||||
| /// </summary> | ||||
| @@ -46,7 +42,6 @@ public class OPCDAClient : IDisposable | ||||
|     private Timer checkTimer; | ||||
| 
 | ||||
|     private int IsExit = 1; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 当前保存的需订阅列表 | ||||
|     /// </summary> | ||||
| @@ -54,7 +49,6 @@ public class OPCDAClient : IDisposable | ||||
| 
 | ||||
|     private OpcServer m_server; | ||||
|     private bool publicConnect; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
| @@ -82,8 +76,7 @@ public class OPCDAClient : IDisposable | ||||
|     /// <summary> | ||||
|     /// 当前配置 | ||||
|     /// </summary> | ||||
|     public OPCDANode OPCNode { get; private set; } | ||||
| 
 | ||||
|     public OPCNode OPCNode { get; private set; } | ||||
|     private List<OpcGroup> Groups => m_server.OpcGroups; | ||||
| 
 | ||||
|     /// <summary> | ||||
| @@ -205,7 +198,7 @@ public class OPCDAClient : IDisposable | ||||
|     /// 初始化设置 | ||||
|     /// </summary> | ||||
|     /// <param name="node"></param> | ||||
|     public void Init(OPCDANode node) | ||||
|     public void Init(OPCNode node) | ||||
|     { | ||||
|         if (node != null) | ||||
|             OPCNode = node; | ||||
| @@ -271,9 +264,10 @@ public class OPCDAClient : IDisposable | ||||
|                     ItemDicts[opcGroup.Name].RemoveWhere(a => tag.Contains(a) && !result.Select(b => b.Item1).Contains(a)); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override string ToString() | ||||
|     { | ||||
| @@ -344,11 +338,11 @@ public class OPCDAClient : IDisposable | ||||
|         } | ||||
|         return results; | ||||
|     } | ||||
| 
 | ||||
|     private void CheckTimer_Elapsed(object sender, ElapsedEventArgs e) | ||||
|     { | ||||
|         lock (checkLock) | ||||
|         { | ||||
| 
 | ||||
|             if (IsExit == 0) | ||||
|             { | ||||
|                 try | ||||
| @@ -377,6 +371,7 @@ public class OPCDAClient : IDisposable | ||||
|                 timeer.Enabled = false; | ||||
|                 timeer.Stop(); | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @@ -391,11 +386,11 @@ public class OPCDAClient : IDisposable | ||||
|             _logAction?.Invoke(3, this, $"添加点位失败:{ex.Message}", ex); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void PrivateConnect() | ||||
|     { | ||||
|         lock (this) | ||||
|         { | ||||
| 
 | ||||
|             if (m_server?.IsConnected == true) | ||||
|             { | ||||
|                 try | ||||
| @@ -410,12 +405,15 @@ public class OPCDAClient : IDisposable | ||||
|                     } | ||||
|                     catch | ||||
|                     { | ||||
| 
 | ||||
|                         Init(OPCNode); | ||||
|                         m_server?.Connect(); | ||||
|                         _logAction?.Invoke(1, this, $"{m_server.Host} - {m_server.Name} - 连接成功", null); | ||||
|                         PrivateAddItems(); | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
| 
 | ||||
|             } | ||||
|             else | ||||
|             { | ||||
| @@ -424,6 +422,7 @@ public class OPCDAClient : IDisposable | ||||
|                 _logAction?.Invoke(1, this, $"{m_server.Host} - {m_server.Name} - 连接成功", null); | ||||
|                 PrivateAddItems(); | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @@ -450,9 +449,9 @@ public class OPCDAClient : IDisposable | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void Subscription_OnDataChanged(List<ItemReadResult> values) | ||||
|     { | ||||
|         DataChangedHandler?.Invoke(values); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,60 +8,51 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.ComponentModel; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.OPCDA; | ||||
| 
 | ||||
| /// <summary> | ||||
| /// OPCDA连接配置项 | ||||
| /// </summary> | ||||
| public class OPCDANode | ||||
| public class OPCNode | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 是否订阅 | ||||
|     /// </summary> | ||||
|     [Description("订阅")] | ||||
|     public bool ActiveSubscribe { get; set; } = true; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 内部检测重连间隔/min | ||||
|     /// </summary> | ||||
|     [Description("重连间隔/min")] | ||||
|     public int CheckRate { get; set; } = 30; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 死区 | ||||
|     /// </summary> | ||||
|     [Description("死区")] | ||||
|     public float DeadBand { get; set; } = 0; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 分组大小 | ||||
|     /// </summary> | ||||
|     [Description("分组大小")] | ||||
|     public int GroupSize { get; set; } = 500; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// OPCIP | ||||
|     /// </summary> | ||||
|     [Description("OPCIP")] | ||||
|     public string OPCIP { get; set; } = "localhost"; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// OPCNAME | ||||
|     /// </summary> | ||||
|     [Description("OPCNAME")] | ||||
|     public string OPCName { get; set; } = "Kepware.KEPServerEX.V6"; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 订阅间隔 | ||||
|     /// </summary> | ||||
|     [Description("订阅间隔")] | ||||
|     public int UpdateRate { get; set; } = 1000; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
| @@ -71,4 +61,4 @@ public class OPCDANode | ||||
|     { | ||||
|         return $"{(string.IsNullOrEmpty(OPCIP) ? "localhost" : OPCIP)}:{OPCName}"; | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -0,0 +1,8 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk"> | ||||
|  | ||||
|  | ||||
| 	<PropertyGroup> | ||||
| 		<TargetFrameworks>net45;netstandard2.0;net6.0;net7.0</TargetFrameworks> | ||||
| 	</PropertyGroup> | ||||
| 	 | ||||
| </Project> | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,11 +8,10 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| global using System; | ||||
| global using System.Collections.Generic; | ||||
| global using System.Linq; | ||||
| global using System.Threading; | ||||
| global using System.Threading.Tasks; | ||||
| global using System.Threading.Tasks; | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,24 +8,21 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.ComponentModel; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.OPCUA; | ||||
| 
 | ||||
| /// <summary> | ||||
| /// OPCUAClient配置项 | ||||
| /// </summary> | ||||
| public class OPCUANode | ||||
| public class OPCNode | ||||
| { | ||||
|     /// <summary> | ||||
|     /// OPCUrl | ||||
|     /// </summary> | ||||
|     [Description("OPCUrl")] | ||||
|     public string OPCUrl { get; set; } = "opc.tcp://127.0.0.1:49320"; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 登录账号 | ||||
|     /// </summary> | ||||
| @@ -38,7 +34,6 @@ public class OPCUANode | ||||
|     /// </summary> | ||||
|     [Description("登录密码")] | ||||
|     public string Password { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 检查域 | ||||
|     /// </summary> | ||||
| @@ -50,46 +45,34 @@ public class OPCUANode | ||||
|     /// </summary> | ||||
|     [Description("更新间隔")] | ||||
|     public int UpdateRate { get; set; } = 1000; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 是否订阅 | ||||
|     /// </summary> | ||||
|     [Description("是否订阅")] | ||||
|     public bool ActiveSubscribe { get; set; } = true; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 分组大小 | ||||
|     /// </summary> | ||||
|     [Description("分组大小")] | ||||
|     public int GroupSize { get; set; } = 500; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 死区 | ||||
|     /// </summary> | ||||
|     [Description("死区")] | ||||
|     public double DeadBand { get; set; } = 0; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// KeepAliveInterval/ms | ||||
|     /// </summary> | ||||
|     [Description("KeepAliveInterval/ms")] | ||||
|     public int KeepAliveInterval { get; set; } = 3000; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 安全策略 | ||||
|     /// </summary> | ||||
|     [Description("安全策略")] | ||||
|     public bool IsUseSecurity { get; set; } = false; | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 加载服务端数据类型 | ||||
|     /// </summary> | ||||
|     [Description("加载服务端数据类型")] | ||||
|     public bool LoadType { get; set; } = true; | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public override string ToString() | ||||
|     { | ||||
|         return OPCUrl; | ||||
|     } | ||||
| } | ||||
| } | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,40 +8,11 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using Opc.Ua; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.OPCUA; | ||||
| 
 | ||||
| /// <summary> | ||||
| /// OPC UA的状态更新消息 | ||||
| /// </summary> | ||||
| public class OpcUaStatusEventArgs | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 日志等级,<br></br> | ||||
|     /// 更为详细的步骤型日志输出 Trace = 0,<br></br> | ||||
|     /// 调试信息日志Debug = 1,<br></br> | ||||
|     /// 消息类日志输出 Info = 2,<br></br> | ||||
|     /// 警告类日志输出 Warning = 3,<br></br> | ||||
|     /// 错误类日志输出 Error = 4,<br></br> | ||||
|     /// 不可控中断类日输出Critical = 5, | ||||
|     /// </summary> | ||||
|     public int LogLevel { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 时间 | ||||
|     /// </summary> | ||||
|     public DateTime Time { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 文本 | ||||
|     /// </summary> | ||||
|     public string Text { get; set; } | ||||
| } | ||||
| 
 | ||||
| /// <summary> | ||||
| /// 读取属性过程中用于描述的 | ||||
| /// </summary> | ||||
| @@ -52,7 +22,6 @@ public class OPCNodeAttribute | ||||
|     /// 属性的名称 | ||||
|     /// </summary> | ||||
|     public string Name { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 操作结果状态描述 | ||||
|     /// </summary> | ||||
| @@ -62,9 +31,10 @@ public class OPCNodeAttribute | ||||
|     /// 属性的类型描述 | ||||
|     /// </summary> | ||||
|     public string Type { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 属性的值,如果读取错误,返回文本描述 | ||||
|     /// </summary> | ||||
|     public object Value { get; set; } | ||||
| } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| @@ -1,14 +1,15 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk"> | ||||
| 
 | ||||
| 	<PropertyGroup> | ||||
| 		<TargetFrameworks>net48;net6.0;net8.0;</TargetFrameworks> | ||||
| 		<TargetFrameworks>net48;net6.0;net7.0</TargetFrameworks> | ||||
| 
 | ||||
| 	</PropertyGroup> | ||||
| 
 | ||||
| 	<ItemGroup> | ||||
| 		<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> | ||||
| 		<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client" Version="1.4.372.76" /> | ||||
| 		<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client.ComplexTypes" Version="1.4.372.76" /> | ||||
| 		<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client" Version="1.4.372.56" /> | ||||
| 		<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client.ComplexTypes" Version="1.4.372.56" /> | ||||
| 	</ItemGroup> | ||||
| 
 | ||||
| 
 | ||||
| </Project> | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.OPCUA; | ||||
| @@ -29,7 +27,6 @@ internal static class CollectionExtensions | ||||
|             @this.Remove(obj); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 异步Select | ||||
|     /// </summary> | ||||
| @@ -38,8 +35,9 @@ internal static class CollectionExtensions | ||||
|     /// <param name="source"></param> | ||||
|     /// <param name="selector"></param> | ||||
|     /// <returns></returns> | ||||
|     internal static async Task<TResult[]> SelectAsync<T, TResult>(this IEnumerable<T> source, Func<T, Task<TResult>> selector) | ||||
|     internal static Task<TResult[]> SelectAsync<T, TResult>(this IEnumerable<T> source, Func<T, Task<TResult>> selector) | ||||
|     { | ||||
|         return await Task.WhenAll(source.Select(selector)); | ||||
|         return Task.WhenAll(source.Select(selector)); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| @@ -121,6 +119,5 @@ internal static class DictionaryExtension | ||||
|     { | ||||
|         return dictionary.TryGetValue(tkey, out var value) ? value : default; | ||||
|     } | ||||
| 
 | ||||
|     #endregion 字典扩展 | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using Opc.Ua; | ||||
| @@ -18,7 +16,6 @@ using Opc.Ua.Client; | ||||
| using System.Text; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.OPCUA; | ||||
| 
 | ||||
| /// <summary> | ||||
| /// 辅助类 | ||||
| /// </summary> | ||||
| @@ -62,7 +59,7 @@ public class FormUtils | ||||
|                     // check for error. | ||||
|                     if (StatusCode.IsBad(results[ii].StatusCode)) | ||||
|                     { | ||||
|                         // this error indicates that the server does not have enough simultaneously active | ||||
|                         // this error indicates that the server does not have enough simultaneously active  | ||||
|                         // continuation points. This request will need to be resent after the other operations | ||||
|                         // have been completed and their continuation points released. | ||||
|                         if (results[ii].StatusCode == StatusCodes.BadNoContinuationPoints) | ||||
| @@ -185,6 +182,7 @@ public class FormUtils | ||||
| 
 | ||||
|                 for (int ii = 0; ii < nodesToBrowse.Count; ii++) | ||||
|                 { | ||||
| 
 | ||||
|                     // check if all references have been fetched. | ||||
|                     if (results[ii].References.Count == 0) | ||||
|                     { | ||||
| @@ -194,7 +192,7 @@ public class FormUtils | ||||
|                     // check for error. | ||||
|                     if (StatusCode.IsBad(results[ii].StatusCode)) | ||||
|                     { | ||||
|                         // this error indicates that the server does not have enough simultaneously active | ||||
|                         // this error indicates that the server does not have enough simultaneously active  | ||||
|                         // continuation points. This request will need to be resent after the other operations | ||||
|                         // have been completed and their continuation points released. | ||||
|                         if (results[ii].StatusCode == StatusCodes.BadNoContinuationPoints) | ||||
| @@ -205,10 +203,14 @@ public class FormUtils | ||||
|                         continue; | ||||
|                     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|                     // save results. | ||||
|                     references.AddRange(results[ii].References); | ||||
| 
 | ||||
|                 } | ||||
| 
 | ||||
| 
 | ||||
|                 while (continuationPoints.Any()) | ||||
|                 { | ||||
|                     // continue browse operation. | ||||
| @@ -236,8 +238,12 @@ public class FormUtils | ||||
|                             continue; | ||||
|                         } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|                         // save results. | ||||
|                         references.AddRange(results[ii].References); | ||||
| 
 | ||||
| 
 | ||||
|                     } | ||||
| 
 | ||||
|                     // check if browsing must continue; | ||||
| @@ -285,6 +291,7 @@ public class FormUtils | ||||
| 
 | ||||
|             // start the browse operation. | ||||
| 
 | ||||
| 
 | ||||
|             var result = await session.BrowseAsync( | ||||
|                   null, | ||||
|                   null, | ||||
| @@ -367,7 +374,7 @@ public class FormUtils | ||||
|                 BrowseDirection = BrowseDirection.Inverse, | ||||
|                 ReferenceTypeId = ReferenceTypeIds.HasSubtype, | ||||
|                 IncludeSubtypes = false, // more efficient to use IncludeSubtypes=False when possible. | ||||
|                 NodeClassMask = 0, // the HasSubtype reference already restricts the targets to Types. | ||||
|                 NodeClassMask = 0, // the HasSubtype reference already restricts the targets to Types.  | ||||
|                 ResultMask = (uint)BrowseResultMask.All | ||||
|             }; | ||||
| 
 | ||||
| @@ -564,7 +571,7 @@ public class FormUtils | ||||
|                     string discoveryUrl = servers[ii].DiscoveryUrls[jj]; | ||||
| 
 | ||||
|                     // Many servers will use the '/discovery' suffix for the discovery endpoint. | ||||
|                     // The URL without this prefix should be the base URL for the server. | ||||
|                     // The URL without this prefix should be the base URL for the server.  | ||||
|                     if (discoveryUrl.EndsWith("/discovery")) | ||||
|                     { | ||||
|                         discoveryUrl = discoveryUrl.Substring(0, discoveryUrl.Length - "/discovery".Length); | ||||
| @@ -726,7 +733,7 @@ public class FormUtils | ||||
|         { | ||||
|             EndpointDescriptionCollection endpoints = client.GetEndpoints(null); | ||||
| 
 | ||||
|             // select the best endpoint to use based on the selected URL and the UseSecurity checkbox. | ||||
|             // select the best endpoint to use based on the selected URL and the UseSecurity checkbox.  | ||||
|             for (int ii = 0; ii < endpoints.Count; ii++) | ||||
|             { | ||||
|                 EndpointDescription endpoint = endpoints[ii]; | ||||
| @@ -753,7 +760,7 @@ public class FormUtils | ||||
|                     // pick the first available endpoint by default. | ||||
|                     selectedEndpoint ??= endpoint; | ||||
| 
 | ||||
|                     // The security level is a relative measure assigned by the server to the | ||||
|                     // The security level is a relative measure assigned by the server to the  | ||||
|                     // endpoints that it returns. Clients should always pick the highest level | ||||
|                     // unless they have a reason not too. | ||||
|                     if (endpoint.SecurityLevel > selectedEndpoint.SecurityLevel) | ||||
| @@ -771,7 +778,7 @@ public class FormUtils | ||||
|         } | ||||
| 
 | ||||
|         // if a server is behind a firewall it may return URLs that are not accessible to the client. | ||||
|         // This problem can be avoided by assuming that the domain in the URL used to call | ||||
|         // This problem can be avoided by assuming that the domain in the URL used to call  | ||||
|         // GetEndpoints can be used to access any of the endpoints. This code makes that conversion. | ||||
|         // Note that the conversion only makes sense if discovery uses the same protocol as the endpoint. | ||||
| 
 | ||||
| @@ -824,6 +831,7 @@ public class FormUtils | ||||
| 
 | ||||
|         // make the call to the server. | ||||
| 
 | ||||
| 
 | ||||
|         var result = await session.TranslateBrowsePathsToNodeIdsAsync( | ||||
|             null, | ||||
|             browsePaths, | ||||
| @@ -863,7 +871,7 @@ public class FormUtils | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             // The targetId is an ExpandedNodeId because it could be node in another server. | ||||
|             // The targetId is an ExpandedNodeId because it could be node in another server.  | ||||
|             // The ToNodeId function is used to convert a local NodeId stored in a ExpandedNodeId to a NodeId. | ||||
|             nodes.Add(ExpandedNodeId.ToNodeId(target.TargetId, session.NamespaceUris)); | ||||
|         } | ||||
| @@ -1117,4 +1125,4 @@ public class FormUtils | ||||
|         } | ||||
|         return continuationPoints; | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,15 +8,14 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using System.Globalization; | ||||
| using System.IO; | ||||
| using System.Text; | ||||
| using System.Xml; | ||||
| 
 | ||||
| #pragma warning disable CS1591 // 缺少对公共可见类型或成员的 XML 注释 | ||||
| 
 | ||||
| namespace Opc.Ua | ||||
| { | ||||
|     public class OPCUAJsonEncoder : IJsonEncoder, IEncoder, IDisposable | ||||
| @@ -713,15 +711,12 @@ namespace Opc.Ua | ||||
|                 case IdType.Numeric: | ||||
|                     WriteUInt32("Id", (uint)value.Identifier); | ||||
|                     break; | ||||
| 
 | ||||
|                 case IdType.String: | ||||
|                     WriteString("Id", (string)value.Identifier); | ||||
|                     break; | ||||
| 
 | ||||
|                 case IdType.Guid: | ||||
|                     WriteGuid("Id", (Guid)value.Identifier); | ||||
|                     break; | ||||
| 
 | ||||
|                 case IdType.Opaque: | ||||
|                     WriteByteString("Id", (byte[])value.Identifier); | ||||
|                     break; | ||||
| @@ -1672,103 +1667,78 @@ namespace Opc.Ua | ||||
|                         case BuiltInType.Boolean: | ||||
|                             WriteBoolean(null, (bool)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.SByte: | ||||
|                             WriteSByte(null, (sbyte)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.Byte: | ||||
|                             WriteByte(null, (byte)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.Int16: | ||||
|                             WriteInt16(null, (short)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.UInt16: | ||||
|                             WriteUInt16(null, (ushort)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.Int32: | ||||
|                             WriteInt32(null, (int)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.UInt32: | ||||
|                             WriteUInt32(null, (uint)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.Int64: | ||||
|                             WriteInt64(null, (long)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.UInt64: | ||||
|                             WriteUInt64(null, (ulong)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.Float: | ||||
|                             WriteFloat(null, (float)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.Double: | ||||
|                             WriteDouble(null, (double)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.String: | ||||
|                             WriteString(null, (string)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.DateTime: | ||||
|                             WriteDateTime(null, (DateTime)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.Guid: | ||||
|                             WriteGuid(null, (Uuid)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.ByteString: | ||||
|                             WriteByteString(null, (byte[])value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.XmlElement: | ||||
|                             WriteXmlElement(null, (XmlElement)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.NodeId: | ||||
|                             WriteNodeId(null, (NodeId)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.ExpandedNodeId: | ||||
|                             WriteExpandedNodeId(null, (ExpandedNodeId)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.StatusCode: | ||||
|                             WriteStatusCode(null, (StatusCode)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.QualifiedName: | ||||
|                             WriteQualifiedName(null, (QualifiedName)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.LocalizedText: | ||||
|                             WriteLocalizedText(null, (LocalizedText)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.ExtensionObject: | ||||
|                             WriteExtensionObject(null, (ExtensionObject)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.DataValue: | ||||
|                             WriteDataValue(null, (DataValue)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.Enumeration: | ||||
|                             WriteEnumerated(null, (Enum)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.DiagnosticInfo: | ||||
|                             WriteDiagnosticInfo(null, (DiagnosticInfo)value); | ||||
|                             break; | ||||
| 
 | ||||
|                         case BuiltInType.Variant: | ||||
|                         case BuiltInType.Number: | ||||
|                         case BuiltInType.Integer: | ||||
| @@ -1833,99 +1803,75 @@ namespace Opc.Ua | ||||
|                     case BuiltInType.Boolean: | ||||
|                         WriteBooleanArray(fieldName, (bool[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.SByte: | ||||
|                         WriteSByteArray(fieldName, (sbyte[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.Byte: | ||||
|                         WriteByteArray(fieldName, (byte[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.Int16: | ||||
|                         WriteInt16Array(fieldName, (short[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.UInt16: | ||||
|                         WriteUInt16Array(fieldName, (ushort[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.Int32: | ||||
|                         WriteInt32Array(fieldName, (int[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.UInt32: | ||||
|                         WriteUInt32Array(fieldName, (uint[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.Int64: | ||||
|                         WriteInt64Array(fieldName, (long[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.UInt64: | ||||
|                         WriteUInt64Array(fieldName, (ulong[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.Float: | ||||
|                         WriteFloatArray(fieldName, (float[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.Double: | ||||
|                         WriteDoubleArray(fieldName, (double[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.String: | ||||
|                         WriteStringArray(fieldName, (string[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.DateTime: | ||||
|                         WriteDateTimeArray(fieldName, (DateTime[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.Guid: | ||||
|                         WriteGuidArray(fieldName, (Uuid[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.ByteString: | ||||
|                         WriteByteStringArray(fieldName, (byte[][])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.XmlElement: | ||||
|                         WriteXmlElementArray(fieldName, (XmlElement[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.NodeId: | ||||
|                         WriteNodeIdArray(fieldName, (NodeId[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.ExpandedNodeId: | ||||
|                         WriteExpandedNodeIdArray(fieldName, (ExpandedNodeId[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.StatusCode: | ||||
|                         WriteStatusCodeArray(fieldName, (StatusCode[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.QualifiedName: | ||||
|                         WriteQualifiedNameArray(fieldName, (QualifiedName[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.LocalizedText: | ||||
|                         WriteLocalizedTextArray(fieldName, (LocalizedText[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.ExtensionObject: | ||||
|                         WriteExtensionObjectArray(fieldName, (ExtensionObject[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.DataValue: | ||||
|                         WriteDataValueArray(fieldName, (DataValue[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.DiagnosticInfo: | ||||
|                         WriteDiagnosticInfoArray(fieldName, (DiagnosticInfo[])array); | ||||
|                         break; | ||||
| 
 | ||||
|                     case BuiltInType.Enumeration: | ||||
|                         { | ||||
|                             Array array6 = array as Array; | ||||
| @@ -2100,4 +2046,4 @@ namespace Opc.Ua | ||||
|             m_nestingLevel++; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
| 
 | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
| #endregion | ||||
| 
 | ||||
| using Newtonsoft.Json; | ||||
| @@ -18,11 +16,11 @@ using Newtonsoft.Json.Linq; | ||||
| using Opc.Ua; | ||||
| 
 | ||||
| using System.Collections; | ||||
| using System.IO; | ||||
| using System.Text; | ||||
| using System.Xml; | ||||
| 
 | ||||
| namespace ThingsGateway.Foundation.Adapter.OPCUA; | ||||
| 
 | ||||
| /// <summary> | ||||
| /// 扩展方法 | ||||
| /// </summary> | ||||
| @@ -42,11 +40,13 @@ public static class JsonUtils | ||||
|         JToken json | ||||
|     ) | ||||
|     { | ||||
| 
 | ||||
|         var data = DecoderObject(Context, dataTypeId, builtInType, valueRank, json); | ||||
|         var dataValue = new DataValue(new Variant(data)); | ||||
|         return dataValue; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 解析获取object | ||||
|     /// </summary> | ||||
| @@ -72,7 +72,6 @@ public static class JsonUtils | ||||
|                     } | ||||
|                 }.ToJsonString(); | ||||
|                 break; | ||||
| 
 | ||||
|             case BuiltInType.Variant: | ||||
|                 var type = TypeInfo.GetDataTypeId(GetSystemType(json.Type)); | ||||
|                 newData = new | ||||
| @@ -82,9 +81,9 @@ public static class JsonUtils | ||||
|                         Type = type.Identifier, | ||||
|                         Body = json | ||||
|                     } | ||||
| 
 | ||||
|                 }.ToJsonString(); | ||||
|                 break; | ||||
| 
 | ||||
|             default: | ||||
|                 newData = new | ||||
|                 { | ||||
| @@ -98,6 +97,8 @@ public static class JsonUtils | ||||
|         return data; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// DecodeRawData | ||||
|     /// </summary> | ||||
| @@ -151,10 +152,10 @@ public static class JsonUtils | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     #endregion | ||||
| 
 | ||||
|     #region Encode | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// OPCUAValue解析为Jtoken | ||||
|     /// </summary> | ||||
| @@ -192,6 +193,7 @@ public static class JsonUtils | ||||
|         bool includeDefaultNumbers = true | ||||
|         ) | ||||
|     { | ||||
| 
 | ||||
|         return new OPCUAJsonEncoder(context, useReversibleEncoding, topLevelIsArray, stream) | ||||
|         { | ||||
|             IncludeDefaultValues = includeDefaultValues, | ||||
| @@ -306,6 +308,7 @@ public static class JsonUtils | ||||
|                         return; | ||||
|                     } | ||||
| 
 | ||||
| 
 | ||||
|                 case BuiltInType.Guid: { encoder.WriteGuid(fieldName, (Uuid)value); return; } | ||||
|                 case BuiltInType.ByteString: { encoder.WriteByteString(fieldName, (byte[])value); return; } | ||||
|                 case BuiltInType.XmlElement: { encoder.WriteXmlElement(fieldName, (XmlElement)value); return; } | ||||
| @@ -355,7 +358,6 @@ public static class JsonUtils | ||||
|             encoder.WriteArray(fieldName, c, c.Rank, builtInType); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #endregion | ||||
| 
 | ||||
|     #region json | ||||
| @@ -380,7 +382,6 @@ public static class JsonUtils | ||||
|         } | ||||
|         return numDimensions; | ||||
|     } | ||||
| 
 | ||||
|     private static bool ElementsHasSameType(this JToken[] jTokens) | ||||
|     { | ||||
|         var checkType = jTokens[0].Type == JTokenType.Integer ? JTokenType.Float : jTokens[0].Type; | ||||
| @@ -395,7 +396,6 @@ public static class JsonUtils | ||||
|             throw new Exception("The array sent must have the same type of element in each dimension"); | ||||
|         return jTokens.First().Type; | ||||
|     } | ||||
| 
 | ||||
|     private static Type GetSystemType(JTokenType jsonType) | ||||
|     { | ||||
|         return jsonType switch | ||||
| @@ -425,7 +425,6 @@ public static class JsonUtils | ||||
|     #endregion | ||||
| 
 | ||||
|     #region Json序列化和反序列化 | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// 从字符串到json | ||||
|     /// </summary> | ||||
| @@ -530,6 +529,6 @@ public static class JsonUtils | ||||
|         else | ||||
|             return Newtonsoft.Json.JsonConvert.SerializeObject(item); | ||||
|     } | ||||
| 
 | ||||
|     #endregion Json序列化和反序列化 | ||||
| 
 | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user