633 Commits

Author SHA1 Message Date
Samuele Locatelli 39609693a8 Aggiunte altre info pagina hw (predisposto x includere liberire classi base x gestione) 2024-09-25 11:55:17 +02:00
Samuele Locatelli 774cc5951a Merge tag 'AddRetryMysql' into develop
Aggiunto retry DB MySql x errori + fix conf gestione dietro lb.ufficio x
DB
2024-04-15 19:35:38 +02:00
Samuele Locatelli 4ce79a88c3 Merge branch 'release/AddRetryMysql' 2024-04-15 19:35:11 +02:00
Samuele Locatelli d1dc1436bb Refresh generale 2024-04-15 19:34:39 +02:00
Samuele Locatelli 3f889940b9 Aggiunta opzione x riprovare chiamata in caso di errore connessione x 10 sec 2024-04-15 19:34:36 +02:00
Samuele Locatelli 257ad739df Update puntamento DB su lb ufficio 2024-04-15 19:34:17 +02:00
Samuele Locatelli badd6d16f7 Update x pulizia (ulteriore) file log x decoder 2024-04-15 11:16:50 +02:00
Samuele Locatelli 7d84defb68 Fix config x DB Cluster in ufficio 2024-04-12 16:21:27 +02:00
Samuele Locatelli dd212d5c1b Merge tag 'AddSentinelLocalhost' into develop
Aggiunto sentinel su localhost
2024-03-16 12:06:55 +01:00
Samuele Locatelli 3b62b84bc2 Merge branch 'release/AddSentinelLocalhost' 2024-03-16 12:06:46 +01:00
Samuele Locatelli cc74087ba0 Fix UI x usare redis sentinel da localhost 2024-03-16 12:06:14 +01:00
Samuele Locatelli 326c35cc0d Fix configurazione redis su sentinel server 2024-03-15 17:35:45 +01:00
Samuele Locatelli 04f1fee8ae Merge tag 'UpdateDbLayerForDecoder01' into develop
Update gestione DB e log x decoder, fix vari errori che davano timeout
con dati > 1mln records
2023-08-21 18:21:34 +02:00
Samuele Locatelli 6aec9fb10c Merge branch 'release/UpdateDbLayerForDecoder01' 2023-08-21 18:21:14 +02:00
Samuele Locatelli cb81d46e85 refresh conf pubblicazione 2023-08-21 18:20:35 +02:00
Samuele Locatelli e71b873a4c - nuget update
- pulizia codice da warning
2023-08-21 18:06:54 +02:00
Samuele Locatelli c6e6d8b7c3 Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2023-08-21 16:56:24 +02:00
Samuele Locatelli cccebb9a66 Refresh globale 2023-08-21 16:54:17 +02:00
Samuele Locatelli 696129e41a COmpletata review log + migrazione con indice aggiunto 2023-08-21 16:54:10 +02:00
Samuele Locatelli 637ec4c26b - eccessivo carico MySql ufficio
- aggiunta preliminare log x chiamate DB
2023-08-21 15:34:32 +02:00
zaccaria.majid 3f668623d3 inizio fix filtraggio per allarmi 2023-07-07 15:50:18 +02:00
zaccaria.majid 1d97c0e02a ok fix grafico x ombre 2023-07-06 16:57:27 +02:00
zaccaria.majid 8ddca2eeea spostata alarms overview 2023-07-06 16:12:23 +02:00
zaccaria.majid 4caafd62ad fix overview allarmi (fissata altezza se compMode) 2023-07-06 15:35:08 +02:00
zaccaria.majid ab441ad981 modifiche grafiche 2023-07-06 13:01:05 +02:00
Samuele Emilio Locatelli da00652d35 Update MyToDo.md x gestione stati/periodi/note modificabilità estese (non vincolo per se/per altri) 2023-06-22 10:32:19 +00:00
zaccaria.majid dcae3b8499 Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2023-06-22 11:44:26 +02:00
zaccaria.majid e6e596579e upload file di specifiche per pagina MyToDo 2023-06-22 11:43:34 +02:00
Samuele Locatelli 343e448836 Merge tag 'FixNullabilityCheck01' into develop
Fix oggetti nullable x check x evitare warnings / RAM retention
2023-04-13 18:31:54 +02:00
Samuele Locatelli 50163d2e13 Merge branch 'release/FixNullabilityCheck01' 2023-04-13 18:31:19 +02:00
Samuele Locatelli a49852b92e Refresh codice 2023-04-13 18:30:41 +02:00
Samuele Locatelli 7ff0836f38 Update minore di errori / warnings (nullability) 2023-04-13 17:45:46 +02:00
Samuele Locatelli 42055e8c7e decoder: fix loglevel x ticket 2023-04-13 17:45:37 +02:00
Samuele Locatelli b046ad72eb Merge tag 'FixDecoderAlarmsTickets' into develop
Fix decoder alarms ticket, tempo e logging
2023-04-08 11:12:06 +02:00
Samuele Locatelli 5da39b7f5f Merge branch 'release/FixDecoderAlarmsTickets' 2023-04-08 11:11:57 +02:00
Samuele Locatelli 23dc550e20 Update x timing gestione cehck tickets allarmi 2023-04-08 11:11:32 +02:00
Samuele Locatelli 7b65efea79 Merge tag 'MinorTypoFix' into develop
Minor fix varie
2023-04-08 09:45:22 +02:00
Samuele Locatelli 4a00b32c73 Merge branch 'release/MinorTypoFix' 2023-04-08 09:44:54 +02:00
Samuele Locatelli 4e91e2c4e0 Cleanup parti inutilizzate 2023-04-08 09:44:32 +02:00
Samuele Locatelli fd5153fe97 Refresh vers 2023-04-08 09:39:46 +02:00
Samuele Locatelli ce990fd1cc Typo + fix BlinkPeriod (2-->3 sec) 2023-04-08 08:41:35 +02:00
Samuele Locatelli a5ef08f0e0 Merge tag '20230331_UiRefreshMaint' into develop
Update x UI con maint negative e progressbar
2023-03-31 15:06:27 +02:00
Samuele Locatelli 3b237db585 Merge branch 'release/20230331_UiRefreshMaint' 2023-03-31 15:06:13 +02:00
Samuele Locatelli c3b2e7d0cf Fix UI x display classi maint rosse 2023-03-31 14:58:44 +02:00
Samuele Locatelli c655fd5b04 fix decimali x calcolo counter in H decoder 2023-03-31 14:34:45 +02:00
Samuele Locatelli d660939ebf Merge tag '20230331_CountersCompleted' into develop
update gestione counters + refresh UI
2023-03-31 12:12:57 +02:00
Samuele Locatelli 3626ccad99 Merge branch 'release/20230331_CountersCompleted' 2023-03-31 12:12:44 +02:00
Samuele Locatelli 7522d18a7b Update nuget + fix calcolo decimali valori counters in ore 2023-03-31 12:11:26 +02:00
Samuele Locatelli 5933d31de8 fix LUA parametri 2023-03-31 11:56:15 +02:00
Samuele Locatelli 35923f29e3 refresh 2023-03-31 11:54:08 +02:00
Samuele Locatelli 41449df7bf update decoder x contatori 2023-03-31 11:54:05 +02:00
Samuele Locatelli 769fadd177 implementaizone corretta LUA x contatori 2023-03-31 11:53:53 +02:00
Samuele Locatelli 250d98b1c5 fix old lua 2023-03-31 11:53:41 +02:00
Samuele Locatelli 1b4d70330e update stored pulizia dati x Taskexec 2023-03-31 11:53:06 +02:00
Samuele Locatelli ae748ebeb2 Update vers test DECODER
- cablata logica Cà
- test su WKST-SAM notturno
2023-03-30 19:16:15 +02:00
Samuele Locatelli 789eb58590 DECODER:
- Aggiunto decodifica stati pareto in minuti (DayDuration)
2023-03-30 09:39:01 +02:00
Samuele Locatelli c81045df7e Fix SIM x spegnimento notturno 2023-03-30 09:38:31 +02:00
Samuele Locatelli c3a6fdd832 Merge tag '20230328_fixMigrations' into develop
Sistemazione migrazione DOWN
2023-03-29 18:33:21 +02:00
Samuele Locatelli e56cf745bc Merge branch 'release/20230328_fixMigrations' 2023-03-29 18:33:14 +02:00
Samuele Locatelli 9a0211f82c Update migration
- down x eliminazione stored & views OK
2023-03-29 18:32:19 +02:00
Samuele Locatelli 09af4902be Merge tag '20230328_fixDb' into develop
Update stored
2023-03-29 18:23:30 +02:00
Samuele Locatelli d9a670bb6c Merge branch 'release/20230328_fixDb' 2023-03-29 18:23:12 +02:00
Samuele Locatelli 8c5d331ed8 Update stored x ProdLog 2023-03-29 18:22:44 +02:00
Samuele Locatelli 057be73c46 Merge tag '20230328_cleanupDB' into develop
Cleanup statistiche
2023-03-29 18:20:59 +02:00
Samuele Locatelli badd1f0075 Merge branch 'release/20230328_cleanupDB' 2023-03-29 18:20:52 +02:00
Samuele Locatelli 70dd210bb4 Data
- Fix creazione stored + migration
- refresh appsettings.json
2023-03-29 18:20:21 +02:00
Samuele Locatelli 115a9c3cc3 DATA:
- Update conf sqlScripts
- migration x TaskExec
- views/stored creation (maybe)
2023-03-29 17:48:44 +02:00
Samuele Locatelli 49c22b57ad Update pubblicazione IIS04 2023-03-29 17:48:07 +02:00
Samuele Locatelli 92a40b1045 Merge tag '20230328_prodUpdate' into develop
Update produzione x recupero info + display pareto stati, refresh UI
2023-03-29 11:03:56 +02:00
Samuele Locatelli 021765948f Merge branch 'release/20230328_prodUpdate' 2023-03-29 11:03:31 +02:00
Samuele Locatelli 71b338077e refresh UI 2023-03-29 11:02:55 +02:00
Samuele Locatelli 72951058ed Fix visualizzazione prod e stats tempi 2023-03-29 11:02:51 +02:00
Samuele Locatelli 59f38fe228 Fix display prod data con barre 2023-03-28 20:54:33 +02:00
Samuele Locatelli bc1980e388 Refresh generale + install in SUM 2023-03-28 20:27:33 +02:00
Samuele Locatelli 01c51fcb00 Fix pareto status x calcolo % status 2023-03-28 20:27:26 +02:00
Samuele Locatelli 27875043b8 Aggiunto DTO x trasf dati status 2023-03-28 20:27:14 +02:00
Samuele Locatelli 0e1607fc0e FIX gestione stored x pareto stati 2023-03-28 19:00:31 +02:00
Samuele Locatelli 7b94368e7c ok lettura vista pareto gloable stati amcchina 2023-03-28 18:03:41 +02:00
Samuele Locatelli 230ad35316 Refresh generico conf admin 2023-03-28 14:19:13 +02:00
Samuele Locatelli 3143bd5233 Update decoder x salvataggio dati prodLog 2023-03-28 14:18:59 +02:00
Samuele Locatelli 43647dd648 Fix migration x DB + update conf 2023-03-28 14:18:48 +02:00
Samuele Locatelli 181db78f3d Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2023-03-27 19:51:30 +02:00
Samuele Locatelli 573375138b refresh manifest vari 2023-03-27 19:48:45 +02:00
Samuele Locatelli 94edd54645 powershell x fix DB espostato da win verso linux 2023-03-27 19:48:18 +02:00
Samuele Locatelli 2c9c86d749 Gestione adapter: riavvio se dati "stale" che non si aggiornano oltre 60 sec 2023-03-27 19:47:58 +02:00
zaccaria.majid c41d087fd6 porting nuget 2023-02-03 12:24:20 +01:00
zaccaria.majid 6e7ea9935c fix grafico tabelle alarm analysis 2022-11-11 11:47:23 +01:00
zaccaria.majid 353f1119b2 fix grafico 2022-11-11 11:14:11 +01:00
Samuele Locatelli 84dcd7553c eliminato log allarmi di default, typo 2022-11-11 08:37:56 +01:00
Samuele Locatelli 2002516dfe refresh UI x alarm analysis 2022-11-10 19:25:40 +01:00
Samuele Locatelli e71ecf1beb Refresh + salvataggio log allarmi 2022-11-10 19:00:05 +01:00
Samuele Locatelli c0718b0042 Merge tag 'FixAlarmCount' into develop
Update alarm display
2022-11-10 10:36:59 +01:00
Samuele Locatelli 3c252aea7f Merge branch 'release/FixAlarmCount' 2022-11-10 10:36:53 +01:00
zaccaria.majid fd4528a0bc fix minore 2022-11-10 10:12:30 +01:00
zaccaria.majid cf7c57d116 Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-11-10 10:08:02 +01:00
zaccaria.majid a13426f34a fix conteggio allarmi attivi +
modifiche grafiche alarm analysis
2022-11-10 10:06:25 +01:00
Samuele Locatelli 8927c74165 Merge tag 'FixSpazioPagContatti' into develop
Fix spazio pag contatti
2022-11-07 19:36:20 +01:00
Samuele Locatelli 698087df93 Merge branch 'release/FixSpazioPagContatti' 2022-11-07 19:36:14 +01:00
Samuele Locatelli 4be2f3e91e Refresh spazio pagina contatti 2022-11-07 19:35:40 +01:00
Samuele Locatelli ce77787b11 Merge tag 'AddContacts' into develop
Aggiunta contatti
2022-11-07 15:25:40 +01:00
Samuele Locatelli a61daa1e6b Merge branch 'release/AddContacts' 2022-11-07 15:25:28 +01:00
Samuele Locatelli a32217368b Aggiunta apgina contatti 2022-11-07 15:25:04 +01:00
Samuele Locatelli 5912b7d414 Merge tag 'UpdateDMono' into develop
Update mono con allarmi in home + nuovo nome da conf
2022-11-07 14:53:52 +01:00
Samuele Locatelli 3f0b2ec017 Merge branch 'release/UpdateDMono' 2022-11-07 14:53:36 +01:00
Samuele Locatelli 95c8d5be1b Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-11-07 14:51:42 +01:00
Samuele Locatelli 383f287610 Refresh 2022-11-07 14:49:28 +01:00
Samuele Locatelli 0b638ce1e3 Fix gestione nome app 2022-11-07 14:49:13 +01:00
Samuele Locatelli 096ce418b0 Update nomi applicazioni 2022-11-07 14:44:11 +01:00
zaccaria.majid b0bbcab47e fix grafico allarmi + bottone x
apertura file maint
2022-11-02 18:03:36 +01:00
zaccaria.majid d42b2681b8 minor fix icone 2022-11-02 17:02:37 +01:00
zaccaria.majid b36210876b fix grafico x allarmi in pagina index 2022-11-02 16:40:37 +01:00
zaccaria.majid fbb5295b20 fix nav collapsed oninitialized 2022-11-02 15:56:51 +01:00
zaccaria.majid e1bdfe7c71 -Aggiunta link x pdf pagina maintenance
-fix layout index con allarmi visibili in caso !=0
2022-11-02 15:01:14 +01:00
Samuele Locatelli 535d3882dd Update con pdf x apertura specifiche allarmi/manutenzioni 2022-11-02 09:26:30 +01:00
Samuele Locatelli 3feb8dec87 Merge tag 'UpdateAlarmsHomePage' into develop
Fix allarmi in home + altri fix grafici vari x prod
2022-10-28 18:02:32 +02:00
Samuele Locatelli e63ec3abdd Merge branch 'release/UpdateAlarmsHomePage' 2022-10-28 18:02:23 +02:00
Samuele Locatelli 10ec2a8853 Fix homepage
- cards colors
- spazi
- link allarmi
- titoli vari
- operazioni lettura/rilettura
- click sel all
2022-10-28 18:01:56 +02:00
zaccaria.majid 0bd15709aa Aggiunta alarms preview 2022-10-28 17:05:31 +02:00
zaccaria.majid eda2d3a2bb modifica display allarmi index +
fix crash per reloadAfterMessage
2022-10-28 11:35:01 +02:00
Samuele Locatelli a8cca9f242 Merge tag 'FixCrashMultiPlot' into develop
Fix problema blocco con multiplot x troppi eventi messaggi
2022-10-27 17:47:13 +02:00
Samuele Locatelli 31fa4f7777 Merge branch 'release/FixCrashMultiPlot' 2022-10-27 17:45:22 +02:00
zaccaria.majid ad4cd504a1 fix doppio fade in offcanvas 2022-10-27 17:41:59 +02:00
zaccaria.majid 98890254e8 aggiunta filtro x max plot 2022-10-27 16:46:20 +02:00
zaccaria.majid 2bb37146dd fix comportamento tools come parameters 2022-10-27 15:47:47 +02:00
Samuele Locatelli 78361306e8 Fix pagina parametri x invoke multiplo
- sistemato aprametro filtro max refresh
- fix max parametri selezioanbili
2022-10-27 15:28:48 +02:00
zaccaria.majid aa544a7ecd fix max plot 2022-10-27 14:23:02 +02:00
zaccaria.majid a325c5154f fix max plot 2022-10-27 10:25:30 +02:00
Samuele Locatelli 113109b5e4 appunti chartBoot x push data 2022-10-26 16:13:31 +02:00
Samuele Locatelli 74db1d2c34 aggiunto try-catch su timer 2022-10-26 14:59:04 +02:00
zaccaria.majid 54d1a47a58 UPDATE: fix plot senza dati 2022-10-26 12:44:11 +02:00
zaccaria.majid f3a947fa72 fix plot senza dati 2022-10-26 10:29:43 +02:00
Samuele Locatelli 00e8d0e8e5 Merge remote-tracking branch 'origin/develop' into develop 2022-10-25 19:33:34 +02:00
Samuele Locatelli c9489f1ad3 Fix comportamento reload con semafori wait/load 2022-10-25 19:33:27 +02:00
zaccaria.majid 3622aa9a54 fix controllo timer null 2022-10-25 16:11:54 +02:00
Samuele Locatelli e6cf6b3b36 Merge tag 'UpdUiRefresh' into develop
update UI refresh
2022-10-25 15:33:41 +02:00
Samuele Locatelli 56fbf03bc8 Merge branch 'release/UpdUiRefresh' 2022-10-25 15:33:35 +02:00
Samuele Locatelli d53c2c7137 Update refresh pagina allatmi
- GC esplicito x dispose e timer
- cambio modalità refresh da nuovo messaggio redis
2022-10-25 15:33:16 +02:00
Samuele Locatelli 547cde5b0d Merge tag 'UpdateUiAndDecoder' into develop
Fix UI and decoder
2022-10-25 14:34:43 +02:00
Samuele Locatelli 6984c0b4eb Merge branch 'release/UpdateUiAndDecoder' 2022-10-25 14:34:35 +02:00
Samuele Locatelli 9d4055714b Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-10-25 14:34:14 +02:00
Samuele Locatelli 9badb298eb Refresh globale 2022-10-25 14:34:12 +02:00
zaccaria.majid e671dbf9a1 fix timer 2022-10-25 14:13:45 +02:00
zaccaria.majid 477a80c7b9 fix display alarmLog solo se attivo 2022-10-25 12:31:35 +02:00
Samuele Locatelli 47d60dc1ee Update sx gestione AlarmLogActive 2022-10-25 12:02:23 +02:00
Samuele Locatelli d3a2cb3ef3 Merge branch 'develop' 2022-10-25 11:17:20 +02:00
Samuele Locatelli d5f29f5945 Merge remote-tracking branch 'origin/main' into develop 2022-10-25 11:17:04 +02:00
Samuele Locatelli ba53accf8b UPdate decode/SIM 2022-10-25 11:16:09 +02:00
zaccaria.majid d0afb435db fix grafici x dimensioni monitor 2022-10-25 10:28:38 +02:00
zaccaria.majid 3e664b4985 update filters:
-sostituzione offcanvas nelle pagine
-aggiunta display filtri attivi
2022-10-25 10:16:44 +02:00
Samuele Locatelli 530b26d4d6 Refreshvari
- cache UI allarmi REC/LOG a 250ms da 1000
- SIM: + allarmi
- decoder: gestione tutta redis allarmi
2022-10-25 09:00:11 +02:00
Samuele Locatelli 2ce90b4eaf Merge branch 'develop' 2022-10-24 20:06:56 +02:00
Samuele Locatelli d3164aea0e MOre decoder FIX 2022-10-24 20:06:27 +02:00
Samuele Locatelli 98c7c254b0 Merge tag 'UpdateDecoderAndUi_221024' into develop
Update decoder, UI e altro x JeldWen D1521
2022-10-24 18:54:21 +02:00
Samuele Locatelli ed052304bf Merge branch 'release/UpdateDecoderAndUi_221024' 2022-10-24 18:53:34 +02:00
Samuele Locatelli e76d200971 Fix minor display su alarm overview 2022-10-24 18:53:10 +02:00
zaccaria.majid e8574c873c fix 2022-10-24 18:23:27 +02:00
zaccaria.majid 620ed9f332 Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-10-24 18:23:14 +02:00
zaccaria.majid be65aaa7bb aggiunta counter allarmi + fix grafico 2022-10-24 18:21:33 +02:00
Samuele Locatelli 7c29fbce77 Fix decoder x
- filtraggio pre/post dati
- gesitone muted
2022-10-24 18:09:46 +02:00
Samuele Locatelli 384a03b6f7 Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-10-24 17:12:17 +02:00
Samuele Locatelli 6a526e66c5 Refresh btn analisi allarmi 2022-10-24 17:12:14 +02:00
Samuele Locatelli e71add5378 UPdate timing SIM 2022-10-24 17:10:35 +02:00
zaccaria.majid 5aba124eb4 Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-10-24 17:06:04 +02:00
zaccaria.majid 556f34fe9c bozza grafica alarms 2022-10-24 17:05:52 +02:00
Samuele Locatelli e631d9fd08 Update header allarmi 2022-10-24 17:04:56 +02:00
Samuele Locatelli 89465ed44c Refresh allarmi x timer 2022-10-24 16:56:27 +02:00
zaccaria.majid 74f8016fa0 Aggiunta cache redis alarm log 2022-10-24 16:27:10 +02:00
Samuele Locatelli 961be55760 Merge tag 'FixDbOverload' into develop
Fix globale
2022-10-24 15:02:25 +02:00
Samuele Locatelli e9000b6448 Merge branch 'release/FixDbOverload' 2022-10-24 15:02:05 +02:00
Samuele Locatelli c2d40c1e5a Merge tag 'DecoderFix_221024' into develop
FIx
2022-10-24 15:01:48 +02:00
Samuele Locatelli bec5a56df2 DB overload:
Fix problema eventi moltiplicati x subscript
2022-10-24 15:00:45 +02:00
zaccaria.majid 7629ee8725 Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-10-24 14:23:47 +02:00
zaccaria.majid 2245ba5c7e aggiunta cache redis 2022-10-24 14:22:50 +02:00
Samuele Locatelli fec802ca03 Merge branch 'release/DecoderFix_221024' 2022-10-24 13:40:34 +02:00
Samuele Locatelli 996e752460 Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-10-24 11:44:20 +02:00
Samuele Locatelli 44f451e50b Update gestione decoder 2022-10-24 11:43:19 +02:00
zaccaria.majid 36015d0945 fix mostra single rec on initialized 2022-10-24 09:59:49 +02:00
Samuele Locatelli 9a0ba684bb UPdate sim allarmi: cambio tempistiche 2022-10-24 09:41:35 +02:00
Samuele E. Locatelli 32537390f4 difica x scrittura azzeramento allarmi LOG 2022-10-23 18:33:31 +02:00
Samuele E. Locatelli dee937990e Merge tag 'UpdateBlinkAlarms' into develop
Update gestione allarmi blink # # Write a message for tag: # UpdateBlinkAlarms # Lines starting with '#' will be ignored.
2022-10-23 18:12:02 +02:00
Samuele E. Locatelli da92a09190 Merge branch 'release/UpdateBlinkAlarms' into main 2022-10-23 18:11:30 +02:00
Samuele E. Locatelli f5dd2ad44d Update record 0 alarms 2022-10-23 18:10:24 +02:00
Samuele E. Locatelli 1792c6417f Update gestione allarmi blink 2022-10-23 15:50:10 +02:00
Samuele E. Locatelli 9bb67a368e refresh codice 2022-10-23 15:04:26 +02:00
Samuele E. Locatelli 32efb52d9d bozza modifica con lista thread safe... 2022-10-22 23:25:29 +02:00
Samuele E. Locatelli 0284b50997 Refresh controller/decoder 2022-10-22 23:03:30 +02:00
Samuele E. Locatelli 38401b75b5 Update x ridurre peso chiamate DB 2022-10-22 23:03:14 +02:00
Samuele E. Locatelli a0976ab148 Update decoder x ridurre scritture inutili 2022-10-22 22:56:00 +02:00
Samuele Locatelli faca184aab Update decoder x gestione nuovo blink allarmi (NON OK) 2022-10-22 19:24:44 +02:00
Samuele Locatelli ce014431d2 DECODER:
- Inizio modifica decoder x filtro allarmi blink (NON OK)
2022-10-21 19:30:12 +02:00
Samuele Locatelli a7575d07a2 Completo fix + update grafico allarmi (text-warning) 2022-10-21 19:09:01 +02:00
Samuele Locatelli d4d49650ec Merge remote-tracking branch 'origin/develop' into develop 2022-10-21 19:07:09 +02:00
Samuele Locatelli cda2541d95 Fix simulatore x allarmi come macchina reale 2022-10-21 19:06:54 +02:00
zaccaria.majid 7f95ad697c Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-10-21 17:30:54 +02:00
zaccaria.majid 82f00ac75e fix allarmoverview 2022-10-21 17:30:45 +02:00
Samuele Locatelli 4305f17a3c Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-10-21 17:18:46 +02:00
Samuele Locatelli b68a7a833c update optPar decoder 2022-10-21 17:18:41 +02:00
zaccaria.majid 282b0b4cd4 fix alarm overview 2022-10-21 17:17:40 +02:00
Samuele Locatelli e33bc2151a Merge tag 'FixTools' into develop
Fix ADAPTER x info sui tools (HOPE)
2022-10-20 18:48:55 +02:00
Samuele Locatelli 00acc83e42 Merge branch 'release/FixTools' 2022-10-20 18:48:43 +02:00
Samuele Locatelli b86a6021bf Riorganizzazione alfabetica codice
- Adapter
- Decoder
- UI
2022-10-20 18:48:25 +02:00
Samuele Locatelli b8e8dd5b95 Fix adapter decoding TOOLS 2022-10-20 18:41:24 +02:00
Samuele Locatelli 24f1432e56 Fix display allarmi 2022-10-20 18:31:30 +02:00
zaccaria.majid 2fea170463 fix wrap pagina allarmi 2022-10-20 17:53:42 +02:00
Samuele Locatelli ad10f042dc Merge tag 'UpdateAsyncDb' into develop
Aggiornamenti x speedup lettura dati tool plot + DB in genere
2022-10-20 09:36:34 +02:00
Samuele Locatelli 7dc9d95cf8 Merge branch 'release/UpdateAsyncDb' 2022-10-20 09:36:20 +02:00
Samuele Locatelli 1fe0cac4bd Refresh versione 2022-10-20 09:35:30 +02:00
zaccaria.majid e21f7ece07 refresh grafico 2022-10-06 12:49:12 +02:00
Samuele Locatelli 6869a84fd4 Fluxh cache limitato a dati dei grafici:
- parametri
- tool life
2022-10-06 12:39:30 +02:00
zaccaria.majid 399cc9654a fix grafici + aggiunta flushCache 2022-10-06 12:32:52 +02:00
Samuele Locatelli ecc14f75c6 fix titolo alarm 2022-10-06 11:37:27 +02:00
zaccaria.majid 863568a938 update x speedup lettura dati toolPlot 2022-10-06 11:28:29 +02:00
zaccaria.majid cc17992917 Merge branch 'FeaturefixPlotRows' into develop 2022-10-06 10:22:44 +02:00
zaccaria.majid 777a3fe6dd aggiunta select all tools 2022-10-06 10:22:27 +02:00
zaccaria.majid bd451a48a1 fix plot che vanno a capo 2022-10-06 09:55:12 +02:00
Samuele Locatelli 253b0bb9eb Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-10-06 09:27:06 +02:00
Samuele Locatelli f7c97c3208 Update x speedup lettura dati paramPlot (LOG) 2022-10-06 09:24:24 +02:00
zaccaria.majid 6b38d86a4a Creazione componente per toggle + applicazione nelle pagine 2022-10-05 13:04:47 +02:00
Samuele Locatelli b5a2f742c6 Aggiunta decodifica valori stato pallet
aggiunta sim pallet
2022-10-04 20:57:43 +02:00
Samuele Locatelli 730266d2ad Update SIM Status 2022-10-04 20:50:06 +02:00
Samuele Locatelli 493b9baa5c Update controller DB
- metodi DB tutti async
- debug log x async
2022-10-04 19:56:52 +02:00
Samuele Locatelli 3dc7378e72 Merge tag 'UpdateIndexLayout' into develop
Update vari:
- index page layout
- SIM tools corretto
2022-10-04 19:25:29 +02:00
Samuele Locatelli b2d79ff194 Merge branch 'release/UpdateIndexLayout' 2022-10-04 19:25:16 +02:00
Samuele Locatelli 7f37bca29f Refresh generale 2022-10-04 19:24:53 +02:00
Samuele Locatelli 56919555e7 Index Page: consensata 2022-10-04 19:24:42 +02:00
Samuele Locatelli 911f83f1ea Fix sim TOOLS (decrescente!) 2022-10-04 19:05:11 +02:00
Samuele Locatelli 286e3c1c12 Minor update collapse 2022-10-04 19:04:56 +02:00
zaccaria.majid 09c9f37c62 Aggiunta collapse sidebar 2022-10-04 17:15:08 +02:00
Samuele Locatelli b0e8ec0dd4 Update home page display + nav 2022-10-04 14:54:49 +02:00
zaccaria.majid 135cb07f49 cleanUP 2022-10-04 14:45:40 +02:00
zaccaria.majid 61021e25b9 fix grafici vari 2022-10-04 14:32:09 +02:00
Samuele Locatelli dd13d4e9f8 Update SIM conf 2022-10-04 12:19:17 +02:00
zaccaria.majid c7876fe493 fix grafico + fix addAll 2022-10-04 11:53:17 +02:00
zaccaria.majid 46fe731931 Aggiunta selectAll 2022-10-04 11:23:19 +02:00
zaccaria.majid 2d145a5e37 fix calcolo percentuali progress bar 2022-10-04 09:14:26 +02:00
Samuele Locatelli b66f4fb239 refresh vers 2022-10-03 18:53:31 +02:00
Samuele Locatelli d6cc81a4a9 Cleanup SIM 2022-10-03 18:20:58 +02:00
Samuele Locatelli c583d7785f Fix gestione tools
- nuova gest SIM/decoder con key/val
- fix decoder valori tool life
- ok salvataggio DB
2022-10-03 17:08:25 +02:00
Samuele Locatelli 11bc6566b5 Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-10-03 15:56:01 +02:00
Samuele Locatelli bed651f6df Merge remote-tracking branch 'origin/develop' into develop 2022-10-03 15:55:53 +02:00
Samuele Locatelli cfaf57f34f UPdate gestione SIM x nuovo val 2022-10-03 15:55:14 +02:00
zaccaria.majid f7357aded9 fix parametri 2022-10-03 15:55:02 +02:00
zaccaria.majid b354763cc4 Aggiunta Filtri pagina tools 2022-10-03 15:46:53 +02:00
zaccaria.majid bc68faea09 aggiunta history plot 2022-10-03 15:28:38 +02:00
Samuele Locatelli 904cafa91b refresh controller 2022-10-03 14:57:30 +02:00
Samuele Locatelli 661734d1df refresh 2022-10-03 14:48:49 +02:00
Samuele Locatelli 6bf82f6615 Update struttura dati x DataLog
- modifica modello dati
- aggiunto enum parametri/tools/all
- aggiunte migrations
2022-10-03 14:48:42 +02:00
zaccaria.majid d7c52768af minor fix 2022-10-03 13:02:48 +02:00
zaccaria.majid 372318a290 Fix grafici 2022-10-03 12:56:31 +02:00
zaccaria.majid 801441fd1a Aggiunta Plot pagina tools 2022-10-03 12:30:09 +02:00
zaccaria.majid beabadd2fc Fix shortList tools index + fix grafico params 2022-10-03 10:35:15 +02:00
zaccaria.majid dd9680a8ca Fix grafico tools list 2022-10-03 10:11:00 +02:00
zaccaria.majid 1847419e7d Merge remote-tracking branch 'origin/develop' into develop 2022-10-03 09:45:15 +02:00
Samuele Locatelli fecc44fda1 update sim tool conf 2022-10-03 09:44:54 +02:00
Samuele Locatelli d8071e3658 Update tools view x sel parametri home 2022-10-03 09:41:32 +02:00
Samuele Locatelli 7945ce17c5 Update SIM x tutti i parametri dei TOOLS 2022-10-03 08:58:00 +02:00
Samuele Locatelli f61f206208 Inizio fix simulatore x + dati in tools 2022-10-03 08:34:41 +02:00
Samuele Locatelli 10c3e68b45 update sim tools params 2022-10-03 07:48:14 +02:00
Samuele Locatelli a86f113347 FIx SIM: + lenta decrescita params tools 2022-10-02 12:14:21 +02:00
Samuele Locatelli 41d5129637 Fix blocco colorato selezione maint sched 2022-09-30 17:15:15 +02:00
Samuele Locatelli 377711be19 Fix errore pag setup maintenance 2022-09-30 17:09:32 +02:00
Samuele Locatelli 249fd91834 Update grafici vari 2022-09-30 17:05:46 +02:00
zaccaria.majid a635f46cff fix grafici 2022-09-30 16:42:27 +02:00
zaccaria.majid 944cdde2b1 minor fix 2022-09-30 12:57:50 +02:00
zaccaria.majid d5c49c48b1 fix filtri parametri 2022-09-30 12:27:01 +02:00
zaccaria.majid 27b4d3aa70 fix filtri enabled/disabled 2022-09-30 12:16:54 +02:00
zaccaria.majid 54bd85ca85 modifiche grafiche + fix reset filtro data allarmi 2022-09-30 12:10:42 +02:00
zaccaria.majid f89ce06f1b Modifiche grafiche 2022-09-30 10:35:16 +02:00
zaccaria.majid 45a8526d57 aggiunta filtro per data allarmi 2022-09-30 10:14:19 +02:00
Samuele Locatelli 710f082b34 Minor refresh 2022-09-29 17:12:51 +02:00
zaccaria.majid 289c2d5112 modifiche grafiche 2022-09-29 16:19:04 +02:00
zaccaria.majid 9721762a3e modifiche grafiche varie 2022-09-29 13:03:28 +02:00
zaccaria.majid ded55b9500 fix ShowParams padding 2022-09-29 11:38:57 +02:00
Samuele Locatelli a988fd00ea minor update grafico :
- standardizzare testate
2022-09-29 11:29:39 +02:00
zaccaria.majid 5f7d2ab1ae aggiunta componente alarmDur + cleanUp 2022-09-29 11:06:01 +02:00
Samuele Locatelli ac759f53ee Merge branch 'feature/FixAlAnBlocks' into develop 2022-09-29 10:17:05 +02:00
Samuele Locatelli 49002a4604 Completato fix componente alarmFreq 2022-09-29 10:16:56 +02:00
Samuele Locatelli 4f0a39ca11 Inizio sistemazione blocchi analisi allarmi
- verifica filtro
- fix pagina master
2022-09-29 09:54:19 +02:00
zaccaria.majid 7b0e29e0d4 Tentativo fix 2022-09-29 09:16:18 +02:00
zaccaria.majid edb2cbaf62 fix currFilter 2022-09-29 08:40:12 +02:00
zaccaria.majid f6722af1cc Continuo split componenti chart 2022-09-28 17:29:45 +02:00
zaccaria.majid 613c4edba8 Continuo split grafici 2022-09-27 18:02:52 +02:00
zaccaria.majid c5b5b1148d fix calcolo soglie chart duration 2022-09-27 08:48:48 +02:00
zaccaria.majid ebd3e075a4 fix pagina duration chart 2022-09-26 17:30:10 +02:00
Samuele Locatelli 0299d6a489 Merge tag 'FixDecoderCloseAlarms' into develop
Fix gestione allarmi:
- decoder che sbaglia a chiudere allarmi attivi
- calcolo LINQ duration che non è possibile in SQL in 1 solo passo
2022-09-26 16:19:18 +02:00
Samuele Locatelli c6ced5c089 Merge branch 'release/FixDecoderCloseAlarms' 2022-09-26 16:18:47 +02:00
Samuele Locatelli 3babbcd5f2 Fix alarm analisys page 2022-09-26 16:17:53 +02:00
Samuele Locatelli 5f5a1dd5d7 - close alarms:
Fix decoder x chiusura allarmi (chiude sempre allarme sull'ultimo x ID)
2022-09-26 16:17:31 +02:00
Samuele Locatelli d24aa0ecb7 LINQ:
- fix recupero dati DURATION in 2 passi (DB + RAM)
2022-09-26 16:16:03 +02:00
zaccaria.majid 243d3bf90a Merge branch 'FeaturealarmDurationChart' into develop 2022-09-26 15:44:14 +02:00
zaccaria.majid bfe4f413d7 fix pagina alarmanalysis 2022-09-26 15:23:07 +02:00
zaccaria.majid 993f068399 aggiunta metodi per chart duration 2022-09-26 14:33:09 +02:00
zaccaria.majid cd3394244b fix grafici + inizio event duration chart 2022-09-26 12:51:08 +02:00
zaccaria.majid 25945b4f5a fix grafico 2022-09-26 11:01:39 +02:00
zaccaria.majid 725caa2aa6 fix pagination dopo cambio num record 2022-09-26 10:54:10 +02:00
zaccaria.majid 5d2f0ab0ca fix chart con progress bars 2022-09-26 10:08:53 +02:00
Samuele Locatelli 5b166bf7b5 Merge tag 'UpdateHistDataLog' into develop
Fix comportamento reload dataLog x dati storici da DB
2022-09-23 18:30:14 +02:00
Samuele Locatelli 38ec150449 Merge branch 'release/UpdateHistDataLog' 2022-09-23 18:29:53 +02:00
Samuele Locatelli d470f435d3 Fix comportamento reload:
- valutare implementazione OnParametersSetAsync() globale
- testare comportamento altri componenti
2022-09-23 18:29:02 +02:00
Samuele Locatelli 40165e0c64 Merge remote-tracking branch 'origin/develop' into develop 2022-09-23 17:48:44 +02:00
Samuele Locatelli 1be45ac909 Cache dati OK x parametri DTO! 2022-09-23 17:48:36 +02:00
zaccaria.majid 91aa971693 fix chart alarms 2022-09-23 17:28:04 +02:00
Samuele Locatelli 432694fc7d Fix calcolo orario + perc 2022-09-23 17:14:39 +02:00
Samuele Locatelli c615b81710 Merge remote-tracking branch 'origin/develop' into develop 2022-09-23 17:06:31 +02:00
Samuele Locatelli 948675e24c Tentativo cache HistPlot (non si vede +...) 2022-09-23 17:05:06 +02:00
zaccaria.majid 96348e0964 Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-09-23 17:00:13 +02:00
zaccaria.majid 9732cdd84a Merge branch 'FeaturealarmAnalysisCharts' into develop 2022-09-23 16:58:55 +02:00
zaccaria.majid 7b6a24cb2a fix pagina errori con charts 2022-09-23 16:58:33 +02:00
Samuele Locatelli 294896905e Restore Line chartJS 2022-09-23 15:28:40 +02:00
zaccaria.majid b351936996 continuo pagina alarmanalysis 2022-09-23 12:56:11 +02:00
zaccaria.majid 5bb817f94c Merge remote-tracking branch 'origin/develop' into FeaturealarmAnalysisCharts 2022-09-23 12:11:32 +02:00
zaccaria.majid 8f843ffc9b Aggiunta grafici 2022-09-23 12:11:21 +02:00
Samuele Locatelli 4315091e9d Update pag test x mostrare num ore parametrico 2022-09-23 12:10:06 +02:00
Samuele Locatelli 513e4a6dd6 Ancora minor fix x decoder 2022-09-23 11:52:58 +02:00
zaccaria.majid 5030ee84b9 Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-09-23 10:27:47 +02:00
zaccaria.majid de9e0c780d Merge branch 'FeaturealarmAnalysis' into develop 2022-09-23 10:27:34 +02:00
zaccaria.majid b8bc8a4854 Demo grafico allarmi 2022-09-23 10:27:19 +02:00
Samuele Locatelli 65852999bd Log invio redis x debug picchi 2022-09-23 10:24:40 +02:00
Samuele Locatelli 1b368c63a8 Update decoder:
- log info insert allarmi su DB
- refresh
2022-09-23 09:39:06 +02:00
zaccaria.majid fb7edefcb0 fix controllo allarmi attivi 2022-09-23 09:28:30 +02:00
zaccaria.majid ebf6f8e144 Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-09-23 08:49:49 +02:00
zaccaria.majid 016c328e23 pagina alarmanalysis 2022-09-23 08:48:58 +02:00
Samuele Locatelli b3134ab4dc Merge tag '20220923_UpdateSim' into develop
Update SIM x allarmi + frequenti in parte bassa conf
2022-09-23 08:43:16 +02:00
Samuele Locatelli 7e93ca846e Merge branch 'release/20220923_UpdateSim' 2022-09-23 08:42:49 +02:00
Samuele Locatelli 92f725cf47 Merge remote-tracking branch 'origin/develop' into develop 2022-09-23 08:40:52 +02:00
Samuele Locatelli 6f502f0b59 Update SIM allarmi
- maggior probabilità allarmi "bassi" in SIM
2022-09-23 08:39:26 +02:00
zaccaria.majid 06634615c1 fix pagina alarms e inzio charts 2022-09-22 17:44:01 +02:00
zaccaria.majid d66ec9016c fix grafici alarm log e rec + inizio charts 2022-09-22 16:19:58 +02:00
zaccaria.majid 635196dc9a Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-09-22 13:01:16 +02:00
zaccaria.majid b76694842c Aggiunta componente visualizzazione allarmi rec 2022-09-22 13:01:08 +02:00
Samuele Locatelli 40c03732bb Fix ordinamento record (descending) 2022-09-22 12:59:42 +02:00
Samuele Locatelli 5fe7abaadf Update modello dati AlarmRec
- end < start appena creato
2022-09-22 12:50:44 +02:00
Samuele Locatelli c62674bd0a Test dati analisi allarmi
- completata pagina Test x freq
- fix chiamate linq su DB
2022-09-22 12:40:16 +02:00
Samuele Locatelli 35ad29f4f3 refresh 2022-09-22 12:26:50 +02:00
Samuele Locatelli d149c4dbe3 OK test recupero freq allarmi 2022-09-22 12:26:41 +02:00
Samuele Locatelli f3ab3949ca aggiunti metodi in currentDataService 2022-09-22 12:06:11 +02:00
Samuele Locatelli 2253c5918b Aggiunta metodo pareto durata (da validare) 2022-09-22 11:39:42 +02:00
Samuele Locatelli d6a469d9b4 Bozza metodo conteggio freq 2022-09-22 11:30:08 +02:00
Samuele Locatelli bcba036b16 Aggiunta metodi fake DB x DTO analisi allarmi 2022-09-22 11:16:56 +02:00
Samuele Locatelli c96991fbc1 Aggiunta oggetti DTO x analisi allarmi 2022-09-22 11:16:46 +02:00
Samuele Locatelli c70495ee18 CodeMaid:
- reorg classe dataService
2022-09-22 10:23:22 +02:00
Samuele Locatelli 4b4c8231f8 Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-09-22 09:48:00 +02:00
Samuele Locatelli ebe422f21b Refresh complessivo 2022-09-22 09:47:06 +02:00
Samuele Locatelli c3466de7f5 Gestione periodo salvataggio db da conf 2022-09-22 09:46:58 +02:00
zaccaria.majid 9120c31869 fix live update 2022-09-22 09:30:10 +02:00
Samuele Locatelli f1a43ae999 Merge tag 'UpdateProdSim' into develop
Aggiornamento x SIMUL IOB
2022-09-21 16:19:36 +02:00
Samuele Locatelli 741e09d986 Merge branch 'release/UpdateProdSim' 2022-09-21 16:19:18 +02:00
Samuele Locatelli 3442c1a2b9 Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-09-21 16:18:50 +02:00
Samuele Locatelli 43c4271cc5 refresh 2022-09-21 16:17:56 +02:00
Samuele Locatelli a660b8a406 Tentativo fix DECODER bugs:
- modifica console.log fuori da debug
2022-09-21 16:17:49 +02:00
zaccaria.majid 8a8ecb3aec fix liveupdate 2022-09-21 16:04:35 +02:00
zaccaria.majid 7dd7fd9604 Aggiunta bottone start/stop live update allarmi 2022-09-21 15:54:38 +02:00
Samuele Locatelli 0cfe49811a refresh appunti + lice IIS01 2022-09-21 11:08:50 +02:00
Samuele Locatelli 050af15d7c refresh 2022-09-16 18:36:06 +02:00
Samuele Locatelli 1046c1d72a ancora refresh, licenza IIS01 fake 2022-09-16 18:36:01 +02:00
Samuele Locatelli db66d337a1 split pagine display e info 2022-09-16 18:35:44 +02:00
Samuele Locatelli 866ab6391d Aggiunta simulazioni stato x demo 2022-09-16 18:35:31 +02:00
Samuele Locatelli 927b5faf79 Refresh versioni 2022-09-16 18:35:16 +02:00
Samuele Locatelli 04465727cc Modifica metodi validatore x speedup 2022-09-16 18:34:51 +02:00
Samuele Locatelli 4a554c4029 Decoder:
- azzeramento blink counter
2022-07-25 17:46:59 +02:00
Samuele Locatelli f0ad53686e Decoder:
- calcolo distinct x evitare duplicati
2022-07-25 17:46:18 +02:00
Samuele Locatelli 49bdfa2e2a Adapter.OPC:
-parametrizzato trim WhiteSpace alalrmi
2022-07-25 16:51:20 +02:00
Samuele Locatelli 40c3a6afff Moidifica rimozione allarmi filtrati 2022-07-25 16:29:16 +02:00
Samuele Locatelli eeb5c5fed6 Cambio modalità filtro allarmi PRE/POST 2022-07-25 15:49:56 +02:00
Samuele Locatelli 239ed38adc modifica filtro allarmi vuoti 2022-07-25 14:52:26 +02:00
Samuele Locatelli 6e617dedc3 Aggiunto trim allarmi vuoti... 2022-07-25 14:35:25 +02:00
Samuele Locatelli efb310f229 refresh 2022-07-25 12:15:44 +02:00
Samuele Locatelli 98c5be3517 Aggiuntag estione blink allarmi (da provare) 2022-07-25 12:15:40 +02:00
Samuele Locatelli c1795433f6 Adapter
- aggiunta nuovi allarmi PLC 11...15
- aggiunta stati 4 pallet in/ext in pre/post
2022-07-25 12:14:58 +02:00
Samuele Locatelli 19b2368941 refresh 2022-07-25 07:37:41 +02:00
Samuele Locatelli 740d50c95d Update conf allarmi PLC (+5) 2022-07-25 07:37:38 +02:00
Samuele Locatelli a7e0c63c87 Nuget refresh 2022-07-14 18:39:34 +02:00
Samuele Locatelli be70f5f0e1 Update generale 2022-07-09 13:12:54 +02:00
Samuele Locatelli 2d375ebaef Update SIM fino a counters e status 2022-07-05 18:45:46 +02:00
Samuele Locatelli 667b6ea242 OK SIM + DECODER x
- params
- tools
- alarms
2022-07-05 17:51:59 +02:00
Samuele Locatelli d57c062bfe Update conf redis x adapter 2022-07-05 17:49:41 +02:00
Samuele Locatelli 135c19d09d Update conf x nuovo server REDIS 2022-07-05 17:49:31 +02:00
Samuele Locatelli 3461efaf76 Fix SIM
- ok sim tools (decrescenti)
- ok sim allarmi
2022-07-05 17:14:05 +02:00
Samuele Locatelli 0a1f92ae74 Update comportamento SIM 2022-07-05 15:04:05 +02:00
Samuele Locatelli 10a881b717 Refresh UI 2022-07-05 13:24:37 +02:00
Samuele Locatelli 4634a99f40 Refresh 2022-07-05 13:24:28 +02:00
Samuele Locatelli 776d86e543 SIM: allineato a decoder 2022-07-05 13:24:17 +02:00
Samuele Locatelli fc17120a30 Test gestione conf x OPC-UA 2022-07-05 13:23:34 +02:00
Samuele Locatelli 5dc28c4dcc Fix conf adapter 2022-07-05 13:23:11 +02:00
Samuele Locatelli 27fd5f1759 pulizia conf inutilizzate 2022-07-05 13:22:34 +02:00
Samuele Locatelli 77092c9f90 Refresh 2022-07-01 17:44:06 +02:00
Samuele Locatelli 126abfc945 OK test differenza tempi calcolo LUA / C# 2022-06-25 07:18:04 +02:00
Samuele Locatelli a4abf98adb INserito calcolo LUA + test velocità esecuzione in ticks (to review...) 2022-06-24 19:18:32 +02:00
Samuele Locatelli 490d6e2dfc Update x integrazione LUA script x calcolo stato 2022-06-24 17:03:50 +02:00
Samuele Locatelli c326761960 Compeltato setup x test locale con LUA nuovi flussi 2022-06-24 12:04:42 +02:00
Samuele Locatelli 424fc11fc1 Update SIM
- generazione dati x stato
- dati x contatori
2022-06-24 11:55:12 +02:00
Samuele Locatelli 72fb70093d Modifica SIM x dati MPCOunt come ora 2022-06-24 11:16:06 +02:00
Samuele E. Locatelli d483f23d4f Update x check valore soglia in % periodo previsto 2022-06-23 18:07:12 +02:00
Samuele E. Locatelli 37305a5ea8 Afgiunta dev notes richeiste Jeldwen 2022-06-23 16:14:15 +02:00
Samuele E. Locatelli 87b159b167 update decodifica status
- errore in decodifica prog name (stringa)
2022-06-23 14:42:08 +02:00
Samuele E. Locatelli 4f4eafd5a2 Test in produzione
- fix lettura part program
- fix timing avvio e veto send dati
- fix config vari
2022-06-23 14:27:53 +02:00
Samuele Locatelli fd9df11711 Rapid hotfix x parametri 2022-06-23 08:06:25 +02:00
Samuele Locatelli 275061adb6 Merge tag 'MainRedisUpdate' into develop
Rimappatura generale aree memoria + gestione decoder x stati macchina
2022-06-22 17:18:07 +02:00
Samuele Locatelli c77f7fa185 Merge branch 'release/MainRedisUpdate' 2022-06-22 17:17:49 +02:00
Samuele Locatelli 23524c902c RImappatura generale memorie APPS 2022-06-22 17:17:28 +02:00
Samuele Locatelli d958358e05 Ottimizzazione scrittura veto cache redis 2022-06-22 15:03:33 +02:00
Samuele Locatelli 2f4c072d8f - ancora ottimizzaizone log 2022-06-22 14:51:48 +02:00
Samuele Locatelli fce7996f7c - Update x gestione counters 2022-06-22 14:21:12 +02:00
Samuele Locatelli daf686b39d pulizia log 2022-06-22 13:47:00 +02:00
Samuele Locatelli 96fcdcd150 Aggiunti step log x decoder OPC 2022-06-22 13:01:44 +02:00
Samuele Locatelli 31ba7eee6c Update conf parametri e tools x multiax 2022-06-22 12:01:34 +02:00
Samuele Locatelli 1bac8b33e0 Update Adapter
- conf dati raw status
- conf dati raw contatori (sono duplicati...)
2022-06-22 11:05:11 +02:00
Samuele Locatelli 97529ee444 Fix reset mute allarmi 2022-06-21 14:51:01 +02:00
Samuele Locatelli 7317c5d39c Merge tag 'FixSimAlarmAndVersion' into develop
Fix gestione versioni + SIM + Adapter x allarmi
2022-06-21 14:32:57 +02:00
Samuele Locatelli cf161344a6 Merge branch 'release/FixSimAlarmAndVersion' 2022-06-21 14:32:47 +02:00
Samuele Locatelli d27dbbeb07 Fix gestione e display versione 2022-06-21 14:31:49 +02:00
Samuele Locatelli fc36b427c4 Update x conflitto allarmi SIM/ADAPTER
- fix alalrmi vuoti
- fix abilitazione SIM se no allarmi da simulare
- fix conf redis allarmi
2022-06-21 14:15:01 +02:00
Samuele Locatelli 4dc2eb96ba Fix conf adapter x test Multiax 2022-06-21 11:22:51 +02:00
Samuele Locatelli f84fca1bc9 Refresh generale 2022-06-20 20:50:25 +02:00
Samuele Locatelli 8927378fdf Update adapter x gestione allarmi come Multiax 2022-06-20 20:50:21 +02:00
Samuele Locatelli f96ba8388b Fix pagina allarmi:
- richiesta pwd priam di fare setup
- fix comportamento
- fix salvataggio setup con filtro display
2022-06-20 16:27:41 +02:00
Samuele Locatelli eeb48a40a9 Merge tag 'FixFiltrAlarmsRawList' into develop
Sistemazione gestioen SIM/DECODER con allarmi filtrati
2022-06-20 15:52:36 +02:00
Samuele Locatelli c401c15932 Merge branch 'release/FixFiltrAlarmsRawList' 2022-06-20 15:52:23 +02:00
Samuele Locatelli 41d6f4153a Anzora correzione pubxml + zip 2022-06-20 15:43:04 +02:00
Samuele Locatelli 43c3fe4582 Fix conf x deploy CI/CD 2022-06-20 15:33:21 +02:00
Samuele Locatelli 29c691d81c Fix yaml x upload debug 2022-06-20 15:26:32 +02:00
Samuele Locatelli a750cb9687 Anzora fix install 2022-06-20 15:19:16 +02:00
Samuele Locatelli d459f4c5c0 Fix vari x generare gli installer
- fix yaml
- fix zip artifacts
- fix pubxml
2022-06-20 15:19:07 +02:00
Samuele Locatelli e085328da8 Fix modalità decoder allarmi 2022-06-20 12:08:13 +02:00
Samuele Locatelli 67ff5e7b34 Update decoder x allarmi muted 2022-06-20 11:44:13 +02:00
Samuele Locatelli a3366188fc Setup allarmi:
- OK reset
- OK ricerca
2022-06-20 11:13:46 +02:00
Samuele Locatelli 80958607ab Update sim:
- include tutti e 16 gli allarmi (fix errore sim)
2022-06-20 10:02:46 +02:00
Samuele Locatelli bfee15d1af Setup allarmi:
- abbozzata selezione modulo setup da alarmMode
2022-06-19 20:22:30 +02:00
Samuele Locatelli 74250d1333 Fix SIM x allarmi 2022-06-19 19:58:02 +02:00
Samuele Locatelli 749d633704 Update decoder
- gestione nuovo tipo di allarmi
- db doppia registrazione
2022-06-19 19:16:09 +02:00
Samuele Locatelli 9c424aa40c Modifica SIM
- nuova modalità allarmi RawList attivata
- installo su SIM x sviluppare DECODER nuovo
2022-06-19 17:07:27 +02:00
Samuele Locatelli cb8a707304 Gestione allarmi
- aggiunta differenziazione modalità BankBit (attuale) + RawList
- aggiunte tab anagrafica allarmi + rec x singolo evento/stato
- aggiunta migration DB x nuove tab
2022-06-19 15:25:33 +02:00
Samuele Locatelli abf74fb2f5 Reorg codice DbController 2022-06-19 14:39:06 +02:00
Samuele Locatelli bd93e43550 Update manutenzioni controlalto da eventi maintenance + veto da conf 2022-06-19 14:38:50 +02:00
Samuele Locatelli bdeb392a81 renaming sched --> pending x PM
- aggiunta migrazione
- test online
2022-06-19 12:29:06 +02:00
Samuele Locatelli 26dfd637cb Completati test edit/create user task 2022-06-19 12:21:09 +02:00
Samuele Locatelli eacac2a1e6 Completata gestione modifica PMTask
- add new
- edit
- delete/disable (secondo stato)
- re-enable
2022-06-19 11:09:38 +02:00
Samuele Locatelli 66c83abd01 Abbozzato(da provare) delete PMTask 2022-06-18 12:29:30 +02:00
Samuele Locatelli c38551d72c refresh e parziale costruzione delete 2022-06-18 12:17:58 +02:00
Samuele Locatelli 89619d9152 Completata migration + fix SQL x interventi PM 2022-06-18 10:29:08 +02:00
Samuele Locatelli f710080d5d Aggiunta migrazione x interventi protetti (manufacturer) 2022-06-18 10:26:34 +02:00
Samuele Locatelli b9e05634dd Ok Update 2022-06-17 20:09:46 +02:00
Samuele Locatelli a537e28609 OK aggiunta task... 2022-06-17 20:05:17 +02:00
Samuele Locatelli a07c21516e OK button edit 2022-06-17 19:54:35 +02:00
Samuele Locatelli 0bf60e8ac2 Ancora updat eprocesso edit PMTask 2022-06-17 19:49:27 +02:00
Samuele Locatelli 3c3cb0611f Bozza edit manutenzioni preventive 2022-06-17 19:23:55 +02:00
Samuele Locatelli 3783dd519f Update x gestione log parametrico avanzato 2022-06-17 18:02:57 +02:00
Samuele Locatelli 0a097daa7c Merge tag 'RefreshAllProj' into develop
Update progetti
2022-06-17 17:01:34 +02:00
Samuele Locatelli aeddb6af98 Merge branch 'release/RefreshAllProj' 2022-06-17 17:01:11 +02:00
Samuele Locatelli 973e0f63e9 Update progetto x nuove librerie da testare in Multiax 2022-06-17 16:59:34 +02:00
Samuele Locatelli bfedbd6c9d Update SIM e UI x nascondere dati in home se non configurati 2022-06-17 09:11:10 +02:00
Samuele Locatelli 4964854038 Modifica conf pulizia dati in ingresso x server OSAI con caratteri in eccesso (da testare) 2022-06-17 09:03:45 +02:00
Samuele Locatelli cbf778217b Update spaziatura progressbar 2022-06-16 19:48:53 +02:00
Samuele Locatelli 1c0b9b510f Ancora udpate adapter post demo 2022-06-16 19:47:47 +02:00
Samuele Locatelli 7600ee8563 Completo review ADAPTER post demo 2022-06-16 19:47:38 +02:00
Samuele Locatelli 3503f01d82 Update gitlab con stages x ADAPTER.OPC 2022-06-16 15:09:21 +02:00
Samuele Locatelli ace5b46440 Merge tag 'FirstReleaseAdapter' into develop
Prima versione adapter con filtraggio caratteri no ammessi
2022-06-16 15:07:03 +02:00
Samuele Locatelli 71e9e450c5 Merge branch 'release/FirstReleaseAdapter' 2022-06-16 15:06:37 +02:00
Samuele Locatelli c2274329cc Update x filtraggio char con regexp 2022-06-16 15:06:14 +02:00
Samuele Locatelli ed8d3b2a34 Update adapter:
- aggiunta gestione (BOZZA) tools %
2022-06-16 11:10:04 +02:00
Samuele Locatelli 6f01d4232b OK test OPC-UA --> ActLog 2022-06-16 10:36:46 +02:00
Samuele Locatelli ebabae204b Update SIM:
- blocco simulazione vuota se non ho conf con parametri da simulare
- update test x OPC-UA --> invio
2022-06-16 10:15:41 +02:00
Samuele Locatelli bbfad99ebc Update adapter OPC-UA
- gestita conf actLog
- legge davvero da OPC-UA
- invia ACT LOG!!!!
2022-06-15 19:47:52 +02:00
Samuele Locatelli 43ba19468f Fix ciclo main:
- ok connessione/disconnessione da ctrl-c
- mostra eventi (tutti)
- levare NLog?!?
2022-06-15 09:46:36 +02:00
Samuele Locatelli e878bcd4db Ancora update x adapter OPC UA 2022-06-14 19:31:53 +02:00
Samuele Locatelli 2fe6f46a85 Rimesso adapter in proj da Ref Client 2022-06-14 14:01:13 +02:00
Samuele Locatelli 03b618f64d Prima bozza:
- OPC UA ref client
- da "Bonifica" ed inserire nuget pack
2022-06-14 10:51:33 +02:00
Samuele Locatelli a623b4f2db Spostamento adapter in ADAPTER.OLD 2022-06-14 10:51:02 +02:00
Samuele Locatelli 9857de0f1a Modifiche preliminari IOB
- creazione adapter OPC-UA (da IOB-WIN-NEXT)
- setup primi step avvio
2022-06-13 19:17:18 +02:00
Samuele Locatelli c1f61a30c3 Modifiche oggetti core x creare adapter 2022-06-13 19:16:48 +02:00
Samuele Locatelli f660cccc6d refresh 2022-06-13 15:15:59 +02:00
Samuele Locatelli 2d7152d08b Fix componente task pending 2022-06-13 15:15:55 +02:00
Samuele Locatelli 0134e6ae09 Fix display margini 2022-06-13 15:14:49 +02:00
Samuele Locatelli 4308bf4b17 Merge tag 'AddLicenseAndMaintenance' into develop
Aggiunta gestione licenze + gestione manutenzioni (preliminare)
2022-06-13 11:47:08 +02:00
Samuele Locatelli 1748df69f4 Merge branch 'release/AddLicenseAndMaintenance' 2022-06-13 11:46:28 +02:00
Samuele Locatelli 609fe74da6 Refresh view maintenance 2022-06-13 11:45:57 +02:00
Samuele Locatelli 0dff589980 update nomi componenti + cambio modalità switch maintenance 2022-06-13 08:52:44 +02:00
Samuele Locatelli 865584761b Update icon button change mode 2022-06-11 19:18:25 +02:00
Samuele Locatelli c24af86f7e Update x modifica comportamneto testata maintenance 2022-06-11 19:16:29 +02:00
Samuele Locatelli fb36448455 Fix licenza WKS R9 2022-06-11 19:16:21 +02:00
Samuele E. Locatelli 0a2f92368c Update con test completamento task 2022-06-11 18:37:28 +02:00
Samuele E. Locatelli 7930ce273f - fix display dettagli solo se presenti
- fix col spacing
- aggiunta warng signal
2022-06-11 18:32:28 +02:00
Samuele E. Locatelli c9f768beb2 Aggiunta num task done + migrazione 2022-06-11 18:09:31 +02:00
Samuele E. Locatelli 6775bb5dfa - aggiunto tempo elasped x SMTask
- aggiunta migrazione DB
2022-06-11 17:09:45 +02:00
Samuele E. Locatelli 7c94aac352 - selezione history interventi (da completare) 2022-06-11 16:32:11 +02:00
Samuele E. Locatelli f6f7b18186 - update x mostrare interventi in scadenza
- aggiunta stored x recuperare interventi da parent schedulato
2022-06-11 16:20:32 +02:00
Samuele E. Locatelli fcbd718a17 Update file lic x portatile 2022-06-11 16:19:52 +02:00
Samuele Locatelli 05c26f4e53 Fix selezione interventi nel periodo 2022-06-11 12:42:42 +02:00
Samuele Locatelli d798e91055 - corretta rigenerazione task 2022-06-11 12:24:18 +02:00
Samuele Locatelli dcbcecc435 - abbozzato gestione completamento task 2022-06-11 12:19:33 +02:00
Samuele Locatelli 58c27bedd6 Aggiunta progress bar valori scadenza remaining 2022-06-11 11:14:13 +02:00
Samuele Locatelli 46d6ae7ae2 - aggiunta valore start contatore x ogni SchedTask
- migration
- refresh
2022-06-11 10:57:11 +02:00
Samuele Locatelli 5586dcfede Avanzamento gestione manutenzione rpeventiva (NON completata...) 2022-06-10 19:45:22 +02:00
Samuele Locatelli 010ca67d6e Aggiunta task schedulati 2022-06-10 18:03:24 +02:00
Samuele Locatelli 0ac05c7e70 - refresh generale 2022-06-10 17:59:47 +02:00
Samuele Locatelli a45b93a177 - Aggiunta task schedMigrations
- Aggiunta info x SIM
2022-06-10 17:59:41 +02:00
Samuele Locatelli 651a83b8ea Aggiunta bozza display MaintTask 2022-06-10 15:24:03 +02:00
Samuele Locatelli 2c7ffaeb04 Aggiornamento tab topic maint 2022-06-10 14:07:19 +02:00
Samuele Locatelli eec7e04588 Aggiunta sql x caricamento manuale tab manutenzioni 2022-06-10 14:06:25 +02:00
Samuele Locatelli 252b780d15 Refresh e test! 2022-06-10 13:43:14 +02:00
Samuele Locatelli 748e5a9062 Aggiunta migrazioni 2022-06-10 13:43:10 +02:00
Samuele Locatelli 1d2ee6dda5 Ancora udpate modello dati (da completare con migrations) 2022-06-10 11:47:55 +02:00
Samuele Locatelli 7539af9d97 refresh generale 2022-06-10 11:35:33 +02:00
Samuele Locatelli ab335bc203 Aggiunto altre origini dati... 2022-06-10 11:35:26 +02:00
Samuele Locatelli 4a886d0ad5 refresh enum 2022-06-10 11:17:42 +02:00
Samuele Locatelli 53c315b9ba Inizio modellazione manutenzione rpeventiva 2022-06-10 11:17:33 +02:00
Samuele Locatelli 3b29876ee6 Merge tag 'UpdateKeyGenProcess' into develop
Aggiornamento proicesso keygen
2022-06-08 19:13:42 +02:00
Samuele Locatelli 2da7b0622e Merge branch 'release/UpdateKeyGenProcess' 2022-06-08 19:13:31 +02:00
Samuele Locatelli 4b975290f5 refresh yaml 2022-06-08 19:13:15 +02:00
Samuele Locatelli 987efafd7a Refresh KeyGen process 2022-06-08 19:12:44 +02:00
Samuele Locatelli 18efe25a9b update verbosità e script obfuscar come exe 2022-06-08 18:32:14 +02:00
Samuele Locatelli 609241bc6c update verbosity check 2022-06-08 18:29:02 +02:00
Samuele Locatelli 1f8c8bd542 Aggiunta quiet x debug 2022-06-08 18:25:55 +02:00
Samuele Locatelli 7fd47cf51b update yaml x obfuscar 2022-06-08 18:23:26 +02:00
Samuele Locatelli b8f7e06e2b fix zipper x tipo release/debug 2022-06-08 17:17:46 +02:00
Samuele Locatelli c0f73e1e9e update yaml x parametrizzare build 2022-06-08 17:15:30 +02:00
Samuele Locatelli cfff0b66a8 Aggiornato task x obfuscate MP.MONO.UI 2022-06-08 16:53:56 +02:00
Samuele Locatelli 6bc6938e56 Correzione post-build ps1 x obfuscar script 2022-06-08 16:44:15 +02:00
Samuele Locatelli 8e90c2f21f Typo fix path Release(s) 2022-06-08 16:21:45 +02:00
Samuele Locatelli c058408420 Fix sintassi zipper x SIM/DECODER 2022-06-08 16:19:37 +02:00
Samuele Locatelli f0ff191393 Pubblicazione SIM/DECODER anche in develop/unstable 2022-06-08 16:15:10 +02:00
Samuele Locatelli 3775aacc4d Fix sintassi robocopy file da spostare 2022-06-08 16:08:53 +02:00
Samuele Locatelli 43c1d8c233 cambio yaml x preparare file UI x pubblicazione 2022-06-08 15:53:54 +02:00
Samuele Locatelli 02e93e0d4e refresh vari 2022-06-08 15:14:06 +02:00
Samuele Locatelli dac29e3b38 rename DataValidator --> MachineDataValidator 2022-06-08 15:13:58 +02:00
Samuele Locatelli 949614aa18 Aggiunto step salvataggio file fingerprint + save dati licenza 2022-06-08 09:43:57 +02:00
Samuele Locatelli e7654f3ed4 Inserito step crittografico + update file licenza + pèassaggio MD5 a sha512 2022-06-07 20:38:50 +02:00
Samuele Locatelli db0ab39ff5 COmpletata bozza verifica LIC e hash calcolata (SENZA cifra...) 2022-06-07 19:51:11 +02:00
Samuele Locatelli 4988f3db7f cleanup generale 2022-06-07 18:36:54 +02:00
Samuele Locatelli 6082c859d1 Aggiunta export log x conf json macchina 2022-06-07 18:36:45 +02:00
Samuele Locatelli 223389b594 Aggiunta watermark 2022-06-07 18:36:24 +02:00
Samuele Locatelli 038ffd15ad Eliminata fase zip x upload su nexus degli zip pubblicati 2022-06-07 18:36:15 +02:00
Samuele Locatelli 5cdd5357a7 Ancora update gitignore 2022-06-07 18:35:53 +02:00
Samuele Locatelli 6591b1da85 udpate gitignore x json export info in log 2022-06-07 18:34:40 +02:00
Samuele Locatelli 5b6f9af4f1 Aggiunta publishProfile corretto + refresh 2022-06-07 16:19:11 +02:00
Samuele Locatelli 2158a460de update yaml deploy 2022-06-07 16:08:00 +02:00
Samuele Locatelli a50741f567 Altro test compilazione 2022-06-07 16:06:43 +02:00
Samuele Locatelli 869d5fc1fb update check tipo versione 2022-06-07 16:05:09 +02:00
Samuele Locatelli a42a312967 Update x compilazione versione UI da provare in debug 2022-06-07 16:04:06 +02:00
Samuele Locatelli 0de0388664 Merge tag 'TestObfusc' into develop
Completato primo test obfuscator
2022-06-07 15:12:43 +02:00
Samuele Locatelli 35c896dd48 Merge branch 'release/TestObfusc' 2022-06-07 15:12:26 +02:00
Samuele Locatelli 0e99c169b3 Test nuova conf 2022-06-07 15:12:02 +02:00
Samuele Locatelli 8ed41a21b4 Refresh testing obfuscatore 2022-06-07 14:22:35 +02:00
Samuele Locatelli 56d0f7152d Refresh x test locale obfuscar 2022-06-07 13:19:30 +02:00
Samuele Locatelli 7033420c8c refresh 2022-06-07 12:53:16 +02:00
Samuele Locatelli 7f66ab097d Aggiunto script x offuscamento (da includere in yaml + testare) 2022-06-07 12:53:13 +02:00
Samuele Locatelli 4e4ec6980d refresh resources varie 2022-06-07 12:45:58 +02:00
Samuele Locatelli d941a7eddf Aggiunta nuovi metodi info macchina + display 2022-06-07 12:37:09 +02:00
Samuele Locatelli ae9cc2c429 Inizio aggiunto pag Hw Info x gestione licenze 2022-06-06 19:36:24 +02:00
Samuele Locatelli 1b4e7a9e8b Aggiunta vbers number su progetti + resources su analyzer 2022-04-28 18:45:15 +02:00
Samuele Locatelli 0474778424 Merge tag 'UpdateYamlForSimDecoder' into develop
update vari componente SIM/DECODER
2022-04-28 18:39:59 +02:00
Samuele Locatelli 2477afe3bd Merge branch 'release/UpdateYamlForSimDecoder' 2022-04-28 18:39:48 +02:00
Samuele Locatelli 9fc2d86bf4 Aggiunto ps1 su .UI 2022-04-28 18:38:23 +02:00
Samuele Locatelli 80f1ac2e04 Update altri file x deploy yaml 2022-04-28 18:36:05 +02:00
Samuele Locatelli 949a513d05 Update yaml file 2022-04-28 18:35:59 +02:00
Samuele Locatelli 29c09ccb6f Aggiunta postBUild.ps1 + MajMinVers.txt 2022-04-28 18:33:15 +02:00
Samuele Locatelli 1c4b1f4a3e spostamento folder resources + fix conf 2022-04-28 18:32:54 +02:00
Samuele Locatelli 27cfbcccc7 Merge tag 'FixIis01DeployAndResourcesFolder' into develop
Aggiunta relòease folder
2022-04-28 17:40:18 +02:00
Samuele Locatelli e67bb0e765 Merge branch 'release/FixIis01DeployAndResourcesFolder' 2022-04-28 17:40:13 +02:00
Samuele Locatelli abceb4e187 Refresh changelog and manifest 2022-04-28 17:40:01 +02:00
Samuele Locatelli 3b410f3908 Refresh iis01 pubxml 2022-04-28 17:37:13 +02:00
Samuele Locatelli b9a69a55d2 Add resource folder 2022-04-28 17:35:15 +02:00
Samuele Locatelli 80864f2b35 Merge branch 'main' into develop 2022-04-28 17:29:53 +02:00
Samuele Locatelli 03f811de57 Revisione display 2022-04-28 17:29:41 +02:00
Samuele Locatelli 857b14e3ae REVISIONE PARAMS OVERVIEW 2022-04-28 17:29:36 +02:00
Samuele Locatelli 65888b1fcd Modifica DECODER x evitare (si spera) scritture vuote dei parametri... 2022-03-24 19:48:07 +01:00
Samuele Locatelli 88c7ee46df Merge tag 'UpdateParFromDb' into develop
Update gestione parametri da live pipe / DB in reload
2022-03-24 19:34:16 +01:00
Samuele Locatelli cbafcfe65d Merge branch 'release/UpdateParFromDb' 2022-03-24 19:34:02 +01:00
Samuele Locatelli 52dc369992 Update grafico selezione parametri/periodo... 2022-03-24 19:32:37 +01:00
Samuele Locatelli 6fc0855626 Update comportamento grafico live / hist log 2022-03-24 19:17:41 +01:00
Samuele Locatelli ed573897d6 Ok passaggio da dati RT a hist su DB 2022-03-24 18:48:52 +01:00
Samuele Locatelli ba845fa78c Cleanup codice parametri 2022-03-24 17:39:33 +01:00
Samuele Locatelli 44dc85c08b Aggiunto comportamento TOGGLE selezione parametri 2022-03-24 17:38:17 +01:00
Samuele Locatelli 0e23351b7c Inizio fix gestione plot parametri RT vs HIST di Log 2022-03-24 17:31:56 +01:00
Samuele Locatelli 78b897ce67 Fix gestione componente display interno 2022-03-24 16:56:56 +01:00
Samuele Locatelli 694d4cb0b5 refresh parametri 2022-03-24 16:56:50 +01:00
Samuele Locatelli 3c3156ed9f Merge branch 'Componente-DetailOverview' into develop 2022-03-24 16:45:22 +01:00
marco.salvi 5d9f0e59df Componente detailOverview 2022-03-24 16:46:52 +01:00
Samuele Locatelli 23d5ebe83b Inizio gestione parametri RT / LogView 2022-03-24 16:43:09 +01:00
Samuele Locatelli 8a0f445b39 update gestione LUA x parametri e allarmi (diminuito LOG info --> trace) 2022-03-24 16:26:37 +01:00
Samuele Locatelli a48e444fe2 Fix gestione allarmi + parametri 2022-03-24 14:57:19 +01:00
Samuele Locatelli 4bfe039623 Update x gestione parametri con calcolo vario... 2022-03-23 20:07:29 +01:00
Samuele Locatelli 195f187ba8 Fix decodificatore lua x variabili calcolate (test in LUA) 2022-03-23 20:07:26 +01:00
Samuele Locatelli 3cebac853b update decoder x gestione decodifica preliminare parametri (manca DB) 2022-03-22 19:56:00 +01:00
Samuele Locatelli 42f01f14af update conf SIM x simulazione parametri 2022-03-22 19:55:47 +01:00
Samuele Locatelli 4e882ea3cb update conf code e aree REDIS salvataggio dati 2022-03-22 19:55:26 +01:00
Samuele Locatelli 3afe990365 cambio logica gestione display multi parameters 2022-03-22 19:54:26 +01:00
Samuele Locatelli 2ffa502538 modifica SIM x nuova gestione parametri (solo valore poi DECODER) 2022-03-21 19:24:53 +01:00
Samuele Locatelli 7e941aec34 conf costanti x allarmi/parametri gestiti 2022-03-21 19:24:44 +01:00
Samuele Locatelli e7c73cbce1 Inizio classe x gestione parametri come allarmi 2022-03-21 19:24:30 +01:00
Samuele Locatelli 6a8ad2604f Nuova modalità setup conf anche x SIM con metodi CORE 2022-03-21 18:51:26 +01:00
Samuele Locatelli a87fee41f5 Riordino lua script x DECODER 2022-03-21 18:51:03 +01:00
Samuele Locatelli 67c8e883fe pulizia conf non usati x DECODER 2022-03-21 18:50:46 +01:00
Samuele Locatelli 37ee6f5997 Modifica adapter x gestione config dei parametri da CORE 2022-03-21 18:50:33 +01:00
Samuele Locatelli 4f0e2d9aa5 Aggiunta classe e metodi gestione config in CORE 2022-03-21 18:50:22 +01:00
Samuele Locatelli ccd3ed8c45 Update layout generale pagine 2022-03-21 16:45:55 +01:00
Samuele Locatelli cbf72f2558 Allarmi: effettua sempre salvataggio su REDIS 2022-03-21 16:41:37 +01:00
Samuele Locatelli d41722f200 Fix decodifica allarmi ALL OK 2022-03-21 12:02:24 +01:00
Samuele Locatelli be7515b16c Merge tag 'FixDecoderAllarmi' into develop
Fix decoder x gestione allarmi
2022-03-21 10:29:03 +01:00
Samuele Locatelli 89fd608eef Merge branch 'release/FixDecoderAllarmi' 2022-03-21 10:28:45 +01:00
Samuele Locatelli cf310ab003 Aggiornamento gestioen DECODER x allarmi e check variazioni 2022-03-21 09:14:01 +01:00
Samuele Locatelli 5177f412de Update script LUA 2022-03-21 09:13:53 +01:00
Samuele Locatelli ccbb6fa644 Update gestione SIM e DECODER x allarmi (NON ancora OK) 2022-03-19 16:33:51 +01:00
Samuele Locatelli dd3491af16 Update formato pubblicazione allarmi da SIM: memAddr + valore 2022-03-19 11:40:34 +01:00
Samuele Locatelli 1403daffd6 Update SIM x gestione allarmi in BANK 2022-03-19 11:12:02 +01:00
Samuele Locatelli 1a9f6c810b Ok gestione allarmi configurati da setup iniziale redis su seconda area memoria 2022-03-19 10:54:49 +01:00
Samuele Locatelli a4841dd8bc OK mute/unmute via redis 2022-03-18 18:37:58 +01:00
Samuele Locatelli 76d25bc727 Inizio setup pagina dettaglio allarmi cons etup attivi/silenziati 2022-03-18 17:23:01 +01:00
Samuele Locatelli 1472c178b1 Update sim x alarm conf (da gestire) 2022-03-18 17:22:48 +01:00
Samuele Locatelli 731d8c6400 Aggiunta classe base gestione allarmi in CORE 2022-03-18 17:22:35 +01:00
Samuele Locatelli 998afbbd7e Abbozzato adapter con gestione lettura conf completa 2022-03-18 17:22:24 +01:00
Samuele Locatelli d2c0761f7b Fix warnings vari e semplificazione classe DB 2022-03-18 09:52:57 +01:00
Samuele Locatelli f2b24aa3ea Fix conf yaml 2022-03-18 09:38:24 +01:00
Samuele Locatelli 7023ef1609 Aggiunti step zip/upload 2022-03-18 09:37:06 +01:00
Samuele Locatelli 19cfeff468 Aggiunta step SIM/DECODER x release 2022-03-18 09:33:21 +01:00
Samuele Locatelli aa0f847aa3 altra opzione x pwd 2022-03-18 08:57:18 +01:00
Samuele Locatelli 0f32dc64bd cambio chaive x password 2022-03-18 08:55:59 +01:00
Samuele Locatelli 699e07e61f test alternative restore pack 2022-03-18 08:51:56 +01:00
Samuele Locatelli 9edb343d40 fix deploy IIS01/02/03 2022-03-18 08:24:38 +01:00
Samuele Locatelli 3a6dc1b08e Update yaml x nexus https 2022-03-18 08:22:39 +01:00
Samuele Locatelli 913d148545 Fix pagina visualizzazione allarmi 2022-03-18 08:13:05 +01:00
Samuele Locatelli 4ff531e435 update script x proxy nuget in dotnet publish 2022-03-18 08:12:43 +01:00
Samuele Locatelli 8eed5081c9 Merge tag 'UpdateAlarms' into develop
Update pagina Allarmi
2022-03-17 18:07:04 +01:00
Samuele Locatelli 5b40dd70f1 Merge branch 'release/UpdateAlarms' 2022-03-17 18:06:18 +01:00
Samuele Locatelli f2f733e6ee Ancora update pagina allarmi 2022-03-17 18:05:22 +01:00
Samuele Locatelli 7173e6e90a fix align e formattazione allarmi 2022-03-17 18:03:20 +01:00
Samuele Locatelli afda7d6221 Merge tag 'AutoRefreshAlarms' into develop
Auto refresh area allarmi
2022-03-17 15:24:29 +01:00
Samuele Locatelli 5587e9efca Merge branch 'release/AutoRefreshAlarms' 2022-03-17 15:24:21 +01:00
Samuele Locatelli 83634c7788 Update x autorefresh da DB degli ultimi allarmi 2022-03-17 15:23:59 +01:00
Samuele Locatelli e3c7cb356c Sistemato decoder: ora finalmente scrive sul DB... 2022-03-17 15:09:58 +01:00
Samuele Locatelli dfb2dd4c5c Merge branch 'feature/LuaPreliminaryTest' into develop 2022-03-17 13:14:05 +01:00
Samuele Locatelli 8e2a9634d1 Merge branch 'feature/LuaPreliminaryTest' into develop 2022-03-17 12:32:41 +01:00
Samuele Locatelli 06cd6ffa05 Merge branch 'develop' of https://gitlab.steamware.net/egalware/mapo-mono into develop 2022-03-16 16:21:33 +01:00
410 changed files with 60501 additions and 3674 deletions
+7 -8
View File
@@ -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
View File
@@ -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
+9
View File
@@ -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
View File
@@ -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:
- ![#3498DB](https://placehold.co/15x15/3498DB/3498DB.png) `Creato`
- ![#3949AB](https://placehold.co/15x15/3949AB/3949AB.png) `Avviato`
- ![#8E24AA](https://placehold.co/15x15/8E24AA/8E24AA.png) `In Esecuzione`
- ![#2ECC71](https://placehold.co/15x15/2ECC71/2ECC71.png) `Completato`
Inoltre si possono avere colori x la "prossimità a scedenza" temporale
- (verde) `Scadenza tra xxxx`
- ![#F1C40F](https://placehold.co/15x15/F1C40F/F1C40F.png) `Prossimo alla scadenza`
- ![#C0392B](https://placehold.co/15x15/C0392B/C0392B.png) `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|
+31
View File
@@ -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
+631
View File
@@ -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>
+291
View File
@@ -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.* &rarr;</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">&copy; 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.* &rarr;</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">&copy; 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>
+991
View File
@@ -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
}
}
+47
View File
@@ -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
}
+52
View File
@@ -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"
]
}
]
+129
View File
@@ -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
}
}
}
+125
View File
@@ -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"
}
]
+32
View File
@@ -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
+25
View File
@@ -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
+38
View File
@@ -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": []
}
]
+26
View File
@@ -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
}
]
+194
View File
@@ -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
}
]
+114
View File
@@ -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"
}
]
+96
View File
@@ -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
}
]
+110
View File
@@ -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>
+175
View File
@@ -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"
}
]
+387
View File
@@ -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"
}
]
+100
View File
@@ -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"
}
]
+26
View File
@@ -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
}
]
+194
View File
@@ -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
}
]
+194
View File
@@ -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
}
]
+380
View File
@@ -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;
}
}
}
+759
View File
@@ -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>
+29
View File
@@ -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>
+78
View File
@@ -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
}
}
+233
View File
@@ -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.* &rarr;</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">&copy; 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.* &rarr;</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">&copy; 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>
+940
View File
@@ -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
}
}
+488
View File
@@ -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);
}
}
}
}
+74
View File
@@ -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
}
+3
View File
@@ -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 @@

+1
View File
@@ -0,0 +1 @@

+1
View File
@@ -0,0 +1 @@

+1
View File
@@ -0,0 +1 @@

Binary file not shown.
+14
View File
@@ -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
+7 -4
View File
@@ -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.* &rarr;</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">&copy; Egalware 2006-2022</a>
</div>
</div>
</body>
+26
View File
@@ -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.* &rarr;</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">&copy; Egalware 2006-2022</a>
</div>
</div>
</body>
+1
View File
@@ -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>
+7
View File
@@ -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>
+32
View File
@@ -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
+253
View File
@@ -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
}
}
+34
View File
@@ -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
}
}
+80
View File
@@ -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 --&gt; armata
/// = 1 / triggered = 0 False --&gt; triggered = 1 / armata = 0
/// </summary>
public bool emergencyArmedTrue { get; set; } = true;
/// <summary>
/// Elenco items FILTRATI da invio come dynData --&gt; 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
}
}
+17
View File
@@ -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;
}
}
+52
View File
@@ -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
}
}
+35
View File
@@ -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
}
}
+188
View File
@@ -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
}
}
+323
View File
@@ -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
}
}
+55 -8
View File
@@ -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
}
+25
View File
@@ -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;
}
}
+64
View File
@@ -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;
}
}
+29
View File
@@ -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
View File
@@ -4,6 +4,65 @@
{
#region Public Enums
/// <summary>
/// Modalità verifica condizioni booleane
/// </summary>
public enum boolCheckMode
{
/// <summary>
/// AND: tutte vere -&gt; 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
+13
View File
@@ -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}}")]
+5 -1
View File
@@ -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>
+203
View File
@@ -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
}
}
+309
View File
@@ -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
}
}
+84
View File
@@ -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