Compare commits
633 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 39609693a8 | |||
| 774cc5951a | |||
| 4ce79a88c3 | |||
| d1dc1436bb | |||
| 3f889940b9 | |||
| 257ad739df | |||
| badd6d16f7 | |||
| 7d84defb68 | |||
| dd212d5c1b | |||
| 3b62b84bc2 | |||
| cc74087ba0 | |||
| 326c35cc0d | |||
| 04f1fee8ae | |||
| 6aec9fb10c | |||
| cb81d46e85 | |||
| e71b873a4c | |||
| c6e6d8b7c3 | |||
| cccebb9a66 | |||
| 696129e41a | |||
| 637ec4c26b | |||
| 3f668623d3 | |||
| 1d97c0e02a | |||
| 8ddca2eeea | |||
| 4caafd62ad | |||
| ab441ad981 | |||
| da00652d35 | |||
| dcae3b8499 | |||
| e6e596579e | |||
| 343e448836 | |||
| 50163d2e13 | |||
| a49852b92e | |||
| 7ff0836f38 | |||
| 42055e8c7e | |||
| b046ad72eb | |||
| 5da39b7f5f | |||
| 23dc550e20 | |||
| 7b65efea79 | |||
| 4a00b32c73 | |||
| 4e91e2c4e0 | |||
| fd5153fe97 | |||
| ce990fd1cc | |||
| a5ef08f0e0 | |||
| 3b237db585 | |||
| c3b2e7d0cf | |||
| c655fd5b04 | |||
| d660939ebf | |||
| 3626ccad99 | |||
| 7522d18a7b | |||
| 5933d31de8 | |||
| 35923f29e3 | |||
| 41449df7bf | |||
| 769fadd177 | |||
| 250d98b1c5 | |||
| 1b4d70330e | |||
| ae748ebeb2 | |||
| 789eb58590 | |||
| c81045df7e | |||
| c3a6fdd832 | |||
| e56cf745bc | |||
| 9a0211f82c | |||
| 09af4902be | |||
| d9a670bb6c | |||
| 8c5d331ed8 | |||
| 057be73c46 | |||
| badd1f0075 | |||
| 70dd210bb4 | |||
| 115a9c3cc3 | |||
| 49c22b57ad | |||
| 92a40b1045 | |||
| 021765948f | |||
| 71b338077e | |||
| 72951058ed | |||
| 59f38fe228 | |||
| bc1980e388 | |||
| 01c51fcb00 | |||
| 27875043b8 | |||
| 0e1607fc0e | |||
| 7b94368e7c | |||
| 230ad35316 | |||
| 3143bd5233 | |||
| 43647dd648 | |||
| 181db78f3d | |||
| 573375138b | |||
| 94edd54645 | |||
| 2c9c86d749 | |||
| c41d087fd6 | |||
| 6e7ea9935c | |||
| 353f1119b2 | |||
| 84dcd7553c | |||
| 2002516dfe | |||
| e71ecf1beb | |||
| c0718b0042 | |||
| 3c252aea7f | |||
| fd4528a0bc | |||
| cf7c57d116 | |||
| a13426f34a | |||
| 8927c74165 | |||
| 698087df93 | |||
| 4be2f3e91e | |||
| ce77787b11 | |||
| a61daa1e6b | |||
| a32217368b | |||
| 5912b7d414 | |||
| 3f0b2ec017 | |||
| 95c8d5be1b | |||
| 383f287610 | |||
| 0b638ce1e3 | |||
| 096ce418b0 | |||
| b0bbcab47e | |||
| d42b2681b8 | |||
| b36210876b | |||
| fbb5295b20 | |||
| e1bdfe7c71 | |||
| 535d3882dd | |||
| 3feb8dec87 | |||
| e63ec3abdd | |||
| 10ec2a8853 | |||
| 0bd15709aa | |||
| eda2d3a2bb | |||
| a8cca9f242 | |||
| 31fa4f7777 | |||
| ad4cd504a1 | |||
| 98890254e8 | |||
| 2bb37146dd | |||
| 78361306e8 | |||
| aa544a7ecd | |||
| a325c5154f | |||
| 113109b5e4 | |||
| 74db1d2c34 | |||
| 54d1a47a58 | |||
| f3a947fa72 | |||
| 00e8d0e8e5 | |||
| c9489f1ad3 | |||
| 3622aa9a54 | |||
| e6cf6b3b36 | |||
| 56fbf03bc8 | |||
| d53c2c7137 | |||
| 547cde5b0d | |||
| 6984c0b4eb | |||
| 9d4055714b | |||
| 9badb298eb | |||
| e671dbf9a1 | |||
| 477a80c7b9 | |||
| 47d60dc1ee | |||
| d3a2cb3ef3 | |||
| d5f29f5945 | |||
| ba53accf8b | |||
| d0afb435db | |||
| 3e664b4985 | |||
| 530b26d4d6 | |||
| 2ce90b4eaf | |||
| d3164aea0e | |||
| 98c7c254b0 | |||
| ed052304bf | |||
| e76d200971 | |||
| e8574c873c | |||
| 620ed9f332 | |||
| be65aaa7bb | |||
| 7c29fbce77 | |||
| 384a03b6f7 | |||
| 6a526e66c5 | |||
| e71add5378 | |||
| 5aba124eb4 | |||
| 556f34fe9c | |||
| e631d9fd08 | |||
| 89465ed44c | |||
| 74f8016fa0 | |||
| 961be55760 | |||
| e9000b6448 | |||
| c2d40c1e5a | |||
| bec5a56df2 | |||
| 7629ee8725 | |||
| 2245ba5c7e | |||
| fec802ca03 | |||
| 996e752460 | |||
| 44f451e50b | |||
| 36015d0945 | |||
| 9a0ba684bb | |||
| 32537390f4 | |||
| dee937990e | |||
| da92a09190 | |||
| f5dd2ad44d | |||
| 1792c6417f | |||
| 9bb67a368e | |||
| 32efb52d9d | |||
| 0284b50997 | |||
| 38401b75b5 | |||
| a0976ab148 | |||
| faca184aab | |||
| ce014431d2 | |||
| a7575d07a2 | |||
| d4d49650ec | |||
| cda2541d95 | |||
| 7f95ad697c | |||
| 82f00ac75e | |||
| 4305f17a3c | |||
| b68a7a833c | |||
| 282b0b4cd4 | |||
| e33bc2151a | |||
| 00acc83e42 | |||
| b86a6021bf | |||
| b8e8dd5b95 | |||
| 24f1432e56 | |||
| 2fea170463 | |||
| ad10f042dc | |||
| 7dc9d95cf8 | |||
| 1fe0cac4bd | |||
| e21f7ece07 | |||
| 6869a84fd4 | |||
| 399cc9654a | |||
| ecc14f75c6 | |||
| 863568a938 | |||
| cc17992917 | |||
| 777a3fe6dd | |||
| bd451a48a1 | |||
| 253b0bb9eb | |||
| f7c97c3208 | |||
| 6b38d86a4a | |||
| b5a2f742c6 | |||
| 730266d2ad | |||
| 493b9baa5c | |||
| 3dc7378e72 | |||
| b2d79ff194 | |||
| 7f37bca29f | |||
| 56919555e7 | |||
| 911f83f1ea | |||
| 286e3c1c12 | |||
| 09c9f37c62 | |||
| b0e8ec0dd4 | |||
| 135cb07f49 | |||
| 61021e25b9 | |||
| dd13d4e9f8 | |||
| c7876fe493 | |||
| 46fe731931 | |||
| 2d145a5e37 | |||
| b66f4fb239 | |||
| d6cc81a4a9 | |||
| c583d7785f | |||
| 11bc6566b5 | |||
| bed651f6df | |||
| cfaf57f34f | |||
| f7357aded9 | |||
| b354763cc4 | |||
| bc68faea09 | |||
| 904cafa91b | |||
| 661734d1df | |||
| 6bf82f6615 | |||
| d7c52768af | |||
| 372318a290 | |||
| 801441fd1a | |||
| beabadd2fc | |||
| dd9680a8ca | |||
| 1847419e7d | |||
| fecc44fda1 | |||
| d8071e3658 | |||
| 7945ce17c5 | |||
| f61f206208 | |||
| 10c3e68b45 | |||
| a86f113347 | |||
| 41d5129637 | |||
| 377711be19 | |||
| 249fd91834 | |||
| a635f46cff | |||
| 944cdde2b1 | |||
| d5c49c48b1 | |||
| 27b4d3aa70 | |||
| 54bd85ca85 | |||
| f89ce06f1b | |||
| 45a8526d57 | |||
| 710f082b34 | |||
| 289c2d5112 | |||
| 9721762a3e | |||
| ded55b9500 | |||
| a988fd00ea | |||
| 5f7d2ab1ae | |||
| ac759f53ee | |||
| 49002a4604 | |||
| 4f0a39ca11 | |||
| 7b0e29e0d4 | |||
| edb2cbaf62 | |||
| f6722af1cc | |||
| 613c4edba8 | |||
| c5b5b1148d | |||
| ebd3e075a4 | |||
| 0299d6a489 | |||
| c6ced5c089 | |||
| 3babbcd5f2 | |||
| 5f5a1dd5d7 | |||
| d24aa0ecb7 | |||
| 243d3bf90a | |||
| bfe4f413d7 | |||
| 993f068399 | |||
| cd3394244b | |||
| 25945b4f5a | |||
| 725caa2aa6 | |||
| 5d2f0ab0ca | |||
| 5b166bf7b5 | |||
| 38ec150449 | |||
| d470f435d3 | |||
| 40165e0c64 | |||
| 1be45ac909 | |||
| 91aa971693 | |||
| 432694fc7d | |||
| c615b81710 | |||
| 948675e24c | |||
| 96348e0964 | |||
| 9732cdd84a | |||
| 7b6a24cb2a | |||
| 294896905e | |||
| b351936996 | |||
| 5bb817f94c | |||
| 8f843ffc9b | |||
| 4315091e9d | |||
| 513e4a6dd6 | |||
| 5030ee84b9 | |||
| de9e0c780d | |||
| b8bc8a4854 | |||
| 65852999bd | |||
| 1b368c63a8 | |||
| fb7edefcb0 | |||
| ebf6f8e144 | |||
| 016c328e23 | |||
| b3134ab4dc | |||
| 7e93ca846e | |||
| 92f725cf47 | |||
| 6f502f0b59 | |||
| 06634615c1 | |||
| d66ec9016c | |||
| 635196dc9a | |||
| b76694842c | |||
| 40c03732bb | |||
| 5fe7abaadf | |||
| c62674bd0a | |||
| 35ad29f4f3 | |||
| d149c4dbe3 | |||
| f3ab3949ca | |||
| 2253c5918b | |||
| d6a469d9b4 | |||
| bcba036b16 | |||
| c96991fbc1 | |||
| c70495ee18 | |||
| 4b4c8231f8 | |||
| ebe422f21b | |||
| c3466de7f5 | |||
| 9120c31869 | |||
| f1a43ae999 | |||
| 741e09d986 | |||
| 3442c1a2b9 | |||
| 43c4271cc5 | |||
| a660b8a406 | |||
| 8a8ecb3aec | |||
| 7dd7fd9604 | |||
| 0cfe49811a | |||
| 050af15d7c | |||
| 1046c1d72a | |||
| db66d337a1 | |||
| 866ab6391d | |||
| 927b5faf79 | |||
| 04465727cc | |||
| 4a554c4029 | |||
| f0ad53686e | |||
| 49bdfa2e2a | |||
| 40c3a6afff | |||
| eeb5c5fed6 | |||
| 239ed38adc | |||
| 6e617dedc3 | |||
| efb310f229 | |||
| 98c5be3517 | |||
| c1795433f6 | |||
| 19b2368941 | |||
| 740d50c95d | |||
| a7e0c63c87 | |||
| be70f5f0e1 | |||
| 2d375ebaef | |||
| 667b6ea242 | |||
| d57c062bfe | |||
| 135c19d09d | |||
| 3461efaf76 | |||
| 0a1f92ae74 | |||
| 10a881b717 | |||
| 4634a99f40 | |||
| 776d86e543 | |||
| fc17120a30 | |||
| 5dc28c4dcc | |||
| 27fd5f1759 | |||
| 77092c9f90 | |||
| 126abfc945 | |||
| a4abf98adb | |||
| 490d6e2dfc | |||
| c326761960 | |||
| 424fc11fc1 | |||
| 72fb70093d | |||
| d483f23d4f | |||
| 37305a5ea8 | |||
| 87b159b167 | |||
| 4f4eafd5a2 | |||
| fd9df11711 | |||
| 275061adb6 | |||
| c77f7fa185 | |||
| 23524c902c | |||
| d958358e05 | |||
| 2f4c072d8f | |||
| fce7996f7c | |||
| daf686b39d | |||
| 96fcdcd150 | |||
| 31ba7eee6c | |||
| 1bac8b33e0 | |||
| 97529ee444 | |||
| 7317c5d39c | |||
| cf161344a6 | |||
| d27dbbeb07 | |||
| fc36b427c4 | |||
| 4dc2eb96ba | |||
| f84fca1bc9 | |||
| 8927378fdf | |||
| f96ba8388b | |||
| eeb48a40a9 | |||
| c401c15932 | |||
| 41d6f4153a | |||
| 43c3fe4582 | |||
| 29c691d81c | |||
| a750cb9687 | |||
| d459f4c5c0 | |||
| e085328da8 | |||
| 67ff5e7b34 | |||
| a3366188fc | |||
| 80958607ab | |||
| bfee15d1af | |||
| 74250d1333 | |||
| 749d633704 | |||
| 9c424aa40c | |||
| cb8a707304 | |||
| abf74fb2f5 | |||
| bd93e43550 | |||
| bdeb392a81 | |||
| 26dfd637cb | |||
| eacac2a1e6 | |||
| 66c83abd01 | |||
| c38551d72c | |||
| 89619d9152 | |||
| f710080d5d | |||
| b9e05634dd | |||
| a537e28609 | |||
| a07c21516e | |||
| 0bf60e8ac2 | |||
| 3c3cb0611f | |||
| 3783dd519f | |||
| 0a097daa7c | |||
| aeddb6af98 | |||
| 973e0f63e9 | |||
| bfedbd6c9d | |||
| 4964854038 | |||
| cbf778217b | |||
| 1c0b9b510f | |||
| 7600ee8563 | |||
| 3503f01d82 | |||
| ace5b46440 | |||
| 71e9e450c5 | |||
| c2274329cc | |||
| ed8d3b2a34 | |||
| 6f01d4232b | |||
| ebabae204b | |||
| bbfad99ebc | |||
| 43ba19468f | |||
| e878bcd4db | |||
| 2fe6f46a85 | |||
| 03b618f64d | |||
| a623b4f2db | |||
| 9857de0f1a | |||
| c1f61a30c3 | |||
| f660cccc6d | |||
| 2d7152d08b | |||
| 0134e6ae09 | |||
| 4308bf4b17 | |||
| 1748df69f4 | |||
| 609fe74da6 | |||
| 0dff589980 | |||
| 865584761b | |||
| c24af86f7e | |||
| fb36448455 | |||
| 0a2f92368c | |||
| 7930ce273f | |||
| c9f768beb2 | |||
| 6775bb5dfa | |||
| 7c94aac352 | |||
| f6f7b18186 | |||
| fcbd718a17 | |||
| 05c26f4e53 | |||
| d798e91055 | |||
| dcbcecc435 | |||
| 58c27bedd6 | |||
| 46d6ae7ae2 | |||
| 5586dcfede | |||
| 010ca67d6e | |||
| 0ac05c7e70 | |||
| a45b93a177 | |||
| 651a83b8ea | |||
| 2c7ffaeb04 | |||
| eec7e04588 | |||
| 252b780d15 | |||
| 748e5a9062 | |||
| 1d2ee6dda5 | |||
| 7539af9d97 | |||
| ab335bc203 | |||
| 4a886d0ad5 | |||
| 53c315b9ba | |||
| 3b29876ee6 | |||
| 2da7b0622e | |||
| 4b975290f5 | |||
| 987efafd7a | |||
| 18efe25a9b | |||
| 609241bc6c | |||
| 1f8c8bd542 | |||
| 7fd47cf51b | |||
| b8f7e06e2b | |||
| c0f73e1e9e | |||
| cfff0b66a8 | |||
| 6bc6938e56 | |||
| 8e90c2f21f | |||
| c058408420 | |||
| f0ff191393 | |||
| 3775aacc4d | |||
| 43c1d8c233 | |||
| 02e93e0d4e | |||
| dac29e3b38 | |||
| 949614aa18 | |||
| e7654f3ed4 | |||
| db0ab39ff5 | |||
| 4988f3db7f | |||
| 6082c859d1 | |||
| 223389b594 | |||
| 038ffd15ad | |||
| 5cdd5357a7 | |||
| 6591b1da85 | |||
| 5b6f9af4f1 | |||
| 2158a460de | |||
| a50741f567 | |||
| 869d5fc1fb | |||
| a42a312967 | |||
| 0de0388664 | |||
| 35c896dd48 | |||
| 0e99c169b3 | |||
| 8ed41a21b4 | |||
| 56d0f7152d | |||
| 7033420c8c | |||
| 7f66ab097d | |||
| 4e4ec6980d | |||
| d941a7eddf | |||
| ae9cc2c429 | |||
| 1b4e7a9e8b | |||
| 0474778424 | |||
| 2477afe3bd | |||
| 9fc2d86bf4 | |||
| 80f1ac2e04 | |||
| 949a513d05 | |||
| 29c09ccb6f | |||
| 1c4b1f4a3e | |||
| 27cfbcccc7 | |||
| e67bb0e765 | |||
| abceb4e187 | |||
| 3b410f3908 | |||
| b9a69a55d2 | |||
| 80864f2b35 | |||
| 03f811de57 | |||
| 857b14e3ae | |||
| 65888b1fcd | |||
| 88c7ee46df | |||
| cbafcfe65d | |||
| 52dc369992 | |||
| 6fc0855626 | |||
| ed573897d6 | |||
| ba845fa78c | |||
| 44dc85c08b | |||
| 0e23351b7c | |||
| 78b897ce67 | |||
| 694d4cb0b5 | |||
| 3c3156ed9f | |||
| 5d9f0e59df | |||
| 23d5ebe83b | |||
| 8a0f445b39 | |||
| a48e444fe2 | |||
| 4bfe039623 | |||
| 195f187ba8 | |||
| 3cebac853b | |||
| 42f01f14af | |||
| 4e882ea3cb | |||
| 3afe990365 | |||
| 2ffa502538 | |||
| 7e941aec34 | |||
| e7c73cbce1 | |||
| 6a8ad2604f | |||
| a87fee41f5 | |||
| 67c8e883fe | |||
| 37ee6f5997 | |||
| 4f0e2d9aa5 | |||
| ccd3ed8c45 | |||
| cbf72f2558 | |||
| d41722f200 | |||
| be7515b16c | |||
| 89fd608eef | |||
| cf310ab003 | |||
| 5177f412de | |||
| ccbb6fa644 | |||
| dd3491af16 | |||
| 1403daffd6 | |||
| 1a9f6c810b | |||
| a4841dd8bc | |||
| 76d25bc727 | |||
| 1472c178b1 | |||
| 731d8c6400 | |||
| 998afbbd7e | |||
| d2c0761f7b | |||
| f2b24aa3ea | |||
| 7023ef1609 | |||
| 19cfeff468 | |||
| aa0f847aa3 | |||
| 0f32dc64bd | |||
| 699e07e61f | |||
| 9edb343d40 | |||
| 3a6dc1b08e | |||
| 913d148545 | |||
| 4ff531e435 | |||
| 8eed5081c9 | |||
| 5b40dd70f1 | |||
| f2f733e6ee | |||
| 7173e6e90a | |||
| afda7d6221 | |||
| 5587e9efca | |||
| 83634c7788 | |||
| e3c7cb356c | |||
| dfb2dd4c5c | |||
| 8e2a9634d1 | |||
| 06cd6ffa05 |
+7
-8
@@ -7,13 +7,12 @@
|
||||
#--------------------------------
|
||||
# aree temp: log/bin/obj
|
||||
#--------------------------------
|
||||
/*/*/bin/*
|
||||
/*/*/obj/*
|
||||
/*/*/logs/*.txt
|
||||
/*/*/logs/*.log
|
||||
/*/*/logs/*.zip
|
||||
|
||||
|
||||
/*/bin/*
|
||||
/*/obj/*
|
||||
/*/logs/*.txt
|
||||
/*/logs/*.log
|
||||
/*/logs/*.zip
|
||||
/*/logs/*.json
|
||||
|
||||
# ---> VisualStudio
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
@@ -346,4 +345,4 @@ UpgradeLog*.XML
|
||||
|
||||
|
||||
.fake
|
||||
.ionide
|
||||
.ionide
|
||||
|
||||
+266
-89
@@ -1,118 +1,295 @@
|
||||
variables:
|
||||
VERS_MAIN: '0.9'
|
||||
NEW_REL: ''
|
||||
APP_NAME: ''
|
||||
APP_CONF: 'Release'
|
||||
|
||||
# Step esecuzione script powershell x code obfuscation (tool install + esecuzione)
|
||||
.obfuscate: &obfuscate
|
||||
- |
|
||||
obfuscate.ps1
|
||||
|
||||
# helper x fix pacchetti nuget da repo locale nexus.steamware.net
|
||||
.nuget-fix: &nuget-fix
|
||||
- |
|
||||
$hasSource = C:\Tools\nuget.exe sources list | find "`"Steamware Nexus`"" /C
|
||||
if ($hasSource -eq 0) {
|
||||
C:\Tools\nuget.exe sources Add -Name "`"Steamware Nexus`"" -Source http://nexus.steamware.net/repository/nuget-group -username "`"nugetUser`"" -password "`"viaDante16`""
|
||||
C:\Tools\nuget.exe sources Add -Name "`"Steamware Nexus`"" -Source https://nexus.steamware.net/repository/nuget-group -username "`"nugetUser`"" -password "`"viaDante16`"" -StorePasswordInClearText
|
||||
} else {
|
||||
C:\Tools\nuget.exe sources Update -Name "`"Steamware Nexus`"" -Source http://nexus.steamware.net/repository/nuget-group -username "`"nugetUser`"" -password "`"viaDante16`""
|
||||
C:\Tools\nuget.exe sources Update -Name "`"Steamware Nexus`"" -Source https://nexus.steamware.net/repository/nuget-group -username "`"nugetUser`"" -password "`"viaDante16`"" -StorePasswordInClearText
|
||||
}
|
||||
echo $hasSource
|
||||
|
||||
# helper creazione hash files x IIS
|
||||
.hashBuild: &hashBuild
|
||||
- |
|
||||
$Target = "$env:APP_NAME\Releases\" + $CI_COMMIT_BRANCH + "\" + $env:APP_NAME + ".zip"
|
||||
$MD5 = Get-FileHash $Target -Algorithm MD5
|
||||
$SHA1 = Get-FileHash $Target -Algorithm SHA1
|
||||
New-Item $Target".md5"
|
||||
New-Item $Target".sha1"
|
||||
$MD5.Hash | Set-Content -Path $Target".md5"
|
||||
$SHA1.Hash | Set-Content -Path $Target".sha1"
|
||||
|
||||
echo "Created HASH files for $Target"
|
||||
|
||||
# helper x send su NEXUS x pack
|
||||
.nexusUpload: &nexusUpload
|
||||
- |
|
||||
Set-Alias mCurl C:\Windows\system32\curl.exe
|
||||
$currentDate = get-date -format yyMM;
|
||||
$currentTime = get-date -format ddHH;
|
||||
$fileVers = $env:APP_NAME + "\Resources\VersNum.txt"
|
||||
$VersNumb = Get-Content $fileVers
|
||||
echo "Curr Version: $VersNumb"
|
||||
if($CI_COMMIT_BRANCH -eq "main")
|
||||
{
|
||||
$version = "stable"
|
||||
}
|
||||
else
|
||||
{
|
||||
$version = "unstable"
|
||||
}
|
||||
$File2Send = Get-ChildItem("$env:APP_NAME\Releases\" + $CI_COMMIT_BRANCH + "\*")
|
||||
ForEach ($File in $File2Send) {
|
||||
$FileName = Split-Path $File -leaf
|
||||
mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file $File https://nexus.steamware.net/repository/SWS/$env:APP_NAME/$version/LAST/$FileName
|
||||
mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file $File https://nexus.steamware.net/repository/SWS/$env:APP_NAME/$version/ARCHIVE/$VersNumb/$FileName
|
||||
echo "mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file $File https://nexus.steamware.net/repository/SWS/$env:APP_NAME/$version/LAST/$FileName"
|
||||
}
|
||||
mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file "$env:APP_NAME\Resources\manifest.xml" https://nexus.steamware.net/repository/SWS/$env:APP_NAME/$version/LAST/manifest.xml
|
||||
mCurl -v -u GitLab:$NEXUS_PASSWD --upload-file "$env:APP_NAME\Resources\ChangeLog.html" https://nexus.steamware.net/repository/SWS/$env:APP_NAME/$version/LAST/ChangeLog.html
|
||||
|
||||
# helper creazione files zip x app console
|
||||
.artifactZipper: &artifactZipper
|
||||
- |
|
||||
$7zipPath = $env:ProgramFiles+"\7-Zip\7z.exe"
|
||||
if (-not (Test-Path -Path $7zipPath -PathType Leaf)) {
|
||||
throw "7 zip file '$7zipPath' not found"
|
||||
}
|
||||
Set-Alias 7zip $7zipPath
|
||||
$Target = "$env:APP_NAME\Releases\" + $CI_COMMIT_BRANCH + "\" + $env:APP_NAME + ".zip"
|
||||
$Source = "$env:APP_NAME\bin\$env:APP_CONF\net6.0\publish\win-x64\*"
|
||||
7zip a -tzip $Target $Source -xr!DATA
|
||||
echo "called ZIP $Source --> $Target"
|
||||
|
||||
# helper copia pubblicati in dir x upload
|
||||
.artifactMover: &artifactMover
|
||||
- |
|
||||
$Target = "$env:APP_NAME\Releases\" + $CI_COMMIT_BRANCH + "\"
|
||||
$Source = "$env:APP_NAME\bin\publish\net6.0\"
|
||||
ROBOCOPY $Source $Target /MIR
|
||||
echo "called ROBOCOPY $Source --> $Target"
|
||||
|
||||
|
||||
stages:
|
||||
- build
|
||||
- staging
|
||||
- deploy
|
||||
- release
|
||||
|
||||
|
||||
UI:build:
|
||||
stage: build
|
||||
tags:
|
||||
- win
|
||||
before_script:
|
||||
- *nuget-fix
|
||||
- dotnet restore MP.MONO.ALL.sln
|
||||
script:
|
||||
- dotnet build MP.MONO.UI/MP.MONO.UI.csproj
|
||||
- pack
|
||||
|
||||
SIM:build:
|
||||
ADAPTER:build:
|
||||
stage: build
|
||||
tags:
|
||||
- win
|
||||
variables:
|
||||
APP_NAME: MP.MONO.ADAPTER.OPC
|
||||
before_script:
|
||||
- *nuget-fix
|
||||
- dotnet restore MP.MONO.ALL.sln
|
||||
script:
|
||||
- dotnet build MP.MONO.SIM/MP.MONO.SIM.csproj
|
||||
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
|
||||
|
||||
# UI:staging:
|
||||
# stage: staging
|
||||
# tags:
|
||||
# - win
|
||||
# only:
|
||||
# - develop
|
||||
# needs: ["UI:build"]
|
||||
# script:
|
||||
# - dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.MONO.UI/MP.MONO.UI.csproj
|
||||
DECODER:build:
|
||||
stage: build
|
||||
tags:
|
||||
- win
|
||||
variables:
|
||||
APP_NAME: MP.MONO.DECODER
|
||||
before_script:
|
||||
- *nuget-fix
|
||||
- dotnet restore MP.MONO.ALL.sln
|
||||
script:
|
||||
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
|
||||
|
||||
# SIM:staging:
|
||||
# stage: staging
|
||||
# tags:
|
||||
# - win
|
||||
# only:
|
||||
# - develop
|
||||
# needs: ["SIM:build"]
|
||||
# script:
|
||||
# - dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.MONO.SIM/MP.MONO.SIM.csproj
|
||||
SIM:build:
|
||||
stage: build
|
||||
tags:
|
||||
- win
|
||||
variables:
|
||||
APP_NAME: MP.MONO.SIM
|
||||
before_script:
|
||||
- *nuget-fix
|
||||
- dotnet restore MP.MONO.ALL.sln
|
||||
script:
|
||||
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
|
||||
|
||||
|
||||
# UI:deploy:
|
||||
# stage: deploy
|
||||
# tags:
|
||||
# - win
|
||||
# only:
|
||||
# - main
|
||||
# needs: ["UI:build"]
|
||||
# script:
|
||||
# # IIS 02
|
||||
# - dotnet publish -p:PublishProfile=IIS02.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.MONO.UI/MP.MONO.UI.csproj
|
||||
# # IIS DEV
|
||||
# - dotnet publish -p:PublishProfile=IIS03.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.MONO.UI/MP.MONO.UI.csproj
|
||||
|
||||
# SIM:deploy:
|
||||
# stage: deploy
|
||||
# tags:
|
||||
# - win
|
||||
# only:
|
||||
# - main
|
||||
# needs: ["SIM:build"]
|
||||
# script:
|
||||
# # IIS 02
|
||||
# - dotnet publish -p:PublishProfile=IIS02.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.MONO.SIM/MP.MONO.SIM.csproj
|
||||
# # IIS DEV
|
||||
# - dotnet publish -p:PublishProfile=IIS03.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true MP.MONO.SIM/MP.MONO.SIM.csproj
|
||||
|
||||
# UI:release:
|
||||
# stage: release
|
||||
# tags:
|
||||
# - win
|
||||
# only:
|
||||
# - main
|
||||
# except:
|
||||
# - branches
|
||||
# needs: ["UI:build"]
|
||||
# artifacts:
|
||||
# paths:
|
||||
# - publish/
|
||||
# script:
|
||||
# - dotnet publish -c Release -o ./publish MP.MONO.UI/MP.MONO.UI.csproj
|
||||
UI:build:
|
||||
stage: build
|
||||
tags:
|
||||
- win
|
||||
variables:
|
||||
APP_NAME: MP.MONO.UI
|
||||
before_script:
|
||||
- *nuget-fix
|
||||
- dotnet restore MP.MONO.ALL.sln
|
||||
script:
|
||||
- dotnet build $env:APP_NAME/$env:APP_NAME.csproj
|
||||
|
||||
# SIM:release:
|
||||
# stage: release
|
||||
# tags:
|
||||
# - win
|
||||
# only:
|
||||
# - main
|
||||
# except:
|
||||
# - branches
|
||||
# needs: ["SIM:build"]
|
||||
# artifacts:
|
||||
# paths:
|
||||
# - publish/
|
||||
# script:
|
||||
# - dotnet publish -c Release -o ./publish MP.MONO.SIM/MP.MONO.SIM.csproj
|
||||
UI:staging:
|
||||
stage: staging
|
||||
tags:
|
||||
- win
|
||||
variables:
|
||||
APP_NAME: MP.MONO.UI
|
||||
only:
|
||||
- develop
|
||||
needs: ["UI:build"]
|
||||
script:
|
||||
- dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true $env:APP_NAME/$env:APP_NAME.csproj
|
||||
|
||||
UI:deploy:
|
||||
stage: deploy
|
||||
tags:
|
||||
- win
|
||||
variables:
|
||||
APP_NAME: MP.MONO.UI
|
||||
only:
|
||||
- main
|
||||
needs: ["UI:build"]
|
||||
script:
|
||||
# IIS02
|
||||
- dotnet publish -p:PublishProfile=IIS02.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true $env:APP_NAME/$env:APP_NAME.csproj
|
||||
# IIS04
|
||||
- dotnet publish -p:PublishProfile=IIS04.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=viadante16 -p:AllowUntrustedCertificate=true $env:APP_NAME/$env:APP_NAME.csproj
|
||||
|
||||
|
||||
ADAPTER:packDebug:
|
||||
stage: pack
|
||||
tags:
|
||||
- win
|
||||
only:
|
||||
- develop
|
||||
variables:
|
||||
APP_NAME: MP.MONO.ADAPTER.OPC
|
||||
APP_CONF: Debug
|
||||
needs: ["ADAPTER:build"]
|
||||
script:
|
||||
- dotnet publish -p:PublishProfile=SingleAppDebug.pubxml -p:RunCodeAnalysis=false -p:Configuration=$env:APP_CONF $env:APP_NAME/$env:APP_NAME.csproj
|
||||
- *artifactZipper
|
||||
- *hashBuild
|
||||
- *nexusUpload
|
||||
|
||||
DECODER:packDebug:
|
||||
stage: pack
|
||||
tags:
|
||||
- win
|
||||
only:
|
||||
- develop
|
||||
variables:
|
||||
APP_NAME: MP.MONO.DECODER
|
||||
APP_CONF: Debug
|
||||
needs: ["DECODER:build"]
|
||||
script:
|
||||
- dotnet publish -p:PublishProfile=SingleAppDebug.pubxml -p:RunCodeAnalysis=false -p:Configuration=$env:APP_CONF $env:APP_NAME/$env:APP_NAME.csproj
|
||||
- *artifactZipper
|
||||
- *hashBuild
|
||||
- *nexusUpload
|
||||
|
||||
SIM:packDebug:
|
||||
stage: pack
|
||||
tags:
|
||||
- win
|
||||
only:
|
||||
- develop
|
||||
variables:
|
||||
APP_NAME: MP.MONO.SIM
|
||||
APP_CONF: Debug
|
||||
needs: ["SIM:build"]
|
||||
script:
|
||||
- dotnet publish -p:PublishProfile=SingleAppDebug.pubxml -p:RunCodeAnalysis=false -p:Configuration=$env:APP_CONF $env:APP_NAME/$env:APP_NAME.csproj
|
||||
- *artifactZipper
|
||||
- *hashBuild
|
||||
- *nexusUpload
|
||||
|
||||
UI:packDebug:
|
||||
stage: pack
|
||||
tags:
|
||||
- win
|
||||
only:
|
||||
- develop
|
||||
variables:
|
||||
APP_NAME: MP.MONO.UI
|
||||
APP_CONF: Debug
|
||||
needs: ["UI:build"]
|
||||
script:
|
||||
- dotnet publish -p:PublishProfile=IISProfile.pubxml -p:RunCodeAnalysis=false -p:Configuration=$env:APP_CONF $env:APP_NAME/$env:APP_NAME.csproj -o:publish
|
||||
- *artifactMover
|
||||
- *hashBuild
|
||||
- *nexusUpload
|
||||
|
||||
|
||||
ADAPTER:packRelease:
|
||||
stage: pack
|
||||
tags:
|
||||
- win
|
||||
only:
|
||||
- main
|
||||
variables:
|
||||
APP_NAME: MP.MONO.ADAPTER.OPC
|
||||
APP_CONF: Release
|
||||
needs: ["ADAPTER:build"]
|
||||
script:
|
||||
- dotnet publish -p:PublishProfile=SingleApp.pubxml -p:RunCodeAnalysis=false -p:Configuration=$env:APP_CONF $env:APP_NAME/$env:APP_NAME.csproj
|
||||
- *artifactZipper
|
||||
- *hashBuild
|
||||
- *nexusUpload
|
||||
|
||||
DECODER:packRelease:
|
||||
stage: pack
|
||||
tags:
|
||||
- win
|
||||
only:
|
||||
- main
|
||||
variables:
|
||||
APP_NAME: MP.MONO.DECODER
|
||||
APP_CONF: Release
|
||||
needs: ["DECODER:build"]
|
||||
script:
|
||||
- dotnet publish -p:PublishProfile=SingleApp.pubxml -p:RunCodeAnalysis=false -p:Configuration=$env:APP_CONF $env:APP_NAME/$env:APP_NAME.csproj
|
||||
- *artifactZipper
|
||||
- *hashBuild
|
||||
- *nexusUpload
|
||||
|
||||
SIM:packRelease:
|
||||
stage: pack
|
||||
tags:
|
||||
- win
|
||||
only:
|
||||
- main
|
||||
variables:
|
||||
APP_NAME: MP.MONO.SIM
|
||||
APP_CONF: Release
|
||||
needs: ["SIM:build"]
|
||||
script:
|
||||
- dotnet publish -p:PublishProfile=SingleApp.pubxml -p:RunCodeAnalysis=false -p:Configuration=$env:APP_CONF $env:APP_NAME/$env:APP_NAME.csproj
|
||||
- *artifactZipper
|
||||
- *hashBuild
|
||||
- *nexusUpload
|
||||
|
||||
UI:packRelease:
|
||||
stage: pack
|
||||
tags:
|
||||
- win
|
||||
only:
|
||||
- main
|
||||
variables:
|
||||
APP_NAME: MP.MONO.UI
|
||||
APP_CONF: Release
|
||||
needs: ["UI:build"]
|
||||
script:
|
||||
- dotnet publish -p:PublishProfile=IISProfile.pubxml -p:RunCodeAnalysis=false -p:Configuration=$env:APP_CONF $env:APP_NAME/$env:APP_NAME.csproj -o:publish
|
||||
- *artifactMover
|
||||
- *hashBuild
|
||||
- *nexusUpload
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
Gestione veto registrazione intervento
|
||||
Manutenzione: impostare il valore come % della vita residua MINIMO, es 95% --> significa che anche se resta 95% del tempo --> permetto di fare manutenzione
|
||||
|
||||
|
||||
nuovi stati da aggiungere...
|
||||
Serve una gestione dal plc x indicare carico vuoto oppure scarico pieno, questo deve dare un segnale di stato/modo che si possa interpretare sul decoder e riportare. Va fatto forse no su impulso ma su un segnale che duri ALMENO 5-10 secondi
|
||||
|
||||
|
||||
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
# 1. MyToDo
|
||||
|
||||
**Table of Content**
|
||||
|
||||
- [1. MyToDo](#1-mytodo)
|
||||
- [2. Progetto generale pagina MyToDo](#2-progetto-generale-pagina-mytodo)
|
||||
- [3. Utilizzo della pagina](#3-utilizzo-della-pagina)
|
||||
- [3.1 Assegnazione ruoli](#31-assegnazione-ruoli)
|
||||
- [3.2 Creazione lista (Contenitore task)](#32-creazione-lista-contenitore-task)
|
||||
- [3.3 Creazione task](#33-creazione-task)
|
||||
- [4. Document revision](#4-document-revision)
|
||||
|
||||
|
||||
|
||||
|
||||
# 2. Progetto generale pagina MyToDo
|
||||
|
||||
La pagina MyToDo all'interno del progetto MAPO-MONO permetterà di avere un sistema di schede per inserire dei promemoria basati a tempo e che abbiano uno schema colori basato sulla scadenza o sullo stato.
|
||||
|
||||
# 3. Utilizzo della pagina
|
||||
|
||||
## 3.1 Assegnazione ruoli
|
||||
Il SuperAdmin dovrà assegnare l'amministratore dell'azienda che potrà a sua volta gestire gli utenti interni all'azienda di cui fa parte
|
||||
|
||||
**Tabella dei ruoli**
|
||||
| Ruolo | Livello |Permessi |
|
||||
|---|---|---|
|
||||
| Utente azienda | 0 |Possono vedere solo le proprie attività (o crearne una per se) e segnarle come fatte
|
||||
| Admin azienda | 1 | Può creare, modificare ed eliminare i tasks per se o per gli utenti azienda, e gestire gli utenti interni (Creare modificare o eliminare un utente).
|
||||
| Superadmin | 2 | Può visualizzare tutti i dati degli utenti e delle varie aziende.
|
||||
|
||||
|
||||
E' prevista la possibilità **per tutti** di:
|
||||
- Creare un task.
|
||||
- Assegnare ALTRI UTENTI ad un task (1/+), nessun limite (di conseguenza modifiche punti seguenti)
|
||||
- Modificare un task .
|
||||
- Eliminare un task .
|
||||
- Dichiarare un task concluso.
|
||||
- Assegnare 1/+ etichette ai task.
|
||||
- Archiviare un task.
|
||||
- Copiare un task.
|
||||
|
||||
OGNI UTENTE PUO' OPERARE SU OGNI TASK (non c'è limite in base a chi crea/chi modifica)
|
||||
|
||||
L'eliminazione del task sarà sempre una cancellazione logica per evitare cancellazioni errate se lo stato è successivo a quello iniziale (creato).
|
||||
|
||||
|
||||
|
||||
**Ipotesi**: L'utente può richiedere di ricevere notifiche sul task selezionato (Mail o altro...)
|
||||
|
||||
## 3.2 Creazione lista (Contenitore task)
|
||||
Per creare una lista è necessario assegnare un titolo.
|
||||
|
||||
Si possono aggiungere collaboratori direttamente alla lista così da poter condividere automaticamente tutti i task presenti nel contenitore.
|
||||
|
||||
## 3.3 Creazione task
|
||||
|
||||
Per ogni task vanno definiti:
|
||||
- Titolo
|
||||
- Data e ora di inizio
|
||||
- Data e ora di scadenza
|
||||
- Descrizione del task
|
||||
- Etichetta (che può magari indicare l'area di produzione che riguarda il task o il nome del cliente ecc..)
|
||||
|
||||
Inoltre si potranno aggiungere collaboratori al task oppure assegnare un task ad un dipendente.
|
||||
|
||||
Un task può essere nei seguenti stati:
|
||||
- Creato
|
||||
- Avviato
|
||||
- In esecuzione
|
||||
- Completato
|
||||
|
||||
Inoltre in merito all'indicazione della "coordinata tempoarel", il task può essere nei seguenti stati
|
||||
- Due in "xxx" (in scadenza in x mesi/settimane/giorni/ore...)
|
||||
- Prossimo alla scadenza (< soglia minima, tipicamente 3 gg)
|
||||
- Scaduto (e da quanto)
|
||||
|
||||
E' utile anche un indicazione con icona del fatto che il task abbia 1 o + assegnatari: 1 -> icona singolo user, tanti --> icona multi utente
|
||||
|
||||
|
||||
In caso di scadenza superata verrà indicato sul task.
|
||||
|
||||
Ogni task può avere delle "sotto attività" che permettono di suddividere il lavoro in maniera più organizzata.
|
||||
|
||||
---
|
||||
|
||||
**Esempio**
|
||||
|
||||
MainTask: Effettuare l'inventario del magazzino.
|
||||
|
||||
SottoTask1: Sistemare tutti gli scatoloni in ordine di grandezza.
|
||||
|
||||
SottoTask2: Preparare tutti gli scanner per i barcode.
|
||||
|
||||
SottoTask3: Scansionare tutti i barcode.
|
||||
|
||||
---
|
||||
|
||||
E' possibile spostare i vari task nelle liste liberamente.
|
||||
|
||||
I colori utilizzati per gli stati dei task saranno:
|
||||
|
||||
-  `Creato`
|
||||
-  `Avviato`
|
||||
-  `In Esecuzione`
|
||||
-  `Completato`
|
||||
|
||||
|
||||
Inoltre si possono avere colori x la "prossimità a scedenza" temporale
|
||||
- (verde) `Scadenza tra xxxx`
|
||||
-  `Prossimo alla scadenza`
|
||||
-  `Scaduto`
|
||||
|
||||
## 4. Document revision
|
||||
|
||||
| Date | Edit | Version | Note |
|
||||
|------------|----------------|:-------:|-----------------:|
|
||||
| 2023.06.22 | S.E. Locatelli | 0.2 | Modifica stato calcolato a tempo vs stati, riduzione differenza "per se/eper altri"|
|
||||
| 2023.06.22 | Z. Majid | 0.1 | Prima versione|
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.2.32519.379
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.MONO.ADAPTER.OPC", "MP.MONO.ADAPTER.OPC\MP.MONO.ADAPTER.OPC.csproj", "{458FD824-7804-4CF9-8C43-463C1F5659DA}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.MONO.ADAPTER.OLD", "MP.MONO.ADAPTER.OLD\MP.MONO.ADAPTER.OLD.csproj", "{84F0ABFE-ADD6-426D-BD9B-E4E9086EE169}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{458FD824-7804-4CF9-8C43-463C1F5659DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{458FD824-7804-4CF9-8C43-463C1F5659DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{458FD824-7804-4CF9-8C43-463C1F5659DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{458FD824-7804-4CF9-8C43-463C1F5659DA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{84F0ABFE-ADD6-426D-BD9B-E4E9086EE169}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{84F0ABFE-ADD6-426D-BD9B-E4E9086EE169}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{84F0ABFE-ADD6-426D-BD9B-E4E9086EE169}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{84F0ABFE-ADD6-426D-BD9B-E4E9086EE169}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {3811E8B4-1DD3-4841-9840-1B1A08782CD3}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,631 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using MP.MONO.Core;
|
||||
using MP.MONO.Core.CONF;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using static MP.MONO.Core.CONF.OpcUaParamConf;
|
||||
using static MP.MONO.Core.Enums;
|
||||
|
||||
namespace MP.MONO.ADAPTER
|
||||
{
|
||||
public class IobGeneric
|
||||
{
|
||||
#region Public Fields
|
||||
|
||||
/// <summary>
|
||||
/// Data/ora ultimo avvio adapter
|
||||
/// </summary>
|
||||
public DateTime dtAvvioAdp = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Data/ora ultimo spegnimento adapter
|
||||
/// </summary>
|
||||
public DateTime dtStopAdp = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// dataOra ultimo log periodico...
|
||||
/// </summary>
|
||||
public DateTime lastPeriodicLog;
|
||||
|
||||
/// <summary>
|
||||
/// dataOra ultimo PING inviato verso il PLC...
|
||||
/// </summary>
|
||||
public DateTime lastPING = DateTime.Now.AddHours(-1);
|
||||
|
||||
/// <summary>
|
||||
/// Struttura memoria PLC x lettura/scrittura da JSON file
|
||||
/// </summary>
|
||||
public plcMemMap memMap;
|
||||
|
||||
#endregion Public Fields
|
||||
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Avvia generico IOB
|
||||
/// </summary>
|
||||
/// <param name="confPath"></param>
|
||||
/// <param name="config"></param>
|
||||
public IobGeneric(string confPath, IConfigurationRoot? config)
|
||||
{
|
||||
lg = LogManager.GetCurrentClassLogger();
|
||||
connectionOk = false;
|
||||
configPath = confPath;
|
||||
confMan = config;
|
||||
if (confMan != null)
|
||||
{
|
||||
var selection = confMan.GetSection("Endpoint");
|
||||
if (selection.Exists())
|
||||
{
|
||||
// recupero dati endpoint
|
||||
cIobConf = selection.Get<EndpointData>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Salva verifica stato connessione OK
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual bool connectionOk
|
||||
{
|
||||
get
|
||||
{
|
||||
return _connOk;
|
||||
}
|
||||
set
|
||||
{
|
||||
_connOk = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifica SE si debba fare log verboso (verboso + ogni tot letture IN)
|
||||
/// </summary>
|
||||
public bool verboseLog
|
||||
{
|
||||
get
|
||||
{
|
||||
bool answ = false;
|
||||
int logEvery = confMan.GetValue<int>("logEvery");
|
||||
if (logEvery < 1)
|
||||
{
|
||||
logEvery = 10;
|
||||
}
|
||||
|
||||
answ = confMan.GetValue<bool>("verbose") && (nReadIN % logEvery == 0);
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Esecuzione dei task richiesti e pulizia coda richieste eseguite
|
||||
/// </summary>
|
||||
/// <param name="task2exe"></param>
|
||||
public virtual Dictionary<string, string> executeTasks(Dictionary<string, string> task2exe)
|
||||
{
|
||||
// Verificare il protocollo: dovrebbe togliere SOLO i task eseguiti...
|
||||
Dictionary<string, string> taskDone = new Dictionary<string, string>();
|
||||
if (task2exe != null)
|
||||
{
|
||||
// controllo se memMap != null...
|
||||
if (memMap != null)
|
||||
{
|
||||
bool taskOk = false;
|
||||
string taskVal = "";
|
||||
// cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4
|
||||
foreach (var item in task2exe)
|
||||
{
|
||||
taskOk = false;
|
||||
taskVal = "";
|
||||
// converto richiesta in enum...
|
||||
taskType tName = taskType.nihil;
|
||||
Enum.TryParse(item.Key, out tName);
|
||||
// controllo sulla KEY...
|
||||
switch (tName)
|
||||
{
|
||||
case taskType.setArt:
|
||||
case taskType.setComm:
|
||||
case taskType.setProg:
|
||||
case taskType.setPzComm:
|
||||
// recupero dati da memMap...
|
||||
if (memMap != null && memMap.mMapWrite != null)
|
||||
{
|
||||
if (memMap.mMapWrite.ContainsKey(item.Key))
|
||||
{
|
||||
dataConf currMem = memMap.mMapWrite[item.Key];
|
||||
string addr = currMem.memAddr;
|
||||
taskVal = $"SET task: {item.Key} --> {item.Value} | mem: {currMem.memAddr} - {currMem.size} byte";
|
||||
// salvo il nuovo valore nella memoria... così prox invio lo trasmetterà
|
||||
memMap.mMapWrite[item.Key].value = item.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
taskVal = $"NO DATA MEM, SET task: {item.Key} --> {item.Value}";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
taskVal = $"NO MemMap found, SET task: {item.Key} --> {item.Value}";
|
||||
}
|
||||
// salvo in currProd..
|
||||
saveProdData(new KeyValuePair<string, string>(item.Key, item.Value));
|
||||
|
||||
break;
|
||||
|
||||
case taskType.forceResetPzCount:
|
||||
// reset contapezzi inizio setup
|
||||
taskOk = resetcontapezziPLC();
|
||||
taskVal = taskOk ? "RESET PZ COUNT OK" : "PZ RESET DISABLED | NO EXEC";
|
||||
lgInfo($"Chiamata forceResetPzCount: taskOk: {taskOk} | taskVal: {taskVal}");
|
||||
break;
|
||||
|
||||
case taskType.startSetup:
|
||||
// reset contapezzi inizio setup
|
||||
taskOk = resetcontapezziPLC();
|
||||
taskVal = taskOk ? "RESET: SETUP START" : "PZ RESET DISABLED | NO EXEC";
|
||||
lgInfo($"Chiamata startSetup: taskOk: {taskOk} | taskVal: {taskVal}");
|
||||
break;
|
||||
|
||||
case taskType.stopSetup:
|
||||
// reset contapezzi fine setup SE ESPLICITAMENTE IMPOSTATO
|
||||
if (confMan.GetValue<bool>("ENABLE_PZ_RESET_stopSetup"))
|
||||
{
|
||||
taskOk = resetcontapezziPLC();
|
||||
}
|
||||
taskVal = taskOk ? "RESET: SETUP END" : "PZ RESET DISABLED | NO EXEC";
|
||||
lgInfo($"Chiamata stopSetup: taskOk: {taskOk} | taskVal: {taskVal}");
|
||||
break;
|
||||
|
||||
case taskType.setParameter:
|
||||
// richiedo da URL i parametri WRITE da popolare
|
||||
lgInfo("Chiamata setParameter --> processMemWriteRequests");
|
||||
taskVal = processMemWriteRequests();
|
||||
// se restituiscce "" faccio altra prova...
|
||||
if (string.IsNullOrEmpty(taskVal))
|
||||
{
|
||||
// i parametri me li aspetto come stringa composta paramName|paramvalue
|
||||
if (item.Value.Contains("|"))
|
||||
{
|
||||
string[] paramsJob = item.Value.Split('|');
|
||||
taskVal = $"REQUEST SET PARAMETERS: {paramsJob[0]} --> {paramsJob[1]}";
|
||||
}
|
||||
else
|
||||
{
|
||||
taskVal = $"WRONG REQUEST FOR SET PARAMETERS: {item.Value} doesnt contain pipe for splitting key/value";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
|
||||
lgInfo($"Chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}");
|
||||
break;
|
||||
}
|
||||
// aggiungo task!
|
||||
taskDone.Add(item.Key, taskVal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError($"Attenzione! memMap è nullo, non posso eseguire task2exe!");
|
||||
}
|
||||
}
|
||||
|
||||
return taskDone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metodo generico di reset contapezzi...
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual bool resetcontapezziPLC()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Salva valori indicati in prod data
|
||||
/// </summary>
|
||||
/// <param name="item">Item KVP di cui salvare i dati in currProdData come chiave/valore</param>
|
||||
/// <returns></returns>
|
||||
public void saveProdData(KeyValuePair<string, string> item)
|
||||
{
|
||||
// imposto i valori...
|
||||
if (currProdData.ContainsKey(item.Key))
|
||||
{
|
||||
currProdData[item.Key] = item.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
currProdData.Add(item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metodo base connessione...
|
||||
/// </summary>
|
||||
public virtual void tryConnect()
|
||||
{
|
||||
dtAvvioAdp = DateTime.Now;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
/// <summary>
|
||||
/// wrapper di log
|
||||
/// </summary>
|
||||
protected static Logger lg;
|
||||
|
||||
protected bool _connOk = false;
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario valori impostati x produzione
|
||||
/// </summary>
|
||||
protected Dictionary<string, string> currProdData = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario ultimi valori (double) delle TSVC
|
||||
/// </summary>
|
||||
protected Dictionary<string, double> LastTSVC = new Dictionary<string, double>();
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario di VC da trattare come TimeSeries (con conf decodificata + processing successivo...)
|
||||
/// </summary>
|
||||
protected Dictionary<string, VCData> TSVC_Data = new Dictionary<string, VCData>();
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
/// <summary>
|
||||
/// Numero letture IN da avvio
|
||||
/// </summary>
|
||||
protected int nReadIN { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// COnfiguraizone Endpoint corrente
|
||||
/// </summary>
|
||||
private EndpointData cIobConf { get; set; } = new EndpointData();
|
||||
|
||||
/// <summary>
|
||||
/// test ping all'indirizzo PLC/CNC impostato nei parametri
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected IPStatus testPingMachine
|
||||
{
|
||||
get
|
||||
{
|
||||
IPStatus answ = IPStatus.Unknown;
|
||||
// se disabilitato salto...
|
||||
if (pingDisabled)
|
||||
{
|
||||
answ = IPStatus.Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPAddress address;
|
||||
PingReply reply;
|
||||
using (Ping pingSender = new Ping())
|
||||
{
|
||||
address = IPAddress.Loopback;
|
||||
int pingMsTimeout = cIobConf.PingMsTimeout;
|
||||
IPAddress.TryParse(cIobConf.IpAddress, out address);
|
||||
try
|
||||
{
|
||||
// se != null --> uso address...
|
||||
if (address != null)
|
||||
{
|
||||
reply = pingSender.Send(address, pingMsTimeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
reply = pingSender.Send(cIobConf.IpAddress, pingMsTimeout);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
reply = pingSender.Send(IPAddress.Loopback, pingMsTimeout);
|
||||
}
|
||||
answ = reply.Status;
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// indica se ping disabilitato da optPar
|
||||
/// </summary>
|
||||
public bool pingDisabled
|
||||
{
|
||||
get
|
||||
{
|
||||
bool answ = false;
|
||||
bool.TryParse(confMan.GetValue<string>("NO_PING"), out answ);
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Stringa raw dei parametri da scrivere...
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected string getParams2write()
|
||||
{
|
||||
string answ = "";
|
||||
// recuperare da una apposita area REDIS...
|
||||
#if false
|
||||
string url2call = $"{urlGetParams2Write}";
|
||||
if (verboseLog)
|
||||
{
|
||||
lgInfo("chiamata URL " + url2call);
|
||||
}
|
||||
answ = utils.callUrlNow(url2call);
|
||||
// se vuoto faccio seconda prova...
|
||||
if (string.IsNullOrEmpty(answ))
|
||||
{
|
||||
answ = utils.callUrlNow(url2call);
|
||||
}
|
||||
#endif
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua logging DEBUG corretto impostanto anche la variabile IOB prima di scrivere...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
protected void lgDebug(string message)
|
||||
{
|
||||
lg.Debug(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua logging DEBUG corretto impostanto anche la variabile IOB prima di scrivere...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="args"></param>
|
||||
protected void lgDebug(string message, params object[] args)
|
||||
{
|
||||
lg.Debug(message, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
protected void lgError(string message)
|
||||
{
|
||||
lg.Error(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="args"></param>
|
||||
protected void lgError(string message, params object[] args)
|
||||
{
|
||||
lg.Error(message, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere...
|
||||
/// </summary>
|
||||
/// <param name="exception"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="args"></param>
|
||||
protected void lgError(Exception exception, string message, params object[] args)
|
||||
{
|
||||
lg.Error(exception, message, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua logging FATAL corretto impostanto anche la variabile IOB prima di scrivere...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
protected void lgFatal(string message)
|
||||
{
|
||||
lg.Fatal(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua logging FATAL corretto impostanto anche la variabile IOB prima di scrivere...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="args"></param>
|
||||
protected void lgFatal(string message, params object[] args)
|
||||
{
|
||||
lg.Fatal(message, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua logging FATAL corretto impostanto anche la variabile IOB prima di scrivere...
|
||||
/// </summary>
|
||||
/// <param name="exception"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="args"></param>
|
||||
protected void lgFatal(Exception exception, string message, params object[] args)
|
||||
{
|
||||
lg.Fatal(exception, message, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
protected void lgInfo(string message)
|
||||
{
|
||||
lg.Info(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="args"></param>
|
||||
protected void lgInfo(string message, params object[] args)
|
||||
{
|
||||
lg.Info(message, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
protected void lgTrace(string message)
|
||||
{
|
||||
lg.Trace(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="args"></param>
|
||||
protected void lgTrace(string message, params object[] args)
|
||||
{
|
||||
lg.Trace(message, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metodo da overridare x scrivere DAVVERO i parametri sul PLC
|
||||
/// </summary>
|
||||
/// <param name="updatedPar"></param>
|
||||
protected virtual void plcWriteParams(ref List<objItem> updatedPar)
|
||||
{
|
||||
// non faccio nulla di base...
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processa le richieste di scrittura memoria
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected string processMemWriteRequests()
|
||||
{
|
||||
string answ = "";
|
||||
// li salvo nei parametri in memoria locale (ogni adapter DOVREBBE salvare POI sul VERO PLC)
|
||||
List<objItem> writeList = new List<objItem>();
|
||||
List<objItem> updatedPar = new List<objItem>();
|
||||
// recupero elenco delle cose da fare
|
||||
string resp = getParams2write();
|
||||
if (!string.IsNullOrEmpty(resp))
|
||||
{
|
||||
try
|
||||
{
|
||||
writeList = JsonConvert.DeserializeObject<List<objItem>>(resp);
|
||||
// se ho da fare chiamo esecuzione..
|
||||
if (writeList.Count > 0)
|
||||
{
|
||||
foreach (var item in writeList)
|
||||
{
|
||||
// scrivo in memoria
|
||||
if (memMap.mMapWrite.ContainsKey(item.uid))
|
||||
{
|
||||
memMap.mMapWrite[item.uid].value = item.reqValue;
|
||||
// accodo in stringa taskVal...
|
||||
answ += $" | Parameter {item.uid} --> {item.reqValue}";
|
||||
// sistemo valori
|
||||
item.value = item.reqValue;
|
||||
lgInfo($"Richiesta update parametro {item.uid} | actVal = {item.value} | reqVal = {item.reqValue}");
|
||||
item.reqValue = "";
|
||||
// salvo in lista da ritrasmettere
|
||||
updatedPar.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
answ += $" | Error: parameter {item.uid} not found";
|
||||
}
|
||||
}
|
||||
// richiamo scrittura parametri su PLC
|
||||
plcWriteParams(ref updatedPar);
|
||||
// invio su cloud parametri!
|
||||
string rawData = JsonConvert.SerializeObject(updatedPar);
|
||||
lgInfo("Notifica a server scrittura parametri");
|
||||
#if false
|
||||
utils.callUrl($"{urlUpdateWriteParams}", rawData);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
lgError($"Eccezione in processMemWriteRequests:{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError("Non è stata ricevuta risposta x task da eseguire");
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// setup parametri da file di conf
|
||||
/// </summary>
|
||||
protected void setupMemMap()
|
||||
{
|
||||
lgInfo($"setupMemMap | trovati {memMap.mMapRead.Count} parametri Read (TSVC)");
|
||||
lgInfo($"setupMemMap | trovati {memMap.mMapWrite.Count} parametri Write");
|
||||
if (confMan.GetValue<bool>("verbose"))
|
||||
{
|
||||
string rawMemConf = JsonConvert.SerializeObject(memMap, Formatting.Indented);
|
||||
lgDebug($"setupMemMap | configurazione memoria R/W:{Environment.NewLine}{rawMemConf}");
|
||||
}
|
||||
// se ho variabili read --> genero dati TSVC...
|
||||
if (memMap.mMapRead.Count > 0)
|
||||
{
|
||||
TSVC_Data.Clear();
|
||||
LastTSVC.Clear();
|
||||
VCData currConf;
|
||||
int periodo = 0;
|
||||
VC_func funz = VC_func.POINT;
|
||||
// accodo nella conf...
|
||||
foreach (var item in memMap.mMapRead)
|
||||
{
|
||||
funz = item.Value.func;
|
||||
periodo = item.Value.period;
|
||||
currConf = new VCData()
|
||||
{
|
||||
Funzione = funz,
|
||||
Period = periodo,
|
||||
DTStart = DateTime.Now.AddHours(-1),
|
||||
dataArray = new List<double>()
|
||||
};
|
||||
TSVC_Data.Add(item.Key, currConf);
|
||||
}
|
||||
// documento...
|
||||
foreach (var item in TSVC_Data)
|
||||
{
|
||||
lgTrace($"TSVC: {item.Key} | periodo: {item.Value.Period} | funz: {item.Value.Funzione}");
|
||||
// salvo i valori PREC...
|
||||
LastTSVC.Add(item.Key, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Properties
|
||||
|
||||
internal string configPath { get; set; } = "";
|
||||
|
||||
internal IConfigurationRoot? confMan { get; set; } = null!;
|
||||
|
||||
#endregion Private Properties
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,59 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>1.12206.1416</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="appsettings.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="NLog" Version="5.0.1" />
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client" Version="1.4.368.58" />
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Configuration" Version="1.4.368.58" />
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Core" Version="1.4.368.58" />
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Security.Certificates" Version="1.4.368.58" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.5.43" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MP.MONO.Core\MP.MONO.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="conf\ModeList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="conf\AlarmList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="conf\ParamList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="conf\StatusList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
<Exec Command="powershell.exe -ExecutionPolicy Unrestricted -NoProfile -NonInteractive -File $(ProjectDir)\post-build.ps1 -ProjectDir $(ProjectDir) -ProjectPath $(ProjectPath)" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,291 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using MP.MONO.ADAPTER;
|
||||
using MP.MONO.Core;
|
||||
using MP.MONO.Core.CONF;
|
||||
using MP.MONO.Core.DTO;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using StackExchange.Redis;
|
||||
|
||||
// init parte config, vedere https://blog.hildenco.com/2020/05/configuration-in-net-core-console.html
|
||||
var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
|
||||
var builder = new ConfigurationBuilder()
|
||||
.AddJsonFile($"appsettings.json", true, true)
|
||||
.AddJsonFile($"appsettings.{env}.json", true, true)
|
||||
.AddEnvironmentVariables();
|
||||
var config = builder.Build();
|
||||
|
||||
// imposto variabili di base
|
||||
string lineSep = "---------------------------------------------";
|
||||
string redisConf = config.GetConnectionString("Redis");
|
||||
string confPath = Path.Combine(Directory.GetCurrentDirectory(), "conf");
|
||||
#if false
|
||||
string alarmSimMode = config.GetValue<string>("AlarmSimMode");
|
||||
#endif
|
||||
Logger Log = LogManager.GetCurrentClassLogger();
|
||||
Random rand = new Random();
|
||||
List<MachineStatus>? statusList = new List<MachineStatus>();
|
||||
List<MachineMode>? modeList = new List<MachineMode>();
|
||||
|
||||
// fix numero minimo dei thread pool x evitare collasso chiamate redis
|
||||
ThreadPool.SetMinThreads(10, 10);
|
||||
|
||||
Dictionary<string, int> LogSimulator = new Dictionary<string, int>();
|
||||
Dictionary<string, DateTime> LastSend = new Dictionary<string, DateTime>();
|
||||
DateTime lastLog = DateTime.Now.AddMinutes(-1);
|
||||
bool verboseLog = false;
|
||||
bool logWriting = false;
|
||||
|
||||
logInfo(lineSep, true, true);
|
||||
logInfo($"Starting Machine ADAPTER", true, true);
|
||||
logInfo($"Redis server param: {redisConf.Substring(0, 20)}...", false, true);
|
||||
logInfo(lineSep, true, true);
|
||||
logInfo("", true, true);
|
||||
logInfo("Running - press CTRL-C to stop SIM", false, true);
|
||||
logInfo("", false, true);
|
||||
|
||||
// Setup REDIS
|
||||
ConnectionMultiplexer.SetFeatureFlag("preventthreadtheft", true);
|
||||
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(redisConf);
|
||||
ISubscriber sub = redis.GetSubscriber();
|
||||
IDatabase? redisDb = redis.GetDatabase();
|
||||
|
||||
// salvo configurazioni in redis
|
||||
setupConf();
|
||||
|
||||
// avvio il vero e proprio programma di comunicaizone OPC-UA
|
||||
var currIob = new IobOpcUa(confPath, config);
|
||||
|
||||
#if false
|
||||
var currSimGen = new Simulator(confPath, modeList.Count, statusList.Count);
|
||||
|
||||
// preparo la lista dei contatori invio...
|
||||
LogSimulator.Add(Constants.ACT_LOG_M_QUEUE, 0);
|
||||
LogSimulator.Add(Constants.ALARM_M_QUEUE, 0);
|
||||
LogSimulator.Add(Constants.EVENT_LOG_M_QUEUE, 0);
|
||||
LogSimulator.Add(Constants.PARAMS_M_QUEUE, 0);
|
||||
LogSimulator.Add(Constants.PROD_M_QUEUE, 0);
|
||||
LogSimulator.Add(Constants.MACH_STATS_M_QUEUE, 0);
|
||||
LogSimulator.Add(Constants.MAINT_STATS_M_QUEUE, 0);
|
||||
LogSimulator.Add(Constants.TOOLS_M_QUEUE, 0);
|
||||
|
||||
// avvio tutti i thread...
|
||||
Thread threadStatus = new Thread(simStatus);
|
||||
Thread threadAlarms = new Thread(simAlarms);
|
||||
Thread threadParams = new Thread(simParameters);
|
||||
Thread threadProd = new Thread(simProd);
|
||||
Thread threadMachStat = new Thread(simMachStat);
|
||||
Thread threadMaint = new Thread(simMaint);
|
||||
Thread threadTools = new Thread(simTools);
|
||||
Thread threadEvHistory = new Thread(simEvents);
|
||||
Thread threadActLog = new Thread(simActivityLog);
|
||||
|
||||
threadStatus.Start();
|
||||
threadAlarms.Start();
|
||||
threadParams.Start();
|
||||
threadProd.Start();
|
||||
threadMachStat.Start();
|
||||
threadMaint.Start();
|
||||
threadTools.Start();
|
||||
threadEvHistory.Start();
|
||||
threadActLog.Start();
|
||||
#endif
|
||||
|
||||
// Ciclo infinito x attesa chiusura con CTRL-C
|
||||
do
|
||||
{
|
||||
// se non fosse connesso... riprovo la connessione...
|
||||
if (!currIob.connectionOk)
|
||||
{
|
||||
currIob.tryConnect();
|
||||
}
|
||||
// attesa...
|
||||
Thread.Sleep(100);
|
||||
} while (true);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// verifica esistenza file oppure lo crea...
|
||||
/// </summary>
|
||||
void checkFilePresent(string filePath)
|
||||
{
|
||||
// verific presenza file log...
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
File.WriteAllText(filePath, $"{filePath} created!");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setup e salvataggio redis delle conf (es modi/stati)
|
||||
/// </summary>
|
||||
void setupConf()
|
||||
{
|
||||
#if false
|
||||
// leggo e salvo conf stati
|
||||
string fullPath = Path.Combine(confPath, "StatusList.json");
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
List<MachineStatus>? statusList = JsonConvert.DeserializeObject<List<MachineStatus>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.STATUS_CONF_KEY, JsonConvert.SerializeObject(statusList));
|
||||
}
|
||||
}
|
||||
|
||||
// leggo e salvo conf modi
|
||||
fullPath = Path.Combine(confPath, "ModeList.json");
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
var localObj = JsonConvert.DeserializeObject<List<MachineMode>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.MODE_CONF_KEY, JsonConvert.SerializeObject(localObj));
|
||||
}
|
||||
}
|
||||
|
||||
// leggo e salvo conf allarmi
|
||||
fullPath = Path.Combine(confPath, "AlarmList.json");
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
var localObj = JsonConvert.DeserializeObject<List<BaseAlarmConf>>(rawData);
|
||||
if (localObj != null)
|
||||
{
|
||||
// sistemo allarmi
|
||||
foreach (var item in localObj)
|
||||
{
|
||||
item.setupData();
|
||||
// loggo
|
||||
logInfo($"Decodifica aree alarmMap: {item.description} | {item.memAddr} x {item.size} byte | {item.messages.Count} messaggi allarme", true, true);
|
||||
}
|
||||
}
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.ALARMS_CONF_KEY, JsonConvert.SerializeObject(localObj));
|
||||
}
|
||||
}
|
||||
|
||||
// leggo e salvo conf parametri
|
||||
fullPath = Path.Combine(confPath, "ParamList.json");
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
var localObj = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.PARAMS_CONF_KEY, JsonConvert.SerializeObject(localObj));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ConfigManager configManager = new ConfigManager(redisConf, confPath);
|
||||
_ = configManager.getAlarmsConf();
|
||||
_ = configManager.getMachineModeConf();
|
||||
_ = configManager.getMachineStatusConf();
|
||||
_ = configManager.getParamsConf();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua log INFO su file e se richiesto su console
|
||||
/// </summary>
|
||||
void logInfo(string msg, bool log2file = true, bool log2console = false)
|
||||
{
|
||||
if (log2console)
|
||||
{
|
||||
Console.WriteLine(msg);
|
||||
}
|
||||
if (log2file)
|
||||
{
|
||||
Log.Info(msg);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Effettua log ERROR su file e se richiesto su console
|
||||
/// </summary>
|
||||
void logError(string msg, bool log2file = true, bool log2console = false)
|
||||
{
|
||||
if (log2console)
|
||||
{
|
||||
Console.WriteLine(msg);
|
||||
}
|
||||
if (log2file)
|
||||
{
|
||||
Log.Error(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void saveAndSendMessage(string memKey, string value, string notifyChannel, string message)
|
||||
{
|
||||
// effettuo la scrittura nell'area di memoria indicata SE passato intervallo minimo
|
||||
bool doSend = true;
|
||||
if (LastSend.ContainsKey(memKey))
|
||||
{
|
||||
if (DateTime.Now.Subtract(LastSend[memKey]).TotalSeconds < 60)
|
||||
{
|
||||
doSend = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LastSend.Add(memKey, DateTime.Now);
|
||||
}
|
||||
if (doSend)
|
||||
{
|
||||
redisDb.StringSetAsync(memKey, value);
|
||||
LastSend[memKey] = DateTime.Now;
|
||||
logInfo($"Redis Cache Key: {memKey}");
|
||||
}
|
||||
//redisDb.SetAdd(memKey, value);
|
||||
|
||||
// invio notifica tramite il canale richiesto
|
||||
sub.Publish(notifyChannel, message);
|
||||
if (verboseLog)
|
||||
{
|
||||
logInfo($"[{notifyChannel}] key: {memKey} | val: {value} | message: {message}");
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!logWriting)
|
||||
{
|
||||
if (LogSimulator.ContainsKey(notifyChannel))
|
||||
{
|
||||
LogSimulator[notifyChannel]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogSimulator.Add(notifyChannel, 1);
|
||||
}
|
||||
logWriting = true;
|
||||
// vedo se loggare...
|
||||
DateTime adesso = DateTime.Now;
|
||||
if (adesso.Subtract(lastLog).TotalSeconds > 15)
|
||||
{
|
||||
lastLog = adesso;
|
||||
logInfo(lineSep);
|
||||
|
||||
// lavoro su copia...
|
||||
var LogSimulatorCopy = new Dictionary<string, int>(LogSimulator);
|
||||
foreach (var item in LogSimulatorCopy)
|
||||
{
|
||||
logInfo($"Redis mQueue {item.Key,-20}{item.Value,12}");
|
||||
}
|
||||
logInfo(lineSep);
|
||||
}
|
||||
logWriting = false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logError($"ERROR{Environment.NewLine}{ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<body>
|
||||
<i>MAPO-MONO</i>
|
||||
<h4>Version: {{CURRENT-REL}}</h4>
|
||||
<br /> Release Note:
|
||||
<ul>
|
||||
<li>
|
||||
<b>Last changes:</b>
|
||||
<ul>{{LAST-CHANGES}}</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>v.1.0.* →</b>
|
||||
<ul>
|
||||
<li>Current CORE version</li>
|
||||
<li>Release dotnet6</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<div>
|
||||
<div style="float: left;">
|
||||
<img src="logoSteamware.png" />
|
||||
</div>
|
||||
<div style="float: right;">
|
||||
<a href="https://www.steamware.net/MAPO" target="_blank">© Egalware 2006-2022</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
@@ -0,0 +1,26 @@
|
||||
<body>
|
||||
<i>MAPO-MONO</i>
|
||||
<h4>Version: 1.12206.1416</h4>
|
||||
<br /> Release Note:
|
||||
<ul>
|
||||
<li>
|
||||
<b>Last changes:</b>
|
||||
<ul>{{LAST-CHANGES}}</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>v.1.0.* →</b>
|
||||
<ul>
|
||||
<li>Current CORE version</li>
|
||||
<li>Release dotnet6</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<div>
|
||||
<div style="float: left;">
|
||||
<img src="logoSteamware.png" />
|
||||
</div>
|
||||
<div style="float: right;">
|
||||
<a href="https://www.steamware.net/MAPO" target="_blank">© Egalware 2006-2022</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
@@ -0,0 +1 @@
|
||||
1.12206.1416
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>1.0.0.0</version>
|
||||
<url>http://nexus.steamware.net/repository/SWS/{{DIRNAME}}/{{BRANCHNAME}}/{{PACKNAME}}.zip</url>
|
||||
<changelog>http://nexus.steamware.net/repository/SWS/{{DIRNAME}}/{{BRANCHNAME}}/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
</item>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>1.12206.1416</version>
|
||||
<url>http://nexus.steamware.net/repository/SWS/MP.MONO.ADAPTER/stable/LAST/MP.Mon.zip</url>
|
||||
<changelog>http://nexus.steamware.net/repository/SWS/MP.MONO.ADAPTER/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
</item>
|
||||
@@ -0,0 +1,991 @@
|
||||
using NLog;
|
||||
using Opc.Ua;
|
||||
using Opc.Ua.Client;
|
||||
using System.Collections;
|
||||
|
||||
namespace MP.MONO.ADAPTER
|
||||
{
|
||||
/// <summary>
|
||||
/// Evento per incapsulare dati x refresh pagina
|
||||
/// </summary>
|
||||
public class opcUaMonitItemChange : EventArgs
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// salvataggio obj
|
||||
/// </summary>
|
||||
/// <param name="newObject"></param>
|
||||
public opcUaMonitItemChange(MonitoredItem monitoredItem, MonitoredItemNotification notification)
|
||||
{
|
||||
_monitoredItem = monitoredItem;
|
||||
_notification = notification;
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Proprietà lettura del MonitoredItem
|
||||
/// </summary>
|
||||
public MonitoredItem CurrMonitoredItem
|
||||
{
|
||||
get { return _monitoredItem; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Proprietà lettura della notifica
|
||||
/// </summary>
|
||||
public MonitoredItemNotification CurrNotify
|
||||
{
|
||||
get { return _notification; }
|
||||
}
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Private Fields
|
||||
|
||||
/// <summary>
|
||||
/// Monitored Item da notificare
|
||||
/// </summary>
|
||||
private readonly MonitoredItem _monitoredItem;
|
||||
|
||||
/// <summary>
|
||||
/// Valore notifica
|
||||
/// </summary>
|
||||
private readonly MonitoredItemNotification _notification;
|
||||
|
||||
#endregion Private Fields
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OPC UA Client with examples of basic functionality.
|
||||
/// </summary>
|
||||
public class UAClient
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the UAClient class.
|
||||
/// </summary>
|
||||
public UAClient(ApplicationConfiguration configuration, string codIOB, string user, string pwd, bool verboseLog, Action<IList, IList> validateResponse)
|
||||
{
|
||||
m_validateResponse = validateResponse;
|
||||
currIob = codIOB;
|
||||
lg = LogManager.GetCurrentClassLogger();
|
||||
if (!string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(pwd))
|
||||
{
|
||||
CurrUserIdentity = new UserIdentity(user, pwd);
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrUserIdentity = new UserIdentity();
|
||||
}
|
||||
isLogVerbose = verboseLog;
|
||||
m_configuration = configuration;
|
||||
m_configuration.CertificateValidator.CertificateValidation += CertificateValidation;
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Events
|
||||
|
||||
/// <summary>
|
||||
/// Evento notifica variazione MonitoredItem
|
||||
/// </summary>
|
||||
public event EventHandler<opcUaMonitItemChange> eh_MonItChange;
|
||||
|
||||
#endregion Public Events
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// The user identity to use when creating the session.
|
||||
/// </summary>
|
||||
public IUserIdentity CurrUserIdentity { get; set; } = new UserIdentity();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the server URL.
|
||||
/// </summary>
|
||||
public string ServerUrl { get; set; } = "opc.tcp://localhost:4840";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the client session.
|
||||
/// </summary>
|
||||
public Session Session => m_session;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Browse Server nodes
|
||||
/// </summary>
|
||||
public bool Browse(ushort startNodeNS, uint startNodeVal, List<string> vetoBrowse, ref Dictionary<string, string> nodeIdNameList)
|
||||
{
|
||||
bool fatto = false;
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lgError("Session not connected!");
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Create a Browser object
|
||||
Browser browser = new Browser(m_session);
|
||||
|
||||
// Set browse parameters
|
||||
browser.BrowseDirection = BrowseDirection.Forward;
|
||||
browser.NodeClassMask = (int)NodeClass.Object | (int)NodeClass.Variable;
|
||||
browser.ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences;
|
||||
|
||||
//NodeId nodeToBrowse = ObjectIds.Server;
|
||||
//NodeId nodeToBrowse = new NodeId("ns=4,i=5001");
|
||||
NodeId nodeToBrowse = new NodeId(startNodeVal, startNodeNS);
|
||||
|
||||
// Call Browse service
|
||||
lgTrace($"Browsing {nodeToBrowse} node...");
|
||||
ReferenceDescriptionCollection browseResults = browser.Browse(nodeToBrowse);
|
||||
|
||||
// Display the results
|
||||
lgTrace($"Browse returned {browseResults.Count} results:");
|
||||
|
||||
foreach (ReferenceDescription result in browseResults)
|
||||
{
|
||||
lgTrace($" NodeId = {result.NodeId}, TypeId = {result.TypeId}, DisplayName = {result.DisplayName.Text}, NodeClass = {result.NodeClass}, Others: {result.BinaryEncodingId} | {result.BrowseName}");
|
||||
// se NON fa parte dell'elenco dei VETO di filterItems...
|
||||
if (!vetoBrowse.Contains($"{result.NodeId}"))
|
||||
{
|
||||
// se mancasse aggiungo...
|
||||
if (!nodeIdNameList.ContainsKey($"{result.NodeId}"))
|
||||
{
|
||||
nodeIdNameList.Add(result.NodeId.ToString(), result.DisplayName.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
fatto = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lgError($"Browse Error : {ex.Message}");
|
||||
}
|
||||
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Browse Server nodes
|
||||
/// </summary>
|
||||
public bool Browse(string browsePath, List<string> vetoBrowse, ref Dictionary<string, string> nodeIdNameList)
|
||||
{
|
||||
bool fatto = false;
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lgError("Session not connected!");
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Create a Browser object
|
||||
Browser browser = new Browser(m_session);
|
||||
|
||||
// Set browse parameters
|
||||
browser.BrowseDirection = BrowseDirection.Forward;
|
||||
browser.NodeClassMask = (int)NodeClass.Object | (int)NodeClass.Variable;
|
||||
browser.ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences;
|
||||
|
||||
//NodeId nodeToBrowse = ObjectIds.Server;
|
||||
//NodeId nodeToBrowse = new NodeId("ns=4;i=5001");
|
||||
NodeId nodeToBrowse = new NodeId(browsePath);
|
||||
//nodeToBrowse = ObjectIds.Server;
|
||||
//nodeToBrowse = new NodeId("Calibratrice_L1", 4);
|
||||
//nodeToBrowse = new NodeId("Dati_Mes", 4);
|
||||
//nodeToBrowse = new NodeId(5001, 2);
|
||||
//nodeToBrowse = new NodeId("ns=4;s=NxController");
|
||||
//nodeToBrowse = new NodeId("ns=4;s=Dati_Mes");
|
||||
//nodeToBrowse = new NodeId("NxController.GlobalVars", 4);
|
||||
//nodeToBrowse = new NodeId("Dati_Mes", 4);
|
||||
|
||||
// Call Browse service
|
||||
lgTrace($"Browsing {nodeToBrowse} node...");
|
||||
ReferenceDescriptionCollection browseResults = browser.Browse(nodeToBrowse);
|
||||
|
||||
// Display the results
|
||||
lgTrace($"Browse returned {browseResults.Count} results:");
|
||||
|
||||
foreach (ReferenceDescription result in browseResults)
|
||||
{
|
||||
// se veto --> loggo veto
|
||||
if (vetoBrowse.Contains($"{result.NodeId}"))
|
||||
{
|
||||
lgTrace($"| FILTERED --> NodeId = {result.NodeId}, DisplayName = {result.DisplayName.Text}, NodeClass = {result.NodeClass}, Others: {result.BinaryEncodingId} | {result.BrowseName}");
|
||||
}
|
||||
// se NON fa parte dell'elenco dei VETO di filterItems...
|
||||
else
|
||||
{
|
||||
lgTrace($" NodeId = {result.NodeId}, DisplayName = {result.DisplayName.Text}, NodeClass = {result.NodeClass}, Others: {result.BinaryEncodingId} | {result.BrowseName}");
|
||||
// se mancasse aggiungo...
|
||||
if (!nodeIdNameList.ContainsKey($"{result.NodeId}"))
|
||||
{
|
||||
nodeIdNameList.Add($"{result.NodeId}", result.DisplayName.Text);
|
||||
// se è un nodo object --> faccio sub browse!
|
||||
if (result.NodeClass != NodeClass.Variable)
|
||||
{
|
||||
this.Browse($"{result.NodeId}", vetoBrowse, ref nodeIdNameList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fatto = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lgError($"Browse Error : {ex.Message}");
|
||||
}
|
||||
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call UA method
|
||||
/// </summary>
|
||||
public void CallMethod()
|
||||
{
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lgError("Session not connected!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Define the UA Method to call Parent node - Objects\CTT\Methods Method node - Objects\CTT\Methods\Add
|
||||
NodeId objectId = new NodeId("ns=2;s=Methods");
|
||||
NodeId methodId = new NodeId("ns=2;s=Methods_Add");
|
||||
|
||||
// Define the method parameters Input argument requires a Float and an UInt32 value
|
||||
object[] inputArguments = new object[] { (float)10.5, (uint)10 };
|
||||
IList<object> outputArguments = null;
|
||||
|
||||
// Invoke Call service
|
||||
lgDebug($"Calling UAMethod for node {methodId} ...");
|
||||
outputArguments = m_session.Call(objectId, methodId, inputArguments);
|
||||
|
||||
// Display results
|
||||
lgDebug($"Method call returned {outputArguments.Count} output argument(s):");
|
||||
|
||||
foreach (var outputArgument in outputArguments)
|
||||
{
|
||||
lgDebug($" OutputValue = {outputArgument}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
lgError($"Method call error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a session with the UA server
|
||||
/// </summary>
|
||||
public async Task<bool> ConnectAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (m_session != null && m_session.Connected == true)
|
||||
{
|
||||
lgInfo("Session already connected!");
|
||||
}
|
||||
else
|
||||
{
|
||||
lgInfo("Connecting...");
|
||||
|
||||
// Get the endpoint by connecting to server's discovery endpoint. Try to find
|
||||
// the first endopint without security.
|
||||
EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(ServerUrl, false);
|
||||
|
||||
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
|
||||
ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);
|
||||
|
||||
// Create the session
|
||||
Session session = await Session.Create(
|
||||
m_configuration,
|
||||
endpoint,
|
||||
false,
|
||||
false,
|
||||
m_configuration.ApplicationName,
|
||||
30 * 60 * 1000,
|
||||
CurrUserIdentity,
|
||||
null
|
||||
);
|
||||
|
||||
// Assign the created session
|
||||
if (session != null && session.Connected)
|
||||
{
|
||||
m_session = session;
|
||||
}
|
||||
|
||||
// Session created successfully.
|
||||
lgInfo($"New Session Created with SessionName = {m_session.SessionName}");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lgError($"Create Session Error : {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disconnects the session.
|
||||
/// </summary>
|
||||
public void Disconnect()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (m_session != null)
|
||||
{
|
||||
lgInfo("Disconnecting...");
|
||||
|
||||
m_session.Close();
|
||||
m_session.Dispose();
|
||||
m_session = null;
|
||||
|
||||
// Log Session Disconnected event
|
||||
lgInfo("Session Disconnected.");
|
||||
}
|
||||
else
|
||||
{
|
||||
lgError("Session not created!");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lgError($"Disconnect Error : {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a SINGLE of nodes value from Server
|
||||
/// </summary>
|
||||
/// <param name="reqNodeId"></param>
|
||||
/// <returns></returns>
|
||||
public string ReadNode(NodeId reqNodeId)
|
||||
{
|
||||
string answ = "";
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lgError("Session not connected!");
|
||||
return answ;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//#region Read a node by calling the Read Service
|
||||
|
||||
//// build a list of nodes to be read
|
||||
//ReadValueIdCollection nodesToRead = new ReadValueIdCollection()
|
||||
//{
|
||||
// // Value of ServerStatus
|
||||
// new ReadValueId() { NodeId = Variables.Server_ServerStatus, AttributeId = Attributes.Value },
|
||||
// // BrowseName of ServerStatus_StartTime
|
||||
// new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.BrowseName },
|
||||
// // Value of ServerStatus_StartTime
|
||||
// new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.Value }
|
||||
//};
|
||||
|
||||
//// Read the node attributes
|
||||
//lgInfo("Reading nodes...");
|
||||
|
||||
//// Call Read Service
|
||||
//m_session.Read(
|
||||
// null,
|
||||
// 0,
|
||||
// TimestampsToReturn.Both,
|
||||
// nodesToRead,
|
||||
// out DataValueCollection resultsValues,
|
||||
// out DiagnosticInfoCollection diagnosticInfos);
|
||||
|
||||
//// Validate the results
|
||||
//m_validateResponse(resultsValues, nodesToRead);
|
||||
|
||||
//// Display the results.
|
||||
//foreach (DataValue result in resultsValues)
|
||||
//{
|
||||
// lgInfo("Read Value = {0} , StatusCode = {1}", result.Value, result.StatusCode);
|
||||
//}
|
||||
|
||||
//#endregion Read a node by calling the Read Service
|
||||
|
||||
#region Read the Value attribute of a node by calling the Session.ReadValue method
|
||||
|
||||
try
|
||||
{
|
||||
DataValue resp = m_session.ReadValue(reqNodeId);
|
||||
answ = $"{resp.Value}";
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
// Log Error
|
||||
lgError($"ReadValue Error : {Environment.NewLine}{exc}");
|
||||
}
|
||||
|
||||
#endregion Read the Value attribute of a node by calling the Session.ReadValue method
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lgError($"Read Nodes Error : {ex.Message}.");
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a SINGLE of nodes value (RAW) from Server
|
||||
/// </summary>
|
||||
/// <param name="reqNodeId"></param>
|
||||
/// <returns></returns>
|
||||
public object ReadNodeRaw(NodeId reqNodeId)
|
||||
{
|
||||
object answ = null;
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lgError("Session not connected!");
|
||||
return answ;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
#region Read the Value attribute of a node by calling the Session.ReadValue method
|
||||
|
||||
try
|
||||
{
|
||||
DataValue resp = m_session.ReadValue(reqNodeId);
|
||||
answ = resp;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
// Log Error
|
||||
lgError($"ReadNodeRaw Error 01: {Environment.NewLine}{exc}");
|
||||
}
|
||||
|
||||
#endregion Read the Value attribute of a node by calling the Session.ReadValue method
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lgError($"ReadNodeRaw Error 02: {ex.Message}.");
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a list of nodes from Server
|
||||
/// </summary>
|
||||
public void ReadNodes()
|
||||
{
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lgError("Session not connected!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
#region Read a node by calling the Read Service
|
||||
|
||||
// build a list of nodes to be read
|
||||
ReadValueIdCollection nodesToRead = new ReadValueIdCollection()
|
||||
{
|
||||
// Value of ServerStatus
|
||||
new ReadValueId() { NodeId = Variables.Server_ServerStatus, AttributeId = Attributes.Value },
|
||||
// BrowseName of ServerStatus_StartTime
|
||||
new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.BrowseName },
|
||||
// Value of ServerStatus_StartTime
|
||||
new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.Value }
|
||||
};
|
||||
|
||||
// Read the node attributes
|
||||
lgInfo("Reading nodes...");
|
||||
|
||||
// Call Read Service
|
||||
m_session.Read(
|
||||
null,
|
||||
0,
|
||||
TimestampsToReturn.Both,
|
||||
nodesToRead,
|
||||
out DataValueCollection resultsValues,
|
||||
out DiagnosticInfoCollection diagnosticInfos);
|
||||
|
||||
// Validate the results
|
||||
m_validateResponse(resultsValues, nodesToRead);
|
||||
|
||||
// Display the results.
|
||||
foreach (DataValue result in resultsValues)
|
||||
{
|
||||
lgTrace($"Read Value = {result.Value} , StatusCode = {result.StatusCode}");
|
||||
}
|
||||
|
||||
#endregion Read a node by calling the Read Service
|
||||
|
||||
#region Read the Value attribute of a node by calling the Session.ReadValue method
|
||||
|
||||
// Read Server NamespaceArray
|
||||
lgTrace("Reading Value of NamespaceArray node...");
|
||||
DataValue namespaceArray = m_session.ReadValue(Variables.Server_NamespaceArray);
|
||||
// Display the result
|
||||
lgTrace($"NamespaceArray Value = {namespaceArray}");
|
||||
|
||||
#endregion Read the Value attribute of a node by calling the Session.ReadValue method
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lgError($"Read Nodes Error : {ex.Message}.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create Subscription and MonitoredItems for DataChanges
|
||||
/// </summary>
|
||||
public List<MonitoredItem> SubscribeToDataChanges(Dictionary<string, string> DataList)
|
||||
{
|
||||
List<MonitoredItem> monItList = new List<MonitoredItem>();
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lgError("Session not connected!");
|
||||
return monItList;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Create a subscription for receiving data change notifications
|
||||
|
||||
// Define Subscription parameters
|
||||
Subscription subscription = new Subscription(m_session.DefaultSubscription);
|
||||
|
||||
subscription.DisplayName = "Steamware IOB-WIN Subscription";
|
||||
subscription.PublishingEnabled = true;
|
||||
subscription.PublishingInterval = 1000;
|
||||
|
||||
m_session.AddSubscription(subscription);
|
||||
|
||||
// Create the subscription on Server side
|
||||
subscription.Create();
|
||||
lgInfo($"New Subscription created with SubscriptionId = {subscription.Id}");
|
||||
|
||||
// Create MonitoredItems for data changes
|
||||
foreach (var item in DataList)
|
||||
{
|
||||
MonitoredItem currMonIt = new MonitoredItem(subscription.DefaultItem);
|
||||
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
currMonIt.StartNodeId = new NodeId(item.Key);
|
||||
currMonIt.AttributeId = Attributes.Value;
|
||||
currMonIt.DisplayName = item.Value;
|
||||
currMonIt.SamplingInterval = 1000;
|
||||
currMonIt.Notification += OnMonitoredItemNotification;
|
||||
subscription.AddItem(currMonIt);
|
||||
monItList.Add(currMonIt);
|
||||
}
|
||||
|
||||
#if false
|
||||
MonitoredItem IO_120_00_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
IO_120_00_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_120.00");
|
||||
IO_120_00_MonitoredItem.AttributeId = Attributes.Value;
|
||||
IO_120_00_MonitoredItem.DisplayName = "IO_120 Variable";
|
||||
IO_120_00_MonitoredItem.SamplingInterval = 1000;
|
||||
IO_120_00_MonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
subscription.AddItem(IO_120_00_MonitoredItem);
|
||||
|
||||
MonitoredItem IO_120_01_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
IO_120_01_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_120.01");
|
||||
IO_120_01_MonitoredItem.AttributeId = Attributes.Value;
|
||||
IO_120_01_MonitoredItem.DisplayName = "IO_120_01 Variable";
|
||||
IO_120_01_MonitoredItem.SamplingInterval = 1000;
|
||||
IO_120_01_MonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
subscription.AddItem(IO_120_01_MonitoredItem);
|
||||
|
||||
MonitoredItem IO_130_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
IO_130_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_130");
|
||||
IO_130_MonitoredItem.AttributeId = Attributes.Value;
|
||||
IO_130_MonitoredItem.DisplayName = "IO_130 Variable";
|
||||
IO_130_MonitoredItem.SamplingInterval = 1000;
|
||||
IO_130_MonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
subscription.AddItem(IO_130_MonitoredItem);
|
||||
|
||||
MonitoredItem IO_135_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
IO_135_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_135");
|
||||
IO_135_MonitoredItem.AttributeId = Attributes.Value;
|
||||
IO_135_MonitoredItem.DisplayName = "IO_135 Variable";
|
||||
IO_135_MonitoredItem.SamplingInterval = 1000;
|
||||
IO_135_MonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
subscription.AddItem(IO_135_MonitoredItem);
|
||||
|
||||
MonitoredItem IO_140_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
IO_140_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_140");
|
||||
IO_140_MonitoredItem.AttributeId = Attributes.Value;
|
||||
IO_140_MonitoredItem.DisplayName = "IO_140 Variable";
|
||||
IO_140_MonitoredItem.SamplingInterval = 1000;
|
||||
IO_140_MonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
subscription.AddItem(IO_140_MonitoredItem);
|
||||
|
||||
//MonitoredItem intMonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
//// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
//intMonitoredItem.StartNodeId = new NodeId("ns=2;s=Scalar_Simulation_Int32");
|
||||
//intMonitoredItem.AttributeId = Attributes.Value;
|
||||
//intMonitoredItem.DisplayName = "Int32 Variable";
|
||||
//intMonitoredItem.SamplingInterval = 1000;
|
||||
//intMonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
|
||||
//subscription.AddItem(intMonitoredItem);
|
||||
|
||||
//MonitoredItem floatMonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
//// Float Node - Objects\CTT\Scalar\Simulation\Float
|
||||
//floatMonitoredItem.StartNodeId = new NodeId("ns=2;s=Scalar_Simulation_Float");
|
||||
//floatMonitoredItem.AttributeId = Attributes.Value;
|
||||
//floatMonitoredItem.DisplayName = "Float Variable";
|
||||
//floatMonitoredItem.SamplingInterval = 1000;
|
||||
//floatMonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
|
||||
//subscription.AddItem(floatMonitoredItem);
|
||||
|
||||
//MonitoredItem stringMonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
//// String Node - Objects\CTT\Scalar\Simulation\String
|
||||
//stringMonitoredItem.StartNodeId = new NodeId("ns=2;s=Scalar_Simulation_String");
|
||||
//stringMonitoredItem.AttributeId = Attributes.Value;
|
||||
//stringMonitoredItem.DisplayName = "String Variable";
|
||||
//stringMonitoredItem.SamplingInterval = 1000;
|
||||
//stringMonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
|
||||
//subscription.AddItem(stringMonitoredItem);
|
||||
#endif
|
||||
|
||||
// Create the monitored items on Server side
|
||||
subscription.ApplyChanges();
|
||||
lgInfo($"MonitoredItems created for SubscriptionId = {subscription.Id}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
lgError($"Subscribe error: {ex.Message}");
|
||||
}
|
||||
return monItList;
|
||||
}
|
||||
|
||||
/// Write a list of nodes to the Server </summary>
|
||||
public void WriteNodes(List<WriteValue> node2Write)
|
||||
{
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lgError("Session not connected!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Write the configured nodes
|
||||
WriteValueCollection nodesToWrite = new WriteValueCollection();
|
||||
nodesToWrite.AddRange(node2Write);
|
||||
|
||||
// Write the node attributes
|
||||
StatusCodeCollection results = null;
|
||||
DiagnosticInfoCollection diagnosticInfos;
|
||||
lgDebug("Writing nodes...");
|
||||
|
||||
// Call Write Service
|
||||
m_session.Write(null,
|
||||
nodesToWrite,
|
||||
out results,
|
||||
out diagnosticInfos);
|
||||
|
||||
// Validate the response
|
||||
m_validateResponse(results, nodesToWrite);
|
||||
|
||||
// Display the results.
|
||||
lgDebug("Write Results :");
|
||||
|
||||
foreach (StatusCode writeResult in results)
|
||||
{
|
||||
lgDebug($" {writeResult}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lgError($"Write Nodes Error : {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a list of nodes to the Server
|
||||
/// </summary>
|
||||
public void WriteSingleNode(WriteValue node2Write)
|
||||
{
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lgError("Session not connected!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Write the configured nodes
|
||||
WriteValueCollection nodesToWrite = new WriteValueCollection();
|
||||
|
||||
nodesToWrite.Add(node2Write);
|
||||
|
||||
// Write the node attributes
|
||||
StatusCodeCollection results = null;
|
||||
DiagnosticInfoCollection diagnosticInfos;
|
||||
lgDebug("Writing nodes...");
|
||||
|
||||
// Call Write Service
|
||||
m_session.Write(null,
|
||||
nodesToWrite,
|
||||
out results,
|
||||
out diagnosticInfos);
|
||||
|
||||
// Validate the response
|
||||
m_validateResponse(results, nodesToWrite);
|
||||
|
||||
// Display the results.
|
||||
lgDebug("Write Results :");
|
||||
|
||||
foreach (StatusCode writeResult in results)
|
||||
{
|
||||
lgDebug(" {writeResult}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lgError($"Write Nodes Error : {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a list of nodes to the Server
|
||||
/// </summary>
|
||||
public void WriteTestNodes()
|
||||
{
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lgError("Session not connected!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// scrivo vaslori a caso.. hhmm odierni
|
||||
int hhmm = 9876;
|
||||
int.TryParse(DateTime.Now.ToString("HHmm"), out hhmm);
|
||||
// Write the configured nodes
|
||||
WriteValueCollection nodesToWrite = new WriteValueCollection();
|
||||
|
||||
// Int32 Node - Objects\CTT\Scalar\Scalar_Static\Int32
|
||||
WriteValue commWriteVal = new WriteValue();
|
||||
commWriteVal.NodeId = new NodeId("ns=4;s=IO_151");
|
||||
commWriteVal.AttributeId = Attributes.Value;
|
||||
commWriteVal.Value = new DataValue();
|
||||
commWriteVal.Value.Value = (int)hhmm - 10;
|
||||
nodesToWrite.Add(commWriteVal);
|
||||
|
||||
WriteValue artWriteVal = new WriteValue();
|
||||
artWriteVal.NodeId = new NodeId("ns=4;s=IO_151");
|
||||
artWriteVal.AttributeId = Attributes.Value;
|
||||
artWriteVal.Value = new DataValue();
|
||||
artWriteVal.Value.Value = (int)hhmm;
|
||||
nodesToWrite.Add(artWriteVal);
|
||||
|
||||
WriteValue qtyWriteVal = new WriteValue();
|
||||
qtyWriteVal.NodeId = new NodeId("ns=4;s=IO_153");
|
||||
qtyWriteVal.AttributeId = Attributes.Value;
|
||||
qtyWriteVal.Value = new DataValue();
|
||||
qtyWriteVal.Value.Value = (int)hhmm + 10;
|
||||
nodesToWrite.Add(qtyWriteVal);
|
||||
|
||||
#if false
|
||||
//// Int32 Node - Objects\CTT\Scalar\Scalar_Static\Int32
|
||||
//WriteValue intWriteVal = new WriteValue();
|
||||
//intWriteVal.NodeId = new NodeId("ns=2;s=Scalar_Static_Int32");
|
||||
//intWriteVal.AttributeId = Attributes.Value;
|
||||
//intWriteVal.Value = new DataValue();
|
||||
//intWriteVal.Value.Value = (int)100;
|
||||
//nodesToWrite.Add(intWriteVal);
|
||||
|
||||
//// Float Node - Objects\CTT\Scalar\Scalar_Static\Float
|
||||
//WriteValue floatWriteVal = new WriteValue();
|
||||
//floatWriteVal.NodeId = new NodeId("ns=2;s=Scalar_Static_Float");
|
||||
//floatWriteVal.AttributeId = Attributes.Value;
|
||||
//floatWriteVal.Value = new DataValue();
|
||||
//floatWriteVal.Value.Value = (float)100.5;
|
||||
//nodesToWrite.Add(floatWriteVal);
|
||||
|
||||
//// String Node - Objects\CTT\Scalar\Scalar_Static\String
|
||||
//WriteValue stringWriteVal = new WriteValue();
|
||||
//stringWriteVal.NodeId = new NodeId("ns=2;s=Scalar_Static_String");
|
||||
//stringWriteVal.AttributeId = Attributes.Value;
|
||||
//stringWriteVal.Value = new DataValue();
|
||||
//stringWriteVal.Value.Value = "String Test";
|
||||
//nodesToWrite.Add(stringWriteVal);
|
||||
#endif
|
||||
|
||||
// Write the node attributes
|
||||
StatusCodeCollection results = null;
|
||||
DiagnosticInfoCollection diagnosticInfos;
|
||||
lgDebug("Writing nodes...");
|
||||
|
||||
// Call Write Service
|
||||
m_session.Write(null,
|
||||
nodesToWrite,
|
||||
out results,
|
||||
out diagnosticInfos);
|
||||
|
||||
// Validate the response
|
||||
m_validateResponse(results, nodesToWrite);
|
||||
|
||||
// Display the results.
|
||||
lgDebug("Write Results :");
|
||||
|
||||
foreach (StatusCode writeResult in results)
|
||||
{
|
||||
lgDebug($" {writeResult}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lgError($"Write Nodes Error : {ex.Message}.");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected static bool isLogVerbose = false;
|
||||
protected static Logger lg;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Effettua logging DEBUG corretto impostanto anche la variabile IOB prima di scrivere...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
protected void lgDebug(string message)
|
||||
{
|
||||
lg.Factory.Configuration.Variables["codIOB"] = currIob;
|
||||
lg.Info(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
protected void lgError(string message)
|
||||
{
|
||||
lg.Factory.Configuration.Variables["codIOB"] = currIob;
|
||||
lg.Error(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
protected void lgInfo(string message)
|
||||
{
|
||||
lg.Factory.Configuration.Variables["codIOB"] = currIob;
|
||||
lg.Info(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua logging TRACE corretto impostanto anche la variabile IOB prima di scrivere...
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
protected void lgTrace(string message)
|
||||
{
|
||||
lg.Factory.Configuration.Variables["codIOB"] = currIob;
|
||||
lg.Trace(message);
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private readonly string currIob;
|
||||
private readonly Action<IList, IList> m_validateResponse;
|
||||
private ApplicationConfiguration m_configuration;
|
||||
private Session m_session;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Handles the certificate validation event. This event is triggered every time an
|
||||
/// untrusted certificate is received from the server.
|
||||
/// </summary>
|
||||
private void CertificateValidation(CertificateValidator sender, CertificateValidationEventArgs e)
|
||||
{
|
||||
bool certificateAccepted = true;
|
||||
|
||||
// **** Implement a custom logic to decide if the certificate should be accepted or not
|
||||
// and set certificateAccepted flag accordingly. The certificate can be retrieved from
|
||||
// the e.Certificate field ***
|
||||
|
||||
ServiceResult error = e.Error;
|
||||
while (error != null)
|
||||
{
|
||||
lgError($"{error.StatusCode} | {error.Code} | {error.LocalizedText}");
|
||||
error = error.InnerResult;
|
||||
}
|
||||
|
||||
if (certificateAccepted)
|
||||
{
|
||||
lgInfo($"Untrusted Certificate accepted. SubjectName = {e.Certificate.SubjectName}");
|
||||
}
|
||||
|
||||
e.AcceptAll = certificateAccepted;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle DataChange notifications from Server
|
||||
/// </summary>
|
||||
private void OnMonitoredItemNotification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Log MonitoredItem Notification event
|
||||
MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
|
||||
|
||||
// sollevo evento notifica vaziazione MonitoredItem
|
||||
if (eh_MonItChange != null)
|
||||
{
|
||||
eh_MonItChange(this, new opcUaMonitItemChange(monitoredItem, notification));
|
||||
}
|
||||
lgTrace($"Notification Received | Variable: {monitoredItem.DisplayName} | Value: {notification.Value}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
lgError($"OnMonitoredItemNotification error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"ConnectionStrings": {
|
||||
"Redis": "redis01.ufficio:26379,serviceName=devel,DefaultDatabase=7,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,password=nkc.password",
|
||||
"AuthConnection": "Server=localhost;port=3306;database=GWMS;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
|
||||
"DefaultConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
|
||||
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Egalware_24068!;sslmode=None;",
|
||||
"MP.MONO.Data": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;"
|
||||
},
|
||||
"DbConfig": {
|
||||
"Server": "10.74.82.230",
|
||||
"nKey": "MONO",
|
||||
"sKey": "Calcium0xide-CaO"
|
||||
},
|
||||
"MachineId": 1,
|
||||
"maxRecord": 15,
|
||||
"ExternalProviders": {
|
||||
"MailKit": {
|
||||
"SMTP": {
|
||||
"Address": "smtp.gmail.com",
|
||||
"Port": "465",
|
||||
"Account": "steamwarebot@gmail.com",
|
||||
"Password": "drmfsls16",
|
||||
"SenderEmail": "steamwarebot@gmail.com",
|
||||
"SenderName": "Steamware Email BOT"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Endpoint": {
|
||||
"IpAddress": "192.168.0.2",
|
||||
"Port": "4840",
|
||||
"PingMsTimeout": 1500
|
||||
},
|
||||
"ENABLE_DATA_FILTER": true,
|
||||
"ENABLE_CLI_RESTART": true,
|
||||
"logEvery": 10,
|
||||
"OPC_PARAM_CONF": "MULTIAX.json",
|
||||
"pingTestSec": 5,
|
||||
"verbose": false,
|
||||
"verboseLogTOut": 60
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
[
|
||||
{
|
||||
"description": "General Alarm",
|
||||
"tipoMem": "DInt",
|
||||
"memAddr": "40901",
|
||||
"index": 901,
|
||||
"size": 2,
|
||||
"messages": [
|
||||
"Alarm 001",
|
||||
"Alarm 002",
|
||||
"Alarm 003",
|
||||
"Alarm 004",
|
||||
"Alarm 005",
|
||||
"Alarm 006",
|
||||
"Alarm 007",
|
||||
"Alarm 008",
|
||||
"Alarm 009",
|
||||
"Alarm 010",
|
||||
"Alarm 011",
|
||||
"Alarm 012",
|
||||
"##Alarm 013",
|
||||
"##Alarm 014",
|
||||
"##Alarm 015",
|
||||
"##Alarm 016"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Secondary Alarm",
|
||||
"tipoMem": "DInt",
|
||||
"memAddr": "40907",
|
||||
"index": 907,
|
||||
"size": 2,
|
||||
"messages": [
|
||||
"Warning 001",
|
||||
"Warning 002",
|
||||
"Warning 003",
|
||||
"Warning 004",
|
||||
"Warning 005",
|
||||
"Warning 006",
|
||||
"Warning 007",
|
||||
"Warning 008",
|
||||
"##Warning 009",
|
||||
"##Warning 010",
|
||||
"##Warning 011",
|
||||
"##Warning 012",
|
||||
"Warning 013",
|
||||
"Warning 014",
|
||||
"Warning 015",
|
||||
"Warning 016"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,129 @@
|
||||
{
|
||||
"BrowseFullVal": "ns=1;s=OSAI-PLC",
|
||||
"BrowseNSIndex": 4,
|
||||
"BrowseValue": 5001,
|
||||
"keyPartCount": "50_2_COUNTER CYCLE",
|
||||
"keyPartReq": "",
|
||||
"keyPartId": "",
|
||||
"keyProgName": "",
|
||||
"keyRunMode": "51_1_MODE",
|
||||
"pingAsPowerOn": true,
|
||||
"condWork": [
|
||||
{
|
||||
"keyName": "1_1_MACHINE STATUS",
|
||||
"targetValue": "ON"
|
||||
}
|
||||
],
|
||||
"condPowerOn": {
|
||||
"checkMode": "AND",
|
||||
"checkList": [
|
||||
{
|
||||
"keyName": "1_1_MACHINE STATUS",
|
||||
"targetValue": "ON"
|
||||
},
|
||||
{
|
||||
"keyName": "51_1_MODE",
|
||||
"targetValue": "AUTO"
|
||||
},
|
||||
{
|
||||
"keyName": "50_1_STATUS",
|
||||
"targetValue": "RUN"
|
||||
}
|
||||
]
|
||||
},
|
||||
"condReady": {
|
||||
"checkMode": "AND",
|
||||
"checkList": [
|
||||
{
|
||||
"keyName": "51_1_MODE",
|
||||
"targetValue": "AUTO"
|
||||
}
|
||||
]
|
||||
},
|
||||
"condManual": {
|
||||
"checkMode": "AND",
|
||||
"checkList": [
|
||||
{
|
||||
"keyName": "51_1_MODE",
|
||||
"targetValue": "HOLD"
|
||||
}
|
||||
]
|
||||
},
|
||||
"condEStop": {
|
||||
"checkMode": "AND",
|
||||
"checkList": [
|
||||
{
|
||||
"keyName": "IO_121.02",
|
||||
"targetValue": "True"
|
||||
}
|
||||
]
|
||||
},
|
||||
"condError": {
|
||||
"checkMode": "AND",
|
||||
"checkList": [
|
||||
{
|
||||
"keyName": "IO_120.08",
|
||||
"targetValue": "True"
|
||||
}
|
||||
]
|
||||
},
|
||||
"condCountEnabled": {
|
||||
"checkMode": "AND",
|
||||
"checkList": []
|
||||
},
|
||||
"condWarmUpCoolDown": {
|
||||
"checkMode": "OR",
|
||||
"checkList": [
|
||||
{
|
||||
"keyName": "IO_120.04",
|
||||
"targetValue": "True"
|
||||
},
|
||||
{
|
||||
"keyName": "IO_120.05",
|
||||
"targetValue": "True"
|
||||
}
|
||||
]
|
||||
},
|
||||
"fluxLogVeto": [
|
||||
"L2p1CommonVariable"
|
||||
],
|
||||
"itemTranslation": {
|
||||
"avail": "Machine Available",
|
||||
"rstat": "Execution Mode",
|
||||
"mode": "Controller Mode",
|
||||
"ncprog": "Program Name",
|
||||
"IO_150": "Qta Prodotta (metri)",
|
||||
"lpremain": "Qta Richiesta",
|
||||
"fdovrd": "PATH FEED OVERRIDE",
|
||||
"rovrd": "PATH RAPID OVERRIDE"
|
||||
},
|
||||
"paramsEndThresh": {
|
||||
"InvDDone": 50
|
||||
},
|
||||
"mMapWrite": {
|
||||
"setPzComm": {
|
||||
"name": "setPzComm",
|
||||
"description": "Qty",
|
||||
"tipoMem": "Int",
|
||||
"memAddr": "ns=4;s=IO_153",
|
||||
"index": 0,
|
||||
"size": -1
|
||||
},
|
||||
"setComm": {
|
||||
"name": "setComm",
|
||||
"description": "Commessa",
|
||||
"tipoMem": "String",
|
||||
"memAddr": "ns=4;s=ST80",
|
||||
"index": 0,
|
||||
"size": 20
|
||||
},
|
||||
"setArt": {
|
||||
"name": "setArt",
|
||||
"description": "Articolo",
|
||||
"tipoMem": "String",
|
||||
"memAddr": "ns=4;s=ST80",
|
||||
"index": 20,
|
||||
"size": 20
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
[
|
||||
{
|
||||
"Order": 3,
|
||||
"Type": "SPEED-5000-10000",
|
||||
"Title": "SPEED",
|
||||
"Value": "4000",
|
||||
"ValueNum": 4000,
|
||||
"MinVal": 1000,
|
||||
"MaxVal": 10000,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-gauge-high",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 2,
|
||||
"Type": "FEED-3000-5000",
|
||||
"Title": "FEED",
|
||||
"Value": "2500",
|
||||
"ValueNum": 2500,
|
||||
"MinVal": 1000,
|
||||
"MaxVal": 5000,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-gauge-high",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 1,
|
||||
"Type": "LOAD",
|
||||
"Title": "SPINDLE LOAD",
|
||||
"Value": "30",
|
||||
"ValueNum": 30,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 4,
|
||||
"Type": "POS",
|
||||
"Title": "X POS",
|
||||
"Value": "1500",
|
||||
"ValueNum": 1500,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 5000,
|
||||
"DisplFormat": "N2",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"CssIcon": "fa-solid fa-ruler-horizontal",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 5,
|
||||
"Type": "POS",
|
||||
"Title": "Y POS",
|
||||
"Value": "5000",
|
||||
"ValueNum": 5000,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10000,
|
||||
"DisplFormat": "N2",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"CssIcon": "fa-solid fa-ruler-horizontal",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 6,
|
||||
"Type": "POS",
|
||||
"Title": "Z POS",
|
||||
"Value": "-1500",
|
||||
"ValueNum": -1500,
|
||||
"MinVal": -3000,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "N2",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"CssIcon": "fa-solid fa-ruler-horizontal",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 7,
|
||||
"Type": "POS",
|
||||
"Title": "A POS",
|
||||
"Value": "150",
|
||||
"ValueNum": 150,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 360,
|
||||
"DisplFormat": "N3",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"CssIcon": "fa-solid fa-rotate-right",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
},
|
||||
{
|
||||
"Order": 8,
|
||||
"Type": "POS",
|
||||
"Title": "B POS",
|
||||
"Value": "150",
|
||||
"ValueNum": 150,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 360,
|
||||
"DisplFormat": "N3",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"CssIcon": "fa-solid fa-rotate-right",
|
||||
"SamplePeriod": 180,
|
||||
"VcFunc": "MEDIAN"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,32 @@
|
||||
param([string]$ProjectDir, [string]$ProjectPath);
|
||||
|
||||
$FileMajMin = "..\MajMin.vers"
|
||||
$FileVers = "Resources\VersNum.txt"
|
||||
$FileManIn = "Resources\manifest-original.xml"
|
||||
$FileManOut = "Resources\manifest.xml"
|
||||
$FileCLogIn = "Resources\ChangeLog-original.html"
|
||||
$FileCLogOut = "Resources\ChangeLog.html"
|
||||
$MajMin = Get-Content $FileMajMin
|
||||
$currentDate = get-date -format yyMM;
|
||||
$currentTime = get-date -format dHH;
|
||||
$find = "<Version>(.|\n)*?</Version>";
|
||||
$currRelNum = $MajMin + $currentDate +"." + $currentTime
|
||||
$replace = "<Version>" + $MajMin + $currentDate +"." + $currentTime + "</Version>";
|
||||
$csproj = Get-Content $ProjectPath
|
||||
$csprojUpdated = $csproj -replace $find, $replace
|
||||
|
||||
Set-Content -Path $ProjectPath -Value $csprojUpdated
|
||||
Set-Content -Path $FileVers -Value $currRelNum
|
||||
|
||||
# replace x manifest
|
||||
$manData = Get-Content $FileManIn
|
||||
$manData = $manData -replace "1.0.0.0", $currRelNum
|
||||
$manData = $manData -replace "{{DIRNAME}}", "MP.MONO.ADAPTER"
|
||||
$manData = $manData -replace "{{BRANCHNAME}}", "stable/LAST"
|
||||
$manData = $manData -replace "{{PACKNAME}}", "MP.Mon"
|
||||
Set-Content -Path $FileManOut -Value $manData
|
||||
|
||||
# replace x ChangeLog
|
||||
$clogData = Get-Content $FileCLogIn
|
||||
$clogData = $clogData -replace "{{CURRENT-REL}}", $currRelNum
|
||||
Set-Content -Path $FileCLogOut -Value $clogData
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.2.32519.379
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.MONO.ADAPTER.OPC", "MP.MONO.ADAPTER.OPC\MP.MONO.ADAPTER.OPC.csproj", "{458FD824-7804-4CF9-8C43-463C1F5659DA}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{458FD824-7804-4CF9-8C43-463C1F5659DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{458FD824-7804-4CF9-8C43-463C1F5659DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{458FD824-7804-4CF9-8C43-463C1F5659DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{458FD824-7804-4CF9-8C43-463C1F5659DA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {3811E8B4-1DD3-4841-9840-1B1A08782CD3}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,38 @@
|
||||
[
|
||||
{
|
||||
"Order": 0,
|
||||
"ExtCode": "ns=5;i=1278",
|
||||
"Type": "ACTLOG",
|
||||
"Title": "User LC001",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N3",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 1,
|
||||
"ExtCode": "ns=5;i=1279",
|
||||
"Type": "ACTLOG",
|
||||
"Title": "User LC001 SetPoint",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N3",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 2,
|
||||
"ExtCode": "ns=5;i=1280",
|
||||
"Type": "ACTLOG",
|
||||
"Title": "User LC001 Ctrl OUT",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N3",
|
||||
"IsNumeric": true
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,52 @@
|
||||
[
|
||||
{
|
||||
"description": "General Alarm",
|
||||
"tipoMem": "DInt",
|
||||
"memAddr": "40901",
|
||||
"index": 901,
|
||||
"size": 2,
|
||||
"messages": [
|
||||
"Alarm 001",
|
||||
"Alarm 002",
|
||||
"Alarm 003",
|
||||
"Alarm 004",
|
||||
"Alarm 005",
|
||||
"Alarm 006",
|
||||
"Alarm 007",
|
||||
"Alarm 008",
|
||||
"##Alarm 009",
|
||||
"##Alarm 010",
|
||||
"##Alarm 011",
|
||||
"##Alarm 012",
|
||||
"##Alarm 013",
|
||||
"##Alarm 014",
|
||||
"##Alarm 015",
|
||||
"##Alarm 016"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Secondary Alarm",
|
||||
"tipoMem": "DInt",
|
||||
"memAddr": "40907",
|
||||
"index": 907,
|
||||
"size": 2,
|
||||
"messages": [
|
||||
"Warning 001",
|
||||
"Warning 002",
|
||||
"Warning 003",
|
||||
"Warning 004",
|
||||
"Warning 005",
|
||||
"Warning 006",
|
||||
"##Warning 007",
|
||||
"##Warning 008",
|
||||
"##Warning 009",
|
||||
"Warning 010",
|
||||
"Warning 011",
|
||||
"Warning 012",
|
||||
"Warning 013",
|
||||
"Warning 014",
|
||||
"Warning 015",
|
||||
"Warning 016"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,10 @@
|
||||
[
|
||||
{
|
||||
"source": "NC Alarm",
|
||||
"messages": []
|
||||
},
|
||||
{
|
||||
"source": "PLC Alarm",
|
||||
"messages": []
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"Order": 1,
|
||||
"ExtCode": "ns=5;i=1274",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM NC",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 2,
|
||||
"ExtCode": "ns=5;i=1259",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 01",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,194 @@
|
||||
[
|
||||
{
|
||||
"Order": 1,
|
||||
"ExtCode": "ns=1;s=3_1_ALARM NC",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM NC",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 2,
|
||||
"ExtCode": "ns=1;s=3_2_ALARM PLC 1",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 01",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 3,
|
||||
"ExtCode": "ns=1;s=3_3_ALARM PLC 2",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 02",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 4,
|
||||
"ExtCode": "ns=1;s=3_4_ALARM PLC 3",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 03",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 5,
|
||||
"ExtCode": "ns=1;s=3_5_ALARM PLC 4",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 04",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 6,
|
||||
"ExtCode": "ns=1;s=3_6_ALARM PLC 5",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 05",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 7,
|
||||
"ExtCode": "ns=1;s=3_7_ALARM PLC 6",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 06",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 8,
|
||||
"ExtCode": "ns=1;s=3_8_ALARM PLC 7",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 07",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 9,
|
||||
"ExtCode": "ns=1;s=3_9_ALARM PLC 8",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 08",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 10,
|
||||
"ExtCode": "ns=1;s=3_10_ALARM PLC 9",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 09",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 11,
|
||||
"ExtCode": "ns=1;s=3_11_ALARM PLC 10",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 10",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 12,
|
||||
"ExtCode": "ns=1;s=3_12_ALARM PLC 11",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 11",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 13,
|
||||
"ExtCode": "ns=1;s=3_13_ALARM PLC 12",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 12",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 14,
|
||||
"ExtCode": "ns=1;s=3_14_ALARM PLC 13",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 13",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 15,
|
||||
"ExtCode": "ns=1;s=3_15_ALARM PLC 14",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 14",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 16,
|
||||
"ExtCode": "ns=1;s=3_16_ALARM PLC 15",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 15",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,194 @@
|
||||
[
|
||||
{
|
||||
"Order": 1,
|
||||
"ExtCode": "ns=1;s=3_1_ALARM NC",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM NC",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 2,
|
||||
"ExtCode": "ns=1;s=3_2_ALARM PLC 1",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 01",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 3,
|
||||
"ExtCode": "ns=1;s=3_3_ALARM PLC 2",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 02",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 4,
|
||||
"ExtCode": "ns=1;s=3_4_ALARM PLC 3",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 03",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 5,
|
||||
"ExtCode": "ns=1;s=3_5_ALARM PLC 4",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 04",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 6,
|
||||
"ExtCode": "ns=1;s=3_6_ALARM PLC 5",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 05",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 7,
|
||||
"ExtCode": "ns=1;s=3_7_ALARM PLC 6",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 06",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 8,
|
||||
"ExtCode": "ns=1;s=3_8_ALARM PLC 7",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 07",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 9,
|
||||
"ExtCode": "ns=1;s=3_9_ALARM PLC 8",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 08",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 10,
|
||||
"ExtCode": "ns=1;s=3_10_ALARM PLC 9",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 09",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 11,
|
||||
"ExtCode": "ns=1;s=3_11_ALARM PLC 10",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 10",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 12,
|
||||
"ExtCode": "ns=1;s=3_12_ALARM PLC 11",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 11",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 13,
|
||||
"ExtCode": "ns=1;s=3_13_ALARM PLC 12",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 12",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 14,
|
||||
"ExtCode": "ns=1;s=3_14_ALARM PLC 13",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 13",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 15,
|
||||
"ExtCode": "ns=1;s=3_15_ALARM PLC 14",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 14",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 16,
|
||||
"ExtCode": "ns=1;s=3_16_ALARM PLC 15",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 15",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"Order": 1,
|
||||
"ExtCode": "ns=5;i=1274",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM NC",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 2,
|
||||
"ExtCode": "ns=5;i=1259",
|
||||
"Type": "ALARM",
|
||||
"Title": "ALARM PLC 01",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 0,
|
||||
"DisplFormat": "",
|
||||
"IsNumeric": false
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,114 @@
|
||||
[
|
||||
{
|
||||
"Order": 1,
|
||||
"ExtCode": "ns=1;s=1_1_MACHINE STATUS",
|
||||
"Type": "STATUS",
|
||||
"Title": "MACHINE STATUS",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 2,
|
||||
"ExtCode": "ns=1;s=500_1_STATUS",
|
||||
"Type": "STATUS",
|
||||
"Title": "PROCESS STATUS",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 20,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 3,
|
||||
"ExtCode": "ns=1;s=501_1_MODE",
|
||||
"Type": "MODE",
|
||||
"Title": "PROCESS MODE",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 4,
|
||||
"ExtCode": "ns=1;s=516_PROC 1 SPINDLE 1 LOAD PC",
|
||||
"HLShow": true,
|
||||
"Type": "LOAD",
|
||||
"Title": "SPINDLE 1 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 5,
|
||||
"ExtCode": "ns=1;s=517_PROC 1 SPINDLE 2 LOAD PC",
|
||||
"HLShow": true,
|
||||
"Type": "LOAD",
|
||||
"Title": "SPINDLE 2 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 6,
|
||||
"ExtCode": "ns=1;s=518_PROC 1 SPINDLE 3 LOAD PC",
|
||||
"HLShow": true,
|
||||
"Type": "LOAD",
|
||||
"Title": "SPINDLE 3 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 7,
|
||||
"ExtCode": "ns=1;s=519_PROC 1 SPINDLE 4 LOAD PC",
|
||||
"HLShow": true,
|
||||
"Type": "LOAD",
|
||||
"Title": "SPINDLE 4 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 7,
|
||||
"ExtCode": "ns=1;s=502_1_RECIPE NAME",
|
||||
"Type": "PROGRAM",
|
||||
"Title": "RECIPE NAME",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,102 @@
|
||||
[
|
||||
{
|
||||
"Order": 1,
|
||||
"ExtCode": "ns=1;s=1_1_MACHINE STATUS",
|
||||
"Type": "STATUS",
|
||||
"Title": "MACHINE STATUS",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 2,
|
||||
"ExtCode": "ns=1;s=500_1_STATUS",
|
||||
"Type": "STATUS",
|
||||
"Title": "PROCESS STATUS",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 20,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 3,
|
||||
"ExtCode": "ns=1;s=501_1_MODE",
|
||||
"Type": "MODE",
|
||||
"Title": "PROCESS MODE",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 4,
|
||||
"ExtCode": "ns=1;s=516_PROC 1 SPINDLE 1 LOAD PC",
|
||||
"HLShow": true,
|
||||
"Type": "LOAD",
|
||||
"Title": "SPINDLE 1 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 5,
|
||||
"ExtCode": "ns=1;s=517_PROC 1 SPINDLE 2 LOAD PC",
|
||||
"HLShow": true,
|
||||
"Type": "LOAD",
|
||||
"Title": "SPINDLE 2 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 6,
|
||||
"ExtCode": "ns=1;s=518_PROC 1 SPINDLE 3 LOAD PC",
|
||||
"HLShow": true,
|
||||
"Type": "LOAD",
|
||||
"Title": "SPINDLE 3 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 7,
|
||||
"ExtCode": "ns=1;s=519_PROC 1 SPINDLE 4 LOAD PC",
|
||||
"HLShow": true,
|
||||
"Type": "LOAD",
|
||||
"Title": "SPINDLE 4 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,96 @@
|
||||
{
|
||||
"BrowseFullVal": "ns=5;i=1240",
|
||||
"Identity": {
|
||||
"UserName": "",
|
||||
"Passwd": ""
|
||||
},
|
||||
"BrowseNSIndex": 1,
|
||||
"BrowseValue": 0,
|
||||
"keyPartCount": "1:507_2_WORKPIECE QTY",
|
||||
"keyPartReq": "",
|
||||
"keyPartId": "",
|
||||
"keyProgName": "1:502_1_RECIPE NAME",
|
||||
"keyRunMode": "",
|
||||
"pingAsPowerOn": true,
|
||||
"condWork": [
|
||||
{
|
||||
"keyName": "1:1_1_MACHINE STATUS",
|
||||
"targetValue": "ON"
|
||||
}
|
||||
],
|
||||
"condWorkOpc": {
|
||||
"checkMode": "AND",
|
||||
"checkList": [
|
||||
{
|
||||
"keyName": "MachineStatus(0)",
|
||||
"targetValue": "4"
|
||||
}
|
||||
]
|
||||
},
|
||||
"condPowerOn": {
|
||||
"checkMode": "OR",
|
||||
"negateValue": true,
|
||||
"checkList": [
|
||||
{
|
||||
"keyName": "1:1_1_MACHINE STATUS",
|
||||
"targetValue": "ON"
|
||||
},
|
||||
{
|
||||
"keyName": "1:500_1_STATUS",
|
||||
"targetValue": "CYCLE"
|
||||
},
|
||||
{
|
||||
"keyName": "1:501_1_MODE",
|
||||
"targetValue": "AUTO"
|
||||
}
|
||||
]
|
||||
},
|
||||
"condReady": {
|
||||
"checkMode": "AND",
|
||||
"checkList": []
|
||||
},
|
||||
"condManual": {
|
||||
"checkMode": "AND",
|
||||
"checkList": []
|
||||
},
|
||||
"condEStop": {
|
||||
"checkMode": "AND",
|
||||
"checkList": []
|
||||
},
|
||||
"condError": {
|
||||
"checkMode": "AND",
|
||||
"checkList": []
|
||||
},
|
||||
"condCountEnabled": {
|
||||
"checkMode": "AND",
|
||||
"checkList": []
|
||||
},
|
||||
"condWarmUpCoolDown": {
|
||||
"checkMode": "OR",
|
||||
"negateValue": true,
|
||||
"checkList": []
|
||||
},
|
||||
"condWarning": {
|
||||
"checkMode": "AND",
|
||||
"checkList": []
|
||||
},
|
||||
"condSetup": {
|
||||
"checkMode": "AND",
|
||||
"checkList": []
|
||||
},
|
||||
"fluxLogVeto": [],
|
||||
"itemTranslation": {
|
||||
"avail": "Machine Available",
|
||||
"rstat": "Execution Mode",
|
||||
"mode": "Controller Mode",
|
||||
"PartName(0)": "Program Name",
|
||||
"PartDone(0)": "Pezzi Prodotti",
|
||||
"PartToDo(0)": "Qta Richiesta",
|
||||
"MachineStatus(0)": "Stato Macchina principale",
|
||||
"MachineStatus(1)": "Stato Macchina secondario",
|
||||
"EmergencyState": "Emergenza",
|
||||
"fdovrd": "PATH FEED OVERRIDE",
|
||||
"rovrd": "PATH RAPID OVERRIDE"
|
||||
},
|
||||
"subscribedItems": []
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
[
|
||||
{
|
||||
"Order": 1,
|
||||
"ExtCode": "ns=3;i=11176",
|
||||
"Type": "STATUS",
|
||||
"Title": "MACHINE STATUS",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"ScaleFactor": 0.1,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 2,
|
||||
"ExtCode": "ns=3;i=11230",
|
||||
"Type": "STATUS",
|
||||
"Title": "PROCESS STATUS",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 20,
|
||||
"ScaleFactor": 0.1,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 3,
|
||||
"ExtCode": "ns=3;i=11236",
|
||||
"Type": "MODE",
|
||||
"Title": "PROCESS MODE",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"ScaleFactor": 0.1,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,110 @@
|
||||
[
|
||||
{
|
||||
"Order": 1,
|
||||
"ExtCode": "ns=1;s=1_1_MACHINE STATUS",
|
||||
"Type": "STATUS",
|
||||
"Title": "MACHINE STATUS",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 2,
|
||||
"ExtCode": "ns=1;s=500_1_STATUS",
|
||||
"Type": "STATUS",
|
||||
"Title": "PROCESS STATUS",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 20,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 3,
|
||||
"ExtCode": "ns=1;s=501_1_MODE",
|
||||
"Type": "MODE",
|
||||
"Title": "PROCESS MODE",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 4,
|
||||
"ExtCode": "ns=1;s=502_1_RECIPE NAME",
|
||||
"Type": "PROGRAM",
|
||||
"Title": "RECIPE NAME",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": false
|
||||
},
|
||||
{
|
||||
"Order": 5,
|
||||
"ExtCode": "ns=1;s=51_P2 PALLET STATUS",
|
||||
"Type": "STATUS",
|
||||
"Title": "P2 PALLET STATUS",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 6,
|
||||
"ExtCode": "ns=1;s=52_P3 PALLET STATUS",
|
||||
"Type": "STATUS",
|
||||
"Title": "P3 PALLET STATUS",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 7,
|
||||
"ExtCode": "ns=1;s=53_P2 EXTERNAL PALLET STATUS",
|
||||
"Type": "STATUS",
|
||||
"Title": "P2 EXTERNAL PALLET STATUS",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 8,
|
||||
"ExtCode": "ns=1;s=54_P3 EXTERNAL PALLET STATUS",
|
||||
"Type": "STATUS",
|
||||
"Title": "P3 EXTERNAL PALLET STATUS",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 9,
|
||||
"ExtCode": "ns=1;s=504_PROC 1 P.P. ORDER",
|
||||
"Type": "ORDER",
|
||||
"Title": "CURR ORDER",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": false
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,110 @@
|
||||
[
|
||||
{
|
||||
"Order": 0,
|
||||
"ExtCode": "ns=1;s=507_2_WORKPIECE QTY",
|
||||
"Type": "QTY",
|
||||
"Title": "PART COUNT",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 1,
|
||||
"ExtCode": "ns=1;s=1_1_MACHINE STATUS",
|
||||
"Type": "STATUS",
|
||||
"Title": "MACHINE STATUS",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 2,
|
||||
"ExtCode": "ns=1;s=500_1_STATUS",
|
||||
"Type": "STATUS",
|
||||
"Title": "PROCESS STATUS",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 20,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 3,
|
||||
"ExtCode": "ns=1;s=501_1_MODE",
|
||||
"Type": "MODE",
|
||||
"Title": "PROCESS MODE",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 4,
|
||||
"ExtCode": "ns=1;s=502_1_RECIPE NAME",
|
||||
"Type": "PROGRAM",
|
||||
"Title": "RECIPE NAME",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 5,
|
||||
"ExtCode": "ns=1;s=51_P2 PALLET STATUS",
|
||||
"Type": "STATUS",
|
||||
"Title": "P2 PALLET STATUS",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 6,
|
||||
"ExtCode": "ns=1;s=52_P3 PALLET STATUS",
|
||||
"Type": "STATUS",
|
||||
"Title": "P3 PALLET STATUS",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 7,
|
||||
"ExtCode": "ns=1;s=53_P2 EXTERNAL PALLET STATUS",
|
||||
"Type": "STATUS",
|
||||
"Title": "P2 EXTERNAL PALLET STATUS",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 8,
|
||||
"ExtCode": "ns=1;s=54_P3 EXTERNAL PALLET STATUS",
|
||||
"Type": "STATUS",
|
||||
"Title": "P3 EXTERNAL PALLET STATUS",
|
||||
"Value": "",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 10,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true
|
||||
}
|
||||
]
|
||||
@@ -54,5 +54,26 @@
|
||||
"Css": "bg-primary text-light",
|
||||
"Priority": 3,
|
||||
"Group": "MANUAL"
|
||||
},
|
||||
{
|
||||
"MModeID": 8,
|
||||
"Description": "ERROR",
|
||||
"Css": "bg-danger text-light",
|
||||
"Priority": 3,
|
||||
"Group": "ERROR"
|
||||
},
|
||||
{
|
||||
"MModeID": 9,
|
||||
"Description": "RESET",
|
||||
"Css": "bg-warning text-light",
|
||||
"Priority": 3,
|
||||
"Group": "MANUAL"
|
||||
},
|
||||
{
|
||||
"MModeID": 10,
|
||||
"Description": "PAUSE",
|
||||
"Css": "bg-warning text-light",
|
||||
"Priority": 3,
|
||||
"Group": "MANUAL"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ApplicationConfiguration
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:ua="http://opcfoundation.org/UA/2008/02/Types.xsd"
|
||||
xmlns="http://opcfoundation.org/UA/SDK/Configuration.xsd"
|
||||
>
|
||||
<ApplicationName>Egalware Console Adapter OPC Client</ApplicationName>
|
||||
<ApplicationUri>urn:localhost:UA:Egalware:MP:MONO:ADAPTER</ApplicationUri>
|
||||
<ProductUri>uri:egalware.com:MP:MONO:ADAPTER</ProductUri>
|
||||
<ApplicationType>Client_1</ApplicationType>
|
||||
|
||||
<SecurityConfiguration>
|
||||
|
||||
<!-- Where the application instance certificate is stored (MachineDefault) -->
|
||||
<ApplicationCertificate>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>%LocalApplicationData%/EgalWare/pki/own</StorePath>
|
||||
<SubjectName>CN=EgalWare Adapter Client, C=IT, S=Bergamo, O=EgalWare, DC=localhost</SubjectName>
|
||||
</ApplicationCertificate>
|
||||
|
||||
<!-- Where the issuer certificate are stored (certificate authorities) -->
|
||||
<TrustedIssuerCertificates>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>%LocalApplicationData%/EgalWare/pki/issuer</StorePath>
|
||||
</TrustedIssuerCertificates>
|
||||
|
||||
<!-- Where the trust list is stored -->
|
||||
<TrustedPeerCertificates>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>%LocalApplicationData%/EgalWare/pki/trusted</StorePath>
|
||||
</TrustedPeerCertificates>
|
||||
|
||||
<!-- The directory used to store invalid certficates for later review by the administrator. -->
|
||||
<RejectedCertificateStore>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>%LocalApplicationData%/EgalWare/pki/rejected</StorePath>
|
||||
</RejectedCertificateStore>
|
||||
|
||||
<!-- WARNING: The following setting (to automatically accept untrusted certificates) should be used
|
||||
for easy debugging purposes ONLY and turned off for production deployments! -->
|
||||
<AutoAcceptUntrustedCertificates>false</AutoAcceptUntrustedCertificates>
|
||||
|
||||
</SecurityConfiguration>
|
||||
|
||||
<TransportConfigurations></TransportConfigurations>
|
||||
|
||||
<TransportQuotas>
|
||||
<OperationTimeout>600000</OperationTimeout>
|
||||
<MaxStringLength>1048576</MaxStringLength>
|
||||
<MaxByteStringLength>1048576</MaxByteStringLength>
|
||||
<MaxArrayLength>65535</MaxArrayLength>
|
||||
<MaxMessageSize>4194304</MaxMessageSize>
|
||||
<MaxBufferSize>65535</MaxBufferSize>
|
||||
<ChannelLifetime>300000</ChannelLifetime>
|
||||
<SecurityTokenLifetime>3600000</SecurityTokenLifetime>
|
||||
</TransportQuotas>
|
||||
|
||||
<ClientConfiguration>
|
||||
<DefaultSessionTimeout>60000</DefaultSessionTimeout>
|
||||
<WellKnownDiscoveryUrls>
|
||||
<ua:String>opc.tcp://{0}:4840</ua:String>
|
||||
<ua:String>http://{0}:52601/UADiscovery</ua:String>
|
||||
<ua:String>http://{0}/UADiscovery/Default.svc</ua:String>
|
||||
</WellKnownDiscoveryUrls>
|
||||
<DiscoveryServers></DiscoveryServers>
|
||||
<MinSubscriptionLifetime>10000</MinSubscriptionLifetime>
|
||||
</ClientConfiguration>
|
||||
|
||||
<Extensions>
|
||||
</Extensions>
|
||||
|
||||
<TraceConfiguration>
|
||||
<OutputFilePath>%LocalApplicationData%/EgalWare/Logs/MP.MONO.ADAPTER.OPC.log.txt</OutputFilePath>
|
||||
<DeleteOnLoad>true</DeleteOnLoad>
|
||||
<!-- Show Only Errors -->
|
||||
<!-- <TraceMasks>1</TraceMasks> -->
|
||||
<!-- Show Only Security and Errors -->
|
||||
<!-- <TraceMasks>513</TraceMasks> -->
|
||||
<!-- Show Only Security, Errors and Trace -->
|
||||
<!-- <TraceMasks>515</TraceMasks> -->
|
||||
<!-- Show Only Security, COM Calls, Errors and Trace -->
|
||||
<!-- <TraceMasks>771</TraceMasks> -->
|
||||
<!-- Show Only Security, Service Calls, Errors and Trace -->
|
||||
<!-- <TraceMasks>523</TraceMasks> -->
|
||||
<!-- Show Only Security, ServiceResultExceptions, Errors and Trace -->
|
||||
<!-- <TraceMasks>519</TraceMasks> -->
|
||||
</TraceConfiguration>
|
||||
|
||||
</ApplicationConfiguration>
|
||||
@@ -0,0 +1,175 @@
|
||||
{
|
||||
"BrowseFullVal": "ns=1;s=OSAI-PLC",
|
||||
"Identity": {
|
||||
"UserName": "",
|
||||
"Passwd": ""
|
||||
},
|
||||
"BrowseNSIndex": 1,
|
||||
"BrowseValue": 0,
|
||||
"keyPartCount": "1:507_2_WORKPIECE QTY",
|
||||
"keyPartReq": "",
|
||||
"keyPartId": "1:504_PROC 1 P.P. ORDER",
|
||||
"keyProgName": "1:502_1_RECIPE NAME",
|
||||
"keyRunMode": "",
|
||||
"pingAsPowerOn": true,
|
||||
"condWork": [
|
||||
{
|
||||
"keyName": "1:1_1_MACHINE STATUS",
|
||||
"targetValue": "ON"
|
||||
}
|
||||
],
|
||||
"condWorkOpc": {
|
||||
"checkMode": "AND",
|
||||
"checkList": [
|
||||
{
|
||||
"keyName": "MachineStatus(0)",
|
||||
"targetValue": "4"
|
||||
}
|
||||
]
|
||||
},
|
||||
"condPowerOn": {
|
||||
"checkMode": "OR",
|
||||
"negateValue": true,
|
||||
"checkList": [
|
||||
{
|
||||
"keyName": "1:1_1_MACHINE STATUS",
|
||||
"targetValue": "ON"
|
||||
},
|
||||
{
|
||||
"keyName": "1:500_1_STATUS",
|
||||
"targetValue": "CYCLE"
|
||||
},
|
||||
{
|
||||
"keyName": "1:501_1_MODE",
|
||||
"targetValue": "AUTO"
|
||||
}
|
||||
]
|
||||
},
|
||||
"condReady": {
|
||||
"checkMode": "AND",
|
||||
"checkList": []
|
||||
},
|
||||
"condManual": {
|
||||
"checkMode": "AND",
|
||||
"checkList": []
|
||||
},
|
||||
"condEStop": {
|
||||
"checkMode": "AND",
|
||||
"checkList": []
|
||||
},
|
||||
"condError": {
|
||||
"checkMode": "AND",
|
||||
"checkList": []
|
||||
},
|
||||
"condCountEnabled": {
|
||||
"checkMode": "AND",
|
||||
"checkList": []
|
||||
},
|
||||
"condWarmUpCoolDown": {
|
||||
"checkMode": "OR",
|
||||
"negateValue": true,
|
||||
"checkList": []
|
||||
},
|
||||
"condWarning": {
|
||||
"checkMode": "AND",
|
||||
"checkList": []
|
||||
},
|
||||
"condSetup": {
|
||||
"checkMode": "AND",
|
||||
"checkList": []
|
||||
},
|
||||
"fluxLogVeto": [],
|
||||
"itemTranslation": {
|
||||
"avail": "Machine Available",
|
||||
"rstat": "Execution Mode",
|
||||
"mode": "Controller Mode",
|
||||
"PartName(0)": "Program Name",
|
||||
"PartDone(0)": "Pezzi Prodotti",
|
||||
"PartToDo(0)": "Qta Richiesta",
|
||||
"MachineStatus(0)": "Stato Macchina principale",
|
||||
"MachineStatus(1)": "Stato Macchina secondario",
|
||||
"EmergencyState": "Emergenza",
|
||||
"fdovrd": "PATH FEED OVERRIDE",
|
||||
"rovrd": "PATH RAPID OVERRIDE"
|
||||
},
|
||||
"subscribedItems": [
|
||||
"ns=1;s=45_P2 AXIS V SW OVT UPPER",
|
||||
"ns=1;s=46_P2 AXIS V SW OVT LOWER",
|
||||
"ns=1;s=47_P2 AXIS V ACTUAL POSITION",
|
||||
"ns=1;s=48_P3 AXIS W SW OVT UPPER",
|
||||
"ns=1;s=49_P3 AXIS W SW OVT LOWER",
|
||||
"ns=1;s=50_P3 AXIS W ACTUAL POSITION",
|
||||
"ns=1;s=515_PROC 1 FEED OVERRIDE",
|
||||
"ns=1;s=516_PROC 1 FEED PROGRAMMED",
|
||||
"ns=1;s=517_PROC 1 FEED ACTUAL",
|
||||
"ns=1;s=518_PROC 1 SPEED OVERRIDE",
|
||||
"ns=1;s=519_PROC 1 SPEED PROGRAMMED",
|
||||
"ns=1;s=520_PROC 1 SPEED ACTUAL",
|
||||
"ns=1;s=521_PROC 1 SPINDLE 1 LOAD PC",
|
||||
"ns=1;s=522_PROC 1 SPINDLE 2 LOAD PC",
|
||||
"ns=1;s=523_PROC 1 SPINDLE 3 LOAD PC",
|
||||
"ns=1;s=524_PROC 1 SPINDLE 4 LOAD PC",
|
||||
"ns=1;s=1_1_MACHINE STATUS",
|
||||
"ns=1;s=3_1_ALARM NC",
|
||||
"ns=1;s=3_2_ALARM PLC 1",
|
||||
"ns=1;s=3_3_ALARM PLC 2",
|
||||
"ns=1;s=3_4_ALARM PLC 3",
|
||||
"ns=1;s=3_5_ALARM PLC 4",
|
||||
"ns=1;s=3_6_ALARM PLC 5",
|
||||
"ns=1;s=3_7_ALARM PLC 6",
|
||||
"ns=1;s=3_8_ALARM PLC 7",
|
||||
"ns=1;s=3_9_ALARM PLC 8",
|
||||
"ns=1;s=3_10_ALARM PLC 9",
|
||||
"ns=1;s=3_11_ALARM PLC 10",
|
||||
"ns=1;s=3_12_ALARM PLC 11",
|
||||
"ns=1;s=3_13_ALARM PLC 12",
|
||||
"ns=1;s=3_14_ALARM PLC 13",
|
||||
"ns=1;s=3_15_ALARM PLC 14",
|
||||
"ns=1;s=3_16_ALARM PLC 15",
|
||||
"ns=1;s=4_1_AXIS 1 LOAD PC",
|
||||
"ns=1;s=4_2_AXIS 2 LOAD PC",
|
||||
"ns=1;s=4_3_AXIS 3 LOAD PC",
|
||||
"ns=1;s=4_4_AXIS 4 LOAD PC",
|
||||
"ns=1;s=4_5_AXIS 5 LOAD PC",
|
||||
"ns=1;s=4_6_AXIS 6 LOAD PC",
|
||||
"ns=1;s=4_7_AXIS 7 LOAD PC",
|
||||
"ns=1;s=4_8_AXIS 8 LOAD PC",
|
||||
"ns=1;s=4_9_AXIS 9 LOAD PC",
|
||||
"ns=1;s=4_10_AXIS 10 LOAD PC",
|
||||
"ns=1;s=4_11_AXIS 11 LOAD PC",
|
||||
"ns=1;s=4_12_AXIS 12 LOAD PC",
|
||||
"ns=1;s=4_13_AXIS 13 LOAD PC",
|
||||
"ns=1;s=4_14_AXIS 14 LOAD PC",
|
||||
"ns=1;s=4_15_AXIS 15 LOAD PC",
|
||||
"ns=1;s=5_1_TOOL 1 CURRENT LIFE PC",
|
||||
"ns=1;s=5_2_TOOL 2 CURRENT LIFE PC",
|
||||
"ns=1;s=5_3_TOOL 3 CURRENT LIFE PC",
|
||||
"ns=1;s=5_4_TOOL 4 CURRENT LIFE PC",
|
||||
"ns=1;s=5_5_TOOL 11 CURRENT LIFE PC",
|
||||
"ns=1;s=5_6_TOOL 12 CURRENT LIFE PC",
|
||||
"ns=1;s=5_7_TOOL 13 CURRENT LIFE PC",
|
||||
"ns=1;s=5_8_TOOL 14 CURRENT LIFE PC",
|
||||
"ns=1;s=5_9_TOOL 21 CURRENT LIFE PC",
|
||||
"ns=1;s=5_10_TOOL 22 CURRENT LIFE PC",
|
||||
"ns=1;s=5_11_TOOL 23 CURRENT LIFE PC",
|
||||
"ns=1;s=5_12_TOOL 24 CURRENT LIFE PC",
|
||||
"ns=1;s=5_13_TOOL 31 CURRENT LIFE PC",
|
||||
"ns=1;s=5_14_TOOL 32 CURRENT LIFE PC",
|
||||
"ns=1;s=5_15_TOOL 33 CURRENT LIFE PC",
|
||||
"ns=1;s=5_16_TOOL 34 CURRENT LIFE PC",
|
||||
"ns=1;s=51_P2 PALLET STATUS",
|
||||
"ns=1;s=52_P3 PALLET STATUS",
|
||||
"ns=1;s=53_P2 EXTERNAL PALLET STATUS",
|
||||
"ns=1;s=54_P3 EXTERNAL PALLET STATUS",
|
||||
"ns=1;s=500_1_STATUS",
|
||||
"ns=1;s=501_1_MODE",
|
||||
"ns=1;s=502_1_RECIPE NAME",
|
||||
"ns=1;s=507_1_WORKPIECE TIME",
|
||||
"ns=1;s=507_2_WORKPIECE QTY",
|
||||
"ns=1;s=507_3_CYCLE TIME",
|
||||
"ns=1;s=504_PROC 1 P.P. ORDER",
|
||||
"ns=1;s=505_PROC 1 P.P. PROCESSING",
|
||||
"ns=1;s=506_PROC 1 P.P. PROCESSING PHASE",
|
||||
"ns=1;s=503_PROC 1 P.P. EXECUTION TIME [HH:MM:SS]"
|
||||
]
|
||||
}
|
||||
@@ -54,5 +54,47 @@
|
||||
"Css": "bg-danger text-light",
|
||||
"Priority": 3,
|
||||
"Group": "ERROR"
|
||||
},
|
||||
{
|
||||
"MStatusID": 8,
|
||||
"Description": "MDI",
|
||||
"Css": "bg-warning text-light",
|
||||
"Priority": 3,
|
||||
"Group": "MANUAL"
|
||||
},
|
||||
{
|
||||
"MStatusID": 9,
|
||||
"Description": "STEP",
|
||||
"Css": "bg-warning text-light",
|
||||
"Priority": 3,
|
||||
"Group": "MANUAL"
|
||||
},
|
||||
{
|
||||
"MStatusID": 10,
|
||||
"Description": "INC_JOG",
|
||||
"Css": "bg-warning text-light",
|
||||
"Priority": 3,
|
||||
"Group": "MANUAL"
|
||||
},
|
||||
{
|
||||
"MStatusID": 11,
|
||||
"Description": "PROFILE",
|
||||
"Css": "bg-warning text-light",
|
||||
"Priority": 3,
|
||||
"Group": "MANUAL"
|
||||
},
|
||||
{
|
||||
"MStatusID": 12,
|
||||
"Description": "HOME",
|
||||
"Css": "bg-warning text-light",
|
||||
"Priority": 3,
|
||||
"Group": "MANUAL"
|
||||
},
|
||||
{
|
||||
"MStatusID": 13,
|
||||
"Description": "HANDWHEEL",
|
||||
"Css": "bg-warning text-light",
|
||||
"Priority": 3,
|
||||
"Group": "MANUAL"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,387 @@
|
||||
[
|
||||
{
|
||||
"Order": 1,
|
||||
"ExtCode": "ns=1;s=515_PROC 1 FEED OVERRIDE",
|
||||
"HLShow": true,
|
||||
"Type": "FEED",
|
||||
"Title": "FEED OVER",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 130,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-gauge-high"
|
||||
},
|
||||
{
|
||||
"Order": 2,
|
||||
"ExtCode": "ns=1;s=518_PROC 1 SPEED OVERRIDE",
|
||||
"HLShow": true,
|
||||
"Type": "SPEED",
|
||||
"Title": "SPEED OVER",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 130,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-gauge-high"
|
||||
},
|
||||
{
|
||||
"Order": 3,
|
||||
"ExtCode": "ns=1;s=521_PROC 1 SPINDLE 1 LOAD PC",
|
||||
"HLShow": true,
|
||||
"Type": "LOAD",
|
||||
"Title": "SPINDLE 1 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 4,
|
||||
"ExtCode": "ns=1;s=522_PROC 1 SPINDLE 2 LOAD PC",
|
||||
"HLShow": true,
|
||||
"Type": "LOAD",
|
||||
"Title": "SPINDLE 2 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 5,
|
||||
"ExtCode": "ns=1;s=523_PROC 1 SPINDLE 3 LOAD PC",
|
||||
"HLShow": true,
|
||||
"Type": "LOAD",
|
||||
"Title": "SPINDLE 3 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 6,
|
||||
"ExtCode": "ns=1;s=524_PROC 1 SPINDLE 4 LOAD PC",
|
||||
"HLShow": true,
|
||||
"Type": "LOAD",
|
||||
"Title": "SPINDLE 4 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 31,
|
||||
"ExtCode": "ns=1;s=4_1_AXIS 1 LOAD PC",
|
||||
"HLShow": true,
|
||||
"Type": "LOAD",
|
||||
"Title": "AXIS 1 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 32,
|
||||
"ExtCode": "ns=1;s=4_2_AXIS 2 LOAD PC",
|
||||
"HLShow": true,
|
||||
"Type": "LOAD",
|
||||
"Title": "AXIS 2 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 33,
|
||||
"ExtCode": "ns=1;s=4_3_AXIS 3 LOAD PC",
|
||||
"HLShow": true,
|
||||
"Type": "LOAD",
|
||||
"Title": "AXIS 3 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 34,
|
||||
"ExtCode": "ns=1;s=4_4_AXIS 4 LOAD PC",
|
||||
"HLShow": true,
|
||||
"Type": "LOAD",
|
||||
"Title": "AXIS 4 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 51,
|
||||
"ExtCode": "ns=1;s=516_PROC 1 FEED PROGRAMMED",
|
||||
"Type": "FEED",
|
||||
"Title": "FEED PROG",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 20000,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-gauge-high"
|
||||
},
|
||||
{
|
||||
"Order": 52,
|
||||
"ExtCode": "ns=1;s=517_PROC 1 FEED ACTUAL",
|
||||
"Type": "FEED",
|
||||
"Title": "FEED ACT",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 20000,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-gauge-high"
|
||||
},
|
||||
{
|
||||
"Order": 53,
|
||||
"ExtCode": "ns=1;s=519_PROC 1 SPEED PROGRAMMED",
|
||||
"Type": "SPEED",
|
||||
"Title": "SPEED PROG",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 20000,
|
||||
"DisplFormat": "N0",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-gauge-high"
|
||||
},
|
||||
{
|
||||
"Order": 54,
|
||||
"ExtCode": "ns=1;s=520_PROC 1 SPEED ACTUAL",
|
||||
"Type": "SPEED",
|
||||
"Title": "SPEED ACT",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 20000,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-gauge-high"
|
||||
},
|
||||
{
|
||||
"Order": 105,
|
||||
"ExtCode": "ns=1;s=4_5_AXIS 5 LOAD PC",
|
||||
"Type": "LOAD",
|
||||
"Title": "AXIS 5 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 106,
|
||||
"ExtCode": "ns=1;s=4_6_AXIS 6 LOAD PC",
|
||||
"Type": "LOAD",
|
||||
"Title": "AXIS 6 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 107,
|
||||
"ExtCode": "ns=1;s=4_7_AXIS 7 LOAD PC",
|
||||
"Type": "LOAD",
|
||||
"Title": "AXIS 7 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 108,
|
||||
"ExtCode": "ns=1;s=4_8_AXIS 8 LOAD PC",
|
||||
"Type": "LOAD",
|
||||
"Title": "AXIS 8 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 109,
|
||||
"ExtCode": "ns=1;s=4_9_AXIS 9 LOAD PC",
|
||||
"Type": "LOAD",
|
||||
"Title": "AXIS 9 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 110,
|
||||
"ExtCode": "ns=1;s=4_10_AXIS 10 LOAD PC",
|
||||
"Type": "LOAD",
|
||||
"Title": "AXIS 10 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 111,
|
||||
"ExtCode": "ns=1;s=4_11_AXIS 11 LOAD PC",
|
||||
"Type": "LOAD",
|
||||
"Title": "AXIS 11 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 112,
|
||||
"ExtCode": "ns=1;s=4_12_AXIS 12 LOAD PC",
|
||||
"Type": "LOAD",
|
||||
"Title": "AXIS 12 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 113,
|
||||
"ExtCode": "ns=1;s=4_13_AXIS 13 LOAD PC",
|
||||
"Type": "LOAD",
|
||||
"Title": "AXIS 13 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 114,
|
||||
"ExtCode": "ns=1;s=4_14_AXIS 14 LOAD PC",
|
||||
"Type": "LOAD",
|
||||
"Title": "AXIS 14 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
},
|
||||
{
|
||||
"Order": 115,
|
||||
"ExtCode": "ns=1;s=4_15_AXIS 15 LOAD PC",
|
||||
"Type": "LOAD",
|
||||
"Title": "AXIS 15 LOAD",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": 0,
|
||||
"MaxVal": 100,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true,
|
||||
"EnablePlot": true,
|
||||
"ShowBar": true,
|
||||
"CssIcon": "fa-solid fa-bolt"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,100 @@
|
||||
[
|
||||
{
|
||||
"MStatusID": 0,
|
||||
"Description": "UNDEFINED",
|
||||
"Css": "bg-dark text-light",
|
||||
"Priority": 1,
|
||||
"Group": "POWEROFF"
|
||||
},
|
||||
{
|
||||
"MStatusID": 1,
|
||||
"Description": "POWEROFF",
|
||||
"Css": "bg-secondary text-light",
|
||||
"Priority": 1,
|
||||
"Group": "POWEROFF"
|
||||
},
|
||||
{
|
||||
"MStatusID": 2,
|
||||
"Description": "AUTOMATIC",
|
||||
"Css": "bg-success text-light",
|
||||
"Priority": 2,
|
||||
"Group": "RUN"
|
||||
},
|
||||
{
|
||||
"MStatusID": 3,
|
||||
"Description": "EDIT",
|
||||
"Css": "bg-warning text-light",
|
||||
"Priority": 3,
|
||||
"Group": "MANUAL"
|
||||
},
|
||||
{
|
||||
"MStatusID": 4,
|
||||
"Description": "SEMIAUTOMATIC",
|
||||
"Css": "bg-warning text-light",
|
||||
"Priority": 3,
|
||||
"Group": "MANUAL"
|
||||
},
|
||||
{
|
||||
"MStatusID": 5,
|
||||
"Description": "MANUAL_JOG",
|
||||
"Css": "bg-warning text-light",
|
||||
"Priority": 3,
|
||||
"Group": "MANUAL"
|
||||
},
|
||||
{
|
||||
"MStatusID": 6,
|
||||
"Description": "ALARM",
|
||||
"Css": "bg-danger text-warning",
|
||||
"Priority": 3,
|
||||
"Group": "ERROR"
|
||||
},
|
||||
{
|
||||
"MStatusID": 7,
|
||||
"Description": "ESTOP",
|
||||
"Css": "bg-danger text-light",
|
||||
"Priority": 3,
|
||||
"Group": "ERROR"
|
||||
},
|
||||
{
|
||||
"MStatusID": 8,
|
||||
"Description": "MDI",
|
||||
"Css": "bg-warning text-light",
|
||||
"Priority": 3,
|
||||
"Group": "MANUAL"
|
||||
},
|
||||
{
|
||||
"MStatusID": 9,
|
||||
"Description": "STEP",
|
||||
"Css": "bg-warning text-light",
|
||||
"Priority": 3,
|
||||
"Group": "MANUAL"
|
||||
},
|
||||
{
|
||||
"MStatusID": 10,
|
||||
"Description": "INC_JOG",
|
||||
"Css": "bg-warning text-light",
|
||||
"Priority": 3,
|
||||
"Group": "MANUAL"
|
||||
},
|
||||
{
|
||||
"MStatusID": 11,
|
||||
"Description": "PROFILE",
|
||||
"Css": "bg-warning text-light",
|
||||
"Priority": 3,
|
||||
"Group": "MANUAL"
|
||||
},
|
||||
{
|
||||
"MStatusID": 12,
|
||||
"Description": "HOME",
|
||||
"Css": "bg-warning text-light",
|
||||
"Priority": 3,
|
||||
"Group": "MANUAL"
|
||||
},
|
||||
{
|
||||
"MStatusID": 13,
|
||||
"Description": "HANDWHEEL",
|
||||
"Css": "bg-warning text-light",
|
||||
"Priority": 3,
|
||||
"Group": "MANUAL"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"Order": 0,
|
||||
"ExtCode": "ns=5;i=1244",
|
||||
"Type": "TOOL",
|
||||
"Title": "TOOL 01",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "P3",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 1,
|
||||
"ExtCode": "ns=5;i=1267",
|
||||
"Type": "TOOL",
|
||||
"Title": "TOOL 02",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "P3",
|
||||
"IsNumeric": true
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,194 @@
|
||||
[
|
||||
{
|
||||
"Order": 0,
|
||||
"ExtCode": "ns=1;s=5_1_TOOL 1 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 1 TOOL 01",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 1,
|
||||
"ExtCode": "ns=1;s=5_2_TOOL 2 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 1 TOOL 02",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 2,
|
||||
"ExtCode": "ns=1;s=5_3_TOOL 3 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 1 TOOL 03",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 3,
|
||||
"ExtCode": "ns=1;s=5_4_TOOL 4 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 1 TOOL 04",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 4,
|
||||
"ExtCode": "ns=1;s=5_5_TOOL 11 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 2 TOOL 01",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 5,
|
||||
"ExtCode": "ns=1;s=5_6_TOOL 12 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 2 TOOL 02",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 6,
|
||||
"ExtCode": "ns=1;s=5_7_TOOL 13 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 2 TOOL 03",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 7,
|
||||
"ExtCode": "ns=1;s=5_8_TOOL 14 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 2 TOOL 04",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 8,
|
||||
"ExtCode": "ns=1;s=5_9_TOOL 21 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 3 TOOL 01",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 9,
|
||||
"ExtCode": "ns=1;s=5_10_TOOL 22 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 3 TOOL 02",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 10,
|
||||
"ExtCode": "ns=1;s=5_11_TOOL 23 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 3 TOOL 03",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 11,
|
||||
"ExtCode": "ns=1;s=5_12_TOOL 24 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 3 TOOL 04",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 12,
|
||||
"ExtCode": "ns=1;s=5_13_TOOL 31 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 4 TOOL 01",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 13,
|
||||
"ExtCode": "ns=1;s=5_14_TOOL 32 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 4 TOOL 02",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 14,
|
||||
"ExtCode": "ns=1;s=5_15_TOOL 33 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 4 TOOL 03",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 15,
|
||||
"ExtCode": "ns=1;s=5_16_TOOL 34 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 4 TOOL 04",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,194 @@
|
||||
[
|
||||
{
|
||||
"Order": 0,
|
||||
"ExtCode": "ns=1;s=5_1_TOOL 1 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 1 TOOL 01",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 1,
|
||||
"ExtCode": "ns=1;s=5_2_TOOL 2 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 1 TOOL 02",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 2,
|
||||
"ExtCode": "ns=1;s=5_3_TOOL 3 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 1 TOOL 03",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 3,
|
||||
"ExtCode": "ns=1;s=5_4_TOOL 4 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 1 TOOL 04",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 4,
|
||||
"ExtCode": "ns=1;s=5_5_TOOL 11 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 2 TOOL 01",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 5,
|
||||
"ExtCode": "ns=1;s=5_6_TOOL 12 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 2 TOOL 02",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 6,
|
||||
"ExtCode": "ns=1;s=5_7_TOOL 13 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 2 TOOL 03",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 7,
|
||||
"ExtCode": "ns=1;s=5_8_TOOL 14 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 2 TOOL 04",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 8,
|
||||
"ExtCode": "ns=1;s=5_9_TOOL 21 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 3 TOOL 01",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 9,
|
||||
"ExtCode": "ns=1;s=5_10_TOOL 22 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 3 TOOL 2",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 10,
|
||||
"ExtCode": "ns=1;s=5_11_TOOL 23 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 3 TOOL 3",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 11,
|
||||
"ExtCode": "ns=1;s=5_12_TOOL 24 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 3 TOOL 4",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 12,
|
||||
"ExtCode": "ns=1;s=5_13_TOOL 31 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 4 TOOL 1",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 13,
|
||||
"ExtCode": "ns=1;s=5_14_TOOL 32 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 4 TOOL 2",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 14,
|
||||
"ExtCode": "ns=1;s=5_15_TOOL 33 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 4 TOOL 3",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
},
|
||||
{
|
||||
"Order": 15,
|
||||
"ExtCode": "ns=1;s=5_16_TOOL 34 CURRENT LIFE PC",
|
||||
"Type": "TOOL",
|
||||
"Title": "SPINDLE 4 TOOL 4",
|
||||
"Value": "0",
|
||||
"ValueNum": 0,
|
||||
"MinVal": -9999,
|
||||
"MaxVal": 9999,
|
||||
"DisplFormat": "N1",
|
||||
"IsNumeric": true
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,380 @@
|
||||
/* ========================================================================
|
||||
* Copyright (c) 2005-2021 The OPC Foundation, Inc. All rights reserved.
|
||||
*
|
||||
* OPC Foundation MIT License 1.00
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* The complete license agreement can be found here:
|
||||
* http://opcfoundation.org/License/MIT/1.00/
|
||||
* ======================================================================*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Mono.Options;
|
||||
using Opc.Ua;
|
||||
using Opc.Ua.Configuration;
|
||||
using Serilog;
|
||||
using Serilog.Events;
|
||||
using Serilog.Templates;
|
||||
using static Opc.Ua.Utils;
|
||||
|
||||
namespace MP.MONO.ADAPTER.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// The log output implementation of a TextWriter.
|
||||
/// </summary>
|
||||
public class LogWriter : TextWriter
|
||||
{
|
||||
private StringBuilder m_builder = new StringBuilder();
|
||||
|
||||
public override void Write(char value)
|
||||
{
|
||||
m_builder.Append(value);
|
||||
}
|
||||
|
||||
public override void WriteLine(char value)
|
||||
{
|
||||
m_builder.Append(value);
|
||||
LogInfo("{0}", m_builder.ToString());
|
||||
m_builder.Clear();
|
||||
}
|
||||
|
||||
public override void WriteLine()
|
||||
{
|
||||
LogInfo("{0}", m_builder.ToString());
|
||||
m_builder.Clear();
|
||||
}
|
||||
|
||||
public override void WriteLine(string format, object arg0)
|
||||
{
|
||||
m_builder.Append(format);
|
||||
LogInfo(m_builder.ToString(), arg0);
|
||||
m_builder.Clear();
|
||||
}
|
||||
|
||||
public override void WriteLine(string format, object arg0, object arg1)
|
||||
{
|
||||
m_builder.Append(format);
|
||||
LogInfo(m_builder.ToString(), arg0, arg1);
|
||||
m_builder.Clear();
|
||||
}
|
||||
|
||||
public override void WriteLine(string format, params object[] arg)
|
||||
{
|
||||
m_builder.Append(format);
|
||||
LogInfo(m_builder.ToString(), arg);
|
||||
m_builder.Clear();
|
||||
}
|
||||
|
||||
public override void Write(string value)
|
||||
{
|
||||
m_builder.Append(value);
|
||||
}
|
||||
|
||||
public override void WriteLine(string value)
|
||||
{
|
||||
m_builder.Append(value);
|
||||
LogInfo("{0}", m_builder.ToString());
|
||||
m_builder.Clear();
|
||||
}
|
||||
|
||||
public override Encoding Encoding
|
||||
{
|
||||
get { return Encoding.Default; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The error code why the application exit.
|
||||
/// </summary>
|
||||
public enum ExitCode : int
|
||||
{
|
||||
Ok = 0,
|
||||
ErrorNotStarted = 0x80,
|
||||
ErrorRunning = 0x81,
|
||||
ErrorException = 0x82,
|
||||
ErrorStopping = 0x83,
|
||||
ErrorCertificate = 0x84,
|
||||
ErrorInvalidCommandLine = 0x100
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// An exception that occured and caused an exit of the application.
|
||||
/// </summary>
|
||||
public class ErrorExitException : Exception
|
||||
{
|
||||
public ExitCode ExitCode { get; }
|
||||
|
||||
public ErrorExitException(ExitCode exitCode)
|
||||
{
|
||||
ExitCode = exitCode;
|
||||
}
|
||||
|
||||
public ErrorExitException()
|
||||
{
|
||||
ExitCode = ExitCode.Ok;
|
||||
}
|
||||
|
||||
public ErrorExitException(string message) : base(message)
|
||||
{
|
||||
ExitCode = ExitCode.Ok;
|
||||
}
|
||||
|
||||
public ErrorExitException(string message, ExitCode exitCode) : base(message)
|
||||
{
|
||||
ExitCode = exitCode;
|
||||
}
|
||||
|
||||
public ErrorExitException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
ExitCode = ExitCode.Ok;
|
||||
}
|
||||
|
||||
public ErrorExitException(string message, Exception innerException, ExitCode exitCode) : base(message, innerException)
|
||||
{
|
||||
ExitCode = exitCode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A dialog which asks for user input.
|
||||
/// </summary>
|
||||
public class ApplicationMessageDlg : IApplicationMessageDlg
|
||||
{
|
||||
private TextWriter m_output;
|
||||
private string m_message = string.Empty;
|
||||
private bool m_ask;
|
||||
|
||||
public ApplicationMessageDlg(TextWriter output)
|
||||
{
|
||||
m_output = output;
|
||||
}
|
||||
|
||||
public override void Message(string text, bool ask)
|
||||
{
|
||||
m_message = text;
|
||||
m_ask = ask;
|
||||
}
|
||||
|
||||
public override async Task<bool> ShowAsync()
|
||||
{
|
||||
if (m_ask)
|
||||
{
|
||||
var message = new StringBuilder(m_message);
|
||||
message.Append(" (y/n, default y): ");
|
||||
m_output.Write(message.ToString());
|
||||
|
||||
try
|
||||
{
|
||||
ConsoleKeyInfo result = Console.ReadKey();
|
||||
m_output.WriteLine();
|
||||
return await Task.FromResult((result.KeyChar == 'y') ||
|
||||
(result.KeyChar == 'Y') || (result.KeyChar == '\r')).ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// intentionally fall through
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_output.WriteLine(m_message);
|
||||
}
|
||||
|
||||
return await Task.FromResult(true).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper functions shared in various console applications.
|
||||
/// </summary>
|
||||
public static class ConsoleUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Process a command line of the console sample application.
|
||||
/// </summary>
|
||||
public static string ProcessCommandLine(
|
||||
TextWriter output,
|
||||
string[] args,
|
||||
Mono.Options.OptionSet options,
|
||||
ref bool showHelp,
|
||||
bool noExtraArgs = true)
|
||||
{
|
||||
IList<string> extraArgs = null;
|
||||
try
|
||||
{
|
||||
extraArgs = options.Parse(args);
|
||||
if (noExtraArgs)
|
||||
{
|
||||
foreach (string extraArg in extraArgs)
|
||||
{
|
||||
output.WriteLine("Error: Unknown option: {0}", extraArg);
|
||||
showHelp = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (OptionException e)
|
||||
{
|
||||
output.WriteLine(e.Message);
|
||||
showHelp = true;
|
||||
}
|
||||
|
||||
if (showHelp)
|
||||
{
|
||||
options.WriteOptionDescriptions(output);
|
||||
throw new ErrorExitException("Invalid Commandline or help requested.", ExitCode.ErrorInvalidCommandLine);
|
||||
}
|
||||
|
||||
return extraArgs.FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configure the logging providers.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Replaces the Opc.Ua.Core default ILogger with a
|
||||
/// Microsoft.Extension.Logger with a Serilog file, debug and console logger.
|
||||
/// The debug logger is only enabled for debug builds.
|
||||
/// The console logger is enabled by the logConsole flag at the consoleLogLevel.
|
||||
/// The file logger uses the setting in the ApplicationConfiguration.
|
||||
/// The Trace logLevel is chosen if required by the Tracemasks.
|
||||
/// </remarks>
|
||||
/// <param name="configuration">The application configuration.</param>
|
||||
/// <param name="context">The context name for the logger. </param>
|
||||
/// <param name="logConsole">Enable logging to the console.</param>
|
||||
/// <param name="consoleLogLevel">The LogLevel to use for the console/debug.<
|
||||
/// /param>
|
||||
public static void ConfigureLogging(
|
||||
ApplicationConfiguration configuration,
|
||||
string context,
|
||||
bool logConsole,
|
||||
LogLevel consoleLogLevel)
|
||||
{
|
||||
var loggerConfiguration = new LoggerConfiguration()
|
||||
.Enrich.FromLogContext();
|
||||
|
||||
if (logConsole)
|
||||
{
|
||||
loggerConfiguration.WriteTo.Console(
|
||||
restrictedToMinimumLevel: (LogEventLevel)consoleLogLevel
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
loggerConfiguration
|
||||
.WriteTo.Debug(restrictedToMinimumLevel: (LogEventLevel)consoleLogLevel);
|
||||
}
|
||||
LogLevel fileLevel = LogLevel.Information;
|
||||
|
||||
// switch for Trace/Verbose output
|
||||
var traceMasks = configuration.TraceConfiguration.TraceMasks;
|
||||
if ((traceMasks & ~(TraceMasks.Information | TraceMasks.Error |
|
||||
TraceMasks.Security | TraceMasks.StartStop | TraceMasks.StackTrace)) != 0)
|
||||
{
|
||||
fileLevel = LogLevel.Trace;
|
||||
}
|
||||
|
||||
// add file logging if configured
|
||||
var outputFilePath = configuration.TraceConfiguration.OutputFilePath;
|
||||
if (!string.IsNullOrWhiteSpace(outputFilePath))
|
||||
{
|
||||
loggerConfiguration.WriteTo.File(
|
||||
new ExpressionTemplate("{UtcDateTime(@t):yyyy-MM-dd HH:mm:ss.fff} [{@l:u3}] {@m}\n{@x}"),
|
||||
ReplaceSpecialFolderNames(outputFilePath),
|
||||
restrictedToMinimumLevel: (LogEventLevel)fileLevel,
|
||||
rollOnFileSizeLimit: true);
|
||||
}
|
||||
|
||||
// adjust minimum level
|
||||
if (fileLevel < LogLevel.Information || consoleLogLevel < LogLevel.Information)
|
||||
{
|
||||
loggerConfiguration.MinimumLevel.Verbose();
|
||||
}
|
||||
|
||||
// create the serilog logger
|
||||
var serilogger = loggerConfiguration
|
||||
.CreateLogger();
|
||||
|
||||
// create the ILogger for Opc.Ua.Core
|
||||
var logger = LoggerFactory.Create(builder => builder.SetMinimumLevel(LogLevel.Trace))
|
||||
.AddSerilog(serilogger)
|
||||
.CreateLogger(context);
|
||||
|
||||
// set logger interface, disables TraceEvent
|
||||
SetLogger(logger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Output log messages.
|
||||
/// </summary>
|
||||
public static void LogTest()
|
||||
{
|
||||
// print legacy logging output, for testing
|
||||
Trace(TraceMasks.Error, "This is an Error message: {0}", TraceMasks.Error);
|
||||
Trace(TraceMasks.Information, "This is a Information message: {0}", TraceMasks.Information);
|
||||
Trace(TraceMasks.StackTrace, "This is a StackTrace message: {0}", TraceMasks.StackTrace);
|
||||
Trace(TraceMasks.Service, "This is a Service message: {0}", TraceMasks.Service);
|
||||
Trace(TraceMasks.ServiceDetail, "This is a ServiceDetail message: {0}", TraceMasks.ServiceDetail);
|
||||
Trace(TraceMasks.Operation, "This is a Operation message: {0}", TraceMasks.Operation);
|
||||
Trace(TraceMasks.OperationDetail, "This is a OperationDetail message: {0}", TraceMasks.OperationDetail);
|
||||
Trace(TraceMasks.StartStop, "This is a StartStop message: {0}", TraceMasks.StartStop);
|
||||
Trace(TraceMasks.ExternalSystem, "This is a ExternalSystem message: {0}", TraceMasks.ExternalSystem);
|
||||
Trace(TraceMasks.Security, "This is a Security message: {0}", TraceMasks.Security);
|
||||
|
||||
// print ILogger logging output
|
||||
LogTrace("This is a Trace message: {0}", LogLevel.Trace);
|
||||
LogDebug("This is a Debug message: {0}", LogLevel.Debug);
|
||||
LogInfo("This is a Info message: {0}", LogLevel.Information);
|
||||
LogWarning("This is a Warning message: {0}", LogLevel.Warning);
|
||||
LogError("This is a Error message: {0}", LogLevel.Error);
|
||||
LogCritical("This is a Critical message: {0}", LogLevel.Critical);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an event which is set if a user
|
||||
/// enters the Ctrl-C key combination.
|
||||
/// </summary>
|
||||
public static ManualResetEvent CtrlCHandler()
|
||||
{
|
||||
var quitEvent = new ManualResetEvent(false);
|
||||
try
|
||||
{
|
||||
Console.CancelKeyPress += (_, eArgs) => {
|
||||
quitEvent.Set();
|
||||
eArgs.Cancel = true;
|
||||
};
|
||||
}
|
||||
catch
|
||||
{
|
||||
// intentionally left blank
|
||||
}
|
||||
return quitEvent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,759 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using MP.MONO.Core;
|
||||
using MP.MONO.Core.CONF;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Text.RegularExpressions;
|
||||
using static MP.MONO.Core.CONF.OpcUaParamConf;
|
||||
using static MP.MONO.Core.Enums;
|
||||
|
||||
namespace MP.MONO.ADAPTER.OPC
|
||||
{
|
||||
public class IobGeneric
|
||||
{
|
||||
#region Public Fields
|
||||
|
||||
/// <summary>
|
||||
/// Struttura memoria PLC x lettura/scrittura da JSON file
|
||||
/// </summary>
|
||||
public plcMemMap memMap;
|
||||
|
||||
#endregion Public Fields
|
||||
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Avvia generico IOB
|
||||
/// </summary>
|
||||
/// <param name="confPath"></param>
|
||||
/// <param name="config"></param>
|
||||
public IobGeneric(string confPath, IConfigurationRoot? config)
|
||||
{
|
||||
lg = LogManager.GetCurrentClassLogger();
|
||||
connectionOk = false;
|
||||
configPath = confPath;
|
||||
confMan = config;
|
||||
if (confMan != null)
|
||||
{
|
||||
// carico dati endpoint
|
||||
var selection = confMan.GetSection("Endpoint");
|
||||
if (selection.Exists())
|
||||
{
|
||||
// recupero dati endpoint
|
||||
cIobConf = selection.Get<EndpointData>();
|
||||
}
|
||||
// carico dati OptPar
|
||||
var optPar = confMan.GetSection("OptPar");
|
||||
if (optPar.Exists())
|
||||
{
|
||||
// configurazione gestione log
|
||||
Log2Console = optPar.GetValue<bool>("Log2Console");
|
||||
Log2File = optPar.GetValue<bool>("Log2File");
|
||||
|
||||
// configurazione gestione split/regexp dati
|
||||
ForceSplit = optPar.GetValue<bool>("ForceSplit");
|
||||
CleanupRegexpPre = optPar.GetValue<string>("CleanupRegexpPre");
|
||||
if (optPar.GetValue<bool>("FiltCrLf"))
|
||||
{
|
||||
FiltSplitChar = new char[] { '\n', '\r', '\0' };
|
||||
}
|
||||
else
|
||||
{
|
||||
FiltSplitChar = optPar.GetValue<char[]>("FiltSplitChar");
|
||||
}
|
||||
CleanupRegexpPost = optPar.GetValue<string>("CleanupRegexpPost");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// indica se ping disabilitato da optPar
|
||||
/// </summary>
|
||||
public bool pingDisabled
|
||||
{
|
||||
get => getCRB("NO_PING");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifica SE si debba fare log verboso (verboso + ogni tot letture IN)
|
||||
/// </summary>
|
||||
public bool verboseLog
|
||||
{
|
||||
get
|
||||
{
|
||||
bool answ = false;
|
||||
int logEvery = getCRI("logEvery");
|
||||
if (logEvery < 1)
|
||||
{
|
||||
logEvery = 10;
|
||||
}
|
||||
|
||||
answ = getCRB("verbose") && (nReadIN % logEvery == 0);
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Esecuzione dei task richiesti e pulizia coda richieste eseguite
|
||||
/// </summary>
|
||||
/// <param name="task2exe"></param>
|
||||
public virtual Dictionary<string, string> executeTasks(Dictionary<string, string> task2exe)
|
||||
{
|
||||
// Verificare il protocollo: dovrebbe togliere SOLO i task eseguiti...
|
||||
Dictionary<string, string> taskDone = new Dictionary<string, string>();
|
||||
if (task2exe != null)
|
||||
{
|
||||
// controllo se memMap != null...
|
||||
if (memMap != null)
|
||||
{
|
||||
bool taskOk = false;
|
||||
string taskVal = "";
|
||||
// cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4
|
||||
foreach (var item in task2exe)
|
||||
{
|
||||
taskOk = false;
|
||||
taskVal = "";
|
||||
// converto richiesta in enum...
|
||||
taskType tName = taskType.nihil;
|
||||
Enum.TryParse(item.Key, out tName);
|
||||
// controllo sulla KEY...
|
||||
switch (tName)
|
||||
{
|
||||
case taskType.setArt:
|
||||
case taskType.setComm:
|
||||
case taskType.setProg:
|
||||
case taskType.setPzComm:
|
||||
// recupero dati da memMap...
|
||||
if (memMap != null && memMap.mMapWrite != null)
|
||||
{
|
||||
if (memMap.mMapWrite.ContainsKey(item.Key))
|
||||
{
|
||||
dataConf currMem = memMap.mMapWrite[item.Key];
|
||||
string addr = currMem.memAddr;
|
||||
taskVal = $"SET task: {item.Key} --> {item.Value} | mem: {currMem.memAddr} - {currMem.size} byte";
|
||||
// salvo il nuovo valore nella memoria... così prox invio lo trasmetterà
|
||||
memMap.mMapWrite[item.Key].value = item.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
taskVal = $"NO DATA MEM, SET task: {item.Key} --> {item.Value}";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
taskVal = $"NO MemMap found, SET task: {item.Key} --> {item.Value}";
|
||||
}
|
||||
// salvo in currProd..
|
||||
saveProdData(new KeyValuePair<string, string>(item.Key, item.Value));
|
||||
|
||||
break;
|
||||
|
||||
case taskType.forceResetPzCount:
|
||||
// reset contapezzi inizio setup
|
||||
taskOk = resetcontapezziPLC();
|
||||
taskVal = taskOk ? "RESET PZ COUNT OK" : "PZ RESET DISABLED | NO EXEC";
|
||||
logInfo($"Chiamata forceResetPzCount: taskOk: {taskOk} | taskVal: {taskVal}");
|
||||
break;
|
||||
|
||||
case taskType.startSetup:
|
||||
// reset contapezzi inizio setup
|
||||
taskOk = resetcontapezziPLC();
|
||||
taskVal = taskOk ? "RESET: SETUP START" : "PZ RESET DISABLED | NO EXEC";
|
||||
logInfo($"Chiamata startSetup: taskOk: {taskOk} | taskVal: {taskVal}");
|
||||
break;
|
||||
|
||||
case taskType.stopSetup:
|
||||
// reset contapezzi fine setup SE ESPLICITAMENTE IMPOSTATO
|
||||
if (getCRB("ENABLE_PZ_RESET_stopSetup"))
|
||||
{
|
||||
taskOk = resetcontapezziPLC();
|
||||
}
|
||||
taskVal = taskOk ? "RESET: SETUP END" : "PZ RESET DISABLED | NO EXEC";
|
||||
logInfo($"Chiamata stopSetup: taskOk: {taskOk} | taskVal: {taskVal}");
|
||||
break;
|
||||
|
||||
case taskType.setParameter:
|
||||
// richiedo da URL i parametri WRITE da popolare
|
||||
logInfo("Chiamata setParameter --> processMemWriteRequests");
|
||||
taskVal = processMemWriteRequests();
|
||||
// se restituiscce "" faccio altra prova...
|
||||
if (string.IsNullOrEmpty(taskVal))
|
||||
{
|
||||
// i parametri me li aspetto come stringa composta paramName|paramvalue
|
||||
if (item.Value.Contains("|"))
|
||||
{
|
||||
string[] paramsJob = item.Value.Split('|');
|
||||
taskVal = $"REQUEST SET PARAMETERS: {paramsJob[0]} --> {paramsJob[1]}";
|
||||
}
|
||||
else
|
||||
{
|
||||
taskVal = $"WRONG REQUEST FOR SET PARAMETERS: {item.Value} doesnt contain pipe for splitting key/value";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
|
||||
logInfo($"Chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}");
|
||||
break;
|
||||
}
|
||||
// aggiungo task!
|
||||
taskDone.Add(item.Key, taskVal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logError($"Attenzione! memMap è nullo, non posso eseguire task2exe!");
|
||||
}
|
||||
}
|
||||
|
||||
return taskDone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fornisce il valore di flusso e valore in formato valido x messa in coda nel formato
|
||||
/// dtEve#flusso#valore#cont <paramref name="flusso">Flusso dati</paramref><paramref
|
||||
/// name="valore">Valore da salvare</paramref>
|
||||
/// </summary>
|
||||
public string qEncodeFLog(string flusso, string valore)
|
||||
{
|
||||
string answ = "";
|
||||
// fixme todo !!! fare tenere? cambiare? modificare? si dovrebbe cambiare con invio su
|
||||
// channel REDIS dei dati ricevuti, eventualmente divisi x canale secondo setup
|
||||
#if false
|
||||
try
|
||||
{
|
||||
answ = $"{DateTime.Now:yyyyMMddHHmmssfff}#{flusso}#{valore}#{counterULog}";
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
#endif
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metodo generico di reset contapezzi...
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual bool resetcontapezziPLC()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Salva valori indicati in prod data
|
||||
/// </summary>
|
||||
/// <param name="item">Item KVP di cui salvare i dati in currProdData come chiave/valore</param>
|
||||
/// <returns></returns>
|
||||
public void saveProdData(KeyValuePair<string, string> item)
|
||||
{
|
||||
// imposto i valori...
|
||||
if (currProdData.ContainsKey(item.Key))
|
||||
{
|
||||
currProdData[item.Key] = item.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
currProdData.Add(item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metodo base connessione...
|
||||
/// </summary>
|
||||
public virtual void tryConnect()
|
||||
{
|
||||
dtAvvioAdp = DateTime.Now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metodo base disconnessione...
|
||||
/// </summary>
|
||||
public virtual void tryDisconnect()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Internal Fields
|
||||
|
||||
/// <summary>
|
||||
/// valore booleano di check se sia stato AVVIATO l'adapter (Running)
|
||||
/// </summary>
|
||||
internal bool adpRunning = false;
|
||||
|
||||
/// <summary>
|
||||
/// Data/ora ultimo avvio adapter
|
||||
/// </summary>
|
||||
internal DateTime dtAvvioAdp = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Data/ora ultimo spegnimento adapter
|
||||
/// </summary>
|
||||
internal DateTime dtStopAdp = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// dataOra ultimo log periodico...
|
||||
/// </summary>
|
||||
internal DateTime lastPeriodicLog;
|
||||
|
||||
/// <summary>
|
||||
/// dataOra ultimo PING inviato verso il PLC...
|
||||
/// </summary>
|
||||
internal DateTime lastPING = DateTime.Now.AddHours(-1);
|
||||
|
||||
/// <summary>
|
||||
/// indica se serva refresh parametri e quindi PLC...
|
||||
/// </summary>
|
||||
internal bool needRefresh = true;
|
||||
|
||||
#endregion Internal Fields
|
||||
|
||||
#region Internal Properties
|
||||
|
||||
/// <summary>
|
||||
/// COnfiguraizone Endpoint corrente
|
||||
/// </summary>
|
||||
internal EndpointData cIobConf { get; set; } = new EndpointData();
|
||||
|
||||
/// <summary>
|
||||
/// Stringa regexp da usare x bonifica caratteri, POST split
|
||||
/// </summary>
|
||||
internal string CleanupRegexpPost { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Stringa regexp da usare x bonifica caratteri, PRE split
|
||||
/// </summary>
|
||||
internal string CleanupRegexpPre { get; set; } = "";
|
||||
|
||||
internal string configPath { get; set; } = "";
|
||||
|
||||
internal IConfigurationRoot? confMan { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Salva verifica stato connessione OK
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal virtual bool connectionOk
|
||||
{
|
||||
get
|
||||
{
|
||||
return _connOk;
|
||||
}
|
||||
set
|
||||
{
|
||||
_connOk = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Carattere x eventuale split/filt valori notificati
|
||||
/// </summary>
|
||||
internal char[] FiltSplitChar { get; set; } = new char[1];
|
||||
|
||||
/// <summary>
|
||||
/// Indica se forzare split caratteri letti
|
||||
/// </summary>
|
||||
internal bool ForceSplit { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Abilitazione al log su console
|
||||
/// </summary>
|
||||
internal bool Log2Console { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Abilitazione al log su file
|
||||
/// </summary>
|
||||
internal bool Log2File { get; set; } = false;
|
||||
|
||||
#endregion Internal Properties
|
||||
|
||||
#region Internal Methods
|
||||
|
||||
/// <summary>
|
||||
/// Effettua log INFO su file e se richiesto su console
|
||||
/// </summary>
|
||||
internal static void logInfo(string msg, bool log2file = true, bool log2console = true)
|
||||
{
|
||||
if (log2console)
|
||||
{
|
||||
Console.WriteLine("INFO | " + msg);
|
||||
}
|
||||
if (log2file)
|
||||
{
|
||||
lg.Info(msg);
|
||||
}
|
||||
}
|
||||
|
||||
internal bool getCRB(string keyName)
|
||||
{
|
||||
bool answ = false;
|
||||
answ = confMan.GetValue<bool>(keyName);
|
||||
return answ;
|
||||
}
|
||||
|
||||
internal int getCRI(string keyName)
|
||||
{
|
||||
int answ = -1;
|
||||
answ = confMan.GetValue<int>(keyName);
|
||||
return answ;
|
||||
}
|
||||
|
||||
internal string getCRS(string keyName)
|
||||
{
|
||||
string answ = "";
|
||||
answ = confMan.GetValue<string>(keyName);
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua log DEBUG su file e se richiesto su console
|
||||
/// </summary>
|
||||
internal void logDebug(string msg)
|
||||
{
|
||||
if (Log2Console)
|
||||
{
|
||||
Console.WriteLine("DEBUG | " + msg);
|
||||
}
|
||||
if (Log2File)
|
||||
{
|
||||
lg.Debug(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua log ERROR su file e se richiesto su console
|
||||
/// </summary>
|
||||
internal void logError(string msg)
|
||||
{
|
||||
if (Log2Console)
|
||||
{
|
||||
Console.WriteLine("ERROR | " + msg);
|
||||
}
|
||||
if (Log2File)
|
||||
{
|
||||
lg.Error(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua log FATAL su file e se richiesto su console
|
||||
/// </summary>
|
||||
internal void logFatal(string msg)
|
||||
{
|
||||
if (Log2Console)
|
||||
{
|
||||
Console.WriteLine("FATAL | " + msg);
|
||||
}
|
||||
if (Log2File)
|
||||
{
|
||||
lg.Fatal(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua log TRACE su file e se richiesto su console
|
||||
/// </summary>
|
||||
internal void logTrace(string msg)
|
||||
{
|
||||
if (Log2Console)
|
||||
{
|
||||
Console.WriteLine("TRACE | " + msg);
|
||||
}
|
||||
if (Log2File)
|
||||
{
|
||||
lg.Trace(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua pulizia caratteri da valori non ammessi...
|
||||
/// </summary>
|
||||
/// <param name="rawData"></param>
|
||||
/// <returns></returns>
|
||||
internal string stringCleanup(string rawData)
|
||||
{
|
||||
string currVal = "";
|
||||
string temp = "";
|
||||
|
||||
// Step 01: pulizia dati preliminare (SE impostato cleanup...)
|
||||
if (!string.IsNullOrEmpty(CleanupRegexpPre))
|
||||
{
|
||||
Regex rgxPre = new Regex(CleanupRegexpPre);
|
||||
temp = rgxPre.Replace(rawData, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = rawData;
|
||||
}
|
||||
// Step 02: se è abilitato filt/split...
|
||||
if (ForceSplit)
|
||||
{
|
||||
var dataArray = temp.Split(FiltSplitChar);
|
||||
if (dataArray.Length > 0)
|
||||
{
|
||||
currVal = dataArray[0];
|
||||
}
|
||||
}
|
||||
// Step 03: se non ok copio x intero
|
||||
if (string.IsNullOrEmpty(currVal))
|
||||
{
|
||||
currVal = temp;
|
||||
}
|
||||
|
||||
// Step 04: pulizia dati finale (SE impostato cleanup...)
|
||||
if (!string.IsNullOrEmpty(CleanupRegexpPost))
|
||||
{
|
||||
Regex rgxPost = new Regex(CleanupRegexpPost);
|
||||
currVal = rgxPost.Replace(currVal, "");
|
||||
}
|
||||
|
||||
return currVal;
|
||||
}
|
||||
|
||||
#endregion Internal Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
/// <summary>
|
||||
/// wrapper di log
|
||||
/// </summary>
|
||||
protected static Logger lg;
|
||||
|
||||
protected bool _connOk = false;
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario valori impostati x produzione
|
||||
/// </summary>
|
||||
protected Dictionary<string, string> currProdData = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario ultimi valori (double) delle TSVC
|
||||
/// </summary>
|
||||
protected Dictionary<string, double> LastTSVC = new Dictionary<string, double>();
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario di VC da trattare come TimeSeries (con conf decodificata + processing successivo...)
|
||||
/// </summary>
|
||||
protected Dictionary<string, VCData> TSVC_Data = new Dictionary<string, VCData>();
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
/// <summary>
|
||||
/// Numero letture IN da avvio
|
||||
/// </summary>
|
||||
protected int nReadIN { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// test ping all'indirizzo PLC/CNC impostato nei parametri
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected IPStatus testPingMachine
|
||||
{
|
||||
get
|
||||
{
|
||||
IPStatus answ = IPStatus.Unknown;
|
||||
// se disabilitato salto...
|
||||
if (pingDisabled)
|
||||
{
|
||||
answ = IPStatus.Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPAddress address;
|
||||
PingReply reply;
|
||||
using (Ping pingSender = new Ping())
|
||||
{
|
||||
address = IPAddress.Loopback;
|
||||
int pingMsTimeout = cIobConf.PingMsTimeout;
|
||||
IPAddress.TryParse(cIobConf.IpAddress, out address);
|
||||
try
|
||||
{
|
||||
// se != null --> uso address...
|
||||
if (address != null)
|
||||
{
|
||||
reply = pingSender.Send(address, pingMsTimeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
reply = pingSender.Send(cIobConf.IpAddress, pingMsTimeout);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
reply = pingSender.Send(IPAddress.Loopback, pingMsTimeout);
|
||||
}
|
||||
answ = reply.Status;
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Stringa raw dei parametri da scrivere...
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected string getParams2write()
|
||||
{
|
||||
string answ = "";
|
||||
// recuperare da una apposita area REDIS...
|
||||
#if false
|
||||
string url2call = $"{urlGetParams2Write}";
|
||||
if (verboseLog)
|
||||
{
|
||||
lgInfo("chiamata URL " + url2call);
|
||||
}
|
||||
answ = utils.callUrlNow(url2call);
|
||||
// se vuoto faccio seconda prova...
|
||||
if (string.IsNullOrEmpty(answ))
|
||||
{
|
||||
answ = utils.callUrlNow(url2call);
|
||||
}
|
||||
#endif
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metodo da overridare x scrivere DAVVERO i parametri sul PLC
|
||||
/// </summary>
|
||||
/// <param name="updatedPar"></param>
|
||||
protected virtual void plcWriteParams(ref List<objItem> updatedPar)
|
||||
{
|
||||
// non faccio nulla di base...
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processa le richieste di scrittura memoria
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected string processMemWriteRequests()
|
||||
{
|
||||
string answ = "";
|
||||
// li salvo nei parametri in memoria locale (ogni adapter DOVREBBE salvare POI sul VERO PLC)
|
||||
List<objItem> writeList = new List<objItem>();
|
||||
List<objItem> updatedPar = new List<objItem>();
|
||||
// recupero elenco delle cose da fare
|
||||
string resp = getParams2write();
|
||||
if (!string.IsNullOrEmpty(resp))
|
||||
{
|
||||
try
|
||||
{
|
||||
writeList = JsonConvert.DeserializeObject<List<objItem>>(resp);
|
||||
// se ho da fare chiamo esecuzione..
|
||||
if (writeList.Count > 0)
|
||||
{
|
||||
foreach (var item in writeList)
|
||||
{
|
||||
// scrivo in memoria
|
||||
if (memMap.mMapWrite.ContainsKey(item.uid))
|
||||
{
|
||||
memMap.mMapWrite[item.uid].value = item.reqValue;
|
||||
// accodo in stringa taskVal...
|
||||
answ += $" | Parameter {item.uid} --> {item.reqValue}";
|
||||
// sistemo valori
|
||||
item.value = item.reqValue;
|
||||
logInfo($"Richiesta update parametro {item.uid} | actVal = {item.value} | reqVal = {item.reqValue}");
|
||||
item.reqValue = "";
|
||||
// salvo in lista da ritrasmettere
|
||||
updatedPar.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
answ += $" | Error: parameter {item.uid} not found";
|
||||
}
|
||||
}
|
||||
// richiamo scrittura parametri su PLC
|
||||
plcWriteParams(ref updatedPar);
|
||||
// invio su cloud parametri!
|
||||
string rawData = JsonConvert.SerializeObject(updatedPar);
|
||||
logInfo("Notifica a server scrittura parametri");
|
||||
#if false
|
||||
utils.callUrl($"{urlUpdateWriteParams}", rawData);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
logError($"Eccezione in processMemWriteRequests:{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logError("Non è stata ricevuta risposta x task da eseguire");
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// setup parametri da file di conf
|
||||
/// </summary>
|
||||
protected void setupMemMap()
|
||||
{
|
||||
logInfo($"setupMemMap | trovati {memMap.mMapRead.Count} parametri Read (TSVC)");
|
||||
logInfo($"setupMemMap | trovati {memMap.mMapWrite.Count} parametri Write");
|
||||
if (getCRB("verbose"))
|
||||
{
|
||||
string rawMemConf = JsonConvert.SerializeObject(memMap, Formatting.Indented);
|
||||
logDebug($"setupMemMap | configurazione memoria R/W:{Environment.NewLine}{rawMemConf}");
|
||||
}
|
||||
// se ho variabili read --> genero dati TSVC...
|
||||
if (memMap.mMapRead.Count > 0)
|
||||
{
|
||||
TSVC_Data.Clear();
|
||||
LastTSVC.Clear();
|
||||
VCData currConf;
|
||||
int periodo = 0;
|
||||
VC_func funz = VC_func.POINT;
|
||||
// accodo nella conf...
|
||||
foreach (var item in memMap.mMapRead)
|
||||
{
|
||||
funz = item.Value.func;
|
||||
periodo = item.Value.period;
|
||||
currConf = new VCData()
|
||||
{
|
||||
Funzione = funz,
|
||||
Period = periodo,
|
||||
DTStart = DateTime.Now.AddHours(-1),
|
||||
dataArray = new List<double>()
|
||||
};
|
||||
TSVC_Data.Add(item.Key, currConf);
|
||||
}
|
||||
// documento...
|
||||
foreach (var item in TSVC_Data)
|
||||
{
|
||||
logTrace($"TSVC: {item.Key} | periodo: {item.Value.Period} | funz: {item.Value.Funzione}");
|
||||
// salvo i valori PREC...
|
||||
LastTSVC.Add(item.Key, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private IConfigurationRoot config;
|
||||
private string confPath;
|
||||
|
||||
#endregion Private Fields
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,136 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<AssemblyName>MP.MONO.ADAPTER.OPC</AssemblyName>
|
||||
<OutputType>Exe</OutputType>
|
||||
<PackageId>MP.MONO.ADAPTER.OPC</PackageId>
|
||||
<Company>EgalWare</Company>
|
||||
<Description>OPC UA Console Client</Description>
|
||||
<Copyright>Copyright � 2020+ EgalWare</Copyright>
|
||||
<RootNamespace>MP.MONO.ADAPTER.OPC</RootNamespace>
|
||||
<Version>1.2.2206.2114</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="UAClient.old.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
|
||||
<PackageReference Include="Mono.Options" Version="6.12.0.148" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client" Version="1.4.368.58" />
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Configuration" Version="1.4.368.58" />
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Core" Version="1.4.368.58" />
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Security.Certificates" Version="1.4.368.58" />
|
||||
<PackageReference Include="Serilog" Version="2.11.0" />
|
||||
<PackageReference Include="Serilog.Expressions" Version="3.4.0" />
|
||||
<PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
|
||||
<PackageReference Include="Serilog.Sinks.Debug" Version="2.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.6.122" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MP.MONO.Core\MP.MONO.Core.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="appsettings.multiax.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="appsettings.office.json">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\AlarmBankList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\AlarmRawList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\Counters.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\Counters.demo.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\Counters.multiax.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\ModeList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\MPStatus.demo.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\MPStatus.multiax.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\MPStatus.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\Alarms.multiax.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\Alarms.demo.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\Alarms.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\Parameters.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\PalletStatusList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\Tools.multiax.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\Tools.demo.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\Tools.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\ActLog.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\MpMonoAdapterClient.Config.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\Demo.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\Multiax.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="logs\.placeholder.file">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="logs\stderr.log">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="logs\stdin.log">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="logs\stdout.log">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="nssm.exe">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="CONF\StatusList.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
|
||||
autoReload="true"
|
||||
throwExceptions="false"
|
||||
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
|
||||
|
||||
<!-- optional, add some variabeles
|
||||
https://github.com/nlog/NLog/wiki/Configuration-file#variables
|
||||
-->
|
||||
<variable name="myvar" value="myvalue" />
|
||||
|
||||
<!--
|
||||
See https://github.com/nlog/nlog/wiki/Configuration-file
|
||||
for information on customizing logging rules and outputs.
|
||||
-->
|
||||
|
||||
<targets async="true">
|
||||
<target xsi:type="File"
|
||||
name="NKC"
|
||||
fileName="${basedir}/logs/${shortdate}.log"
|
||||
layout="${longdate} ${uppercase:${level}} ${message}" />
|
||||
</targets>
|
||||
|
||||
<rules>
|
||||
<logger name="*" minlevel="Info" writeTo="NKC" />
|
||||
</rules>
|
||||
</nlog>
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MP.MONO.ADAPTER.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Classe di estensione x oggetti DataItems OPC-UA con struttura e valori
|
||||
/// </summary>
|
||||
public class OpcUaDataItemExt : Opc.Ua.Client.MonitoredItem
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
public OpcUaDataItemExt(Opc.Ua.Client.MonitoredItem MonIt)
|
||||
{
|
||||
if (MonIt != null)
|
||||
{
|
||||
AttributeId = MonIt.AttributeId;
|
||||
CacheQueueSize = MonIt.CacheQueueSize;
|
||||
Handle = MonIt.Handle;
|
||||
DiscardOldest = MonIt.DiscardOldest;
|
||||
DisplayName = MonIt.DisplayName;
|
||||
Encoding = MonIt.Encoding;
|
||||
Filter = MonIt.Filter;
|
||||
IndexRange = MonIt.IndexRange;
|
||||
MonitoringMode = MonIt.MonitoringMode;
|
||||
NodeClass = MonIt.NodeClass;
|
||||
QueueSize = MonIt.QueueSize;
|
||||
RelativePath = MonIt.RelativePath;
|
||||
SamplingInterval = MonIt.SamplingInterval;
|
||||
StartNodeId = MonIt.StartNodeId;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// NodeId univoco dell'oggetto x subscription (StartNodeId)
|
||||
/// </summary>
|
||||
public string nodeId { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Valore (in sec) del periodo di downsampling (0 --> NON usato)
|
||||
/// </summary>
|
||||
public int samplePeriod { get; set; } = 60;
|
||||
|
||||
/// <summary>
|
||||
/// Valore soglia DeadBand (0 --> non usata)
|
||||
/// </summary>
|
||||
public double thresholdDeadBand { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// UUID univoco dell'oggetto --> flusso (DisplayName)
|
||||
/// </summary>
|
||||
public string uid { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Valore Registrato in formato stringa
|
||||
/// </summary>
|
||||
public string value { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Valore Registrato in formato byte array
|
||||
/// </summary>
|
||||
public byte[] rawByte { get; set; } = new byte[1];
|
||||
|
||||
/// <summary>
|
||||
/// Timestamp data-ora evento registrato
|
||||
/// </summary>
|
||||
public DateTime valueTimestamp { get; set; } = DateTime.Now;
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using MP.MONO.Core;
|
||||
using MP.MONO.Core.CONF;
|
||||
using MP.MONO.Core.DTO;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using Opc.Ua;
|
||||
using StackExchange.Redis;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static MP.MONO.Core.Enums;
|
||||
|
||||
namespace MP.MONO.ADAPTER.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// The program.
|
||||
/// </summary>
|
||||
public static class Program
|
||||
{
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Main entry point.
|
||||
/// </summary>
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
await Task.Delay(1);
|
||||
TextWriter output = Console.Out;
|
||||
output.WriteLine(lineSep);
|
||||
output.WriteLine("Egalware | MP.MONO.ADAPTER | OPC UA Console Client");
|
||||
output.WriteLine($"vers.{Assembly.GetExecutingAssembly().GetName().Version}");
|
||||
output.WriteLine(lineSep);
|
||||
output.WriteLine();
|
||||
output.WriteLine("OPC UA library: {0} @ {1} -- {2}",
|
||||
Utils.GetAssemblyBuildNumber(),
|
||||
Utils.GetAssemblyTimestamp().ToString("G", CultureInfo.InvariantCulture),
|
||||
Utils.GetAssemblySoftwareVersion());
|
||||
|
||||
// init parte config, vedere https://blog.hildenco.com/2020/05/configuration-in-net-core-console.html
|
||||
var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
|
||||
var builder = new ConfigurationBuilder()
|
||||
.AddJsonFile($"appsettings.json", true, true)
|
||||
.AddJsonFile($"appsettings.{env}.json", true, true)
|
||||
.AddEnvironmentVariables();
|
||||
IConfigurationRoot config = builder.Build();
|
||||
|
||||
// imposto variabili di base
|
||||
redisConf = config.GetConnectionString("Redis");
|
||||
confPath = Path.Combine(Directory.GetCurrentDirectory(), "conf");
|
||||
Random rand = new Random();
|
||||
List<MachineStatus>? statusList = new List<MachineStatus>();
|
||||
List<MachineMode>? modeList = new List<MachineMode>();
|
||||
|
||||
// fix numero minimo dei thread pool x evitare collasso chiamate redis
|
||||
ThreadPool.SetMinThreads(10, 10);
|
||||
|
||||
logInfo(lineSep, true, true);
|
||||
logInfo($"Starting Machine ADAPTER", true, true);
|
||||
logInfo($"Redis server param: {redisConf.Substring(0, 20)}...", false, true);
|
||||
logInfo(lineSep, true, true);
|
||||
logInfo("", true, true);
|
||||
|
||||
// Setup REDIS
|
||||
ConnectionMultiplexer.SetFeatureFlag("preventthreadtheft", true);
|
||||
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(redisConf);
|
||||
sub = redis.GetSubscriber();
|
||||
redisDb = redis.GetDatabase();
|
||||
|
||||
// salvo configurazioni in redis
|
||||
setupConfRedis(config);
|
||||
|
||||
// avvio il vero e proprio programma di comunicaizone OPC-UA
|
||||
var currIob = new IobOpcUa(confPath, config);
|
||||
|
||||
logInfo($"Started IOB at path {confPath}", true, true);
|
||||
logInfo("Running - press CTRL-C to stop ADAPTER", false, true);
|
||||
logInfo("", false, true);
|
||||
|
||||
// wait for timeout or Ctrl-C
|
||||
var quitEvent = ConsoleUtils.CtrlCHandler();
|
||||
bool quit = false;
|
||||
DateTime start = DateTime.UtcNow;
|
||||
int waitTime = int.MaxValue;
|
||||
// Ciclo infinito x attesa chiusura con CTRL-C
|
||||
do
|
||||
{
|
||||
// se non fosse connesso... riprovo la connessione...
|
||||
currIob.tryConnect();
|
||||
|
||||
// attesa...
|
||||
Thread.Sleep(100);
|
||||
|
||||
// aggiunta condizioni check dati "recenti" x ri-connessione: se NON si fosse
|
||||
// aggiornato entro limite indicato --> disconnect/reconnect
|
||||
if (currIob.dataIsStale)
|
||||
{
|
||||
currIob.tryDisconnect();
|
||||
Thread.Sleep(500);
|
||||
currIob.tryConnect();
|
||||
}
|
||||
|
||||
// verifico se c'è evento quit
|
||||
quit = quitEvent.WaitOne(Math.Min(1_000, waitTime));
|
||||
} while (!quit);
|
||||
|
||||
// disconnetto alla fine...
|
||||
if (currIob.connectionOk)
|
||||
{
|
||||
currIob.tryDisconnect();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static AlarmReportingMode alarmMode = AlarmReportingMode.ND;
|
||||
private static string confPath = "";
|
||||
private static DateTime lastLog = DateTime.Now.AddMinutes(-1);
|
||||
private static Dictionary<string, DateTime> LastSend = new Dictionary<string, DateTime>();
|
||||
private static string lineSep = "---------------------------------------------";
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
private static Dictionary<string, int> LogSimulator = new Dictionary<string, int>();
|
||||
private static bool logWriting = false;
|
||||
private static string redisConf = "";
|
||||
private static bool verboseLog = false;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
/// <summary>
|
||||
/// Redis DB
|
||||
/// </summary>
|
||||
private static IDatabase? redisDb { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Redis channel manager
|
||||
/// </summary>
|
||||
private static ISubscriber sub { get; set; }
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// verifica esistenza file oppure lo crea...
|
||||
/// </summary>
|
||||
private static void checkFilePresent(string filePath)
|
||||
{
|
||||
// verific presenza file log...
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
File.WriteAllText(filePath, $"{filePath} created!");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua log ERROR su file e se richiesto su console
|
||||
/// </summary>
|
||||
private static void logError(string msg, bool log2file = true, bool log2console = false)
|
||||
{
|
||||
if (log2console)
|
||||
{
|
||||
Console.WriteLine(msg);
|
||||
}
|
||||
if (log2file)
|
||||
{
|
||||
Log.Error(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua log INFO su file e se richiesto su console
|
||||
/// </summary>
|
||||
private static void logInfo(string msg, bool log2file = true, bool log2console = false)
|
||||
{
|
||||
if (log2console)
|
||||
{
|
||||
Console.WriteLine(msg);
|
||||
}
|
||||
if (log2file)
|
||||
{
|
||||
Log.Info(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setup e salvataggio redis delle conf (es modi/stati)
|
||||
/// </summary>
|
||||
private static void setupConfRedis(IConfigurationRoot appConf)
|
||||
{
|
||||
// fix configuraizoni di base
|
||||
MachineDTO currMach = new MachineDTO()
|
||||
{
|
||||
Manufacturer = appConf.GetValue<string>("Machine:Manufacturer"),
|
||||
Model = appConf.GetValue<string>("Machine:Model"),
|
||||
SerNumber = appConf.GetValue<string>("Machine:SerialNumber"),
|
||||
Name = appConf.GetValue<string>("Machine:Name"),
|
||||
ModeId = 0,
|
||||
StatusId = 0
|
||||
};
|
||||
redisDb.StringSet(Constants.MACHINE_CONF_PLATE, JsonConvert.SerializeObject(currMach));
|
||||
|
||||
// allarmi
|
||||
alarmMode = appConf.GetValue<AlarmReportingMode>("OptPar:AlarmMode");
|
||||
redisDb.StringSet(Constants.ALARMS_MODE_KEY, JsonConvert.SerializeObject(alarmMode));
|
||||
|
||||
// gestore specifico configurazioni
|
||||
ConfigManager configManager = new ConfigManager(redisConf, confPath);
|
||||
if (alarmMode == AlarmReportingMode.RawList)
|
||||
{
|
||||
_ = configManager.getAlarmsRawConf();
|
||||
}
|
||||
else
|
||||
{
|
||||
_ = configManager.getAlarmsBankConf();
|
||||
}
|
||||
// altre conf
|
||||
_ = configManager.getMachineModeConf();
|
||||
_ = configManager.getMachineStatusConf();
|
||||
_ = configManager.getPalletStatusConf();
|
||||
_ = configManager.getParamsConf();
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>bin\Release\net6.0\publish\win-x64\</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<SelfContained>false</SelfContained>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<PublishSingleFile>true</PublishSingleFile>
|
||||
<PublishReadyToRun>true</PublishReadyToRun>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>bin\Debug\net6.0\publish\win-x64\</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<SelfContained>false</SelfContained>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<PublishSingleFile>true</PublishSingleFile>
|
||||
<PublishReadyToRun>true</PublishReadyToRun>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,26 @@
|
||||
<body>
|
||||
<i>MAPO-MONO</i>
|
||||
<h4>Version: {{CURRENT-REL}}</h4>
|
||||
<br /> Release Note:
|
||||
<ul>
|
||||
<li>
|
||||
<b>Last changes:</b>
|
||||
<ul>{{LAST-CHANGES}}</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>v.1.0.* →</b>
|
||||
<ul>
|
||||
<li>Current CORE version</li>
|
||||
<li>Release dotnet6</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<div>
|
||||
<div style="float: left;">
|
||||
<img src="logoSteamware.png" />
|
||||
</div>
|
||||
<div style="float: right;">
|
||||
<a href="https://www.steamware.net/MAPO" target="_blank">© Egalware 2006-2022</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
@@ -0,0 +1,26 @@
|
||||
<body>
|
||||
<i>MAPO-MONO</i>
|
||||
<h4>Version: 1.12206.1709</h4>
|
||||
<br /> Release Note:
|
||||
<ul>
|
||||
<li>
|
||||
<b>Last changes:</b>
|
||||
<ul>{{LAST-CHANGES}}</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>v.1.0.* →</b>
|
||||
<ul>
|
||||
<li>Current CORE version</li>
|
||||
<li>Release dotnet6</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<div>
|
||||
<div style="float: left;">
|
||||
<img src="logoSteamware.png" />
|
||||
</div>
|
||||
<div style="float: right;">
|
||||
<a href="https://www.steamware.net/MAPO" target="_blank">© Egalware 2006-2022</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
@@ -0,0 +1 @@
|
||||
1.12206.1709
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>1.0.0.0</version>
|
||||
<url>http://nexus.steamware.net/repository/SWS/{{DIRNAME}}/{{BRANCHNAME}}/{{PACKNAME}}.zip</url>
|
||||
<changelog>http://nexus.steamware.net/repository/SWS/{{DIRNAME}}/{{BRANCHNAME}}/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
</item>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>1.12206.1709</version>
|
||||
<url>http://nexus.steamware.net/repository/SWS/MP.MONO.SIM/stable/LAST/MP.Mon.zip</url>
|
||||
<changelog>http://nexus.steamware.net/repository/SWS/MP.MONO.SIM/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
</item>
|
||||
@@ -0,0 +1,940 @@
|
||||
using NLog;
|
||||
using Opc.Ua;
|
||||
using Opc.Ua.Client;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MP.MONO.ADAPTER.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// Evento per incapsulare dati x refresh pagina
|
||||
/// </summary>
|
||||
public class opcUaMonitItemChange : EventArgs
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// salvataggio obj
|
||||
/// </summary>
|
||||
/// <param name="newObject"></param>
|
||||
public opcUaMonitItemChange(MonitoredItem monitoredItem, MonitoredItemNotification notification)
|
||||
{
|
||||
_monitoredItem = monitoredItem;
|
||||
_notification = notification;
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Proprietà lettura del MonitoredItem
|
||||
/// </summary>
|
||||
public MonitoredItem CurrMonitoredItem
|
||||
{
|
||||
get { return _monitoredItem; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Proprietà lettura della notifica
|
||||
/// </summary>
|
||||
public MonitoredItemNotification CurrNotify
|
||||
{
|
||||
get { return _notification; }
|
||||
}
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Private Fields
|
||||
|
||||
/// <summary>
|
||||
/// Monitored Item da notificare
|
||||
/// </summary>
|
||||
private readonly MonitoredItem _monitoredItem;
|
||||
|
||||
/// <summary>
|
||||
/// Valore notifica
|
||||
/// </summary>
|
||||
private readonly MonitoredItemNotification _notification;
|
||||
|
||||
#endregion Private Fields
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OPC UA Client with examples of basic functionality.
|
||||
/// </summary>
|
||||
public class UAClient
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the UAClient class.
|
||||
/// </summary>
|
||||
public UAClient(ApplicationConfiguration configuration, string user, string pwd, Action<IList, IList> validateResponse)
|
||||
{
|
||||
m_validateResponse = validateResponse;
|
||||
lg = LogManager.GetCurrentClassLogger();
|
||||
if (!string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(pwd))
|
||||
{
|
||||
CurrUserIdentity = new UserIdentity(user, pwd);
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrUserIdentity = new UserIdentity();
|
||||
}
|
||||
m_configuration = configuration;
|
||||
m_configuration.CertificateValidator.CertificateValidation += CertificateValidation;
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Events
|
||||
|
||||
/// <summary>
|
||||
/// Evento notifica variazione MonitoredItem
|
||||
/// </summary>
|
||||
public event EventHandler<opcUaMonitItemChange> eh_MonItChange;
|
||||
|
||||
#endregion Public Events
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// The user identity to use when creating the session.
|
||||
/// </summary>
|
||||
public IUserIdentity CurrUserIdentity { get; set; } = new UserIdentity();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the server URL.
|
||||
/// </summary>
|
||||
public string ServerUrl { get; set; } = "opc.tcp://localhost:4840";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the client session.
|
||||
/// </summary>
|
||||
public Session Session => m_session;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Browse Server nodes
|
||||
/// </summary>
|
||||
public bool Browse(ushort startNodeNS, uint startNodeVal, List<string> vetoBrowse, ref Dictionary<string, string> nodeIdNameList)
|
||||
{
|
||||
bool fatto = false;
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lg.Error("Session not connected!");
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Create a Browser object
|
||||
Browser browser = new Browser(m_session);
|
||||
|
||||
// Set browse parameters
|
||||
browser.BrowseDirection = BrowseDirection.Forward;
|
||||
browser.NodeClassMask = (int)NodeClass.Object | (int)NodeClass.Variable;
|
||||
browser.ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences;
|
||||
|
||||
//NodeId nodeToBrowse = ObjectIds.Server;
|
||||
//NodeId nodeToBrowse = new NodeId("ns=4,i=5001");
|
||||
NodeId nodeToBrowse = new NodeId(startNodeVal, startNodeNS);
|
||||
|
||||
// Call Browse service
|
||||
lg.Trace($"Browsing {nodeToBrowse} node...");
|
||||
ReferenceDescriptionCollection browseResults = browser.Browse(nodeToBrowse);
|
||||
|
||||
// Display the results
|
||||
lg.Trace($"Browse returned {browseResults.Count} results:");
|
||||
|
||||
foreach (ReferenceDescription result in browseResults)
|
||||
{
|
||||
lg.Trace($" NodeId = {result.NodeId}, TypeId = {result.TypeId}, DisplayName = {result.DisplayName.Text}, NodeClass = {result.NodeClass}, Others: {result.BinaryEncodingId} | {result.BrowseName}");
|
||||
// se NON fa parte dell'elenco dei VETO di filterItems...
|
||||
if (!vetoBrowse.Contains($"{result.NodeId}"))
|
||||
{
|
||||
// se mancasse aggiungo...
|
||||
if (!nodeIdNameList.ContainsKey($"{result.NodeId}"))
|
||||
{
|
||||
nodeIdNameList.Add(result.NodeId.ToString(), result.DisplayName.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
fatto = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lg.Error($"Browse Error : {ex.Message}");
|
||||
}
|
||||
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Browse Server nodes
|
||||
/// </summary>
|
||||
public bool Browse(string browsePath, List<string> vetoBrowse, ref Dictionary<string, string> nodeIdNameList)
|
||||
{
|
||||
bool fatto = false;
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lg.Error("Session not connected!");
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Create a Browser object
|
||||
Browser browser = new Browser(m_session);
|
||||
|
||||
// Set browse parameters
|
||||
browser.BrowseDirection = BrowseDirection.Forward;
|
||||
browser.NodeClassMask = (int)NodeClass.Object | (int)NodeClass.Variable;
|
||||
browser.ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences;
|
||||
|
||||
NodeId nodeToBrowse = new NodeId(browsePath);
|
||||
|
||||
// Call Browse service
|
||||
lg.Trace($"Browsing {nodeToBrowse} node...");
|
||||
ReferenceDescriptionCollection browseResults = browser.Browse(nodeToBrowse);
|
||||
|
||||
// Display the results
|
||||
lg.Trace($"Browse returned {browseResults.Count} results:");
|
||||
|
||||
foreach (ReferenceDescription result in browseResults)
|
||||
{
|
||||
// se veto --> loggo veto
|
||||
if (vetoBrowse.Contains($"{result.NodeId}"))
|
||||
{
|
||||
lg.Trace($"| FILTERED --> NodeId = {result.NodeId}, DisplayName = {result.DisplayName.Text}, NodeClass = {result.NodeClass}, Others: {result.BinaryEncodingId} | {result.BrowseName}");
|
||||
}
|
||||
// se NON fa parte dell'elenco dei VETO di filterItems...
|
||||
else
|
||||
{
|
||||
lg.Trace($" NodeId = {result.NodeId}, DisplayName = {result.DisplayName.Text}, NodeClass = {result.NodeClass}, Others: {result.BinaryEncodingId} | {result.BrowseName}");
|
||||
// se mancasse aggiungo...
|
||||
if (!nodeIdNameList.ContainsKey($"{result.NodeId}"))
|
||||
{
|
||||
nodeIdNameList.Add($"{result.NodeId}", result.DisplayName.Text);
|
||||
// se è un nodo object --> faccio sub browse!
|
||||
if (result.NodeClass != NodeClass.Variable)
|
||||
{
|
||||
this.Browse($"{result.NodeId}", vetoBrowse, ref nodeIdNameList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fatto = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lg.Error($"Browse Error : {ex.Message}");
|
||||
}
|
||||
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call UA method
|
||||
/// </summary>
|
||||
public void CallMethod()
|
||||
{
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lg.Error("Session not connected!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Define the UA Method to call Parent node - Objects\CTT\Methods Method node - Objects\CTT\Methods\Add
|
||||
NodeId objectId = new NodeId("ns=2;s=Methods");
|
||||
NodeId methodId = new NodeId("ns=2;s=Methods_Add");
|
||||
|
||||
// Define the method parameters Input argument requires a Float and an UInt32 value
|
||||
object[] inputArguments = new object[] { (float)10.5, (uint)10 };
|
||||
IList<object> outputArguments = null;
|
||||
|
||||
// Invoke Call service
|
||||
lg.Debug($"Calling UAMethod for node {methodId} ...");
|
||||
outputArguments = m_session.Call(objectId, methodId, inputArguments);
|
||||
|
||||
// Display results
|
||||
lg.Debug($"Method call returned {outputArguments.Count} output argument(s):");
|
||||
|
||||
foreach (var outputArgument in outputArguments)
|
||||
{
|
||||
lg.Debug($" OutputValue = {outputArgument}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
lg.Error($"Method call error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a session with the UA server
|
||||
/// </summary>
|
||||
public async Task<bool> ConnectAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (m_session != null && m_session.Connected == true)
|
||||
{
|
||||
lg.Info("Session already connected!");
|
||||
}
|
||||
else
|
||||
{
|
||||
lg.Info("Connecting...");
|
||||
|
||||
// Get the endpoint by connecting to server's discovery endpoint. Try to find
|
||||
// the first endopint without security.
|
||||
EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(ServerUrl, false);
|
||||
|
||||
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
|
||||
ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);
|
||||
|
||||
// Create the session
|
||||
Session session = await Session.Create(
|
||||
m_configuration,
|
||||
endpoint,
|
||||
false,
|
||||
false,
|
||||
m_configuration.ApplicationName,
|
||||
30 * 60 * 1000,
|
||||
CurrUserIdentity,
|
||||
null
|
||||
);
|
||||
|
||||
// Assign the created session
|
||||
if (session != null && session.Connected)
|
||||
{
|
||||
m_session = session;
|
||||
}
|
||||
|
||||
// Session created successfully.
|
||||
lg.Info($"New Session Created with SessionName = {m_session.SessionName}");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lg.Error($"Create Session Error : {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disconnects the session.
|
||||
/// </summary>
|
||||
public void Disconnect()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (m_session != null)
|
||||
{
|
||||
lg.Info("Disconnecting...");
|
||||
|
||||
m_session.Close();
|
||||
m_session.Dispose();
|
||||
m_session = null;
|
||||
|
||||
// Log Session Disconnected event
|
||||
lg.Info("Session Disconnected.");
|
||||
}
|
||||
else
|
||||
{
|
||||
lg.Error("Session not created!");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lg.Error($"Disconnect Error : {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a SINGLE of nodes value from Server
|
||||
/// </summary>
|
||||
/// <param name="reqNodeId"></param>
|
||||
/// <returns></returns>
|
||||
public string ReadNode(NodeId reqNodeId)
|
||||
{
|
||||
string answ = "";
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lg.Error("Session not connected!");
|
||||
return answ;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//#region Read a node by calling the Read Service
|
||||
|
||||
//// build a list of nodes to be read
|
||||
//ReadValueIdCollection nodesToRead = new ReadValueIdCollection()
|
||||
//{
|
||||
// // Value of ServerStatus
|
||||
// new ReadValueId() { NodeId = Variables.Server_ServerStatus, AttributeId = Attributes.Value },
|
||||
// // BrowseName of ServerStatus_StartTime
|
||||
// new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.BrowseName },
|
||||
// // Value of ServerStatus_StartTime
|
||||
// new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.Value }
|
||||
//};
|
||||
|
||||
//// Read the node attributes
|
||||
//lg.Info("Reading nodes...");
|
||||
|
||||
//// Call Read Service
|
||||
//m_session.Read(
|
||||
// null,
|
||||
// 0,
|
||||
// TimestampsToReturn.Both,
|
||||
// nodesToRead,
|
||||
// out DataValueCollection resultsValues,
|
||||
// out DiagnosticInfoCollection diagnosticInfos);
|
||||
|
||||
//// Validate the results
|
||||
//m_validateResponse(resultsValues, nodesToRead);
|
||||
|
||||
//// Display the results.
|
||||
//foreach (DataValue result in resultsValues)
|
||||
//{
|
||||
// lg.Info("Read Value = {0} , StatusCode = {1}", result.Value, result.StatusCode);
|
||||
//}
|
||||
|
||||
//#endregion Read a node by calling the Read Service
|
||||
|
||||
#region Read the Value attribute of a node by calling the Session.ReadValue method
|
||||
|
||||
try
|
||||
{
|
||||
DataValue resp = m_session.ReadValue(reqNodeId);
|
||||
answ = $"{resp.Value}";
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
// Log Error
|
||||
lg.Error($"ReadValue Error : {Environment.NewLine}{exc}");
|
||||
}
|
||||
|
||||
#endregion Read the Value attribute of a node by calling the Session.ReadValue method
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lg.Error($"Read Nodes Error : {ex.Message}.");
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a SINGLE of nodes value (RAW) from Server
|
||||
/// </summary>
|
||||
/// <param name="reqNodeId"></param>
|
||||
/// <returns></returns>
|
||||
public object ReadNodeRaw(NodeId reqNodeId)
|
||||
{
|
||||
object answ = null;
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lg.Error("Session not connected!");
|
||||
return answ;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
#region Read the Value attribute of a node by calling the Session.ReadValue method
|
||||
|
||||
try
|
||||
{
|
||||
DataValue resp = m_session.ReadValue(reqNodeId);
|
||||
answ = resp;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
// Log Error
|
||||
lg.Error($"ReadNodeRaw Error 01: {Environment.NewLine}{exc}");
|
||||
}
|
||||
|
||||
#endregion Read the Value attribute of a node by calling the Session.ReadValue method
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lg.Error($"ReadNodeRaw Error 02: {ex.Message}.");
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a list of nodes from Server
|
||||
/// </summary>
|
||||
public void ReadNodes()
|
||||
{
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lg.Error("Session not connected!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
#region Read a node by calling the Read Service
|
||||
|
||||
// build a list of nodes to be read
|
||||
ReadValueIdCollection nodesToRead = new ReadValueIdCollection()
|
||||
{
|
||||
// Value of ServerStatus
|
||||
new ReadValueId() { NodeId = Variables.Server_ServerStatus, AttributeId = Attributes.Value },
|
||||
// BrowseName of ServerStatus_StartTime
|
||||
new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.BrowseName },
|
||||
// Value of ServerStatus_StartTime
|
||||
new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.Value }
|
||||
};
|
||||
|
||||
// Read the node attributes
|
||||
lg.Info("Reading nodes...");
|
||||
|
||||
// Call Read Service
|
||||
m_session.Read(
|
||||
null,
|
||||
0,
|
||||
TimestampsToReturn.Both,
|
||||
nodesToRead,
|
||||
out DataValueCollection resultsValues,
|
||||
out DiagnosticInfoCollection diagnosticInfos);
|
||||
|
||||
// Validate the results
|
||||
m_validateResponse(resultsValues, nodesToRead);
|
||||
|
||||
// Display the results.
|
||||
foreach (DataValue result in resultsValues)
|
||||
{
|
||||
lg.Trace($"Read Value = {result.Value} , StatusCode = {result.StatusCode}");
|
||||
}
|
||||
|
||||
#endregion Read a node by calling the Read Service
|
||||
|
||||
#region Read the Value attribute of a node by calling the Session.ReadValue method
|
||||
|
||||
// Read Server NamespaceArray
|
||||
lg.Trace("Reading Value of NamespaceArray node...");
|
||||
DataValue namespaceArray = m_session.ReadValue(Variables.Server_NamespaceArray);
|
||||
// Display the result
|
||||
lg.Trace($"NamespaceArray Value = {namespaceArray}");
|
||||
|
||||
#endregion Read the Value attribute of a node by calling the Session.ReadValue method
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lg.Error($"Read Nodes Error : {ex.Message}.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create Subscription and MonitoredItems for DataChanges
|
||||
/// </summary>
|
||||
public List<MonitoredItem> SubscribeToDataChanges(Dictionary<string, string> DataList)
|
||||
{
|
||||
List<MonitoredItem> monItList = new List<MonitoredItem>();
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lg.Error("Session not connected!");
|
||||
return monItList;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Create a subscription for receiving data change notifications
|
||||
|
||||
// Define Subscription parameters
|
||||
Subscription subscription = new Subscription(m_session.DefaultSubscription);
|
||||
|
||||
subscription.DisplayName = "Steamware IOB-WIN Subscription";
|
||||
subscription.PublishingEnabled = true;
|
||||
subscription.PublishingInterval = 1000;
|
||||
|
||||
m_session.AddSubscription(subscription);
|
||||
|
||||
// Create the subscription on Server side
|
||||
subscription.Create();
|
||||
lg.Info($"New Subscription created with SubscriptionId = {subscription.Id}");
|
||||
|
||||
// Create MonitoredItems for data changes
|
||||
foreach (var item in DataList)
|
||||
{
|
||||
MonitoredItem currMonIt = new MonitoredItem(subscription.DefaultItem);
|
||||
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
currMonIt.StartNodeId = new NodeId(item.Key);
|
||||
currMonIt.AttributeId = Attributes.Value;
|
||||
currMonIt.DisplayName = item.Value;
|
||||
currMonIt.SamplingInterval = 1000;
|
||||
currMonIt.Notification += OnMonitoredItemNotification;
|
||||
subscription.AddItem(currMonIt);
|
||||
monItList.Add(currMonIt);
|
||||
}
|
||||
|
||||
#if false
|
||||
MonitoredItem IO_120_00_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
IO_120_00_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_120.00");
|
||||
IO_120_00_MonitoredItem.AttributeId = Attributes.Value;
|
||||
IO_120_00_MonitoredItem.DisplayName = "IO_120 Variable";
|
||||
IO_120_00_MonitoredItem.SamplingInterval = 1000;
|
||||
IO_120_00_MonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
subscription.AddItem(IO_120_00_MonitoredItem);
|
||||
|
||||
MonitoredItem IO_120_01_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
IO_120_01_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_120.01");
|
||||
IO_120_01_MonitoredItem.AttributeId = Attributes.Value;
|
||||
IO_120_01_MonitoredItem.DisplayName = "IO_120_01 Variable";
|
||||
IO_120_01_MonitoredItem.SamplingInterval = 1000;
|
||||
IO_120_01_MonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
subscription.AddItem(IO_120_01_MonitoredItem);
|
||||
|
||||
MonitoredItem IO_130_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
IO_130_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_130");
|
||||
IO_130_MonitoredItem.AttributeId = Attributes.Value;
|
||||
IO_130_MonitoredItem.DisplayName = "IO_130 Variable";
|
||||
IO_130_MonitoredItem.SamplingInterval = 1000;
|
||||
IO_130_MonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
subscription.AddItem(IO_130_MonitoredItem);
|
||||
|
||||
MonitoredItem IO_135_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
IO_135_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_135");
|
||||
IO_135_MonitoredItem.AttributeId = Attributes.Value;
|
||||
IO_135_MonitoredItem.DisplayName = "IO_135 Variable";
|
||||
IO_135_MonitoredItem.SamplingInterval = 1000;
|
||||
IO_135_MonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
subscription.AddItem(IO_135_MonitoredItem);
|
||||
|
||||
MonitoredItem IO_140_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
IO_140_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_140");
|
||||
IO_140_MonitoredItem.AttributeId = Attributes.Value;
|
||||
IO_140_MonitoredItem.DisplayName = "IO_140 Variable";
|
||||
IO_140_MonitoredItem.SamplingInterval = 1000;
|
||||
IO_140_MonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
subscription.AddItem(IO_140_MonitoredItem);
|
||||
|
||||
//MonitoredItem intMonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
//// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
//intMonitoredItem.StartNodeId = new NodeId("ns=2;s=Scalar_Simulation_Int32");
|
||||
//intMonitoredItem.AttributeId = Attributes.Value;
|
||||
//intMonitoredItem.DisplayName = "Int32 Variable";
|
||||
//intMonitoredItem.SamplingInterval = 1000;
|
||||
//intMonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
|
||||
//subscription.AddItem(intMonitoredItem);
|
||||
|
||||
//MonitoredItem floatMonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
//// Float Node - Objects\CTT\Scalar\Simulation\Float
|
||||
//floatMonitoredItem.StartNodeId = new NodeId("ns=2;s=Scalar_Simulation_Float");
|
||||
//floatMonitoredItem.AttributeId = Attributes.Value;
|
||||
//floatMonitoredItem.DisplayName = "Float Variable";
|
||||
//floatMonitoredItem.SamplingInterval = 1000;
|
||||
//floatMonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
|
||||
//subscription.AddItem(floatMonitoredItem);
|
||||
|
||||
//MonitoredItem stringMonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
//// String Node - Objects\CTT\Scalar\Simulation\String
|
||||
//stringMonitoredItem.StartNodeId = new NodeId("ns=2;s=Scalar_Simulation_String");
|
||||
//stringMonitoredItem.AttributeId = Attributes.Value;
|
||||
//stringMonitoredItem.DisplayName = "String Variable";
|
||||
//stringMonitoredItem.SamplingInterval = 1000;
|
||||
//stringMonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
|
||||
//subscription.AddItem(stringMonitoredItem);
|
||||
#endif
|
||||
|
||||
// Create the monitored items on Server side
|
||||
subscription.ApplyChanges();
|
||||
lg.Info($"MonitoredItems created for SubscriptionId = {subscription.Id}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
lg.Error($"Subscribe error: {ex.Message}");
|
||||
}
|
||||
return monItList;
|
||||
}
|
||||
|
||||
/// Write a list of nodes to the Server </summary>
|
||||
public void WriteNodes(List<WriteValue> node2Write)
|
||||
{
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lg.Error("Session not connected!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Write the configured nodes
|
||||
WriteValueCollection nodesToWrite = new WriteValueCollection();
|
||||
nodesToWrite.AddRange(node2Write);
|
||||
|
||||
// Write the node attributes
|
||||
StatusCodeCollection results = null;
|
||||
DiagnosticInfoCollection diagnosticInfos;
|
||||
lg.Debug("Writing nodes...");
|
||||
|
||||
// Call Write Service
|
||||
m_session.Write(null,
|
||||
nodesToWrite,
|
||||
out results,
|
||||
out diagnosticInfos);
|
||||
|
||||
// Validate the response
|
||||
m_validateResponse(results, nodesToWrite);
|
||||
|
||||
// Display the results.
|
||||
lg.Debug("Write Results :");
|
||||
|
||||
foreach (StatusCode writeResult in results)
|
||||
{
|
||||
lg.Debug($" {writeResult}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lg.Error($"Write Nodes Error : {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a list of nodes to the Server
|
||||
/// </summary>
|
||||
public void WriteSingleNode(WriteValue node2Write)
|
||||
{
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lg.Error("Session not connected!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Write the configured nodes
|
||||
WriteValueCollection nodesToWrite = new WriteValueCollection();
|
||||
|
||||
nodesToWrite.Add(node2Write);
|
||||
|
||||
// Write the node attributes
|
||||
StatusCodeCollection results = null;
|
||||
DiagnosticInfoCollection diagnosticInfos;
|
||||
lg.Debug("Writing nodes...");
|
||||
|
||||
// Call Write Service
|
||||
m_session.Write(null,
|
||||
nodesToWrite,
|
||||
out results,
|
||||
out diagnosticInfos);
|
||||
|
||||
// Validate the response
|
||||
m_validateResponse(results, nodesToWrite);
|
||||
|
||||
// Display the results.
|
||||
lg.Debug("Write Results :");
|
||||
|
||||
foreach (StatusCode writeResult in results)
|
||||
{
|
||||
lg.Debug(" {writeResult}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lg.Error($"Write Nodes Error : {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a list of nodes to the Server
|
||||
/// </summary>
|
||||
public void WriteTestNodes()
|
||||
{
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
lg.Error("Session not connected!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// scrivo vaslori a caso.. hhmm odierni
|
||||
int hhmm = 9876;
|
||||
int.TryParse(DateTime.Now.ToString("HHmm"), out hhmm);
|
||||
// Write the configured nodes
|
||||
WriteValueCollection nodesToWrite = new WriteValueCollection();
|
||||
|
||||
// Int32 Node - Objects\CTT\Scalar\Scalar_Static\Int32
|
||||
WriteValue commWriteVal = new WriteValue();
|
||||
commWriteVal.NodeId = new NodeId("ns=4;s=IO_151");
|
||||
commWriteVal.AttributeId = Attributes.Value;
|
||||
commWriteVal.Value = new DataValue();
|
||||
commWriteVal.Value.Value = (int)hhmm - 10;
|
||||
nodesToWrite.Add(commWriteVal);
|
||||
|
||||
WriteValue artWriteVal = new WriteValue();
|
||||
artWriteVal.NodeId = new NodeId("ns=4;s=IO_151");
|
||||
artWriteVal.AttributeId = Attributes.Value;
|
||||
artWriteVal.Value = new DataValue();
|
||||
artWriteVal.Value.Value = (int)hhmm;
|
||||
nodesToWrite.Add(artWriteVal);
|
||||
|
||||
WriteValue qtyWriteVal = new WriteValue();
|
||||
qtyWriteVal.NodeId = new NodeId("ns=4;s=IO_153");
|
||||
qtyWriteVal.AttributeId = Attributes.Value;
|
||||
qtyWriteVal.Value = new DataValue();
|
||||
qtyWriteVal.Value.Value = (int)hhmm + 10;
|
||||
nodesToWrite.Add(qtyWriteVal);
|
||||
|
||||
#if false
|
||||
//// Int32 Node - Objects\CTT\Scalar\Scalar_Static\Int32
|
||||
//WriteValue intWriteVal = new WriteValue();
|
||||
//intWriteVal.NodeId = new NodeId("ns=2;s=Scalar_Static_Int32");
|
||||
//intWriteVal.AttributeId = Attributes.Value;
|
||||
//intWriteVal.Value = new DataValue();
|
||||
//intWriteVal.Value.Value = (int)100;
|
||||
//nodesToWrite.Add(intWriteVal);
|
||||
|
||||
//// Float Node - Objects\CTT\Scalar\Scalar_Static\Float
|
||||
//WriteValue floatWriteVal = new WriteValue();
|
||||
//floatWriteVal.NodeId = new NodeId("ns=2;s=Scalar_Static_Float");
|
||||
//floatWriteVal.AttributeId = Attributes.Value;
|
||||
//floatWriteVal.Value = new DataValue();
|
||||
//floatWriteVal.Value.Value = (float)100.5;
|
||||
//nodesToWrite.Add(floatWriteVal);
|
||||
|
||||
//// String Node - Objects\CTT\Scalar\Scalar_Static\String
|
||||
//WriteValue stringWriteVal = new WriteValue();
|
||||
//stringWriteVal.NodeId = new NodeId("ns=2;s=Scalar_Static_String");
|
||||
//stringWriteVal.AttributeId = Attributes.Value;
|
||||
//stringWriteVal.Value = new DataValue();
|
||||
//stringWriteVal.Value.Value = "String Test";
|
||||
//nodesToWrite.Add(stringWriteVal);
|
||||
#endif
|
||||
|
||||
// Write the node attributes
|
||||
StatusCodeCollection results = null;
|
||||
DiagnosticInfoCollection diagnosticInfos;
|
||||
lg.Debug("Writing nodes...");
|
||||
|
||||
// Call Write Service
|
||||
m_session.Write(null,
|
||||
nodesToWrite,
|
||||
out results,
|
||||
out diagnosticInfos);
|
||||
|
||||
// Validate the response
|
||||
m_validateResponse(results, nodesToWrite);
|
||||
|
||||
// Display the results.
|
||||
lg.Debug("Write Results :");
|
||||
|
||||
foreach (StatusCode writeResult in results)
|
||||
{
|
||||
lg.Debug($" {writeResult}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
lg.Error($"Write Nodes Error : {ex.Message}.");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected static Logger lg;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private readonly Action<IList, IList> m_validateResponse;
|
||||
private ApplicationConfiguration m_configuration;
|
||||
private Session m_session;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Handles the certificate validation event. This event is triggered every time an
|
||||
/// untrusted certificate is received from the server.
|
||||
/// </summary>
|
||||
private void CertificateValidation(CertificateValidator sender, CertificateValidationEventArgs e)
|
||||
{
|
||||
bool certificateAccepted = true;
|
||||
|
||||
// **** Implement a custom logic to decide if the certificate should be accepted or not
|
||||
// and set certificateAccepted flag accordingly. The certificate can be retrieved from
|
||||
// the e.Certificate field ***
|
||||
|
||||
ServiceResult error = e.Error;
|
||||
while (error != null)
|
||||
{
|
||||
lg.Error($"{error.StatusCode} | {error.Code} | {error.LocalizedText}");
|
||||
error = error.InnerResult;
|
||||
}
|
||||
|
||||
if (certificateAccepted)
|
||||
{
|
||||
lg.Info($"Untrusted Certificate accepted. SubjectName = {e.Certificate.SubjectName}");
|
||||
}
|
||||
|
||||
e.AcceptAll = certificateAccepted;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle DataChange notifications from Server
|
||||
/// </summary>
|
||||
private void OnMonitoredItemNotification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Log MonitoredItem Notification event
|
||||
MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
|
||||
|
||||
// sollevo evento notifica vaziazione MonitoredItem
|
||||
if (eh_MonItChange != null)
|
||||
{
|
||||
eh_MonItChange(this, new opcUaMonitItemChange(monitoredItem, notification));
|
||||
}
|
||||
lg.Trace($"Notification Received | Variable: {monitoredItem.DisplayName} | Value: {notification.Value}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
lg.Error($"OnMonitoredItemNotification error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,488 @@
|
||||
/* ========================================================================
|
||||
* Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
|
||||
*
|
||||
* OPC Foundation MIT License 1.00
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* The complete license agreement can be found here:
|
||||
* http://opcfoundation.org/License/MIT/1.00/
|
||||
* ======================================================================*/
|
||||
|
||||
using Opc.Ua;
|
||||
using Opc.Ua.Client;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MP.MONO.ADAPTER.OPC
|
||||
{
|
||||
/// <summary>
|
||||
/// OPC UA Client with examples of basic functionality.
|
||||
/// </summary>
|
||||
internal class UAClient
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the UAClient class.
|
||||
/// </summary>
|
||||
public UAClient(ApplicationConfiguration configuration, TextWriter writer, Action<IList, IList> validateResponse)
|
||||
{
|
||||
m_validateResponse = validateResponse;
|
||||
m_output = writer;
|
||||
m_configuration = configuration;
|
||||
m_configuration.CertificateValidator.CertificateValidation += CertificateValidation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Auto accept untrusted certificates.
|
||||
/// </summary>
|
||||
public bool AutoAccept { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the client session.
|
||||
/// </summary>
|
||||
public Session Session => m_session;
|
||||
|
||||
/// <summary>
|
||||
/// Browse Server nodes
|
||||
/// </summary>
|
||||
public void Browse()
|
||||
{
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
m_output.WriteLine("Session not connected!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Create a Browser object
|
||||
Browser browser = new Browser(m_session);
|
||||
|
||||
// Set browse parameters
|
||||
browser.BrowseDirection = BrowseDirection.Forward;
|
||||
browser.NodeClassMask = (int)NodeClass.Object | (int)NodeClass.Variable;
|
||||
browser.ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences;
|
||||
|
||||
NodeId nodeToBrowse = ObjectIds.Server;
|
||||
|
||||
// Call Browse service
|
||||
m_output.WriteLine("Browsing {0} node...", nodeToBrowse);
|
||||
ReferenceDescriptionCollection browseResults = browser.Browse(nodeToBrowse);
|
||||
|
||||
// Display the results
|
||||
m_output.WriteLine("Browse returned {0} results:", browseResults.Count);
|
||||
|
||||
foreach (ReferenceDescription result in browseResults)
|
||||
{
|
||||
m_output.WriteLine(" DisplayName = {0}, NodeClass = {1}", result.DisplayName.Text, result.NodeClass);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
m_output.WriteLine($"Browse Error : {ex.Message}.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call UA method
|
||||
/// </summary>
|
||||
public void CallMethod()
|
||||
{
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
m_output.WriteLine("Session not connected!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Define the UA Method to call Parent node - Objects\CTT\Methods Method node - Objects\CTT\Methods\Add
|
||||
NodeId objectId = new NodeId("ns=2;s=Methods");
|
||||
NodeId methodId = new NodeId("ns=2;s=Methods_Add");
|
||||
|
||||
// Define the method parameters Input argument requires a Float and an UInt32 value
|
||||
object[] inputArguments = new object[] { (float)10.5, (uint)10 };
|
||||
IList<object> outputArguments = null;
|
||||
|
||||
// Invoke Call service
|
||||
m_output.WriteLine("Calling UAMethod for node {0} ...", methodId);
|
||||
outputArguments = m_session.Call(objectId, methodId, inputArguments);
|
||||
|
||||
// Display results
|
||||
m_output.WriteLine("Method call returned {0} output argument(s):", outputArguments.Count);
|
||||
|
||||
foreach (var outputArgument in outputArguments)
|
||||
{
|
||||
m_output.WriteLine(" OutputValue = {0}", outputArgument.ToString());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_output.WriteLine("Method call error: {0}", ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a session with the UA server
|
||||
/// </summary>
|
||||
public async Task<bool> ConnectAsync(string serverUrl)
|
||||
{
|
||||
if (serverUrl == null) throw new ArgumentNullException(nameof(serverUrl));
|
||||
|
||||
try
|
||||
{
|
||||
if (m_session != null && m_session.Connected == true)
|
||||
{
|
||||
m_output.WriteLine("Session already connected!");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_output.WriteLine("Connecting to... {0}", serverUrl);
|
||||
|
||||
// Get the endpoint by connecting to server's discovery endpoint. Try to find
|
||||
// the first endopint with security.
|
||||
EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(m_configuration, serverUrl, true);
|
||||
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
|
||||
ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);
|
||||
|
||||
// Create the session
|
||||
Session session = await Session.Create(
|
||||
m_configuration,
|
||||
endpoint,
|
||||
false,
|
||||
false,
|
||||
m_configuration.ApplicationName,
|
||||
30 * 60 * 1000,
|
||||
new UserIdentity(),
|
||||
null
|
||||
);
|
||||
|
||||
// Assign the created session
|
||||
if (session != null && session.Connected)
|
||||
{
|
||||
m_session = session;
|
||||
}
|
||||
|
||||
// Session created successfully.
|
||||
m_output.WriteLine("New Session Created with SessionName = {0}", m_session.SessionName);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
m_output.WriteLine("Create Session Error : {0}", ex.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disconnects the session.
|
||||
/// </summary>
|
||||
public void Disconnect()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (m_session != null)
|
||||
{
|
||||
m_output.WriteLine("Disconnecting...");
|
||||
|
||||
m_session.Close();
|
||||
m_session.Dispose();
|
||||
m_session = null;
|
||||
|
||||
// Log Session Disconnected event
|
||||
m_output.WriteLine("Session Disconnected.");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_output.WriteLine("Session not created!");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
m_output.WriteLine($"Disconnect Error : {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a list of nodes from Server
|
||||
/// </summary>
|
||||
public void ReadNodes()
|
||||
{
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
m_output.WriteLine("Session not connected!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// build a list of nodes to be read
|
||||
ReadValueIdCollection nodesToRead = new ReadValueIdCollection()
|
||||
{
|
||||
// Value of ServerStatus
|
||||
new ReadValueId() { NodeId = Variables.Server_ServerStatus, AttributeId = Attributes.Value },
|
||||
// BrowseName of ServerStatus_StartTime
|
||||
new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.BrowseName },
|
||||
// Value of ServerStatus_StartTime
|
||||
new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.Value }
|
||||
};
|
||||
|
||||
// Read the node attributes
|
||||
m_output.WriteLine("Reading nodes...");
|
||||
|
||||
// Call Read Service
|
||||
m_session.Read(
|
||||
null,
|
||||
0,
|
||||
TimestampsToReturn.Both,
|
||||
nodesToRead,
|
||||
out DataValueCollection resultsValues,
|
||||
out DiagnosticInfoCollection diagnosticInfos);
|
||||
|
||||
// Validate the results
|
||||
m_validateResponse(resultsValues, nodesToRead);
|
||||
|
||||
// Display the results.
|
||||
foreach (DataValue result in resultsValues)
|
||||
{
|
||||
m_output.WriteLine("Read Value = {0} , StatusCode = {1}", result.Value, result.StatusCode);
|
||||
}
|
||||
|
||||
// Read Server NamespaceArray
|
||||
m_output.WriteLine("Reading Value of NamespaceArray node...");
|
||||
DataValue namespaceArray = m_session.ReadValue(Variables.Server_NamespaceArray);
|
||||
// Display the result
|
||||
m_output.WriteLine($"NamespaceArray Value = {namespaceArray}");
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
m_output.WriteLine($"Read Nodes Error : {ex.Message}.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create Subscription and MonitoredItems for DataChanges
|
||||
/// </summary>
|
||||
public void SubscribeToDataChanges()
|
||||
{
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
m_output.WriteLine("Session not connected!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Create a subscription for receiving data change notifications
|
||||
|
||||
// Define Subscription parameters
|
||||
Subscription subscription = new Subscription(m_session.DefaultSubscription);
|
||||
|
||||
subscription.DisplayName = "Console ReferenceClient Subscription";
|
||||
subscription.PublishingEnabled = true;
|
||||
subscription.PublishingInterval = 1000;
|
||||
|
||||
m_session.AddSubscription(subscription);
|
||||
|
||||
// Create the subscription on Server side
|
||||
subscription.Create();
|
||||
m_output.WriteLine("New Subscription created with SubscriptionId = {0}.", subscription.Id);
|
||||
|
||||
// Create MonitoredItems for data changes (Reference Server)
|
||||
|
||||
MonitoredItem intMonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
intMonitoredItem.StartNodeId = new NodeId("ns=2;s=Scalar_Simulation_Int32");
|
||||
intMonitoredItem.AttributeId = Attributes.Value;
|
||||
intMonitoredItem.DisplayName = "Int32 Variable";
|
||||
intMonitoredItem.SamplingInterval = 1000;
|
||||
intMonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
|
||||
subscription.AddItem(intMonitoredItem);
|
||||
|
||||
MonitoredItem floatMonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
// Float Node - Objects\CTT\Scalar\Simulation\Float
|
||||
floatMonitoredItem.StartNodeId = new NodeId("ns=2;s=Scalar_Simulation_Float");
|
||||
floatMonitoredItem.AttributeId = Attributes.Value;
|
||||
floatMonitoredItem.DisplayName = "Float Variable";
|
||||
floatMonitoredItem.SamplingInterval = 1000;
|
||||
floatMonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
|
||||
subscription.AddItem(floatMonitoredItem);
|
||||
|
||||
MonitoredItem stringMonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
// String Node - Objects\CTT\Scalar\Simulation\String
|
||||
stringMonitoredItem.StartNodeId = new NodeId("ns=2;s=Scalar_Simulation_String");
|
||||
stringMonitoredItem.AttributeId = Attributes.Value;
|
||||
stringMonitoredItem.DisplayName = "String Variable";
|
||||
stringMonitoredItem.SamplingInterval = 1000;
|
||||
stringMonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
|
||||
subscription.AddItem(stringMonitoredItem);
|
||||
|
||||
// Create the monitored items on Server side
|
||||
subscription.ApplyChanges();
|
||||
m_output.WriteLine("MonitoredItems created for SubscriptionId = {0}.", subscription.Id);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_output.WriteLine("Subscribe error: {0}", ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a list of nodes to the Server
|
||||
/// </summary>
|
||||
public void WriteNodes()
|
||||
{
|
||||
if (m_session == null || m_session.Connected == false)
|
||||
{
|
||||
m_output.WriteLine("Session not connected!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Write the configured nodes
|
||||
WriteValueCollection nodesToWrite = new WriteValueCollection();
|
||||
|
||||
// Int32 Node - Objects\CTT\Scalar\Scalar_Static\Int32
|
||||
WriteValue intWriteVal = new WriteValue();
|
||||
intWriteVal.NodeId = new NodeId("ns=2;s=Scalar_Static_Int32");
|
||||
intWriteVal.AttributeId = Attributes.Value;
|
||||
intWriteVal.Value = new DataValue();
|
||||
intWriteVal.Value.Value = (int)100;
|
||||
nodesToWrite.Add(intWriteVal);
|
||||
|
||||
// Float Node - Objects\CTT\Scalar\Scalar_Static\Float
|
||||
WriteValue floatWriteVal = new WriteValue();
|
||||
floatWriteVal.NodeId = new NodeId("ns=2;s=Scalar_Static_Float");
|
||||
floatWriteVal.AttributeId = Attributes.Value;
|
||||
floatWriteVal.Value = new DataValue();
|
||||
floatWriteVal.Value.Value = (float)100.5;
|
||||
nodesToWrite.Add(floatWriteVal);
|
||||
|
||||
// String Node - Objects\CTT\Scalar\Scalar_Static\String
|
||||
WriteValue stringWriteVal = new WriteValue();
|
||||
stringWriteVal.NodeId = new NodeId("ns=2;s=Scalar_Static_String");
|
||||
stringWriteVal.AttributeId = Attributes.Value;
|
||||
stringWriteVal.Value = new DataValue();
|
||||
stringWriteVal.Value.Value = "String Test";
|
||||
nodesToWrite.Add(stringWriteVal);
|
||||
|
||||
// Write the node attributes
|
||||
StatusCodeCollection results = null;
|
||||
DiagnosticInfoCollection diagnosticInfos;
|
||||
m_output.WriteLine("Writing nodes...");
|
||||
|
||||
// Call Write Service
|
||||
m_session.Write(null,
|
||||
nodesToWrite,
|
||||
out results,
|
||||
out diagnosticInfos);
|
||||
|
||||
// Validate the response
|
||||
m_validateResponse(results, nodesToWrite);
|
||||
|
||||
// Display the results.
|
||||
m_output.WriteLine("Write Results :");
|
||||
|
||||
foreach (StatusCode writeResult in results)
|
||||
{
|
||||
m_output.WriteLine(" {0}", writeResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log Error
|
||||
m_output.WriteLine($"Write Nodes Error : {ex.Message}.");
|
||||
}
|
||||
}
|
||||
|
||||
private readonly TextWriter m_output;
|
||||
|
||||
private readonly Action<IList, IList> m_validateResponse;
|
||||
|
||||
private ApplicationConfiguration m_configuration;
|
||||
|
||||
private Session m_session;
|
||||
|
||||
/// <summary>
|
||||
/// Handles the certificate validation event. This event is triggered every time an
|
||||
/// untrusted certificate is received from the server.
|
||||
/// </summary>
|
||||
private void CertificateValidation(CertificateValidator sender, CertificateValidationEventArgs e)
|
||||
{
|
||||
bool certificateAccepted = false;
|
||||
|
||||
// **** Implement a custom logic to decide if the certificate should be accepted or not
|
||||
// and set certificateAccepted flag accordingly. The certificate can be retrieved from
|
||||
// the e.Certificate field ***
|
||||
|
||||
ServiceResult error = e.Error;
|
||||
m_output.WriteLine(error);
|
||||
if (error.StatusCode == StatusCodes.BadCertificateUntrusted && AutoAccept)
|
||||
{
|
||||
certificateAccepted = true;
|
||||
}
|
||||
|
||||
if (certificateAccepted)
|
||||
{
|
||||
m_output.WriteLine("Untrusted Certificate accepted. Subject = {0}", e.Certificate.Subject);
|
||||
e.Accept = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_output.WriteLine("Untrusted Certificate rejected. Subject = {0}", e.Certificate.Subject);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle DataChange notifications from Server
|
||||
/// </summary>
|
||||
private void OnMonitoredItemNotification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Log MonitoredItem Notification event
|
||||
MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
|
||||
m_output.WriteLine("Notification Received for Variable \"{0}\" and Value = {1}.", monitoredItem.DisplayName, notification.Value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_output.WriteLine("OnMonitoredItemNotification error: {0}", ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"Redis": "redis01.ufficio:26379,serviceName=devel,DefaultDatabase=7,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false",
|
||||
"AuthConnection": "Server=localhost;port=3306;database=GWMS;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
|
||||
"DefaultConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
|
||||
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Seriate_24068!;sslmode=None;",
|
||||
"MP.MONO.Data": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;"
|
||||
},
|
||||
"DbConfig": {
|
||||
"Server": "10.74.82.230",
|
||||
"nKey": "MONO",
|
||||
"sKey": "Calcium0xide-CaO"
|
||||
},
|
||||
"MachineId": 1,
|
||||
"maxRecord": 15,
|
||||
"ExternalProviders": {
|
||||
"MailKit": {
|
||||
"SMTP": {
|
||||
"Address": "smtp.gmail.com",
|
||||
"Port": "465",
|
||||
"Account": "steamwarebot@gmail.com",
|
||||
"Password": "drmfsls16",
|
||||
"SenderEmail": "steamwarebot@gmail.com",
|
||||
"SenderName": "Steamware Email BOT"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Endpoint": {
|
||||
"ConfFile": "Demo.json",
|
||||
"FullUrl": "opc.tcp://wrkst-r9-sam:62541/Quickstarts/ReferenceServer",
|
||||
"PingMsTimeout": 1500
|
||||
},
|
||||
"OptPar": {
|
||||
"AlarmMode": "RawList",
|
||||
"AlarmRegexp": "^{[\\d\\w\\:\\ \\.\\/\\(\\)]*}",
|
||||
//"AlarmRegexp": "^{.*}",
|
||||
"AlarmCleanPre": "{",
|
||||
"AlarmCleanPost": "}",
|
||||
"AlarmTrimWSpace": true,
|
||||
"CleanupRegexpPre": "",
|
||||
//"CleanupRegexpPre": "[^a-zA-Z0-9 %/,.\\-\\+\\r\\n]",
|
||||
"CleanupRegexpPost": "[^a-zA-Z0-9 %\\{\\},.\\-\\+]",
|
||||
"FiltCrLf": true,
|
||||
"FiltSplitChar": [],
|
||||
"ForceSplit": true,
|
||||
"Log2Console": true,
|
||||
"Log2File": true,
|
||||
"MinWait": 50,
|
||||
"MaxWait": 150,
|
||||
"VetoSendCache": 50,
|
||||
"DataStaleSec": 60
|
||||
},
|
||||
"Machine": {
|
||||
"Manufacturer": "Multiax",
|
||||
"Model": "Model-D",
|
||||
"Name": "D1521",
|
||||
"SerialNumber": "1521"
|
||||
},
|
||||
"ENABLE_DATA_FILTER": true,
|
||||
"ENABLE_CLI_RESTART": true,
|
||||
"logEvery": 10,
|
||||
"OPC_PARAM_CONF": "Multiax.json",
|
||||
"pingTestSec": 5,
|
||||
"verbose": false,
|
||||
"disconMaxSec": 30,
|
||||
"verboseLogTOut": 60,
|
||||
"waitRecMSec": 60000
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"Redis": "localhost:6379,DefaultDatabase=7,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false",
|
||||
"AuthConnection": "Server=localhost;port=3306;database=GWMS;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
|
||||
"DefaultConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
|
||||
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Seriate_24068!;sslmode=None;",
|
||||
"MP.MONO.Data": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;"
|
||||
},
|
||||
"DbConfig": {
|
||||
"Server": "localhost",
|
||||
"nKey": "MONO",
|
||||
"sKey": "Calcium0xide-CaO"
|
||||
},
|
||||
"MachineId": 1,
|
||||
"maxRecord": 15,
|
||||
"ExternalProviders": {
|
||||
"MailKit": {
|
||||
"SMTP": {
|
||||
"Address": "smtp.gmail.com",
|
||||
"Port": "465",
|
||||
"Account": "steamwarebot@gmail.com",
|
||||
"Password": "drmfsls16",
|
||||
"SenderEmail": "steamwarebot@gmail.com",
|
||||
"SenderName": "Steamware Email BOT"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Endpoint": {
|
||||
"ConfFile": "Multiax.json",
|
||||
"FullUrl": "opc.tcp://192.168.0.2:4840",
|
||||
"PingMsTimeout": 1500
|
||||
},
|
||||
"OptPar": {
|
||||
"AlarmMode": "RawList",
|
||||
"AlarmRegexp": "^{[\\d\\w\\:\\ \\.\\/\\(\\)]*}",
|
||||
//"AlarmRegexp": "^{.*}",
|
||||
"AlarmCleanPre": "{",
|
||||
"AlarmCleanPost": "}",
|
||||
"CleanupRegexpPre": "",
|
||||
//"CleanupRegexpPre": "[^a-zA-Z0-9 %/,.\\-\\+\\r\\n]",
|
||||
"CleanupRegexpPost": "[^a-zA-Z0-9 %/,.\\-\\+]",
|
||||
"FiltCrLf": true,
|
||||
"FiltSplitChar": [],
|
||||
"ForceSplit": true,
|
||||
"Log2Console": true,
|
||||
"Log2File": true,
|
||||
"MinWait": 50,
|
||||
"MaxWait": 150,
|
||||
"VetoSendCache": 50
|
||||
},
|
||||
"Machine": {
|
||||
"Manufacturer": "Multiax",
|
||||
"Model": "Model-D",
|
||||
"Name": "D1521",
|
||||
"SerialNumber": "1521"
|
||||
},
|
||||
"ENABLE_DATA_FILTER": true,
|
||||
"ENABLE_CLI_RESTART": true,
|
||||
"logEvery": 10,
|
||||
"OPC_PARAM_CONF": "Multiax.json",
|
||||
"pingTestSec": 5,
|
||||
"verbose": false,
|
||||
"disconMaxSec": 30,
|
||||
"verboseLogTOut": 60,
|
||||
"waitRecMSec": 60000
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"Redis": "redis01.ufficio:26379,serviceName=devel,DefaultDatabase=7,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false",
|
||||
"AuthConnection": "Server=localhost;port=3306;database=GWMS;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
|
||||
"DefaultConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;",
|
||||
"AdminConnection": "Server=localhost;port=3306;database=MAPO.MONO;user=root;pwd=Seriate_24068!;sslmode=None;",
|
||||
"MP.MONO.Data": "Server=localhost;port=3306;database=MAPO.MONO;user=GWMS;pwd=GWMS_secret_pwd;sslmode=None;"
|
||||
},
|
||||
"DbConfig": {
|
||||
"Server": "10.74.82.230",
|
||||
"nKey": "MONO",
|
||||
"sKey": "Calcium0xide-CaO"
|
||||
},
|
||||
"MachineId": 1,
|
||||
"maxRecord": 15,
|
||||
"ExternalProviders": {
|
||||
"MailKit": {
|
||||
"SMTP": {
|
||||
"Address": "smtp.gmail.com",
|
||||
"Port": "465",
|
||||
"Account": "steamwarebot@gmail.com",
|
||||
"Password": "drmfsls16",
|
||||
"SenderEmail": "steamwarebot@gmail.com",
|
||||
"SenderName": "Steamware Email BOT"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Endpoint": {
|
||||
"ConfFile": "Demo.json",
|
||||
"FullUrl": "opc.tcp://wrkst-r9-sam:62541/Quickstarts/ReferenceServer",
|
||||
"PingMsTimeout": 1500
|
||||
},
|
||||
"OptPar": {
|
||||
"AlarmMode": "RawList",
|
||||
"AlarmRegexp": "^{[\\d\\w\\:\\ \\.\\/\\(\\)]*}",
|
||||
//"AlarmRegexp": "^{.*}",
|
||||
"AlarmCleanPre": "{",
|
||||
"AlarmCleanPost": "}",
|
||||
"CleanupRegexpPre": "",
|
||||
//"CleanupRegexpPre": "[^a-zA-Z0-9 %/,.\\-\\+\\r\\n]",
|
||||
"CleanupRegexpPost": "[^a-zA-Z0-9 %/,.\\-\\+]",
|
||||
"FiltCrLf": true,
|
||||
"FiltSplitChar": [],
|
||||
"ForceSplit": true,
|
||||
"Log2Console": true,
|
||||
"Log2File": true,
|
||||
"MinWait": 50,
|
||||
"MaxWait": 150,
|
||||
"VetoSendCache": 50
|
||||
},
|
||||
"Machine": {
|
||||
"Manufacturer": "Multiax",
|
||||
"Model": "Model-D",
|
||||
"Name": "D1521",
|
||||
"SerialNumber": "1521"
|
||||
},
|
||||
"ENABLE_DATA_FILTER": true,
|
||||
"ENABLE_CLI_RESTART": true,
|
||||
"logEvery": 10,
|
||||
"OPC_PARAM_CONF": "Multiax.json",
|
||||
"pingTestSec": 5,
|
||||
"verbose": false,
|
||||
"disconMaxSec": 30,
|
||||
"verboseLogTOut": 60,
|
||||
"waitRecMSec": 60000
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
REM collect a trace using the EventSource provider OPC-UA-Core
|
||||
dotnet tool install --global dotnet-trace
|
||||
dotnet-trace collect --name consolereferenceclient --providers OPC-UA-Core,OPC-UA-Client
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
Binary file not shown.
@@ -15,6 +15,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.MONO.DECODER", "MP.MONO.
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.MONO.ANALYZER", "MP.MONO.ANALYZER\MP.MONO.ANALYZER.csproj", "{4C9BEAED-1A33-41A7-B9D6-7C173A43FDB8}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.MONO.ADAPTER.OPC", "MP.MONO.ADAPTER.OPC\MP.MONO.ADAPTER.OPC.csproj", "{FA236252-9AF8-426A-8A0A-D3C234441563}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -97,6 +99,18 @@ Global
|
||||
{4C9BEAED-1A33-41A7-B9D6-7C173A43FDB8}.Release|x64.Build.0 = Release|x64
|
||||
{4C9BEAED-1A33-41A7-B9D6-7C173A43FDB8}.Release|x86.ActiveCfg = Release|x86
|
||||
{4C9BEAED-1A33-41A7-B9D6-7C173A43FDB8}.Release|x86.Build.0 = Release|x86
|
||||
{FA236252-9AF8-426A-8A0A-D3C234441563}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FA236252-9AF8-426A-8A0A-D3C234441563}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FA236252-9AF8-426A-8A0A-D3C234441563}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{FA236252-9AF8-426A-8A0A-D3C234441563}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{FA236252-9AF8-426A-8A0A-D3C234441563}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{FA236252-9AF8-426A-8A0A-D3C234441563}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{FA236252-9AF8-426A-8A0A-D3C234441563}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FA236252-9AF8-426A-8A0A-D3C234441563}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FA236252-9AF8-426A-8A0A-D3C234441563}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{FA236252-9AF8-426A-8A0A-D3C234441563}.Release|x64.Build.0 = Release|Any CPU
|
||||
{FA236252-9AF8-426A-8A0A-D3C234441563}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{FA236252-9AF8-426A-8A0A-D3C234441563}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -6,12 +6,13 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>AnyCPU;x86;x64</Platforms>
|
||||
<Version>1.2.2409.2509</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="NLog" Version="4.7.14" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.5.43" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="NLog" Version="5.2.3" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.6.122" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -43,5 +44,7 @@
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
<Exec Command="powershell.exe -ExecutionPolicy Unrestricted -NoProfile -NonInteractive -File $(ProjectDir)\post-build.ps1 -ProjectDir $(ProjectDir) -ProjectPath $(ProjectPath)" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>bin\Debug\net6.0\publish\win-x64\</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<SelfContained>false</SelfContained>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<PublishSingleFile>true</PublishSingleFile>
|
||||
<PublishReadyToRun>true</PublishReadyToRun>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,26 @@
|
||||
<body>
|
||||
<i>MAPO-MONO</i>
|
||||
<h4>Version: {{CURRENT-REL}}</h4>
|
||||
<br /> Release Note:
|
||||
<ul>
|
||||
<li>
|
||||
<b>Last changes:</b>
|
||||
<ul>{{LAST-CHANGES}}</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>v.1.0.* →</b>
|
||||
<ul>
|
||||
<li>Current CORE version</li>
|
||||
<li>Release dotnet6</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<div>
|
||||
<div style="float: left;">
|
||||
<img src="logoSteamware.png" />
|
||||
</div>
|
||||
<div style="float: right;">
|
||||
<a href="https://www.steamware.net/MAPO" target="_blank">© Egalware 2006-2022</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
@@ -0,0 +1,26 @@
|
||||
<body>
|
||||
<i>MAPO-MONO</i>
|
||||
<h4>Version: 1.2.2409.2509</h4>
|
||||
<br /> Release Note:
|
||||
<ul>
|
||||
<li>
|
||||
<b>Last changes:</b>
|
||||
<ul>{{LAST-CHANGES}}</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>v.1.0.* →</b>
|
||||
<ul>
|
||||
<li>Current CORE version</li>
|
||||
<li>Release dotnet6</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<div>
|
||||
<div style="float: left;">
|
||||
<img src="logoSteamware.png" />
|
||||
</div>
|
||||
<div style="float: right;">
|
||||
<a href="https://www.steamware.net/MAPO" target="_blank">© Egalware 2006-2022</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
@@ -0,0 +1 @@
|
||||
1.2.2409.2509
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>1.0.0.0</version>
|
||||
<url>http://nexus.steamware.net/repository/SWS/{{DIRNAME}}/{{BRANCHNAME}}/{{PACKNAME}}.zip</url>
|
||||
<changelog>http://nexus.steamware.net/repository/SWS/{{DIRNAME}}/{{BRANCHNAME}}/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
</item>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>1.2.2409.2509</version>
|
||||
<url>http://nexus.steamware.net/repository/SWS/MP.MONO.ANALYZER/stable/LAST/MP.Mon.zip</url>
|
||||
<changelog>http://nexus.steamware.net/repository/SWS/MP.MONO.ANALYZER/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
</item>
|
||||
@@ -0,0 +1,32 @@
|
||||
param([string]$ProjectDir, [string]$ProjectPath);
|
||||
|
||||
$FileMajMin = "..\MajMin.vers"
|
||||
$FileVers = "Resources\VersNum.txt"
|
||||
$FileManIn = "Resources\manifest-original.xml"
|
||||
$FileManOut = "Resources\manifest.xml"
|
||||
$FileCLogIn = "Resources\ChangeLog-original.html"
|
||||
$FileCLogOut = "Resources\ChangeLog.html"
|
||||
$MajMin = Get-Content $FileMajMin
|
||||
$currentDate = get-date -format yyMM;
|
||||
$currentTime = get-date -format dHH;
|
||||
$find = "<Version>(.|\n)*?</Version>";
|
||||
$currRelNum = $MajMin + $currentDate +"." + $currentTime
|
||||
$replace = "<Version>" + $MajMin + $currentDate +"." + $currentTime + "</Version>";
|
||||
$csproj = Get-Content $ProjectPath
|
||||
$csprojUpdated = $csproj -replace $find, $replace
|
||||
|
||||
Set-Content -Path $ProjectPath -Value $csprojUpdated
|
||||
Set-Content -Path $FileVers -Value $currRelNum
|
||||
|
||||
# replace x manifest
|
||||
$manData = Get-Content $FileManIn
|
||||
$manData = $manData -replace "1.0.0.0", $currRelNum
|
||||
$manData = $manData -replace "{{DIRNAME}}", "MP.MONO.ANALYZER"
|
||||
$manData = $manData -replace "{{BRANCHNAME}}", "stable/LAST"
|
||||
$manData = $manData -replace "{{PACKNAME}}", "MP.Mon"
|
||||
Set-Content -Path $FileManOut -Value $manData
|
||||
|
||||
# replace x ChangeLog
|
||||
$clogData = Get-Content $FileCLogIn
|
||||
$clogData = $clogData -replace "{{CURRENT-REL}}", $currRelNum
|
||||
Set-Content -Path $FileCLogOut -Value $clogData
|
||||
@@ -0,0 +1,253 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using static MP.MONO.Core.Enums;
|
||||
|
||||
namespace MP.MONO.Core.CONF
|
||||
{
|
||||
/// <summary>
|
||||
/// Classe gestione configurazione parametri di base x allarmi di tipo BankBit
|
||||
/// </summary>
|
||||
public class BaseAlarmBankConf
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Segnaposto impiegato x disabilitare gli allarmi (sempre)
|
||||
/// </summary>
|
||||
public string disableMark { get; set; } = "##";
|
||||
|
||||
/// <summary>
|
||||
/// Elenco dei contatori blink x gestione caso fronte salita/discesa segnale che blinka
|
||||
/// </summary>
|
||||
public int[] alarmsBlinkCounter { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// BitMask 16bit (1 = valido, 0 = filtro) degli allarmi silenziati (salvato in redis) come valore da sottrarre x check
|
||||
/// </summary>
|
||||
public uint[] silenceMask { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// BitMask 16bit (1 = valido, 0 = filtro) degli allarmi DISABILITATI (se iniziano per [disableMark]) come valore da sottrarre x check
|
||||
/// </summary>
|
||||
public uint[] disableMask { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Array dei valori allarme correnti
|
||||
/// </summary>
|
||||
public uint[] alarmsState { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// valore di partenza x un segnale di blink in caso di fine variazione (fronte discesa)
|
||||
/// </summary>
|
||||
public int blinkDownVal { get; set; } = 4;
|
||||
|
||||
/// <summary>
|
||||
/// valore di partenza x un segnale di blink in caso di inizio variazione (fronte salita)
|
||||
/// </summary>
|
||||
public int blinkUpVal { get; set; } = 3;
|
||||
|
||||
/// <summary>
|
||||
/// Descrizione area allarmi
|
||||
/// </summary>
|
||||
public string description { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Indice nell'area di memoria (da valore iniziale = 0)
|
||||
/// </summary>
|
||||
public int index { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Nome "assoluto" della posizione nell'area di memoria (anche diverso da indice)
|
||||
/// </summary>
|
||||
public string memAddr { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Elenco allarmi configurati x la bitmap
|
||||
/// </summary>
|
||||
public List<string> messages { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Dictionary calcolato allarmi
|
||||
/// </summary>
|
||||
public Dictionary<int, string> messagesMap //{ get; set; } = new Dictionary<int, string>();
|
||||
{
|
||||
get
|
||||
{
|
||||
Dictionary<int, string> map = new Dictionary<int, string>();
|
||||
if (messages != null)
|
||||
{
|
||||
foreach (var item in messages)
|
||||
{
|
||||
map.Add(map.Count + 1, item);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
public bool isSilenced(int messIndex)
|
||||
{
|
||||
//decremento: è base 1 mi serve base 0...
|
||||
messIndex--;
|
||||
bool answ = false;
|
||||
int bank = (messIndex) / 16;
|
||||
if (silenceMask != null && silenceMask.Length >= bank)
|
||||
{
|
||||
var testVal = 1 << messIndex;
|
||||
answ = !((silenceMask[bank] & testVal) == testVal);
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Size in byte
|
||||
/// </summary>
|
||||
public int size { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Tipo di dato
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public plcDataType tipoMem { get; set; } = plcDataType.Boolean;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Calcola il filtro da condizione blink (ovvero maschera per valori indicati blinking)
|
||||
/// </summary>
|
||||
/// <param name="num"></param>
|
||||
/// <returns></returns>
|
||||
public uint blinkFilter(int num)
|
||||
{
|
||||
uint answ = 0;
|
||||
int idx = 16 * num;
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
if (alarmsBlinkCounter[idx + i] > 0)
|
||||
{
|
||||
answ += (uint)1 << i;
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua update dei contatori blink per gestire i segnali alternati sul fronte di salita/discesa
|
||||
/// </summary>
|
||||
/// <param name="num"></param>
|
||||
/// <param name="newStatus"></param>
|
||||
public void checkBlinkCounter(int num, uint newStatus)
|
||||
{
|
||||
// calcola la maschera di variazione da valore precedente
|
||||
var variations = newStatus ^ alarmsState[num];
|
||||
// ciclo sui 16 bit...
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
// controllo se è variato
|
||||
if ((variations & (1 << i)) == (1 << i))
|
||||
{
|
||||
// se il valore nuovo è 1 --> è in fronte salita
|
||||
if ((newStatus & (1 << i)) == (1 << i))
|
||||
{
|
||||
// cambio SOLO SE il valore blink è zero...
|
||||
if (alarmsBlinkCounter[num * 16 + i] == 0)
|
||||
{
|
||||
alarmsBlinkCounter[num * 16 + i] = blinkUpVal;
|
||||
}
|
||||
}
|
||||
// altrimenti se è fronte discesa
|
||||
else
|
||||
{
|
||||
// cambio SOLO SE il valore blink è zero...
|
||||
if (alarmsBlinkCounter[num * 16 + i] == 0)
|
||||
{
|
||||
alarmsBlinkCounter[num * 16 + i] = blinkDownVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// decremento contatori blink
|
||||
int idx = 0;
|
||||
foreach (var item in alarmsBlinkCounter)
|
||||
{
|
||||
alarmsBlinkCounter[idx] = item > 0 ? item - 1 : item;
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Confronta un valore di stato allarme con lo stato precedentemente salvato considerando blink/veto
|
||||
/// </summary>
|
||||
/// <param name="num">Numero/indice del banco di allarme (uint16)</param>
|
||||
/// <param name="newValue">Valore (bitmap) allarmi come uint16</param>
|
||||
/// <returns></returns>
|
||||
public bool isChanged(int num, uint newValue)
|
||||
{
|
||||
// per prima cosa controllo valori RAW
|
||||
bool answ = !alarmsState[num].Equals(newValue);
|
||||
if (answ)
|
||||
{
|
||||
// controllo valori filtrati x silenziamento temporaneo o definitivo (sottraendo BITMASK dai valori di filtro)
|
||||
answ = ((alarmsState[num] & disableMask[num] & silenceMask[num]) != (newValue & disableMask[num] & silenceMask[num]));
|
||||
// se fossero ancora differenti controllo ulteriore mask dato il counter dei blink:
|
||||
if (answ)
|
||||
{
|
||||
var blinkFilt = blinkFilter(num);
|
||||
answ = ((alarmsState[num] & (disableMask[num] & silenceMask[num] & ~blinkFilt)) != (newValue & (disableMask[num] & silenceMask[num] & ~blinkFilt)));
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inizializzazione classe con valori calcolati: attenzione si aspetta banchi da 32 bit...
|
||||
/// </summary>
|
||||
public void setupData()
|
||||
{
|
||||
// inizializzo vettore valore allarmi x banco int16
|
||||
alarmsState = new uint[size / 2];
|
||||
disableMask = new uint[size / 2];
|
||||
silenceMask = new uint[size / 2];
|
||||
|
||||
// una volta inizializzata la classe di base sistemo vettori allarmi disabilitati ed il contatore blink dei fronti di discesa
|
||||
alarmsBlinkCounter = new int[messages.Count];
|
||||
int idx = 0;
|
||||
int bank = 0;
|
||||
foreach (var item in messages)
|
||||
{
|
||||
if (item.StartsWith(disableMark))
|
||||
{
|
||||
alarmsBlinkCounter[idx] = -999;
|
||||
}
|
||||
else
|
||||
{
|
||||
alarmsBlinkCounter[idx] = 1;
|
||||
disableMask[bank] += (uint)1 << idx;
|
||||
}
|
||||
silenceMask[bank] += (uint)1 << idx;
|
||||
idx++;
|
||||
// sistemo bank/indice
|
||||
if (idx > 15)
|
||||
{
|
||||
bank++;
|
||||
idx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imposta il valore dello status attuale allarme impostando eventuale valore blink x le variazioni
|
||||
/// </summary>
|
||||
/// <param name="num"></param>
|
||||
/// <param name="newStatus"></param>
|
||||
public void updStatusVal(int num, uint newStatus)
|
||||
{
|
||||
// salvo nuovo valore
|
||||
alarmsState[num] = newStatus;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
namespace MP.MONO.Core.CONF
|
||||
{
|
||||
/// <summary>
|
||||
/// Classe gestione configurazione parametri di base x allarmi di tipo RawList
|
||||
/// </summary>
|
||||
public class BaseAlarmRawConf
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Elenco allarmi configurati x la bitmap
|
||||
/// </summary>
|
||||
public List<string> messages { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Descrizione area allarmi
|
||||
/// </summary>
|
||||
public string source { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto modificato:
|
||||
/// - true: l'oggetto è stato modificato e necessita salvataggio su filesystem
|
||||
/// - false: dati in redis e filesystem allineati
|
||||
/// </summary>
|
||||
public bool changed { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// DataOra ultima operazione di salvataggio
|
||||
/// </summary>
|
||||
public DateTime lastWrite { get; set; } = DateTime.Now;
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MP.MONO.Core.CONF
|
||||
{
|
||||
/// <summary>
|
||||
/// Classe gestione configurazione parametri di base x configuraizone estesa (es MTConnect,
|
||||
/// OPC-UA, ...)
|
||||
/// </summary>
|
||||
public class BaseParamConf
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Struttura dati x check condizione LAVORA / Green
|
||||
/// </summary>
|
||||
public List<diCheckCondition> condWork { get; set; } = new List<diCheckCondition>();
|
||||
|
||||
/// <summary>
|
||||
/// Indica se l'emergenza armata va riportata verso Mapo come bit a TRUE True --> armata
|
||||
/// = 1 / triggered = 0 False --> triggered = 1 / armata = 0
|
||||
/// </summary>
|
||||
public bool emergencyArmedTrue { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Elenco items FILTRATI da invio come dynData --> FluxLog (events o samples)
|
||||
/// </summary>
|
||||
public List<string> fluxLogVeto { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Array degli elementi di traduzione item
|
||||
/// </summary>
|
||||
public Dictionary<string, string> itemTranslation { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Nome variabile x EmergencyStop
|
||||
/// </summary>
|
||||
public string keyEStop { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Nome variabile x pezzi FATTI
|
||||
/// </summary>
|
||||
public string keyPartCount { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Nome variabile x Codice Articolo
|
||||
/// </summary>
|
||||
public string keyPartId { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Nome variabile x pezzi RICHIESTI
|
||||
/// </summary>
|
||||
public string keyPartReq { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Nome variabile x NOME PROGRAMMA
|
||||
/// </summary>
|
||||
public string keyProgName { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Nome variabile x RunMode
|
||||
/// </summary>
|
||||
public string keyRunMode { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Dictionary dei nomi da cercare come "endsWith" a cui applicare la soglia indicata
|
||||
/// </summary>
|
||||
public Dictionary<string, int> paramsEndThresh { get; set; } = new Dictionary<string, int>();
|
||||
|
||||
/// <summary>
|
||||
/// Indica se il ping sia un criterio valido x determinare powerON impianto
|
||||
/// </summary>
|
||||
public bool pingAsPowerOn { get; set; } = true;
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MP.MONO.Core.CONF
|
||||
{
|
||||
public class EndpointData
|
||||
{
|
||||
public string ConfFile { get; set; } = "Demo.json";
|
||||
public string IpAddress { get; set; } = "";
|
||||
public string FullUrl { get; set; } = "";
|
||||
public int Port { get; set; } = 0;
|
||||
public int PingMsTimeout { get; set; } = 1000;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using static MP.MONO.Core.Enums;
|
||||
|
||||
namespace MP.MONO.Core.CONF
|
||||
{
|
||||
/// <summary>
|
||||
/// Descrittore oggetto DataItem generico
|
||||
/// </summary>
|
||||
public class MachDataItem
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
public MachDataItem()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Categoria oggetto
|
||||
/// </summary>
|
||||
public DataItemCategory Category { get; set; } = DataItemCategory.EVENT;
|
||||
|
||||
/// <summary>
|
||||
/// Nome / descrizione
|
||||
/// </summary>
|
||||
public string Name { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Tipologia specifica
|
||||
/// </summary>
|
||||
public string SubType { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Tipologia principale
|
||||
/// </summary>
|
||||
public string Type { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Unità di misura
|
||||
/// </summary>
|
||||
public string Units { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// ID generico
|
||||
/// </summary>
|
||||
public string uuid { get; set; } = "";
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using static MP.MONO.Core.Enums;
|
||||
|
||||
namespace MP.MONO.Core.CONF
|
||||
{
|
||||
/// <summary>
|
||||
/// Definizione parametri di setup incrociato...
|
||||
/// </summary>
|
||||
public class MachineSetupConf
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario dei parametri di corrispondenza tra variabili MES e variabili Macchina MES =
|
||||
/// scritte dal MES Macchina = scritte da macchina
|
||||
/// </summary>
|
||||
public Dictionary<string, string> checkParList { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Abilitazione gestione Setup Avanzato (= scrittura)
|
||||
/// </summary>
|
||||
public bool EnableAdvSetup { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Modalità gestione setup
|
||||
/// </summary>
|
||||
public MachineSetupMode SetupMode { get; set; } = MachineSetupMode.ND;
|
||||
|
||||
/// <summary> Dizionario dei parametri da scrivere quando si rilevano differenze tra i
|
||||
/// parametri MES/Macchina string (key) --> memoria da scrivere tuple<int isEqual,int
|
||||
/// notEqual> --> valori da scrivere quando uguali o diversi </summary>
|
||||
public List<MachineSetupAction> writeParAction { get; set; } = new List<MachineSetupAction>();
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
using static MP.MONO.Core.Enums;
|
||||
|
||||
namespace MP.MONO.Core.CONF
|
||||
{
|
||||
/// <summary>
|
||||
/// Classe gestione configurazione parametri specifici OPC-UA da BaseParamConf
|
||||
/// </summary>
|
||||
public class OpcUaParamConf : BaseParamConf
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Identificativo nodo iniziale
|
||||
/// </summary>
|
||||
public string BrowseFullVal { get; set; } = "ns=2;s=Scalar_Static";
|
||||
|
||||
/// <summary>
|
||||
/// Parametri identity x accesso con nome/pwd
|
||||
/// </summary>
|
||||
public UserIdent Identity { get; set; } = new UserIdent();
|
||||
|
||||
/// <summary>
|
||||
/// Indice NS da cui fare il browse dei file
|
||||
/// </summary>
|
||||
public ushort BrowseNSIndex { get; set; } = 4;
|
||||
|
||||
/// <summary>
|
||||
/// ID del nodo da cui partire x il browse di identificazione nodi iniziale
|
||||
/// </summary>
|
||||
public uint BrowseValue { get; set; } = 5001;
|
||||
|
||||
/// <summary>
|
||||
/// Struttura dati x check condizione Contapezzi Abilitato (se vuoto = sempre abilitato)
|
||||
/// </summary>
|
||||
public diCheckCondSetup condCountEnabled { get; set; } = new diCheckCondSetup();
|
||||
|
||||
/// <summary>
|
||||
/// Struttura dati x check condizione Errore
|
||||
/// </summary>
|
||||
public diCheckCondSetup condError { get; set; } = new diCheckCondSetup();
|
||||
|
||||
/// <summary>
|
||||
/// Struttura dati x check condizione Emergenza
|
||||
/// </summary>
|
||||
public diCheckCondSetup condEStop { get; set; } = new diCheckCondSetup();
|
||||
|
||||
/// <summary>
|
||||
/// Struttura dati x check condizione Manual
|
||||
/// </summary>
|
||||
public diCheckCondSetup condManual { get; set; } = new diCheckCondSetup();
|
||||
|
||||
/// <summary>
|
||||
/// Struttura dati x check condizione PowerOn
|
||||
/// </summary>
|
||||
public diCheckCondSetup condPowerOn { get; set; } = new diCheckCondSetup();
|
||||
|
||||
/// <summary>
|
||||
/// Struttura dati x check condizione READY
|
||||
/// </summary>
|
||||
public diCheckCondSetup condReady { get; set; } = new diCheckCondSetup();
|
||||
|
||||
/// <summary>
|
||||
/// Struttura dati x check condizione Setup
|
||||
/// </summary>
|
||||
public diCheckCondSetup condSetup { get; set; } = new diCheckCondSetup();
|
||||
|
||||
/// <summary>
|
||||
/// Struttura dati x check condizione WarmUp - CoolDown
|
||||
/// </summary>
|
||||
public diCheckCondSetup condWarmUpCoolDown { get; set; } = new diCheckCondSetup();
|
||||
|
||||
/// <summary>
|
||||
/// Struttura dati x check condizione Warning
|
||||
/// </summary>
|
||||
public diCheckCondSetup condWarning { get; set; } = new diCheckCondSetup();
|
||||
|
||||
/// <summary>
|
||||
/// Struttura dati x check condizione Errore
|
||||
/// </summary>
|
||||
public diCheckCondSetup condWorkOpc { get; set; } = new diCheckCondSetup();
|
||||
|
||||
/// <summary>
|
||||
/// Elenco dei NodeId da ignorare intesi come interi rami (se vuoto NON filtro)
|
||||
/// </summary>
|
||||
public List<string> filterItemsNodeId { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Aree di memoria lettura
|
||||
/// </summary>
|
||||
public Dictionary<string, dataConfTSVC> mMapRead { get; set; } = new Dictionary<string, dataConfTSVC>();
|
||||
|
||||
/// <summary>
|
||||
/// Aree di memoria scrittura
|
||||
/// </summary>
|
||||
public Dictionary<string, dataConf> mMapWrite { get; set; } = new Dictionary<string, dataConf>();
|
||||
|
||||
/// <summary>
|
||||
/// Elenco item RAW sottoscritti e relative configurazioni di decodifica da byte[]
|
||||
/// </summary>
|
||||
public Dictionary<string, string> rawSubscribedItemsConf { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Conf gestione setup macchina
|
||||
/// </summary>
|
||||
public MachineSetupConf SetupConf { get; set; } = new MachineSetupConf();
|
||||
|
||||
/// <summary>
|
||||
/// Elenco dei SOLI item sottoscritti (se vuoto TUTTI)
|
||||
/// </summary>
|
||||
public List<string> subscribedItems { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Conf Gestione WatchDog
|
||||
/// </summary>
|
||||
public WatchDogConf WatchDog { get; set; } = new WatchDogConf();
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Classes
|
||||
|
||||
/// <summary>
|
||||
/// Classe gestione ITEM di un OBJ (machine) generico (read/write)
|
||||
/// </summary>
|
||||
public class objItem
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Ultimo messaggio associato (conferma scrittura, errore, ...)
|
||||
/// </summary>
|
||||
public string lastMessage { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// DataOra ultima lettura
|
||||
/// </summary>
|
||||
public DateTime lastRead { get; set; } = DateTime.Now.AddHours(-1);
|
||||
|
||||
/// <summary>
|
||||
/// DataOra ultima richiesta scrittura
|
||||
/// </summary>
|
||||
public DateTime lastRequest { get; set; } = DateTime.Now.AddDays(-1);
|
||||
|
||||
/// <summary>
|
||||
/// NOME item
|
||||
/// </summary>
|
||||
public string name { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Indica il NUOVO valore richiesto x l'item
|
||||
/// </summary>
|
||||
public string reqValue { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// UID univoco
|
||||
/// </summary>
|
||||
public string uid { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Unità Misura parametro
|
||||
/// </summary>
|
||||
public string UM { get; set; } = "#";
|
||||
|
||||
/// <summary>
|
||||
/// Valore MASSIMO (SE impostato)
|
||||
/// </summary>
|
||||
public int valMax { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Valore minimo (SE impostato)
|
||||
/// </summary>
|
||||
public int valMin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Valore parametro (come stringa, decimali con ",", default VUOTO), sul CNC/PLC
|
||||
/// </summary>
|
||||
public string value { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Indica se sia abilitato in scrittura (WRITE)
|
||||
/// </summary>
|
||||
public bool writable { get; set; } = false;
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
|
||||
#endregion Public Classes
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
using MP.MONO.Core.CONF;
|
||||
using MP.MONO.Core.DTO;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace MP.MONO.Core
|
||||
{
|
||||
public class ConfigManager
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
public ConfigManager(string redisConf, string confDirPath)
|
||||
{
|
||||
confPath = confDirPath;
|
||||
ConnectionMultiplexer.SetFeatureFlag("preventthreadtheft", true);
|
||||
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(redisConf);
|
||||
redisDb = redis.GetDatabase();
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Verifica se alarm log sia attivato (da DECODER; in REDIS)
|
||||
/// </summary>
|
||||
public bool AlarmLogActive
|
||||
{
|
||||
get
|
||||
{
|
||||
bool answ = false;
|
||||
string rawVal = redisDb.StringGet(Constants.ALARM_LOG_ENABLED);
|
||||
if (!string.IsNullOrEmpty(rawVal))
|
||||
{
|
||||
bool.TryParse(rawVal, out answ);
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
set => redisDb.StringSet(Constants.ALARM_LOG_ENABLED, $"{value}");
|
||||
}
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public List<DisplayDataDTO> getActLog(string fileName = "ActLog.json")
|
||||
{
|
||||
List<DisplayDataDTO>? currConf = null;
|
||||
string fullPath = Path.Combine(confPath, fileName);
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
currConf = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.ACTLOG_CONF_KEY, JsonConvert.SerializeObject(currConf));
|
||||
}
|
||||
}
|
||||
if (currConf == null)
|
||||
{
|
||||
currConf = new List<DisplayDataDTO>();
|
||||
}
|
||||
return currConf;
|
||||
}
|
||||
|
||||
public List<BaseAlarmBankConf> getAlarmsBankConf(string fileName = "AlarmBankList.json")
|
||||
{
|
||||
List<BaseAlarmBankConf>? currConf = null;
|
||||
// leggo e salvo conf stati
|
||||
string fullPath = Path.Combine(confPath, fileName);
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
currConf = JsonConvert.DeserializeObject<List<BaseAlarmBankConf>>(rawData);
|
||||
if (currConf != null)
|
||||
{
|
||||
// sistemo allarmi
|
||||
foreach (var item in currConf)
|
||||
{
|
||||
item.setupData();
|
||||
// loggo
|
||||
Log.Info($"Decodifica aree BankBit: {item.description} | {item.memAddr} x {item.size} byte | {item.messages.Count} messaggi allarme", true, true);
|
||||
}
|
||||
}
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.ALARMS_CONF_BBIT_KEY, JsonConvert.SerializeObject(currConf));
|
||||
}
|
||||
}
|
||||
if (currConf == null)
|
||||
{
|
||||
currConf = new List<BaseAlarmBankConf>();
|
||||
}
|
||||
return currConf;
|
||||
}
|
||||
|
||||
public List<DisplayDataDTO> getAlarmsConf(string fileName = "Alarms.json")
|
||||
{
|
||||
List<DisplayDataDTO>? currConf = null;
|
||||
string fullPath = Path.Combine(confPath, fileName);
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
currConf = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSet(Constants.ALARMS_ADAP_CONF_KEY, JsonConvert.SerializeObject(currConf));
|
||||
}
|
||||
}
|
||||
if (currConf == null)
|
||||
{
|
||||
currConf = new List<DisplayDataDTO>();
|
||||
}
|
||||
return currConf;
|
||||
}
|
||||
|
||||
public List<BaseAlarmRawConf> getAlarmsRawConf(string fileName = "AlarmRawList.json")
|
||||
{
|
||||
List<BaseAlarmRawConf>? currConf = null;
|
||||
// leggo e salvo conf stati
|
||||
string fullPath = Path.Combine(confPath, fileName);
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
currConf = JsonConvert.DeserializeObject<List<BaseAlarmRawConf>>(rawData);
|
||||
if (currConf != null)
|
||||
{
|
||||
// sistemo allarmi
|
||||
foreach (var item in currConf)
|
||||
{
|
||||
// loggo
|
||||
Log.Info($"Decodifica aree AlarmRaw | source: {item.source} | {item.messages.Count} messaggi allarme", true, true);
|
||||
}
|
||||
}
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.ALARMS_CONF_RLIST_KEY, JsonConvert.SerializeObject(currConf));
|
||||
}
|
||||
}
|
||||
if (currConf == null)
|
||||
{
|
||||
currConf = new List<BaseAlarmRawConf>();
|
||||
}
|
||||
return currConf;
|
||||
}
|
||||
|
||||
public List<DisplayDataDTO> getCountersConf(string fileName = "Counters.json")
|
||||
{
|
||||
List<DisplayDataDTO>? currConf = null;
|
||||
string fullPath = Path.Combine(confPath, fileName);
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
currConf = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.CNT_STATUS_CONF_KEY, JsonConvert.SerializeObject(currConf));
|
||||
}
|
||||
}
|
||||
if (currConf == null)
|
||||
{
|
||||
currConf = new List<DisplayDataDTO>();
|
||||
}
|
||||
return currConf;
|
||||
}
|
||||
|
||||
public List<MachineMode> getMachineModeConf(string fileName = "ModeList.json")
|
||||
{
|
||||
List<MachineMode>? currConf = null;
|
||||
// leggo e salvo conf stati
|
||||
string fullPath = Path.Combine(confPath, fileName);
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
currConf = JsonConvert.DeserializeObject<List<MachineMode>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.MODE_CONF_KEY, JsonConvert.SerializeObject(currConf));
|
||||
}
|
||||
}
|
||||
if (currConf == null)
|
||||
{
|
||||
currConf = new List<MachineMode>();
|
||||
}
|
||||
return currConf;
|
||||
}
|
||||
|
||||
public List<MachineStatus> getMachineStatusConf(string fileName = "StatusList.json")
|
||||
{
|
||||
List<MachineStatus>? currConf = null;
|
||||
// leggo e salvo conf stati
|
||||
string fullPath = Path.Combine(confPath, fileName);
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
currConf = JsonConvert.DeserializeObject<List<MachineStatus>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.DISPLSTATUS_CONF_KEY, JsonConvert.SerializeObject(currConf));
|
||||
}
|
||||
}
|
||||
if (currConf == null)
|
||||
{
|
||||
currConf = new List<MachineStatus>();
|
||||
}
|
||||
return currConf;
|
||||
}
|
||||
|
||||
public List<DisplayDataDTO> getMPStatusConf(string fileName = "MPStatus.json")
|
||||
{
|
||||
List<DisplayDataDTO>? currConf = null;
|
||||
string fullPath = Path.Combine(confPath, fileName);
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
currConf = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.MP_STATUS_CONF_KEY, JsonConvert.SerializeObject(currConf));
|
||||
}
|
||||
}
|
||||
if (currConf == null)
|
||||
{
|
||||
currConf = new List<DisplayDataDTO>();
|
||||
}
|
||||
return currConf;
|
||||
}
|
||||
|
||||
public List<MachineStatus> getPalletStatusConf(string fileName = "PalletStatusList.json")
|
||||
{
|
||||
List<MachineStatus>? currConf = null;
|
||||
// leggo e salvo conf stati
|
||||
string fullPath = Path.Combine(confPath, fileName);
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
currConf = JsonConvert.DeserializeObject<List<MachineStatus>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.PALLSTATUS_CONF_KEY, JsonConvert.SerializeObject(currConf));
|
||||
}
|
||||
}
|
||||
if (currConf == null)
|
||||
{
|
||||
currConf = new List<MachineStatus>();
|
||||
}
|
||||
return currConf;
|
||||
}
|
||||
|
||||
public List<DisplayDataDTO> getParamsConf(string fileName = "Parameters.json")
|
||||
{
|
||||
List<DisplayDataDTO>? currConf = null;
|
||||
// leggo e salvo conf stati
|
||||
string fullPath = Path.Combine(confPath, fileName);
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
currConf = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.PARAMS_CONF_KEY, JsonConvert.SerializeObject(currConf));
|
||||
}
|
||||
}
|
||||
if (currConf == null)
|
||||
{
|
||||
currConf = new List<DisplayDataDTO>();
|
||||
}
|
||||
return currConf;
|
||||
}
|
||||
|
||||
public List<DisplayDataDTO> getTools(string fileName = "Tools.json")
|
||||
{
|
||||
List<DisplayDataDTO>? currConf = null;
|
||||
string fullPath = Path.Combine(confPath, fileName);
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var rawData = File.ReadAllText(fullPath);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
currConf = JsonConvert.DeserializeObject<List<DisplayDataDTO>>(rawData);
|
||||
// salvo in redis!
|
||||
redisDb.StringSetAsync(Constants.TOOLS_CONF_KEY, JsonConvert.SerializeObject(currConf));
|
||||
}
|
||||
}
|
||||
if (currConf == null)
|
||||
{
|
||||
currConf = new List<DisplayDataDTO>();
|
||||
}
|
||||
return currConf;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected string confPath = "";
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
protected IDatabase redisDb { get; set; } = null!;
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
#endregion Private Fields
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ namespace MP.MONO.Core
|
||||
//// </Auto-Generated>
|
||||
public class Constants
|
||||
{
|
||||
|
||||
#region Public Fields
|
||||
|
||||
// dati conf REDIS Cache
|
||||
@@ -21,33 +20,81 @@ namespace MP.MONO.Core
|
||||
//public static readonly string BASE_PATH = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) ?? Directory.GetCurrentDirectory();
|
||||
|
||||
// Configurazioni
|
||||
public static readonly string STATUS_CONF_KEY = $"{BASE_HASH}:Conf:Status";
|
||||
public static readonly string ACTLOG_CONF_KEY = $"{BASE_HASH}:Conf:ActLog";
|
||||
public static readonly string ALARMS_CONF_KEY = $"{BASE_HASH}:Conf:Alarms";
|
||||
public static readonly string ALARM_LOG_ENABLED = $"{BASE_HASH}:Conf:AlarmLogEnabled";
|
||||
public static readonly string ALARMS_ADAP_CONF_KEY = $"{BASE_HASH}:Conf:AdapterAlarms";
|
||||
public static readonly string ALARMS_CONF_BBIT_KEY = $"{BASE_HASH}:Conf:AlarmsBankBit";
|
||||
public static readonly string ALARMS_CONF_RLIST_KEY = $"{BASE_HASH}:Conf:AlarmsRawList";
|
||||
public static readonly string MACHINE_CONF_PLATE = $"{BASE_HASH}:Conf:MachinePlate";
|
||||
public static readonly string ALARMS_MODE_KEY = $"{BASE_HASH}:Conf:AlarmMode";
|
||||
public static readonly string MODE_CONF_KEY = $"{BASE_HASH}:Conf:Mode";
|
||||
public static readonly string PARAMS_CONF_KEY = $"{BASE_HASH}:Conf:Params";
|
||||
public static readonly string DISPLSTATUS_CONF_KEY = $"{BASE_HASH}:Conf:Status";
|
||||
public static readonly string PALLSTATUS_CONF_KEY = $"{BASE_HASH}:Conf:PalletStatus";
|
||||
public static readonly string TOOLS_CONF_KEY = $"{BASE_HASH}:Conf:Tools";
|
||||
public static readonly string MP_STATUS_CONF_KEY = $"{BASE_HASH}:Conf:MacProcStatus";
|
||||
public static readonly string CNT_STATUS_CONF_KEY = $"{BASE_HASH}:Conf:CountStatus";
|
||||
|
||||
// Dati correnti
|
||||
// settings utente
|
||||
public static readonly string ALARMS_SETT_BBIT_KEY = $"{BASE_HASH}:Settings:AlarmsBankBit";
|
||||
public static readonly string ALARMS_SETT_MUTED_KEY = $"{BASE_HASH}:Settings:AlarmsMuted";
|
||||
public static readonly string ALARMS_SETT_RLIST_KEY = $"{BASE_HASH}:Settings:AlarmsRawList";
|
||||
|
||||
// REDIS KEY Dati correnti
|
||||
public static readonly string ACT_LOG_CURR_KEY = $"{BASE_HASH}:Current:ActivityLog";
|
||||
public static readonly string ALARM_ADAPTER_ACT_KEY = $"{BASE_HASH}:Current:AdapterAlarm";
|
||||
public static readonly string ALARM_ACT_KEY = $"{BASE_HASH}:Current:AlarmsVal";
|
||||
public static readonly string ALARM_BLINK_CURR_KEY = $"{BASE_HASH}:Current:AlarmsBlink";
|
||||
public static readonly string ALARM_CURR_KEY = $"{BASE_HASH}:Current:Alarms";
|
||||
public static readonly string ALARM_LOG_SAVED = $"{BASE_HASH}:Current:AlarmsLogSaved";
|
||||
public static readonly string ALARM_RECEIV_KEY = $"{BASE_HASH}:Current:AlarmsReceived";
|
||||
public static readonly string ALARM_PEND_KEY = $"{BASE_HASH}:Current:AlarmsPendingClose";
|
||||
public static readonly string EVENT_LOG_CURR_KEY = $"{BASE_HASH}:Current:EventsLog";
|
||||
public static readonly string MACH_DAY_DUR_CURR_KEY = $"{BASE_HASH}:Current:MachDayDur";
|
||||
public static readonly string MACH_STATS_CURR_KEY = $"{BASE_HASH}:Current:MachStats";
|
||||
public static readonly string MAINT_STATS_CURR_KEY = $"{BASE_HASH}:Current:Maintenance";
|
||||
public static readonly string PARAMS_CURR_KEY = $"{BASE_HASH}:Current:Parameters";
|
||||
public static readonly string PARAMS_ACT_KEY = $"{BASE_HASH}:Current:ParamsVal";
|
||||
public static readonly string PARAMS_CURR_KEY = $"{BASE_HASH}:Current:Params";
|
||||
public static readonly string PROD_CURR_KEY = $"{BASE_HASH}:Current:Production";
|
||||
public static readonly string STATUS_ACT_KEY = $"{BASE_HASH}:Current:StatusVal";
|
||||
public static readonly string STATUS_LAST_KEY = $"{BASE_HASH}:Current:StatusLastVal";
|
||||
public static readonly string STATUS_PARETO_KEY = $"{BASE_HASH}:Current:StatusPareto";
|
||||
public static readonly string STATUS_CURR_KEY = $"{BASE_HASH}:Current:Status";
|
||||
public static readonly string TOOLS_ACT_KEY = $"{BASE_HASH}:Current:ToolsVal";
|
||||
public static readonly string TOOLS_CURR_KEY = $"{BASE_HASH}:Current:Tools";
|
||||
public static readonly string COUNT_CURR_KEY = $"{BASE_HASH}:Current:Counters";
|
||||
|
||||
// Canali messaggi REDIS
|
||||
|
||||
// REDIS KEY Dati cache
|
||||
public static readonly string DATA_LOG_KEY = $"{BASE_HASH}:Cache:DataLog";
|
||||
public static readonly string DATA_LOG_DTO_KEY = $"{BASE_HASH}:Cache:DataLogDto";
|
||||
|
||||
// REDIS Channels messaggi (verso UI)
|
||||
public static readonly string ACT_LOG_M_QUEUE = $"ActivityLog";
|
||||
public static readonly string ALARM_ACT_VAL = $"AlarmsActVal";
|
||||
public static readonly string ALARM_M_QUEUE = $"Alarms";
|
||||
public static readonly string EVENT_LOG_M_QUEUE = $"EventsLog";
|
||||
public static readonly string EVENT_LOG_M_QUEUE = $"EventsLog";
|
||||
public static readonly string MACH_DAY_DUR_M_QUEUE = $"MachDayDur";
|
||||
public static readonly string MACH_STATS_M_QUEUE = $"MachStats";
|
||||
public static readonly string MAINT_STATS_M_QUEUE = $"Maintenance";
|
||||
public static readonly string PARAMS_M_QUEUE = $"Parameters";
|
||||
public static readonly string PARAMS_M_QUEUE = $"Params";
|
||||
public static readonly string PROD_M_QUEUE = $"Production";
|
||||
public static readonly string STATUS_M_QUEUE = $"Status";
|
||||
public static readonly string STATUS_PAR_QUEUE = $"StatusPareto";
|
||||
public static readonly string COUNT_M_QUEUE = $"Count";
|
||||
public static readonly string TOOLS_M_QUEUE = $"Tools";
|
||||
|
||||
// REDIS Channels messaggi (verso DECODER)
|
||||
public static readonly string ALARM_RAW_QUEUE = $"AlarmsRawVal";
|
||||
public static readonly string COUNT_RAW_QUEUE = $"CountRawVal";
|
||||
public static readonly string PARAMS_RAW_QUEUE = $"ParamsRawVal";
|
||||
public static readonly string STATUS_RAW_QUEUE = $"StatusRawVal";
|
||||
public static readonly string TOOLS_RAW_QUEUE = $"ToolsRawVal";
|
||||
|
||||
//REDIS caching keys
|
||||
public static readonly string ALARM_REC = $"{BASE_HASH}:Current:AlarmsRecVal";
|
||||
public static readonly string ALARM_LOG = $"{BASE_HASH}:Current:AlarmsLogVal";
|
||||
|
||||
|
||||
#endregion Public Fields
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
// <Auto-Generated>
|
||||
// This is here so CodeMaid doesn't reorganize this document
|
||||
// </Auto-Generated>
|
||||
namespace MP.MONO.Core.DTO
|
||||
{
|
||||
/// <summary>
|
||||
/// Array valori per analisi pareto
|
||||
/// </summary>
|
||||
public class AlarmStatsDTO
|
||||
{
|
||||
public string Code { get; set; } = "0000";
|
||||
public string Description { get; set; } = "";
|
||||
public int EventCount { get; set; } = 1;
|
||||
public double DurationTotal { get; set; } = 0;
|
||||
public double DurationAvg { get; set; } = 0;
|
||||
public double DurationMin { get; set; } = 0;
|
||||
public double DurationMax { get; set; } = 0;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static MP.MONO.Core.Enums;
|
||||
|
||||
// <Auto-Generated>
|
||||
// This is here so CodeMaid doesn't reorganize this document
|
||||
@@ -11,18 +12,81 @@ namespace MP.MONO.Core.DTO
|
||||
{
|
||||
public class DisplayDataDTO
|
||||
{
|
||||
/// <summary>
|
||||
/// Display Order
|
||||
/// </summary>
|
||||
public int Order { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// External code (for ref lookup)
|
||||
/// </summary>
|
||||
public string ExtCode { get; set; } = "";
|
||||
/// <summary>
|
||||
/// Data Type
|
||||
/// </summary>
|
||||
public string Type { get; set; } = "";
|
||||
/// <summary>
|
||||
/// Title/Name
|
||||
/// </summary>
|
||||
public string Title { get; set; } = "";
|
||||
/// <summary>
|
||||
/// Value (string format)
|
||||
/// </summary>
|
||||
public string Value { get; set; } = "";
|
||||
/// <summary>
|
||||
/// Value (number)
|
||||
/// </summary>
|
||||
public double ValueNum { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// Valore scala (da moltiplicare, > 1 aumenta, 0>x>1 riduce)
|
||||
/// </summary>
|
||||
public double ScaleFactor { get; set; } = 1;
|
||||
/// <summary>
|
||||
/// Display format
|
||||
/// </summary>
|
||||
public string DisplFormat { get; set; } = "N0";
|
||||
/// <summary>
|
||||
/// Min Value permitted
|
||||
/// </summary>
|
||||
public double MinVal { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// Max Value permitted
|
||||
/// </summary>
|
||||
public double MaxVal { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// Define if is numeric
|
||||
/// </summary>
|
||||
public bool IsNumeric { get; set; } = false;
|
||||
/// <summary>
|
||||
/// Enabled for plotting
|
||||
/// </summary>
|
||||
public bool EnablePlot { get; set; } = true;
|
||||
/// <summary>
|
||||
/// Enable percent BAR display
|
||||
/// </summary>
|
||||
public bool ShowBar { get; set; } = false;
|
||||
/// <summary>
|
||||
/// Enable GAUGE display
|
||||
/// </summary>
|
||||
public bool ShowGauge { get; set; } = false;
|
||||
/// <summary>
|
||||
/// Enable display on Homepage List
|
||||
/// </summary>
|
||||
public bool HLShow{ get; set; } = false;
|
||||
/// <summary>
|
||||
/// CSS Icon (ex: Fontawesome 6)
|
||||
/// </summary>
|
||||
public string CssIcon { get; set; } = "";
|
||||
/// <summary>
|
||||
/// CSS Style
|
||||
/// </summary>
|
||||
public string CssClass { get; set; } = "";
|
||||
/// <summary>
|
||||
/// Sample period for DB recording of min/Avg/MAX data (seconds)
|
||||
/// </summary>
|
||||
public double SamplePeriod { get; set; } = 60 * 3;
|
||||
/// <summary>
|
||||
/// Tipo di trasformazione VC da applicare ai dati al momento del raggiungimento del periodo di acquisizione
|
||||
/// </summary>
|
||||
public VC_func VcFunc { get; set; } = VC_func.POINT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
namespace MP.MONO.Core.DTO
|
||||
{
|
||||
public class RangeDTO
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Descrizione parametro
|
||||
/// </summary>
|
||||
public string Description { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Parametro in uscita previsto
|
||||
/// </summary>
|
||||
public double OutVal { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Valore massimo range
|
||||
/// </summary>
|
||||
public double maxVal { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Valore minimo range
|
||||
/// </summary>
|
||||
public double minVal { get; set; } = 0;
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
}
|
||||
+192
-5
@@ -4,6 +4,65 @@
|
||||
{
|
||||
#region Public Enums
|
||||
|
||||
/// <summary>
|
||||
/// Modalità verifica condizioni booleane
|
||||
/// </summary>
|
||||
public enum boolCheckMode
|
||||
{
|
||||
/// <summary>
|
||||
/// AND: tutte vere -> true
|
||||
/// </summary>
|
||||
AND = 0,
|
||||
|
||||
/// <summary>
|
||||
/// OR: almeno una vera
|
||||
/// </summary>
|
||||
OR
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tipo di dati salvato in DataLog
|
||||
/// </summary>
|
||||
public enum DataLogType
|
||||
{
|
||||
ND = 0,
|
||||
Parameter = 1,
|
||||
Tools
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Categoria dataItem
|
||||
/// </summary>
|
||||
public enum DataItemCategory
|
||||
{
|
||||
CONDITION = 0,
|
||||
EVENT = 1,
|
||||
SAMPLE = 2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modalità pubblicazione allarmi da ADAPTER
|
||||
/// </summary>
|
||||
public enum AlarmReportingMode
|
||||
{
|
||||
ND = 0,
|
||||
|
||||
/// <summary>
|
||||
/// MOdalità report per bank di memoria + bitmap degli allarmi attivi nel bank
|
||||
/// </summary>
|
||||
BankBit,
|
||||
|
||||
/// <summary>
|
||||
/// Modalità di invio di un elenco di allarmi attivi in un dato istante
|
||||
/// </summary>
|
||||
RawList,
|
||||
|
||||
/// <summary>
|
||||
/// Modalità di invio di un elenco di allarmi attivi in un dato istante con BLINK ogni 10 sec (come amcchina multiax)
|
||||
/// </summary>
|
||||
RawListBlink
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ENUM degli stati (es path OPC-UA)
|
||||
/// </summary>
|
||||
@@ -19,6 +78,17 @@
|
||||
DONE
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modalità gestione setup macchina
|
||||
/// </summary>
|
||||
public enum MachineSetupMode
|
||||
{
|
||||
ND = 0,
|
||||
|
||||
// Modalità come Mecolpress (se variato stato --> porto a 1 la variabile di controllo)
|
||||
BitHighOnSetup = 1
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ENUM dei MODE (es path OPC-UA)
|
||||
/// </summary>
|
||||
@@ -72,6 +142,83 @@
|
||||
String
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco task ammessi (x IOB-WIN da eseguire...)
|
||||
/// </summary>
|
||||
public enum taskType
|
||||
{
|
||||
/// <summary>
|
||||
/// Task nullo / fake
|
||||
/// </summary>
|
||||
nihil,
|
||||
|
||||
/// <summary>
|
||||
/// Rimanda a PLC eventuale segnale NON in setup (MA NON RESETTA)
|
||||
/// </summary>
|
||||
fixStopSetup,
|
||||
|
||||
/// <summary>
|
||||
/// Indica al PLC di forzare il reset del contapezzi
|
||||
/// </summary>
|
||||
forceResetPzCount,
|
||||
|
||||
/// <summary>
|
||||
/// Indica al PLC di forzare il NUOVO valore di contapezzi (impostato come value)
|
||||
/// </summary>
|
||||
forceSetPzCount,
|
||||
|
||||
/// <summary>
|
||||
/// Imposta Articolo su PLC
|
||||
/// </summary>
|
||||
setArt,
|
||||
|
||||
/// <summary>
|
||||
/// Imposta Commessa su PLC
|
||||
/// </summary>
|
||||
setComm,
|
||||
|
||||
/// <summary>
|
||||
/// Set di un PARAMETRO su PLC (in value avremo un JSON object)
|
||||
/// </summary>
|
||||
setParameter,
|
||||
|
||||
/// <summary>
|
||||
/// Set Programma CNC su PLC
|
||||
/// </summary>
|
||||
setProg,
|
||||
|
||||
/// <summary>
|
||||
/// Indica al PLC di impostare il numero di pezzi da produrre per la commessa (impostato
|
||||
/// come value)
|
||||
/// </summary>
|
||||
setPzComm,
|
||||
|
||||
/// <summary>
|
||||
/// Indica al PLC iniziato setup (e secondo casi ferma contapezzi /resetta)
|
||||
/// </summary>
|
||||
startSetup,
|
||||
|
||||
/// <summary>
|
||||
/// Indica al PLC finito setup (e secondo casi ferma contapezzi /resetta)
|
||||
/// </summary>
|
||||
stopSetup,
|
||||
|
||||
/// <summary>
|
||||
/// Richiesta invio watchdog a PLC
|
||||
/// </summary>
|
||||
sendWatchDogMes2Plc,
|
||||
|
||||
/// <summary>
|
||||
/// Indica che è FINITA la produzione (e quindi cancello dati backup)
|
||||
/// </summary>
|
||||
endProd,
|
||||
|
||||
/// <summary>
|
||||
/// Richiesta esecuzione di un sync dei dati DB di frontiera
|
||||
/// </summary>
|
||||
syncDbData
|
||||
}
|
||||
|
||||
#if false
|
||||
/// <summary>
|
||||
/// Elenco task ammessi (x IOB-WIN da eseguire...)
|
||||
@@ -119,7 +266,8 @@
|
||||
setProg,
|
||||
|
||||
/// <summary>
|
||||
/// Indica al PLC di impostare il numero di pezzi da produrre per la commessa (impostato come value)
|
||||
/// Indica al PLC di impostare il numero di pezzi da produrre per la commessa (impostato
|
||||
/// come value)
|
||||
/// </summary>
|
||||
setPzComm,
|
||||
|
||||
@@ -145,6 +293,45 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
#if false
|
||||
/// <summary>
|
||||
/// Tipologia di driverer x il calcolo scadenza task di Preventive Maintenance
|
||||
/// </summary>
|
||||
public enum PMTaskDriver
|
||||
{
|
||||
ND = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Cronologico puro (data poi periodo temporale)
|
||||
/// </summary>
|
||||
TimeOnly = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Basato su valore di soglia un counter rilevato
|
||||
/// </summary>
|
||||
CountLevel = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Basato su un evento specifico (valore esatto di un counter)
|
||||
/// </summary>
|
||||
Event = 3
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Intervallo temporale x schedulazioni
|
||||
/// </summary>
|
||||
public enum PMTimeInterval
|
||||
{
|
||||
ND = 0,
|
||||
Minute = 1,
|
||||
Hour = 2,
|
||||
Day = 3,
|
||||
Week = 4,
|
||||
Month = 5,
|
||||
Year = 6
|
||||
}
|
||||
#endif
|
||||
|
||||
public enum UserLevel
|
||||
{
|
||||
ND = 0,
|
||||
@@ -170,9 +357,9 @@
|
||||
AVG,
|
||||
|
||||
/// <summary>
|
||||
/// Valore massimo del periodo
|
||||
/// Calcolo MEDIANA
|
||||
/// </summary>
|
||||
MAX,
|
||||
MEDIAN,
|
||||
|
||||
/// <summary>
|
||||
/// Valore minimo del periodo
|
||||
@@ -180,9 +367,9 @@
|
||||
MIN,
|
||||
|
||||
/// <summary>
|
||||
/// Calcolo MEDIANA
|
||||
/// Valore massimo del periodo
|
||||
/// </summary>
|
||||
MEDIAN
|
||||
MAX
|
||||
}
|
||||
|
||||
#endregion Public Enums
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// This file is used by Code Analysis to maintain SuppressMessage
|
||||
// attributes that are applied to this project.
|
||||
// Project-level suppressions either have no target or are given
|
||||
// a specific target and scoped to a namespace, type, member, etc.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>", Scope = "member", Target = "~M:MP.MONO.Core.MachineInfo.GetBiosInfo~System.Threading.Tasks.Task{System.Collections.Generic.Dictionary{System.String,System.String}}")]
|
||||
[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>", Scope = "member", Target = "~M:MP.MONO.Core.MachineInfo.searchWmiParam(System.Collections.Generic.Dictionary{System.String,System.String},System.Management.ManagementObject,System.String,System.String)")]
|
||||
[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>", Scope = "member", Target = "~M:MP.MONO.Core.MachineInfo.GetCpuInfo~System.Threading.Tasks.Task{System.Collections.Generic.Dictionary{System.String,System.String}}")]
|
||||
[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>", Scope = "member", Target = "~M:MP.MONO.Core.MachineInfo.GetNetInfo~System.Threading.Tasks.Task{System.Collections.Generic.Dictionary{System.String,System.String}}")]
|
||||
[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>", Scope = "member", Target = "~M:MP.MONO.Core.MachineInfo.GetOsInfo~System.Threading.Tasks.Task{System.Collections.Generic.Dictionary{System.String,System.String}}")]
|
||||
[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>", Scope = "member", Target = "~M:MP.MONO.Core.MachineInfo.GetRamInfo~System.Threading.Tasks.Task{System.Collections.Generic.Dictionary{System.String,System.String}}")]
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
@@ -9,7 +9,11 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MathNet.Numerics" Version="4.15.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="NLog" Version="5.2.3" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.6.122" />
|
||||
<PackageReference Include="System.Collections" Version="4.3.0" />
|
||||
<PackageReference Include="System.Management" Version="6.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace MP.MONO.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Classe validazione valori
|
||||
/// </summary>
|
||||
public class MachineDataValidator
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Init classe validatore
|
||||
/// </summary>
|
||||
/// <param name="currMachineData"></param>
|
||||
public MachineDataValidator()
|
||||
{
|
||||
// inizializzo info di base
|
||||
if (machTestData == null || machTestData.Count == 0)
|
||||
{
|
||||
machTestData = setupData().Result;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Restituisce HASH del codice impiego = payload utente
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string macHash
|
||||
{
|
||||
get => calcMachineHash();
|
||||
}
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
#if false
|
||||
/// <summary>
|
||||
/// Verifica validità info correnti
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> testCurrInfo()
|
||||
{
|
||||
return await testInfo();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Verifica validità info correnti
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static async Task<bool> testCurrInfo()
|
||||
{
|
||||
var cDV = new MachineDataValidator();
|
||||
return await cDV.testInfo();
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
/// <summary>
|
||||
/// Dati rispetto cui fare i calcoli di validazione
|
||||
/// </summary>
|
||||
private static Dictionary<string, string> machTestData = new Dictionary<string, string>();
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Calcola HASH del codice impiego = payload utente
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private string calcMachineHash()
|
||||
{
|
||||
string hash = "";
|
||||
string buffData = currBaseBuffer();
|
||||
if (!string.IsNullOrEmpty(buffData))
|
||||
{
|
||||
// hashing!
|
||||
|
||||
using (var hAlgo = SHA512.Create())
|
||||
//using (var hAlgo = MD5.Create())
|
||||
{
|
||||
byte[] InputBytes = Encoding.UTF8.GetBytes(buffData);
|
||||
var byteHash = hAlgo.ComputeHash(InputBytes);
|
||||
hash = BitConverter.ToString(byteHash).Replace("-", "").Replace("/", "").Replace("\\", "").ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calcola hash key da info PC
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private string currBaseBuffer()
|
||||
{
|
||||
string answ = "????????????????????????????????????????????";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try
|
||||
{
|
||||
// calcolo hashKey da alcuni valori solamente
|
||||
sb.Append($"{machTestData["SystemName"]}|");
|
||||
sb.Append($"{machTestData["ProcessorId"]}|");
|
||||
sb.Append($"{machTestData["PartNumber"]}|");
|
||||
sb.Append($"{machTestData["MACAddress"]}|");
|
||||
sb.Append($"{machTestData["SerialNumber"]}|");
|
||||
sb.Append($"{machTestData["OSArchitecture"]}|");
|
||||
sb.Append($"{machTestData["SoftwareElementID"]}|");
|
||||
sb.Append($"{machTestData["SystemBiosMajorVersion"]}|");
|
||||
sb.Append($"{machTestData["SystemBiosMinorVersion"]}|");
|
||||
sb.Append($"{machTestData["CpuVersion"]}|");
|
||||
sb.Append($"{machTestData["BiosVersion"]}|");
|
||||
if (sb.Length > 0)
|
||||
{
|
||||
answ = sb.ToString();
|
||||
// lo uso 2 volte dritto e reverse...
|
||||
answ += ReverseString(sb.ToString());
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esegue reverse delal stringa
|
||||
/// </summary>
|
||||
/// <param name="myStr"></param>
|
||||
/// <returns></returns>
|
||||
private string ReverseString(string myStr)
|
||||
{
|
||||
char[] myArr = myStr.ToCharArray();
|
||||
Array.Reverse(myArr);
|
||||
return new string(myArr);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Legge la hash key dal file licenza salvato
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private async Task<string> getSavedHash()
|
||||
{
|
||||
string answ = "############################################################";
|
||||
string filePath = "Conf/lic.file";
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
answ = await File.ReadAllTextAsync(filePath);
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
public static Dictionary<string, string> biosInfo = new Dictionary<string, string>();
|
||||
public static Dictionary<string, string> cpuInfo = new Dictionary<string, string>();
|
||||
public static Dictionary<string, string> netInfo = new Dictionary<string, string>();
|
||||
public static Dictionary<string, string> osInfo = new Dictionary<string, string>();
|
||||
public static Dictionary<string, string> ramInfo = new Dictionary<string, string>();
|
||||
public static Dictionary<string, string> volInfo = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Predispone elenco dati di test
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task<Dictionary<string, string>> setupData()
|
||||
{
|
||||
// creo un unico array di info
|
||||
Dictionary<string, string> testData = new Dictionary<string, string>();
|
||||
biosInfo = await MachineInfo.GetInfo("BIOS");
|
||||
cpuInfo = await MachineInfo.GetInfo("CPU");
|
||||
netInfo = await MachineInfo.GetInfo("NET");
|
||||
osInfo = await MachineInfo.GetInfo("OS");
|
||||
ramInfo = await MachineInfo.GetInfo("RAM");
|
||||
volInfo = await MachineInfo.GetInfo("VOL");
|
||||
testData = biosInfo.Concat(cpuInfo).Concat(netInfo).Concat(osInfo).Concat(ramInfo).GroupBy(ele => ele.Key).ToDictionary(ele => ele.Key, ele => ele.First().Value);
|
||||
return testData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua verifica putuale tra hash Key fornita ed hash key calcolata da info PC
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task<bool> testInfo()
|
||||
{
|
||||
// recupero hash key da conf applicativo (licenza)
|
||||
string fileHash = await getSavedHash();
|
||||
/// recupero hash calcolata
|
||||
string calcHash = calcMachineHash();
|
||||
// confronto con hashKey calcolata da info PC + dati...
|
||||
return fileHash.Equals(calcHash);
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
using NLog;
|
||||
using System.Management;
|
||||
|
||||
namespace MP.MONO.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Gestione info macchina
|
||||
/// </summary>
|
||||
public class MachineInfo
|
||||
{
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Restitusice info richieste
|
||||
/// </summary>
|
||||
/// <param name="infoType"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task<Dictionary<string, string>> GetInfo(string infoType)
|
||||
{
|
||||
var outInfo = new Dictionary<string, string>();
|
||||
switch (infoType)
|
||||
{
|
||||
case "BIOS":
|
||||
outInfo = await GetBiosInfo();
|
||||
break;
|
||||
|
||||
case "CPU":
|
||||
outInfo = await GetCpuInfo();
|
||||
break;
|
||||
|
||||
case "NET":
|
||||
outInfo = await GetNetInfo();
|
||||
break;
|
||||
|
||||
case "OS":
|
||||
outInfo = await GetOsInfo();
|
||||
break;
|
||||
|
||||
case "RAM":
|
||||
outInfo = await GetRamInfo();
|
||||
break;
|
||||
|
||||
case "VOL":
|
||||
outInfo = await GetVolumeInfo();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return outInfo;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Info BIOS
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static async Task<Dictionary<string, string>> GetBiosInfo()
|
||||
{
|
||||
ManagementObjectCollection moc;
|
||||
Dictionary<string, string> DictParam = new Dictionary<string, string>();
|
||||
|
||||
try
|
||||
{
|
||||
moc = new ManagementObjectSearcher("select * from Win32_BIOS").Get();
|
||||
}
|
||||
catch
|
||||
{
|
||||
Log.Error("Error: WMI API Not loaded.");
|
||||
return DictParam;
|
||||
}
|
||||
|
||||
foreach (ManagementObject obj in moc)
|
||||
{
|
||||
searchWmiParam(DictParam, obj, "Manufacturer", "Manufacturer");
|
||||
searchWmiParam(DictParam, obj, "ReleaseDate", "ReleaseDate");
|
||||
searchWmiParam(DictParam, obj, "SMBIOSBIOSVersion", "SMBIOSBIOSVersion");
|
||||
searchWmiParam(DictParam, obj, "SMBIOSMajorVersion", "SMBIOSMajorVersion");
|
||||
searchWmiParam(DictParam, obj, "SMBIOSMinorVersion", "SMBIOSMinorVersion");
|
||||
searchWmiParam(DictParam, obj, "SoftwareElementID", "SoftwareElementID");
|
||||
searchWmiParam(DictParam, obj, "SoftwareElementState", "SoftwareElementState");
|
||||
searchWmiParam(DictParam, obj, "SystemBiosMajorVersion", "SystemBiosMajorVersion");
|
||||
searchWmiParam(DictParam, obj, "SystemBiosMajorVersion", "SystemBiosMajorVersion");
|
||||
searchWmiParam(DictParam, obj, "SystemBiosMinorVersion", "SystemBiosMinorVersion");
|
||||
searchWmiParam(DictParam, obj, "BiosVersion", "Version");
|
||||
}
|
||||
await Task.Delay(1);
|
||||
return DictParam;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Info processore
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static async Task<Dictionary<string, string>> GetCpuInfo()
|
||||
{
|
||||
ManagementObjectCollection moc;
|
||||
Dictionary<string, string> DictParam = new Dictionary<string, string>();
|
||||
|
||||
try
|
||||
{
|
||||
moc = new ManagementObjectSearcher("select * from Win32_Processor").Get();
|
||||
}
|
||||
catch
|
||||
{
|
||||
Log.Error("Error: WMI API Not loaded.");
|
||||
return DictParam;
|
||||
}
|
||||
|
||||
foreach (ManagementObject obj in moc)
|
||||
{
|
||||
searchWmiParam(DictParam, obj, "AddressWidth", "AddressWidth");
|
||||
searchWmiParam(DictParam, obj, "Architecture", "Architecture");
|
||||
searchWmiParam(DictParam, obj, "CurrentClockSpeed", "CurrentClockSpeed");
|
||||
searchWmiParam(DictParam, obj, "CurrentVoltage", "CurrentVoltage");
|
||||
searchWmiParam(DictParam, obj, "DataWidth", "DataWidth");
|
||||
searchWmiParam(DictParam, obj, "Description", "Description");
|
||||
searchWmiParam(DictParam, obj, "ExtClock", "ExtClock");
|
||||
searchWmiParam(DictParam, obj, "Family", "Family");
|
||||
searchWmiParam(DictParam, obj, "L2CacheSize", "L2CacheSize");
|
||||
searchWmiParam(DictParam, obj, "L3CacheSize", "L3CacheSize");
|
||||
searchWmiParam(DictParam, obj, "Level", "Level");
|
||||
searchWmiParam(DictParam, obj, "LoadPercentage", "LoadPercentage");
|
||||
searchWmiParam(DictParam, obj, "Manufacturer", "Manufacturer");
|
||||
searchWmiParam(DictParam, obj, "NumberOfCores", "NumberOfCores");
|
||||
searchWmiParam(DictParam, obj, "NumberOfLogicalProcessors", "NumberOfLogicalProcessors");
|
||||
searchWmiParam(DictParam, obj, "ProcessorId", "ProcessorId");
|
||||
searchWmiParam(DictParam, obj, "ProcessorType", "ProcessorType");
|
||||
searchWmiParam(DictParam, obj, "Revision", "Revision");
|
||||
searchWmiParam(DictParam, obj, "Role", "Role");
|
||||
searchWmiParam(DictParam, obj, "SocketDesignation", "SocketDesignation");
|
||||
searchWmiParam(DictParam, obj, "SystemName", "SystemName");
|
||||
searchWmiParam(DictParam, obj, "CpuVersion", "Version");
|
||||
}
|
||||
await Task.Delay(1);
|
||||
return DictParam;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Info Networking
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static async Task<Dictionary<string, string>> GetNetInfo()
|
||||
{
|
||||
ManagementObjectCollection moc;
|
||||
Dictionary<string, string> DictParam = new Dictionary<string, string>();
|
||||
|
||||
try
|
||||
{
|
||||
moc = new ManagementObjectSearcher("select * from Win32_NetworkAdapter WHERE NetEnabled = 'true'").Get();
|
||||
}
|
||||
catch
|
||||
{
|
||||
Log.Error("Error: WMI API Not loaded.");
|
||||
return DictParam;
|
||||
}
|
||||
|
||||
foreach (ManagementObject obj in moc)
|
||||
{
|
||||
searchWmiParam(DictParam, obj, "AdapterType", "AdapterType");
|
||||
searchWmiParam(DictParam, obj, "Description", "Description");
|
||||
searchWmiParam(DictParam, obj, "GUID", "GUID");
|
||||
searchWmiParam(DictParam, obj, "MACAddress", "MACAddress");
|
||||
searchWmiParam(DictParam, obj, "Manufacturer", "Manufacturer");
|
||||
searchWmiParam(DictParam, obj, "Name", "Name");
|
||||
searchWmiParam(DictParam, obj, "SystemName", "SystemName");
|
||||
searchWmiParam(DictParam, obj, "PhysicalAdapter", "PhysicalAdapter");
|
||||
searchWmiParam(DictParam, obj, "ProductName", "ProductName");
|
||||
searchWmiParam(DictParam, obj, "ServiceName", "ServiceName");
|
||||
}
|
||||
await Task.Delay(1);
|
||||
return DictParam;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Info OS
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static async Task<Dictionary<string, string>> GetOsInfo()
|
||||
{
|
||||
ManagementObjectCollection moc;
|
||||
Dictionary<string, string> DictParam = new Dictionary<string, string>();
|
||||
|
||||
try
|
||||
{
|
||||
moc = new ManagementObjectSearcher("select * from Win32_OperatingSystem").Get();
|
||||
}
|
||||
catch
|
||||
{
|
||||
Log.Error("Error: WMI API Not loaded.");
|
||||
return DictParam;
|
||||
}
|
||||
|
||||
foreach (ManagementObject obj in moc)
|
||||
{
|
||||
searchWmiParam(DictParam, obj, "Caption", "Caption");
|
||||
searchWmiParam(DictParam, obj, "Version", "Version");
|
||||
searchWmiParam(DictParam, obj, "MaxNumberOfProcesses", "MaxNumberOfProcesses");
|
||||
searchWmiParam(DictParam, obj, "MaxProcessMemorySize", "MaxProcessMemorySize");
|
||||
searchWmiParam(DictParam, obj, "OSArchitecture", "OSArchitecture");
|
||||
searchWmiParam(DictParam, obj, "SerialNumber", "SerialNumber");
|
||||
searchWmiParam(DictParam, obj, "BuildNumber", "BuildNumber");
|
||||
searchWmiParam(DictParam, obj, "RegisteredUser", "RegisteredUser");
|
||||
}
|
||||
await Task.Delay(1);
|
||||
return DictParam;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Info RAM
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static async Task<Dictionary<string, string>> GetRamInfo()
|
||||
{
|
||||
ManagementObjectCollection moc;
|
||||
Dictionary<string, string> DictParam = new Dictionary<string, string>();
|
||||
|
||||
try
|
||||
{
|
||||
moc = new ManagementObjectSearcher("select * from Win32_PhysicalMemory").Get();
|
||||
}
|
||||
catch
|
||||
{
|
||||
Log.Error("Error: WMI API Not loaded.");
|
||||
return DictParam;
|
||||
}
|
||||
|
||||
foreach (ManagementObject obj in moc)
|
||||
{
|
||||
searchWmiParam(DictParam, obj, "DeviceLocator", "DeviceLocator");
|
||||
searchWmiParam(DictParam, obj, "DataWidth", "DataWidth");
|
||||
searchWmiParam(DictParam, obj, "ConfiguredVoltage", "ConfiguredVoltage");
|
||||
searchWmiParam(DictParam, obj, "FormFactor", "FormFactor");
|
||||
searchWmiParam(DictParam, obj, "ConfiguredClockSpeed", "ConfiguredClockSpeed");
|
||||
searchWmiParam(DictParam, obj, "MaxVoltage", "MaxVoltage");
|
||||
searchWmiParam(DictParam, obj, "MinVoltage", "MinVoltage");
|
||||
searchWmiParam(DictParam, obj, "Speed", "Speed");
|
||||
searchWmiParam(DictParam, obj, "SMBIOSMemoryType", "SMBIOSMemoryType");
|
||||
searchWmiParam(DictParam, obj, "PartNumber", "PartNumber");
|
||||
}
|
||||
await Task.Delay(1);
|
||||
return DictParam;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Info Volumes (HDD/SSD)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static async Task<Dictionary<string, string>> GetVolumeInfo()
|
||||
{
|
||||
ManagementObjectCollection moc;
|
||||
Dictionary<string, string> DictParam = new Dictionary<string, string>();
|
||||
|
||||
try
|
||||
{
|
||||
moc = new ManagementObjectSearcher("select DriveLetter, DeviceID from Win32_Volume").Get();
|
||||
}
|
||||
catch
|
||||
{
|
||||
Log.Error("Error: WMI API Not loaded.");
|
||||
return DictParam;
|
||||
}
|
||||
|
||||
foreach (ManagementObject obj in moc)
|
||||
{
|
||||
// mi limito al disco "C:"
|
||||
string sDrive = "DriveLetter";
|
||||
var objVal = $"{obj[sDrive]}";
|
||||
if (objVal == "C:")
|
||||
{
|
||||
searchWmiParam(DictParam, obj, "DeviceID", "DeviceID");
|
||||
searchWmiParam(DictParam, obj, "DriveLetter", "DriveLetter");
|
||||
}
|
||||
}
|
||||
await Task.Delay(1);
|
||||
return DictParam;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua estrazione parametri WMI da elenco recuperato
|
||||
/// </summary>
|
||||
/// <param name="Processor"></param>
|
||||
/// <param name="obj"></param>
|
||||
/// <param name="pName"></param>
|
||||
/// <param name="pKey"></param>
|
||||
private static void searchWmiParam(Dictionary<string, string> Processor, ManagementObject obj, string pName, string pKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
var objVal = $"{obj[pKey]}";
|
||||
string strVal = objVal != null ? objVal : "";
|
||||
Processor.Add(pName, strVal);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MP.MONO.Core
|
||||
{
|
||||
public class TimeUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Effettua trim di una data al numero di minuti indicato
|
||||
///
|
||||
/// vedere qui:
|
||||
/// https://stackoverflow.com/questions/1393696/rounding-datetime-objects
|
||||
/// </summary>
|
||||
/// <param name="DateOrig">DataOra originale</param>
|
||||
/// <param name="roundMin">Minuti di arrotondamento richeisti</param>
|
||||
/// <param name="isFloor">Arrotondamento x difetto (floor = true) o eccesso (false)</param>
|
||||
/// <returns></returns>
|
||||
public static DateTime DateRounded(DateTime DateOrig, int roundMin, bool isFloor)
|
||||
{
|
||||
long ticks = 0;
|
||||
roundMin = roundMin <= 0 ? 1 : roundMin;
|
||||
TimeOnly step = new TimeOnly(0, roundMin);
|
||||
if (isFloor)
|
||||
{
|
||||
ticks = DateOrig.Ticks / step.Ticks;
|
||||
}
|
||||
else
|
||||
{
|
||||
ticks = (DateOrig.Ticks + step.Ticks - 1) / step.Ticks;
|
||||
}
|
||||
DateTime answ = new DateTime(ticks * step.Ticks, DateOrig.Kind);
|
||||
return answ;
|
||||
}
|
||||
/// <summary>
|
||||
/// Effettua arrotondamento di un timespan ad un dato step di minuti
|
||||
///
|
||||
/// vedere qui:
|
||||
/// https://stackoverflow.com/questions/1393696/rounding-datetime-objects
|
||||
/// </summary>
|
||||
/// <param name="DateOrig">DataOra originale</param>
|
||||
/// <param name="roundMin">Minuti di arrotondamento richeisti</param>
|
||||
/// <param name="isFloor">Arrotondamento x difetto (floor = true) o eccesso (false)</param>
|
||||
/// <returns></returns>
|
||||
public static TimeSpan TSpanRounded(TimeSpan TSpanOrig, int roundMin, bool isFloor)
|
||||
{
|
||||
long ticks = 0;
|
||||
roundMin = roundMin <= 0 ? 1 : roundMin;
|
||||
TimeOnly step = new TimeOnly(0, roundMin);
|
||||
if (isFloor)
|
||||
{
|
||||
ticks = TSpanOrig.Ticks / step.Ticks;
|
||||
}
|
||||
else
|
||||
{
|
||||
ticks = (TSpanOrig.Ticks + step.Ticks - 1) / step.Ticks;
|
||||
}
|
||||
TimeSpan answ = new TimeSpan(ticks * step.Ticks);
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua arrotondamento di un timespan ad un dato step di minuti
|
||||
///
|
||||
/// vedere qui:
|
||||
/// https://stackoverflow.com/questions/1393696/rounding-datetime-objects
|
||||
/// </summary>
|
||||
/// <param name="DateOrig">DataOra originale</param>
|
||||
/// <param name="roundMin">Minuti di arrotondamento richeisti</param>
|
||||
/// <returns></returns>
|
||||
public static TimeSpan TSpanRounded(TimeSpan TSpanOrig, int roundMin)
|
||||
{
|
||||
long ticks = 0;
|
||||
roundMin = roundMin <= 0 ? 1 : roundMin;
|
||||
TimeOnly step = new TimeOnly(0, roundMin);
|
||||
ticks = (TSpanOrig.Ticks + step.Ticks / 2) / step.Ticks;
|
||||
TimeSpan answ = new TimeSpan(ticks * step.Ticks);
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user