diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 992f2e5..1428700 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -165,6 +165,19 @@ stages: # -------------------------------- # BUILD # -------------------------------- +EgwConf.Iob:build: + stage: build + tags: + - win + variables: + APP_NAME: EgwConf.Iob + before_script: + - *nuget-fix + - '& "$env:NUGET_PATH" restore "$env:APP_NAME.sln" -verbosity quiet' + - *version-fix + script: + - '& "$env:MSBUILD_PATH" "$env:APP_NAME\$env:APP_NAME.csproj" -target:Build /p:Configuration=Release /p:Platform="x86" /p:OutputPath=bin/ /nodeReuse:false /verbosity:minimal /m' + EgwProxy.Ftp:build: stage: build tags: @@ -256,10 +269,37 @@ EgwProxy.SqlDb:build: script: - '& "$env:MSBUILD_PATH" "$env:APP_NAME\$env:APP_NAME.csproj" -target:Build /p:Configuration=Release /p:Platform="x86" /p:OutputPath=bin/ /nodeReuse:false /verbosity:minimal /m' - # -------------------------------- # STAGING: (nuget beta) # -------------------------------- +EgwConf.Iob:staging: + stage: staging + needs: ["EgwConf.Iob:build"] + tags: + - win + variables: + CONFIG: Debug + APP_NAME: EgwConf.Iob + # rules: + # - if: $CI_COMMIT_BRANCH == 'develop' + # changes: + # - EgwConf.Iob/* + # when: always + # - if: $CI_COMMIT_BRANCH == 'SDK/Conf' + # changes: + # - EgwConf.Iob/* + before_script: + - *nuget-fix + - '& "$env:NUGET_PATH" restore "$env:APP_NAME.sln" -verbosity quiet' + - *version-fix + - *nuspec-fix + script: + - '& "$env:MSBUILD_PATH" "$env:APP_NAME\$env:APP_NAME.csproj" -target:Build /p:Configuration=$env:CONFIG /p:Platform="Any CPU" /p:OutputPath=bin/$env:CONFIG /verbosity:minimal /m' + - '& Remove-Item *.nupkg' + - '& $env:NUGET_PATH pack "$env:APP_NAME.Debug.nuspec"' + - '& "$env:NUGET_PATH" setapikey $NUGET_API_KEY -source http://nexus.steamware.net/repository/nuget-hosted' + - '& "$env:NUGET_PATH" push *$env:NUM_DEB.nupkg -Source http://nexus.steamware.net/repository/nuget-hosted' + EgwProxy.Ftp:staging: stage: staging needs: ["EgwProxy.Ftp:build"] @@ -459,6 +499,31 @@ EgwProxy.SqlDb:staging: # -------------------------------- # RELEASE # -------------------------------- +EgwConf.Iob:build:release: + stage: release + needs: ["EgwConf.Iob:build"] + tags: + - win + variables: + CONFIG: Release + APP_NAME: EgwConf.Iob + # rules: + # - if: $CI_COMMIT_BRANCH == 'main' + # changes: + # - EgwConf.Iob/* + # when: always + before_script: + - *nuget-fix + - '& "$env:NUGET_PATH" restore "$env:APP_NAME.sln" -verbosity quiet' + - *version-fix + - *nuspec-fix + script: + - '& "$env:MSBUILD_PATH" "$env:APP_NAME\$env:APP_NAME.csproj" -target:Build /p:Configuration=$env:CONFIG /p:Platform="Any CPU" /p:OutputPath=bin/$env:CONFIG /verbosity:minimal /m' + - '& Remove-Item *.nupkg' + - '& $env:NUGET_PATH pack "$env:APP_NAME.Release.nuspec"' + - '& "$env:NUGET_PATH" setapikey $NUGET_API_KEY -source http://nexus.steamware.net/repository/nuget-hosted' + - '& "$env:NUGET_PATH" push *$env:NUM_REL.nupkg -Source http://nexus.steamware.net/repository/nuget-hosted' + EgwProxy.Ftp:build:release: stage: release needs: ["EgwProxy.Ftp:build"] @@ -635,6 +700,26 @@ EgwProxy.SqlDb:build:release: # -------------------------------- # DocFx # -------------------------------- +EgwConf.Iob:docfx: + stage: docfx + needs: ["EgwConf.Iob:build"] + tags: + - win + variables: + APP_NAME: EgwConf.Iob + rules: + - if: $CI_COMMIT_BRANCH == 'main' + changes: + - EgwConf.Iob/* + when: always + before_script: + - *nuget-fix + - '& "$env:NUGET_PATH" restore "$env:APP_NAME.sln" -verbosity quiet' + script: + - docfx $env:APP_NAME/docfx.json + - mv $env:APP_NAME/_site "docfx" + - *DocReplica + EgwProxy.Ftp:docfx: stage: docfx needs: ["EgwProxy.Ftp:build"] diff --git a/EgwConf.Iob.Debug.nuspec b/EgwConf.Iob.Debug.nuspec new file mode 100644 index 0000000..8124496 --- /dev/null +++ b/EgwConf.Iob.Debug.nuspec @@ -0,0 +1,25 @@ + + + + EgwConf.Iob + #version# + EgwConf.Iob + Samuele E. Locatelli, EgalWare + false + MIT + Libreria per gestione configurazione in modalità *.ini (legacy) o *.yaml (nuova) dei singoli IOB-WIN-NEXT - beta/unstable + #releaseNotes# + #copyright# + EgwConf.Iob EgwConf Iob + + + + + + + + + + + + \ No newline at end of file diff --git a/EgwConf.Iob.Release.nuspec b/EgwConf.Iob.Release.nuspec new file mode 100644 index 0000000..3103b1e --- /dev/null +++ b/EgwConf.Iob.Release.nuspec @@ -0,0 +1,24 @@ + + + + EgwConf.Iob + #version# + EgwConf.Iob + Samuele E. Locatelli, EgalWare + false + MIT + Libreria per gestione configurazione in modalità *.ini (legacy) o *.yaml (nuova) dei singoli IOB-WIN-NEXT + #releaseNotes# + #copyright# + EgwConf.Iob EgwConf Iob + + + + + + + + + + + \ No newline at end of file diff --git a/EgwConf.Iob.sln b/EgwConf.Iob.sln new file mode 100644 index 0000000..d10092e --- /dev/null +++ b/EgwConf.Iob.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35527.113 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EgwConf.Iob", "EgwConf.Iob\EgwConf.Iob.csproj", "{26CD6258-206B-4FB4-B9FB-1C573C930919}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {26CD6258-206B-4FB4-B9FB-1C573C930919}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {26CD6258-206B-4FB4-B9FB-1C573C930919}.Debug|Any CPU.Build.0 = Debug|Any CPU + {26CD6258-206B-4FB4-B9FB-1C573C930919}.Release|Any CPU.ActiveCfg = Release|Any CPU + {26CD6258-206B-4FB4-B9FB-1C573C930919}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E2472E21-58D3-4EAD-BC4A-BC3915B18BEF} + EndGlobalSection +EndGlobal diff --git a/EgwConf.Iob/Base/CmdUriDto.cs b/EgwConf.Iob/Base/CmdUriDto.cs new file mode 100644 index 0000000..676f992 --- /dev/null +++ b/EgwConf.Iob/Base/CmdUriDto.cs @@ -0,0 +1,85 @@ +using System.Collections.Generic; +using System.Linq; + +namespace EgwConf.Iob.Base +{ + /// + /// Set comandi URI x chiamate server + /// + public class CmdUriDto + { + #region Public Constructors + + /// + /// Init classe gestione comandi + /// + /// + public CmdUriDto(string baseURI) + { + BaseUri = baseURI; + } + + #endregion Public Constructors + + #region Public Properties + + /// + /// comando base x USER LOG - salvataggio parametri extra sistema MAPO + /// + public string ULog { get; set; } = "IOB/ulog/"; + + /// + /// comando base x USER LOG - salvataggio parametri extra sistema MAPO in modalità JSON + /// payload come lista + /// + public string ULogJson { get; set; } = "IOB/ulogJson/"; + + #endregion Public Properties + + #region Public Methods + + /// + /// Recupera path/URI comando richiesto (SE disponibile) senno default + /// + /// + /// + public string GetCommand(string key) + { + // default ad implicito... + string answ = $"{BaseUri}/{key}/"; + if (CurrSetup.ContainsKey(key)) + { + answ = CurrSetup[key]; + } + return answ; + } + + public Dictionary StdCommands() + { + CurrSetup = new Dictionary(); + CurrSetup.Add("Alive", "IOB"); + CurrSetup.Add("Base", "IOB/input/"); + CurrSetup.Add("BaseJson", "IOB/evListJson/"); + CurrSetup.Add("RawTransfJson", "IOB/rawTransfJson/"); + CurrSetup.Add("Enabled", "IOB/enabled/"); + CurrSetup.Add("Flog", "IOB/flog/"); + CurrSetup.Add("FlogJson", "IOB/flogJson/"); + CurrSetup.Add("ForcleSplitOdl", "IOB/forceSplitOdlFull/"); + CurrSetup.Add("IdleTime", "IOB/getIdlePeriod/"); + CurrSetup.Add("OdlStarted", "IOB/getCurrOdlStart/"); + CurrSetup.Add("Reboot", "IOB/sendReboot.aspx?idxMacchina=/"); + // riordino + CurrSetup = CurrSetup.OrderBy(x => x.Key).ToDictionary(x => x.Key, x => x.Value); + return CurrSetup; + } + + #endregion Public Methods + + #region Protected Properties + + protected string BaseUri { get; set; } = "IOB"; + protected Dictionary CurrSetup { get; set; } = new Dictionary(); + + #endregion Protected Properties + } +} \ No newline at end of file diff --git a/EgwConf.Iob/Base/ConnectParamsDto.cs b/EgwConf.Iob/Base/ConnectParamsDto.cs new file mode 100644 index 0000000..59829e6 --- /dev/null +++ b/EgwConf.Iob/Base/ConnectParamsDto.cs @@ -0,0 +1,35 @@ +using EgwConf.Iob.Special; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EgwConf.Iob.Base +{ + /// + /// Definizione parametri Macchina / CN / PLC + /// + public class ConnectParamsDto + { + /// + /// Indirizzo Ip del CNC Controllato + /// + public string IpAddr { get; set; } = "127.0.0.1"; + + /// + /// Porta del CNC Controllato + /// + public string Port { get; set; } = "0"; + + /// + /// Timeout test PING + /// + public int pingMsTimeout { get; set; } = 500; + + /// + /// Configurazione specifica Siemens (se applicabile) + /// + public SiemensDto SiemensCpu { get; set; } + } +} diff --git a/EgwConf.Iob/Base/InputSignalDto.cs b/EgwConf.Iob/Base/InputSignalDto.cs new file mode 100644 index 0000000..ebcf426 --- /dev/null +++ b/EgwConf.Iob/Base/InputSignalDto.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EgwConf.Iob.Base +{ + /// + /// Configurazioni specifiche per segnali ingresso (tipicamente gestione blink) + /// + public class InputSignalDto + { + /// + /// Maschera di filtro blink, INT corrispondente ai BIT da filtrare, ad es + /// 11111111 = 255 + /// 00010110 = 22 + /// 00000111 = 7 + /// + public int BlinkFilterMask { get; set; } = 0; + + /// + /// Numero di cicli per cui effettuare il mascheramento dei valori (sul fronte di discesa) + /// + public int BlinkMaxCounter { get; set; } = 10; + + } +} diff --git a/EgwConf.Iob/Base/IobManDto.cs b/EgwConf.Iob/Base/IobManDto.cs new file mode 100644 index 0000000..d623e85 --- /dev/null +++ b/EgwConf.Iob/Base/IobManDto.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EgwConf.Iob.Base +{ + /// + /// Classe setup comunicazione server REDIS per comunicazione con IOB-MAN + /// + public class IobManDto + { + + /// + /// Minimo delta in sec x considerare variazioni informazioni inviate ad IOB-MAN via redis + /// + public int MinDeltaSec { get; set; } = 2; + } +} diff --git a/EgwConf.Iob/Base/ServerMapoDto.cs b/EgwConf.Iob/Base/ServerMapoDto.cs new file mode 100644 index 0000000..9879f90 --- /dev/null +++ b/EgwConf.Iob/Base/ServerMapoDto.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EgwConf.Iob.Base +{ + public class ServerMapoDto + { + /// + /// Indica il metodo di trasporto http/https + /// + public string Transport { get; set; } = "http"; + + /// + /// Indirizzo IP server + /// + public string IpAddr { get; set; } = "127.0.0.1"; + + /// + /// URL Base del server applicativo + /// + public string BaseAppUrl { get; set; } = "/MP/IO/"; + + /// + /// Dizionario comandi configurati + /// + public Dictionary Commands { get; set; } = new CmdUriDto("IOB").StdCommands(); + + /// + /// Installazione di riferimento + /// + public string ClientInstall { get; set; } = "SW"; + + } +} diff --git a/EgwConf.Iob/Base/TCDataDto.cs b/EgwConf.Iob/Base/TCDataDto.cs new file mode 100644 index 0000000..7380f80 --- /dev/null +++ b/EgwConf.Iob/Base/TCDataDto.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EgwConf.Iob.Base +{ + /// + /// Classe gestione parametri legati a gestioen TempoCiclo + /// + public class TCDataDto + { + /// + /// Fattore Lambda (innovazione) per calcolo EWMA valore TCiclo corrente + /// + public double Lambda { get; set; } = 0.4; + + /// + /// Fattore massimo ammesso di delay x il TCiclo + /// + public double MaxDelayFactor { get; set; } = 1.2; + + /// + /// Incremento massimo pezzi per cui fare calcolo del tempociclo attuale + /// + public double MaxIncrPz { get; set; } = 2; + + } +} diff --git a/EgwConf.Iob/EgwConf.Iob.csproj b/EgwConf.Iob/EgwConf.Iob.csproj new file mode 100644 index 0000000..e58c7fe --- /dev/null +++ b/EgwConf.Iob/EgwConf.Iob.csproj @@ -0,0 +1,77 @@ + + + + + Debug + AnyCPU + {26CD6258-206B-4FB4-B9FB-1C573C930919} + Library + Properties + EgwConf.Iob + EgwConf.Iob + v4.6.2 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\MapoSDK.6.14.2411.518\lib\MapoSDK.dll + + + ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll + + + ..\packages\NLog.5.3.4\lib\net46\NLog.dll + + + + + + + + + + + + + ..\packages\YamlDotNet.16.3.0\lib\netstandard2.0\YamlDotNet.dll + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/EgwConf.Iob/EnumConf.cs b/EgwConf.Iob/EnumConf.cs new file mode 100644 index 0000000..da40adf --- /dev/null +++ b/EgwConf.Iob/EnumConf.cs @@ -0,0 +1,396 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EgwConf.Iob +{ + public class EnumConf + { + + /// + /// Macro tipologia sistema di comunicazione (macro-adapter) + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum ComLayer + { + ND = 0, + Db, + Dll, + File, + ModBus, + Network, + Serial + } + + /// + /// Tipologia di adapters ammessi + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum AdapterType + { + /// + /// Adapter SIMULAZIONE + /// + SIMULA, + + /// + /// Adapter Beckhoff + /// + BECKHOFF, + + /// + /// Adapter Beckhoff x CPA (selezionatrici ex Jetco) + /// + BECKHOFF_CPA, + + /// + /// adapter FANUC + /// + FANUC, + + /// + /// File Based exchange generic adapter + /// + FILE_GEN, + + /// + /// File Based exchange Euromap63 + /// + FILE_EUROM63, + + ///// + ///// File Based exchange SCM Xylog + ///// + //FILE_XYLOG, + + /// + /// File Based Log file analisys per Soitaab + /// + FILE_SOITAAB, + + /// + /// Gestione sync FTP + /// + FTP, + + /// + /// Adapter KAWASAKI e-controller + /// + KAWASAKI, + + /// + /// Adapter Icoel per DB (barcode, tracciatura, produzione,...) + /// + IcoelDb, + + /// + /// Adapter Icoel per WS SOAP (sizer) + /// + IcoelSoap, + + /// + /// Adapter non specificato + /// + ND, + + /// + /// Adapter MITSUBISHI con EZCnc lib + /// + MITSUBISHI, + + /// + /// Adapter ModBus TCP generico + /// + MODBUS_TCP, + + /// + /// Adapter ModBus TCP versione Cedax (Giacovelli) + /// + MODBUS_TCP_CEDAX, + + /// + /// Adapter ModBus TCP versione Centerfrigo (Giacovelli) + /// + MODBUS_TCP_CENTERFRIGO, + + /// + /// Adapter modbus (+ file) x FIMAT (Tenditalia) + /// + MODBUS_TCP_FIMAT, + + /// + /// Adapter ModBus TCP versione HAM (Pizzaferri) + /// + MODBUS_TCP_HAM, + + /// + /// Adapter ModBus TCP versione HELPI (Cererie Finassi) + /// + MODBUS_TCP_HELPI, + + /// + /// Adapter Modubus TCP versione IMAX Aeromacchine (Jetco) + /// + MODBUS_TCP_IMAS_AEROMEC, + + /// + /// Adapter Modubus TCP versione Rimor (IMI Remosa) + /// + MODBUS_TCP_RIMOR, + + /// + /// Adapter Modubus TCP versione Saim (Giacovelli) + /// + MODBUS_TCP_SAIM, + + /// + /// Adapter Modubus TCP versione Zetapack (Giacovelli) + /// + MODBUS_TCP_ZETAPACK, + + /// + /// Adapter MTConnect + /// + MTConnect, + + /// + /// Adapter OMRON + /// + OMRON, + + /// + /// Adapter OPC-UA + /// + OpcUa, + + /// + /// Adapter OPC-UA CMS + /// + OpcUaCMS, + + /// + /// Adapter OPC-UA per Ewon + /// + OpcUaEwon, + + /// + /// Adapter OPC-UA per Ewon x Adige (BLM) / STIL + /// + OpcUaEwonAdige, + + /// + /// Adapter OPC-UA per Ewon x BLM / Mecart + /// + OpcUaEwonBLM, + + /// + /// Adapter OPC-UA per Ewon x Monti / Tenditalia + /// + OpcUaEwonMonti, + + /// + /// Adapter OPC-UA per Ewon x Mecolpress (BLM) / STIL + /// + OpcUaEwonMecolpress, + + /// + /// Adapter OPC-UA per KeepWare + /// + OpcUaKwp, + + /// + /// Adapter OPC-UA per KeepWare, UnitechRama + /// + OpcUaKwpRama, + + /// + /// Adapter OPC-UA per IMAS Aeromec / Jetco + /// + OpcUaImasAeromec, + + /// + /// Adapter MBH (es Cimolai) + /// + OpcUaMBH, + + /// + /// Adapter MBH implementazione Cimolai x travel lift + /// + OpcUaMBHCimolai, + + /// + /// Adapter OMRON (es ICOEL) + /// + OpcUaOmron, + + /// + /// Implementaizone OMRON specifica x ICOEL + /// + OpcUaOmronIcoel, + + /// + /// Adapter OPC-UA SCM + /// + OpcUaSCM, + + /// + /// Adapter OPC-UA Siemens generico + /// + OpcUaSiemens, + + /// + /// Adapter OPC-UA Siemens OMP + /// + OpcUaSiemensOMP, + + /// + /// Adapter OPC-UA Siemens Rama + /// + OpcUaSiemensRama, + + /// + /// Adapter OPC-UA Ulma (packaging, Giacovelli) + /// + OpcUaUlma, + + /// + /// Adapter OSAI CNDEX (Cndex) + /// + OSAI_CNDEX, + + /// + /// Adapter OSAI OPEN (ws) + /// + OSAI_OPEN, + + /// + /// Adapter OSAI VB6 + /// + OSAI_VB6, + + /// + /// Adapter tipo watchdog via ping (per impianti spenti e non rilevati) + /// + PingWatchdog, + + /// + /// Adapter REST (base) + /// + REST, + + /// + /// Adapter REST Citizen + /// + REST_CITIZEN, + + /// + /// Shelly's Device (tipicamente PM series) + /// + Shelly, + + /// + /// Adapter SIEMENS + /// + SIEMENS, + + /// + /// Adapter SIEMENS, interfaccia versione APROCHIM (filtro liquidi rettifiche) + /// + SIEMENS_APROCHIM, + + /// + /// Adapter SIEMENS, interfaccia versione VIPA @2001 + /// + SIEMENS_AT2001, + + /// + /// Adapter SIEMENS, interfaccia versione FAPE (punzonatrici) vers 2018 + /// + SIEMENS_FAPE, + + /// + /// Adapter SIEMENS, interfaccia versione FAPE (punzonatrici) vers 2024 + /// + SIEMENS_FAPE_2, + + /// + /// Adapter SIEMENS, interfaccia versione COMECA (impianti gestione GNL) + /// + SIEMENS_COMECA, + + /// + /// Adapter SIEMENS, interfaccia versione COMUR (dentatrice) + /// + SIEMENS_COMUR, + + /// + /// Adapter SIEMENS, interfaccia versione COSMAP (transfer smerigliatrice donati) + /// + SIEMENS_COSMAP, + + /// + /// Adapter SIEMENS, interfaccia versione INGENIA (Valvital, Automazione) + /// + SIEMENS_INGENIA, + + /// + /// Adapter SIEMENS, interfaccia versione LASCO (Valvital, Pressa Bilancere) + /// + SIEMENS_LASCO, + + /// + /// Adapter SIEMENS, interfaccia versione NWSE (Giacovelli, impianto filtrazione NWS) + /// + SIEMENS_NWSE, + + /// + /// Adapter SIEMENS, interfaccia versione PRESSOIL + CEI (Valvital, Pressa Idraulica) + /// + SIEMENS_PRESSOIL_CEI, + + /// + /// Adapter SIEMENS, interfaccia verisone RobotService (Donati, smerigliatrici) + /// + SIEMENS_ROBOTSERVICE, + + /// + /// Adapter SIEMENS, interfaccia versione SAET (Valvital, forni / tempra) + /// + SIEMENS_SAET, + + /// + /// Adapter SIEMENS, interfaccia versione SIMEC (Valvital, taglio) + /// + SIEMENS_SIMEC, + + /// + /// Adapter SIEMENS, interfaccia versione Torri + /// + SIEMENS_TORRI, + + /// + /// Adapter SOAP x bilance Gomba + /// + SOAP_GOMBA, + + /// + /// Adapter basato su DB scambio Microsoft SqlServer, macchine LANTEK + /// + SQLSERVER_LANTEK, + + /// + /// Adapter basato su DB scambio Microsoft SqlServer, macchine PAMA + /// + SQLSERVER_PAMA, + + /// + /// Metodi di WPS WebPageScraping (es x compressori Atlas Copco) + /// + WPS + } + } +} diff --git a/EgwConf.Iob/IniFile.cs b/EgwConf.Iob/IniFile.cs new file mode 100644 index 0000000..89c3d1b --- /dev/null +++ b/EgwConf.Iob/IniFile.cs @@ -0,0 +1,316 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace EgwConf.Iob +{ + /// + /// Create a new INI file to store or load data + /// + public class IniFile + { + #region Public Fields + + public string FileName; + + #endregion Public Fields + + #region Public Constructors + + /// + /// Constructor + /// + /// + public IniFile(string INIPath) + { + FileName = INIPath; + } + + #endregion Public Constructors + + #region Public Methods + + /// + /// Delete a key from section + /// + /// + /// + public void IniDeleteKey(string Section, string Key) + { + WritePrivateProfileString(Section, Key, "", FileName); + } + + /// + /// Completely remove one section + /// + /// + public void IniDeleteSection(string Section) + { + WritePrivateProfileSection(Section, "", FileName); + } + + /// + /// Return true if section exists + /// + /// + /// + public bool IniSectionExists(string Section) + { + int bytesReturned = 0; + const int bufferSize = 2048; // max is 32767 + IntPtr pReturnedString = Marshal.AllocCoTaskMem(bufferSize); + try + { + bytesReturned = GetPrivateProfileSection(Section, pReturnedString, bufferSize, FileName); + } + finally + { + Marshal.FreeCoTaskMem(pReturnedString); + } + return (bytesReturned > 0); + } + + /// + /// Read a boolean + /// + /// + /// + /// + public bool ReadBoolean(string Section, string Key) + { + return (ReadInteger(Section, Key, 0) != 0); + } + + /// + /// Read a boolean with default value + /// + /// + /// + /// + /// + public bool ReadBoolean(string Section, string Key, bool DefaultVal) + { + int v = DefaultVal ? 1 : 0; + return (ReadInteger(Section, Key, v) != 0); + } + + /// + /// Read an integer + /// + /// + /// + /// + public int ReadInteger(string Section, string Key) + { + return GetPrivateProfileInt(Section, Key, 0, FileName); + //System.Convert.ToInt32(IniReadValue(Section, Key)); + } + + /// + /// Read an integer. If not found use default value + /// + /// + /// + /// + /// + public int ReadInteger(string Section, string Key, int DefaultVal) + { + //int temp = System.Convert.ToInt32(IniReadString(Section, Key, Convert.ToString(DefaultVal))); + //return temp; + return GetPrivateProfileInt(Section, Key, DefaultVal, FileName); + } + + /// + /// Read a complete section (keys=values) + /// + /// + /// Section name + /// + /// restituisce delle stringhe keys=values da suddividere appunto come key/val successivamente + /// + public string[] ReadSection(string Section) + { + const int bufferSize = 2048; // max is 32767 + + StringBuilder returnedString = new StringBuilder(); + + IntPtr pReturnedString = Marshal.AllocCoTaskMem(bufferSize); + try + { + int bytesReturned = GetPrivateProfileSection(Section, pReturnedString, bufferSize, FileName); + if (bytesReturned > 0) + { + //bytesReturned -1 to remove trailing \0 + for (int i = 0; i < bytesReturned - 1; i++) + { + var currPointer = IntPtr.Add(pReturnedString, i); + var currChar = (char)Marshal.ReadByte(currPointer); + returnedString.Append(currChar); + } + } + } + finally + { + Marshal.FreeCoTaskMem(pReturnedString); + } + + string sectionData = returnedString.ToString(); + return sectionData.Split('\0'); + } + + /// + /// Read data from the Ini file + /// + /// + /// + /// + /// + public string ReadString(string Section, string Key) + { + StringBuilder temp = new StringBuilder(255); + int i = GetPrivateProfileString(Section, Key, "", temp, 255, FileName); + return temp.ToString(); + } + + /// + /// Read a string. If not found use default value + /// + /// + /// + /// + /// + public string ReadString(string Section, string Key, string DefaultVal) + { + string temp = ReadString(Section, Key); + if (temp == "") temp = DefaultVal; + return temp; + } + + /// + /// Return true if value exists + /// + /// + /// + /// + public bool ValueExists(string Section, string Key) + { + StringBuilder temp = new StringBuilder(255); + int i = GetPrivateProfileString(Section, Key, "", temp, 255, FileName); + return (i > 0); + } + + /// + /// Write a boolean value + /// + /// + /// + /// + public void WriteBoolean(string Section, string Key, bool Value) + { + int flag = Value ? 1 : 0; + WriteString(Section, Key, Convert.ToString(flag)); + } + + /// + /// Write a double value + /// + /// + /// + /// + public void WriteDouble(string Section, string Key, double Value) + { + WriteString(Section, Key, Convert.ToString(Value, NumberFormatInfo.InvariantInfo)); + } + + /// + /// Write an integer value + /// + /// + /// + /// + public void WriteInteger(string Section, string Key, int Value) + { + WriteString(Section, Key, Convert.ToString(Value)); + } + + /// + /// Write data to the INI file + /// + /// + /// Section name + /// + /// Key Name + /// + /// Value Name + public void WriteString(string Section, string Key, string Value) + { + WritePrivateProfileString(Section, Key, Value, FileName); + } + + #endregion Public Methods + + #region Private Methods + + /// + /// GetPrivateProfileInt: import windows dll functions + /// + /// + /// + /// + /// + /// + [DllImport("kernel32")] + private static extern int GetPrivateProfileInt(string section, string key, int def, string filePath); + + /// + /// GetPrivateProfileSection: import windows dll functions + /// + /// + /// + /// + /// + /// + [DllImport("kernel32")] + private static extern int GetPrivateProfileSection(string section, IntPtr retVal, uint size, string filePath); + + /// + /// GetPrivateProfileString: import windows dll functions + /// + /// + /// + /// + /// + /// + /// + /// + [DllImport("kernel32")] + private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath); + + /// + /// WritePrivateProfileSection: import windows dll functions + /// + /// + /// + /// + /// + [DllImport("kernel32")] + private static extern bool WritePrivateProfileSection(string section, string value, string filePath); + + /// + /// WritePrivateProfileString: import windows dll functions + /// + /// + /// + /// + /// + /// + [DllImport("kernel32", CharSet = CharSet.Auto, BestFitMapping = false)] + private static extern long WritePrivateProfileString(string section, string key, string val, string filePath); + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/EgwConf.Iob/IobConfTree.cs b/EgwConf.Iob/IobConfTree.cs new file mode 100644 index 0000000..3c74b84 --- /dev/null +++ b/EgwConf.Iob/IobConfTree.cs @@ -0,0 +1,374 @@ +using Newtonsoft.Json; +using YamlDotNet.Serialization.NamingConventions; +using YamlDotNet.Serialization; +using NLog; +using System.IO; +using System; +using static EgwConf.Iob.EnumConf; +using System.Collections.Generic; +using System.Linq; +using EgwConf.Iob.Base; + +// +// This is here so CodeMaid doesn't reorganize this document +// +namespace EgwConf.Iob +{ + /// + /// Albero configurazione globale IOB in formato serializable + /// + [Serializable] + public class IobConfTree + { + /// + /// Init classe configurazione + /// + public IobConfTree() + { + Log = LogManager.GetCurrentClassLogger(); + } + + /// + /// Init classe configurazione da file + /// + public IobConfTree(string confFilePath) + { + Log = LogManager.GetCurrentClassLogger(); + if (File.Exists(confFilePath)) + { + IobConfTree newConfObj = new IobConfTree(); + // verifico TIPO file... + string fileExt = Path.GetExtension(confFilePath); + string fileName = Path.GetFileName(confFilePath); + string rawData = File.ReadAllText(confFilePath); + if (!string.IsNullOrEmpty(rawData)) + { + // leggo in base al tipo... + switch (fileExt) + { + case "yaml": + case "yml": + var deserializer = new DeserializerBuilder() + .WithNamingConvention(CamelCaseNamingConvention.Instance) + .Build(); + try + { + newConfObj = deserializer.Deserialize(rawData); + } + catch (Exception exc) + { + //lgError($"Eccezione in LoadFromYaml{Environment.NewLine}{exc}"); + } + break; + default: + break; + } + if (newConfObj != null) + { + // ora copio in oggetto corrente... + CncData = newConfObj.CncData; + CodIOB = newConfObj.CodIOB; + ConfFileName = fileName; + Customer = newConfObj.Customer; + GeneralCom = newConfObj.GeneralCom; + InputDataProc = newConfObj.InputDataProc; + IobManConf = newConfObj.IobManConf; + IobType = newConfObj.IobType; + Model = newConfObj.Model; + OptPar = newConfObj.OptPar; + ReleaseVers = newConfObj.ReleaseVers; + ServerMES = newConfObj.ServerMES; + TempoCiclo = newConfObj.TempoCiclo; + Vendor = newConfObj.Vendor; + } + } + } + } + + /// + /// Restituisce un oggetto di conf leggendo INI ed effettuando conversione + /// + /// + /// + public static IobConfTree LoadFromINI(string iniFilePath) + { + IobConfTree newConfObj = new IobConfTree(); + try + { + // leggo file INI + IniFile fIni = new IniFile(iniFilePath); + string codIob = Path.GetFileNameWithoutExtension(iniFilePath); + + // effettuo conversione... + + // Dati generali (vendor, modello...) + newConfObj.CodIOB = fIni.ReadString("IOB", "IOB_NAME", codIob); + newConfObj.Vendor = fIni.ReadString("MACHINE", "VENDOR", "STEAMWARE"); + newConfObj.Model = fIni.ReadString("MACHINE", "MODEL", "NONE"); + newConfObj.ConfFileName = Path.GetFileName(iniFilePath); + + // tipo adapter// verifico tipo adapter + try + { + newConfObj.IobType = (AdapterType)Enum.Parse(typeof(AdapterType), fIni.ReadString("IOB", "CNCTYPE", "ND")); + } + catch (Exception exc) + { + newConfObj.IobType = AdapterType.ND; + string rawVal = fIni.ReadString("IOB", "CNCTYPE", "DEMO"); + newConfObj.lgError($"Eccezione in conversione tipo adapter: richiesto {rawVal} | tipo non codificato...{Environment.NewLine}{exc}"); + } + newConfObj.GeneralCom = (ComLayer)Enum.Parse(typeof(ComLayer), fIni.ReadString("IOB", "CNCFAMILY", "ND")); + + // CNC + newConfObj.CncData.pingMsTimeout = fIni.ReadInteger("IOB", "PING_MS_TIMEOUT", 500); + newConfObj.CncData.IpAddr = fIni.ReadString("CNC", "IP", "::1"); + newConfObj.CncData.Port = fIni.ReadString("CNC", "PORT", "0"); + if (!string.IsNullOrEmpty(fIni.ReadString("CNC", "CPUTYPE", ""))) + { + newConfObj.CncData.SiemensCpu = new Special.SiemensDto(); + newConfObj.CncData.SiemensCpu.CpuType = fIni.ReadString("CNC", "CPUTYPE", ""); + newConfObj.CncData.SiemensCpu.Rack = (short)fIni.ReadInteger("CNC", "RACK", 0); + newConfObj.CncData.SiemensCpu.Slot = (short)fIni.ReadInteger("CNC", "SLOT", 0); + } + + // BLINK + newConfObj.InputDataProc.BlinkMaxCounter = Convert.ToInt32(fIni.ReadString("BLINK", "MAX_COUNTER_BLINK", "1")); + newConfObj.InputDataProc.BlinkFilterMask = Convert.ToInt32(fIni.ReadString("BLINK", "BLINK_FILT", "0")); + newConfObj.TempoCiclo.MaxDelayFactor = Convert.ToDouble(fIni.ReadString("OPTPAR", "TC_MAX_TC_FACTOR", "1.2").Replace(".", ",")); + newConfObj.TempoCiclo.Lambda = Convert.ToDouble(fIni.ReadString("OPTPAR", "TC_LAMBDA", "0.5").Replace(".", ",")); + newConfObj.TempoCiclo.MaxIncrPz = Convert.ToDouble(fIni.ReadString("OPTPAR", "TC_MAX_INCR", "5").Replace(".", ",")); + + // Server + string MpIp = fIni.ReadString("SERVER", "MPIP", "::1"); + if (!string.IsNullOrEmpty(MpIp)) + { + newConfObj.ServerMES.Transport = MpIp.StartsWith("https://") ? "https" : "http"; + newConfObj.ServerMES.IpAddr = MpIp.Replace($"{newConfObj.ServerMES.Transport}://", ""); // tolgo http/https... + } + + // Altro (versione, ...) + newConfObj.ReleaseVers = $"{System.Reflection.Assembly.GetExecutingAssembly().GetName().Version}"; + newConfObj.IobManConf.MinDeltaSec = fIni.ReadInteger("IOB", "MinDeltaSec", 6); + + // OptPar + Dictionary optParRead = new Dictionary(); + string[] optParRows = fIni.ReadSection("OPTPAR"); + if (optParRows.Length > 0) + { + try + { + string[] kvp; + foreach (var item in optParRows) + { + kvp = item.Split('='); + optParRead.Add(kvp[0], kvp[1]); + } + //newConfObj.lgDebug($"Caricati {optParRead.Count} parametri opzionali da OPTPAR"); + } + catch (Exception exc) + { + newConfObj.lgError(string.Format("EXCEPTION in fase di lettura OPTPAR: {0}{1}", Environment.NewLine, exc)); + } + } + // riordino alfabeticamente + optParRead = optParRead.OrderBy(x => x.Key).ToDictionary(x => x.Key, x => x.Value); + newConfObj.OptPar = optParRead; + } + catch + { } + return newConfObj; + } + + #region Logging + + /// + /// oggetto logging + /// + protected Logger Log;// = LogManager.GetCurrentClassLogger(); + + /// + /// Effettua logging DEBUG corretto impostanto anche la variabile IOB prima di scrivere... + /// + /// + protected void lgDebug(string txt2log) + { + Log.Factory.Configuration.Variables["codIOB"] = this.CodIOB; + Log.Debug(txt2log); + } + + /// + /// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere... + /// + /// + protected void lgError(string txt2log) + { + if (!string.IsNullOrEmpty(txt2log)) + { + Log.Factory.Configuration.Variables["codIOB"] = this.CodIOB; + Log.Error(txt2log); + } + } + + /// + /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere... + /// + /// + protected void lgInfo(string txt2log) + { + Log.Factory.Configuration.Variables["codIOB"] = this.CodIOB; + Log.Info(txt2log); + } + + /// + /// Effettua logging TRACE corretto impostanto anche la variabile IOB prima di scrivere... + /// + /// + protected void lgTrace(string txt2log) + { + Log.Factory.Configuration.Variables["codIOB"] = this.CodIOB; + Log.Trace(txt2log); + } + + #endregion + + /// + /// Codice Cliente/Installazione + /// + public string Customer { get; set; } = "SteamWare"; + + /// + /// Codice univoco IOB + /// + public string CodIOB { get; set; } = "ND"; + /// + /// Costruttore + /// + public string Vendor { get; set; } = "ACME"; + + /// + /// Codice modello + /// + public string Model { get; set; } = "NONE"; + + /// + /// Nome file di configurazione + /// + public string ConfFileName { get; set; } = ""; + + /// + /// Tipologia generale dell'adapter + /// + public ComLayer GeneralCom { get; set; } = ComLayer.ND; + + /// + /// Tipo Adapter specifico (implementazione) + /// + public AdapterType IobType { get; set; } = AdapterType.ND; + + /// + /// Setup server MP da chiamare + /// + public ServerMapoDto ServerMES { get; set; } = new ServerMapoDto(); + + /// + /// Setup info verso IOB-MAN + /// + public IobManDto IobManConf { get; set; } = new IobManDto(); + + /// + /// Dati configurazione CNC + /// + public ConnectParamsDto CncData { get; set; } = new ConnectParamsDto(); + + /// + /// Setup processing dati in ingresso (es: blink segnali) + /// + public InputSignalDto InputDataProc { get; set; } = new InputSignalDto(); + + /// + /// Dati relativi ai parametri gestione tempo ciclo + /// + public TCDataDto TempoCiclo { get; set; } = new TCDataDto(); + + /// + /// Dizionario dei parametri opzionali + /// + public Dictionary OptPar { get; set; } = new Dictionary(); + + /// + /// Versione software IOB + /// + public string ReleaseVers { get; set; } = "0.0.0.0"; + + #region Metodi Serializzazione + + /// + /// Restituisce conf serializzata in formato JSON + /// + /// + /// + public string GetJson() + { + string rawdata = JsonConvert.SerializeObject(this, Formatting.Indented); + return rawdata; + } + /// + /// Restituisce conf serializzata in formato YAML + /// + /// + /// + public string GetYaml() + { + // opzioni alternative: PascalCaseNamingConvention (iniziale masiucola) o lowerCaseNamingConvention + var serializer = new SerializerBuilder() + .WithNamingConvention(CamelCaseNamingConvention.Instance) + .Build(); + var rawdata = serializer.Serialize(this); + return rawdata; + } + + #endregion + + #region Metodi Load/Save + + /// + /// Scrive conf serializzata in formato JSON + /// + /// + /// + public bool SaveJson(string filePath) + { + bool answ = false; + try + { + string rawdata = GetJson(); + File.WriteAllText(filePath, rawdata); + answ = true; + } + catch + { } + return answ; + } + /// + /// Scrive conf serializzata in formato YAML + /// + /// + /// + public bool SaveYaml(string filePath) + { + bool answ = false; + try + { + var rawdata = GetYaml(); + File.WriteAllText(filePath, rawdata); + answ = true; + } + catch + { } + return answ; + } + + #endregion + } +} \ No newline at end of file diff --git a/EgwConf.Iob/Mem/ToMapo.cs b/EgwConf.Iob/Mem/ToMapo.cs new file mode 100644 index 0000000..558d60c --- /dev/null +++ b/EgwConf.Iob/Mem/ToMapo.cs @@ -0,0 +1,923 @@ +using MapoSDK; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.Collections.Generic; + +namespace EgwConf.Iob.Mem +{ + /// + /// Classe gestione configurazione parametri di base x allarmi + /// + public class BaseAlarmConf + { + #region Public Properties + + /// + /// Elenco dei contatori blink x gestione caso fronte salita/discesa segnale che blinka + /// + public int[] alarmsBlinkCounter { get; set; } + + /// + /// BitMask 16bit (1 = valido, 0 = filtro) degli allarmi silenziati/disabilitati (se + /// iniziano per ##) come valore da sottrarre x check + /// + public uint[] alarmsMask { get; set; } + + /// + /// Array dei valori allarme correnti + /// + public uint[] alarmsState { get; set; } + + /// + /// valore di partenza x un segnale di blink in caso di fine variazione (fronte discesa) + /// + public int blinkDownVal { get; set; } = 4; + + /// + /// valore di partenza x un segnale di blink in caso di inizio variazione (fronte salita) + /// + public int blinkUpVal { get; set; } = 3; + + /// + /// Descrizione area allarmi + /// + public string description { get; set; } = ""; + + /// + /// Indice nell'area di memoria (da valore iniziale = 0) + /// + public int index { get; set; } = 0; + + /// + /// Nome "assoluto" della posizione nell'area di memoria (anche diverso da indice) + /// + public string memAddr { get; set; } = ""; + + /// + /// Elenco allarmi configurati x la bitmap + /// + public List messages { get; set; } = new List(); + + /// + /// Size in byte + /// + public int size { get; set; } = 0; + + /// + /// Tipo di dato + /// + [JsonConverter(typeof(StringEnumConverter))] + public plcDataType tipoMem { get; set; } = plcDataType.Boolean; + + + /// + /// Tipo del blocco allarmi configurato + /// + [JsonConverter(typeof(StringEnumConverter))] + public AlarmBlockType blockType { get; set; } = AlarmBlockType.Bitmap; + + /// + /// Livello del blocco memoria + /// + [JsonConverter(typeof(StringEnumConverter))] + public AlarmLevel blockLevel { get; set; } = AlarmLevel.Alarm; + + /// + /// Elenco KEY codici allarme attivabili + /// + public List activeKeys { get; set; } = new List(); + + /// + /// Elenco VALUE codici allarme attivabili + /// + public List activeValues { get; set; } = new List(); + + + #endregion Public Properties + + #region Public Methods + + /// + /// Calcola il filtro da condizione blink (ovvero maschera per valori indicati blinking) + /// + /// + /// + 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; + } + + /// + /// Effettua update dei contatori blink per gestire i segnali alternati sul fronte di salita/discesa + /// + /// + /// + 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++; + } + } + + /// + /// Confronta un valore di stato allarme con lo stato precedentemente salvato considerando blink/veto + /// + /// Numero/indice del banco di allarme (uint16) + /// Valore (bitmap) allarmi come uint16 + /// + public bool isChanged(int num, uint newValue) + { + // per prima cosa controllo valori RAW + bool answ = !alarmsState[num].Equals(newValue); + if (answ) + { + // controllo valori filtrati con ## (sottraendo BITMASK dai valori di filtro) + answ = ((alarmsState[num] & alarmsMask[num]) != (newValue & alarmsMask[num])); + // se fossero ancora differenti controllo ulteriore mask dato il counter dei blink: + if (answ) + { + var blinkFilt = blinkFilter(num); + answ = ((alarmsState[num] & (alarmsMask[num] & ~blinkFilt)) != (newValue & (alarmsMask[num] & ~blinkFilt))); + //answ = ((alarmsState[num] & (alarmsMask[num] | blinkFilt)) != (newValue & (alarmsMask[num] | blinkFilt))); + } + } + return answ; + } + + /// + /// Inizializzazione classe con valori calcolati: attenzione si aspetta banchi da 32 bit... + /// ATTENZIONE: eseguita solo se blockType == bitmap + /// + public void setupData() + { + // verifico si tratti di un tipo allarmi a bitmap... altrimenti salto + if (blockType == AlarmBlockType.Bitmap) + { + // inizializzo vettore valore allarmi x banco int8 x iniziare + alarmsState = new uint[size]; + alarmsMask = new uint[size]; + int bitSize = 8; + + // 16/32 bit + if (size > 1) + { + // inizializzo vettore valore allarmi x banco int16 + alarmsState = new uint[size / 2]; + alarmsMask = new uint[size / 2]; + bitSize = 16; + } + + // una volta inizializzata la classe di base sistemo vettori allarmi disabilitati ed il + // contatore blink dei fronti di discesa + alarmsBlinkCounter = new int[messages.Count]; + //verifico i contatori di blink da eventuale conf... + + int idx = 0; + int bank = 0; + foreach (var item in messages) + { + if (item.StartsWith("##")) + { + alarmsBlinkCounter[idx] = -999; + } + else + { + alarmsBlinkCounter[idx] = 1; + alarmsMask[bank] += (uint)1 << idx; + } + idx++; + // sistemo bank/indice + if (idx > bitSize - 1) + { + bank++; + idx = 0; + } + } + } + } + + /// + /// Effettua il caricamento dello status da un valore precedente (es da cache REDIS) + /// ATTENZIONE: eseguita solo se blockType == bitmap e size corrisponde a quella della mem allarmi + /// + /// + public void loadPrev(uint[] lastState) + { + // verifico si tratti di un tipo allarmi a bitmap... altrimenti salto + if (blockType == AlarmBlockType.Bitmap) + { + if (lastState.Length == alarmsState.Length) + { + alarmsState = lastState; + } + } + } + + /// + /// Imposta il valore dello status attuale allarme impostando eventuale valore blink x le variazioni + /// + /// + /// + public void updStatusVal(int num, uint newStatus) + { + // salvo nuovo valore + alarmsState[num] = newStatus; + } + + /// + /// Tipologia del blocco allarmi configurato + /// + public enum AlarmBlockType + { + /// + /// Modalità standard a bitmap + /// + Bitmap, + + /// + /// Modalità elenco dei valori attivi (es OPC-UA BLM/Adige) + /// + ActiveList + } + + /// + /// Livello Allarme + /// + public enum AlarmLevel + { + /// + /// Messaggio (non bloccante) + /// + Message = 0, + + /// + /// Avviso (non bloccante) + /// + Warning = 100, + + /// + /// Allarme (bloccante) + /// + Alarm = 200, + + /// + /// Allarme di massimo livello + /// + Emergency = 300 + } + + + #endregion Public Methods + } + + /// + /// Classe gestione configurazione parametri di base x configurazione estesa (es MTConnect, + /// OPC-UA, ...) + /// + public class BaseParamConf + { + #region Public Properties + + /// + /// Struttura dati x check condizione LAVORA / Green + /// + public List condWork { get; set; } = new List(); + + + /// + /// Struttura dati x check condizione EXTRA di controllo x singoli BIT + /// + public Dictionary bitSpecCond { get; set; } = new Dictionary(); + + /// + /// Indica se l'emergenza armata va riportata verso Mapo come bit a TRUE True --> armata + /// = 1 / triggered = 0 False --> triggered = 1 / armata = 0 + /// + public bool emergencyArmedTrue { get; set; } = true; + + /// + /// Elenco items FILTRATI da invio come dynData --> FluxLog (events o samples), ricerca SECCA + /// + public List fluxLogVeto { get; set; } = new List(); + + /// + /// Elenco items FILTRATI da invio come dynData --> FluxLog (events o samples), ricerca testo come contains in displayName + /// + public List fluxLogVetoContains { get; set; } = new List(); + + /// + /// Indica se il controllo di ping sia OK (x controllo prima della connessione) + /// + public bool forcePingOk { get; set; } = false; + + /// + /// Array degli elementi di traduzione item + /// + public Dictionary itemTranslation { get; set; } = new Dictionary(); + + + /// + /// Indica se decodificare valori dall'area mMapRead da valori byte[] delle variabili sottoscritte + /// + public bool mMapReadFromRawByte { get; set; } = false; + /// + /// Indica se decodificare valori dall'area mMapWrite da valori byte[] delle variabili sottoscritte + /// + public bool mMapWriteFromRawByte { get; set; } = false; + + /// + /// Indica se inviare i dati sottoscritti che sono "raw" o meno... + /// + public bool sendSubscribItemsRaw { get; set; } = true; + + /// + /// Separatore configurazione area OPC e subObj in caso di memorie struct speciali + /// + public char kvDelim { get; set; } = '#'; + + /// + /// Separatore definizione aree memoria speciali + /// + public char memDelim { get; set; } = '.'; + + + /// + /// Nome variabile x EmergencyStop + /// + public string keyEStop { get; set; } = ""; + + /// + /// Nome variabile x ExeMode + /// + public string keyExeMode { get; set; } = ""; + + /// + /// Nome variabile x pezzi FATTI + /// + public string keyPartCount { get; set; } = ""; + + /// + /// Nome variabile x Codice Articolo + /// + public string keyPartId { get; set; } = ""; + + /// + /// Nome variabile x pezzi RICHIESTI + /// + public string keyPartReq { get; set; } = ""; + + /// + /// Nome variabile x NOME PROGRAMMA + /// + public string keyProgName { get; set; } = ""; + + /// + /// Nome variabile x RunMode + /// + public string keyRunMode { get; set; } = ""; + + /// + /// Aree di memoria lettura + /// + public Dictionary mMapRead { get; set; } = new Dictionary(); + + /// + /// Aree di memoria scrittura + /// + public Dictionary mMapWrite { get; set; } = new Dictionary(); + + /// + /// Dictionary dei nomi da cercare come "endsWith" a cui applicare la soglia indicata + /// + public Dictionary paramsEndThresh { get; set; } = new Dictionary(); + + /// + /// Dictionary dei nomi da cercare come "contains" a cui applicare la soglia indicata + /// + public Dictionary paramsContainsThresh { get; set; } = new Dictionary(); + + /// + /// Indica se il ping sia un criterio valido x determinare powerON impianto + /// + public bool pingAsPowerOn { get; set; } = true; + + /// + /// Indica se venga richiesta invio del run mode + /// + public bool runModeSend { get; set; } = false; + + /// + /// Indica se venga richiesta traduzione del run mode + /// + public bool runModeTrad { get; set; } = false; + + /// + /// Lista ulteriori configurazioni KeyValuePair + /// + public Dictionary optKVP { get; set; } = new Dictionary(); + + #endregion Public Properties + } + + /// + /// Oggetto x processing valori (elenco valori e modalità) + /// + public class calcConf + { + #region Public Properties + + public calcMode calcMode { get; set; } = calcMode.None; + public List listVal { get; set; } = new List(); + + #endregion Public Properties + } + + /// + /// Classe per rappresentare oggetti chiave/valore target x controlo condizioni multiple + /// + public class diCheckCondition + { + #region Public Properties + + /// + /// Nome variabile + /// + public string keyName { get; set; } = ""; + + /// + /// Se >=0 indica ordine bit x decodifica di byte[] raw + /// + public int bitNum { get; set; } = -1; + + /// + /// valore target per esito richiesto + /// + public string targetValue { get; set; } = ""; + + #endregion Public Properties + } + + /// + /// Classe per rappresentare una lista di oggetti chiave/valore target x controlo condizioni + /// multiple + indicazione modalità di controllo (AND/OR/...) + /// + public class diCheckCondSetup + { + #region Public Properties + + /// + /// Elenco condizioni + /// + public List checkList { get; set; } = new List(); + + /// + /// Modalità verifica condizioni + /// + public boolCheckMode checkMode { get; set; } = boolCheckMode.AND; + + /// + /// indica se il check vada NEGATO (esempio se cerco la condizione opposta, esempio num + /// allarmi 0 --> se true NEGO la condizione HO ALLARMI) + /// + public bool negateValue { get; set; } = false; + + #endregion Public Properties + } + + /// + /// Classe x definizione delle azioni in fase di setup macchina + /// + public class MachineSetupAction + { + #region Public Properties + + /// + /// Indica se vada disabilitato il contapezzi quando la condizione NotEqual sia soddisfatta + /// + public bool DisablePzCountNotEqual { get; set; } = false; + + /// + /// Parametro target dell'azione + /// + public string TargetParam { get; set; } = ""; + + /// + /// parametro da impostare SE il check da esito EQUAL + /// + public int TargetValEqual { get; set; } = 0; + + /// + /// parametro da impostare SE il check da esito NOT EQUAL + /// + public int TargetValNotEqual { get; set; } = 1; + + #endregion Public Properties + } + + /// + /// Definizione parametri di setup incrociato... + /// + public class MachineSetupConf + { + #region Public Properties + + /// + /// Dizionario dei parametri di corrispondenza tra variabili MES e variabili Macchina MES = + /// scritte dal MES Macchina = scritte da macchina + /// + public Dictionary checkParList { get; set; } = new Dictionary(); + + /// + /// Abilitazione gestione Setup Avanzato (= scrittura) + /// + public bool EnableAdvSetup { get; set; } = false; + + /// + /// Modalità gestione setup + /// + public MachineSetupMode SetupMode { get; set; } = MachineSetupMode.ND; + + /// + /// Dizionario dei parametri da scrivere quando si rilevano differenze tra i parametri MES/Macchina + /// + public List writeParAction { get; set; } = new List(); + + #endregion Public Properties + } + + /// + /// COnfigurazione blocchi x accesso memoria ottimizzato + /// + public class MemBlockConf + { + #region Public Properties + + public Dictionary ReadBlocks { get; set; } = new Dictionary(); + + #endregion Public Properties + } + + /// + /// Classe gestione configurazione parametri specifici MTC da BaseParamConf + /// + public class MtcParamConf : BaseParamConf + { + #region Public Properties + + /// + /// Struttura dati x check condizione PowerOn + /// + public diCheckCondition condPowerOn { get; set; } = new diCheckCondition(); + + /// + /// Intervallo standard x SAMPLE data in ms + /// + public int clientSampleIntMs { get; set; } = 500; + + /// + /// Timeout standard x richieste in ms + /// + public int reqTOutMs { get; set; } = 1500; + + /// + /// Intervallo riconnessione standard in caso di mancanza risposta in ms + /// + public int reconnectIntMs { get; set; } = 1500; + + /// + /// Indica se usare il metodo di sottoscrizione alle variazioni in modalità observations + /// + public bool doSubsObserv { get; set; } = false; + + /// + /// Indica se usare il metodo di sottoscrizione alle variazioni sample + /// + public bool doSubsSample { get; set; } = true; + + + #endregion Public Properties + } + + /// + /// Classe gestione configurazione parametri specifici OPC-UA da BaseParamConf + /// + public class OpcUaParamConf : BaseParamConf + { + #region Public Properties + + /// + /// Elenco Variabili (e valori da impostare) x indicare di resettare contatore lotto e + /// quindi riavviare produzione (es: impostando valore a 1...) + /// + public Dictionary actResetCounter { get; set; } = new Dictionary(); + + /// + /// Elenco Variabili (e valori da impostare) x indicare di effettuare impostazione nuovo + /// programma/ricetta (es: impostando valore a 1...) + /// + public Dictionary actSetRecipe { get; set; } = new Dictionary(); + + /// + /// Elenco Variabili (e valori da impostare) x indicare di fermare la produzione (es: + /// impostando valore a 1...) + /// + public Dictionary actStopProd { get; set; } = new Dictionary(); + + /// + /// Identificativo nodo iniziale + /// + public string BrowseFullVal { get; set; } = "ns=2;s=Scalar_Static"; + + /// + /// Elenco di nodi da sottoscrivere direttamente al posto dell'albero derivante dal BrowseFullVal + /// + public List BrowseNodeList { get; set; } = new List(); + + /// + /// Indice NS da cui fare il browse dei file + /// + public ushort BrowseNSIndex { get; set; } = 4; + + /// + /// ID del nodo da cui partire x il browse di identificazione nodi iniziale + /// + public uint BrowseValue { get; set; } = 5001; + + /// + /// Lista valori calcolati/derivati da processare + /// + public Dictionary calcValues { get; set; } = new Dictionary(); + + /// + /// Numero minimo di secondi di durata di uno status + /// + public int minSecStatusDuration { get; set; } = 1; + + /// + /// Numero minimo di secondi di attesa finale (es prima di chiedere chiusura ODL) + /// + public int minSecFinalWait { get; set; } = 30; + + /// + /// Struttura dati x check condizione Contapezzi Abilitato (se vuoto = sempre abilitato) + /// + public diCheckCondSetup condCountEnabled { get; set; } = new diCheckCondSetup(); + + /// + /// Struttura dati x check condizione Errore + /// + public diCheckCondSetup condError { get; set; } = new diCheckCondSetup(); + + /// + /// Struttura dati x check condizione Emergenza + /// + public diCheckCondSetup condEStop { get; set; } = new diCheckCondSetup(); + + /// + /// Struttura dati x check condizione Manual + /// + public diCheckCondSetup condManual { get; set; } = new diCheckCondSetup(); + + /// + /// Struttura dati x check condizione PowerOn + /// + public diCheckCondSetup condPowerOn { get; set; } = new diCheckCondSetup(); + + /// + /// Struttura dati x check condizione READY + /// + public diCheckCondSetup condReady { get; set; } = new diCheckCondSetup(); + + /// + /// Struttura dati x check condizione Setup + /// + public diCheckCondSetup condSetup { get; set; } = new diCheckCondSetup(); + + /// + /// Struttura dati x check condizione WarmUp - CoolDown + /// + public diCheckCondSetup condWarmUpCoolDown { get; set; } = new diCheckCondSetup(); + + /// + /// Struttura dati x check condizione Warning + /// + public diCheckCondSetup condWarning { get; set; } = new diCheckCondSetup(); + + /// + /// Struttura dati x check condizione Errore + /// + public diCheckCondSetup condWorkOpc { get; set; } = new diCheckCondSetup(); + + /// + /// Elenco dei NodeId da ignorare intesi come interi rami (se vuoto NON filtro) + /// + public List filterItemsNodeId { get; set; } = new List(); + + /// + /// Elenco item flux da FILTRARE per chiave tradotta/VALORE + /// es: Cimolai / Baglietto, RunModeVal NON VOGLIO inviare quando il valore è 0 + /// + public Dictionary> fluxLogKeyValVeto { get; set; } = new Dictionary>(); + + public UserIdent Identity { get; set; } = new UserIdent(); + + /// + /// Aree di memoria lettura + /// + public new Dictionary mMapRead { get; set; } = new Dictionary(); + + /// + /// Aree di memoria scrittura + /// + public new Dictionary mMapWrite { get; set; } = new Dictionary(); + + /// + /// Elenco item RAW sottoscritti e relative configurazioni di decodifica da byte[] + /// + public Dictionary rawSubscribedItemsConf { get; set; } = new Dictionary(); + + /// + /// Conf gestione setup macchina + /// + public MachineSetupConf SetupConf { get; set; } = new MachineSetupConf(); + + /// + /// Elenco dei SOLI item sottoscritti (se vuoto TUTTI) + /// + public List subscribedItems { get; set; } = new List(); + + /// + /// Conf Gestione WatchDog + /// + public WatchDogConf WatchDog { get; set; } = new WatchDogConf(); + + /// + /// Indica che si utilizza (per LUT e gestione conf) il NodeId completo, default false (solo il DisplayName) + /// + public bool UseFullId { get; set; } = false; + + /// + /// Numero massimo di letture null prima di disconnettere il client + /// + public int maxNullRead { get; set; } = 1000; + + /// + /// Base del namespace da mascherare in invio OPC + /// + public string BaseIdMask { get; set; } = ""; + + public Dictionary DictOpcNameReplace { get; set; } = new Dictionary(); + + #endregion Public Properties + } + + /// + /// Classe gestione configurazione parametri specifici Rest Client da BaseParamConf + /// + public class RestParamConf : BaseParamConf + { + /// + /// Timeout chiamate REST + /// + public int timeOutSec { get; set; } = 60; + + /// + /// API di base x chiamate REST, eventuali variabili van indicate come [[nomevar]] + /// + public string apiUrl { get; set; } = ""; + + /// + /// Periodo minimo di campionamento in ms x lettura dati frequenti stato/semafori... + /// + public int samplePeriod { get; set; } = 1000; + + /// + /// Numero di errori dopo cui fare una vera disconnesisone con report poweroff della macchina + /// + public int connErrorMax { get; set; } = 5; + + /// + /// Elenco delle chiamate x ID / struttura + /// + public Dictionary CallList { get; set; } = new Dictionary(); + + public class CallStruc + { + /// + /// ID univoco chiamata per poterla recuperare + /// + public int Idx { get; set; } = 0; + + /// + /// Metodo chiamata + /// + public RestSharp.Method Method { get; set; } = RestSharp.Method.Get; + + /// + /// Url chiamata + /// + public string Url { get; set; } = ""; + + /// + /// Nome x invio a MES + /// + public string Name { get; set; } = ""; + + /// + /// Nome x salvataggio valore output in ProdData da poter richiamare + /// + public string OutVarName { get; set; } = ""; + + /// + /// Intervallo di campionamento (minimo) da rispettare x evitare flood chiamate + /// + public int SamplePeriod { get; set; } = 5000; + + /// + /// Elenco chiamate richieste se non fosse trovata/valida una variabile + /// + public List ListPrevCall { get; set; } = new List(); + } + } + + public class UserIdent + { + #region Public Properties + + public string Passwd { get; set; } = ""; + public string UserName { get; set; } = ""; + + #endregion Public Properties + } + + /// + /// Definizione parametri watchdog + /// + public class WatchDogConf + { + #region Public Properties + + /// + /// Abilitazione WatchDog + /// + public bool IsEnabled { get; set; } = false; + + /// + /// Valore max contatore prima di resettare + /// + public int MaxVal { get; set; } = 9999; + + /// + /// Conf memoria x lettura WatchDog (ToMes), se !="" è gestito + /// + public string MemConfRead { get; set; } = ""; + + /// + /// Conf memoria x scrittura WatchDog (FromMes), se !="" è gestito + /// + public string MemConfWrite { get; set; } = ""; + + #endregion Public Properties + } +} \ No newline at end of file diff --git a/EgwConf.Iob/Mem/plcMemMapExt.cs b/EgwConf.Iob/Mem/plcMemMapExt.cs new file mode 100644 index 0000000..21f0a58 --- /dev/null +++ b/EgwConf.Iob/Mem/plcMemMapExt.cs @@ -0,0 +1,52 @@ +using MapoSDK; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EgwConf.Iob.Mem +{ + public class plcMemMapExt : plcMemMap + { + /// + /// Dizionario parametri opzionali + /// + public Dictionary optMemPar { get; set; } = new Dictionary(); + + /// + /// Dizionario x decodifica file + /// + public Dictionary fileDecod { get; set; } = new Dictionary(); + + /// + /// Lista ulteriori configurazioni KeyValuePair + /// + public Dictionary optKVP { get; set; } = new Dictionary(); + + + /// + /// Dizionario opzionale di configurazione memorie WRITE con "alias", + /// impiegato tipicamente per poter gestire scritture valori INT su CNC/PLC che non accettano stringhe (es FANUC) + /// + public Dictionary mMapWriteLink { get; set; } = new Dictionary(); + + /// + /// Dizionario di dizionari di decodifica, chiave è nome/tipo dizionario e poi dizionario da impiegare + /// Usato ad esempio x decodifica stati da valore intero o degli step di esecuzione di un ciclo (es Fape v2+) + /// + public Dictionary> DataDecodMap { get; set; } = new Dictionary>(); + +#if false + /// + /// Base del NameSpace usato per le funzionalità di translate (parametri ACT-SET), da inserire come PRE + /// + public string BaseKeyTranslate { get; set; } = ""; + + /// + /// Dizionario per la traduzione delle ricette (se gestite) tra valori acquisiti in dossier e impostazioni da inviare (ACTual, SETup) + /// + public Dictionary RecipeKeyTranslate { get; set; } = new Dictionary(); +#endif + } +} \ No newline at end of file diff --git a/EgwConf.Iob/Properties/AssemblyInfo.cs b/EgwConf.Iob/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..655d96b --- /dev/null +++ b/EgwConf.Iob/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("EgwConf.Iob")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("EgwConf.Iob")] +[assembly: AssemblyCopyright("Copyright © 2025")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("26cd6258-206b-4fb4-b9fb-1c573c930919")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/EgwConf.Iob/Special/SiemensDto.cs b/EgwConf.Iob/Special/SiemensDto.cs new file mode 100644 index 0000000..dd2766d --- /dev/null +++ b/EgwConf.Iob/Special/SiemensDto.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EgwConf.Iob.Special +{ + public class SiemensDto + { + /// + /// TipoCPU (es: 1500, 1200, 300) + /// + public string CpuType { get; set; } = "ND"; + + /// + /// Rack (Siemens S7) + /// + public short Rack { get; set; } = 0; + + /// + /// Slot (Siemens S7) + /// + public short Slot { get; set; } = 0; + } +} diff --git a/EgwConf.Iob/packages.config b/EgwConf.Iob/packages.config new file mode 100644 index 0000000..020955f --- /dev/null +++ b/EgwConf.Iob/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/EgwProxy.Ftp.Debug.nuspec b/EgwProxy.Ftp.Debug.nuspec index a10657b..247796a 100644 --- a/EgwProxy.Ftp.Debug.nuspec +++ b/EgwProxy.Ftp.Debug.nuspec @@ -12,10 +12,8 @@ #copyright# EgwProxy.Ftp EgwProxy Ftp - - diff --git a/EgwProxy.Shelly.Test/App.config b/EgwProxy.Shelly.Test/App.config index 0b589db..330a68a 100644 --- a/EgwProxy.Shelly.Test/App.config +++ b/EgwProxy.Shelly.Test/App.config @@ -10,7 +10,27 @@ - + + + + + + + + + + + + + + + + + + + + + diff --git a/EgwProxy.Shelly.Test/Program.cs b/EgwProxy.Shelly.Test/Program.cs index a087a9c..68d4301 100644 --- a/EgwProxy.Shelly.Test/Program.cs +++ b/EgwProxy.Shelly.Test/Program.cs @@ -11,6 +11,7 @@ using EgwProxy.Shelly.Clients; using System.Net.Http; using EgwProxy.Shelly.Options; using System.Threading; +using Newtonsoft.Json.Linq; namespace EgwProxy.Shelly.Test { @@ -26,7 +27,7 @@ namespace EgwProxy.Shelly.Test /// /// legge conf in formato stringa /// - /// + /// /// protected static string ReadSetting(string key) { @@ -51,7 +52,7 @@ namespace EgwProxy.Shelly.Test /// /// Programma principale /// - /// + /// private static void Main(string[] args) { Console.WriteLine(separator); diff --git a/EgwProxy.Shelly/Clients/ShellyClientBase.cs b/EgwProxy.Shelly/Clients/ShellyClientBase.cs index f1e56ae..99add74 100644 --- a/EgwProxy.Shelly/Clients/ShellyClientBase.cs +++ b/EgwProxy.Shelly/Clients/ShellyClientBase.cs @@ -78,7 +78,7 @@ namespace EgwProxy.Shelly.Clients { var readAsStringAsync = await response.Content.ReadAsStringAsync(); var shelly1Status = JsonConvert.DeserializeObject(readAsStringAsync); - return ShellyResult.Success(shelly1Status); + return ShellyResult.Success(shelly1Status, readAsStringAsync); } } } diff --git a/EgwProxy.Shelly/EgwProxy.Shelly.csproj b/EgwProxy.Shelly/EgwProxy.Shelly.csproj index 9b14bd4..f4608dd 100644 --- a/EgwProxy.Shelly/EgwProxy.Shelly.csproj +++ b/EgwProxy.Shelly/EgwProxy.Shelly.csproj @@ -39,35 +39,38 @@ ..\packages\Flurl.Http.4.0.2\lib\net461\Flurl.Http.dll - - ..\packages\Microsoft.Bcl.AsyncInterfaces.6.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + ..\packages\Microsoft.Bcl.AsyncInterfaces.9.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll - - ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + ..\packages\System.Buffers.4.6.0\lib\net462\System.Buffers.dll - - ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + ..\packages\System.IO.Pipelines.9.0.0\lib\net462\System.IO.Pipelines.dll + + + ..\packages\System.Memory.4.6.0\lib\net462\System.Memory.dll - - ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + ..\packages\System.Numerics.Vectors.4.6.0\lib\net462\System.Numerics.Vectors.dll - - ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + ..\packages\System.Runtime.CompilerServices.Unsafe.6.1.0\lib\net462\System.Runtime.CompilerServices.Unsafe.dll - - ..\packages\System.Text.Encodings.Web.6.0.0\lib\net461\System.Text.Encodings.Web.dll + + ..\packages\System.Text.Encodings.Web.9.0.0\lib\net462\System.Text.Encodings.Web.dll - - ..\packages\System.Text.Json.6.0.4\lib\net461\System.Text.Json.dll + + ..\packages\System.Text.Json.9.0.0\lib\net462\System.Text.Json.dll - - ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + ..\packages\System.Threading.Tasks.Extensions.4.6.0\lib\net462\System.Threading.Tasks.Extensions.dll ..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll @@ -109,11 +112,4 @@ - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - \ No newline at end of file diff --git a/EgwProxy.Shelly/ShellyResult.cs b/EgwProxy.Shelly/ShellyResult.cs index 32f81c9..0011630 100644 --- a/EgwProxy.Shelly/ShellyResult.cs +++ b/EgwProxy.Shelly/ShellyResult.cs @@ -59,7 +59,7 @@ namespace EgwProxy.Shelly return new ShellyResult(default, success: false, isTransient: false, message); } - public static ShellyResult Success(T value, string message = null) + public static ShellyResult Success(T value, string rawResp, string message = null) { return new ShellyResult(value, true, false, message); } diff --git a/EgwProxy.Shelly/app.config b/EgwProxy.Shelly/app.config index 1696df6..7494728 100644 --- a/EgwProxy.Shelly/app.config +++ b/EgwProxy.Shelly/app.config @@ -4,7 +4,27 @@ - + + + + + + + + + + + + + + + + + + + + + diff --git a/EgwProxy.Shelly/packages.config b/EgwProxy.Shelly/packages.config index 45a386e..d1fb4ef 100644 --- a/EgwProxy.Shelly/packages.config +++ b/EgwProxy.Shelly/packages.config @@ -2,14 +2,15 @@ - + - - - - - - - + + + + + + + + \ No newline at end of file