From 4d17de11175cea9b7d269065ddf4dbfeb8d82a40 Mon Sep 17 00:00:00 2001 From: Jason Craig Date: Sun, 11 Feb 2018 00:06:27 -0700 Subject: [PATCH 1/7] Adding support for out of process data stream handling --- .../Device/IMaster.cs | 0 .../Device/IMessage.cs | 0 .../Device/Modbus/Crc16.cs | 0 .../Device/Modbus/Data/BooleanRegister.cs | 0 .../Device/Modbus/Data/CoilRegister.cs | 0 .../Modbus/Data/DiscreteInputRegister.cs | 0 .../Device/Modbus/Data/EventArchiveRecord.cs | 0 .../Device/Modbus/Data/FloatRegister.cs | 0 .../Modbus/Data/HistoryArchiveRecord.cs | 0 .../Device/Modbus/Data/HoldingRegister.cs | 0 .../Device/Modbus/Data/IModbusRegisterData.cs | 0 .../Device/Modbus/Data/InputRegister.cs | 0 .../Device/Modbus/Data/LongRegister.cs | 0 .../Device/Modbus/Data/ModbusAddress.cs | 0 .../Device/Modbus/Data/ModbusRegister.cs | 0 .../Device/Modbus/Data/ShortRegister.cs | 0 .../Device/Modbus/Data/StringRegister.cs | 0 .../Device/Modbus/Device.cs | 0 .../Device/Modbus/IO/Transport/Transport.cs | 0 .../Device/Modbus/Message/IModbusMessage.cs | 0 .../Modbus/Message/IModbusRequestMessage.cs | 0 .../Modbus/Message/IModbusResponseMessage.cs | 0 .../Modbus/Message/ModbusErrorResponse.cs | 0 .../Device/Modbus/Message/ModbusMessage.cs | 0 .../Modbus/Message/ModbusMessageFactory.cs | 0 .../Message/ReadCoilRegistersRequest.cs | 0 .../Message/ReadCoilRegistersResponse.cs | 0 .../ReadDiscreteInputRegistersRequest.cs | 0 .../ReadDiscreteInputRegistersResponse.cs | 0 .../Modbus/Message/ReadEventArchiveRequest.cs | 0 .../Message/ReadEventArchiveResponse.cs | 0 .../Modbus/Message/ReadFloatsRequest.cs | 0 .../Modbus/Message/ReadFloatsResponse.cs | 0 .../Message/ReadHistoryArchiveRequest.cs | 0 .../Message/ReadHistoryArchiveResponse.cs | 0 .../Message/ReadHoldingRegistersRequest.cs | 0 .../Message/ReadHoldingRegistersResponse.cs | 0 .../Message/ReadInputRegistersRequest.cs | 0 .../Message/ReadInputRegistersResponse.cs | 0 .../Device/Modbus/Message/ReadLongsRequest.cs | 0 .../Modbus/Message/ReadLongsResponse.cs | 0 .../Modbus/Message/ReadShortsRequest.cs | 0 .../Modbus/Message/ReadShortsResponse.cs | 0 .../Modbus/Message/ReadStringRequest.cs | 0 .../Modbus/Message/ReadStringResponse.cs | 0 .../Modbus/Message/WriteBooleanRequest.cs | 0 .../Modbus/Message/WriteBooleanResponse.cs | 0 .../Modbus/Message/WriteFloatsRequest.cs | 0 .../Modbus/Message/WriteFloatsResponse.cs | 0 .../Device/Modbus/ModbusConverter.cs | 0 .../Device/Modbus/ModbusMaster.cs | 0 .../Device/Modbus/ModbusSlaveException.cs | 0 .../Device/ROC/Crc16.cs | 0 .../Device/ROC/Data/Ac10Parameter.cs | 0 .../Device/ROC/Data/Ac12Parameter.cs | 0 .../Device/ROC/Data/Ac20Parameter.cs | 0 .../Device/ROC/Data/Ac30Parameter.cs | 0 .../Device/ROC/Data/Ac3Parameter.cs | 0 .../Device/ROC/Data/Ac40Parameter.cs | 0 .../Device/ROC/Data/Ac7Parameter.cs | 0 .../Device/ROC/Data/AlarmRecord.cs | 0 .../Device/ROC/Data/ArchiveInfo.cs | 0 .../Device/ROC/Data/AuditLogRecord.cs | 0 .../Device/ROC/Data/BinParameter.cs | 0 .../Device/ROC/Data/DoubleParameter.cs | 0 .../Device/ROC/Data/EventRecord.cs | 0 .../Device/ROC/Data/FlpParameter.cs | 0 .../Device/ROC/Data/FstCodeChunk.cs | 0 .../Device/ROC/Data/FstHeaderInfo.cs | 0 .../ROC/Data/HistoryPointConfiguration.cs | 0 .../Device/ROC/Data/HistoryRecord.cs | 0 .../Device/ROC/Data/IRocParameterData.cs | 0 .../Device/ROC/Data/Int16Parameter.cs | 0 .../Device/ROC/Data/Int32Parameter.cs | 0 .../Device/ROC/Data/Int8Parameter.cs | 0 .../Device/ROC/Data/Parameter.cs | 26 - .../Device/ROC/Data/ParameterType.cs | 30 + .../Device/ROC/Data/RocPlusAlarmRecord.cs | 0 .../Device/ROC/Data/RocPlusEventRecord.cs | 1 + .../Device/ROC/Data/RocPlusHistoryRecord.cs | 0 .../Device/ROC/Data/TimeParameter.cs | 0 .../Device/ROC/Data/Tlp.cs | 0 .../Device/ROC/Data/TlpParameter.cs | 0 .../Device/ROC/Data/UInt16Parameter.cs | 0 .../Device/ROC/Data/UInt32Parameter.cs | 0 .../Device/ROC/Data/UInt8Parameter.cs | 0 .../Device/ROC/Device.cs | 0 .../Device/ROC/FST/Arguments/ArgumentBase.cs | 0 .../ROC/FST/Arguments/ArgumentDataType.cs | 0 .../Device/ROC/FST/Arguments/ArgumentType.cs | 0 .../Device/ROC/FST/Arguments/DatabasePoint.cs | 4 +- .../DatabasePointOrConstantValueArgument.cs | 0 .../Device/ROC/FST/Arguments/NullArgument.cs | 0 .../ROC/FST/Instructions/AddInstruction.cs | 0 .../ROC/FST/Instructions/InstructionBase.cs | 0 .../FST/Instructions/InstructionCategory.cs | 0 .../ROC/FST/Instructions/InstructionType.cs | 0 .../Device/ROC/IO/Transport/Transport.cs | 0 .../Device/ROC/Message/IRocMessage.cs | 0 .../Device/ROC/Message/IRocRequestMessage.cs | 0 .../Device/ROC/Message/IRocResponseMessage.cs | 0 .../Device/ROC/Message/OpCode007Request.cs | 0 .../Device/ROC/Message/OpCode007Response.cs | 0 .../Device/ROC/Message/OpCode008Request.cs | 0 .../Device/ROC/Message/OpCode008Response.cs | 0 .../Device/ROC/Message/OpCode017Request.cs | 0 .../Device/ROC/Message/OpCode017Response.cs | 0 .../Device/ROC/Message/OpCode080Function.cs | 0 .../Device/ROC/Message/OpCode080Request.cs | 0 .../Device/ROC/Message/OpCode080Response.cs | 0 .../Device/ROC/Message/OpCode118Request.cs | 0 .../Device/ROC/Message/OpCode118Response.cs | 0 .../Device/ROC/Message/OpCode119Request.cs | 0 .../Device/ROC/Message/OpCode119Response.cs | 0 .../Device/ROC/Message/OpCode120Request.cs | 0 .../Device/ROC/Message/OpCode120Response.cs | 0 .../Device/ROC/Message/OpCode121Request.cs | 0 .../Device/ROC/Message/OpCode121Response.cs | 0 .../Device/ROC/Message/OpCode122Request.cs | 0 .../Device/ROC/Message/OpCode122Response.cs | 0 .../Device/ROC/Message/OpCode126Request.cs | 0 .../Device/ROC/Message/OpCode126Response.cs | 0 .../Device/ROC/Message/OpCode130Request.cs | 0 .../Device/ROC/Message/OpCode130Response.cs | 0 .../Device/ROC/Message/OpCode131Request.cs | 0 .../Device/ROC/Message/OpCode131Response.cs | 0 .../Device/ROC/Message/OpCode132Request.cs | 0 .../Device/ROC/Message/OpCode132Response.cs | 0 .../Device/ROC/Message/OpCode136Request.cs | 0 .../Device/ROC/Message/OpCode136Response.cs | 0 .../Device/ROC/Message/OpCode139Request.cs | 0 .../Device/ROC/Message/OpCode139Response.cs | 0 .../Device/ROC/Message/OpCode165Request .cs | 0 .../Device/ROC/Message/OpCode165Response.cs | 0 .../Device/ROC/Message/OpCode166Request.cs | 0 .../Device/ROC/Message/OpCode166Response.cs | 0 .../Device/ROC/Message/OpCode167Request.cs | 0 .../Device/ROC/Message/OpCode167Response.cs | 0 .../Device/ROC/Message/OpCode180Request.cs | 0 .../Device/ROC/Message/OpCode180Response.cs | 0 .../Device/ROC/Message/OpCode181Request.cs | 0 .../Device/ROC/Message/OpCode181Response.cs | 0 .../Device/ROC/Message/OpCode255Response.cs | 0 .../Device/ROC/Message/ParameterDatabase.cs | 0 .../Device/ROC/Message/RocMessage.cs | 0 .../Device/ROC/Message/RocMessageFactory.cs | 0 .../Device/ROC/OpCode255Exception.cs | 0 .../Device/ROC/ROCMaster.cs | 0 .../Device/ROC/Utility/Crc16.cs | 0 DeviceSQL.Devices/DeviceSQL.Devices.csproj | 206 ++++ .../IO/Channels/ChannelTraceEventArgs.cs | 0 .../IO/Channels/ChannelTraceListener.cs | 0 .../IO/Channels/HexConverter.cs | 0 .../IO/Channels/IChannel.cs | 0 .../IO/Channels/IMuxChannel.cs | 0 .../IO/Channels/SerialPortChannel.cs | 0 .../IO/Channels/SerialPortMuxChannel.cs | 2 +- .../IO/Channels/TcpChannel.cs | 0 .../IO/Channels/TcpMuxChannel.cs | 2 +- .../IO/Channels/TimedThreadBlocker.cs | 0 .../IO/Channels/Transport/ITransport.cs | 0 DeviceSQL.Devices/Properties/AssemblyInfo.cs | 36 + DeviceSQL.SQLTypes/DeviceSQL.SQLTypes.csproj | 238 +++++ .../ModbusMaster/BooleanRegister.cs | 2 +- .../ModbusMaster/BooleanRegisterArray.cs | 2 +- .../ModbusMaster/CoilRegister.cs | 2 +- .../ModbusMaster/CoilRegisterArray.cs | 2 +- .../ModbusMaster/DiscreteInputRegister.cs | 2 +- .../DiscreteInputRegisterArray.cs | 2 +- .../ModbusMaster/EventArchiveRecord.cs | 2 +- .../ModbusMaster/EventArchiveRecordArray.cs | 2 +- .../ModbusMaster/FloatRegister.cs | 2 +- .../ModbusMaster/FloatRegisterArray.cs | 2 +- .../ModbusMaster/HistoryArchiveRecord.cs | 2 +- .../ModbusMaster/HistoryArchiveRecordArray.cs | 2 +- .../ModbusMaster/HoldingRegister.cs | 2 +- .../ModbusMaster/HoldingRegisterArray.cs | 2 +- .../ModbusMaster/InputRegister.cs | 2 +- .../ModbusMaster/InputRegisterArray.cs | 2 +- .../ModbusMaster/LongRegister.cs | 2 +- .../ModbusMaster/LongRegisterArray.cs | 2 +- .../ModbusMaster/ModbusAddress.cs | 2 +- .../ModbusMaster/ShortRegister.cs | 2 +- .../ModbusMaster/ShortRegisterArray.cs | 2 +- .../ModbusMaster/StringRegister.cs | 2 +- .../ModbusMaster/StringRegisterArray.cs | 2 +- DeviceSQL.SQLTypes/Properties/AssemblyInfo.cs | 36 + .../ROCMaster/AlarmRecord.cs | 2 +- .../ROCMaster/AlarmRecordArray.cs | 2 +- .../ROCMaster/ArchiveInformation.cs | 2 +- .../ROCMaster/AuditLogRecord.cs | 3 +- .../ROCMaster/AuditLogRecordArray.cs | 2 +- .../ROCMaster/EventRecord.cs | 3 +- .../ROCMaster/EventRecordArray.cs | 2 +- .../ROCMaster/FSTInformation.cs | 2 +- .../ROCMaster/HistoryRecord.cs | 2 +- .../ROCMaster/HistoryRecordArray.cs | 2 +- .../ROCMaster/Parameter.cs | 3 +- .../ROCMaster/ParameterArray.cs | 2 +- .../ROCMaster/ROCPlusAlarmRecord.cs | 3 +- .../ROCMaster/ROCPlusAlarmRecordArray.cs | 2 +- .../ROCMaster/ROCPlusEventRecord.cs | 3 +- .../ROCMaster/ROCPlusEventRecordArray.cs | 2 +- .../ROCMaster/ROCPlusHistoryPointArray.cs | 2 +- .../ROCMaster/ROCPlusHistoryRecord.cs | 2 +- .../ROCMaster/ROCPlusHistoryRecordArray.cs | 2 +- DeviceSQL.Service/App.config | 6 + DeviceSQL.Service/DeviceSQL.Service.csproj | 72 ++ DeviceSQL.Service/Program.cs | 25 + .../ProjectInstaller.Designer.cs | 56 + DeviceSQL.Service/ProjectInstaller.cs | 19 + DeviceSQL.Service/ProjectInstaller.resx | 129 +++ DeviceSQL.Service/Properties/AssemblyInfo.cs | 36 + DeviceSQL.Service/Service1.Designer.cs | 37 + DeviceSQL.Service/Service1.cs | 28 + DeviceSQL.Services/App.config | 43 + DeviceSQL.Services/DeviceSQL.Services.csproj | 83 ++ DeviceSQL.Services/IService.cs | 23 + DeviceSQL.Services/Properties/AssemblyInfo.cs | 36 + DeviceSQL.Services/Service.cs | 39 + DeviceSQL.sln | 42 +- DeviceSQL/DeviceSQL.sqlproj | 323 ------ .../Modbus_Application_Protocol_V1_1b3.pdf | Bin 818663 -> 0 bytes .../ChannelManager/DisableChannelTracing.cs | 45 - .../ChannelManager/EnableChannelTracing.cs | 45 - .../Functions/ChannelManager/GetChannels.cs | 54 - .../RegisterSerialPortChannel.cs | 76 -- .../ChannelManager/RegisterTcpChannel.cs | 89 -- .../Functions/ChannelManager/TraceChannels.cs | 91 -- .../ChannelManager/UnregisterChannel.cs | 43 - .../Functions/DeviceManager/GetDevices.cs | 73 -- .../DeviceManager/RegisterModbusMaster.cs | 54 - .../DeviceManager/RegisterROCMaster.cs | 56 - .../DeviceManager/UnregisterDevice.cs | 42 - DeviceSQL/Functions/ModbusMaster/ReadCoils.cs | 24 - .../ModbusMaster/ReadDiscreteInputs.cs | 24 - .../ModbusMaster/ReadEventArchiveRecords.cs | 22 - .../Functions/ModbusMaster/ReadFloats.cs | 24 - .../ModbusMaster/ReadHistoryArchiveRecord.cs | 22 - .../Functions/ModbusMaster/ReadHoldings.cs | 24 - .../Functions/ModbusMaster/ReadInputs.cs | 24 - DeviceSQL/Functions/ModbusMaster/ReadLongs.cs | 24 - .../Functions/ModbusMaster/ReadShorts.cs | 24 - .../Functions/ModbusMaster/ReadString.cs | 24 - .../Functions/ModbusMaster/WriteBoolean.cs | 23 - .../Functions/ModbusMaster/WriteFloats.cs | 24 - .../ROCMaster/ClearAuditLogEventFlags.cs | 21 - DeviceSQL/Functions/ROCMaster/GetAlarms.cs | 22 - .../Functions/ROCMaster/GetArchiveInfo.cs | 22 - .../Functions/ROCMaster/GetAuditLogRecords.cs | 22 - .../ROCMaster/GetCurrentROCPlusAlarmIndex.cs | 21 - .../ROCMaster/GetCurrentROCPlusEventIndex.cs | 21 - .../GetCurrentROCPlusHistorySegmentIndex.cs | 21 - .../Functions/ROCMaster/GetDoubleValue.cs | 24 - DeviceSQL/Functions/ROCMaster/GetEvents.cs | 22 - .../Functions/ROCMaster/GetFloatValue.cs | 25 - .../Functions/ROCMaster/GetFstInformation.cs | 46 - DeviceSQL/Functions/ROCMaster/GetHistory.cs | 22 - .../Functions/ROCMaster/GetInt16Value.cs | 24 - .../Functions/ROCMaster/GetInt32Value.cs | 24 - DeviceSQL/Functions/ROCMaster/GetInt8Value.cs | 23 - .../Functions/ROCMaster/GetMinutelyHistory.cs | 21 - .../Functions/ROCMaster/GetROCPlusAlarms.cs | 22 - .../GetROCPlusConfiguredHistoryPoints.cs | 21 - .../Functions/ROCMaster/GetROCPlusEvents.cs | 22 - .../Functions/ROCMaster/GetROCPlusHistory.cs | 22 - .../GetROCPlusHistoryByHistoryPointArray.cs | 22 - .../ROCMaster/GetRealTimeClockValue.cs | 20 - .../GetRealTimeClockValueWithCentury.cs | 21 - .../Functions/ROCMaster/GetStringValue.cs | 46 - DeviceSQL/Functions/ROCMaster/GetTimeValue.cs | 22 - .../Functions/ROCMaster/GetUInt16Value.cs | 23 - .../Functions/ROCMaster/GetUInt32Value.cs | 23 - .../Functions/ROCMaster/GetUInt8Value.cs | 23 - .../Functions/ROCMaster/ReadParameters.cs | 101 -- .../Functions/ROCMaster/SetFloatValue.cs | 23 - .../Functions/ROCMaster/SetInt16Value.cs | 23 - .../Functions/ROCMaster/SetInt32Value.cs | 23 - DeviceSQL/Functions/ROCMaster/SetInt8Value.cs | 24 - .../ROCMaster/SetOperatorIdentification.cs | 22 - .../Functions/ROCMaster/SetRealTimeClock.cs | 21 - .../Functions/ROCMaster/SetStringValue.cs | 47 - DeviceSQL/Functions/ROCMaster/SetTimeValue.cs | 23 - .../Functions/ROCMaster/SetUInt16Value.cs | 24 - .../Functions/ROCMaster/SetUInt32Value.cs | 24 - .../Functions/ROCMaster/SetUInt8Value.cs | 23 - .../Functions/ROCMaster/WriteParameters.cs | 93 -- .../Functions/Watchdog/GetCounterValue.cs | 28 - DeviceSQL/Functions/Watchdog/IsAlive.cs | 29 - DeviceSQL/Functions/Watchdog/Run.cs | 28 - DeviceSQL/Functions/Watchdog/Stop.cs | 43 - DeviceSQL/IOC/ISimpleIOC.cs | 227 ----- DeviceSQL/IOC/PreferredConstructor.cs | 31 - DeviceSQL/IOC/SimpleIOC.cs | 961 ------------------ .../ServiceLocation/ActivationException.cs | 44 - DeviceSQL/ServiceLocation/IServiceLocator.cs | 75 -- DeviceSQL/ServiceLocation/ServiceLocator.cs | 52 - .../ServiceLocation/ServiceLocatorImplBase.cs | 181 ---- .../ServiceLocation/ServiceLocatorProvider.cs | 10 - ...tialPressureMeterProcessVariableAlarms.sql | 26 - ...tialPressureMeterProcessVariableValues.sql | 41 - DeviceSQL/Tables/FlowSQL/MeterAttributes.sql | 9 - DeviceSQL/Tables/FlowSQL/Meters.sql | 8 - .../ROCMaster/FloBoss.103.MeterHistory.sql | 16 - ...FloBoss.103.MeterProcessVariableAlarms.sql | 26 - .../FloBoss.103.MeterProcessVariables.sql | 46 - .../Tables/ROCMaster/ROCChannelGroup.sql | 10 - DeviceSQL/Tables/ROCMaster/ROCChannels.sql | 12 - DeviceSQL/Tables/ROCMaster/ROCMeters.sql | 14 - DeviceSQL/Watchdog/Worker.cs | 144 --- 310 files changed, 1272 insertions(+), 4546 deletions(-) rename {DeviceSQL => DeviceSQL.Devices}/Device/IMaster.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/IMessage.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Crc16.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Data/BooleanRegister.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Data/CoilRegister.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Data/DiscreteInputRegister.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Data/EventArchiveRecord.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Data/FloatRegister.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Data/HistoryArchiveRecord.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Data/HoldingRegister.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Data/IModbusRegisterData.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Data/InputRegister.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Data/LongRegister.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Data/ModbusAddress.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Data/ModbusRegister.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Data/ShortRegister.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Data/StringRegister.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Device.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/IO/Transport/Transport.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/IModbusMessage.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/IModbusRequestMessage.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/IModbusResponseMessage.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ModbusErrorResponse.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ModbusMessage.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ModbusMessageFactory.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadCoilRegistersRequest.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadCoilRegistersResponse.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadDiscreteInputRegistersRequest.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadDiscreteInputRegistersResponse.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadEventArchiveRequest.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadEventArchiveResponse.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadFloatsRequest.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadFloatsResponse.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadHistoryArchiveRequest.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadHistoryArchiveResponse.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadHoldingRegistersRequest.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadHoldingRegistersResponse.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadInputRegistersRequest.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadInputRegistersResponse.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadLongsRequest.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadLongsResponse.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadShortsRequest.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadShortsResponse.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadStringRequest.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/ReadStringResponse.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/WriteBooleanRequest.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/WriteBooleanResponse.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/WriteFloatsRequest.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/Message/WriteFloatsResponse.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/ModbusConverter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/ModbusMaster.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/Modbus/ModbusSlaveException.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Crc16.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/Ac10Parameter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/Ac12Parameter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/Ac20Parameter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/Ac30Parameter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/Ac3Parameter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/Ac40Parameter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/Ac7Parameter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/AlarmRecord.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/ArchiveInfo.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/AuditLogRecord.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/BinParameter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/DoubleParameter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/EventRecord.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/FlpParameter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/FstCodeChunk.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/FstHeaderInfo.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/HistoryPointConfiguration.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/HistoryRecord.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/IRocParameterData.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/Int16Parameter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/Int32Parameter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/Int8Parameter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/Parameter.cs (83%) create mode 100644 DeviceSQL.Devices/Device/ROC/Data/ParameterType.cs rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/RocPlusAlarmRecord.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/RocPlusEventRecord.cs (99%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/RocPlusHistoryRecord.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/TimeParameter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/Tlp.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/TlpParameter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/UInt16Parameter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/UInt32Parameter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Data/UInt8Parameter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Device.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/FST/Arguments/ArgumentBase.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/FST/Arguments/ArgumentDataType.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/FST/Arguments/ArgumentType.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/FST/Arguments/DatabasePoint.cs (86%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/FST/Arguments/DatabasePointOrConstantValueArgument.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/FST/Arguments/NullArgument.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/FST/Instructions/AddInstruction.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/FST/Instructions/InstructionBase.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/FST/Instructions/InstructionCategory.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/FST/Instructions/InstructionType.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/IO/Transport/Transport.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/IRocMessage.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/IRocRequestMessage.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/IRocResponseMessage.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode007Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode007Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode008Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode008Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode017Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode017Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode080Function.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode080Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode080Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode118Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode118Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode119Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode119Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode120Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode120Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode121Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode121Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode122Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode122Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode126Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode126Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode130Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode130Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode131Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode131Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode132Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode132Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode136Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode136Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode139Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode139Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode165Request .cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode165Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode166Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode166Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode167Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode167Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode180Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode180Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode181Request.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode181Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/OpCode255Response.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/ParameterDatabase.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/RocMessage.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Message/RocMessageFactory.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/OpCode255Exception.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/ROCMaster.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/Device/ROC/Utility/Crc16.cs (100%) create mode 100644 DeviceSQL.Devices/DeviceSQL.Devices.csproj rename {DeviceSQL => DeviceSQL.Devices}/IO/Channels/ChannelTraceEventArgs.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/IO/Channels/ChannelTraceListener.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/IO/Channels/HexConverter.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/IO/Channels/IChannel.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/IO/Channels/IMuxChannel.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/IO/Channels/SerialPortChannel.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/IO/Channels/SerialPortMuxChannel.cs (96%) rename {DeviceSQL => DeviceSQL.Devices}/IO/Channels/TcpChannel.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/IO/Channels/TcpMuxChannel.cs (99%) rename {DeviceSQL => DeviceSQL.Devices}/IO/Channels/TimedThreadBlocker.cs (100%) rename {DeviceSQL => DeviceSQL.Devices}/IO/Channels/Transport/ITransport.cs (100%) create mode 100644 DeviceSQL.Devices/Properties/AssemblyInfo.cs create mode 100644 DeviceSQL.SQLTypes/DeviceSQL.SQLTypes.csproj rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/BooleanRegister.cs (98%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/BooleanRegisterArray.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/CoilRegister.cs (98%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/CoilRegisterArray.cs (98%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/DiscreteInputRegister.cs (98%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/DiscreteInputRegisterArray.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/EventArchiveRecord.cs (98%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/EventArchiveRecordArray.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/FloatRegister.cs (98%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/FloatRegisterArray.cs (98%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/HistoryArchiveRecord.cs (98%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/HistoryArchiveRecordArray.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/HoldingRegister.cs (98%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/HoldingRegisterArray.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/InputRegister.cs (98%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/InputRegisterArray.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/LongRegister.cs (98%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/LongRegisterArray.cs (98%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/ModbusAddress.cs (98%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/ShortRegister.cs (98%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/ShortRegisterArray.cs (98%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/StringRegister.cs (98%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ModbusMaster/StringRegisterArray.cs (99%) create mode 100644 DeviceSQL.SQLTypes/Properties/AssemblyInfo.cs rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/AlarmRecord.cs (98%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/AlarmRecordArray.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/ArchiveInformation.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/AuditLogRecord.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/AuditLogRecordArray.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/EventRecord.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/EventRecordArray.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/FSTInformation.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/HistoryRecord.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/HistoryRecordArray.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/Parameter.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/ParameterArray.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/ROCPlusAlarmRecord.cs (98%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/ROCPlusAlarmRecordArray.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/ROCPlusEventRecord.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/ROCPlusEventRecordArray.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/ROCPlusHistoryPointArray.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/ROCPlusHistoryRecord.cs (99%) rename {DeviceSQL/Types => DeviceSQL.SQLTypes}/ROCMaster/ROCPlusHistoryRecordArray.cs (99%) create mode 100644 DeviceSQL.Service/App.config create mode 100644 DeviceSQL.Service/DeviceSQL.Service.csproj create mode 100644 DeviceSQL.Service/Program.cs create mode 100644 DeviceSQL.Service/ProjectInstaller.Designer.cs create mode 100644 DeviceSQL.Service/ProjectInstaller.cs create mode 100644 DeviceSQL.Service/ProjectInstaller.resx create mode 100644 DeviceSQL.Service/Properties/AssemblyInfo.cs create mode 100644 DeviceSQL.Service/Service1.Designer.cs create mode 100644 DeviceSQL.Service/Service1.cs create mode 100644 DeviceSQL.Services/App.config create mode 100644 DeviceSQL.Services/DeviceSQL.Services.csproj create mode 100644 DeviceSQL.Services/IService.cs create mode 100644 DeviceSQL.Services/Properties/AssemblyInfo.cs create mode 100644 DeviceSQL.Services/Service.cs delete mode 100644 DeviceSQL/Documentation/Modbus_Application_Protocol_V1_1b3.pdf delete mode 100644 DeviceSQL/Functions/ChannelManager/DisableChannelTracing.cs delete mode 100644 DeviceSQL/Functions/ChannelManager/EnableChannelTracing.cs delete mode 100644 DeviceSQL/Functions/ChannelManager/GetChannels.cs delete mode 100644 DeviceSQL/Functions/ChannelManager/RegisterSerialPortChannel.cs delete mode 100644 DeviceSQL/Functions/ChannelManager/RegisterTcpChannel.cs delete mode 100644 DeviceSQL/Functions/ChannelManager/TraceChannels.cs delete mode 100644 DeviceSQL/Functions/ChannelManager/UnregisterChannel.cs delete mode 100644 DeviceSQL/Functions/DeviceManager/GetDevices.cs delete mode 100644 DeviceSQL/Functions/DeviceManager/RegisterModbusMaster.cs delete mode 100644 DeviceSQL/Functions/DeviceManager/RegisterROCMaster.cs delete mode 100644 DeviceSQL/Functions/DeviceManager/UnregisterDevice.cs delete mode 100644 DeviceSQL/Functions/ModbusMaster/ReadCoils.cs delete mode 100644 DeviceSQL/Functions/ModbusMaster/ReadDiscreteInputs.cs delete mode 100644 DeviceSQL/Functions/ModbusMaster/ReadEventArchiveRecords.cs delete mode 100644 DeviceSQL/Functions/ModbusMaster/ReadFloats.cs delete mode 100644 DeviceSQL/Functions/ModbusMaster/ReadHistoryArchiveRecord.cs delete mode 100644 DeviceSQL/Functions/ModbusMaster/ReadHoldings.cs delete mode 100644 DeviceSQL/Functions/ModbusMaster/ReadInputs.cs delete mode 100644 DeviceSQL/Functions/ModbusMaster/ReadLongs.cs delete mode 100644 DeviceSQL/Functions/ModbusMaster/ReadShorts.cs delete mode 100644 DeviceSQL/Functions/ModbusMaster/ReadString.cs delete mode 100644 DeviceSQL/Functions/ModbusMaster/WriteBoolean.cs delete mode 100644 DeviceSQL/Functions/ModbusMaster/WriteFloats.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/ClearAuditLogEventFlags.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetAlarms.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetArchiveInfo.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetAuditLogRecords.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetCurrentROCPlusAlarmIndex.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetCurrentROCPlusEventIndex.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetCurrentROCPlusHistorySegmentIndex.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetDoubleValue.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetEvents.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetFloatValue.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetFstInformation.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetHistory.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetInt16Value.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetInt32Value.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetInt8Value.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetMinutelyHistory.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetROCPlusAlarms.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetROCPlusConfiguredHistoryPoints.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetROCPlusEvents.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetROCPlusHistory.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetROCPlusHistoryByHistoryPointArray.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetRealTimeClockValue.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetRealTimeClockValueWithCentury.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetStringValue.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetTimeValue.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetUInt16Value.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetUInt32Value.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/GetUInt8Value.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/ReadParameters.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/SetFloatValue.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/SetInt16Value.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/SetInt32Value.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/SetInt8Value.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/SetOperatorIdentification.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/SetRealTimeClock.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/SetStringValue.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/SetTimeValue.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/SetUInt16Value.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/SetUInt32Value.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/SetUInt8Value.cs delete mode 100644 DeviceSQL/Functions/ROCMaster/WriteParameters.cs delete mode 100644 DeviceSQL/Functions/Watchdog/GetCounterValue.cs delete mode 100644 DeviceSQL/Functions/Watchdog/IsAlive.cs delete mode 100644 DeviceSQL/Functions/Watchdog/Run.cs delete mode 100644 DeviceSQL/Functions/Watchdog/Stop.cs delete mode 100644 DeviceSQL/IOC/ISimpleIOC.cs delete mode 100644 DeviceSQL/IOC/PreferredConstructor.cs delete mode 100644 DeviceSQL/IOC/SimpleIOC.cs delete mode 100644 DeviceSQL/ServiceLocation/ActivationException.cs delete mode 100644 DeviceSQL/ServiceLocation/IServiceLocator.cs delete mode 100644 DeviceSQL/ServiceLocation/ServiceLocator.cs delete mode 100644 DeviceSQL/ServiceLocation/ServiceLocatorImplBase.cs delete mode 100644 DeviceSQL/ServiceLocation/ServiceLocatorProvider.cs delete mode 100644 DeviceSQL/Tables/FlowSQL/DifferentialPressureMeterProcessVariableAlarms.sql delete mode 100644 DeviceSQL/Tables/FlowSQL/DifferentialPressureMeterProcessVariableValues.sql delete mode 100644 DeviceSQL/Tables/FlowSQL/MeterAttributes.sql delete mode 100644 DeviceSQL/Tables/FlowSQL/Meters.sql delete mode 100644 DeviceSQL/Tables/ROCMaster/FloBoss.103.MeterHistory.sql delete mode 100644 DeviceSQL/Tables/ROCMaster/FloBoss.103.MeterProcessVariableAlarms.sql delete mode 100644 DeviceSQL/Tables/ROCMaster/FloBoss.103.MeterProcessVariables.sql delete mode 100644 DeviceSQL/Tables/ROCMaster/ROCChannelGroup.sql delete mode 100644 DeviceSQL/Tables/ROCMaster/ROCChannels.sql delete mode 100644 DeviceSQL/Tables/ROCMaster/ROCMeters.sql delete mode 100644 DeviceSQL/Watchdog/Worker.cs diff --git a/DeviceSQL/Device/IMaster.cs b/DeviceSQL.Devices/Device/IMaster.cs similarity index 100% rename from DeviceSQL/Device/IMaster.cs rename to DeviceSQL.Devices/Device/IMaster.cs diff --git a/DeviceSQL/Device/IMessage.cs b/DeviceSQL.Devices/Device/IMessage.cs similarity index 100% rename from DeviceSQL/Device/IMessage.cs rename to DeviceSQL.Devices/Device/IMessage.cs diff --git a/DeviceSQL/Device/Modbus/Crc16.cs b/DeviceSQL.Devices/Device/Modbus/Crc16.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Crc16.cs rename to DeviceSQL.Devices/Device/Modbus/Crc16.cs diff --git a/DeviceSQL/Device/Modbus/Data/BooleanRegister.cs b/DeviceSQL.Devices/Device/Modbus/Data/BooleanRegister.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Data/BooleanRegister.cs rename to DeviceSQL.Devices/Device/Modbus/Data/BooleanRegister.cs diff --git a/DeviceSQL/Device/Modbus/Data/CoilRegister.cs b/DeviceSQL.Devices/Device/Modbus/Data/CoilRegister.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Data/CoilRegister.cs rename to DeviceSQL.Devices/Device/Modbus/Data/CoilRegister.cs diff --git a/DeviceSQL/Device/Modbus/Data/DiscreteInputRegister.cs b/DeviceSQL.Devices/Device/Modbus/Data/DiscreteInputRegister.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Data/DiscreteInputRegister.cs rename to DeviceSQL.Devices/Device/Modbus/Data/DiscreteInputRegister.cs diff --git a/DeviceSQL/Device/Modbus/Data/EventArchiveRecord.cs b/DeviceSQL.Devices/Device/Modbus/Data/EventArchiveRecord.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Data/EventArchiveRecord.cs rename to DeviceSQL.Devices/Device/Modbus/Data/EventArchiveRecord.cs diff --git a/DeviceSQL/Device/Modbus/Data/FloatRegister.cs b/DeviceSQL.Devices/Device/Modbus/Data/FloatRegister.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Data/FloatRegister.cs rename to DeviceSQL.Devices/Device/Modbus/Data/FloatRegister.cs diff --git a/DeviceSQL/Device/Modbus/Data/HistoryArchiveRecord.cs b/DeviceSQL.Devices/Device/Modbus/Data/HistoryArchiveRecord.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Data/HistoryArchiveRecord.cs rename to DeviceSQL.Devices/Device/Modbus/Data/HistoryArchiveRecord.cs diff --git a/DeviceSQL/Device/Modbus/Data/HoldingRegister.cs b/DeviceSQL.Devices/Device/Modbus/Data/HoldingRegister.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Data/HoldingRegister.cs rename to DeviceSQL.Devices/Device/Modbus/Data/HoldingRegister.cs diff --git a/DeviceSQL/Device/Modbus/Data/IModbusRegisterData.cs b/DeviceSQL.Devices/Device/Modbus/Data/IModbusRegisterData.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Data/IModbusRegisterData.cs rename to DeviceSQL.Devices/Device/Modbus/Data/IModbusRegisterData.cs diff --git a/DeviceSQL/Device/Modbus/Data/InputRegister.cs b/DeviceSQL.Devices/Device/Modbus/Data/InputRegister.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Data/InputRegister.cs rename to DeviceSQL.Devices/Device/Modbus/Data/InputRegister.cs diff --git a/DeviceSQL/Device/Modbus/Data/LongRegister.cs b/DeviceSQL.Devices/Device/Modbus/Data/LongRegister.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Data/LongRegister.cs rename to DeviceSQL.Devices/Device/Modbus/Data/LongRegister.cs diff --git a/DeviceSQL/Device/Modbus/Data/ModbusAddress.cs b/DeviceSQL.Devices/Device/Modbus/Data/ModbusAddress.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Data/ModbusAddress.cs rename to DeviceSQL.Devices/Device/Modbus/Data/ModbusAddress.cs diff --git a/DeviceSQL/Device/Modbus/Data/ModbusRegister.cs b/DeviceSQL.Devices/Device/Modbus/Data/ModbusRegister.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Data/ModbusRegister.cs rename to DeviceSQL.Devices/Device/Modbus/Data/ModbusRegister.cs diff --git a/DeviceSQL/Device/Modbus/Data/ShortRegister.cs b/DeviceSQL.Devices/Device/Modbus/Data/ShortRegister.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Data/ShortRegister.cs rename to DeviceSQL.Devices/Device/Modbus/Data/ShortRegister.cs diff --git a/DeviceSQL/Device/Modbus/Data/StringRegister.cs b/DeviceSQL.Devices/Device/Modbus/Data/StringRegister.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Data/StringRegister.cs rename to DeviceSQL.Devices/Device/Modbus/Data/StringRegister.cs diff --git a/DeviceSQL/Device/Modbus/Device.cs b/DeviceSQL.Devices/Device/Modbus/Device.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Device.cs rename to DeviceSQL.Devices/Device/Modbus/Device.cs diff --git a/DeviceSQL/Device/Modbus/IO/Transport/Transport.cs b/DeviceSQL.Devices/Device/Modbus/IO/Transport/Transport.cs similarity index 100% rename from DeviceSQL/Device/Modbus/IO/Transport/Transport.cs rename to DeviceSQL.Devices/Device/Modbus/IO/Transport/Transport.cs diff --git a/DeviceSQL/Device/Modbus/Message/IModbusMessage.cs b/DeviceSQL.Devices/Device/Modbus/Message/IModbusMessage.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/IModbusMessage.cs rename to DeviceSQL.Devices/Device/Modbus/Message/IModbusMessage.cs diff --git a/DeviceSQL/Device/Modbus/Message/IModbusRequestMessage.cs b/DeviceSQL.Devices/Device/Modbus/Message/IModbusRequestMessage.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/IModbusRequestMessage.cs rename to DeviceSQL.Devices/Device/Modbus/Message/IModbusRequestMessage.cs diff --git a/DeviceSQL/Device/Modbus/Message/IModbusResponseMessage.cs b/DeviceSQL.Devices/Device/Modbus/Message/IModbusResponseMessage.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/IModbusResponseMessage.cs rename to DeviceSQL.Devices/Device/Modbus/Message/IModbusResponseMessage.cs diff --git a/DeviceSQL/Device/Modbus/Message/ModbusErrorResponse.cs b/DeviceSQL.Devices/Device/Modbus/Message/ModbusErrorResponse.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ModbusErrorResponse.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ModbusErrorResponse.cs diff --git a/DeviceSQL/Device/Modbus/Message/ModbusMessage.cs b/DeviceSQL.Devices/Device/Modbus/Message/ModbusMessage.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ModbusMessage.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ModbusMessage.cs diff --git a/DeviceSQL/Device/Modbus/Message/ModbusMessageFactory.cs b/DeviceSQL.Devices/Device/Modbus/Message/ModbusMessageFactory.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ModbusMessageFactory.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ModbusMessageFactory.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadCoilRegistersRequest.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadCoilRegistersRequest.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadCoilRegistersRequest.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadCoilRegistersRequest.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadCoilRegistersResponse.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadCoilRegistersResponse.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadCoilRegistersResponse.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadCoilRegistersResponse.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadDiscreteInputRegistersRequest.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadDiscreteInputRegistersRequest.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadDiscreteInputRegistersRequest.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadDiscreteInputRegistersRequest.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadDiscreteInputRegistersResponse.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadDiscreteInputRegistersResponse.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadDiscreteInputRegistersResponse.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadDiscreteInputRegistersResponse.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadEventArchiveRequest.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadEventArchiveRequest.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadEventArchiveRequest.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadEventArchiveRequest.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadEventArchiveResponse.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadEventArchiveResponse.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadEventArchiveResponse.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadEventArchiveResponse.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadFloatsRequest.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadFloatsRequest.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadFloatsRequest.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadFloatsRequest.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadFloatsResponse.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadFloatsResponse.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadFloatsResponse.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadFloatsResponse.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadHistoryArchiveRequest.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadHistoryArchiveRequest.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadHistoryArchiveRequest.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadHistoryArchiveRequest.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadHistoryArchiveResponse.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadHistoryArchiveResponse.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadHistoryArchiveResponse.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadHistoryArchiveResponse.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadHoldingRegistersRequest.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadHoldingRegistersRequest.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadHoldingRegistersRequest.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadHoldingRegistersRequest.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadHoldingRegistersResponse.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadHoldingRegistersResponse.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadHoldingRegistersResponse.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadHoldingRegistersResponse.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadInputRegistersRequest.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadInputRegistersRequest.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadInputRegistersRequest.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadInputRegistersRequest.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadInputRegistersResponse.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadInputRegistersResponse.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadInputRegistersResponse.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadInputRegistersResponse.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadLongsRequest.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadLongsRequest.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadLongsRequest.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadLongsRequest.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadLongsResponse.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadLongsResponse.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadLongsResponse.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadLongsResponse.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadShortsRequest.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadShortsRequest.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadShortsRequest.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadShortsRequest.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadShortsResponse.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadShortsResponse.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadShortsResponse.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadShortsResponse.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadStringRequest.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadStringRequest.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadStringRequest.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadStringRequest.cs diff --git a/DeviceSQL/Device/Modbus/Message/ReadStringResponse.cs b/DeviceSQL.Devices/Device/Modbus/Message/ReadStringResponse.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/ReadStringResponse.cs rename to DeviceSQL.Devices/Device/Modbus/Message/ReadStringResponse.cs diff --git a/DeviceSQL/Device/Modbus/Message/WriteBooleanRequest.cs b/DeviceSQL.Devices/Device/Modbus/Message/WriteBooleanRequest.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/WriteBooleanRequest.cs rename to DeviceSQL.Devices/Device/Modbus/Message/WriteBooleanRequest.cs diff --git a/DeviceSQL/Device/Modbus/Message/WriteBooleanResponse.cs b/DeviceSQL.Devices/Device/Modbus/Message/WriteBooleanResponse.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/WriteBooleanResponse.cs rename to DeviceSQL.Devices/Device/Modbus/Message/WriteBooleanResponse.cs diff --git a/DeviceSQL/Device/Modbus/Message/WriteFloatsRequest.cs b/DeviceSQL.Devices/Device/Modbus/Message/WriteFloatsRequest.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/WriteFloatsRequest.cs rename to DeviceSQL.Devices/Device/Modbus/Message/WriteFloatsRequest.cs diff --git a/DeviceSQL/Device/Modbus/Message/WriteFloatsResponse.cs b/DeviceSQL.Devices/Device/Modbus/Message/WriteFloatsResponse.cs similarity index 100% rename from DeviceSQL/Device/Modbus/Message/WriteFloatsResponse.cs rename to DeviceSQL.Devices/Device/Modbus/Message/WriteFloatsResponse.cs diff --git a/DeviceSQL/Device/Modbus/ModbusConverter.cs b/DeviceSQL.Devices/Device/Modbus/ModbusConverter.cs similarity index 100% rename from DeviceSQL/Device/Modbus/ModbusConverter.cs rename to DeviceSQL.Devices/Device/Modbus/ModbusConverter.cs diff --git a/DeviceSQL/Device/Modbus/ModbusMaster.cs b/DeviceSQL.Devices/Device/Modbus/ModbusMaster.cs similarity index 100% rename from DeviceSQL/Device/Modbus/ModbusMaster.cs rename to DeviceSQL.Devices/Device/Modbus/ModbusMaster.cs diff --git a/DeviceSQL/Device/Modbus/ModbusSlaveException.cs b/DeviceSQL.Devices/Device/Modbus/ModbusSlaveException.cs similarity index 100% rename from DeviceSQL/Device/Modbus/ModbusSlaveException.cs rename to DeviceSQL.Devices/Device/Modbus/ModbusSlaveException.cs diff --git a/DeviceSQL/Device/ROC/Crc16.cs b/DeviceSQL.Devices/Device/ROC/Crc16.cs similarity index 100% rename from DeviceSQL/Device/ROC/Crc16.cs rename to DeviceSQL.Devices/Device/ROC/Crc16.cs diff --git a/DeviceSQL/Device/ROC/Data/Ac10Parameter.cs b/DeviceSQL.Devices/Device/ROC/Data/Ac10Parameter.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/Ac10Parameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/Ac10Parameter.cs diff --git a/DeviceSQL/Device/ROC/Data/Ac12Parameter.cs b/DeviceSQL.Devices/Device/ROC/Data/Ac12Parameter.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/Ac12Parameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/Ac12Parameter.cs diff --git a/DeviceSQL/Device/ROC/Data/Ac20Parameter.cs b/DeviceSQL.Devices/Device/ROC/Data/Ac20Parameter.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/Ac20Parameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/Ac20Parameter.cs diff --git a/DeviceSQL/Device/ROC/Data/Ac30Parameter.cs b/DeviceSQL.Devices/Device/ROC/Data/Ac30Parameter.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/Ac30Parameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/Ac30Parameter.cs diff --git a/DeviceSQL/Device/ROC/Data/Ac3Parameter.cs b/DeviceSQL.Devices/Device/ROC/Data/Ac3Parameter.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/Ac3Parameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/Ac3Parameter.cs diff --git a/DeviceSQL/Device/ROC/Data/Ac40Parameter.cs b/DeviceSQL.Devices/Device/ROC/Data/Ac40Parameter.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/Ac40Parameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/Ac40Parameter.cs diff --git a/DeviceSQL/Device/ROC/Data/Ac7Parameter.cs b/DeviceSQL.Devices/Device/ROC/Data/Ac7Parameter.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/Ac7Parameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/Ac7Parameter.cs diff --git a/DeviceSQL/Device/ROC/Data/AlarmRecord.cs b/DeviceSQL.Devices/Device/ROC/Data/AlarmRecord.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/AlarmRecord.cs rename to DeviceSQL.Devices/Device/ROC/Data/AlarmRecord.cs diff --git a/DeviceSQL/Device/ROC/Data/ArchiveInfo.cs b/DeviceSQL.Devices/Device/ROC/Data/ArchiveInfo.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/ArchiveInfo.cs rename to DeviceSQL.Devices/Device/ROC/Data/ArchiveInfo.cs diff --git a/DeviceSQL/Device/ROC/Data/AuditLogRecord.cs b/DeviceSQL.Devices/Device/ROC/Data/AuditLogRecord.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/AuditLogRecord.cs rename to DeviceSQL.Devices/Device/ROC/Data/AuditLogRecord.cs diff --git a/DeviceSQL/Device/ROC/Data/BinParameter.cs b/DeviceSQL.Devices/Device/ROC/Data/BinParameter.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/BinParameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/BinParameter.cs diff --git a/DeviceSQL/Device/ROC/Data/DoubleParameter.cs b/DeviceSQL.Devices/Device/ROC/Data/DoubleParameter.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/DoubleParameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/DoubleParameter.cs diff --git a/DeviceSQL/Device/ROC/Data/EventRecord.cs b/DeviceSQL.Devices/Device/ROC/Data/EventRecord.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/EventRecord.cs rename to DeviceSQL.Devices/Device/ROC/Data/EventRecord.cs diff --git a/DeviceSQL/Device/ROC/Data/FlpParameter.cs b/DeviceSQL.Devices/Device/ROC/Data/FlpParameter.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/FlpParameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/FlpParameter.cs diff --git a/DeviceSQL/Device/ROC/Data/FstCodeChunk.cs b/DeviceSQL.Devices/Device/ROC/Data/FstCodeChunk.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/FstCodeChunk.cs rename to DeviceSQL.Devices/Device/ROC/Data/FstCodeChunk.cs diff --git a/DeviceSQL/Device/ROC/Data/FstHeaderInfo.cs b/DeviceSQL.Devices/Device/ROC/Data/FstHeaderInfo.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/FstHeaderInfo.cs rename to DeviceSQL.Devices/Device/ROC/Data/FstHeaderInfo.cs diff --git a/DeviceSQL/Device/ROC/Data/HistoryPointConfiguration.cs b/DeviceSQL.Devices/Device/ROC/Data/HistoryPointConfiguration.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/HistoryPointConfiguration.cs rename to DeviceSQL.Devices/Device/ROC/Data/HistoryPointConfiguration.cs diff --git a/DeviceSQL/Device/ROC/Data/HistoryRecord.cs b/DeviceSQL.Devices/Device/ROC/Data/HistoryRecord.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/HistoryRecord.cs rename to DeviceSQL.Devices/Device/ROC/Data/HistoryRecord.cs diff --git a/DeviceSQL/Device/ROC/Data/IRocParameterData.cs b/DeviceSQL.Devices/Device/ROC/Data/IRocParameterData.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/IRocParameterData.cs rename to DeviceSQL.Devices/Device/ROC/Data/IRocParameterData.cs diff --git a/DeviceSQL/Device/ROC/Data/Int16Parameter.cs b/DeviceSQL.Devices/Device/ROC/Data/Int16Parameter.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/Int16Parameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/Int16Parameter.cs diff --git a/DeviceSQL/Device/ROC/Data/Int32Parameter.cs b/DeviceSQL.Devices/Device/ROC/Data/Int32Parameter.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/Int32Parameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/Int32Parameter.cs diff --git a/DeviceSQL/Device/ROC/Data/Int8Parameter.cs b/DeviceSQL.Devices/Device/ROC/Data/Int8Parameter.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/Int8Parameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/Int8Parameter.cs diff --git a/DeviceSQL/Device/ROC/Data/Parameter.cs b/DeviceSQL.Devices/Device/ROC/Data/Parameter.cs similarity index 83% rename from DeviceSQL/Device/ROC/Data/Parameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/Parameter.cs index 9834418..9d78949 100644 --- a/DeviceSQL/Device/ROC/Data/Parameter.cs +++ b/DeviceSQL.Devices/Device/ROC/Data/Parameter.cs @@ -10,32 +10,6 @@ namespace DeviceSQL.Device.ROC.Data { - #region Enumerations - - public enum ParameterType : byte - { - BIN = 0, - INT8 = 1, - INT16 = 2, - INT32 = 3, - UINT8 = 4, - UINT16 = 5, - UINT32 = 6, - FL = 7, - TLP = 8, - AC3 = 9, - AC7 = 10, - AC10 = 11, - AC12 = 12, - AC20 = 13, - AC30 = 14, - AC40 = 15, - DOUBLE = 16, - TIME = 17 - } - - #endregion - public abstract class Parameter : IROCParameterData { diff --git a/DeviceSQL.Devices/Device/ROC/Data/ParameterType.cs b/DeviceSQL.Devices/Device/ROC/Data/ParameterType.cs new file mode 100644 index 0000000..ff4625b --- /dev/null +++ b/DeviceSQL.Devices/Device/ROC/Data/ParameterType.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DeviceSQL.Devices.Device.ROC.Data +{ + public enum ParameterType : byte + { + BIN = 0, + INT8 = 1, + INT16 = 2, + INT32 = 3, + UINT8 = 4, + UINT16 = 5, + UINT32 = 6, + FL = 7, + TLP = 8, + AC3 = 9, + AC7 = 10, + AC10 = 11, + AC12 = 12, + AC20 = 13, + AC30 = 14, + AC40 = 15, + DOUBLE = 16, + TIME = 17 + } +} diff --git a/DeviceSQL/Device/ROC/Data/RocPlusAlarmRecord.cs b/DeviceSQL.Devices/Device/ROC/Data/RocPlusAlarmRecord.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/RocPlusAlarmRecord.cs rename to DeviceSQL.Devices/Device/ROC/Data/RocPlusAlarmRecord.cs diff --git a/DeviceSQL/Device/ROC/Data/RocPlusEventRecord.cs b/DeviceSQL.Devices/Device/ROC/Data/RocPlusEventRecord.cs similarity index 99% rename from DeviceSQL/Device/ROC/Data/RocPlusEventRecord.cs rename to DeviceSQL.Devices/Device/ROC/Data/RocPlusEventRecord.cs index 2cf3b34..4ac6e17 100644 --- a/DeviceSQL/Device/ROC/Data/RocPlusEventRecord.cs +++ b/DeviceSQL.Devices/Device/ROC/Data/RocPlusEventRecord.cs @@ -1,5 +1,6 @@ #region Imported Types +using DeviceSQL.Devices.Device.ROC.Data; using System; using System.Collections.Generic; using System.Linq; diff --git a/DeviceSQL/Device/ROC/Data/RocPlusHistoryRecord.cs b/DeviceSQL.Devices/Device/ROC/Data/RocPlusHistoryRecord.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/RocPlusHistoryRecord.cs rename to DeviceSQL.Devices/Device/ROC/Data/RocPlusHistoryRecord.cs diff --git a/DeviceSQL/Device/ROC/Data/TimeParameter.cs b/DeviceSQL.Devices/Device/ROC/Data/TimeParameter.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/TimeParameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/TimeParameter.cs diff --git a/DeviceSQL/Device/ROC/Data/Tlp.cs b/DeviceSQL.Devices/Device/ROC/Data/Tlp.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/Tlp.cs rename to DeviceSQL.Devices/Device/ROC/Data/Tlp.cs diff --git a/DeviceSQL/Device/ROC/Data/TlpParameter.cs b/DeviceSQL.Devices/Device/ROC/Data/TlpParameter.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/TlpParameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/TlpParameter.cs diff --git a/DeviceSQL/Device/ROC/Data/UInt16Parameter.cs b/DeviceSQL.Devices/Device/ROC/Data/UInt16Parameter.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/UInt16Parameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/UInt16Parameter.cs diff --git a/DeviceSQL/Device/ROC/Data/UInt32Parameter.cs b/DeviceSQL.Devices/Device/ROC/Data/UInt32Parameter.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/UInt32Parameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/UInt32Parameter.cs diff --git a/DeviceSQL/Device/ROC/Data/UInt8Parameter.cs b/DeviceSQL.Devices/Device/ROC/Data/UInt8Parameter.cs similarity index 100% rename from DeviceSQL/Device/ROC/Data/UInt8Parameter.cs rename to DeviceSQL.Devices/Device/ROC/Data/UInt8Parameter.cs diff --git a/DeviceSQL/Device/ROC/Device.cs b/DeviceSQL.Devices/Device/ROC/Device.cs similarity index 100% rename from DeviceSQL/Device/ROC/Device.cs rename to DeviceSQL.Devices/Device/ROC/Device.cs diff --git a/DeviceSQL/Device/ROC/FST/Arguments/ArgumentBase.cs b/DeviceSQL.Devices/Device/ROC/FST/Arguments/ArgumentBase.cs similarity index 100% rename from DeviceSQL/Device/ROC/FST/Arguments/ArgumentBase.cs rename to DeviceSQL.Devices/Device/ROC/FST/Arguments/ArgumentBase.cs diff --git a/DeviceSQL/Device/ROC/FST/Arguments/ArgumentDataType.cs b/DeviceSQL.Devices/Device/ROC/FST/Arguments/ArgumentDataType.cs similarity index 100% rename from DeviceSQL/Device/ROC/FST/Arguments/ArgumentDataType.cs rename to DeviceSQL.Devices/Device/ROC/FST/Arguments/ArgumentDataType.cs diff --git a/DeviceSQL/Device/ROC/FST/Arguments/ArgumentType.cs b/DeviceSQL.Devices/Device/ROC/FST/Arguments/ArgumentType.cs similarity index 100% rename from DeviceSQL/Device/ROC/FST/Arguments/ArgumentType.cs rename to DeviceSQL.Devices/Device/ROC/FST/Arguments/ArgumentType.cs diff --git a/DeviceSQL/Device/ROC/FST/Arguments/DatabasePoint.cs b/DeviceSQL.Devices/Device/ROC/FST/Arguments/DatabasePoint.cs similarity index 86% rename from DeviceSQL/Device/ROC/FST/Arguments/DatabasePoint.cs rename to DeviceSQL.Devices/Device/ROC/FST/Arguments/DatabasePoint.cs index 9354610..3491bba 100644 --- a/DeviceSQL/Device/ROC/FST/Arguments/DatabasePoint.cs +++ b/DeviceSQL.Devices/Device/ROC/FST/Arguments/DatabasePoint.cs @@ -1,4 +1,6 @@ -namespace DeviceSQL.Device.ROC.Data.FST.Arguments +using DeviceSQL.Devices.Device.ROC.Data; + +namespace DeviceSQL.Device.ROC.Data.FST.Arguments { public class DatabasePoint { diff --git a/DeviceSQL/Device/ROC/FST/Arguments/DatabasePointOrConstantValueArgument.cs b/DeviceSQL.Devices/Device/ROC/FST/Arguments/DatabasePointOrConstantValueArgument.cs similarity index 100% rename from DeviceSQL/Device/ROC/FST/Arguments/DatabasePointOrConstantValueArgument.cs rename to DeviceSQL.Devices/Device/ROC/FST/Arguments/DatabasePointOrConstantValueArgument.cs diff --git a/DeviceSQL/Device/ROC/FST/Arguments/NullArgument.cs b/DeviceSQL.Devices/Device/ROC/FST/Arguments/NullArgument.cs similarity index 100% rename from DeviceSQL/Device/ROC/FST/Arguments/NullArgument.cs rename to DeviceSQL.Devices/Device/ROC/FST/Arguments/NullArgument.cs diff --git a/DeviceSQL/Device/ROC/FST/Instructions/AddInstruction.cs b/DeviceSQL.Devices/Device/ROC/FST/Instructions/AddInstruction.cs similarity index 100% rename from DeviceSQL/Device/ROC/FST/Instructions/AddInstruction.cs rename to DeviceSQL.Devices/Device/ROC/FST/Instructions/AddInstruction.cs diff --git a/DeviceSQL/Device/ROC/FST/Instructions/InstructionBase.cs b/DeviceSQL.Devices/Device/ROC/FST/Instructions/InstructionBase.cs similarity index 100% rename from DeviceSQL/Device/ROC/FST/Instructions/InstructionBase.cs rename to DeviceSQL.Devices/Device/ROC/FST/Instructions/InstructionBase.cs diff --git a/DeviceSQL/Device/ROC/FST/Instructions/InstructionCategory.cs b/DeviceSQL.Devices/Device/ROC/FST/Instructions/InstructionCategory.cs similarity index 100% rename from DeviceSQL/Device/ROC/FST/Instructions/InstructionCategory.cs rename to DeviceSQL.Devices/Device/ROC/FST/Instructions/InstructionCategory.cs diff --git a/DeviceSQL/Device/ROC/FST/Instructions/InstructionType.cs b/DeviceSQL.Devices/Device/ROC/FST/Instructions/InstructionType.cs similarity index 100% rename from DeviceSQL/Device/ROC/FST/Instructions/InstructionType.cs rename to DeviceSQL.Devices/Device/ROC/FST/Instructions/InstructionType.cs diff --git a/DeviceSQL/Device/ROC/IO/Transport/Transport.cs b/DeviceSQL.Devices/Device/ROC/IO/Transport/Transport.cs similarity index 100% rename from DeviceSQL/Device/ROC/IO/Transport/Transport.cs rename to DeviceSQL.Devices/Device/ROC/IO/Transport/Transport.cs diff --git a/DeviceSQL/Device/ROC/Message/IRocMessage.cs b/DeviceSQL.Devices/Device/ROC/Message/IRocMessage.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/IRocMessage.cs rename to DeviceSQL.Devices/Device/ROC/Message/IRocMessage.cs diff --git a/DeviceSQL/Device/ROC/Message/IRocRequestMessage.cs b/DeviceSQL.Devices/Device/ROC/Message/IRocRequestMessage.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/IRocRequestMessage.cs rename to DeviceSQL.Devices/Device/ROC/Message/IRocRequestMessage.cs diff --git a/DeviceSQL/Device/ROC/Message/IRocResponseMessage.cs b/DeviceSQL.Devices/Device/ROC/Message/IRocResponseMessage.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/IRocResponseMessage.cs rename to DeviceSQL.Devices/Device/ROC/Message/IRocResponseMessage.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode007Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode007Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode007Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode007Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode007Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode007Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode007Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode007Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode008Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode008Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode008Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode008Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode008Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode008Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode008Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode008Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode017Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode017Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode017Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode017Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode017Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode017Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode017Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode017Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode080Function.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode080Function.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode080Function.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode080Function.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode080Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode080Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode080Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode080Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode080Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode080Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode080Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode080Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode118Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode118Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode118Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode118Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode118Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode118Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode118Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode118Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode119Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode119Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode119Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode119Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode119Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode119Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode119Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode119Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode120Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode120Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode120Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode120Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode120Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode120Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode120Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode120Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode121Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode121Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode121Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode121Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode121Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode121Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode121Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode121Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode122Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode122Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode122Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode122Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode122Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode122Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode122Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode122Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode126Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode126Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode126Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode126Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode126Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode126Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode126Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode126Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode130Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode130Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode130Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode130Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode130Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode130Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode130Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode130Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode131Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode131Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode131Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode131Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode131Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode131Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode131Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode131Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode132Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode132Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode132Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode132Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode132Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode132Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode132Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode132Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode136Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode136Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode136Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode136Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode136Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode136Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode136Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode136Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode139Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode139Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode139Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode139Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode139Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode139Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode139Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode139Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode165Request .cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode165Request .cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode165Request .cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode165Request .cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode165Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode165Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode165Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode165Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode166Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode166Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode166Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode166Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode166Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode166Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode166Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode166Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode167Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode167Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode167Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode167Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode167Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode167Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode167Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode167Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode180Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode180Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode180Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode180Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode180Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode180Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode180Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode180Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode181Request.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode181Request.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode181Request.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode181Request.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode181Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode181Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode181Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode181Response.cs diff --git a/DeviceSQL/Device/ROC/Message/OpCode255Response.cs b/DeviceSQL.Devices/Device/ROC/Message/OpCode255Response.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/OpCode255Response.cs rename to DeviceSQL.Devices/Device/ROC/Message/OpCode255Response.cs diff --git a/DeviceSQL/Device/ROC/Message/ParameterDatabase.cs b/DeviceSQL.Devices/Device/ROC/Message/ParameterDatabase.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/ParameterDatabase.cs rename to DeviceSQL.Devices/Device/ROC/Message/ParameterDatabase.cs diff --git a/DeviceSQL/Device/ROC/Message/RocMessage.cs b/DeviceSQL.Devices/Device/ROC/Message/RocMessage.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/RocMessage.cs rename to DeviceSQL.Devices/Device/ROC/Message/RocMessage.cs diff --git a/DeviceSQL/Device/ROC/Message/RocMessageFactory.cs b/DeviceSQL.Devices/Device/ROC/Message/RocMessageFactory.cs similarity index 100% rename from DeviceSQL/Device/ROC/Message/RocMessageFactory.cs rename to DeviceSQL.Devices/Device/ROC/Message/RocMessageFactory.cs diff --git a/DeviceSQL/Device/ROC/OpCode255Exception.cs b/DeviceSQL.Devices/Device/ROC/OpCode255Exception.cs similarity index 100% rename from DeviceSQL/Device/ROC/OpCode255Exception.cs rename to DeviceSQL.Devices/Device/ROC/OpCode255Exception.cs diff --git a/DeviceSQL/Device/ROC/ROCMaster.cs b/DeviceSQL.Devices/Device/ROC/ROCMaster.cs similarity index 100% rename from DeviceSQL/Device/ROC/ROCMaster.cs rename to DeviceSQL.Devices/Device/ROC/ROCMaster.cs diff --git a/DeviceSQL/Device/ROC/Utility/Crc16.cs b/DeviceSQL.Devices/Device/ROC/Utility/Crc16.cs similarity index 100% rename from DeviceSQL/Device/ROC/Utility/Crc16.cs rename to DeviceSQL.Devices/Device/ROC/Utility/Crc16.cs diff --git a/DeviceSQL.Devices/DeviceSQL.Devices.csproj b/DeviceSQL.Devices/DeviceSQL.Devices.csproj new file mode 100644 index 0000000..0bc84fc --- /dev/null +++ b/DeviceSQL.Devices/DeviceSQL.Devices.csproj @@ -0,0 +1,206 @@ + + + + + Debug + AnyCPU + {80ED4080-6FD1-492F-B70E-8C837B3DADC7} + Library + Properties + DeviceSQL.Devices + DeviceSQL.Devices + v4.6.1 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DeviceSQL/IO/Channels/ChannelTraceEventArgs.cs b/DeviceSQL.Devices/IO/Channels/ChannelTraceEventArgs.cs similarity index 100% rename from DeviceSQL/IO/Channels/ChannelTraceEventArgs.cs rename to DeviceSQL.Devices/IO/Channels/ChannelTraceEventArgs.cs diff --git a/DeviceSQL/IO/Channels/ChannelTraceListener.cs b/DeviceSQL.Devices/IO/Channels/ChannelTraceListener.cs similarity index 100% rename from DeviceSQL/IO/Channels/ChannelTraceListener.cs rename to DeviceSQL.Devices/IO/Channels/ChannelTraceListener.cs diff --git a/DeviceSQL/IO/Channels/HexConverter.cs b/DeviceSQL.Devices/IO/Channels/HexConverter.cs similarity index 100% rename from DeviceSQL/IO/Channels/HexConverter.cs rename to DeviceSQL.Devices/IO/Channels/HexConverter.cs diff --git a/DeviceSQL/IO/Channels/IChannel.cs b/DeviceSQL.Devices/IO/Channels/IChannel.cs similarity index 100% rename from DeviceSQL/IO/Channels/IChannel.cs rename to DeviceSQL.Devices/IO/Channels/IChannel.cs diff --git a/DeviceSQL/IO/Channels/IMuxChannel.cs b/DeviceSQL.Devices/IO/Channels/IMuxChannel.cs similarity index 100% rename from DeviceSQL/IO/Channels/IMuxChannel.cs rename to DeviceSQL.Devices/IO/Channels/IMuxChannel.cs diff --git a/DeviceSQL/IO/Channels/SerialPortChannel.cs b/DeviceSQL.Devices/IO/Channels/SerialPortChannel.cs similarity index 100% rename from DeviceSQL/IO/Channels/SerialPortChannel.cs rename to DeviceSQL.Devices/IO/Channels/SerialPortChannel.cs diff --git a/DeviceSQL/IO/Channels/SerialPortMuxChannel.cs b/DeviceSQL.Devices/IO/Channels/SerialPortMuxChannel.cs similarity index 96% rename from DeviceSQL/IO/Channels/SerialPortMuxChannel.cs rename to DeviceSQL.Devices/IO/Channels/SerialPortMuxChannel.cs index aa98fe5..29d18a3 100644 --- a/DeviceSQL/IO/Channels/SerialPortMuxChannel.cs +++ b/DeviceSQL.Devices/IO/Channels/SerialPortMuxChannel.cs @@ -27,7 +27,7 @@ public IChannel SourceChannel { get { - return Watchdog.Worker.Channels.FirstOrDefault(channel => channel.Name == sourceChannelName); + return null;//return Watchdog.Worker.Channels.FirstOrDefault(channel => channel.Name == sourceChannelName); } } diff --git a/DeviceSQL/IO/Channels/TcpChannel.cs b/DeviceSQL.Devices/IO/Channels/TcpChannel.cs similarity index 100% rename from DeviceSQL/IO/Channels/TcpChannel.cs rename to DeviceSQL.Devices/IO/Channels/TcpChannel.cs diff --git a/DeviceSQL/IO/Channels/TcpMuxChannel.cs b/DeviceSQL.Devices/IO/Channels/TcpMuxChannel.cs similarity index 99% rename from DeviceSQL/IO/Channels/TcpMuxChannel.cs rename to DeviceSQL.Devices/IO/Channels/TcpMuxChannel.cs index 43026f8..340d24e 100644 --- a/DeviceSQL/IO/Channels/TcpMuxChannel.cs +++ b/DeviceSQL.Devices/IO/Channels/TcpMuxChannel.cs @@ -37,7 +37,7 @@ public IChannel SourceChannel { get { - return DeviceSQL.Watchdog.Worker.Channels.FirstOrDefault(); + return null; //DeviceSQL.Watchdog.Worker.Channels.FirstOrDefault(); } } diff --git a/DeviceSQL/IO/Channels/TimedThreadBlocker.cs b/DeviceSQL.Devices/IO/Channels/TimedThreadBlocker.cs similarity index 100% rename from DeviceSQL/IO/Channels/TimedThreadBlocker.cs rename to DeviceSQL.Devices/IO/Channels/TimedThreadBlocker.cs diff --git a/DeviceSQL/IO/Channels/Transport/ITransport.cs b/DeviceSQL.Devices/IO/Channels/Transport/ITransport.cs similarity index 100% rename from DeviceSQL/IO/Channels/Transport/ITransport.cs rename to DeviceSQL.Devices/IO/Channels/Transport/ITransport.cs diff --git a/DeviceSQL.Devices/Properties/AssemblyInfo.cs b/DeviceSQL.Devices/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f720c30 --- /dev/null +++ b/DeviceSQL.Devices/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +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("DeviceSQL.Devices")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("DeviceSQL.Devices")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[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("80ed4080-6fd1-492f-b70e-8c837b3dadc7")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/DeviceSQL.SQLTypes/DeviceSQL.SQLTypes.csproj b/DeviceSQL.SQLTypes/DeviceSQL.SQLTypes.csproj new file mode 100644 index 0000000..03465fd --- /dev/null +++ b/DeviceSQL.SQLTypes/DeviceSQL.SQLTypes.csproj @@ -0,0 +1,238 @@ + + + + + Debug + AnyCPU + {91B62CD7-190B-4727-B1EB-66B51913709D} + Library + Properties + DeviceSQL.SQLTypes + DeviceSQL.SQLTypes + v4.6.1 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + Devices\Device\Modbus\Data\BooleanRegister.cs + + + Devices\Device\Modbus\Data\CoilRegister.cs + + + Devices\Device\Modbus\Data\DiscreteInputRegister.cs + + + Devices\Device\Modbus\Data\EventArchiveRecord.cs + + + Devices\Device\Modbus\Data\FloatRegister.cs + + + Devices\Device\Modbus\Data\HistoryArchiveRecord.cs + + + Devices\Device\Modbus\Data\HoldingRegister.cs + + + Devices\Device\Modbus\Data\IModbusRegisterData.cs + + + Devices\Device\Modbus\Data\InputRegister.cs + + + Devices\Device\Modbus\Data\LongRegister.cs + + + Devices\Device\Modbus\Data\ModbusAddress.cs + + + Devices\Device\Modbus\Data\ModbusRegister.cs + + + Devices\Device\Modbus\Data\ShortRegister.cs + + + Devices\Device\Modbus\Data\StringRegister.cs + + + Devices\Device\Modbus\ModbusConverter.cs + + + Devices\Device\ROC\Data\Ac10Parameter.cs + + + Devices\Device\ROC\Data\Ac12Parameter.cs + + + Devices\Device\ROC\Data\Ac20Parameter.cs + + + Devices\Device\ROC\Data\Ac30Parameter.cs + + + Devices\Device\ROC\Data\Ac3Parameter.cs + + + Devices\Device\ROC\Data\Ac40Parameter.cs + + + Devices\Device\ROC\Data\Ac7Parameter.cs + + + Devices\Device\ROC\Data\AlarmRecord.cs + + + Devices\Device\ROC\Data\ArchiveInfo.cs + + + Devices\Device\ROC\Data\AuditLogRecord.cs + + + Devices\Device\ROC\Data\BinParameter.cs + + + Devices\Device\ROC\Data\DoubleParameter.cs + + + Devices\Device\ROC\Data\EventRecord.cs + + + Devices\Device\ROC\Data\FlpParameter.cs + + + Devices\Device\ROC\Data\FstCodeChunk.cs + + + Devices\Device\ROC\Data\FstHeaderInfo.cs + + + Devices\Device\ROC\Data\HistoryPointConfiguration.cs + + + Devices\Device\ROC\Data\HistoryRecord.cs + + + Devices\Device\ROC\Data\Int16Parameter.cs + + + Devices\Device\ROC\Data\Int32Parameter.cs + + + Devices\Device\ROC\Data\Int8Parameter.cs + + + Devices\Device\ROC\Data\IRocParameterData.cs + + + Devices\Device\ROC\Data\Parameter.cs + + + Devices\Device\ROC\Data\ParameterType.cs + + + Devices\Device\ROC\Data\RocPlusAlarmRecord.cs + + + Devices\Device\ROC\Data\RocPlusEventRecord.cs + + + Devices\Device\ROC\Data\RocPlusHistoryRecord.cs + + + Devices\Device\ROC\Data\TimeParameter.cs + + + Devices\Device\ROC\Data\Tlp.cs + + + Devices\Device\ROC\Data\TlpParameter.cs + + + Devices\Device\ROC\Data\UInt16Parameter.cs + + + Devices\Device\ROC\Data\UInt32Parameter.cs + + + Devices\Device\ROC\Data\UInt8Parameter.cs + + + Devices\Device\ROC\Message\ParameterDatabase.cs + + + IO\Channels\HexConverter.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DeviceSQL/Types/ModbusMaster/BooleanRegister.cs b/DeviceSQL.SQLTypes/ModbusMaster/BooleanRegister.cs similarity index 98% rename from DeviceSQL/Types/ModbusMaster/BooleanRegister.cs rename to DeviceSQL.SQLTypes/ModbusMaster/BooleanRegister.cs index 7ac3bbd..3717216 100644 --- a/DeviceSQL/Types/ModbusMaster/BooleanRegister.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/BooleanRegister.cs @@ -7,7 +7,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 8)] diff --git a/DeviceSQL/Types/ModbusMaster/BooleanRegisterArray.cs b/DeviceSQL.SQLTypes/ModbusMaster/BooleanRegisterArray.cs similarity index 99% rename from DeviceSQL/Types/ModbusMaster/BooleanRegisterArray.cs rename to DeviceSQL.SQLTypes/ModbusMaster/BooleanRegisterArray.cs index dc051cb..ccfda43 100644 --- a/DeviceSQL/Types/ModbusMaster/BooleanRegisterArray.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/BooleanRegisterArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL/Types/ModbusMaster/CoilRegister.cs b/DeviceSQL.SQLTypes/ModbusMaster/CoilRegister.cs similarity index 98% rename from DeviceSQL/Types/ModbusMaster/CoilRegister.cs rename to DeviceSQL.SQLTypes/ModbusMaster/CoilRegister.cs index a2cc44b..381d7b1 100644 --- a/DeviceSQL/Types/ModbusMaster/CoilRegister.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/CoilRegister.cs @@ -7,7 +7,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 8)] diff --git a/DeviceSQL/Types/ModbusMaster/CoilRegisterArray.cs b/DeviceSQL.SQLTypes/ModbusMaster/CoilRegisterArray.cs similarity index 98% rename from DeviceSQL/Types/ModbusMaster/CoilRegisterArray.cs rename to DeviceSQL.SQLTypes/ModbusMaster/CoilRegisterArray.cs index 6a11f55..2e38c29 100644 --- a/DeviceSQL/Types/ModbusMaster/CoilRegisterArray.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/CoilRegisterArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL/Types/ModbusMaster/DiscreteInputRegister.cs b/DeviceSQL.SQLTypes/ModbusMaster/DiscreteInputRegister.cs similarity index 98% rename from DeviceSQL/Types/ModbusMaster/DiscreteInputRegister.cs rename to DeviceSQL.SQLTypes/ModbusMaster/DiscreteInputRegister.cs index 69bd86a..4067ca8 100644 --- a/DeviceSQL/Types/ModbusMaster/DiscreteInputRegister.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/DiscreteInputRegister.cs @@ -7,7 +7,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 8)] diff --git a/DeviceSQL/Types/ModbusMaster/DiscreteInputRegisterArray.cs b/DeviceSQL.SQLTypes/ModbusMaster/DiscreteInputRegisterArray.cs similarity index 99% rename from DeviceSQL/Types/ModbusMaster/DiscreteInputRegisterArray.cs rename to DeviceSQL.SQLTypes/ModbusMaster/DiscreteInputRegisterArray.cs index 88ec74f..3fb046d 100644 --- a/DeviceSQL/Types/ModbusMaster/DiscreteInputRegisterArray.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/DiscreteInputRegisterArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL/Types/ModbusMaster/EventArchiveRecord.cs b/DeviceSQL.SQLTypes/ModbusMaster/EventArchiveRecord.cs similarity index 98% rename from DeviceSQL/Types/ModbusMaster/EventArchiveRecord.cs rename to DeviceSQL.SQLTypes/ModbusMaster/EventArchiveRecord.cs index 07c7774..e7bea83 100644 --- a/DeviceSQL/Types/ModbusMaster/EventArchiveRecord.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/EventArchiveRecord.cs @@ -7,7 +7,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 264)] diff --git a/DeviceSQL/Types/ModbusMaster/EventArchiveRecordArray.cs b/DeviceSQL.SQLTypes/ModbusMaster/EventArchiveRecordArray.cs similarity index 99% rename from DeviceSQL/Types/ModbusMaster/EventArchiveRecordArray.cs rename to DeviceSQL.SQLTypes/ModbusMaster/EventArchiveRecordArray.cs index 2c5b9a3..60753b5 100644 --- a/DeviceSQL/Types/ModbusMaster/EventArchiveRecordArray.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/EventArchiveRecordArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL/Types/ModbusMaster/FloatRegister.cs b/DeviceSQL.SQLTypes/ModbusMaster/FloatRegister.cs similarity index 98% rename from DeviceSQL/Types/ModbusMaster/FloatRegister.cs rename to DeviceSQL.SQLTypes/ModbusMaster/FloatRegister.cs index 93c8a5a..2e7b523 100644 --- a/DeviceSQL/Types/ModbusMaster/FloatRegister.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/FloatRegister.cs @@ -7,7 +7,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 13)] diff --git a/DeviceSQL/Types/ModbusMaster/FloatRegisterArray.cs b/DeviceSQL.SQLTypes/ModbusMaster/FloatRegisterArray.cs similarity index 98% rename from DeviceSQL/Types/ModbusMaster/FloatRegisterArray.cs rename to DeviceSQL.SQLTypes/ModbusMaster/FloatRegisterArray.cs index 43d0353..35a9515 100644 --- a/DeviceSQL/Types/ModbusMaster/FloatRegisterArray.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/FloatRegisterArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL/Types/ModbusMaster/HistoryArchiveRecord.cs b/DeviceSQL.SQLTypes/ModbusMaster/HistoryArchiveRecord.cs similarity index 98% rename from DeviceSQL/Types/ModbusMaster/HistoryArchiveRecord.cs rename to DeviceSQL.SQLTypes/ModbusMaster/HistoryArchiveRecord.cs index 5252536..a2ddbdc 100644 --- a/DeviceSQL/Types/ModbusMaster/HistoryArchiveRecord.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/HistoryArchiveRecord.cs @@ -7,7 +7,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 264)] diff --git a/DeviceSQL/Types/ModbusMaster/HistoryArchiveRecordArray.cs b/DeviceSQL.SQLTypes/ModbusMaster/HistoryArchiveRecordArray.cs similarity index 99% rename from DeviceSQL/Types/ModbusMaster/HistoryArchiveRecordArray.cs rename to DeviceSQL.SQLTypes/ModbusMaster/HistoryArchiveRecordArray.cs index 542b21f..8e4178e 100644 --- a/DeviceSQL/Types/ModbusMaster/HistoryArchiveRecordArray.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/HistoryArchiveRecordArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL/Types/ModbusMaster/HoldingRegister.cs b/DeviceSQL.SQLTypes/ModbusMaster/HoldingRegister.cs similarity index 98% rename from DeviceSQL/Types/ModbusMaster/HoldingRegister.cs rename to DeviceSQL.SQLTypes/ModbusMaster/HoldingRegister.cs index 92b1cea..4eede16 100644 --- a/DeviceSQL/Types/ModbusMaster/HoldingRegister.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/HoldingRegister.cs @@ -7,7 +7,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 10)] diff --git a/DeviceSQL/Types/ModbusMaster/HoldingRegisterArray.cs b/DeviceSQL.SQLTypes/ModbusMaster/HoldingRegisterArray.cs similarity index 99% rename from DeviceSQL/Types/ModbusMaster/HoldingRegisterArray.cs rename to DeviceSQL.SQLTypes/ModbusMaster/HoldingRegisterArray.cs index 82ff78a..31c49d6 100644 --- a/DeviceSQL/Types/ModbusMaster/HoldingRegisterArray.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/HoldingRegisterArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL/Types/ModbusMaster/InputRegister.cs b/DeviceSQL.SQLTypes/ModbusMaster/InputRegister.cs similarity index 98% rename from DeviceSQL/Types/ModbusMaster/InputRegister.cs rename to DeviceSQL.SQLTypes/ModbusMaster/InputRegister.cs index ac3be00..b234b63 100644 --- a/DeviceSQL/Types/ModbusMaster/InputRegister.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/InputRegister.cs @@ -7,7 +7,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 10)] diff --git a/DeviceSQL/Types/ModbusMaster/InputRegisterArray.cs b/DeviceSQL.SQLTypes/ModbusMaster/InputRegisterArray.cs similarity index 99% rename from DeviceSQL/Types/ModbusMaster/InputRegisterArray.cs rename to DeviceSQL.SQLTypes/ModbusMaster/InputRegisterArray.cs index e1cee68..6ef3074 100644 --- a/DeviceSQL/Types/ModbusMaster/InputRegisterArray.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/InputRegisterArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL/Types/ModbusMaster/LongRegister.cs b/DeviceSQL.SQLTypes/ModbusMaster/LongRegister.cs similarity index 98% rename from DeviceSQL/Types/ModbusMaster/LongRegister.cs rename to DeviceSQL.SQLTypes/ModbusMaster/LongRegister.cs index b6198a5..5690095 100644 --- a/DeviceSQL/Types/ModbusMaster/LongRegister.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/LongRegister.cs @@ -7,7 +7,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 13)] diff --git a/DeviceSQL/Types/ModbusMaster/LongRegisterArray.cs b/DeviceSQL.SQLTypes/ModbusMaster/LongRegisterArray.cs similarity index 98% rename from DeviceSQL/Types/ModbusMaster/LongRegisterArray.cs rename to DeviceSQL.SQLTypes/ModbusMaster/LongRegisterArray.cs index a0e04e5..4494d1d 100644 --- a/DeviceSQL/Types/ModbusMaster/LongRegisterArray.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/LongRegisterArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL/Types/ModbusMaster/ModbusAddress.cs b/DeviceSQL.SQLTypes/ModbusMaster/ModbusAddress.cs similarity index 98% rename from DeviceSQL/Types/ModbusMaster/ModbusAddress.cs rename to DeviceSQL.SQLTypes/ModbusMaster/ModbusAddress.cs index d52d0a6..404df43 100644 --- a/DeviceSQL/Types/ModbusMaster/ModbusAddress.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/ModbusAddress.cs @@ -7,7 +7,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 6)] diff --git a/DeviceSQL/Types/ModbusMaster/ShortRegister.cs b/DeviceSQL.SQLTypes/ModbusMaster/ShortRegister.cs similarity index 98% rename from DeviceSQL/Types/ModbusMaster/ShortRegister.cs rename to DeviceSQL.SQLTypes/ModbusMaster/ShortRegister.cs index 8bdc1c0..7760aaf 100644 --- a/DeviceSQL/Types/ModbusMaster/ShortRegister.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/ShortRegister.cs @@ -7,7 +7,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 10)] diff --git a/DeviceSQL/Types/ModbusMaster/ShortRegisterArray.cs b/DeviceSQL.SQLTypes/ModbusMaster/ShortRegisterArray.cs similarity index 98% rename from DeviceSQL/Types/ModbusMaster/ShortRegisterArray.cs rename to DeviceSQL.SQLTypes/ModbusMaster/ShortRegisterArray.cs index 918a620..79cc2d6 100644 --- a/DeviceSQL/Types/ModbusMaster/ShortRegisterArray.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/ShortRegisterArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL/Types/ModbusMaster/StringRegister.cs b/DeviceSQL.SQLTypes/ModbusMaster/StringRegister.cs similarity index 98% rename from DeviceSQL/Types/ModbusMaster/StringRegister.cs rename to DeviceSQL.SQLTypes/ModbusMaster/StringRegister.cs index 945c0b1..c66f5a1 100644 --- a/DeviceSQL/Types/ModbusMaster/StringRegister.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/StringRegister.cs @@ -7,7 +7,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 264)] diff --git a/DeviceSQL/Types/ModbusMaster/StringRegisterArray.cs b/DeviceSQL.SQLTypes/ModbusMaster/StringRegisterArray.cs similarity index 99% rename from DeviceSQL/Types/ModbusMaster/StringRegisterArray.cs rename to DeviceSQL.SQLTypes/ModbusMaster/StringRegisterArray.cs index c827f91..3ffb171 100644 --- a/DeviceSQL/Types/ModbusMaster/StringRegisterArray.cs +++ b/DeviceSQL.SQLTypes/ModbusMaster/StringRegisterArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.MODBUSMaster +namespace DeviceSQL.SQLTypes.MODBUSMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL.SQLTypes/Properties/AssemblyInfo.cs b/DeviceSQL.SQLTypes/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b3df95d --- /dev/null +++ b/DeviceSQL.SQLTypes/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +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("DeviceSQL.SQLTypes")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("DeviceSQL.SQLTypes")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[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("91b62cd7-190b-4727-b1eb-66b51913709d")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/DeviceSQL/Types/ROCMaster/AlarmRecord.cs b/DeviceSQL.SQLTypes/ROCMaster/AlarmRecord.cs similarity index 98% rename from DeviceSQL/Types/ROCMaster/AlarmRecord.cs rename to DeviceSQL.SQLTypes/ROCMaster/AlarmRecord.cs index 86da088..e11ceef 100644 --- a/DeviceSQL/Types/ROCMaster/AlarmRecord.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/AlarmRecord.cs @@ -8,7 +8,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 27)] diff --git a/DeviceSQL/Types/ROCMaster/AlarmRecordArray.cs b/DeviceSQL.SQLTypes/ROCMaster/AlarmRecordArray.cs similarity index 99% rename from DeviceSQL/Types/ROCMaster/AlarmRecordArray.cs rename to DeviceSQL.SQLTypes/ROCMaster/AlarmRecordArray.cs index b3217d6..098b7fa 100644 --- a/DeviceSQL/Types/ROCMaster/AlarmRecordArray.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/AlarmRecordArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL/Types/ROCMaster/ArchiveInformation.cs b/DeviceSQL.SQLTypes/ROCMaster/ArchiveInformation.cs similarity index 99% rename from DeviceSQL/Types/ROCMaster/ArchiveInformation.cs rename to DeviceSQL.SQLTypes/ROCMaster/ArchiveInformation.cs index 82b3b9a..cdfb814 100644 --- a/DeviceSQL/Types/ROCMaster/ArchiveInformation.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/ArchiveInformation.cs @@ -8,7 +8,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 27)] diff --git a/DeviceSQL/Types/ROCMaster/AuditLogRecord.cs b/DeviceSQL.SQLTypes/ROCMaster/AuditLogRecord.cs similarity index 99% rename from DeviceSQL/Types/ROCMaster/AuditLogRecord.cs rename to DeviceSQL.SQLTypes/ROCMaster/AuditLogRecord.cs index 829f3a7..5e47e38 100644 --- a/DeviceSQL/Types/ROCMaster/AuditLogRecord.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/AuditLogRecord.cs @@ -1,6 +1,7 @@ #region Imported Types using DeviceSQL.Device.ROC.Data; +using DeviceSQL.Devices.Device.ROC.Data; using Microsoft.SqlServer.Server; using System; using System.Data.SqlTypes; @@ -9,7 +10,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 29)] diff --git a/DeviceSQL/Types/ROCMaster/AuditLogRecordArray.cs b/DeviceSQL.SQLTypes/ROCMaster/AuditLogRecordArray.cs similarity index 99% rename from DeviceSQL/Types/ROCMaster/AuditLogRecordArray.cs rename to DeviceSQL.SQLTypes/ROCMaster/AuditLogRecordArray.cs index e435c0d..459576b 100644 --- a/DeviceSQL/Types/ROCMaster/AuditLogRecordArray.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/AuditLogRecordArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL/Types/ROCMaster/EventRecord.cs b/DeviceSQL.SQLTypes/ROCMaster/EventRecord.cs similarity index 99% rename from DeviceSQL/Types/ROCMaster/EventRecord.cs rename to DeviceSQL.SQLTypes/ROCMaster/EventRecord.cs index aa47e75..6319a7f 100644 --- a/DeviceSQL/Types/ROCMaster/EventRecord.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/EventRecord.cs @@ -1,6 +1,7 @@ #region Imported Types using DeviceSQL.Device.ROC.Data; +using DeviceSQL.Devices.Device.ROC.Data; using Microsoft.SqlServer.Server; using System; using System.Data.SqlTypes; @@ -9,7 +10,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 27)] diff --git a/DeviceSQL/Types/ROCMaster/EventRecordArray.cs b/DeviceSQL.SQLTypes/ROCMaster/EventRecordArray.cs similarity index 99% rename from DeviceSQL/Types/ROCMaster/EventRecordArray.cs rename to DeviceSQL.SQLTypes/ROCMaster/EventRecordArray.cs index 0926089..05a7a36 100644 --- a/DeviceSQL/Types/ROCMaster/EventRecordArray.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/EventRecordArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL/Types/ROCMaster/FSTInformation.cs b/DeviceSQL.SQLTypes/ROCMaster/FSTInformation.cs similarity index 99% rename from DeviceSQL/Types/ROCMaster/FSTInformation.cs rename to DeviceSQL.SQLTypes/ROCMaster/FSTInformation.cs index 4c2f27c..93d216e 100644 --- a/DeviceSQL/Types/ROCMaster/FSTInformation.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/FSTInformation.cs @@ -7,7 +7,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL/Types/ROCMaster/HistoryRecord.cs b/DeviceSQL.SQLTypes/ROCMaster/HistoryRecord.cs similarity index 99% rename from DeviceSQL/Types/ROCMaster/HistoryRecord.cs rename to DeviceSQL.SQLTypes/ROCMaster/HistoryRecord.cs index 91bec24..505db2f 100644 --- a/DeviceSQL/Types/ROCMaster/HistoryRecord.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/HistoryRecord.cs @@ -8,7 +8,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 11)] diff --git a/DeviceSQL/Types/ROCMaster/HistoryRecordArray.cs b/DeviceSQL.SQLTypes/ROCMaster/HistoryRecordArray.cs similarity index 99% rename from DeviceSQL/Types/ROCMaster/HistoryRecordArray.cs rename to DeviceSQL.SQLTypes/ROCMaster/HistoryRecordArray.cs index 471c98c..0c8097a 100644 --- a/DeviceSQL/Types/ROCMaster/HistoryRecordArray.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/HistoryRecordArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL/Types/ROCMaster/Parameter.cs b/DeviceSQL.SQLTypes/ROCMaster/Parameter.cs similarity index 99% rename from DeviceSQL/Types/ROCMaster/Parameter.cs rename to DeviceSQL.SQLTypes/ROCMaster/Parameter.cs index 6cab5b7..af587c9 100644 --- a/DeviceSQL/Types/ROCMaster/Parameter.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/Parameter.cs @@ -1,6 +1,7 @@ #region Imported Types using DeviceSQL.Device.ROC.Data; +using DeviceSQL.Devices.Device.ROC.Data; using Microsoft.SqlServer.Server; using System; using System.Data.SqlTypes; @@ -8,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] diff --git a/DeviceSQL/Types/ROCMaster/ParameterArray.cs b/DeviceSQL.SQLTypes/ROCMaster/ParameterArray.cs similarity index 99% rename from DeviceSQL/Types/ROCMaster/ParameterArray.cs rename to DeviceSQL.SQLTypes/ROCMaster/ParameterArray.cs index b9a676a..97e4824 100644 --- a/DeviceSQL/Types/ROCMaster/ParameterArray.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/ParameterArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] diff --git a/DeviceSQL/Types/ROCMaster/ROCPlusAlarmRecord.cs b/DeviceSQL.SQLTypes/ROCMaster/ROCPlusAlarmRecord.cs similarity index 98% rename from DeviceSQL/Types/ROCMaster/ROCPlusAlarmRecord.cs rename to DeviceSQL.SQLTypes/ROCMaster/ROCPlusAlarmRecord.cs index 3ac0be1..61deae3 100644 --- a/DeviceSQL/Types/ROCMaster/ROCPlusAlarmRecord.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/ROCPlusAlarmRecord.cs @@ -1,6 +1,7 @@ #region Imported Types using DeviceSQL.Device.ROC.Data; +using DeviceSQL.Devices.Device.ROC.Data; using Microsoft.SqlServer.Server; using System; using System.Data.SqlTypes; @@ -9,7 +10,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 28)] diff --git a/DeviceSQL/Types/ROCMaster/ROCPlusAlarmRecordArray.cs b/DeviceSQL.SQLTypes/ROCMaster/ROCPlusAlarmRecordArray.cs similarity index 99% rename from DeviceSQL/Types/ROCMaster/ROCPlusAlarmRecordArray.cs rename to DeviceSQL.SQLTypes/ROCMaster/ROCPlusAlarmRecordArray.cs index 5d95eff..af950c8 100644 --- a/DeviceSQL/Types/ROCMaster/ROCPlusAlarmRecordArray.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/ROCPlusAlarmRecordArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL/Types/ROCMaster/ROCPlusEventRecord.cs b/DeviceSQL.SQLTypes/ROCMaster/ROCPlusEventRecord.cs similarity index 99% rename from DeviceSQL/Types/ROCMaster/ROCPlusEventRecord.cs rename to DeviceSQL.SQLTypes/ROCMaster/ROCPlusEventRecord.cs index 8c6cf9d..533a872 100644 --- a/DeviceSQL/Types/ROCMaster/ROCPlusEventRecord.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/ROCPlusEventRecord.cs @@ -1,6 +1,7 @@ #region Imported Types using DeviceSQL.Device.ROC.Data; +using DeviceSQL.Devices.Device.ROC.Data; using Microsoft.SqlServer.Server; using System; using System.Data.SqlTypes; @@ -9,7 +10,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 27)] diff --git a/DeviceSQL/Types/ROCMaster/ROCPlusEventRecordArray.cs b/DeviceSQL.SQLTypes/ROCMaster/ROCPlusEventRecordArray.cs similarity index 99% rename from DeviceSQL/Types/ROCMaster/ROCPlusEventRecordArray.cs rename to DeviceSQL.SQLTypes/ROCMaster/ROCPlusEventRecordArray.cs index 35ae73f..6ef2e3a 100644 --- a/DeviceSQL/Types/ROCMaster/ROCPlusEventRecordArray.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/ROCPlusEventRecordArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL/Types/ROCMaster/ROCPlusHistoryPointArray.cs b/DeviceSQL.SQLTypes/ROCMaster/ROCPlusHistoryPointArray.cs similarity index 99% rename from DeviceSQL/Types/ROCMaster/ROCPlusHistoryPointArray.cs rename to DeviceSQL.SQLTypes/ROCMaster/ROCPlusHistoryPointArray.cs index 0339928..6ee3e53 100644 --- a/DeviceSQL/Types/ROCMaster/ROCPlusHistoryPointArray.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/ROCPlusHistoryPointArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL/Types/ROCMaster/ROCPlusHistoryRecord.cs b/DeviceSQL.SQLTypes/ROCMaster/ROCPlusHistoryRecord.cs similarity index 99% rename from DeviceSQL/Types/ROCMaster/ROCPlusHistoryRecord.cs rename to DeviceSQL.SQLTypes/ROCMaster/ROCPlusHistoryRecord.cs index ee7bdc9..57ab050 100644 --- a/DeviceSQL/Types/ROCMaster/ROCPlusHistoryRecord.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/ROCPlusHistoryRecord.cs @@ -7,7 +7,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 15)] diff --git a/DeviceSQL/Types/ROCMaster/ROCPlusHistoryRecordArray.cs b/DeviceSQL.SQLTypes/ROCMaster/ROCPlusHistoryRecordArray.cs similarity index 99% rename from DeviceSQL/Types/ROCMaster/ROCPlusHistoryRecordArray.cs rename to DeviceSQL.SQLTypes/ROCMaster/ROCPlusHistoryRecordArray.cs index c056a31..8727010 100644 --- a/DeviceSQL/Types/ROCMaster/ROCPlusHistoryRecordArray.cs +++ b/DeviceSQL.SQLTypes/ROCMaster/ROCPlusHistoryRecordArray.cs @@ -9,7 +9,7 @@ #endregion -namespace DeviceSQL.Types.ROCMaster +namespace DeviceSQL.SQLTypes.ROCMaster { [Serializable()] [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] diff --git a/DeviceSQL.Service/App.config b/DeviceSQL.Service/App.config new file mode 100644 index 0000000..731f6de --- /dev/null +++ b/DeviceSQL.Service/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/DeviceSQL.Service/DeviceSQL.Service.csproj b/DeviceSQL.Service/DeviceSQL.Service.csproj new file mode 100644 index 0000000..64c375a --- /dev/null +++ b/DeviceSQL.Service/DeviceSQL.Service.csproj @@ -0,0 +1,72 @@ + + + + + Debug + AnyCPU + {F7B38332-A678-424C-A67E-25CF36C2430D} + WinExe + DeviceSQL.Service + DeviceSQL.Service + v4.6.1 + 512 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + Component + + + ProjectInstaller.cs + + + Component + + + Service1.cs + + + + + + + + + + ProjectInstaller.cs + + + + \ No newline at end of file diff --git a/DeviceSQL.Service/Program.cs b/DeviceSQL.Service/Program.cs new file mode 100644 index 0000000..cf9c86e --- /dev/null +++ b/DeviceSQL.Service/Program.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.ServiceProcess; +using System.Text; +using System.Threading.Tasks; + +namespace DeviceSQL.Service +{ + static class Program + { + /// + /// The main entry point for the application. + /// + static void Main() + { + ServiceBase[] ServicesToRun; + ServicesToRun = new ServiceBase[] + { + new Service1() + }; + ServiceBase.Run(ServicesToRun); + } + } +} diff --git a/DeviceSQL.Service/ProjectInstaller.Designer.cs b/DeviceSQL.Service/ProjectInstaller.Designer.cs new file mode 100644 index 0000000..5f66bd6 --- /dev/null +++ b/DeviceSQL.Service/ProjectInstaller.Designer.cs @@ -0,0 +1,56 @@ +namespace DeviceSQL.Service +{ + partial class ProjectInstaller + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.serviceProcessInstaller = new System.ServiceProcess.ServiceProcessInstaller(); + this.serviceInstaller = new System.ServiceProcess.ServiceInstaller(); + // + // serviceProcessInstaller + // + this.serviceProcessInstaller.Password = null; + this.serviceProcessInstaller.Username = null; + // + // serviceInstaller + // + this.serviceInstaller.ServiceName = "Service1"; + // + // ProjectInstaller + // + this.Installers.AddRange(new System.Configuration.Install.Installer[] { + this.serviceProcessInstaller, + this.serviceInstaller}); + + } + + #endregion + + private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller; + private System.ServiceProcess.ServiceInstaller serviceInstaller; + } +} \ No newline at end of file diff --git a/DeviceSQL.Service/ProjectInstaller.cs b/DeviceSQL.Service/ProjectInstaller.cs new file mode 100644 index 0000000..bda0512 --- /dev/null +++ b/DeviceSQL.Service/ProjectInstaller.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Configuration.Install; +using System.Linq; +using System.Threading.Tasks; + +namespace DeviceSQL.Service +{ + [RunInstaller(true)] + public partial class ProjectInstaller : System.Configuration.Install.Installer + { + public ProjectInstaller() + { + InitializeComponent(); + } + } +} diff --git a/DeviceSQL.Service/ProjectInstaller.resx b/DeviceSQL.Service/ProjectInstaller.resx new file mode 100644 index 0000000..2c076de --- /dev/null +++ b/DeviceSQL.Service/ProjectInstaller.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 196, 17 + + + False + + \ No newline at end of file diff --git a/DeviceSQL.Service/Properties/AssemblyInfo.cs b/DeviceSQL.Service/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b9c1f13 --- /dev/null +++ b/DeviceSQL.Service/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +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("DeviceSQL.Service")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("DeviceSQL.Service")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[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("f7b38332-a678-424c-a67e-25cf36c2430d")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/DeviceSQL.Service/Service1.Designer.cs b/DeviceSQL.Service/Service1.Designer.cs new file mode 100644 index 0000000..d644fb8 --- /dev/null +++ b/DeviceSQL.Service/Service1.Designer.cs @@ -0,0 +1,37 @@ +namespace DeviceSQL.Service +{ + partial class Service1 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + this.ServiceName = "Service1"; + } + + #endregion + } +} diff --git a/DeviceSQL.Service/Service1.cs b/DeviceSQL.Service/Service1.cs new file mode 100644 index 0000000..e900e1d --- /dev/null +++ b/DeviceSQL.Service/Service1.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Linq; +using System.ServiceProcess; +using System.Text; +using System.Threading.Tasks; + +namespace DeviceSQL.Service +{ + public partial class Service1 : ServiceBase + { + public Service1() + { + InitializeComponent(); + } + + protected override void OnStart(string[] args) + { + } + + protected override void OnStop() + { + } + } +} diff --git a/DeviceSQL.Services/App.config b/DeviceSQL.Services/App.config new file mode 100644 index 0000000..14efc92 --- /dev/null +++ b/DeviceSQL.Services/App.config @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DeviceSQL.Services/DeviceSQL.Services.csproj b/DeviceSQL.Services/DeviceSQL.Services.csproj new file mode 100644 index 0000000..5c25c6b --- /dev/null +++ b/DeviceSQL.Services/DeviceSQL.Services.csproj @@ -0,0 +1,83 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {4136548D-5D58-4EEB-8876-D450ADC62369} + Library + Properties + DeviceSQL.Services + DeviceSQL.Services + {3D9AD99F-2412-4246-B90B-4EAA41C64699};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + /client:"WcfTestClient.exe" + v4.6.1 + True + True + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + {80ed4080-6fd1-492f-b70e-8c837b3dadc7} + DeviceSQL.Devices + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio + $(VSToolsPath)\WCF + + + + + + + True + + + + + + \ No newline at end of file diff --git a/DeviceSQL.Services/IService.cs b/DeviceSQL.Services/IService.cs new file mode 100644 index 0000000..be482a3 --- /dev/null +++ b/DeviceSQL.Services/IService.cs @@ -0,0 +1,23 @@ +using DeviceSQL.Device; +using DeviceSQL.IO.Channels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.ServiceModel; +using System.Text; + +namespace DeviceSQL.Services +{ + [ServiceContract] + public interface IService + { + [OperationContract] + List GetChannels(); + + [OperationContract] + List GetDevices(); + + } + +} diff --git a/DeviceSQL.Services/Properties/AssemblyInfo.cs b/DeviceSQL.Services/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..d295e60 --- /dev/null +++ b/DeviceSQL.Services/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +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("DeviceSQL.Services")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("DeviceSQL.Services")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[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("4136548d-5d58-4eeb-8876-d450adc62369")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/DeviceSQL.Services/Service.cs b/DeviceSQL.Services/Service.cs new file mode 100644 index 0000000..4b8a4b6 --- /dev/null +++ b/DeviceSQL.Services/Service.cs @@ -0,0 +1,39 @@ +using DeviceSQL.Device; +using DeviceSQL.IO.Channels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.ServiceModel; +using System.Text; + +namespace DeviceSQL.Services +{ + [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] + public class Service : IService + { + + #region Fields + + public static Dictionary Channels = new Dictionary(); + public static Dictionary Devices = new Dictionary(); + + public List GetChannels() + { + throw new NotImplementedException(); + } + + public List GetDevices() + { + throw new NotImplementedException(); + } + + #endregion + + #region Service Methods + + + #endregion + + } +} diff --git a/DeviceSQL.sln b/DeviceSQL.sln index cadd9af..8155053 100644 --- a/DeviceSQL.sln +++ b/DeviceSQL.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.27130.2010 +VisualStudioVersion = 15.0.27130.2026 MinimumVisualStudioVersion = 10.0.40219.1 Project("{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}") = "DeviceSQL", "DeviceSQL\DeviceSQL.sqlproj", "{CB6F0884-5A58-432A-800E-4ABFEEAB6F46}" EndProject @@ -13,6 +13,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.Utilities.RealFLO EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.DatabaseSetupUtility", "DeviceSQL.DatabaseSetupUtility\DeviceSQL.DatabaseSetupUtility.csproj", "{22929CF0-D02A-47D9-A308-D1D5497BF42B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.Services", "DeviceSQL.Services\DeviceSQL.Services.csproj", "{4136548D-5D58-4EEB-8876-D450ADC62369}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.Service", "DeviceSQL.Service\DeviceSQL.Service.csproj", "{F7B38332-A678-424C-A67E-25CF36C2430D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.Devices", "DeviceSQL.Devices\DeviceSQL.Devices.csproj", "{80ED4080-6FD1-492F-B70E-8C837B3DADC7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.SQLTypes", "DeviceSQL.SQLTypes\DeviceSQL.SQLTypes.csproj", "{91B62CD7-190B-4727-B1EB-66B51913709D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -65,6 +73,38 @@ Global {22929CF0-D02A-47D9-A308-D1D5497BF42B}.Release|Any CPU.Build.0 = Release|Any CPU {22929CF0-D02A-47D9-A308-D1D5497BF42B}.Release|x86.ActiveCfg = Release|Any CPU {22929CF0-D02A-47D9-A308-D1D5497BF42B}.Release|x86.Build.0 = Release|Any CPU + {4136548D-5D58-4EEB-8876-D450ADC62369}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4136548D-5D58-4EEB-8876-D450ADC62369}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4136548D-5D58-4EEB-8876-D450ADC62369}.Debug|x86.ActiveCfg = Debug|Any CPU + {4136548D-5D58-4EEB-8876-D450ADC62369}.Debug|x86.Build.0 = Debug|Any CPU + {4136548D-5D58-4EEB-8876-D450ADC62369}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4136548D-5D58-4EEB-8876-D450ADC62369}.Release|Any CPU.Build.0 = Release|Any CPU + {4136548D-5D58-4EEB-8876-D450ADC62369}.Release|x86.ActiveCfg = Release|Any CPU + {4136548D-5D58-4EEB-8876-D450ADC62369}.Release|x86.Build.0 = Release|Any CPU + {F7B38332-A678-424C-A67E-25CF36C2430D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F7B38332-A678-424C-A67E-25CF36C2430D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F7B38332-A678-424C-A67E-25CF36C2430D}.Debug|x86.ActiveCfg = Debug|Any CPU + {F7B38332-A678-424C-A67E-25CF36C2430D}.Debug|x86.Build.0 = Debug|Any CPU + {F7B38332-A678-424C-A67E-25CF36C2430D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F7B38332-A678-424C-A67E-25CF36C2430D}.Release|Any CPU.Build.0 = Release|Any CPU + {F7B38332-A678-424C-A67E-25CF36C2430D}.Release|x86.ActiveCfg = Release|Any CPU + {F7B38332-A678-424C-A67E-25CF36C2430D}.Release|x86.Build.0 = Release|Any CPU + {80ED4080-6FD1-492F-B70E-8C837B3DADC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {80ED4080-6FD1-492F-B70E-8C837B3DADC7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {80ED4080-6FD1-492F-B70E-8C837B3DADC7}.Debug|x86.ActiveCfg = Debug|Any CPU + {80ED4080-6FD1-492F-B70E-8C837B3DADC7}.Debug|x86.Build.0 = Debug|Any CPU + {80ED4080-6FD1-492F-B70E-8C837B3DADC7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {80ED4080-6FD1-492F-B70E-8C837B3DADC7}.Release|Any CPU.Build.0 = Release|Any CPU + {80ED4080-6FD1-492F-B70E-8C837B3DADC7}.Release|x86.ActiveCfg = Release|Any CPU + {80ED4080-6FD1-492F-B70E-8C837B3DADC7}.Release|x86.Build.0 = Release|Any CPU + {91B62CD7-190B-4727-B1EB-66B51913709D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {91B62CD7-190B-4727-B1EB-66B51913709D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {91B62CD7-190B-4727-B1EB-66B51913709D}.Debug|x86.ActiveCfg = Debug|Any CPU + {91B62CD7-190B-4727-B1EB-66B51913709D}.Debug|x86.Build.0 = Debug|Any CPU + {91B62CD7-190B-4727-B1EB-66B51913709D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {91B62CD7-190B-4727-B1EB-66B51913709D}.Release|Any CPU.Build.0 = Release|Any CPU + {91B62CD7-190B-4727-B1EB-66B51913709D}.Release|x86.ActiveCfg = Release|Any CPU + {91B62CD7-190B-4727-B1EB-66B51913709D}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/DeviceSQL/DeviceSQL.sqlproj b/DeviceSQL/DeviceSQL.sqlproj index d2b0ca9..afb9f04 100644 --- a/DeviceSQL/DeviceSQL.sqlproj +++ b/DeviceSQL/DeviceSQL.sqlproj @@ -62,323 +62,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -392,19 +80,8 @@ - - - - - - - - - - - diff --git a/DeviceSQL/Documentation/Modbus_Application_Protocol_V1_1b3.pdf b/DeviceSQL/Documentation/Modbus_Application_Protocol_V1_1b3.pdf deleted file mode 100644 index c531a74b62f479f252d490321bbcd04c059c1e44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 818663 zcmdSBbzEE9);5Y$+$m5bxJ!b2ad&rjcZXs{ij-o7;#%B_yA&^4+@W}BvEp(A?0t6k zk@q|Az284K{6ex;<{UD|m@6yKc;=*36cuL#GO?o|Qr3bWD2PA+3&6qH8U>M$k6G2r z(TrKd$koW!!Gc-Q$imD800Muk%q(kUZ$V>b�zC3t(1pb#^mxRdqHqQ+9B01pqnO z9^1$nIon9tn>&EzJiIkC1%TU`34k9ch-UVtk2)Tt{Y}}U5@rzxH+xqAI}5Xnm8pvk zfb~Hh0Qe{t0OEc;Vr74Nc{*a_d^}>~dU|;}$5>`zkI zIi8w4NnwAI!u}+M<4Fp~lN638DI8ByIG&_%JW1hrlEU#Mh2u#I$CDJ!Cn=myQaGQa za6UQh3iQQ*OL^kCtJ9lq;Ne+;d+w7^&|!O zhiSk+i~>HHqX+msBoEU5B_!bBJDY(+@~Dwn+04bk&Dq4v1sqy&2Yc6t7a-tKF|#-b z@TiknoD~3kG?!VN4FG)XC?LSBsbFkvX7bQO$_|`Q+<-^Nz#k|&JD8}Lx#}>3^O0HA z%+vL$f$-Cd$kU6|gQ?7NW~Np~!VaD~U`ts5?A+{3Y-|87HXsuRmmUC|JNB+%Q(XX$ zu%&N{t_AZVOE}3{Si>NS*nz>t-$&>{@Sh_jZe{Cg=FBW^YvgJsYG&eKYQ`*UW^dtY`Cu38LoXLsXEP%^6hzOo z+H{@R#fGX^D=3H;f~O`5=r%oXXlS27T{QItwmMBO!*o)i)tt@Rr2QK1NlyE=Lh_EX z_>FRrrZRnVM?9M#qRN!gC#+x zm7DD!SI1LRVX>SV27=4WH*08N5(>m5#I211KaW#*PSt**IxMfW7oyhQ8xYMmS@ZZ< zrWfgYc%JOuwO$>P-dz5;Yt4)adlNvod~!F+BeJH``km3!&PI#pUx%Sgoo?(sRYrJJTY1TH7|;2MQ8;%(s%9YMBul-n;4n z8krHXInNhH_lkSZyEjKkCJIT6Pwp}4*KA7B?`LKet=feBp9>oF?jN4t-z45R;QYM& zR#MNq+-uPKCLkaN)c(2M;HI8xahGzjV2kDUs5@w`U|em%)I2$Js(>SLkOZRE(q)SBQFyWMGGFHve6Li^E|Exo;yU$;I1w_nz_ z?poW>eqn@!IqZ$xZ|Ic-8q|i>>wn%nQP3bMzwVA-=+1;kJ{a^i=KPC*w~xIvkQ}(YaVW;+@RdrK8-tEqPwdh z<{QSPBd?oXlYsnCo#l(zT~Pn6z#vc0=;0*EI?lzJ9QKCb0*!eK>iU{SMcjPh5$hs? zb_S)$_pj)|$W@)_O|*8CYWB)N)`Yc4^^Z9coVE+n*VCZly?1ZhMRn9pU(*plWd`UU zBjnTBIpdojEtiAn+LPI}4cZ!-E*-h_SNJY|jKeAgon9RV*~E#~Pyjo8jt{Nwv3;bu z?-OkJpY?q~K}19NgwFdCKSQ9Yyx+9#6{UyW0fC)hhjgPd_-rr$ctAvR-a8 zf_w&05Oefb^p?`{7;_-ssK>)=)WB&k*LPie(!CAy>|V1OpVTGN&xwGAo@>3Y)K!e( z)Sr@@`d00=u<)*NaHb+TF~XNf>Y4-2dUXdKO22Ou9=oYEHWQ6T^M-O6p^81kJIs^F z(fNbpM4lsh(C2+fYIJXB*qm2c{9}n)DvWuBFG$KQ5}UEq*>;b6Ra*z`1Y{6)kM*Sh z`HBeinI}HFW@PO%#_fFtHU1T${>=W8r#$Tnz*laG7;`#~zp$YJUM-Dc8VaVunAsXP zC+M~rSG_aiI`=pR*N0v0!b@FzFt6l^EbuQe9dvC`osMXd)#Ngf<_1hq5I3vl=}Xki zkF&L2jVg}t(mq;;EfF$by3G$u-E5lT8i`ms9V-_G2R4tU&rsz~O#Ua()b z-e}o!a<_rVH5lmI;xGB%^?g{7St6FY8M*f4Z~57|U!g?kh*NP-kn0tGypo;Kk&H*u zu?j(~(k>%{f{0FkK_5Z4`1aZEMS7Vwc}39cV~eTJ81?aQ(^tn8{mWXbS^Ps81Z3bh zrwd%vR=yVoJKHXN7BbX^r!O;N2~2${8ex7k#hVXP9Um&H;yFhp8J^i-KeY35vbk7| zoFXI_T5fa!H5WR?*8giIQwnbsswtVl=W)oxa~*8z)i!?LUKg96=sJ@27rZ||3W!I% zi17_A>5s-y6S}Ilri+)Fiy(|SwXTr+)%eANmUL;JzUWJgw53D6TBgPeRebsZMwi^L zG5D;D>pDJNQL=PMD2N)KDrjSxM-9I|d>r3pNn|aATOhKw!CX zHe}mBdPbtlJW2zFw{ZojZ#lN@W%G5q8s`E-^|ux^IUJg28>=K6UAh^1nooO4RJt4; zAh*EN;VoI97{p73T$ooGFfXCY=_?2^A>>rtQW9E~u_Ylq?GEyUz_|$3LGRR58iF(2 z$X`w$w{UJ;-^Wo8R#pF8kf?Zh>%0Jok>}ipgG{M*_^9eI=$G+mA85_YFC7HaVzK^= z*a9Oe%JMV^l;yN=JQT|v0|Oz=>;TGb3W+Okl#E`1+pL<4USl=c-_WT|^@ zjL3K2(x^G!8wr!fYqB)%+#_geZq@AMuZ*R2IYX_nz^(G1Ih|hWV8iN;wt-d7(4rvX zokSiI!uSqtQPPNcw>c+TYp7xFUfu=PpdjMbByZDCoRAK2)?D#1=550>TTffAxs72f zl3LJ~aN)xyyn+G-229Z4f-cm)yrBOU*khk2-^eKNQK>x_!{WKMman1=FT3=c4QPfF zHQ$N=87&ExZp-*>D0+YZKnn8&ee36iifSM${-N(CSAt=4AllDy!c7!J0vla!_-r;Q zOohWS1Wl!M3Mp+IkvQ+4oiO=Q?>ybikI~Z#Ln$I=a@cc2pAQ7)>ht<$eZnL3dO_ic zohJVbHDXD!bPii?miU+MEC#xn>9{CWm0>koYQL%d8>-a|Zs;~ZlWo75X8ifbem?H9 z59kJ^MI7GYKq^{NppR1Lm`M~+kM_amQ-H~^#yjgZ9G0klYq*vyfQX4295n+x{E zYw#rpRhB^2vwlnr67PnG!PRg`$fN@ve!n=l_Z14_8-cj@tt^IC$QPPD-_$b;Lmy7Y zHtHf(1VIb&eo>+c>WCD2TOWZ8qy7vkV#yO>k^`NK%`HNxgSo@n6yP}Fr8E^T^vW!# z-3H;=sW$pc5@X#>wg|#S#T%>Fi?&MYWFW783`sjuw6y@Pi z5b1x&@B-N?WetPlUUrv;_TFdhK(4>`pn3OR*7^zs@tRaFH>x`gj|-2Pg|Q1dWSIMF zdcfY5+LSa@9;@1lG0+DxWSE&vU(dq%A;~S6Qi}ByyJR+IjWlBAxq!S3+&rD5_*|sC z51J1+-0`qLzqY>{P7^PJL_LeU1x%<)`uXeJi@qwqh45L(0^)6)6U!P9=8j;X7{S z)xCFd!teMH^7=oJ#RYvSRPN%Fj$4xaUS}(1Kt{iaZ)+6X-JYW(p|yVLFCfE_o2 zRb9J-I72li2&CgzqAabMw?Q zc05>HqSI_-q4XQ6(zFcb^#_GCx>^<`Z9`@HlnMIf_)6~*h3ZID88ts4e5ly^WfF1V zieO^4&nf0^QuRUIDYXv4#NH*L^75m0M3R$vm)CxxE0F~iR`|G-;=~sv(8z}R1tw9kaK+`FX-n})f6-p^kSyQe(z!3_b+@H%AUXV3@C@HCEczgaQVG`Gdjq^*idbd zGhu*zD{2_!$v`O@5N50?3hS{RLy3jsq0HBW;o$301rHz>RFE4FL=Z-p@1YCW*J~&;GE<5MXw*5AORe|Z8Q{w$_ z5lfoi>+Iu{PT5d-rSr;4bwWZYeS2FaO!m5 zINY$%L(Pmw1G}Etd-&aeCaEI~Qg$mOYQXuBdUC)-NgkTLfG`UN;{}}cAU`W;bNZ80 z^kS+-AdI3$*rE)DIrDNHZG9aQJ*RU?{xKJx(TN$0_A;sq3Sw@HHD=W8rKa9I3LYeXT7(%q4NIYwS zPSiP`NwVSVOBvLINMA{=SnBOT1<;df?+Le&kCFz2?Dz2NHm47YsmLK=ntjNDK5@az zU057fBc=MZNiTXj^WQ>>R)3&|ps2`(L3dA8NAfts24|Z6{OaV_)C^{*SBKr4pZx?N z0h+J|a7W^qDY6jZH0-d`JLwQz3S68`ch{l9*LTQhdr9QjGM@dWgDRxB$52i4?e>X#}}Ums8A`pDn%MbDW+kII%Fzb zFs^lODo_~J%$lk693knX)7)ay%F6!``ezIWu47uD_Dtw*e|%^Z_)A8$%!;a-+H}4$ zfD8Op7T<4bY@<81E$)CNpQ#76(_t2uor^`N54F?3Pn#W#cF#Msg~r%TL z2fHHuu3UMJVu`;@LoiXN?5p0lE;bbQDfoW1ef%Qp>awwll=f^Sq;@nL;2M9!9mgrU z4nwkYE-Wwkz1O(jsq5-|h>YqYdqw{>LSD8a6p-?*Bx6daRKC`VK}xQ1hO(f2Y7-_- zL4i_smo~psZAvQnXBxA5a$Igjz=u)r-D}WH=bKHIKx=7t2xGUKYV>2SEUI~QC>ikpYZu8^8Q^zyi@#%}Uez z4DxX0F;sxCEU9kg@Glvw~_`@>-zvO!)8utly;%p z5XK|4SjAd^0AqRwEX(Ll#0ni`=_PqKx?0F}C-7a0Z|oZgC}Y#lM~Khxb;en~c^xl* z=$_{RU*z!O@H>oVh<=WyOuhIVZ-lT)Mjws*d>RGO30PDVg5*BkV>(bX)bQ{{#x#Oi z(_qQYZwnF#y~^RV}b>p4jUHu3WX*#gI-hJ$O{3$wQ-C%N=V za4vWF_re@V`s(4^1r=}E2s74J?Y?CK=P-MjrF?F1G(u4jKX;vmgt!@lZ-v_;E8sOJ zZpoSBbeF8uTqP;044*eHccvD1DxVqCx2~1Xn5&tecuDue!g2gKZp*}U)(X@B72PuC zq~O3cNSQK+i#K%u91c$X4K0Rz!pACjMwky&wi9D404=RJ{anx&UeK@f9rJQH)j zskA=Ykr2wRy`hf`2F)QdiZ_!R{dB6yfhF zI7#f~Rvg|DLTN8WjL+6d)5!@7CqTIxLuS=i)yDmJWFwdvs!Bo6J|J0yXmveaRkZxN zwFCw~PFfNRqUsMK5RV)WP#jYw#|L5USIS*OGtaK6yCbEkc_))`5H`nnuIhk{=Le4D~)V zl}pfTmYItsioMgV15)>1rpfpV?X~-G1*FxOT1cWWi!zLZ=h&TJ3%mzQm0GTT#Zi6# z-AuoB2k!ksmHVy5*!xocT5f*`EEXFTZkS<=*P}{~--f;oA2}Rd(W{bFJU69Zc%5#+ zIw#{!vmimuy9EBGmFC`AcW+C%i_Upn=6#ON{=H8Jd=q>kO0KIUOu*>=qJVAig;ADL zHyXe#lvp??uE(B1-7Z^cMt#0K3*!f>ZPs`f`O+sNUNl=7d@avYD_0|~62jL4897Qt zPE()m&uE)Sf{`Ncjd6=Q_+K&m3MSp->EYY4+E;E1Gc%K;Cy3uYBJW7mf=mnyh8^>|j^$j%I0&tMidaxr^sA>?djWXmjO4@UQ`>@Aoz ztn7vCU9A3b{Ln_!%*Djn%F)%q8Sq$mVHUS?c5xN4G;#*8g22_XKi&gD?BMREu9hwU zP9V!;QRer;!b8`8G4Lz*tE7ac5I9^^}b3v^Z{LiQH6W&jpuAs3T}QVll? zJGid#^qvs}WC7Rl93{=HEG%6CoFFb{A$N;MO8{(aKyZD|^XUM@!NLBhM&qd^8w(4w z<{!O4;Ch^_nbE@-09aYU1rjqmb#U*;=E9HV7)Ee!z=JLTh=qmaLCxPwOAm#ifAQ}> z1pxF{0938)%v{JpEb?X^;Qz`Fc1HFL!Vb2k|8-0rNBTd;1o&G_{wPQNRiS+7`Y$&B zyO{h(Bmd_xad88G4-?04VdCKA{4Go%&fmhs&d&9Fm^lAKnAkvnh6(h0n83Xs!o=|u zCa{{nhv{Jq{^s%@MZ14Q>ale9G-v=2I0ODj5FiUHxcX-6;H=_kWMcMLQH@#H%GE{D z%vr?2&e6gCAveLsKh@1dMO6Q&nn{7HcFv9t4|TN1I`N-nG&VLCw%^NW_p|q_5a`n4 zQsNMhkdP3D;6I4_1qcy{XK--vaInwd;o%Vwo`EmUU{n(s2?-e=6AKNSh=7Ech=7m~ zK*2-}AY&jWB&6Y_Wnclav9Xa*bMte7_?TGPKo4Rd5fBiNk&y9F5WyH5h?I~N^uK=G zcR*k~gRp=&g@z=9fWm-;#(=!8fA$Om>=_gc3^WY=y;w8s*W0bC16LcdiBfzw+%LuKnfN zJOnZ{BshT37!ZOG=T|hjY!J$dl6n0k(sB!mXx6MTLB#_3ma(;kvbWYf&Uq1yc%Z9b zE#X@3W^t+NH0`Mz*@+2@R1m$fSWY}yG8=@FxaAiJY^7Azm$2C8QDcx|_+W|u$CFAg zpLr`Q*Gt>`C_;Fv6E}Mv6${~$doHdhNH2`GvxlxDnG5LdA*fwydV6c6e2}(5qK5Y6 zWd5Yv`wY5Gkgh#%iNAIpKt1I0smyqfv!HjjzofC=1c$<7jr8@diBZ3q#9i$Xmvth| z*J#nJjM7FrPAPluXXFK5AGe!c&v6csWu5=jZEcToc5<@$PE^>{{faa-QcX0;`fbsm`PM>kX|g&4>6&K%ho2oNn-2pBaRin-e|UK-Y=S z6ihCg$Az=g-1cq^a$?dsQ)kHH7%H)Ba!oWjZBgqeh%`B1@btg z&&RYpSM@tUjQ9c_-t9@8Zd+}c+{cme-r=M@M+h#)AJ)8O!pmP0DV>R$Am|eN75Jk( zX&i-A;`A9#_~g8$(c(QJt!;xR01oVA1S znR#(a9m6v-@okaogh2jN;b45-!X5SKw%2_3&}^sPd0StZ4lDmB+wTR!x$bD*d#>~n zuc=dx`G#TP$24LuNR$aYA{j$ov2mgxerq5P%z&)$=!LI!pIrNuyq=cUm@NOA&4sy4 zQHtIJ1+fpB%|X`EpJpN9=TqL?D;F&;htJirtDD&4lRF|mKD{p+; zJt1lNnPa}l%RJhlB)YRbKM)>q7+Y=s4R0-nKYHCeb>2codR*HLYUs=?oO+Jde4Vzr zT6#94PVmpWAVKZ5bdJ3B+NvGlVn>yvWVT%pJuRO^PF2@looGgv+dTxqxRkP}Mszp1 zGYVo_@WofI0sA*m8_c1L$!=6)imlVG2b?5!ZS}$YFx9ZsC&j^^y%7xID$EgfkcZ?{ zK4>TzyIB=lP}uSoGiinr7sOG9CL zK8v+3r`rl^!Bw{s3m=;R`+8gt3vpU$t)bWN7x_gHhwl z&)jN81MAfUcqv0x%SEP^XK80%^$Y_-W$t}f|#08CPfjP_E_b=>>9SSZv)a* zCr$@yb-vZVGK4-Eh{2I?`Kdot6xL%@v|%kHS<-$%ot9|JZ?%?H8(*JYy9#CqwTIVY zv8_f6EN-duJ?9q=h^;l+1KrkZG`<7>xS>i5pOOIIH8{fW>X(?0?+D;d!B&5dL{e4_ zs1t&?m15r(z^J|sh&e(51+U~NgM9P>I>dX)1C0m+ko|kq&2gbZF)3xpm@q7K#FG4w=ZsP2U za?jMWup@e{jGftkF&UTwW9C~H_Ez5et+)EmZhm1MJ#tN}^yvJLn6Ufxo5r&@CFw^7 z(UeERLiTlSq8N>Kf#)?(F0QuU=N|98(46Q@G<1kni>k9yK~&G) zpIxbrfuA;$UL>*h{P^r)fr9AhG`duxJ=0Utsv?^)z(7`~m2A?Ul9}*}2;MsK4G!Jn zn0su0lLNSl%U3fk&KZQ<-OJ+@l4$<+XP;Z=QmVppc{gVKm4nNOw3ivzj#>W3O%9<~ zY}NV-B|{j;?^p>bVq5x(NM7CAL|*GA>63E0^j%-rw@gQjfJ97#f0dDaJ;HQaBB#nn zLB!Y^=e!^ho?R$Qk8Z6tWB@W4`a$4quHZU|HYG*}y%hzf=Ao~Bfhfta+r)rBe+h|ZhJLkeP7{cib?v`h7++&RSZchiw z$(CEH8FQWF2s@1UQPwH-P5do7%S-nT!Js&OpIj6~q92rg&NA%`AL*tqC}X?^`0gRD z_9t32$`(BpL?*r)RtK%azZrNtf?$xqOz3@bsllALcZY(QL{3$e^UR*p=^MN$dHs=- zwqpEdLYj`;>Ed9EN&+A+FyTV>A!N1Em47z8AcNu=wnxyQ;NZ z^Kt^FvOnm1=}{0T91Cd~C+JWRk0rNik+#1gpu#7hsySUv!~PmZaj>X! z4c);GSyz8D+)H_aDq!+eW80-iK3{?-<{)DsHBm(mOJNWE*3G0n{r5-|^D&r}%g<8WSrgai#wpj7~2O4CNTqYPj z*-9>}Gef^295uXdOuJq7K;Zy258;giCZKZr}UjEu~LN2fI zC^MQ)Jui&89p)0NeTK8RQ36773c|QOR(0DOUdl#VyTZ~JjmFqC?DG^h1TczFfv;$9 zzyzdp9&6ORvMB?RFG*Cth~(A$&p;+)2d0x0)y)wWF}C<>O`Q2unQQ4JGL6@ANtwu4 ztI<0wUi;b`WsE-9fR8GwMY}j--_le!M=6VhuO%mcvEW_}BE91A3P%+r7;=EVaEiSN zGJ;+Z+|YZ@R$FR4LN`!NDW29wQ(!uG;UYOX%U+&thgBi2`FibQIv(IgH;9557la1* znxI50tzE~}1yql$il7epg#W%~7uPhSAsl=mvC6X2_7pUoJXq`Rq{V}|V=ojVp3YTw zHoYeBXr}`n_yTig7yF#-3UtKSOcUZ%5~+(yI0@u4y=YSRdgr|$dUuW0xlRX2wA;l{ zmF>@&-*MDN?U!N6wbshmym{dfDDcf37<%QcM#D#xrNiZU`a!W{o02ntXE`TS*+#VA zHEU^}Ofrd0O$-IGWLyHO=I0H6-d=Ruxk7#VsD>&2&Axi1v>b1NN{DuiHa-V2(S&Q= zibdf<*UGXg{>>i8Vci?b1wDZe_LDW2p@Ytvzu0TVG(M&Obn+o^uZ^6+eY@0U-1M3| zmpai6hNNSf^@6%PMv903<2{5M@TMduC&7Yi=e>Lab!p=8Gv60$*B)rZan^Vqw9S{( zi%#KVWFJuw;UJ(PR1;cvrJa*|esE2O2;dk2#Taoo=sK+Oe9Y4#dh{#2u*4Wgp7aO9euyn4;xHqPc*8eGA}xz*A(=l(5n`bgyd8zl5UL8q*LA$N~J<^K+=13r@5{~NIG(JJNN z0o2F7|6=FAL+gGs?0?4R{%aVOllwP(jsuLaJ`B+xFzSE8=l+6GIe*9Jz`g$`81<1% z|1Vzt1D*RPAe-&4X#5+9^1p^qfsd;U{$p5J{=!h70{FME{L7kxzhmZ)zCQxn|IWhy zIX?dre#*`I8-B|2JIu|_@wfQ=Cz$&${FLSQ_<(!=j-PU~{vAJkT&VK5_&ls?`Clxd z_-o|^I{=K*J}kHq2ZObb69c?L;jc9ma%QeZAn+%TZNQ)W-(N%ld|K7%q;aC7S5J>ck^wQ)qb;&9oS+e(Yt8Xk9 z$j}wwyK{EF+}_yw)_ry6-@LpeXse)5a-#8k>T+|fbKr&2+VJ2QPBj-mr01|Yp?EhG&xH&4!>(`AF7rFT%BjGmT0OSE|-t^ zUX$}h`*eL&IAqc|KU^*?kBN!aF7vw{Id4BVAo0B~bCBR6;rqfoCg>k}C*AC^6YN@f z8($ce>mOMo0=_5QkEmJc@DX&(3EhC9C8r*fPwS{TX1yDl#BR$!W4yR42`J7rC>{zR zByNH0+n|bkmD%dIgWN5C*6H>xk1;f&*J7tLoUoz zlyjK1*&FaVDLtV5_w{q9o;WGJf)X( zxKO^giE5$V$!8;1~GJtUKC{jSZ#?tYCu z%Ef?{l9DP$*6GDEOYX|&uSj&F^s|*#j!@PJ=5IvZREY+0G8M2XzWM{?_=%Jp=L}Mm z-I0-PHGS5LKW)k4YS@xCGW1i{4V!R7Nw_SFX2s#{u|bE-1)BIeM_{ZpmV9sNVFB^U zTPu_d^KM0BRep+8@<5K^_?~_YZAG9{C!3`UO{jdkMGJ^`8}QXps<#^)wJa&+squ zKKTF(`^o|W*K&fBU1lVXNBmJKh2y2RJT{_{C$EjPC5Tr-l8pGA5{_e67!>!gpwe`f znx1nLh%=18TlCcBcn+idmAtMQB&Pk2Ji+0lxBDYFQ|2jIClNTyeY_+W1`KtPHKm>QrPN9j4{m4kv3v z69?REK$DSK%*!9|4sCj934L2v^?=9%z_)#C=&yT-NE}(`wO^x!sP!|vrj?{=U=WTk zHqx_;6t1`olj8|OUrW`RX3|NH$>~+&12TlS2vo6C5eibzeDsH)LLzOzrW)s}QgFo5 zq0$=$uQbq=9b^iJ#t9N1w1G1soEIw~JBK8t@Nh%*=VF_6@{Tu`30eXTkEr;9-eYqy zn0>)!hhqr_WbH?Fs4+0U-UWsKNPTxH{G$GK#dvTnz99hevH|ivCmQ%pHiE%YxJU>_!Nq8Y_ zv>s2tRj+9w>@*UhXQf?_BToTD3UqD!2A&PG>Vl(lpKOnB%WcT=n*|#t0+<_!571nB zSGDFzL`*^6l@4X!DrHDx7Y$G)dY@4mxKMd1k~zu=WHQ7cC*#dF)8f5$g2_l+M}Qi` z<*I}q`aJKQ@G?e{3QTO&exqF;=g_nKm;)^aCd(KZD+Y9(R zHRh2d$J&!9h*}A%{UuD;cLN9Am8C3@tYdVYc9w}I3|7BRbdg-xcO52b2}L|7LaYGEt_?My4RbcFqSA9vtyT2s)Om_E>q4Z4MI>7vYWTD zu6ZbYAC@qIemZ&MWSgmBrbSztA6tzZof(wehMqrOTG0x-Svf>*A))^=E{_g9hHW6A zq#A*cDV;=H?;ModiRDI{HYPMKyN5gYwM^D(w7_1aSpOTneKfC|_RA_g>GA%+zD*%6 z7gFSmMc1ND;FmL*kv^P~VCeK#vqOD(jn0TWS)9c^s}7(FOdme=xyx9FnhdS%G1qCS zHSM@4@tM8L_UM%qZ#(GusC7P!x5>R1^H;g0ISMjnFo49b1k}=0NDny}EiRa7ii=M% zE;eF4W+}+QrY_0TrpT4d{A6@8Q=&>7^I;a3VgqwRa*`RCOH8UQ@StlHLM7Zdn~}r zp%=|FYMv{s4nRYEyTv!T;=uAHpv!iXuVik(to$if%B_Ggo_^gkw zN2!i&T08KZ#JS-yiT0~RdVcB7l0eQ99(O0ELEmpUEm?us(@~k38X0VMf~wje;fa;r z9w=yipLnr)-ZvO;_Ux-#9StiI=_M(w`I*iR_LvUnZcz{uElOQ!WuR}SWeOo2l&my# ziHOKM=7H5C6+?08-g9|Bf>I79+pa7>daRR?!`J-CzV@HBEc8WnQaIzGzR0_q z^Fr_PUsC9}BU=rFfO*wUb5zB?;}>pVxh7rJgac-$55v&4lMugen#_nP^(j&{6Jyj4 za3*zggZ(7G?BH%Qr(Qu^Oj2NZz^L+Gym@C$YEbOE+qJ!Jq`t6e5`nNB;9`sB>wwT^ zy+n4By>F4iKEiA&*TiMkCJt(U^>_?lEMk4@*g~%=E0||skHa3S* zeLk=oL8asG#a!t6StqFUF6ES4ej+GLQ5RyKW1kNzULx$!EOX>zfw4~2y&5V$^A0H# zMDFKVMXH~1qU_AfnKjz@=@MP38bjLj8dj2&8(`|bwb>k@y31Erb^C3S#J;w1)ROAy zr>M>kO+AiSQJEnfL1zkcy%Yb z24Puu+ zNT{~3^%vPizQS5NaXAb-HMy!^6nw2{ifl)&Lf<(ADkt|l3J#A735S9t&h&`bENY4@2tjk|WPybjc! ze{%NinsRSXjxjZ%hXK6$h3>^wAwjq6anEURKE+}gpIF)YnKlZdN0iLmY(ox7rmem& zYj`_Do4&+>TVnP?@E(+r9eQ_)Kp^kfT>*{pMj!r%4rZ3~0+}5&MnwS^# z9~;b4Z-1Gx?%cOll=9%wNYMK55bt6{^Un_y}(LDJJEf$#cs@u>#$5Ty?LWg=yv|f z=xeN8`&g5a>|moq);B3P_dber=dyJO3_FDG)~l+%S8>no;p1V-ga1AL_HUVie<40# z{vyj?FwZ~n6{SqUlq)M&FGk5fh-Rin_O1^Aj0S6B!Fe~xTof`gP zz&$p4gfnyiz(*#X9^ki6e<#TO6J_#GYNd#j=!3oob|vU(BZh}VX7FiM2MH-rIU`5r zKaFG-)c|iB0j9HoKUDE@0dou=wh#dTA9;C?7|dU29+i^S|<9}_o6M_V(y2ZGw)_Ir3#^EW)_Kfzc3 zKjLLRjwKj&F$3?{0ek}YejmL@u<2iX{*M_a3?`h3(Sw<>77z4Lm%mWOKgavuBp>K$ zGm*a~-y_=eH#;60{gHg2M+oxw2SMfc}UB7!>_eISYUd$i~D51Y5z%#Ki{IFK6WHZ1u2>3=@!(^>G&- z@CAj5m7Vo5HCY}k{EyqafQ9_?_Ac*r9CX>y`&KjtJ-A|hBBy`d9!oO6R3r^#68^Xj zDJ(5yg<%ExYvF{%$CvxVk{ktYp!`M^KWj!+fJsH_R|>H-`v86&skKBl|EsV&S7n9F z%(AiD>re0EF=@qkwemwbud5a zz068DG*Tuw=0ZWtd){l>DGU$eFrr>jBlcoZwVi3#9C&FBf$N5X*tOG{6DLno(`Wpg z!8HoEHD@Z(;gCtk6#6^K<$)p7s*SU&BLiO_CPw0c&V;yDK3ki% zL*|IRANM_%T|1u+e^`>k@ja#9jUJ2=Iebw;G|cqG`s?@Hwvl4!D2PEjy#QPy6Lea& z8$C_>!LS5&8|>!yXPWy#dhj3ErLh9~T&oNcm|}17swhu0Txp3y>Jpf8spipsgbW0! z^+bx)eJHJXTOznsdAGUkwJ{ygn#pO-pDkDIQS&8$M0!UaRMz3$irJf_yX7wXDUUR1 zU@`+AMj#Sh+7TX1Z?yHOwsg^bqdyzbb)5w#@+=eN6r0VYxudDQhhG}`Mv#hI8v8im z84rK3YaLXhomf}p$8hRY?DWG9S}aS2k6B`;J}#a|-w~>R5#4!ne|gb-=c?}Q=Y=qb z)IYL~f|#m6>bie$`FY0jDsBGx2~|RspyFL-Kr{6ai)mVCkR!UKUV^(tgn;H-7e+j| zzMgzSmSoyR80A;Ldac%WSSXFE=u3JRn{qliNXq69XwvNH>Z`Z--ovJz$*1puf9^yU zH-0)^HEwXPQQ>nty)3p1rRx)vj=@UEk04rmk)> z22&sy@%WeS6%K8&CmAtb;e??XMcs6N#2)OMau=DlB+bB zT!HCXAHmxsIjBlhJnIq6_G1NeTkKCrC@ww0(k*6wiWqB3OUH)a9E)oUN!ueDO z$8F@h`gpII{WZm*;>S>U52{U_wKa8SzA|2oBo6la$aQ@W2!Ui7sf-Au*Wmm5AC4t6 z>C<|?r7G~TKNA#7Ib!M|CC=&8p09Uo%zk$&Va{{2&{+67F&KF*tk`8%=|)QPQ+WY5 zdtwjCYKgMJZEy8RQ}BFE1I&6!!DwgLxtJQ5P%GF-h9zp3Av#~zSXT|>AyB~*u7Pj& z1TLr^y-4qPrx0VnD3sQH!{3*vyfs;sUs6b?G5n=PYV+-TcilamjkCP)>G#>+NySNA zM&GGiN;bofY4wHMi1e}6^Jda+a^XaeF8=V5yfk;W_*PTi?)j@GWAOf3>hHmKkOmW~c8WnSEuY9BAf{IkAdIUyr?uQWrL;bjtj`qmI64Jzz88PTCucWm1F4 zo!(UA`cD46mmpzcuf%d`?h8l7r^tEmCQhYXtK}mq{GoMpOkm_o>3kz|#Kaqyn5NCB)a1y^_=Q_l%CG$w zJDMqrn)|+eO;%3a8JVc+JBZ;2s{r$od=`Jq>R58U<|o+Mc*T$E9rhloBHny7_W$tq6;M_0OSpifAT6axx5TEqyHmPLx}^~Tr5ou|x}~MNySt>j zk>+jjdX#g{z3<+4@T~>QSZw(3VSe-bX6Bo3sJ@~qj7wLb?_+^@OZ9LFNYUBDxim>} zCW%L=kiU%RrzUObg3m3y*mT$$N66My`)6QfcWEb1l?BqRv1=^``9U&aH z;mYD-Gh-tLaRr_a7*dq(x-E|$x|)`~LJQug9$2_o^L9=QBe+uPUynizVXiMIVY`UL z+R?>H7BsBU5VU#>a31%T3%>5Gb^nxlvycJ8-TaJqPQbNcMv4I(H)eshZCkPwxe$^8 z{-y4u&NU$2uBDqEex;tC$TIE;;;6WdbJiD(K_&Z|&V{45uEHrc1>}S59GTtgNt3KX z2Oxv+hJKI>!bDl`p2Vhvmp4DYYF}xERYB2PnSUyaXYj1BF^IyS%N7N<=!kGBD^KCW zAb1Rmo$-Rq$h4)xqlY&3cG=?Ur_)j_U2OT;$u!;yw86%fSo!04XrGGNOUtknvy-*F zGtlr0zr3Sh>`K@|>QiN&Mn9k)(98tVcYyO|e;z%%g(G*c%xwnr1DO7)WzY0WF83YD z0Y_(ybb+%^azNcW;2#olKN0r-WgHDiCAjS$|C@QVUuK`a=XQ6X>#w=pe*-xG`k4P2 zcme=4w0|H^N?I1$U!W&5FbVuQqz3HQ|1qQnpapU*zS-|TLQi_e+pqc8WEu+{uw&0c ziwgh%B@uz&`p@X|Hov^{-hWLWZ{PbrZsPx?bx#Mt1%7<{^?YmO)6oKF`M&+@w>0wU zzURvK)5yQ=$p09ty#3BUeEUBDW=8ry0p=bob&DrV2Q%(BO`M%AF<-v!puGW|I^#y@ zPhP=o=G2Iet8+Oki&3veB9kGyH`L)+_PW4soWGPe zRCefILF|i15633b%@RJ9Rh(Ko;KrG_RI{+3(m31Ons#p`3AMfG)o3h^OK2GCc7tC` zn$L@6pgAcXqIr!Vn7^J3e~Y*9PQ+XXN$Q z)^6@*4(O6an5*r29ZDF!UyJnyvKC&~n!J$NtVQp{=h^FJ94+N74@8Xw;c~Ti*jrrS zIoz0Wq$`M?pO|rS{i+}J7#^;#S)+SVzrZ-o<95jiqPhx>kkAa`Yww8|YT06wLeU?ml4N+dD9mKmL6?E*1(bvSz zQ8&tHtnFWm*sQ3uwHUs2Cbs8anfC$8_fwDhpzpfj7(MVRiRjlVs5pHdBSPoGh;Meo1x6DT|fefsMI@o4umY!*c%-J37_;pt*SL#|@*y zo_S^q_KSN#jmF;a$@E_JVfA@dsv>VAHIlPoltpN^%uBX!tn>;nO65K>*(C~1%JdBe z6}}AfO7tNHy!C&3Izz?ZQ&AXYG2mdM~ab z6UN5G8zT%6yB$Ngwo7$bKRUz~W7c=?a|L)63VfVXhmAb1-S+xU*vBb+|2USJsh z8Fu(bxj`hMA}OK8M-N3f{Rzvl&w^qifht!Dfh@^#Ov z_vQQ;>mXhjkH!uo^csXkQ7V~>%WzrA7di;j9fLqQvK6TL){?wqI}}!SBsDhX>?hdJ z@lN2JCjqv0pM@>H3R5h-pkXBgY&@|LSWVa3A|8Ah-_&Uc*6OBN`7!z9n|AYL`AC?> z&1C;6+?!1rH&Mg)r4v^aPV1}z0}!>w+Asz>>M$3skIPUhskL(+XEHXzy>xg?d&vd1 zy<|JTmJZ94g#f>%oBQ%0YdFQEA>1I-r(*>CbXZwD#(Siht5N)fr+$wCs)kc^zZ@vu zM(+Fanzr8(Wk~`{$-8vI0-B_o9bnp}^0h^FT{(R6bL_ax)(Egg@c;}eO{$?TMa|0Y zQd9>LW3Mhm)}AC;9OLsdNFehS%|JZbiUbkT%F+!?`x)e5ynBFEx`gLZX9LCNmjfE^ z`4?X(u#r@z8*SLju=6KFK%;?rXXS4E7~RZG`|WfXFEKDsCI$)!KD91`LK;5TOzZnX zK|r8=&fZ`-UoX%aK4C>ZFfFJRp@gg3L_1#?yU6qCp@ddj`m!I4_9tU;$erayjr3rT zM-S_#7}m-bc_Lv1>8Lyqi8UJVGoS!93*_Fv7N61rlXdp-Zx>0YNCQ=L~BatGK=6SpZLj5Y7H?m z;k@u16E&lC?)0;28B-H}PwD+xC*+e54@f}&u&nMR*{5bL$?)Ad&t&r_JJl8Dxr4!P znk^49ooj|l!$BS2>cbZtn2YwgUwu7+$@K*|TRLskU_Txa<^Q5C#51$A##U;PNjc0M z?k9O%4IeS8(QIpPV9%7yyq0*40_7U6L--aj)3)CvW11UI5O&ybNZugrANrJ{X$~^l zd9<}sVg+qdwKSYZTSReD>v=b}S*{a-hFDxvoW6Hiwlu`5JVlrOaejW|3s5Lm95~Fh zuucwgkX_#RT5&_n0IpRUbD2s>vqsPumNeYaR@yyIZT}28a+%FRv;F$KeL$pnDNhjv zpS(JSQxyeLp}EIl#&F@3!|PfGjHRF#X4PD?(QG)yUPQ1->;aD+@)A=iS)M;L~UdR#D zC+MPUAmRyP&N-6e$S!w%*HpuavOsHd)!8yBEQxu6ARP-VZv$MAL_C(Etg|Fw#7P@p zns)y?|DSu!In7@*3OT)olVA-XTrLv zFrfmzL@OcUug&^}I5V6z84O)EAnV{0+q*!#-z;%q^X)oGmw}dFk*UgSVY`%G>@(;= z-6@ac@(f|9<*3nlu9ogXr&t**{;o--Pf$P;z`p1dJN2Y45*Lm=lSN@58Gl% z>b)y$DCT*)Yst^xQVCDJ=%;W|H!b5_KpMs(RVyf?-h6Pe@CJSMERqH$kJWRn+8B4S ztcPemwoWx4U66r#Hx{RSVdHCPMjD#ylzX$D=)&PLIB6LEFpB@14kB`v(EX2c5S5cx zRBkPdAbIK%FE;^0Uy>ETl1F#W!6F_#G|J%?7f++YD%^dxt{$OiNe7yhPiaVb-ttc@-t48YsF-`W}fxya1G{3po#UcSqGiW{yPwx4T{6oRyhQ1ODfOjtHK1I@CZub*$8Ie1h; znnd7rU2&LcR}efyKq;l)Q+V$sR>>txFUGHS%gnJ(DRrk}Nx(Yc3XVLC_tFF96$}nv zhoIEPFRYWf8ykzt>R0(W-6|T+%Ukc8Sx#b_nZ?#-Y7+)f;?eDnuVsZJMg&x*N8X1t z36TQj*&yA6Y(z^=6`0+J><&K!_Lyy69FD(RIWCmwv7xAS^jL-j78xi?=Zy9%@~P1H zA}LLwpOZ;y7a$S1K~;bPJKS~D+^#Y1E|lPE1yXAxS^ON%b&v6%u)REf0RzxCR3*~+ z;#DLm!`nUHhDk&Jypw`Fg*MJs;jAOP+1#)fSO$uJ*ec{EDq{ zF_N@Mxp9*n>3z71!xtqMW1Bsp-B5f=%J1~596jCCJL&jqVBy{o47iWZUyWTYIrUtk|ndwaNFuQ-t~JRgtpURmN5^!&6VF21^9Om zOREOAKZ6@>!*eF(DN2n%WqELpQ#e0g^L{h`>)v>fR~4UbpY!JjNMZfS$Grpw@OV;i zy6v1X2pC!vK?%Db*ojq!z>SZ%Q=bqr!%gsAJ?NiDC;IzS@kh7qhhqMJ-Ev_DYQlW4 zH2gRgf2;!d)A?YeVW48fr3W@)ZuRC2)4NesW6C}Rv1yb=5>vR<-UAx(uJ78FN;Orm&CnnQF#Y+?hGs2s-B;Ia>2=N^C**L`Y3hLPdQV4sL zdA8xYLWQ)#401Tln0DPi&gXEDpyGi&-TlBUG+@l5>=_W`Od6L7-Un{n(FthuKxvm5 zs1efN-sU8KyZ{jqjM)0@?bKF^v3il8(i6hAY$}K)X7f;KGz9evn#qOzlf8ky9CRfFOI4DkO;i(d#Foa$}qlml2FJ?!G@n0 z6KBXYP(fB@bK`-agL$LA<8^HK8^EPIe8cq3JZL`o5;`OJ* zuaTZ`RCPIGTvhX_%H>rs%vmFE%^fV2#yZ2O@k@!OmYvzK=rN0HVM{;s&b7@+w;$rq^P>@6x1;7E;Oog!C@wCqnMjB|R znWZj_9b7InLi3U)V5C4xFtNP-;z#e+h}bIQEsfv2YyuUgOE;b>*v^_Hqq`t6C=D$z zigUnebjqjvl@{B<_w+4ue7kG&yJm?;4<~U}uGc3luwl2$s5YTD?G_thUVMDs1D(*a z(j@ z5>>jh_^_fT|Zls3z}dDL^~rCpO5#Pl_0O!BA75 zW~o}wuLNA_^MFH7tAH#uy4%5=O~Skoebsp(U)ChxOub1K%gIXd*qk~%X$D1$&XAm| z+9kUn7lN6-o6pWlXcVsi(S=m0xZSIjVp3yh2RH`|wEYQLZYSB;2!qmDsFyf*gfAdf z;lk6<;H7eps^%K_vLfcdT$v#=S3by2rq)8Hg>7F=nE#34E5#LD#v)pfDhi<;wo6AB zhnFA6PN)6Xp14fRbdh?h&!XOR z_Fvb(>Hfvo_`lb`zq5&ctpVS@_AgKSw}gv7Ki=Qgy(s~-|Fb&VuVaM(7N7*%FNN>_ zajcL5xXS2Ooee<8@;B;iw;Pr2yxae=;{9`2?FR(-YsH%hm+m{~?6%?!1P!)yy=)3Z(sHkowTSaTRde#c0*6T>2DtrN3@Dn#Nk1#7ka8! zIBSQzz0%Opq=eNW7#~wexje2}N0_7hyhub+?BWwlf6S*2okFEHMS(I#DbCrNstJu5 z22IyeM{E1?8mFo%a}5hBgf>masMpx`af(w@_7~eTRZZ8M1#uaDNeoideSM774s=C@ zCR7%^eGWshuN{ZV#SyaCoqHmTsa~^jnZ&7HoSs~69d9h3^LCDKjiG0&b1?O39}lxH zZ)om(4PK$tWLU8;clt6Jyppv&6yRjx=0C!ASf#F>2Nat!Q@=>qyy>ms_nTh#&xlNXu!4Y#6+9_oNpz;IASMeEiRI5 z&EfFuY~t&xVGk2^5X9_J%jC*W2F7jp$OqA7hV-K7KrnMSa3GV>8X5NsM(X; zP5h6VpYxg;1e48-KJ}Xt>TY+k4XA0Ysorct8NRac z{osD?sqMP%W}(K$enToT97onFjQBdbVdeISMu@-6uUCIZ8DavPm*8N9b%Yz&@AG0M+~WnA>EydOD_>Z^60Es3kM z_*&j$TwZs2vR;|HQbVg(6`iMjs0WPTlijU&Q3qYz&qv^!3y@^0~#LCdy6E z88eHa?fkqJ&PM%qe6mQ%CYolPBX>pp09YWK#fMk);$J%)*NwoL)i9t4X8YP=Br7$q z^sh6%F3w-6GC8ecS8c-r+^H;tB9YpO>1kf_Ph(+y#^3`|p1nJ@R?S3-kP+DQorppi zi{;WOEJ5I{#V~I8PoN{Cw@^D1Buv_$cqr1~Mdy=^XPW9UpiH9>7olX3d+5+fjPX0z zP>Qucc0mP$KQaF7j3@ z&dWE0Y)vpvfpL?~a_DN+9?T|CM$q96sCJHQ{ zI#cXCS$1J>=AN!gDCRpd2vLeOzlx@ymr9l(olVE{AcQ2nGu4{Wf)n}NQRaI5S!f*Z z5rP}k8_)X#@_lW5(73U!OVVAxNW$@C3uYPta4`_aYeK_qHj4~1*Lt2jiN|2b@=8vH`3fN#+P}M{#(kRa!Z2A_QL^~OhP1~G zU4)y)d+s{lah(A4_kn?tj~;&UZZsBiY^k@!k!qNMR+^)cKnk9%?mz7GEa~SWK316G zT-MCcrBi@4vIb4eEm@2FT!!g5tQca}uN-MrVysNEH~sLYtAH+s_oA9hLAVVE{xci0MPC{u>< z2H+|wP?-mxK6-czmq4G6rAq5}?z5S_;)?IY?MjobX2T_;0x^=uaw$Q}W84JQh_@|u z=ER|m|H1PdAk00w~X#m2$xuTss<%mp{=cu6^Rfv=<+EiFM z2^|Rs-_S}0`-$w0s&84n??#bT391(n3Tq^&x^ftKpDty-LB5>bGN?TTY72FWqtUMUp|-5Odx@nfS$5-#quFxPqx$8 zp+}ZVZtWLFw226L)*<$j9xW*s~B8LKlJ936e7+zEsPtcC7mCc3XP^ik$=Z+M!c@zL9_l9Bu`@W98) zP|2245$TIlA3X%ElWExclnQSUC%Nsn>S;juYC4WZZg`ChI{nS#W+ciY(yx~rs+bD{ z&a_w@JtZ%YD>phvtkV@xg)?1e!tG?*Vk5u?-bWcMel%oHe6E@!_C-)uh)*vv)!3(= zCWCjNi7|r4@1+nUp^E~*Ps2y%sK2<-iC3YK)Tf?Y8DF*@TF`$reOZD%%IL#cTVnN9 zxSoYgO5)=CB*p7_(i7{vBIiSD} zknsYvInZk+Cqk<1^*=Z?tZoFAvB=MR*(!nusaO)o$9j-t1F9f5>e?0&Z%Y+7(^nXe z;d06u;_LB%zCgx?G!dyLNaxYR$B&;!)FwbCm#0h`XN-q&^AISJwGP=j;_tsqB^mNG zY$F$dY`8fI_8@qrlomh(1A@+vWJb>ry&8&PVIBJ13VncTC7avMY$JkFA_|O8(k;zd zsu9hMz)1mTit@NHmTp7}wT?ih{<-5`rMu)y#L(SjAfYNxdyn#yEaEQ5x+gvZ2N^wB zpEw80I~VC2o>Xof#Pvks*ES2op=#@=eB+D3!sN>-VZDhK{H_!X0m!FNWD%EX5ivg2 z60OA7)`)oF*a|D)oLSdKird4T=g5Hc%XzAuYCah&4ZAB4-zL15Ga5@6_}3^*V5FE> z$Uz!s(QS4o)d1K`!WWrRILD%#Rhyw`ec^P8gKq>>u-lL!u*6A^Gvwl*lY5`L#O9=@ z7I|NjI~#M?Q1GI4I~6ZOP!vpu=FY(>R1lY4>VS`&g*e7yBHKSk+eH#rA8SU$zY-~6 z%x)JQP!x$-C?Zq8?0_{n9*)=J^u(Fo@9m z7ZsTY-8pKL!J-?mDRlx~BvF$>Te_Ha($9+C@5^DeR3Ro5+dXF&>Zqj24N0PRjeyEs zVeTk$$A)`3&(}TUN#*)Qxq;EVO*m@aT*MYfl~gMwhP)**ZNnMfej?HlUa&a#W;tL> z;*GZ>j3w7u8t;_`xvEZ(o@R^LmF)Crr#q`gF5hyT({tkos>rt0wc>B2TVH@@)sPcU56;=Z>{SdjCwP4e2S?4Lq4SS8dEF4fm&y+q`g21k(P8njw_{QB zO5xmn&HsF5OtvA05M!@LmtOS}#fGGmV*rOuJd6I7swgUcdUEge7Mq{u9=w^ zCq0LJhps`B9lLlV%tc6~R4M@U0j7Oxx2pK5XioY@Dh|;Pvw0ksHgf=Ds09TdPl(j| z$D8{6`A2~{heuQ*PLS zCOYYUZaiJoqsQD~J_cvSd(PJ{ZH(`<=MixYTkwR7$Pewx2rsbg%tjf_<}s%F%PDJ6wwJK1Bc=pmw6COPrfsFCXC#|XoI|h}|D9N?E@zGFXc%PQ~-NV1`BmP$h z?@xURpwKuK3-HV78K{_nis-*K?wD@ZFn{Yy(6i9pu801=^d)Fmn7$PZerEo8iV_x6 z!f-XPd#|HYpB_Z%hg2IwBi|VoG?jp73^HaQ*5i~ljY1f z#ZNDOjfdYtz>hW^f4hNd@)Cg$SpP?PPVfM0 zr{!WtyL6nfP=oPMdX8af^S$v(p$2^|N?jSpG_|ddR_shP9|=r74iYU8E!_uC?Ew=`f>cND@eFs*FnKVgqA6nt`&fF$;2_CRD?vT#bs z-3}#KyJu~$eLQ&nB4Q8C(oM50rxmoO;z_cPSRY9o!)oE-1;!WQ%`k%tdiwCK-p>ZQ zc<;6QILn^6ABbUno;lKX9G$3XwAOpGVJnS6Er?8q;ZfvKA)vw$3z6Utb~Q`ctcJ!b zix2SU-^&-)dQvc3fM;vi{qQ&KdclXrg)$N z$sWilO-d>hK1sxK6M+yG`VB3(8}Y6%1X`Oi(loVi4dd(X+1zGhXqzk07XNfZ&}Sn*W(teh`ik$dmWBQYg)y*g zovLaSQ^g|2{wnH)G$CKG++xSs&NH?)#v+xlD>*d3o0htZYll5JDDQTNDgbr>^LU?| z2xm~2wL+tcQisZ0!wn}%VfY}e4{C&OU*giRRtifihk%PAL_vgd$PD0zhj z%LwuDz(0CO^Km#-sh>0IEh#rt3=AHGG;gS1FJ?KA`2V5_Ob=;3sM$R_7=Od(Z8MAj zrrQ}Z;fE|jV2e38bO}N~bs0rtVrF^GA4vx^)OrmLv7NM#UHb&JaQ<1}mHBl)l^(dt zb(jWs#|)aR41Nd1DC42p+>MK=_Z#b~Zk7PKQ%j6}b1lKaBJZV(<|p0ppmefs!2b2= zRjJmahZ|DJf<|jL3-NAk$_{M#gi7;%u1^b{bvFsC2C_!5yj8_FAm3gfCqbfD5}={dzw6#I&@<3e0jstE7G_%D-t{|ik_K=~ zVEz^-Y3LZ~ZijaNbD(6RW4;?F1LY+wuz28V3QBIYgT&Ir+vpMtOeRx}gJGD4AK(wY zBY$IyXXNIVcFTrkGK+ znH}!OqUz_Ez0i#o#&i)ri??kSfzzN1dN$Q6td>$+(vx~|L{n)wQyoBMTCNmao3meD zR)J-~Yp%71DvK= zHh!jqs0f+G&6AMxL6{(~x+N+L-shb;**46mT}zD#zy!OVU9nrMD<>GzD)J-g6Jz;Q zdx*`6#p@R=St)8MM@^_`bYg2{SEQ?C#-7xg<_%3aQB_3w+gm&B+J3=Xoj^|aH=7^) z+I4jTX%^78(U*+Pf1QSPz~lc6``e0(-1gJVJh@T*1oii;W>Z_N%`vt>RUA2ray77z z)in^+$;!1HO7Hdtn&Kl`X0}2>vG~RE7--?Y*i@J#1$d93!cU=(zw`vb0ItG%N^!Gc zN8A!c(%+^fr5?=twHo6L-pfOLXV}zNa%=NRP?cZJ7-pJfC-07S0|SB|yljcRpx-R? z`<%Dow!Hk$cmfLjV8l}!kV`?CCSaKmNUUCYy2s_8>sZTTgFkvWPdb!HEl|dQ^?6za zzB&ksXXVku>WCGl`!sikwuw zI24A(WmG|SA^PwYP4dmdy$kUG?)7{0uxelWMclJW(@&2cUP`KlJan~;M*!v4c_r9TH`57&a$oG~-bvQR*B=|Z&4$0p&$o}cr z!4I9lU-1qLaPk!hpnxiZKUy^ZTf>FN+}y&}MirO-wxjax$m{DFY2U8=0iJbS1{MZj zB*0~+2YhFA@Bv3NfJ5{)K#s@lPraX+gIhrLW9H!YJO2QL|Goo5PtU|~H@<8?HL-YF zzF!4$@#zv;wmEB)bQ`LTrgu<;);LK|Su_^yY8Tr&avHBkbs`xDpCa}ID&LOYx+U(afO{hHk-h4aE228q40x}w4*D!h?v5;526j@l5>4X9gLyZc z2T5O;qpHnG*%>vHrZQFqx2b$SCZDG0xaub&NU&XB$Hr!Ql0gO|*72^sx)gA9Gd#kl zG*R(1rt3*t_QgP3CF@YE-iatL>j+7O{)h#Nzq*hWmdrO}iEu;%(fRp>xAKc@)C(c( z&V#{rH@j1Dv8y5PIgaeurd`FjLu0E~u6s*ow3I6eUfNTbJpqDxi$0q@4dp^&eJx9iN7JILx?Ri#xt#%at#MoGXcYc8hLp(ZlUY8e-__OccRh4w=m884$9wVI(E)d#C?R=UBP&`LhdktPrJ*9 z$aLIuaI^c%7L9{0B|=F7%!nHuaI4_CV$-g|uy*`*H~u^tU_gxQbyh@g zeN7oQRFX1H?PuKL#AtZ*2xpMymeX^}Gi*)Gi59kDs&2ZERsvq6`enJJ02%vH3^Qnv z*MOP_N2*oQsG_DqMK?Oo{(E-T&c@x(q*l9CkQ2)YF@-+8sS{}OAKq*5p>$y3;|g*x zg|^{&%CKm9ylC#Ju~6skO6t&A+X@um>9&?(S~zjgPEP+YX<)6=@Ww$8dNclowt5Q^ zYK_E^>Fc7#Jk8|A{RU=#U6f{?H)?m-Rn^Jyk+OVupv&tUjMG+B5ucnMrz3<595h6Z54;K9yf{2QkFlZ%S z731c@hfPwr-?}O?Zs1}FUo4^cH3la4X%c!m47z9G7#C2a(WK3~!oghR0jcPNp*R>+ zWsvjbOi^J`)0ujMgGIpG#-HdLA~J+Xjt1~u0&WGBMc;@Car#W zNTi90jr{Ha2Fsp8tGImwoN~MZS#J@PP?mVVE;?1w*MQRbOUIOS`9P}|2%KPjEBqdZ zlHsr;nlYpr7y~OQk|;L#d0a)-lVg*BSyqT}l{G680i$7pgmFYiRP&U!dDQ9H$iU<4 zp)_p4o^ai{Ks(&y4Wc!aGh zr6UrDo&|3mvQv9)&ReLne&GWff)Ru)`OQ)gGKWZ$7gBg0dZQ|jW4KHt#7fXSv}oSW zJ{2i_OZs`0^LajqzBD4r&Ey)`e8)s4S$j0i0(}lzF2u!rU%0J~YTDuz;dQ8;saPHX zx}BmzA?8QmBrApfSO2f+SCLB0s|;FOpgWwM+}2}=h<+Dx2IvFmRJ=T? zvxQd8tIeP*{NSfczClL74X_|uPWYTQz8*^S+*RBf9Q4oDlKWU@hz>>oc|)_fA|H13 z@pE}ksR_M)TdUP1>LOsER4L*n*fvFB&6 zVm4J~L7^sf(+|dKCse3pC(>w&dGyfb<>fAr;-^O|fv2u2McIzpY?Oz#6yXPd$DRB5y%z%WC7-kRGFP8u%OQ(Aw91jf)8nydW&A6iceRzISR(!K7 zn;QJjtxzS{^C)rLoD+4*tdX^mMMRxRw2xtxF? zu6D|xyblYZ{TD=s7Sr)izSP|p@G|4r%uA?`jnGMS4#_u8m&l7hr$}=yFe{eLB$P5^ z6A`qKKvVI@q5+bIsa(S5+vs(eI0tH{PL~=Y57!GFTjAD#jq%y15N5JW02>6hf%!fc z5ikxcYKSo0j}g@eOwj?YvLcqTzOJ5j&;XIQQyB3j(;_(nhG9}7LCu4MXlM;~=7R5G zw2VTirnDPrWz=HJov2zu%bdc?AeWOb%eE(_I-n_Zpk(7nSCf+)HRTe;(~Ll}9=(#6uZJCm5_zvtz z$S5T%XY5z<11%|nr0`ZP>c}Ch3YVkfL1bU2Nk=)VC9k@se&2T?heEK0STz1OHH2r* zHJVNlUEy4qZ^5gzw6ycY#N^m<2m*@LEESsa0H0{9EkBA%7%9O7@} zOEkF2F@`MAQ?Dr#Lvr-Fg-sbphA33-&QxN}~#8Xgrj+OyF{YdjMm9GjyN zJ=3_VEO{gQPlCGBYPO*<3zE*c9Z>A^i7M>wCL<-c(IO%S93YJbG8JW+crN7$LyR%hjh`fs= zjBR}ASv?Wk57t&P@kzd?VrXQD`^08L-szOTUQ>A~;Bc@QkGJ&rlN^SZ2*k2?aIc8{ zVC3Wwmk37lI~ADM5{|U*(R|;c9!4bjTCk79t-s_X=Bu=b90E|I&rORA+xuIPzRO~7 zrtqMfA$XlZnz34nF<9+8QNzIEZeE5MC@FQ#wY0x4)fUUgUCfSNw(?An>eH()CTe}x z7##r&CaWPNq&}DCczwADSYGUJh6m8l511*euu4Bas1+{9Wd;uDJUem?ouprSGbi7k zk~1E5;nFK6X@sdt52WENuCCh?Ga|j6V;Fdh3dtzz=uyt6MYl;X;D83Gz_l=Z5Qlv! zUwIslWS0V?XzZ3nOZ*`2Lly*V8s1lZ-lEB;(9u)@h%r~}5Z`3}OhrB7%g_>}x~gEM zbhgTJRF{Km_(&rrI5@RQhsznzId|5jU-nlOKvgx(;!Qc;gk+94D^&76WpRY7izX!GN(xzfz8|hfaw#3 z$s7D0@d*Zvubnt-`cE9DHoOv{R594l1nGv!o9(KSpDySGaWNW4;O>3cT7r0O;sm+) zm@0ZGwR)}Rtwz@3g9L3ROx6}N#^@tTh#5Q??ig%fxyyi0@l;<=?sA5A%tew~?yD6E z185PRs4q@I8s~l#<&Xvok-3IJ*~*+?jP_MPASqfb_93uhBJNpRlB?KS;uQ?$AJM33 zG7%H&2)PKwSZwmP+(+F}2PuyVdrmne6Fyw@G!`MJ=6E?Rg?_vJiSp}OZBuf0v!k#6 zoEsGnCWu1f_f@iKrG1Hq-n>8r->^wO7Yrhw5VI>q)F`-geQu_kOUbhaOJIQGnEQMa zS)5m_jvTn{%?@K5R%fxb5Af1Fz!=tS?gfo6;dxumhyn6OUWdYj=vCU|H03CT@H}5$ z7^lI=j#vd*am>1`ht!3( z?<*rR7462ruLe1phaNj1p!MMo_8Ay8UyhSDwze;JSa;8U!6s_daP_c|V}dBmA1WjA z)f6x9-oK7H%#1Xj#As(r6xxnp2^PH&EMar`XaHYyViWGS!YM7uwRfQ3nH|hj- zJ{VB5pagU3#6V(I^>V0(LBbYE=1kqiPhna zjPfaL!^vDXi7+W*vhZXAu&5!UK0GJ4{qt*U$Uw#nWgx`Jp- zOCS?*Q?wA(irPA6I?vh@UjM-=RMf-ACvM67Od-X|sWw`e^uzJl__HbMq8L(~`n2sOh3&e2#M1oH@hHmnxln@^Y=#o_A!Ca*S$D@iDq3N7 zWFnA?K5jqS+Dbrts63G)q@a1&QByb6k|H-2gJH5WDFfZBQZR);sO?nTJSY%Q-<_5s zJB2|jeV~Ju&L!QgExH|9o2KXCQpEl;ZXdq4W3xEQfAHkky1J(5xPZ0>u(uP`6B%f) z>q;YeTC?mhm;SUhl40F{o4T8tj*=S2g?!w*51f3A25EU4X9?0~hjpM-N<`kzXJ-_;O*r6u3KB^qPHE7KMI+D>1_Xxr28LK`=7O4YQZ1%-oMcAfwX_%$M2Gu zxgFkAtMQCw>szATXA}rs_?)Osw2iy^*rT?dmf*+3aSCi1= z0%;Jx%_QHaMDNEWx6{!-juOK+&%P71{vVy>KP+2fVZ;S~{Li-e(LiDOcG_kC`vwZj z_i%qd#sb_?ZDRQ5n)hR^e;;mGa9O^&>F-grV)-6w@5eawzlIxzzl=fuKYJ2zM;(CX zHVOdG*>70SMRT7mHo)EU^zEeHuZR44N&U3Ue>iUd8XzGH`1!kh2tae6;RtZoi@rVf z|9AWS4j;SMD0JJ9{Uc`oMbi5J@udCb76Z^Q0X^q7-u|YOcY6=q6WRgXS&jD%HQtlw z{Al=73;sNBzsVl=8IA#Wy8R6I2a@kt;a}`1AdLSujS3W_1ZEDu4;}+(ZtueT@|Zhm z#4RWFK4Q&Z&k=AT#2-r`e#Z^=uYIrgbBzP;qzyo!`TIIYcl_oz#MpnWSG^xA(B8=u zfK%VU#R`8uJ-|@&eOu`7i7($beB9INp}m8J8Sf7Z-|>?_TL^d~ec!n9n=EvnHxlig ziFd|-iim&SL;p7K1OWM>-#&jE*847Sd|w`P2P@xddEH0+{fUr&kB|IoWzIdtnLBuw z@&54c4{!P3Z15w?27E8{{r71$;Cl`DzC7a&!e#uY2=|9AekF9?i8BAgZS>PZw<*>C zVxjxYlW6atJI4D*yFkDBQ|tvUlL7qBHQBWHnIqBOK{1T~6#f46mS277hhP1Tt$^(Q z@3Qg#+xh!1S;0X0_HQx%o=zLxU99s@3&lUI@~fqOwcjtbuK(fO{nwVc&kTX?F2?z% zSop^~|J5=-to2tP0_tl5zH8h69v`|_IeWT0ScmEU@bXWa{jk*U&%?j(5V)_?bqD1z z{r|zqK-n$8ciFDrC;vdlfAW(*-DW^(Ou(%?=I^Pj16Q=&XN10k zhnViKs{CtQ{&BwkCK3T}v)`yP2Kbkr+5I4Dx;u5i+m&?plU4j`s~;mmzv*<{>m7Cn zDKh<2EdBFz{d<1_a!&x?$EALceeQKA>ihWQk7_!QopAq^o;%%{-++1kMaj9R^K%C| zGyPNK{8xXuV~syWWg!0s@SV2vn>^<}?=AW}xcOG!;JzcxUt=+FfDrI~i10UA=sxc) z`aAfU>7U}~pT6`n7XKzI+-H78e+L^g-xoIi8{Ys{|87YwzX{XO-)Dd7`zos+ahLi2 zaPiNK;dgtWGu-FZbJr^OS2g~DYk$_zf6bz(1%Iw60QMXKw@u~WbCl6r$r#SZq`v0|-^}FNkZHwsM>~W|24_s+^Ke+!+ zWVz);0NWRU+ZM)eIw`kJqkFT;9rS-o#lD}D^3z}b|J~2GZIS!348t9?e@oQ;i6$wQ>3pWttblhLxX}Xv>Q~!EAMnb)_^J-P`!hdJG zW1?r9OS0FkZYIg4yz0`jrs~4d=IYYX{(M8<-s$A1qr+sj=Zf9da5sr_0h{h--(0UI zQJyKNQZbwDVtpNDRDCjui^KKcWUXhPjx6}v`ck|wMRCQRm6f6HV69;1Txh5>nAL{k zX^rJqi=KkAy7Vz28_FQgXp>jAZkOU+DG61tSJ${ck3JE4y}k1wY4>TL)H}`+ET^ok z(hs1VmNzMja5ZjlgO48eBuaZ6eO+-(x2)?z{75?yQ;5`RQHRy}G)yDl0N0GGcGMGn(i5sjSu8iXF{j^||S<7;}LGBAHRd zQ|m2mUAc5w^-3MsCn|o8gg%3wjJyJ;-;g#6-Gy9p9~5)n-jOyM9$%Or^|V9eGEb5S zy;y#fYYIPoAOR=;ypwsH$V}akp@2}dzqqjTwU#hKb$8NZ_Z4Y}K>_IukOotPU*c6e z>t0z#66?Qh2NMetRi?OZmqj*lG2-h!ME8(3GO!7hBr}dhxGp>9e=-O^%w2E)J(Q6x(t+lT=1qE7Fs8F_ zGZV*)yOtrBHWMr`@;bi?^|s++h5 z7_J@WarFu|)yR~RKgIiELW89q4cJb%LTOTbtZ@%JIwUAb!f9K|eG*483-(wisE4<# z-vOQ`32KjeVjV&mvxaw4N@541L!ANz5ykksO^=bs(D{0@d*om&Pw-=PPVy}|JYN!C zhGOO~a7s}A3?WELl}uu@`ALKOn)`@FcP89a;(Uo)KOlts{}_I=ECQqU1q--%t2@bqsJ1G>PtkiJBtKqF7AWe&pZFE)%N0cMj$Tj`{B6u9 zHYWr{>{N5X>i3JtP=VE?n097Zgiq*75l~Q!pKM|5^v2JFZF15qV;K~{QcQR+>Z+%T z+}BV$8v28W{9K`T3YMr~k{LzRUtSIA{Qipi3tVgZ{%A3(->UPKK+{NhO6o}Tz&!_y zy^idaF8m+)&|Z*GTfXKu8z-Fg&yBw}r@m>McBGat=>CR5nK1NVd0SYLY=V=P&Bg+F zU*HOkjh`tnD67Dh(5`-q2Ogp&tB#17>mg3`$agQ3eO=s@*t4A;;g!o=Uxp#-5-^{*lybg2^{-hPx4@Jm{06P7qZ zt#1{tA<@w4ubXpK(WTXu+@^BoB%8NZ3&mT9?kh64%T+i$CRXar3CiGLHc=WX4Sp_V zBo2_+_pG{mE_T-l#Lqzn{8B;hDjN`JKY|`WIlsV-EJg(Bt+5}gu^dAQx>gkFo?GaA zZs+64L5~eajq4eZYubd(tF}xLYLBWV8EeRS-sKqwnr=gh2>n@iba34Rt=Wz${&`?y z&W3%U!)$A)7G@{cCJ~^Ggsy?3X?inln^I1T5ml_$4pq~IMe>JO3~|&zjLvk1peNYj zQ@^pb zz)8WGA!_V5hxNHp`LbPDM*LGA1Zs)694h+v__DQlG00SN=^h)qher3YbboaBosweDux3tqU!ckl$VSPyn3 zn;3YWMa(*-XhVu2(LHPz!OaY*jyZVKv-6Vqt8=k*k7!J>7%%EaBuc7m6L?j_RG7b- zTW0mH5pH@sj;TligP|jBfW+&39wa7kxiM`J97@kubqyVNlpv#oXF;Nd3lK2_3L!D^ zSggZIDa`en4ZIpb8}kgGn=!!bWmRJ2g$2Ra+W+;UY7{iiKi=gLX@Z z#`j7PiwE!1+?xK;3dG7I0~=HmpHDsPE~jwAU~$4Z+%)Z*eB1n~1|HQ%)N3OG<8PTV z7(!}3z)@e?PX=fbe6<2q=Ph=vhn>YF*Lc*wCWx=dTD&qZZ;nu-*&&z&gaSyAlDJM1 z^PH6Kii|0_LR5HIcpn1HWRI&%TW&_W6ds##S2Qox%#RtiarQ}A%cR0}M5Y)d%dU79 zUP-Q=nR^I@s=`LGBGV&{32Xg4(hR!-p8fr=T+#a(hKmSM8YoUE70P}`Pi4;Bel{|X zV48n{izfsq^(LU2aMCLr%|jGUZ-NwZKs7%zmxIm%Lp2^4s`0>3B?g8n z@jpWqtO~Lpr-z$aDw#O?2gy}h((Ka=vAl3rFeUX`{)mqdrgCWx!b8%N|9XBuL<%V+ zKS>EXEaQC=p)5mTh&abU_xxjj*mipS@7t_^=Ei*v%Rd$~b(W0p>D@tbuLNFCKiXrBF(EEbL@|=SIwUKog2-rl7|B_k4<4CU*tN!C=2$*mzhZ z)Ob6Ed8gX68s^=$&mr(!W*ScHWolJ`T7GYNv;TbVs{MQ`s>~?% z%_8!Eelg58MB-ht0^eV1g?OGIHam^cwzL=izy+_hAYHQ`XT<*#Pb7^SPvkLAA{1Xw z>=zWlmHLQB{DPfD8d9HopD%D0PbdjSJ(fUkUc$b41E^!f=QF}Y)svB2Jl}_#A zKXtY?(BB|rm#RTRL1&c=d3#QOtzz_&K)I0{ z=0)Io7BpJgU@APe*>K%=1I6R7cCyA}ANJfuc+NKa(|WRREkMNDFr|}fRPcc{kHIX> zzukS+`TMBkobIfzu_oA3&ADns%K;rr{2MDKKXnl|=A`6QU`}x$(d-&hW{?!W6APfS ztIaIkeap;G#r@s%*oVMQ!oZqL*D!>t-SQ@+#w^@?(WG=I<*gTMZ{(TzPA$cB(1YVh zuP?6Yde4!69I|3)415BzqGrYVUCGs!^*)F3o82TEvi> zC+vkC7R;G|ry70nJUj_zeoK;QohmoVIS5Ro3lCNF?g$jQ)v_SyG{s>S7@<#ZIleZR z#keFJ3DsJYtibATplZ8F7yHU+{YASC3uS|~!(Q|*+@mH~86e6$6D5!0kzE~=0qX`+ zJ;~vm*86HPk3j-ym4I_SPwKY~rjwFmi5vs37G?K0(Hs1pWU*7?$u&jqs0Wn? z@#0M`@>Y=3HD`StR5e-5HI0v%y4DPj8bj!nx+QEZCno3bY4yX`L(C(Exc=r*GNG7x zr*(m&`pA>^;;`r=;}>ldAF=igZZ&#YY1%??Vz6PQG=FsU9)faN*{50`BKi#3SGf}q z0%`_|5%O^SJeRZZo`%z_(@FZeF7O5fQCQYPT8`<;4RL(V1y3F%I|fNBP2~u!DQYM= zN=w?Fnz0pjEA*?CHR{r}v^m4O=Ngx&%;&6uwibyxOw#thAek-->AIBO!I6j?JtpR} zzQ=id+;x^Ou`dl1>pL>Sztud~W0Phez#*9cB}+|C4+t`mO$L@R4h#s{9=#`NHK=#OEh}ftcC~>6pRtkVVh035-u&{`oX*uSG zUY(ud7(!0L%o+qNjqNcQTwtu!{i3i%F$#phzJj?-X2ssPz}*V#Abo!K=TfWZL0T=- zT=%!5wJIDmrd+)D@esn?%z*T$xt?{Shu9XSbv@?ibp<4^uW7ogderAk(Rx7goLG}^ z0hP0q1~#PC$vhejMr+Ksf)L!bc^hYvw~(KhbuRDpUw;9N$;b*OmZ~B=^WuN!OK>=l z+y>=}h$lE1qRE+bXi^Ts$#0tq8-7usY7Cn)mAB~6?O#ft7A+T#XE+s4*34$vS!NDk zRI$<75WFbneZu!r$3_g;9{rv6Nw~i8z~30CyV@^5|3MlvW{sPCyMD`4T+||{@6a76 zSTPUN$Xq%{-ab`E4|Xd`^YsC0Ql>|X4l3x|6+HPbQ}7@{hc!WsMXC&veRCa_qaTpO z+k|XK)axFR{HsT|S;8@NwJU)bq{^@X#eY-JN=HTolbDPPq*J*bFcC$sPKeu6+_8!5 z=r+)9^_AwfWwm8lXO-z$cI)1{^Cu!sK~fUAzy6B+3xN^eTS>R7x20nv6`2ChTGSkQ z0jo?m*9)v&<*}=D9x8siQpOaUYL3*ae7L;B1{LYdAj`@AKmj5DMFEP}y<=cU|I5!x zy#^ham5hnRXCr*3!6IIfrG-y}D1*Pi4N>oUcN z$a{YJH!eb9S|}W|=`n;03KL|KE9Uy|tk#T`f*T+?>;2xi!9oD0gvln1-AuzQ~SS^azpA z5{jyn^Fp`*s%iH6@6Yb-_`dLusp|-BC~PCwSL6fguya_Jyr{Ze38U7|!9h$;-!`kS zf2N9`9<;GVU!Poj3h%FdtqYSx~jrEs+_sI>WFR$i#F%ySLvL zF}xXP@T)g!Qw~qE)d19J!jF1}t!|Np9tJkDC{!%&uMe@w&u_(3IK=wV{h(YRs4#+sCFIj zmf%s7Ci-AoC6h0IwuX!adj|UBxuC)F_FZ2%3%!jADar08)YMC0)eVp&=seSy+lGdo z1?VAN2*u;DepYYGGQy}}paIWizZn@!0La;xnG!1#QqXMI>!N_taH4N!B9Gd0MIFaIeo z-%7E0SZbVKUcv5z-L&z)&ZK+1`Jl1ET@y5X1iroLf5Im3)P$^xh@~ zquCL|lFlAhMX~Usj5tUEAwZ*+Wtc4RFlfcfN9F`Y;1zoKYEo3@*CvHK-!rtV@Lfo4 ztHve}iR4^n0GN(hV8IsLBL&bsXkix#wBcR4*JezlOJNUwO({w(W;Fhk{uz;^8>OEk zM_FqXP_Ue^_E? zG_nP0j=3;DuX7RCQ21|oeteWC`d5@oQay$`nEoNy0lh~sXw%$Tz)vDJgBK&^j$|o3 ze`Q3B?RS~i`vT`+sB^6^-2PKjzEuQb(wb~i0|q&MK34E2D+*S{pp41aTiPG2@2^y> zUP6k4Ojat*>HL4bZT!~LCnm?syNfu%bJJgkl>6956@*Pbrqpm{`E{B}r!w)N8Z-QG z&f9RG{hd#Fzc}o7U%huTxqJ(|>zotnJ2`^hK|ysU`_F2>!;5tXK99PtwTW^s*STat zVw{6Oh0%E#3I?>sTOhLKc>WQN{5z*N!l> zk1x^%5j(Qd*XO7H=uqNYj!WnEw%8%YaMnbE5&H?+cdZ2aU()pa%O&z3apZq#V*cNZ znE#KdN7CNuJHVylZ13u1V&)7KTK>bw@(=t^eDnW<7zY~*CnJzQ%nFdrbN^GOVC3Rt z<*o}5%d@g_{kyXSBqA`fa2;r`E`buM}egCYdQV_uoV!f@*O48DH0F%Np2IG%-6B!@x=Y{ zfw%72_Kc~k6QUrBpJ+0n9b`lZ(8bu}K3us3gyR;IhKJ)GUuket)3yPc%jbOr3nz;E zoUQG%YeBUpExAawKH|_rEhF*4-PI~|LAkCr4{@YYYU(7Xd9mJX}gkdI$0H(I9_`` z!>024Erg7wI&etV5={obat25_qvJa{1*j12jR7`6cX_2>Sda{_h+GKc8zo+RANDsu z0x({mFyCt_<=|cUG_&sqN`_(uJCUmq`r(R4=8|FCV$p$!CX$zX0uCQ-qVlP9DYk_G zUv7`M_;;m7zBA}0IL|T zHeOoaH0hg)@ElAWx;LdQswyESI6htBBbgZ1rDEsB_Bi_)g=yl2_~JVyMjtZWgeXa) zi_@qO-jCTsT?97BAdOMLVgAT|(9xr3hDdh6r5vBw=O3G4v7@zS(X%QP_@O-yB^y)v z-KBgCjl*|w;bLZ9;J&5PU;)1!L6tj3v058pm_YJdY2y}D#8H6Me%SfZ zXu*iUOv2NHe(FY_b>KqYTV%W|__J9&7fF|cn8DdT*CExza{XIq{z)bCj5T-~lU*ur zho*3Sm4EMs2?!OaZ*vmoj>8u? z#@^oxS3&N=dmea-V5iAHxnQFk&%i#w=+huM{%d>l-{;xhC-VJy zXB?y>hon?;&bBJ6n9L7P&;E{$e0U1*b?J=P&5gLY-g>aUd(@?6jWbrI*4^J*KcA@o zaBxW@kdxy3$;DbGp>H}DH4{7T^h8z1iq*)ft*v7u$NA2=I#Tzwsh!|FD>lyUv7Yd= zrp@B!8l`;U2}DES<0x0CTbE~Yy9N95^&L;ELU*UE>Z*Kj=_)I3%I&e7aO&-2b@eEE2WB?FyoXx(1(IL0f>M%KKAz1Q?6nZK zJU#U(^^oR0_KNSx`#`hfl_&FqbJgPuT&OERt^F`xi`uaNzz^x0X(g`?^W9jdp4*xY z>BjJIv&s!tK?5f*vVPt#Tk6q?MBUtm&Ne|^GLp7UKl;aqZwdom6;?z1APvN&oVhKH zTKeB!;+=uInaS4~g@>0X=1g+YE5n9wRh>Yv--znUWyQLEsy!UVzq3bLRFUqpQF>YA zpols${Mh-D_XQgvqeM_cWByFn?MBpW?sl$5t<>J1|6_2jgugNxm8WFrd~NLNu0*ko zE`=KVBTb9x?Y94N?#mPmNdIiy2$CcdM26k?+0ZVl+Uq=P-a&1Zy`Z%x1_&-_Uzc0 zZM)V*hrn`7w?;|NV$zkLbLf)bk)Jy_8GV4R%ipo193W-G>FDsV50b_PYwRXq>};Bl?tb?vLd_-$E|d3e_O0J8;U$!wmYerSE)9RZK}^GX=6eJVYmJ z(zX#Fz=J~+W_kJ<)YL}3y5$WgD!)kmod8LlgukmT!8i1-LcXbWw`w2WWahmFy0e&vMo~Gw(lDkexBl-Qj^&+4vjL66`Qu`oPW`5$_kG| zCO*?*osOAQ+1Wdk-2qEH`xm%E%Y7~Tf?PlpwRXBPnFE9Ums#I+OkA7IC3HE%BOwzp zK-`)qrvPH7-}XVVn`(`qX6IEu0)>FA=V}=zAgWv}>gBS%6z4lI6R4>p$~Z=fwMiKE z;|rVuFVgZnajBIhp{VYf%Z~=BDTDG>>|^P^GRF4z*?oEA?P-TI((k1?TTyDuZloJY zI`g^|D$hyQh#i^JPIwOssyFl4bbkzy_RhoAC&|xX9_Vf--HsPUB5Nb9xFqzfJ3;z> zkh|`pa`$YLCr9yw2YC#$RAfB0!Iv${a~cOLcR^FRs`GAPx0Q+v@-oZn{5ni~k@3}R z7+d_F(Qit&X-3oI)@syJ;|FS^bRMclA-?Q>9xwsg=*?BG{Ip<$BzRYeEpXYT(bkUQ z=$lnXJH^D4VwNShLK3##P9V1(!Tan5hRNBRT1T8_p?C0HCQS`pCH zo+;Kw`e$!lQV_Z&8&|xsf7EH|wB&%K&f}dztvQO%e2iChJ5DQb*`GVW-kB21W+if^ z@XG$XRzRKkRB7jU+Gqhq(_^&|G;bYy_0b>ey}tz6-I`X~N#Cawt!nZ`z`o5@H_C6y z*krO7q{km{A-rGIhkk*p-)+RFz?}&9uxNDhoQ^@_#ZCU}R$5UT&gosKU*pVx9VK~3 zn+84vJ~VQrI;~|jA6mo8iuJPl$1O!eB)D&K+~+G0*8#7qq~q-)%nk_^z}+Omd2rDN zv`W{;{1H8`Td?-P6bG)cA1`s8!^wx5=Ri^JxkkoJC$j7yy7((qw5yitQ6t)wOOrZ|0fbt zx7O31Zu?GQ*!1rp{jNuE9waAfLcawlw;m`~gqUG#DQ1Qu7O(aSu`Yj5M)sd&?7XRZvt{Q;EJM*QZO-M(63`{%Xwe zVqQmkThN>5T7?h1hZPgw=y|1X$qz3tlh#$=qs5wyaCEBThX+EekJArkETPJbC5L^i zckWE<^g!iAitgzk5eK?r8thV?2MiD?Cj@3>%WkZAnJKZpOjDa3ZZVVUMB9WaSX?1c za63Oi3F-3)kn6HHzRSfHjziRI8=jnqD=r=aU)+v@uKSTp&G*YGP?EgV#4;ly+mTS? z`W9^N8mxFT&L!meXksjg0EVByT8=IbLJ*!xLU>c-iWa1Zec@Dr6+?;)R^|iYje6Njm}!{qs)nPtl`ZdhNYQDX{|r+JLwJPGOx--{WPHK% zX=*@aLNzvF==QgDscaGlRNs@+)IK)g)W+^m%rTFM0of_3#5kG3&wy7tr(iRYWk*C# zT2bv)+Av{vOU-%TtYt+ojGc)-gUilDLR2S#AgN?qG(M*?R8EX{Td&tCcBu5&fWbd} zyrT^9+8<2ZaT$*dRfdHM&VhbL!csKNf`(SMum2Q=$p(A3aIW#zB^hiG9+3a^w1EAK zlWZx$MA!p(oE&{K^ei&z&dqgWpaaf1M{7z<#8fLIhL)M*xaosKhY+g5rl;j-!wQO_ z-@m{qMl!e#_7T}pu=!a#pw7kQR36ND*WH6Sp{x4aWG8@I+O=_mlr{s(A%3mq+-scVnSM7lLz@Q3Ev9jTGk9Llxi?x*ONyA#OsdLHHJT)Bcb9B2$9O9RNLvv z4b*x91B!!b@CQ^%eb``Smo^h6^@yi+AZF&N^l0)P^$umtqLY6OWVmon*xxz-eK(2f zZ5S>v43`f+;#J8wT9_97xu+%7^NRyZ^ebZNV~$jo(jtAC*tDx`QtdrjH`?~F&(GtH zEQ7Qc0qzinsrwO=ea_gxO?(Y(nEZNF`7A6pXh6**n)ZC?QQV^^c27V?SO`W-W2BS- z>Ohr^wH}>-)D%>{WSNfzP;qgt=J&85-jBWLo%=UZ{pf~TtH>qMjPW30Sg<%%gMejyP#okx1j ziZyq8zum}8KgGZmI*}6!-m_@;%#FWJF*l=ix<6-WEA9ktlOSifFrvBc7f{7& zR6UhQ$L|-q(2CJaXjBD+G0!AeiDD`gX!*Cu-l4ke5;_N+6P=@2-Gnc@z&beXkl4w? zCW(|;9eu7>1I%%h5+5+mq9#$vvMI>Z=>u*TQMGWa-@wge`FGq!U%mA1kN7g*dGXt! zhjCN_>U=t(5Wq8H)D`{Z zGzm#)H*EXsaCL~M!KFMU%NWB3(}`nlJE=Yi!6n}8$%gMuh`9WE%<+|shI{4WajnEz z+dbZ$_mUoP>hh&=glqET@}=qCG9=!JB_`|2sqUx{^v4hoF<8vaJaDdBGc6(~4%{Nt zSO|$PZ;5^AcSoriMLl^pE8Z{M=-a}6DN(|_Egwu?QNUS*bBNQ&mca?^8=X5@)pB^l7%ua8VF6;jwtLz&ATQZyDBDJKa z$MSfylS)vjS+(p>9LS`3r2pzv6{F6xZ(W8LZ|Z4Z~m1hpN{A9orpd5SOKHMXcT}VLz*s($34YOpd)`a^4l+iasw}o3qDxi< zlCzbM7PX~Egt%9!xQY7@lr#&+aPEM!Z|$_a5UkjqC%v4zt-UvT_*W7e^yE`ff(#@q zX6t{l+xUwc(_yHnt}_#Bdv2?Iw9`)AN!Qnb{eHsxwMFm1({<& zXeE7|(Eq&o|T=AhtNob^2Ba1;lg$%0#T0gihU+m;9*<*X8j7RC{Q@P{W%bfG_4KX zC3A$Q!9QJin*_hhADoxtafIABd=f9N4{{-Aw*twYhDY5+Dh`RFpx1z!Sw9qlx zU#AGToI)SL?uaH;aJvyMQ_UzRF<@A$Im$#Z1Mjp8giY`gsh(d;cPkWg=k8OmI)C41 z(Q=MlFect7UL4pxJlxNnYAz-v*|fhCy{;^U1p7ZU6GA>A=e-ajoYl^S6x_G#-w|$*+xk}~Q z^80w$IbFMa%S_$c4CP{K^80*VYPz1-^7DG#YI6I$epwLeGI2_c^Q#-(i{dH@xH$ux z-WqVYWx#7~8UlNpW6JG{AF_W$l%M$fus@})y8eI_-4rNfAWtgDuA1|Hjz@2AC)Do! z@^;?TbUZP(1pUeNF(j~6AGNrz9;y7@XSe`l%J__Zo8YGA2bkbeMZ=kn1VZ zjOyz}J6uYd7{Rz9T6BU?hCG9L!m$+MFu#9}S^DwahqmAEW9iZF?KaNkmWy%Nt1|Sl zsjFkc-gif+%e#ecsAC2>=Ib-2Gi#$u!F_p^ zDYu{HR=!*EER}@nFQc!Vyj2{Wo5Sf}H_2OtU5Reb$4)hcCfl3yJBpDgL< zM}dC>eT{l!a-mfFnjJpTTCbLts(fGi^hGprdQSpr2V>d_VRL=34E+VeD zawxX7MYCYH@@bat4s9sG9@*h9sFW5&FKFGU1x5JkHGjfVlkt2-_$Juf7R{N?s}rvy z;I!mG`Q(gKI{2(EeZF+Dy4oVnC^ZLF=_Pd;&AIw=_p>0{u50~Uhz^2)W}Y&d%jc=+ z`4rMSrE*x!#fd0$qwa=~M{6}8xw7O)<3b{Y+;>jBviB4Jw;$9A*nDAJT#c8z!mDQY zoF;K@C)kE)?7G8VI>+qogrV(vsxLJ5Zwd;fC&K%!natA4ErHD**!mwGZ4NU03+@hR za$Q{t-j(ahIRyN^_vUQRDF>>ZOzv~L`WEh;!tw%)<+=O@FmH(bo?#_~KPW@joG+2- zxHFcI>M~c777YmfBow`LF)lDt2(>ONPcGgzbRLDLOxvn>Jljv-P42u&20e`4_n!mF z3?4bSHXYo=A3fi-B!2WszNr^F{JiMAANstg^ZaCaM}x%N`h0%)AoGzC^7VOsI6rqo z*Yp9`Uuqb=B!4&B)^xD!+B0&v`!$z&=jN}c+Y;1tc_ibE-rMmijHIN}n>T&rSnz0b z(gWRe+=?uJ%(R}gvN-_xkrG=e;CJIqQURamka-j4wandyftyUq;aS(Jrb&PwBMY*% ziNtg%v`H)F$!nxSvY5}+P2-&LLACI?RP|5#M z?$Wi2-Q|jZKM*G7wqtf0JrBJoPrqR73*2m%(N!@)hlPNorJib1XfX*nXYW>QG+xG@ zVi?}4s%3ClE}2T$mJmPrM02(W#2LC&dMGY#;!7Gfsm~QW$``mWf{#e|NH$hG3q+>u zS#flE^YuwVHNsP)V5q*dt8?4^-5eSPP1;yd)UtXuKt_2E=UOp*PYGM6hW$Zvb!8U$ z3mn!`gE8tyI3U@D!eD2iX_K29FpP~uTv#vY2A<&3=;SChkW-;Y%!5}(GD!}-HcZnn zg=T~D2tmlezCO;6QP>~D$lq_RDLua{Db-;Rf#;DS6M;t{wJ*!o<_&y%ZvH*Fd1mDX zn@f-b+4VE5`5GlJARm=e<d${|*iwfhY+kXD_USO&Pcyue^cX zkp_~&y7quqX#7bVWwHS)ZCDv<1v-hhKe{>P`T{cGsYMuGF8x z5i00iX)U)ajKOw?Q|zv3v>TKi#asAG_!Jji=dd^}4`#qdKbbHqKP}H;gl=GmMM~Mz z`q%aZoj|gbu*7jlfT&CrYs}#TvzTLrW_qW27|s{CT6I1XL{zqfEi2rg9$L{jxc=@% z@*emGNjbQd-22Hnqkz}1<7jDnkesussS32|G)LRQN_77$styGUnrF2%{SOb1){6!>^h)YJ^VL7$ENRk=;bkoXg0B^z7C5Tu_7@zU~rBVP}r8- z?<5+RTrYotTa{^4tQX@O(b$NE=ZES4LCyaiNqh80Q zQAw)aWOZtAn5-On#4orO5joMj|CxY(u$rfrl3)s!a27MQtUPH!hjp)#HS^7cVq!t* zs<_Ts9)oxWFgP|uHzI{I;YeG~Wt7`)BvS+G>(l%gSm^ycghf4?O{YNumIG@%0|@c# zb)elAg%c}AIIuI8Lp16k||iLnXBN%_&_uF?DHjKmsW3n%075=s_p1C_Si0DEc7U?aWfiW2_x zD^r6I@JPe|09BNI6pcsvhY20FlZDo{QV(xkAC zrpPK7q${*kHYxuWh3i3B(a-YxBH*O`>hFc9B6nNY^pmQ0wBIEYL@YKVqY_!J@AcDR z-w^%cT!?yk*M$c-Fcv~dx-2X%%0>qJ8n&Dz+#sfm)WU41{Symn`0(Q3TljNTNQ5Dg z5Yb|nIF&?7OTpQD{s3OC{61rmC?{)`q*&nJSe(VBVe~LgdakqVn4yboPJDz$45LXN-V9tUf7BZWWX2G`|AFF*_U|>BNSqwcI(2x^44W`9y z=VeH`{UG_UyJDO~7BIdNy^-P3Glb|ft61(h$Y@g~R)2vTYe^lJJgK7{h6>R|{2}sT zZuX=lwJ6ccIBcLe05y<{h;~OX)qJfj6b>6n&3a*UcMW`LG0h~Ig;m4^TsIFkvIg}m zI6#sH^M`2c!#{_D3cw*EAKE|f+C|39TI>J?4`TtGq)rAX{=s|kL@4akO16cag8?wO zIpk*)5BHej5Rnf?At9Z2L2}a$484Nb{GF=y9N?8qp(J>dG4;GFq35Sg!=d;5vQQ9l zgTPMe){86|>F->wv!VxeMe(FgVDB!X6AV70k^ziE@^gv}dl>58c|h`nZVouOh1!!y z8JAjy^dN-)K`c~wISg@s`)B!=9dO~Fa{NIeat8fjmVS~DNO8+jQ+k-xMP5xZ|T z^a>v7?5`*(8KM82C1w+i+3p!8?U?{c29OoNYyd?8ECNskzzP73dx8=c0y9CKdV)~y z1Mxrufi^}^CTJpn902A6s2&7OHU@qVDxxnuJ`5XpG zQUlozN*cgL0K@-jqu4m=VGRH)0n`Gp7C;?$=KMwnGGRRcTd#yoJ$B6fJFg5)0|4v= zFk;6zeh|O}pgjs;I)IY^=I!(h%l1uxlme*JH(~h&E?_oud=8xQ3HU2M&Di8ZKzE23p-vEcX6Cr6m7F_z@JVd6oKL%agv0(B2pYgmdnkZ6(w)nhS&s&i=SCRg~fxwn~}6cG@}^eviTt zCHF2d`Pm*c?LUkDn|eB%f?Wv5qIbC33xG96o(xzS62tLp~ZoYKF?QyJQ^OuudOzLj)54t_zkdXHG9QQZ;#S;i8|nud!LCWuF0 zbyEtHUq20-ke|2Hmqxf(FK!Fm2G$J7_m@pFiUp@ucFZ4BiuNu0XNF_V6b!)tE5@He zW>);1iq+q6k**!luGg4M=-zIeo0+cKnDz(Vxrp9T}SwAVbv#N>P%VL)yw>l1XK?rJNdr*ye|7=kdu8 z-Y&H^6EBPKyLtw>!t6;V(h0Toy!Pz6>0Jh|wu4%;{*Ve-)9V+P69$%EARP9#RkMPdWV8y&*LG77AM`Say-e6kf_ zYAV~v0720{wFl82bH5R2YOZ^hD7>)srO~SH5nrF|seER{akN=QAYP#+y58Pcgpdx1 zQUs<|;BvfQqoF2UT5o6nb(Dgce`NRw4Ayev>rfM=nlwyIgWdFJ zuQ=Pl`!X8tZZF}PIF^U9p>8VH}w{M|dz_WNTSVz<377Ug-hO^0{{cT{RAsYZD zFnVQpJhIEW!n+V$!oESi{vCEFsRm`E3zRBDLp1u{K4B%)8IQkUnZE=NSa#OLWZ&6X z6c9v$1^&hxxF9br-TgDIxWkY0?-l_W&CbK{7|T!{5&V96JfU*MQ6qRr~L zYcd*|pT22L+ZeS~(_)u=tE~0`{@ns^BJ5w&M=Fj2O4&z_2B%8J=Y_^LT-o$xiYRbmnj;yk7-Dekm;(C{r0ZJ zBYI|;ZU2I*@BCgHHKz%5tlfWrj;yQBdh3yQ=eFJV!-ZGr0FBCVFz0}$(}CYcHb^LT zkS0yb$AN^NZ3RNHN)SY!7dqgBB{WzFMRNd~R>;&80x=$jYIjyXm7J7}Y&1YzErKyO z7!rpBhgGzS^aY3fEuz_pZC5JV6j3c9H%~4kSO7)S?&*#dDFy+Df!xy+abx)pnf_hW zTeKqt@sn*%wAURvwHTQQMY*KfqDr4r^fgZX4!iMDXI>^tTCilhBtil&`AtMKtu&!j zEeV;va$GozY?z(9(O0q7529xrXJDx$O|?5Zv0M&4_4J+Z6-O2)4qw0=cP z1(mN%>ncY}f>-%RTqQyf6bjxLuf&Oj%*5ggoOCdn6m!_d_(F4lT zcM&W{=C*C2(b36z(uHV_f6dQOpc85?qTi;mzmmO#{#cebAeWLP&9#h)_>FoYu7^QB z-|+t1l$<>I3h2NWI2&vSKY}$}(Lgi`V#6aK z{{@cau~FR4ycK~JHN4wyP%>+HV*ES+#(oiG&Fuovj}A`{4_=>!8RJ?0dVpEtpQf!E zzKtf~kUajbRTV={*l)3U!u(*+bY)ujXPEm1g6#cFI~pAW$D+WH{75=iv`1PMC1-Lb zzQ0Zquf;l_r3L~eCucT(_*N2|hPJovJ1(kAVeV95LNV#eskBfxB$>KIfkNvrq0pg1T?g$6|oSLJpIy(z`5CfFv^Q0#;Rf9tbI&(6?yDQM9&|V#hsE4emnH1 zzB6woYSwE`Z<#^HY0D!MlFz8g?H=Dmcr=ow37rLeH>iP7 zrjF^(Waq(p*b(0-JOjC1*cyYwq@A*eW8b3Douuys_VO}q6^BC-5=;;y%28ts{#Fx{ z!4lx$v`vcTcNyemCKSa+M}I#iQD)D#sOfXM`+k}iQ4T6FLco*0wrWD|XpVEmcDs$j z^3V}xr^N%LvYp5!N%b#d6Sd}vq($zdIsGlM&yIt^4OCyxwx|?fSK$bRGQ>sU!6L#m zwe5_Hp1%4@#;r}{d7ODGh8ClGkHV7pOfutk8TQw3gzlo8Y=a2Z$II{kq3kOI@@SSd z(Ex!2cbDMq?(Xgo+}$C#dvJGmcMtCF7F>c`aM;OrouyrrphJzz7az)y?M zgwB6w3$O{M2E!VmoKb&{3?)qWg~U80;U`uh4z2=g!-S&HE69j} z7~F~GEWixKFlFFpyUm*kwb1*DZ_2`-a}gSuA#DxC$oSdOSD1a{40WavzlLD90m>+F zlL2dHfN*+({WBOQjO>>@Nt8{PPan}pR*@a_jfSNN>~)FTo#y%ri-X_*zk+Kf*$iLd z#H3ZU*vuNuX1@~9{RUBweIsafdZdE=F?VK1>O<+`n*x;?;1zzQHV>W7Q5T7ezJ;_2 z4J-m)(b5&?6#ZdC|ARV4($N#1dkje4b#0wa37lo#|y@7lJQxOFzrP%Mh!d-q0zd*la_TRGhVsSOo`|;g?@fsk z?@fUW?M(qb_TChk;og)WAj$mwJPJ69{LBA;%?kq29~TwYA1D2jjP%C^f%MOFUwRYb zJbDvkAR&ok)FUcj)WiHeL2LZ|ycm)HzjFS%3grBwBs4+fN+>mu;*IDcVuBdbfrO11 z#PHAaSm1wbAOkD{a0F7iU2*kh(5H|8APyW6{^cAX%LD_E3?v5_*2FHZj4MjojFfiP$#j525?_$Q$aQbRx+vJ!pzXvhjo ze+|(<1OH<258Z#V39$Uve~`aP`Y*aLfaLy2?2q(_{z&c5`M>}Fx4eIq?mzDX%KSIU z19bj+3MBgDAO1n(ALah-sr(VpAGrf9Ooc`oq!tER1hh&T48{t~uFW8F}Mjus+GLxC)@ejZ!Hv4bd+!gU0VDBJxver;l?kD20yl zQ6{k`!V)bDpSF_~3C4mY5)tuVi1i-D6RnG8Mh(*ydlE>)D5Z?ch!&nC6OuEO77=ma zb44T;5UY#6TtULfZO#cN!7Zg!d=3);I(e0Ew}QgZucH){Y`tRSTXb%c z3S!~mmkh92NbK$Ke+?rE-VQLLe@2R2w(sG>lbJun6=F@Cjrs!-B)GX^i^)%afu{E( z1pz9K8g1Yh){ho6Vl#>q1Zou4Ys9C7LJFpZLi$Z3kA7wF@3}y!k^SX7`k7(0AW(zw zUL!Uwln;^2QR;d0{L%^-IR)5xMklMiG6Glsx*qg3K6LVkwjl zp#WG5xD8N>KnjKQ86f}XR=av({kqsMK#s6#*q;KBf9eJ3{i((`9mt4}q6P?ti~gx+ z2qg#h`~Fse=g`5{f%4SbfAGk!Ynn_bP5_m^N^|H%9Af?4^~Y(3yf!~-G|5@#nQRq1z!4!a3kIwA%VPTcGTSHq?&NDE5vrJ9hE>l z9Ms&^fzcx2shV(g)NSxcRHCxLIcQ!h4MHT-W`ll57b?$S?YY#~KW5X&U39*iFc{`-qy0EveV*b&$((0k|{Y69yVmOCwf+T9V5}ZICf)<5u6x2(h zIY>!!HZzWc4#cQooIA=S%Cf}3vDBJzwo5zra|@?w@y)=&)2rvznFotc zV@HQ3U9(#HT|C+8(E|mSrZm~jp}$H;os~U9CUjC?ww}nOOsR$fMiq;eXO^sk%W*LJ z+=#ggBbPkov$IRi%_+tpBbUE|vF+>2r;nbfm;tR5pI@I?A_t>-?qCiW+x^|MGABMq zjwX3~og7!cEJYQ6eRfW`86E2YeY!+FN_26|5#VTf8<7&NV$*lc(Lj`3e+4@*&JRPA zMNWuJ>+zU}5It~x*%(9d4thq-@VU%S>okqXE{-?VQ#W1Lllvm63u7^*6vHN6E;W{D zGnY4@kbYBxU$Opp#Y#9LK2a!h@igFmOK>R2sDx=lP1U&drCmdY%!ga=Wc8$JN02LM zE8S!jMH`L!5DSJ5@I$LEM*e-eN0ClO;MTBW!k&ge{EZq4`wJ zst*;5zP_3?9kS^hiwXG1q!ezWZab4T$I(p6G7&0q^KTwp-BNs)qH&i!wtqZe9QVG_ zzmJ9Z^syHo{3JGe>XkG4s}eS9jmQFHznWgtU8vjJ=`K+e3%bC%Z9NRHf{IJ3U{`Dh zePumM7>O}LJe9Au)D)$J=9PAn_#uTNp$VsWhIAqQ=bgn?u(&ECQv!SMx>Z_2P<-3v6HtAFw=oB=k-CMat$`UU0uv*Z z%RG=U0`<>%?_k3FNfL&wC6K)Lx?R`Mt+$Rn0aqLvC!Fo1SD9M0B2wC; znX`{2GHKCRKW)Au~^ZVX4ptA)Y3GDn7o#V zym~6Su`~v1+q`pmNLnykx`-0Z0`}4&QBMSGC@ak?e&qfg`(_yA=I*7dq-|eJ1bE(v zuyP3TX7g!F-)a%TyF%~1iB;E_dy(LS2LfE!n~hG=qDZ~0CKnNZc!`N>6-y(?6P1yw zY==#PvpwOQ$iRu*xZcQnM;0K@#= zpX-`L&jB98qH?B(nb;48149w;^AM=05Y)okXd)HCUx?g{2K=AjTLSEHK7EuRbVb*^ zb#oHM3WMbn+awfkO|;x$UVXVIX3axgEPY#R6LLUXM&P&hI_t43V$HQVJ!xgC*x`h{ zh|BQTtN=%z#;<15s@u)?$SOf$4VkRpKUL^oR<*AIuk@|amLjFZWO!holDaGCeAm-Q zRBTCy+n1rFO*lW_<$QOGk2EPfCQthiC9>NV|78%_=x3~Gqf3FiFXyR385=N4po={1 z@$jK=z2>~&it?{vaJP5kZ+U|zW?mP)>Pfq1b1HNFNU784D0Zb{o9ssa=2iRsbAmMu-R_SO0gl77OcYe zm!ZxA_FYp=BcepdZ&2JCDpw(Mv!s4%(=E-EFYtS*eW)rbbKW$7!z98-GEh+yuZw6* z!WI(Wpy5<|Q+%;Wk_;`AUk^oFI=5^N$d8Blo<@V&_k^uv$jm!$vGVJ)VYpKP zvqg=H2BLKmi3=7hx6$bYZKz2~-W6!s4fQ%5FyAb@1@G+1b+Me49dM~J4(6ew1BICF z3|S<|Nrv|LUa$mgGFRC(^WxdFpNs`AUMknJHV)KmoqPjh1QFX1OzZMY2gLt=KxWv^ZId{=~*J_+Ex?QSsbY;oS{2 z%B_xNl*Hs2ZA-31Kfh>aJ?DMVXSb(s1rgus#24#{PYQGKc_UbN0Zg+r;epZ5g;fnI@A@MJzm(@mQDb|v?HOi!x#hp)5Nw1;puI9Flc z$kF;fHYC@~>@r*8{$q(&$fnWy_fH=eI(zizwn}oyR-{B39@Yc~tXU{`@i&TSKL6*@ z^}hiS|391G0YKe<(9sqD=>q?6hIq_ufa5z8V2H;;%kpoAcr1U5ulhGbyuZ-I|7SZq zW>)&YLKys)9bTulTs&^8b+_DtX9(}F);yORKKDyPS&k})MEF|eD}nuh`~^8#2T+3aSG;Fusr<}73n()X2mu5LiObj5EB(|Yj`qU-kz#r=w#U=Mlwy2dZr+zi zwK>=C@ZDa|50@uC_e!Z@M`z97;Z2B&VBVil4)uzfvk4Au9}e%o!(ZsW9`4i4t?>bO zMYF%}UTt4YS$vsrsm?TCn`A7ee?`u?O=N$kN3?*McM1!}{_KZc^q#xTmZzpp{c0)k zmK}KEQv_uyF*ZWyGHH^hs#9C9&pvP*ra=`|Z1N4u->{HDei4=Fuoqt&g0R1Z*VtL-mHEscJh%GNJW&XF`K^2LEMLfGMq2>yM4{w{#A6v z;Lg}dBTY!X%%tO!uw%kD(*>y?a%+dZN}y+hc&W&4NmQX(8?n`Jqtick1FKrwv3h;mfjY=(!DLr4UJje|4NVGe{bpd zT+OR3ox39F;}zlKP4wc*-`U*}EqHbHd_lXYJykL_>qhUYW1`~9++|_4mX-Uv*9cv@ zg)6v2%*9L`dHctbMXf>?8S;-ne4saQSic@7$Rc;u>S7U(l0!HQVt3Xy z;cG=Oo!Y!0A549EE%ho^2nD-;VTpVk#+5K;wMVru49u>V=WBoJglROMQEx%LY(Q4S z&$vk`OR_4wimQMouR>Ij5Z4nElqa_5$XD6Q_^=V!UBTuUOKwCa#l*7IZT;i^9_b21 zt3PN|bQeKCC$bQH6uL5kgjV^0x1vM(`G^9B&=JhkSltXsgvI_DH zk`xpsVY~-WqfitCm%TR?yR;hscVO{2Z&7S1ru%_>=MVvP;X0O!Ig|4+c8Lz&9`ir^ z5XJXl`??{#&+eH1aF8-O-#AlwenUFa>^6G)JQf%0vsJUjtEYrPOZJD{Yo~f*LkKqX z=B3jx`Bbuavl!2mD+ijL;Mui>Xat5ffJkHGXex(;Bbb|yphAN_@`$Jh zdF_;nTSc6LlM5QEC2C~$|5*0;irJpHWxOg%7OU7AE+ho&Ua9a|DW<)I8d6i})5mhO z(GQRmzWf#o-rezZvrW=edX>g7C=xZI!hC6J#YZk=s{2K$XEu%(d|!37D)bu~ygD$* zm@L{*RtWS2U+rKRQ{OaA7x3u@yPnPlr~{lYn4EBBD#_D_YpePat67i0zo(~OtX<-* zXmn~(-pJ?FEVU}) z-a4UGcCpRnTy*rw#5&=)O%zT&^grX_0(KSiwK)9EsF?gCK9>yaun4CFlQ-K{XibmW zMW{P@Hcnu-FxCueiF-JnVbeaX#BlJ`%?KoU2A>XdX;bItM=$X3PBD#VnP$j49AVYz zV^g^k6(10H`+F8~`Q%uQ9=U^0%uYkEYWV$l%r#l)4BY5XYcr0epH4t8cJge3?f0-F z6fOmf|JINZiC9*8T6@{QoAQgiP?e1{3>j;tmtO zcf>D&=_ubtoBlA6URV|Dd$dft>Vs4dVNx5m7(Sk7C!gLLgz0|X= zgoSagLIHHXX1VwGdJXCI>_atK`b@1UB7x&mW2a=TzF*TqjCnG&$H={kNCy!MzD zGIA_Ym&h)?=e^sdJrVoAo#pxHHvceUacHZ{U#F+YTh^lob1agV;1I>i&d(rRW5Z;c zJK!$RUgB>l`dP>Od-43no^GA|1lYDbQ$1ba0nYlc1IO=7d;Z zGt|TSvpnFH{6l-wq&ZLUU|4p3AtqJoz7WcDqCv3 zLwtiROgpbRWDh>~tCsd$O+H^m#TH>Tl?5|r;5*v1ffoea2@iP;DNMs+vsVLcgF3#K@>4#t4=Qxmc~P&_0;` zPR?DQu-}g{eEPv4Uuaesq4cMnL^obekI-M-)?%<$0jJ>_(gp^<(!j}Vt+i~GV`6aJwY3a5Gq>e%I{Pl8v@JY`sRP@A#_G=Y;?714lE!0d;t_I|jBuR4qe;0+0c_OZB-KwJ2i5HP z3uG*Wgd4=4mXSegKV&k~h1okK?oe<<1y!p@O**jO#Zl>nZ+=%^mPC!OnHhIgl;+2z zou6T>!FasnPhn#?6j?nS52ma2oqM7hb1l`Ym5}<7fx@kv!*5cKugA0Jvse;Ly`c8m z%oC-y4@)=uM%robBG9%$`|65z(rzSH&N4a`_x|Mseeze!*Yn2w-A-mG0p7kK7b?E! zkWwh9|M>2X^81#VnC@V&MIHzb*2^utVv9 zXmY;PFcE5A81c_d=**neZvTo7eV*F)Q$&wwFq>MOUl&w%-hr|wj5vU%oZ6;*Y#ZlV zZ(9=Y`$2CD?LEYb4%r9C+LwJP08y2Bizp8;KjSsU%2Y97mTXAfWek%|%~!}z~r*091cTEZqD&w*t z=?GG7z1)v}frE_f)1UPN%ibL#bH;45?`PN&O%`H1pprNQr);*`*(3PLeuX%Li;lKf zqvw)^m7NV`^SpmXY?hq=`)6hf$DuODWI8=|v&y!e^22P-W^Lkb{9{bizTWdx(oJ|)3avR*h`|GxARU5% zR;B5Wl)Va+`E)q=El*Kh@i<--#7L0dZPwdS%AxK37uLLuoE81ee3dTnh?@hNa#i!q zUf-%Jx~P_H)2f1M4>0Ls9K6gmPT-`dIHeScQ|?Nv`{9DMlZw+0{JPaK{PjcL(H^-&lOBWBX57l+dzTiFntQWS{ z{w`hDI%~L`qB(R(p(710ytM3mVy8wcvi^{K{2Cz#Ea`uZh@C%K*{AF_@bWS zFUK~!T^aG?WnNRN1^lxKztWfvns;U=nxPGc=;vn@VVic;2a_OC&58sh@auwb-wr38 zy0Gk>WOZ1WM!Zmjh($0mF(rt#W=;5c$H(4}hXzxK%ost9(&)Qsm@^-e5Sg*0PDJ(JtSnmuf@dJ5JHX7cv#W-oGTpmc*c5qj zPM#0s04SWs0<)kf)zG%4>NvzRz?asbZC5WZMl1A+OCm1oNaRNx^>YuN3eF{ofrT?}9RhYdRne*1 zcc)q}O=+oRRpc2}Znl;`ePjus*6wd0k{3&$j3CM|M}q17QPqUz?#pF7y)^5Tczw6} zJqov<_2=TunRl-Mb!bKb{_FUC;=(mbs3SHyXxq$EHDk``GRRU?SJTscUu_icJH5EI zh@bOqdo`8e&*ZbC-6(Cor-J;o$Swq@d^zamXkGz(+*f~tDeqfYzWmC3x|^zKZ~ID7 zX;HqV)d|igDnYTY>TNS>VVqB^Y0+Fx~S zfX#cX;p0bmSx%>E<+K%0i4rcKq-+=tSn)xINwHDDl_PKAA~q4HhHOyw`-ZCYWuc<%7M^9jF=j|c05FJ#sr(|}7w7gx^1(VfXy~z1UQ~dckOr_5Wp~sg z)b7X)ha!ly5nuj(_F-EjcAikX0*shXy~jHQT z=i0J6$YwyIHV+7bWZ!%!SS8*xFCF$`VSI-N|Ggt9>W|ElI%o$=r9T+}1k1CoH8+T> zz}NwxkD)&=y#Xmy=joY;1$6=CCoF*nnRYG3F(UDz?;5j=%LzcQ#SSpgF(E4-+9mUdDAO z!um?jWuO_W03 zK(dQ>9-VhGWR5-`&V8#@Ab{1uf+kxpGh zlYo_-fDI`BM~S86HUmU2nN+2YrX~TIb1V-I4kZ0HKOGh%5Xo47&&?a>Ylv@UWg=aXxjPJE^{iAyyQU zOjuka^`({T{La$PxDikRD|YVFdYsh^4{KkLJfDCfghjewtcvY9(Q zZ%Svgt*ei?IX(ULV0IO4%2FP2`s?5!)Rg1pP$QK|r?i5aMTxTg$-^_j)bi%x_~Gd0 z)WMr*|1|kAY}6F}vckmlGNJzK*)!S0s3~R#dc6|Y8;G2B7X1m{=D_La&6}0G7vV7t z!y#9+w@L2}&4(!5A!puY7JSf6FG#o2aju>%PIhlwwLy*S^>dJVqL`NFPaiwfa7n|l zrR|LSAqII!FUL=#yH{9RarIpwes(VxXS~PiyzW07(I6}$EX^oghc9Hz-Y`|L!IhW! zOQ7}=4Iri$uEC3Do!wB>#-W9W5p|xh_07a**vB4gGU*s4?o^E8sSSzwyc4c9Xwz8? zCJI1zl}aDSg)xq$3ihPqM}L2F@l5FK@X5Rq<#W)H`#Cy6H4(xCM>Czvbv$Czn*R)Bj#~H;1AUwP=?`cGN4hLAO; z7AZ!S{1Z9ZwM@n1DCLty?ZES-7La%b$TP7y&Xl}j{SW;|EZmSY*CA9a5*k%e>jt3m zA(9U-=;}PLmQ3m=P0A-meFzu{dTubv^0g>ndEI=oZej;kIv}(wh~Qu_Ar{N^Fm2wxwygk;B39!jP^DY zzKZ*p#%LgjR*`g!{JUggZXWN-sb{Hf)zm#!lUElJgDNvg$8Ygc)lW^>QgyQ4mz70m zm!CxWLCfG>)dm-S?!ExJzKMR#U5_hKYkS0_GxF#<%4;Z=r<42iZ8GaT)y?|0I94vi z{C__(o#8J+FK%PqMk*3GnaR``!fMf0x*=tbFWMs3 z>p$?y%Xy5;OHkNzT|^?IvMSd-Ynj_zMv8+1{LDW6pqX^f{b z5q)C|GaDVW8?H2ZA^jUc)sXc#JzO%2tTu|RR0s)u3EbOXPPpmH*$7z!D8EY8kZiBt zGF*eP0vp|O67+3E0>4~MC+OiIbMJxW3_{YUkN2NGDgdsSm|u}h2qTrs0 z?3N|F=Wd<36*y@&J-@S;vFCvd<UHc`RkcpSa zwor=M)di;(>#!^^rlDf4;iR^aGqf^~S(z`g5}>L@aSECYW3d}rkH`DPaS-K|^r9z6J9uVQ61q_%8jp>_pua9L9BtJN)j{(O8fr z*lvC!_>@_qfwp{ETp~C0@n9cIHrtbZwyFQ_HK{)RZ~-kXuoUgA_mbUHo9e{XnM{&5 zt5jDAImA{wiuL5pbU0RII3~*fYOVJsjIza`Lgc4GndTMeUukvx#dknHPl-2K#ri-; zwcDu`bt2;#6EpH55^j);sVxaMc`<>i{w0@zrN}>vRen6z{tj#AjDo^}GA@Kg__at#3 zs~FPz`B>=0RGG%V*H|sr7v4MAbtkKLv%D!sS%K?nI8&M!-}4@^Z!H!lFLS*maUAWN z$9<0FvD}jD`Wae7-P$b!Kg0FGARJ+q)=o0G1EGJzMw|6Ura~;e2$7qxxnpFS~ZMCd*PJ@czFLLq&U#0x#Fp%8+kb^TVIbl)qGaMW^|47M{$|0beEhV;zfnW z(P-b&9c{_lKb9(|aPkTlBFSo?VNhSo1KrjOAgmS4qm9ciFF?8GnyyIXWXZPvtg7-X zYgcfbZJ{{bRy|dc-*%yQH&y+eD|n%Mz7b^7EitL2s{vnGK@9<{{F>gp*s-{P$M?O4o`UsM)*jBP>pNl5t@~wW6 zfFVDr+5X*#HM63M1Eab`QZo2L3a?{H$aTgR3p|`T*X>L=L6J*JStI^Y=9d6>+5nv^ zrp~K3i`AJFqa1f`Ni#j&piX;>!`sGA>^lT_h{a=We4YU1Ec;4uiqPE6nrf> zl5?mJE4BzlTe2))Q!;Pw zrYuk_bEFT|QR5->>uh-O!>OR6ZrA)doCyRzL!eZHdC8^>M9@2Q4!vOK(Oq=kYc*jx zDlO5tnpF-@$95n}NpFH8{S9>N$K(%n=YT$HT5qP)*;*5dM`E5Yt!U;1tOQi|YkL(q zjS~cJ5IGgw8qb}_WM=vt=MnOB8B|m-)P+y#hyoRe$jFv}mj9+C5h^ThR%lvcz3JlQs}(#W=i(95SH!q~p`a%}K*Gv_|PpK7QWlW@#viFjbjY+4KYf zVOhhF+$zamlGUu}0{->Umgi$>tFn%c>GL>6tw4W0MSl9+dXhN|nl@X+w6IV9#`O4O zY7$43;e~3*4jH}4=Y^$@U9l)_17SNlUcPE~R60ZZHU83B;;Ml5C3x#ts>oU#kF45F z#2fj8ABMOSMh58xe-f#}Mub#2tm7k}@2i(dZ9d^dM9P=-FrVx>L)p#g8DbU*6jBY? zeC+wxuEvC3{NSx;vGz?{8wi)44SB>F_pK~)kt0n7$<26rq;AD~Df{B**`IixM5ev; z3sXTXbRO)x)E$0+yR@^wZ;`ZZip_XCr(j$p^5=2%VJ8@7Ei0}s?6u5-;+g($c>_)6hR42JWmnd=P$q@ zmVde}_S^Edl#)Z5ebxMOWdLr)Q!jV=^&4moo4c2(+a77Pi*6yTd2dO~r;pY`i$AI@ zVOyPNq8!*FhKMD<0RC7=8MYa7#5{+$onA3AT}!V@u~w-A_rIxB&zpSZBN)>^)h7CqBlP=w*NOlQj4e64qlI+QyfO{?x9AkgI<+8hd>ne+L zrj8ZU{ao2Q7rxr&KtRYH zN!F@$sUB?Q&QG>EmzM&?f^+)u@$0zzYovfMqVZp&dUn8qs^b?b?FkS<052CwGz2|kmkgAY63F@^NyCFzMQeP8LECy;-aw0T-xc=((So&;Lf39}s zi_Jdu-JA34Eiy(UxVbLcMH?M6l5CVL~p9&2=hyqqb#Cxgl zWnkKPJxg{HGlI{^(B4#Q%6$E9P1P`?9}X(s313Hbr>ddN)X~ZrU|#efv>G$tnnP>m zxPCQzJ|F%>CMMo)>e5_Kq${yE#Eujqr?CmL*0iDdA735@`acix|Gpq)U}53-D{}Wg z-afaC4lj-RFU?U0?L@cu=Y}dFC(3an>!co>f)V>Of!6K{a(v6Lc9oPgGcGFT*lRZ@ zAtcbG;$Q@}S!pmL+A28y1kk=DymlkW_^+39u3!1Q@86f^^})a0p0Z7S9lxok%j&k9tCxHI`MNUn zcJXrhbGQ5bNNS=U>iyzwMeOR{_3Z-b?Mc(;?!9TM>*hTx%j@oCfRXQ8WcNGDad$+a zE%9sm1J~uF&fa4{@sOe%U;Cx49JuG!eYfbO{K@y_wqkb~^4z=X*Y0~IBvXHq9!!#} zZc~YupCQXT@8R4sFZ*adem?JC-ZHb_5BrkeZ~EZ9k5RD`BAzlPyt&{O4zs!WvKG%y ztX;m)nBf$-2c12B^^W%OL1Cv^+&HCde)6h0ia0ho?Q@`RHuhT1Y(0bL>v+2icz;L^ zVH^2%V$Vbiy*IWVpw*PVfmf6c-dp{?4^;8K4F%u*GC>AU2Z{dja3;ss`I>$Zl(;*w zMsX$9AHD^uhkZ#>(-2iyo&&{X-Rw-0@;KWOm9V;Ca7oW4|on@6>h$+-ZsNqKVAWvO1tyHR8?kB6fc>uw7HUJ@l0{DE)#Y>B#gtoW$FM0_cCdjgVp6EMY?sn5{@v=I-Z+6u1`REQdHL|{K z9K2^&GziNCEEc|9j9I6bdBpio7}>1p&i3LwJ2n(GKN#$2|Jupu7{o+6?3n@_G~~O& z629hI7R|sgIa1&G=%;ugdBJ)6pjvj4a_i&zX*`{XgM0e&y`=Bbu|Kt~{}x#kF(e{R z7uUcubxg15-<+zlfpI+fMRq$Om*E|w_0H#5?-X9Bs4g2Wz?(t!pklh)_WtZR`g{GJ zX7Xa#8=k41be~$BqqjKY%f`fMzG9ktYo!K^NnI_Xh%{L!M}LW3k$WfZO-Y8!rtMAA z3Y}w$5iSALMcT`~WyKy$%@KMvsT%^V986k=I`k8&YlZeeM z!9_jAlK4FYX5UT=$)?RULl)^at@yIBVpW3oDh|?jR0a-?sMxI*_)M}xN%-^ z*z%DMlI5%Ow3av9hbc8}?tT(Azl)i%^dSVrAJQ-lT^rBFJ+wX-SsSlUI9}3N*>_g9 zSFyUp;u{r+p9e(J+hC7?dJ8VUBs1GCXtp;W@3TISGF*D)b)H+fZwMJJuvW^&f75k+ zP5G576&d^igCg#NmHNH1_3eeaO7Le~;vPQY>C2;gc}KgjI_VF?+sAKT>l=&G7o5ok z%)mWSTBBO+g-~!_olUo^oZYg?X(vbeD5(>6<9O{}FZ~~4399KFI4bDm@l=Jis_DFA zWXi{ZWxn8E&8CSrB+^L$ev!jPNEH$R`3fai;I*OJ=<80S{*~wYK_lhYqPlr=+Z)SV9M$m>PM+!g7vkND6}kYES?et4B?g})IW(CVg=F(IgPv5fbAO=7tIfh z-q3{J7eZNsIz9X5JN+xdyRI39OY{EK?+}T6MOGF}@f!=C>Q8uR_!^I)S)MPEDmFr5^*ai8L&o(UV<5>hV!Xqh$U*I`pOtySh5Q?+r3 zy~{XD%J`x`i_I}7UMm<)YbLBX8S!q$kMov6M$m!^Am`%Wgo~`BIAm0&vtF+pdmYdB z_RkNqZFMh_5DKdHQMu^Ut0f_;NgC`qTr9qft1_esHigA7N>HVXEbsIz`>Wx3H{H|z ztgX!)>yU2VCh|ea`&xZ#EfSh~`@0?E`vbqtO4jSmBW%4$M4HD^=_-vs9LY2YPd{VL z;bj`h&##V-6ucNhXnG4o3E^tq^xoDkVLZ`pl(~ePL3`k2wZI zaANXvaaT;}Xx71Q)%ohl0V`w?v*x*>I`63VNS5bP%elw1qcobXCM>QjcWrpK9jmx) zMmy$WkhBzDUTSZZxIpwHi1gHejcxdMZ7$P3XaVtx(`a$M=v}iw0%a?vZ|vBDqbI85 zabmqAMEVP=z1HGLYm^eCX(;kWoU*Bgs=^7!>?$$PsUJRl^c9#;4-8DCNVuR{P%4>- z5HTZ@GCM(AO3+tIbdG~@sH|~D80(WjF%_w0EVX5bXS5DRaAYj&f|iIYpAjRlhf-L9 z`#d@#Y9?UJbU2Rjl*PG=lHML8Zu}UXKA{8c*RUdT#b_>%8^?H7q%*GQd`4TW_}MR8 zwaXMW@KJU+E&^v*Rb`97cx3miGA1u;X}hC>Yom0e9s9hUJTBu7c)4`0SwAx7@j3j4Ht5R@UlF z56On%o_sw(vYRw$y|U?Un$_aMe7-MZU?D0vsAsAV)XMWpsM?+Mf^+j_yYKu=Fk8pC zkewAOs^92KHa(@mpn2n!@{$sX?uCVOSh?yPWqQ`+64Fs&sAs>I%i)(0cUkNc9~qcV zS^TDNq6KWRT2E<)*qh~^RoVA_0-_AL5&H(BOF_uSBPmKP5d`~=6#DG@ou57;-#I8B zuaor3^SWlP!WA#lCr^I*$Q9zkotge!{`qJ24tRO1&^$sHO=Jl;ZOtkrI#nwOsi6ou z{|AL%3EDiA5jr~Q@AFvaMFyR5$M%$Ie2hHUbQe-d3E`DSm`o3v z`vxKb#YPooc19pN;)HyLw!yM2_o{^k0=~K0r)|xx>V+#dl)vNrzXP>UV8qwvfhxW( zg9Zv`cx!RWbgwBF8sxqLB~4c0N@lI-P`?eSubw`~LMYX$QFl(L(5f~#Ne+%?f!x_M zB79JkDq3ApDP3l^{=8?l~@2c zj8cM(DrF_a#7KjT5$$i~u#-%dJ&`E%ERtz8QOq@{lD&(Q`t9@o1}DVzoYz2)v(V#+ zd9CUZkbVxmo61>7#VrHvoPR!d9Sx&|RtuF9=Tn8?x|#=Fdg` zU}PJ!&EA|(9~-x6*P-!90>!1KhT+y*$fbL+6X^}ns;`2Lt{~V*A`X8|2k@@v1eSGL zc7P%ob>ya|`(bO=>vY&l{9xHcK#8;yn&n%JzJ>=ZcqL1Y?@O*eK*wAK=lu-$Q;es> zen^iK11O9FfuknvHSa6L=-i8)M^>=Pj_GvyAs28!)d7#j{CRssQwJ5mmLST}Gea$k zV&@b!1`<8<8+oUt4g(Ko=TabLyXrB9em*1pJM~VCdJMfXwVb}Bh6)GuV|1kZv+4W(;-?I zTFDI%hR(FP#0oE1anif!!}t(MewK8xfQuN(e4^a?jEFY1i5JQMM~aEsH((lGMUxy1 z{>8praF9fuS_sJxG)%v6Cn1fQ5)biLd_}UtOsIVJo>Qd1NWrRUT928ya7i>jL{PFF zv;r@@P>&@&r|IWsQ?Nk71;jgdwUitf5wM0>abHoO^PVu^paeSavOL@kN-PtSQ1*T~ z!kels1Zs49an21EU%-S}(rdEZPdv^5E>!(PXoL|sJ(Ppm}+CXt~cOnR@&L4KhrNWV0zE)4yl4H0VrZIT7e zm?m#rShX3)Pog2fc@uz26f~wPcw#5u5+Ki2a?YrZF+@l!ii{;l&?Uq-YxY{WTGh_5 zjhNe_<9;lJ@KL9R@&OCL;TRrZkTN=sH6VRJ{&hGWP6atl%)6%0D6ijDCScpsV5lj>9lSj!7*JDg`o$%1pG2 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�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 z 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 Y{`{vNM(ZcozIyuT-Tmp`{@)+{A0!YkcmMzZ diff --git a/DeviceSQL/Functions/ChannelManager/DisableChannelTracing.cs b/DeviceSQL/Functions/ChannelManager/DisableChannelTracing.cs deleted file mode 100644 index f3c3174..0000000 --- a/DeviceSQL/Functions/ChannelManager/DisableChannelTracing.cs +++ /dev/null @@ -1,45 +0,0 @@ -#region Imported Types - -using DeviceSQL.IO.Channels; -using System; -using System.Data.SqlTypes; -using System.Diagnostics; -using System.Linq; - -#endregion -namespace DeviceSQL.Functions -{ - public partial class ChannelManager - { - - [Microsoft.SqlServer.Server.SqlFunction] - public static SqlBoolean ChannelManager_DisableChannelLogging (SqlString channelName) - { - try - { - var channelNameValue = channelName.Value; - var channels = DeviceSQL.Watchdog.Worker.Channels; - var channel = channels.FirstOrDefault(c => c.Name == channelName.Value); - - if (channel != null) - { - - channel.TracingEnabled = false; - - return new SqlBoolean(true); - - } - else - { - throw new ArgumentException("Channel does not exist"); - } - } - catch (Exception ex) - { - Trace.TraceError(string.Format("Error disabling channel tracing: {0}", ex.Message)); - } - return new SqlBoolean(false); - } - } - -} diff --git a/DeviceSQL/Functions/ChannelManager/EnableChannelTracing.cs b/DeviceSQL/Functions/ChannelManager/EnableChannelTracing.cs deleted file mode 100644 index f91a8c1..0000000 --- a/DeviceSQL/Functions/ChannelManager/EnableChannelTracing.cs +++ /dev/null @@ -1,45 +0,0 @@ -#region Imported Types - -using System; -using System.Data.SqlTypes; -using System.Diagnostics; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ChannelManager - { - - [Microsoft.SqlServer.Server.SqlFunction] - public static SqlBoolean ChannelManager_EnableChannelLogging(SqlString channelName) - { - try - { - var channelNameValue = channelName.Value; - var channels = DeviceSQL.Watchdog.Worker.Channels; - var channel = channels.FirstOrDefault(c => c.Name == channelName.Value); - - if (channel != null) - { - - channel.TracingEnabled = true; - - return new SqlBoolean(true); - - } - else - { - throw new ArgumentException("Channel does not exist"); - } - } - catch (Exception ex) - { - Trace.TraceError(string.Format("Error enabling channel tracing: {0}", ex.Message)); - } - return new SqlBoolean(false); - } - } - -} diff --git a/DeviceSQL/Functions/ChannelManager/GetChannels.cs b/DeviceSQL/Functions/ChannelManager/GetChannels.cs deleted file mode 100644 index 27a6a2b..0000000 --- a/DeviceSQL/Functions/ChannelManager/GetChannels.cs +++ /dev/null @@ -1,54 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System.Collections; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ChannelManager - { - [SqlFunction(FillRowMethodName = "GetChannels_FillRow", TableDefinition = "ChannelName nvarchar(512), ChannelType nvarchar(512), ReadTimeout int, WriteTimeout int, ConnectionString nvarchar(512), TracingEnabled bit")] - public static IEnumerable ChannelManager_GetChannels() - { - ArrayList resultCollection = new ArrayList(); - var channels = DeviceSQL.Watchdog.Worker.Channels; - channels.ToList().ForEach(channel => resultCollection.Add(new GetChannels_Result(channel.Name, channel.GetType().Name, channel.ReadTimeout, channel.WriteTimeout, channel.ConnectionString, channel.TracingEnabled))); - return resultCollection; - } - - internal class GetChannels_Result - { - public SqlString ChannelName; - public SqlString ChannelType; - public SqlInt32 ReadTimeout; - public SqlInt32 WriteTimeout; - public SqlString ConnectionString; - public SqlBoolean TracingEnabled; - - public GetChannels_Result(SqlString channelName, SqlString channelType, SqlInt32 readTimeout, SqlInt32 writeTimeout, SqlString connectionString, SqlBoolean tracingEnabled) - { - ChannelName = channelName; - ChannelType = channelType; - ReadTimeout = readTimeout; - WriteTimeout = writeTimeout; - ConnectionString = connectionString; - TracingEnabled = tracingEnabled; - } - } - - public static void GetChannels_FillRow(object getChannels_ResultObj, out SqlString channelName, out SqlString channelType, out SqlInt32 readTimeout, out SqlInt32 writeTimeout, out SqlString connectionString, out SqlBoolean tracingEnabled) - { - var getChannels_Result = (getChannels_ResultObj as GetChannels_Result); - channelName = getChannels_Result.ChannelName; - channelType = getChannels_Result.ChannelType; - readTimeout = getChannels_Result.ReadTimeout; - writeTimeout = getChannels_Result.WriteTimeout; - connectionString = getChannels_Result.ConnectionString; - tracingEnabled = getChannels_Result.TracingEnabled; - } - } -} diff --git a/DeviceSQL/Functions/ChannelManager/RegisterSerialPortChannel.cs b/DeviceSQL/Functions/ChannelManager/RegisterSerialPortChannel.cs deleted file mode 100644 index 9156a1f..0000000 --- a/DeviceSQL/Functions/ChannelManager/RegisterSerialPortChannel.cs +++ /dev/null @@ -1,76 +0,0 @@ -#region Imported Types - -using DeviceSQL.IO.Channels; -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Diagnostics; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ChannelManager - { - [SqlFunction] - public static SqlBoolean ChannelManager_RegisterSerialPortChannel(SqlString channelName, SqlString portName, SqlInt32 baudRate, SqlByte dataBits, SqlByte parity, SqlByte stopBits, SqlInt32 readTimeout, SqlInt32 writeTimeout) - { - try - { - var channelNameValue = channelName.Value; - var channels = DeviceSQL.Watchdog.Worker.Channels; - - if (channels.Where(serialPortChannel => serialPortChannel.Name == channelNameValue).Count() == 0) - { - if (channelNameValue.Count(c => - { - switch (c) - { - case '|': - case ';': - case ',': - return true; - default: - return false; - } - }) > 0) - { - throw new ArgumentException("Invalid channel name"); - } - - var serialPortChannel = new SerialPortChannel() - { - Name = channelNameValue, - ReadTimeout = readTimeout.Value, - WriteTimeout = writeTimeout.Value - }; - - serialPortChannel.SerialPort.PortName = portName.Value; - serialPortChannel.SerialPort.BaudRate = baudRate.Value; - serialPortChannel.SerialPort.Parity = (System.IO.Ports.Parity)Enum.Parse(typeof(System.IO.Ports.Parity), parity.Value.ToString()); - serialPortChannel.SerialPort.StopBits = (System.IO.Ports.StopBits)Enum.Parse(typeof(System.IO.Ports.StopBits), stopBits.Value.ToString()); - serialPortChannel.SerialPort.Handshake = System.IO.Ports.Handshake.None; - serialPortChannel.SerialPort.DtrEnable = false; - serialPortChannel.SerialPort.RtsEnable = false; - - serialPortChannel.SerialPort.Open(); - - channels.Add(serialPortChannel); - - return new SqlBoolean(true); - - } - else - { - throw new ArgumentException("Channel name is already registered"); - } - } - catch (Exception ex) - { - Trace.TraceError(string.Format("Error registering channel: {0}", ex.Message)); - } - return new SqlBoolean(false); - } - } -} diff --git a/DeviceSQL/Functions/ChannelManager/RegisterTcpChannel.cs b/DeviceSQL/Functions/ChannelManager/RegisterTcpChannel.cs deleted file mode 100644 index 3a2caeb..0000000 --- a/DeviceSQL/Functions/ChannelManager/RegisterTcpChannel.cs +++ /dev/null @@ -1,89 +0,0 @@ -#region Imported Types - -using DeviceSQL.IO.Channels; -using System; -using System.Data.SqlTypes; -using System.Diagnostics; -using System.Linq; -using System.Net.Sockets; - -#endregion -namespace DeviceSQL.Functions -{ - public partial class ChannelManager - { - - [Microsoft.SqlServer.Server.SqlFunction] - public static SqlBoolean ChannelManager_RegisterTcpChannel(SqlString channelName, SqlString hostName, SqlInt32 hostPort, SqlInt32 connectAttempts, SqlInt32 connectionRetryDelay, SqlInt32 readTimeout, SqlInt32 writeTimeout) - { - - var channelNameValue = channelName.Value; - var channels = DeviceSQL.Watchdog.Worker.Channels; - - if (channelNameValue.Count(c => - { - switch (c) - { - case '|': - case ';': - case ',': - return true; - default: - return false; - } - }) > 0) - { - throw new ArgumentException("Invalid channel name"); - } - - if (channels.Where(channel => channel.Name == channelNameValue).Count() == 0) - { - var tcpChannel = new TcpChannel() - { - Name = channelNameValue, - HostName = hostName.Value, - HostPort = hostPort.Value, - ConnectionAttempts = connectAttempts.Value, - ConnectionRetryDelay = connectionRetryDelay.Value - }; - - var currentConnectAttempts = 0; - - Connect: - currentConnectAttempts++; - - try - { - - tcpChannel.TcpClient.Connect(tcpChannel.HostName, tcpChannel.HostPort); - - } - catch(SocketException socketException) - { - if (currentConnectAttempts > tcpChannel.ConnectionAttempts) - { - throw socketException; - } - else - { - System.Threading.Thread.Sleep(500); - goto Connect; - } - } - - tcpChannel.ReadTimeout = readTimeout.Value; - tcpChannel.WriteTimeout = writeTimeout.Value; - - channels.Add(tcpChannel); - - return new SqlBoolean(true); - - } - else - { - throw new ArgumentException("Channel name is already registered"); - } - } - } - -} diff --git a/DeviceSQL/Functions/ChannelManager/TraceChannels.cs b/DeviceSQL/Functions/ChannelManager/TraceChannels.cs deleted file mode 100644 index 353a3f0..0000000 --- a/DeviceSQL/Functions/ChannelManager/TraceChannels.cs +++ /dev/null @@ -1,91 +0,0 @@ -#region Imported Types - -using DeviceSQL.IO.Channels; -using Microsoft.SqlServer.Server; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Data.SqlTypes; -using System.Linq; -using System.Threading; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ChannelManager - { - [SqlFunction(FillRowMethodName = "TraceChannels_FillRow", TableDefinition = "[MessageDateTimeStamp] datetime, [ChannelType] nvarchar(64), [ChannelName] nvarchar(1024), [Operation] nvarchar(32), [Sequence] int, [StartTime] datetime, [Duration] float, [Count] int, [Data] nvarchar(640)")] - public static IEnumerable ChannelManager_TraceChannels() - { - var queueLockObject = new object(); - using (var channelTraceListener = new ChannelTraceListener()) - { - var channelTraceListenerMessageQueue = new Queue(); - channelTraceListener.ChannelTraceMessageReceived += (object sender, ChannelTraceEventArgs e) => - { - lock (queueLockObject) - { - channelTraceListenerMessageQueue.Enqueue(new TraceChannels_Result(e.MessageDateTimeStamp, e.ChannelType, e.Name, e.Operation, e.Sequence, e.StartTime, e.Duration, e.Count, e.Data)); - } - }; - - while (channelTraceListener != null) - { - lock (queueLockObject) - { - while (channelTraceListenerMessageQueue.Count > 0) - { - yield return channelTraceListenerMessageQueue.Dequeue(); - } - } - TimedThreadBlocker.Wait(125); - } - - } - } - - internal class TraceChannels_Result - { - - internal SqlDateTime MessageDateTimeStamp { get; set; } - internal SqlString Name { get; set; } - internal SqlDateTime StartTime { get; set; } - internal SqlString Operation { get; set; } - internal SqlDouble Duration { get; set; } - internal SqlInt32 Sequence { get; set; } - internal SqlInt32 Count { get; set; } - internal SqlString Data { get; set; } - internal SqlString ChannelType { get; set; } - - public TraceChannels_Result(SqlDateTime messageDateTimeStamp, SqlString channelType, SqlString name, SqlString operation, SqlInt32 sequence, SqlDateTime startTime, SqlDouble duration, SqlInt32 count, SqlString data) - { - MessageDateTimeStamp = messageDateTimeStamp; - Name = name; - StartTime = startTime; - Operation = operation; - Duration = duration; - Sequence = sequence; - Count = count; - Data = data; - ChannelType = channelType; - } - } - - public static void TraceChannels_FillRow(object TraceChannels_ResultObj, out SqlDateTime messageDateTimeStamp, out SqlString channelType, out SqlString name, out SqlString operation, out SqlInt32 sequence, out SqlDateTime startTime, out SqlDouble duration, out SqlInt32 count, out SqlString data) - { - var TraceChannels_Result = (TraceChannels_ResultObj as TraceChannels_Result); - - messageDateTimeStamp = TraceChannels_Result.MessageDateTimeStamp; - name = TraceChannels_Result.Name; - startTime = TraceChannels_Result.StartTime; - operation = TraceChannels_Result.Operation; - duration = TraceChannels_Result.Duration; - sequence = TraceChannels_Result.Sequence; - count = TraceChannels_Result.Count; - data = TraceChannels_Result.Data; - channelType = TraceChannels_Result.ChannelType; - - } - } -} diff --git a/DeviceSQL/Functions/ChannelManager/UnregisterChannel.cs b/DeviceSQL/Functions/ChannelManager/UnregisterChannel.cs deleted file mode 100644 index 34d5ad7..0000000 --- a/DeviceSQL/Functions/ChannelManager/UnregisterChannel.cs +++ /dev/null @@ -1,43 +0,0 @@ -#region Imported Types - -using System; -using System.Data.SqlTypes; -using System.Diagnostics; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ChannelManager - { - [Microsoft.SqlServer.Server.SqlFunction] - public static SqlBoolean ChannelManager_UnregisterChannel(SqlString channelName) - { - try - { - var channelNameValue = channelName.Value; - var channels = DeviceSQL.Watchdog.Worker.Channels; - var channelsToRemove = channels.Where(channel => channel.Name == channelNameValue).ToList(); - channelsToRemove.ForEach((channel) => - { - try - { - channel.Dispose(); - channels.TryTake(out channel); - } - catch (Exception ex) - { - Trace.TraceError(string.Format("Error unregistering channel: {0}", ex.Message)); - } - }); - } - catch (Exception ex) - { - Trace.TraceError(string.Format("Error unregistering channel: {0}", ex.Message)); - } - return new SqlBoolean(true); - } - } - -} diff --git a/DeviceSQL/Functions/DeviceManager/GetDevices.cs b/DeviceSQL/Functions/DeviceManager/GetDevices.cs deleted file mode 100644 index 3836665..0000000 --- a/DeviceSQL/Functions/DeviceManager/GetDevices.cs +++ /dev/null @@ -1,73 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System.Collections; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class DeviceManager - { - - [SqlFunction(FillRowMethodName = "GetDevices_FillRow", TableDefinition = "DeviceName nvarchar(512), ChannelName nvarchar(512), DeviceType nvarchar(512), Address nvarchar(512), NumberOfRetries int, WaitToRetry int, RequestWriteDelay int, ResponseReadDelay int")] - public static IEnumerable DeviceManager_GetDevices() - { - ArrayList resultCollection = new ArrayList(); - var devices = DeviceSQL.Watchdog.Worker.Devices; - devices.ToList().ForEach(device => resultCollection.Add(new GetDevices_Result(device.Name, device.Transport.Channel.Name, device.GetType().Name, device.Address, device.Transport.NumberOfRetries, device.Transport.WaitToRetryMilliseconds, device.Transport.RequestWriteDelayMilliseconds, device.Transport.ResponseReadDelayMilliseconds))); - return resultCollection; - } - - internal class GetDevices_Result - { - - #region Fields - - public SqlString ChannelName; - public SqlString DeviceName; - public SqlString DeviceType; - public SqlString Address; - public SqlInt32 NumberOfRetries; - public SqlInt32 WaitToRetry; - public SqlInt32 RequestWriteDelay; - public SqlInt32 ResponseReadDelay; - - #endregion - - #region Constructor - - public GetDevices_Result(SqlString channelName, SqlString deviceName, SqlString deviceType, SqlString address, SqlInt32 numberOfRetries, SqlInt32 waitToRetry, SqlInt32 requestWriteDelay, SqlInt32 responseReadDelay) - { - ChannelName = channelName; - DeviceName = deviceName; - DeviceType = deviceType; - Address = address; - NumberOfRetries = numberOfRetries; - WaitToRetry = waitToRetry; - RequestWriteDelay = requestWriteDelay; - ResponseReadDelay = responseReadDelay; - } - - #endregion - - } - - public static void GetDevices_FillRow(object getDevices_ResultObj, out SqlString channelName, out SqlString deviceName, out SqlString deviceType, out SqlString address, out SqlInt32 numberOfRetries, out SqlInt32 waitToRetry, out SqlInt32 requestWriteDelay, out SqlInt32 responseReadDelay) - { - GetDevices_Result getDevices_Result = (getDevices_ResultObj as GetDevices_Result); - channelName = getDevices_Result.ChannelName; - deviceName = getDevices_Result.DeviceName; - deviceType = getDevices_Result.DeviceType; - address = getDevices_Result.Address; - numberOfRetries = getDevices_Result.NumberOfRetries; - waitToRetry = getDevices_Result.WaitToRetry; - requestWriteDelay = getDevices_Result.RequestWriteDelay; - responseReadDelay = getDevices_Result.ResponseReadDelay; - } - - } - -} diff --git a/DeviceSQL/Functions/DeviceManager/RegisterModbusMaster.cs b/DeviceSQL/Functions/DeviceManager/RegisterModbusMaster.cs deleted file mode 100644 index b56fea3..0000000 --- a/DeviceSQL/Functions/DeviceManager/RegisterModbusMaster.cs +++ /dev/null @@ -1,54 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Diagnostics; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class DeviceManager - { - [SqlFunction] - public static SqlBoolean DeviceManager_RegisterMODBUSMaster(SqlString channelName, SqlString deviceName, SqlInt32 unitId, SqlBoolean useExtendedAddressing, SqlInt32 numberOfRetries, SqlInt32 waitToRetry, SqlInt32 requestWriteDelay, SqlInt32 responseReadDelay) - { - try - { - var deviceNameValue = deviceName.Value; - var devices = DeviceSQL.Watchdog.Worker.Devices; - if (devices.Where(device => device.Name == deviceNameValue).Count() == 0) - { - var channelNameValue = channelName.Value; - var MODBUSMaster = new Device.MODBUS.MODBUSMaster(DeviceSQL.Watchdog.Worker.Channels.First(channel => channel.Name == channelNameValue)) - { - Name = deviceNameValue, - UnitId = Convert.ToUInt16(unitId.Value), - UseExtendedAddressing = useExtendedAddressing.Value - }; - - MODBUSMaster.Transport.NumberOfRetries = numberOfRetries.Value; - MODBUSMaster.Transport.WaitToRetryMilliseconds = waitToRetry.Value; - MODBUSMaster.Transport.RequestWriteDelayMilliseconds = requestWriteDelay.Value; - MODBUSMaster.Transport.ResponseReadDelayMilliseconds = responseReadDelay.Value; - - devices.Add(MODBUSMaster); - - return new SqlBoolean(true); - - } - else - { - throw new ArgumentException("Device name is already registered"); - } - } - catch (Exception ex) - { - Trace.TraceError(string.Format("Error registering device: {0}", ex.Message)); - } - return new SqlBoolean(false); - } - } -} diff --git a/DeviceSQL/Functions/DeviceManager/RegisterROCMaster.cs b/DeviceSQL/Functions/DeviceManager/RegisterROCMaster.cs deleted file mode 100644 index be8894d..0000000 --- a/DeviceSQL/Functions/DeviceManager/RegisterROCMaster.cs +++ /dev/null @@ -1,56 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Diagnostics; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class DeviceManager - { - [SqlFunction] - public static SqlBoolean DeviceManager_RegisterROCMaster(SqlString channelName, SqlString deviceName, SqlByte deviceAddress, SqlByte deviceGroup, SqlByte hostAddress, SqlByte hostGroup, SqlInt32 numberOfRetries, SqlInt32 waitToRetry, SqlInt32 requestWriteDelay, SqlInt32 responseReadDelay) - { - try - { - var deviceNameValue = deviceName.Value; - var devices = DeviceSQL.Watchdog.Worker.Devices; - if (devices.Where(device => device.Name == deviceNameValue).Count() == 0) - { - var channelNameValue = channelName.Value; - var rocMaster = new Device.ROC.ROCMaster(DeviceSQL.Watchdog.Worker.Channels.First(channel => channel.Name == channelNameValue)) - { - Name = deviceNameValue, - DeviceAddress = deviceAddress.Value, - DeviceGroup = deviceGroup.Value, - HostAddress = hostAddress.Value, - HostGroup = hostGroup.Value - }; - - rocMaster.Transport.NumberOfRetries = numberOfRetries.Value; - rocMaster.Transport.WaitToRetryMilliseconds = waitToRetry.Value; - rocMaster.Transport.RequestWriteDelayMilliseconds = requestWriteDelay.Value; - rocMaster.Transport.ResponseReadDelayMilliseconds = responseReadDelay.Value; - - devices.Add(rocMaster); - - return new SqlBoolean(true); - - } - else - { - throw new ArgumentException("Device name is already registered"); - } - } - catch (Exception ex) - { - Trace.TraceError(string.Format("Error registering device: {0}", ex.Message)); - } - return new SqlBoolean(false); - } - } -} diff --git a/DeviceSQL/Functions/DeviceManager/UnregisterDevice.cs b/DeviceSQL/Functions/DeviceManager/UnregisterDevice.cs deleted file mode 100644 index c2c3e14..0000000 --- a/DeviceSQL/Functions/DeviceManager/UnregisterDevice.cs +++ /dev/null @@ -1,42 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Diagnostics; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class DeviceManager - { - [SqlFunction] - public static SqlBoolean DeviceManager_UnregisterDevice(SqlString deviceName) - { - try - { - var deviceNameValue = deviceName.Value; - var devices = DeviceSQL.Watchdog.Worker.Devices; - var devicesToRemove = devices.Where(channel => channel.Name == deviceNameValue).ToList(); - devicesToRemove.ForEach((device) => - { - try - { - devices.TryTake(out device); - } - catch (Exception ex) - { - Trace.TraceError(string.Format("Error unregistering device: {0}", ex.Message)); - } - }); - } - catch (Exception ex) - { - Trace.TraceError(string.Format("Error unregistering device: {0}", ex.Message)); - } - return new SqlBoolean(true); - } - } -} diff --git a/DeviceSQL/Functions/ModbusMaster/ReadCoils.cs b/DeviceSQL/Functions/ModbusMaster/ReadCoils.cs deleted file mode 100644 index 675ecbc..0000000 --- a/DeviceSQL/Functions/ModbusMaster/ReadCoils.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Collections.Generic; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class MODBUSMaster - { - [SqlFunction] - public static Types.MODBUSMaster.MODBUSMaster_CoilRegisterArray MODBUSMaster_ReadCoils(SqlString deviceName, Types.MODBUSMaster.MODBUSMaster_CoilRegisterArray coilRegisterArray) - { - var deviceNameValue = deviceName.Value; - var coilRegisters = new List(coilRegisterArray.coilRegisters.Select(coilRegister => new Device.MODBUS.Data.CoilRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(coilRegister.Address.RelativeAddress.Value), coilRegister.Address.IsZeroBased.Value)))); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadCoilRegisters(null, ref coilRegisters, null); - return new Types.MODBUSMaster.MODBUSMaster_CoilRegisterArray() { coilRegisters = coilRegisters.Select(coilRegister => new Types.MODBUSMaster.MODBUSMaster_CoilRegister() { Address = new Types.MODBUSMaster.MODBUSMaster_MODBUSAddress { RelativeAddress = coilRegister.Address.RelativeAddress, IsZeroBased = coilRegister.Address.IsZeroBased }, Data = coilRegister.Data }).ToList() }; - } - } -} diff --git a/DeviceSQL/Functions/ModbusMaster/ReadDiscreteInputs.cs b/DeviceSQL/Functions/ModbusMaster/ReadDiscreteInputs.cs deleted file mode 100644 index 06e21eb..0000000 --- a/DeviceSQL/Functions/ModbusMaster/ReadDiscreteInputs.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Collections.Generic; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class MODBUSMaster - { - [SqlFunction] - public static Types.MODBUSMaster.MODBUSMaster_DiscreteInputRegisterArray MODBUSMaster_ReadDiscreteInputs(SqlString deviceName, Types.MODBUSMaster.MODBUSMaster_DiscreteInputRegisterArray discreteInputRegisterArray) - { - var deviceNameValue = deviceName.Value; - var discreteInputRegisters = new List(discreteInputRegisterArray.discreteInputRegisters.Select(discreteInputRegister => new Device.MODBUS.Data.DiscreteInputRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(discreteInputRegister.Address.RelativeAddress.Value), discreteInputRegister.Address.IsZeroBased.Value)))); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadDiscreteInputRegisters(null, ref discreteInputRegisters, null); - return new Types.MODBUSMaster.MODBUSMaster_DiscreteInputRegisterArray() { discreteInputRegisters = discreteInputRegisters.Select(discreteInputRegister => new Types.MODBUSMaster.MODBUSMaster_DiscreteInputRegister() { Address = new Types.MODBUSMaster.MODBUSMaster_MODBUSAddress { RelativeAddress = discreteInputRegister.Address.RelativeAddress, IsZeroBased = discreteInputRegister.Address.IsZeroBased }, Data = discreteInputRegister.Data }).ToList() }; - } - } -} \ No newline at end of file diff --git a/DeviceSQL/Functions/ModbusMaster/ReadEventArchiveRecords.cs b/DeviceSQL/Functions/ModbusMaster/ReadEventArchiveRecords.cs deleted file mode 100644 index 5e3e5e7..0000000 --- a/DeviceSQL/Functions/ModbusMaster/ReadEventArchiveRecords.cs +++ /dev/null @@ -1,22 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class MODBUSMaster - { - [SqlFunction] - public static Types.MODBUSMaster.MODBUSMaster_EventArchiveRecordArray MODBUSMaster_ReadEventArchiveRecords(SqlString deviceName, Types.MODBUSMaster.MODBUSMaster_MODBUSAddress eventArchiveAddress, SqlInt32 index) - { - var deviceNameValue = deviceName.Value; - var eventArchiveRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadEventArchiveRecord(null, new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(eventArchiveAddress.RelativeAddress.Value), eventArchiveAddress.IsZeroBased.Value), Convert.ToUInt16(index.Value), null); - return new Types.MODBUSMaster.MODBUSMaster_EventArchiveRecordArray() { eventArchiveRecords = eventArchiveRecords.Select(ear => new Types.MODBUSMaster.MODBUSMaster_EventArchiveRecord() { Index = ear.Index, Data = ear.Data }).ToList() }; - } - } -} diff --git a/DeviceSQL/Functions/ModbusMaster/ReadFloats.cs b/DeviceSQL/Functions/ModbusMaster/ReadFloats.cs deleted file mode 100644 index 1c4afd1..0000000 --- a/DeviceSQL/Functions/ModbusMaster/ReadFloats.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Collections.Generic; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class MODBUSMaster - { - [SqlFunction] - public static Types.MODBUSMaster.MODBUSMaster_FloatRegisterArray MODBUSMaster_ReadFloats(SqlString deviceName, Types.MODBUSMaster.MODBUSMaster_FloatRegisterArray floatRegisterArray) - { - var deviceNameValue = deviceName.Value; - var floatRegisters = new List(floatRegisterArray.floatRegisters.Select(floatRegister => new Device.MODBUS.Data.FloatRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(floatRegister.Address.RelativeAddress.Value), floatRegister.Address.IsZeroBased.Value), floatRegister.ByteSwap.Value, floatRegister.WordSwap.Value))); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadFloatRegisters(null, ref floatRegisters, null); - return new Types.MODBUSMaster.MODBUSMaster_FloatRegisterArray() { floatRegisters = floatRegisters.Select(floatRegister => new Types.MODBUSMaster.MODBUSMaster_FloatRegister() { Address = new Types.MODBUSMaster.MODBUSMaster_MODBUSAddress { RelativeAddress = floatRegister.Address.RelativeAddress, IsZeroBased = floatRegister.Address.IsZeroBased }, Data = floatRegister.Data }).ToList() }; - } - } -} diff --git a/DeviceSQL/Functions/ModbusMaster/ReadHistoryArchiveRecord.cs b/DeviceSQL/Functions/ModbusMaster/ReadHistoryArchiveRecord.cs deleted file mode 100644 index 6cedc48..0000000 --- a/DeviceSQL/Functions/ModbusMaster/ReadHistoryArchiveRecord.cs +++ /dev/null @@ -1,22 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class MODBUSMaster - { - [SqlFunction] - public static Types.MODBUSMaster.MODBUSMaster_HistoryArchiveRecord MODBUSMaster_ReadHistoryArchiveRecord(SqlString deviceName, Types.MODBUSMaster.MODBUSMaster_MODBUSAddress historyArchiveAddress, SqlInt32 index, SqlByte recordSize) - { - var deviceNameValue = deviceName.Value; - var historyArchiveRecord = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadHistoryArchiveRecord(null, new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(historyArchiveAddress.RelativeAddress.Value), historyArchiveAddress.IsZeroBased.Value), Convert.ToUInt16(index.Value), recordSize.Value, null); - return new Types.MODBUSMaster.MODBUSMaster_HistoryArchiveRecord() { Index = historyArchiveRecord.Index, Data = historyArchiveRecord.Data }; - } - } -} diff --git a/DeviceSQL/Functions/ModbusMaster/ReadHoldings.cs b/DeviceSQL/Functions/ModbusMaster/ReadHoldings.cs deleted file mode 100644 index d758aca..0000000 --- a/DeviceSQL/Functions/ModbusMaster/ReadHoldings.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Collections.Generic; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class MODBUSMaster - { - [SqlFunction] - public static Types.MODBUSMaster.MODBUSMaster_HoldingRegisterArray MODBUSMaster_ReadHoldings(SqlString deviceName, Types.MODBUSMaster.MODBUSMaster_HoldingRegisterArray holdingRegisterArray) - { - var deviceNameValue = deviceName.Value; - var holdingRegisters = new List(holdingRegisterArray.holdingRegisters.Select(holdingRegister => new Device.MODBUS.Data.HoldingRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(holdingRegister.Address.RelativeAddress.Value), holdingRegister.Address.IsZeroBased.Value), holdingRegister.ByteSwap.Value))); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadHoldingRegisters(null, ref holdingRegisters, null); - return new Types.MODBUSMaster.MODBUSMaster_HoldingRegisterArray() { holdingRegisters = holdingRegisters.Select(holdingRegister => new Types.MODBUSMaster.MODBUSMaster_HoldingRegister() { Address = new Types.MODBUSMaster.MODBUSMaster_MODBUSAddress { RelativeAddress = holdingRegister.Address.RelativeAddress, IsZeroBased = holdingRegister.Address.IsZeroBased }, ByteSwap = holdingRegister.ByteSwap, Data = holdingRegister.Data }).ToList() }; - } - } -} diff --git a/DeviceSQL/Functions/ModbusMaster/ReadInputs.cs b/DeviceSQL/Functions/ModbusMaster/ReadInputs.cs deleted file mode 100644 index 3bdb884..0000000 --- a/DeviceSQL/Functions/ModbusMaster/ReadInputs.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Collections.Generic; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class MODBUSMaster - { - [SqlFunction] - public static Types.MODBUSMaster.MODBUSMaster_InputRegisterArray MODBUSMaster_ReadInputs(SqlString deviceName, Types.MODBUSMaster.MODBUSMaster_InputRegisterArray inputRegisterArray) - { - var deviceNameValue = deviceName.Value; - var inputRegisters = new List(inputRegisterArray.inputRegisters.Select(inputRegister => new Device.MODBUS.Data.InputRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(inputRegister.Address.RelativeAddress.Value), inputRegister.Address.IsZeroBased.Value), inputRegister.ByteSwap.Value))); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadInputRegisters(null, ref inputRegisters, null); - return new Types.MODBUSMaster.MODBUSMaster_InputRegisterArray() { inputRegisters = inputRegisters.Select(inputRegister => new Types.MODBUSMaster.MODBUSMaster_InputRegister() { Address = new Types.MODBUSMaster.MODBUSMaster_MODBUSAddress { RelativeAddress = inputRegister.Address.RelativeAddress, IsZeroBased = inputRegister.Address.IsZeroBased }, ByteSwap = inputRegister.ByteSwap, Data = inputRegister.Data }).ToList() }; - } - } -} diff --git a/DeviceSQL/Functions/ModbusMaster/ReadLongs.cs b/DeviceSQL/Functions/ModbusMaster/ReadLongs.cs deleted file mode 100644 index e3c1f46..0000000 --- a/DeviceSQL/Functions/ModbusMaster/ReadLongs.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Collections.Generic; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class MODBUSMaster - { - [SqlFunction] - public static Types.MODBUSMaster.MODBUSMaster_LongRegisterArray MODBUSMaster_ReadLongs(SqlString deviceName, Types.MODBUSMaster.MODBUSMaster_LongRegisterArray longRegisterArray) - { - var deviceNameValue = deviceName.Value; - var longRegisters = new List(longRegisterArray.longRegisters.Select(longRegister => new Device.MODBUS.Data.LongRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(longRegister.Address.RelativeAddress.Value), longRegister.Address.IsZeroBased.Value), longRegister.ByteSwap.Value, longRegister.WordSwap.Value))); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadLongRegisters(null, ref longRegisters, null); - return new Types.MODBUSMaster.MODBUSMaster_LongRegisterArray() { longRegisters = longRegisters.Select(floatRegister => new Types.MODBUSMaster.MODBUSMaster_LongRegister() { Address = new Types.MODBUSMaster.MODBUSMaster_MODBUSAddress { RelativeAddress = floatRegister.Address.RelativeAddress, IsZeroBased = floatRegister.Address.IsZeroBased }, Data = floatRegister.Data }).ToList() }; - } - } -} diff --git a/DeviceSQL/Functions/ModbusMaster/ReadShorts.cs b/DeviceSQL/Functions/ModbusMaster/ReadShorts.cs deleted file mode 100644 index fe31434..0000000 --- a/DeviceSQL/Functions/ModbusMaster/ReadShorts.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Collections.Generic; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class MODBUSMaster - { - [SqlFunction] - public static Types.MODBUSMaster.MODBUSMaster_ShortRegisterArray MODBUSMaster_ReadShorts(SqlString deviceName, Types.MODBUSMaster.MODBUSMaster_ShortRegisterArray shortRegisterArray) - { - var deviceNameValue = deviceName.Value; - var shortRegisters = new List(shortRegisterArray.shortRegisters.Select(longRegister => new Device.MODBUS.Data.ShortRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(longRegister.Address.RelativeAddress.Value), longRegister.Address.IsZeroBased.Value), longRegister.ByteSwap.Value))); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadShortRegisters(null, ref shortRegisters, null); - return new Types.MODBUSMaster.MODBUSMaster_ShortRegisterArray() { shortRegisters = shortRegisters.Select(shortRegister => new Types.MODBUSMaster.MODBUSMaster_ShortRegister() { Address = new Types.MODBUSMaster.MODBUSMaster_MODBUSAddress { RelativeAddress = shortRegister.Address.RelativeAddress, IsZeroBased = shortRegister.Address.IsZeroBased }, Data = shortRegister.Data }).ToList() }; - } - } -} diff --git a/DeviceSQL/Functions/ModbusMaster/ReadString.cs b/DeviceSQL/Functions/ModbusMaster/ReadString.cs deleted file mode 100644 index 6c28c57..0000000 --- a/DeviceSQL/Functions/ModbusMaster/ReadString.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class MODBUSMaster - { - [SqlFunction] - public static Types.MODBUSMaster.MODBUSMaster_StringRegister MODBUSMaster_ReadString(SqlString deviceName, Types.MODBUSMaster.MODBUSMaster_StringRegister stringRegister) - { - var deviceNameValue = deviceName.Value; - var stringRegisterValue = new Device.MODBUS.Data.StringRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(stringRegister.Address.RelativeAddress.Value), stringRegister.Address.IsZeroBased.Value), stringRegister.Length.Value); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadStringRegister(null, null, ref stringRegisterValue); - stringRegister.Data = stringRegisterValue.Data; - return stringRegister; - } - } -} diff --git a/DeviceSQL/Functions/ModbusMaster/WriteBoolean.cs b/DeviceSQL/Functions/ModbusMaster/WriteBoolean.cs deleted file mode 100644 index d7edbbc..0000000 --- a/DeviceSQL/Functions/ModbusMaster/WriteBoolean.cs +++ /dev/null @@ -1,23 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class MODBUSMaster - { - [SqlFunction] - public static SqlBoolean MODBUSMaster_WriteBoolean(SqlString deviceName, Types.MODBUSMaster.MODBUSMaster_BooleanRegister booleanRegister) - { - var deviceNameValue = deviceName.Value; - var booleanRegisterRaw = new Device.MODBUS.Data.BooleanRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(booleanRegister.Address.RelativeAddress.Value), booleanRegister.Address.IsZeroBased.Value)); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).WriteBooleanRegister(null, booleanRegisterRaw, null); - return true; - } - } -} diff --git a/DeviceSQL/Functions/ModbusMaster/WriteFloats.cs b/DeviceSQL/Functions/ModbusMaster/WriteFloats.cs deleted file mode 100644 index 2b951f3..0000000 --- a/DeviceSQL/Functions/ModbusMaster/WriteFloats.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Collections.Generic; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class MODBUSMaster - { - [SqlFunction] - public static SqlBoolean MODBUSMaster_WriteFloats(SqlString deviceName, Types.MODBUSMaster.MODBUSMaster_FloatRegisterArray floatRegisterArray) - { - var deviceNameValue = deviceName.Value; - var floatRegisters = new List(floatRegisterArray.floatRegisters.Select(floatRegister => new Device.MODBUS.Data.FloatRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(floatRegister.Address.RelativeAddress.Value), floatRegister.Address.IsZeroBased.Value), floatRegister.ByteSwap.Value, floatRegister.WordSwap.Value))); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).WriteFloatRegisters(null, floatRegisters, null); - return true; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/ClearAuditLogEventFlags.cs b/DeviceSQL/Functions/ROCMaster/ClearAuditLogEventFlags.cs deleted file mode 100644 index a798040..0000000 --- a/DeviceSQL/Functions/ROCMaster/ClearAuditLogEventFlags.cs +++ /dev/null @@ -1,21 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static int ROCMaster_ClearAuditLogEventFlags(SqlString deviceName, byte numberOfAuditLogRecordsToClear, int startingAuditLogPointer) - { - var deviceNameValue = deviceName.Value; - return (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ClearAuditLogEventFlags(null, null, null, null, numberOfAuditLogRecordsToClear, Convert.ToUInt16(startingAuditLogPointer)); - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetAlarms.cs b/DeviceSQL/Functions/ROCMaster/GetAlarms.cs deleted file mode 100644 index 8d60bd1..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetAlarms.cs +++ /dev/null @@ -1,22 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static Types.ROCMaster.ROCMaster_AlarmRecordArray ROCMaster_GetAlarms(SqlString deviceName, byte count, int startIndex) - { - var deviceNameValue = deviceName.Value; - var alarmsRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetAlarms(null, null, null, null, count, Convert.ToUInt16(startIndex)); - return new Types.ROCMaster.ROCMaster_AlarmRecordArray() { alarmRecords = alarmsRecords.Select(a => new Types.ROCMaster.ROCMaster_AlarmRecord() { data = a.data, Index = a.Index }).ToList() }; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetArchiveInfo.cs b/DeviceSQL/Functions/ROCMaster/GetArchiveInfo.cs deleted file mode 100644 index 4790a17..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetArchiveInfo.cs +++ /dev/null @@ -1,22 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static Types.ROCMaster.ROCMaster_ArchiveInformation ROCMaster_GetArchiveInfo(SqlString deviceName) - { - var deviceNameValue = deviceName.Value; - var archiveInfo = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetArchiveInfo(null, null, null, null); - return new Types.ROCMaster.ROCMaster_ArchiveInformation() { Data = archiveInfo.data }; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetAuditLogRecords.cs b/DeviceSQL/Functions/ROCMaster/GetAuditLogRecords.cs deleted file mode 100644 index abbceaa..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetAuditLogRecords.cs +++ /dev/null @@ -1,22 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static Types.ROCMaster.ROCMaster_AuditLogRecordArray ROCMaster_GetAuditLogRecords(SqlString deviceName, byte count, int startIndex) - { - var deviceNameValue = deviceName.Value; - var auditLogRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetAuditLogRecords(null, null, null, null, count, Convert.ToUInt16(startIndex)); - return new Types.ROCMaster.ROCMaster_AuditLogRecordArray() { auditLogRecords = auditLogRecords.Select(e => new Types.ROCMaster.ROCMaster_AuditLogRecord() { Data = e.data, Index = e.Index }).ToList() }; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetCurrentROCPlusAlarmIndex.cs b/DeviceSQL/Functions/ROCMaster/GetCurrentROCPlusAlarmIndex.cs deleted file mode 100644 index 874e0f8..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetCurrentROCPlusAlarmIndex.cs +++ /dev/null @@ -1,21 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static int ROCMaster_GetCurrentROCPlusAlarmIndex(SqlString deviceName) - { - var deviceNameValue = deviceName.Value; - return (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetCurrentROCPlusAlarmIndex(null, null, null, null); - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetCurrentROCPlusEventIndex.cs b/DeviceSQL/Functions/ROCMaster/GetCurrentROCPlusEventIndex.cs deleted file mode 100644 index 5c24221..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetCurrentROCPlusEventIndex.cs +++ /dev/null @@ -1,21 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static int ROCMaster_GetCurrentROCPlusEventIndex(SqlString deviceName) - { - var deviceNameValue = deviceName.Value; - return (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetCurrentROCPlusEventIndex(null, null, null, null); - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetCurrentROCPlusHistorySegmentIndex.cs b/DeviceSQL/Functions/ROCMaster/GetCurrentROCPlusHistorySegmentIndex.cs deleted file mode 100644 index a562308..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetCurrentROCPlusHistorySegmentIndex.cs +++ /dev/null @@ -1,21 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static int ROCMaster_GetCurrentROCPlusHistorySegmentIndex(SqlString deviceName, byte historySegment, byte historyType) - { - var deviceNameValue = deviceName.Value; - return (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetCurrentROCPlusHistorySegmentIndex(null, null, null, null, historySegment, historyType); - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetDoubleValue.cs b/DeviceSQL/Functions/ROCMaster/GetDoubleValue.cs deleted file mode 100644 index 66aa649..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetDoubleValue.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlDouble ROCMaster_GetDoubleValue(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber) - { - var deviceNameValue = deviceName.Value; - var DoubleParameter = new DoubleParameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref DoubleParameter); - return DoubleParameter.NullableValue.HasValue ? DoubleParameter.Value : SqlDouble.Null; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetEvents.cs b/DeviceSQL/Functions/ROCMaster/GetEvents.cs deleted file mode 100644 index 74a94c1..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetEvents.cs +++ /dev/null @@ -1,22 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static Types.ROCMaster.ROCMaster_EventRecordArray ROCMaster_GetEvents(SqlString deviceName, byte count, int startIndex) - { - var deviceNameValue = deviceName.Value; - var eventRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetEvents(null, null, null, null, count, Convert.ToUInt16(startIndex)); - return new Types.ROCMaster.ROCMaster_EventRecordArray() { eventRecords = eventRecords.Select(e => new Types.ROCMaster.ROCMaster_EventRecord() { Data = e.data, Index = e.Index }).ToList() }; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetFloatValue.cs b/DeviceSQL/Functions/ROCMaster/GetFloatValue.cs deleted file mode 100644 index 0637600..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetFloatValue.cs +++ /dev/null @@ -1,25 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlSingle ROCMaster_GetFloatValue(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber) - { - var deviceNameValue = deviceName.Value; - var flpParameter = new FlpParameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref flpParameter); - return flpParameter.NullableValue.HasValue ? flpParameter.Value : SqlSingle.Null; - } - - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetFstInformation.cs b/DeviceSQL/Functions/ROCMaster/GetFstInformation.cs deleted file mode 100644 index 5f50b43..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetFstInformation.cs +++ /dev/null @@ -1,46 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System; -using System.Collections.Generic; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static Types.ROCMaster.ROCMaster_FSTInformation ROCMaster_GetFstInformation(SqlString deviceName, SqlByte fstNumber) - { - var deviceNameValue = deviceName.Value; - var rocMaster = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster); - - var fstHeaderInfo = rocMaster.GetFstHeaderInfo(null, null, null, null, fstNumber.Value); - var fstSizeParameter = new UInt16Parameter(new Tlp(16, fstNumber.Value, 25)); - - rocMaster.ReadParameter(null, null, null, null, ref fstSizeParameter); - - var fstSize = fstSizeParameter.Value; - var codeBytes = new List(); - - while (fstSize > codeBytes.Count) - { - codeBytes.AddRange(rocMaster.GetFstCodeChunk(null, null, null, null, 0, (byte)codeBytes.Count, (fstSize - codeBytes.Count) > 240 ? (byte)240 : (byte)(fstSize - codeBytes.Count)).CodeBytes); - } - - return new Types.ROCMaster.ROCMaster_FSTInformation() - { - FSTNumber = fstNumber.Value, - Version = fstHeaderInfo.Version, - Description = fstHeaderInfo.Description, - FSTCode = codeBytes.ToArray() - }; - - } - - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetHistory.cs b/DeviceSQL/Functions/ROCMaster/GetHistory.cs deleted file mode 100644 index 8f0b172..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetHistory.cs +++ /dev/null @@ -1,22 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static Types.ROCMaster.ROCMaster_HistoryRecordArray ROCMaster_GetHistory(SqlString deviceName, byte historicalRamArea, byte historyPointNumber, byte count, int startIndex) - { - var deviceNameValue = deviceName.Value; - var historyRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetHistory(null, null, null, null, historicalRamArea, historyPointNumber, count, Convert.ToUInt16(startIndex)); - return new Types.ROCMaster.ROCMaster_HistoryRecordArray() { historyRecords = historyRecords.Select(h => new Types.ROCMaster.ROCMaster_HistoryRecord() { HistorySegment = h.HistorySegment, HistoryPointNumber = h.HistoryPointNumber, Index = h.Index, Value = h.Value }).ToList() }; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetInt16Value.cs b/DeviceSQL/Functions/ROCMaster/GetInt16Value.cs deleted file mode 100644 index 403a2d8..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetInt16Value.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlInt16 ROCMaster_GetInt16Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber) - { - var deviceNameValue = deviceName.Value; - var int16Parameter = new Int16Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref int16Parameter); - return int16Parameter.Value; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetInt32Value.cs b/DeviceSQL/Functions/ROCMaster/GetInt32Value.cs deleted file mode 100644 index 6106d85..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetInt32Value.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlInt32 ROCMaster_GetInt32Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber) - { - var deviceNameValue = deviceName.Value; - var int32Parameter = new Int32Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref int32Parameter); - return int32Parameter.Value; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetInt8Value.cs b/DeviceSQL/Functions/ROCMaster/GetInt8Value.cs deleted file mode 100644 index 4aec4aa..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetInt8Value.cs +++ /dev/null @@ -1,23 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlInt16 ROCMaster_GetInt8Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber) - { - var deviceNameValue = deviceName.Value; - var int8Parameter = new Int8Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref int8Parameter); - return int8Parameter.Value; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetMinutelyHistory.cs b/DeviceSQL/Functions/ROCMaster/GetMinutelyHistory.cs deleted file mode 100644 index d59020f..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetMinutelyHistory.cs +++ /dev/null @@ -1,21 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static Types.ROCMaster.ROCMaster_HistoryRecordArray ROCMaster_GetMinutelyHistory(SqlString deviceName, byte historyPointNumber) - { - var deviceNameValue = deviceName.Value; - var historyRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetMinutelyHistory(null, null, null, null, historyPointNumber); - return new Types.ROCMaster.ROCMaster_HistoryRecordArray() { historyRecords = historyRecords.Select(h => new Types.ROCMaster.ROCMaster_HistoryRecord() { HistoryPointNumber = h.HistoryPointNumber, Index = h.Index, Value = h.Value }).ToList() }; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetROCPlusAlarms.cs b/DeviceSQL/Functions/ROCMaster/GetROCPlusAlarms.cs deleted file mode 100644 index 068bf69..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetROCPlusAlarms.cs +++ /dev/null @@ -1,22 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static Types.ROCMaster.ROCMaster_ROCPlusAlarmRecordArray ROCMaster_GetROCPlusAlarms(SqlString deviceName, byte count, int startIndex) - { - var deviceNameValue = deviceName.Value; - var rocPlusAlarmRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetROCPlusAlarms(null, null, null, null, count, Convert.ToUInt16(startIndex)); - return new Types.ROCMaster.ROCMaster_ROCPlusAlarmRecordArray() { rocPlusAlarmRecords = rocPlusAlarmRecords.Select(a => new Types.ROCMaster.ROCMaster_ROCPlusAlarmRecord() { Data = a.data, Index = a.Index }).ToList() }; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetROCPlusConfiguredHistoryPoints.cs b/DeviceSQL/Functions/ROCMaster/GetROCPlusConfiguredHistoryPoints.cs deleted file mode 100644 index eba61f8..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetROCPlusConfiguredHistoryPoints.cs +++ /dev/null @@ -1,21 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static Types.ROCMaster.ROCMaster_ROCPlusHistoryPointArray ROCMaster_GetROCPlusConfiguredHistoryPoints(SqlString deviceName, byte historySegment) - { - var deviceNameValue = deviceName.Value; - var configuredHistoryPoints = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetROCPlusConfiguredHistoryPoints(null, null, null, null, historySegment); - return new Types.ROCMaster.ROCMaster_ROCPlusHistoryPointArray() { historyPoints = configuredHistoryPoints }; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetROCPlusEvents.cs b/DeviceSQL/Functions/ROCMaster/GetROCPlusEvents.cs deleted file mode 100644 index ab6705a..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetROCPlusEvents.cs +++ /dev/null @@ -1,22 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static Types.ROCMaster.ROCMaster_ROCPlusEventRecordArray ROCMaster_GetROCPlusEvents(SqlString deviceName, byte count, int startIndex) - { - var deviceNameValue = deviceName.Value; - var rocPlusEventRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetROCPlusEvents(null, null, null, null, count, Convert.ToUInt16(startIndex)); - return new Types.ROCMaster.ROCMaster_ROCPlusEventRecordArray() { rocPlusEventRecords = rocPlusEventRecords.Select(e => new Types.ROCMaster.ROCMaster_ROCPlusEventRecord() { Data = e.data, Index = e.Index }).ToList() }; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetROCPlusHistory.cs b/DeviceSQL/Functions/ROCMaster/GetROCPlusHistory.cs deleted file mode 100644 index 2344d10..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetROCPlusHistory.cs +++ /dev/null @@ -1,22 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static Types.ROCMaster.ROCMaster_ROCPlusHistoryRecordArray ROCMaster_GetROCPlusHistory(SqlString deviceName, byte historySegment, int historyIndex, byte historyType, byte startingHistoryPoint, byte numberOfHistoryPoints, byte numberOfTimePeriods) - { - var deviceNameValue = deviceName.Value; - var rocPlusHistoryRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetROCPlusHistory(null, null, null, null, historySegment, Convert.ToUInt16(historyIndex), historyType, startingHistoryPoint, numberOfHistoryPoints, numberOfTimePeriods); - return new Types.ROCMaster.ROCMaster_ROCPlusHistoryRecordArray() { rocPlusHistoryRecords = rocPlusHistoryRecords.Select(h => new Types.ROCMaster.ROCMaster_ROCPlusHistoryRecord() { HistorySegment = h.HistorySegment, HistoryPointNumber = h.HistoryPointNumber, Index = h.Index, Value = h.Value }).ToList() }; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetROCPlusHistoryByHistoryPointArray.cs b/DeviceSQL/Functions/ROCMaster/GetROCPlusHistoryByHistoryPointArray.cs deleted file mode 100644 index b57c984..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetROCPlusHistoryByHistoryPointArray.cs +++ /dev/null @@ -1,22 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static Types.ROCMaster.ROCMaster_ROCPlusHistoryRecordArray ROCMaster_GetROCPlusHistoryByHistoryPointArray(SqlString deviceName, byte historySegment, int historyIndex, byte historyType, byte startingHistoryPoint, bool requestTimeStamps, byte numberOfHistoryPoints, Types.ROCMaster.ROCMaster_ROCPlusHistoryPointArray requestedHistoryPoints, byte numberOfTimePeriods) - { - var deviceNameValue = deviceName.Value; - var rocPlusHistoryRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetROCPlusHistory(null, null, null, null, historySegment, Convert.ToUInt16(historyIndex), historyType, requestTimeStamps, requestedHistoryPoints.historyPoints, numberOfTimePeriods); - return new Types.ROCMaster.ROCMaster_ROCPlusHistoryRecordArray() { rocPlusHistoryRecords = rocPlusHistoryRecords.Select(h => new Types.ROCMaster.ROCMaster_ROCPlusHistoryRecord() { HistorySegment = h.HistorySegment, HistoryPointNumber = h.HistoryPointNumber, Index = h.Index, Value = h.Value }).ToList() }; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetRealTimeClockValue.cs b/DeviceSQL/Functions/ROCMaster/GetRealTimeClockValue.cs deleted file mode 100644 index 9619e71..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetRealTimeClockValue.cs +++ /dev/null @@ -1,20 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlDateTime ROCMaster_GetRealTimeClockValue(SqlString deviceName) - { - var deviceNameValue = deviceName.Value; - return new SqlDateTime((DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetRealTimeClockValue(null, null, null, null)); - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetRealTimeClockValueWithCentury.cs b/DeviceSQL/Functions/ROCMaster/GetRealTimeClockValueWithCentury.cs deleted file mode 100644 index 65125ec..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetRealTimeClockValueWithCentury.cs +++ /dev/null @@ -1,21 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlDateTime ROCMaster_GetRealTimeClockValueWithCentury(SqlString deviceName, SqlInt32 century) - { - var deviceNameValue = deviceName.Value; - return new SqlDateTime((DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetRealTimeClockValue(null, null, null, null, Convert.ToUInt16(century.Value))); - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetStringValue.cs b/DeviceSQL/Functions/ROCMaster/GetStringValue.cs deleted file mode 100644 index 338c658..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetStringValue.cs +++ /dev/null @@ -1,46 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlString ROCMaster_GetStringValue(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlByte stringLength) - { - var deviceNameValue = deviceName.Value; - - if (10 >= stringLength) - { - var ac10Parameter = new Ac10Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref ac10Parameter); - return ac10Parameter.Value; - } - else if (12 >= stringLength) - { - var ac12Parameter = new Ac12Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref ac12Parameter); - return ac12Parameter.Value; - } - else if (20 >= stringLength) - { - var ac20Parameter = new Ac20Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref ac20Parameter); - return ac20Parameter.Value; - } - else - { - var ac30Parameter = new Ac30Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref ac30Parameter); - return ac30Parameter.Value; - } - - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetTimeValue.cs b/DeviceSQL/Functions/ROCMaster/GetTimeValue.cs deleted file mode 100644 index 0f44e4d..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetTimeValue.cs +++ /dev/null @@ -1,22 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlDateTime ROCMaster_GetTimeValue(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber) - { - var deviceNameValue = deviceName.Value; - var timeParameter = new Device.ROC.Data.TimeParameter(new Device.ROC.Data.Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref timeParameter); - return timeParameter.Value; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetUInt16Value.cs b/DeviceSQL/Functions/ROCMaster/GetUInt16Value.cs deleted file mode 100644 index e885d9b..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetUInt16Value.cs +++ /dev/null @@ -1,23 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlInt32 ROCMaster_GetUInt16Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber) - { - var deviceNameValue = deviceName.Value; - var uInt16Parameter = new UInt16Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref uInt16Parameter); - return uInt16Parameter.Value; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetUInt32Value.cs b/DeviceSQL/Functions/ROCMaster/GetUInt32Value.cs deleted file mode 100644 index 1f2887b..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetUInt32Value.cs +++ /dev/null @@ -1,23 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlInt64 ROCMaster_GetUInt32Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber) - { - var deviceNameValue = deviceName.Value; - var uInt32Parameter = new UInt32Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref uInt32Parameter); - return uInt32Parameter.Value; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/GetUInt8Value.cs b/DeviceSQL/Functions/ROCMaster/GetUInt8Value.cs deleted file mode 100644 index 61eaf5a..0000000 --- a/DeviceSQL/Functions/ROCMaster/GetUInt8Value.cs +++ /dev/null @@ -1,23 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlByte ROCMaster_GetUInt8Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber) - { - var deviceNameValue = deviceName.Value; - var uInt8Parameter = new UInt8Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref uInt8Parameter); - return uInt8Parameter.Value; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/ReadParameters.cs b/DeviceSQL/Functions/ROCMaster/ReadParameters.cs deleted file mode 100644 index 75a77b3..0000000 --- a/DeviceSQL/Functions/ROCMaster/ReadParameters.cs +++ /dev/null @@ -1,101 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System.Collections.Generic; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static Types.ROCMaster.ROCMaster_ParameterArray ROCMaster_ReadParameters(SqlString deviceName, Types.ROCMaster.ROCMaster_ParameterArray parameterArray) - { - var deviceNameValue = deviceName.Value; - var parameters = new List(); - var length = parameterArray.Length; - - for (var parameterIndex = 0; length > parameterIndex; parameterIndex++) - { - var parameter = parameterArray.GetParameter(parameterIndex); - - switch (parameter.RawType) - { - case ParameterType.AC3: - parameters.Add(new Ac3Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.AC7: - parameters.Add(new Ac7Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.AC10: - parameters.Add(new Ac10Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.AC12: - parameters.Add(new Ac12Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.AC20: - parameters.Add(new Ac20Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.AC30: - parameters.Add(new Ac30Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.AC40: - parameters.Add(new Ac40Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.BIN: - parameters.Add(new BinParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.FL: - parameters.Add(new FlpParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.DOUBLE: - parameters.Add(new DoubleParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.INT16: - parameters.Add(new Int16Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.INT32: - parameters.Add(new Int32Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.INT8: - parameters.Add(new Int8Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.TLP: - parameters.Add(new TlpParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.UINT16: - parameters.Add(new UInt16Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.UINT32: - parameters.Add(new UInt32Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.TIME: - parameters.Add(new TimeParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.UINT8: - parameters.Add(new UInt8Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - } - - } - - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameters(null, null, null, null, ref parameters); - - - for (var parameterIndex = 0; length > parameterIndex; parameterIndex++) - { - var parameter = parameterArray[parameterIndex]; - parameter.RawValue = parameters[parameterIndex].Data; - parameterArray[parameterIndex] = parameter; - } - - return parameterArray; - - } - - } -} diff --git a/DeviceSQL/Functions/ROCMaster/SetFloatValue.cs b/DeviceSQL/Functions/ROCMaster/SetFloatValue.cs deleted file mode 100644 index 1f14278..0000000 --- a/DeviceSQL/Functions/ROCMaster/SetFloatValue.cs +++ /dev/null @@ -1,23 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlBoolean ROCMaster_SetFloatValue(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlSingle value) - { - var deviceNameValue = deviceName.Value; - var flpParameter = new FlpParameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = value.Value }; - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, flpParameter); - return true; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/SetInt16Value.cs b/DeviceSQL/Functions/ROCMaster/SetInt16Value.cs deleted file mode 100644 index 215410d..0000000 --- a/DeviceSQL/Functions/ROCMaster/SetInt16Value.cs +++ /dev/null @@ -1,23 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlBoolean ROCMaster_SetInt16Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlInt16 value) - { - var deviceNameValue = deviceName.Value; - var int16Parameter = new Int16Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = value.Value }; - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, int16Parameter); - return true; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/SetInt32Value.cs b/DeviceSQL/Functions/ROCMaster/SetInt32Value.cs deleted file mode 100644 index aa27474..0000000 --- a/DeviceSQL/Functions/ROCMaster/SetInt32Value.cs +++ /dev/null @@ -1,23 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlBoolean ROCMaster_SetInt32Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlInt32 value) - { - var deviceNameValue = deviceName.Value; - var int32Parameter = new Int32Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = value.Value }; - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, int32Parameter); - return true; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/SetInt8Value.cs b/DeviceSQL/Functions/ROCMaster/SetInt8Value.cs deleted file mode 100644 index 9fc8c50..0000000 --- a/DeviceSQL/Functions/ROCMaster/SetInt8Value.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlBoolean ROCMaster_SetInt8Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlInt16 value) - { - var deviceNameValue = deviceName.Value; - var int8Parameter = new Int8Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = Convert.ToSByte(value.Value) }; - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as DeviceSQL.Device.ROC.ROCMaster).WriteParameter(null, null, null, null, int8Parameter); - return true; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/SetOperatorIdentification.cs b/DeviceSQL/Functions/ROCMaster/SetOperatorIdentification.cs deleted file mode 100644 index f71784c..0000000 --- a/DeviceSQL/Functions/ROCMaster/SetOperatorIdentification.cs +++ /dev/null @@ -1,22 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlBoolean ROCMaster_SetOperatorIdentification(SqlString deviceName, SqlString operatorId, SqlInt32 password) - { - var deviceNameValue = deviceName.Value; - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).SetOperatorIdentification(null, null, null, null, operatorId.IsNull ? "LOI" : operatorId.Value, Convert.ToUInt16(password.IsNull ? 1000 : password.Value)); - return true; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/SetRealTimeClock.cs b/DeviceSQL/Functions/ROCMaster/SetRealTimeClock.cs deleted file mode 100644 index bbb2759..0000000 --- a/DeviceSQL/Functions/ROCMaster/SetRealTimeClock.cs +++ /dev/null @@ -1,21 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlBoolean ROCMaster_SetRealTimeClock(SqlString deviceName, SqlDateTime dateTime) - { - var deviceNameValue = deviceName.Value; - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).SetRealTimeClock(null, null, null, null, dateTime.Value); - return true; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/SetStringValue.cs b/DeviceSQL/Functions/ROCMaster/SetStringValue.cs deleted file mode 100644 index f4b524e..0000000 --- a/DeviceSQL/Functions/ROCMaster/SetStringValue.cs +++ /dev/null @@ -1,47 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlBoolean ROCMaster_SetStringValue(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlByte stringLength, SqlString value) - { - var deviceNameValue = deviceName.Value; - - if (10 >= stringLength) - { - var ac10Parameter = new Ac10Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = value.Value }; - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, ac10Parameter); - return true; - } - else if (12 >= stringLength) - { - var ac12Parameter = new Ac12Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = value.Value }; - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, ac12Parameter); - return true; - } - else if (20 >= stringLength) - { - var ac20Parameter = new Ac20Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = value.Value }; - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, ac20Parameter); - return true; - } - else - { - var ac30Parameter = new Ac30Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = value.Value }; - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, ac30Parameter); - return true; - } - - } - - } -} diff --git a/DeviceSQL/Functions/ROCMaster/SetTimeValue.cs b/DeviceSQL/Functions/ROCMaster/SetTimeValue.cs deleted file mode 100644 index 0ce8543..0000000 --- a/DeviceSQL/Functions/ROCMaster/SetTimeValue.cs +++ /dev/null @@ -1,23 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlBoolean ROCMaster_SetTimeValue(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlDateTime value) - { - var deviceNameValue = deviceName.Value; - var timeParameter = new TimeParameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = value.Value }; - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, timeParameter); - return true; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/SetUInt16Value.cs b/DeviceSQL/Functions/ROCMaster/SetUInt16Value.cs deleted file mode 100644 index 72213ea..0000000 --- a/DeviceSQL/Functions/ROCMaster/SetUInt16Value.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlBoolean ROCMaster_SetUInt16Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlInt32 value) - { - var deviceNameValue = deviceName.Value; - var uInt16Parameter = new UInt16Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = Convert.ToUInt16(value.Value) }; - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref uInt16Parameter); - return true; - } - } -} \ No newline at end of file diff --git a/DeviceSQL/Functions/ROCMaster/SetUInt32Value.cs b/DeviceSQL/Functions/ROCMaster/SetUInt32Value.cs deleted file mode 100644 index f4ec445..0000000 --- a/DeviceSQL/Functions/ROCMaster/SetUInt32Value.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlBoolean ROCMaster_SetUInt32Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlInt64 value) - { - var deviceNameValue = deviceName.Value; - var uInt32Parameter = new UInt32Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = Convert.ToUInt32(value.Value) }; - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, uInt32Parameter); - return true; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/SetUInt8Value.cs b/DeviceSQL/Functions/ROCMaster/SetUInt8Value.cs deleted file mode 100644 index fbc5294..0000000 --- a/DeviceSQL/Functions/ROCMaster/SetUInt8Value.cs +++ /dev/null @@ -1,23 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlBoolean ROCMaster_SetUInt8Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlByte value) - { - var deviceNameValue = deviceName.Value; - var uInt8Parameter = new UInt8Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = value.Value }; - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, uInt8Parameter); - return true; - } - } -} diff --git a/DeviceSQL/Functions/ROCMaster/WriteParameters.cs b/DeviceSQL/Functions/ROCMaster/WriteParameters.cs deleted file mode 100644 index 6a2a1d5..0000000 --- a/DeviceSQL/Functions/ROCMaster/WriteParameters.cs +++ /dev/null @@ -1,93 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device.ROC.Data; -using Microsoft.SqlServer.Server; -using System.Collections.Generic; -using System.Data.SqlTypes; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class ROCMaster - { - [SqlFunction] - public static SqlBoolean ROCMaster_WriteParameters(SqlString deviceName, Types.ROCMaster.ROCMaster_ParameterArray parameterArray) - { - var deviceNameValue = deviceName.Value; - var parameters = new List(); - var length = parameterArray.Length; - - for (var parameterIndex = 0; length > parameterIndex; parameterIndex++) - { - var parameter = parameterArray.GetParameter(parameterIndex); - - switch (parameter.RawType) - { - case ParameterType.AC3: - parameters.Add(new Ac3Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.AC7: - parameters.Add(new Ac7Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.AC10: - parameters.Add(new Ac10Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.AC12: - parameters.Add(new Ac12Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.AC20: - parameters.Add(new Ac20Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.AC30: - parameters.Add(new Ac30Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.AC40: - parameters.Add(new Ac40Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.BIN: - parameters.Add(new BinParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.FL: - parameters.Add(new FlpParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.DOUBLE: - parameters.Add(new DoubleParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.INT16: - parameters.Add(new Int16Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.INT32: - parameters.Add(new Int32Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.INT8: - parameters.Add(new Int8Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.TLP: - parameters.Add(new TlpParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.UINT16: - parameters.Add(new UInt16Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.UINT32: - parameters.Add(new UInt32Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.TIME: - parameters.Add(new TimeParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - case ParameterType.UINT8: - parameters.Add(new UInt8Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); - break; - } - - } - - (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameters(null, null, null, null, parameters); - - return true; - - } - - } -} diff --git a/DeviceSQL/Functions/Watchdog/GetCounterValue.cs b/DeviceSQL/Functions/Watchdog/GetCounterValue.cs deleted file mode 100644 index 517bfc6..0000000 --- a/DeviceSQL/Functions/Watchdog/GetCounterValue.cs +++ /dev/null @@ -1,28 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Diagnostics; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class Watchdog - { - [SqlFunction] - public static SqlInt32 Watchdog_GetCounterValue() - { - try - { - return new SqlInt32(DeviceSQL.Watchdog.Worker.WatchdogCounter); - } - catch (Exception ex) - { - Trace.TraceError(string.Format("Error getting watchdog counter value: {0}", ex.Message)); - } - return 0; - } - } -} diff --git a/DeviceSQL/Functions/Watchdog/IsAlive.cs b/DeviceSQL/Functions/Watchdog/IsAlive.cs deleted file mode 100644 index 2c38a28..0000000 --- a/DeviceSQL/Functions/Watchdog/IsAlive.cs +++ /dev/null @@ -1,29 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Diagnostics; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class Watchdog - - { - [SqlFunction] - public static SqlBoolean Watchdog_IsAlive() - { - try - { - return new SqlBoolean(DeviceSQL.Watchdog.Worker.IsAlive); - } - catch (Exception ex) - { - Trace.TraceError(string.Format("Error getting watchdog IsAlive value: {0}", ex.Message)); - } - return false; - } - } -} diff --git a/DeviceSQL/Functions/Watchdog/Run.cs b/DeviceSQL/Functions/Watchdog/Run.cs deleted file mode 100644 index a6c99cc..0000000 --- a/DeviceSQL/Functions/Watchdog/Run.cs +++ /dev/null @@ -1,28 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Diagnostics; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class Watchdog - { - [SqlFunction] - public static SqlBoolean Watchdog_Run() - { - try - { - DeviceSQL.Watchdog.Worker.Run(); - } - catch (Exception ex) - { - Trace.TraceError(string.Format("Error starting channel manager: {0}", ex.Message)); - } - return new SqlBoolean(true); - } - } -} diff --git a/DeviceSQL/Functions/Watchdog/Stop.cs b/DeviceSQL/Functions/Watchdog/Stop.cs deleted file mode 100644 index 5df65cc..0000000 --- a/DeviceSQL/Functions/Watchdog/Stop.cs +++ /dev/null @@ -1,43 +0,0 @@ -#region Imported Types - -using Microsoft.SqlServer.Server; -using System; -using System.Data.SqlTypes; -using System.Diagnostics; -using System.Linq; - -#endregion - -namespace DeviceSQL.Functions -{ - public partial class Watchdog - { - [SqlFunction] - public static SqlBoolean Watchdog_Stop() - { - try - { - var channels = DeviceSQL.Watchdog.Worker.Channels; - var channelList = channels.ToList(); - channelList.ForEach((channel) => - { - try - { - channel.Dispose(); - channels.TryTake(out channel); - } - catch (Exception ex) - { - Trace.TraceError(string.Format("Error disposing channel: {0}", ex.Message)); - } - }); - DeviceSQL.Watchdog.Worker.Stop(); - } - catch (Exception ex) - { - Trace.TraceError(string.Format("Error stopping channel manager: {0}", ex.Message)); - } - return new SqlBoolean(true); - } - } -} diff --git a/DeviceSQL/IOC/ISimpleIOC.cs b/DeviceSQL/IOC/ISimpleIOC.cs deleted file mode 100644 index a22db5e..0000000 --- a/DeviceSQL/IOC/ISimpleIOC.cs +++ /dev/null @@ -1,227 +0,0 @@ -// **************************************************************************** -// -// Copyright © GalaSoft Laurent Bugnion 2011-2016 -// -// **************************************************************************** -// Laurent Bugnion -// laurent@galasoft.ch -// 10.4.2011 -// GalaSoft.MvvmLight.Extras.Ioc -// http://www.mvvmlight.net -// -// See license.txt in this project or http://www.galasoft.ch/license_MIT.txt -// -// **************************************************************************** - -using DeviceSQL.ServiceLocation; -using System; -using System.Diagnostics.CodeAnalysis; - - -namespace DeviceSQL.IOC -{ - /// - /// A very simple IOC container with basic functionality needed to register and resolve - /// instances. If needed, this class can be replaced by another more elaborate - /// IOC container implementing the IServiceLocator interface. - /// The inspiration for this class is at https://gist.github.com/716137 but it has - /// been extended with additional features. - /// - //// [ClassInfo(typeof(SimpleIoc))] - [SuppressMessage( - "Microsoft.Naming", - "CA1704:IdentifiersShouldBeSpelledCorrectly", - MessageId = "Ioc")] - public interface ISimpleIOC : IServiceLocator - { - /// - /// Checks whether at least one instance of a given class is already created in the container. - /// - /// The class that is queried. - /// True if at least on instance of the class is already created, false otherwise. - [SuppressMessage( - "Microsoft.Design", - "CA1004:GenericMethodsShouldProvideTypeParameter", - Justification = "This syntax is more convenient than the alternatives.")] - bool ContainsCreated(); - - /// - /// Checks whether the instance with the given key is already created for a given class - /// in the container. - /// - /// The class that is queried. - /// The key that is queried. - /// True if the instance with the given key is already registered for the given class, - /// false otherwise. - [SuppressMessage( - "Microsoft.Design", - "CA1004:GenericMethodsShouldProvideTypeParameter", - Justification = "This syntax is more convenient than the alternatives.")] - bool ContainsCreated(string key); - - /// - /// Gets a value indicating whether a given type T is already registered. - /// - /// The type that the method checks for. - /// True if the type is registered, false otherwise. - [SuppressMessage( - "Microsoft.Design", - "CA1004:GenericMethodsShouldProvideTypeParameter", - Justification = "This syntax is more convenient than the alternatives.")] - bool IsRegistered(); - - /// - /// Gets a value indicating whether a given type T and a give key - /// are already registered. - /// - /// The type that the method checks for. - /// The key that the method checks for. - /// True if the type and key are registered, false otherwise. - [SuppressMessage( - "Microsoft.Design", - "CA1004:GenericMethodsShouldProvideTypeParameter", - Justification = "This syntax is more convenient than the alternatives.")] - bool IsRegistered(string key); - - /// - /// Registers a given type for a given interface. - /// - /// The interface for which instances will be resolved. - /// The type that must be used to create instances. - [SuppressMessage( - "Microsoft.Design", - "CA1004:GenericMethodsShouldProvideTypeParameter", - Justification = "This syntax is more convenient than the alternatives.")] - void Register() - where TClass : class - where TInterface : class; - - /// - /// Registers a given type for a given interface with the possibility for immediate - /// creation of the instance. - /// - /// The interface for which instances will be resolved. - /// The type that must be used to create instances. - /// If true, forces the creation of the default - /// instance of the provided class. - [SuppressMessage( - "Microsoft.Design", - "CA1004:GenericMethodsShouldProvideTypeParameter", - Justification = "This syntax is more convenient than the alternatives.")] - void Register(bool createInstanceImmediately) - where TClass : class - where TInterface : class; - - /// - /// Registers a given type. - /// - /// The type that must be used to create instances. - [SuppressMessage( - "Microsoft.Design", - "CA1004:GenericMethodsShouldProvideTypeParameter", - Justification = "This syntax is more convenient than the alternatives.")] - void Register() - where TClass : class; - - /// - /// Registers a given type with the possibility for immediate - /// creation of the instance. - /// - /// The type that must be used to create instances. - /// If true, forces the creation of the default - /// instance of the provided class. - [SuppressMessage( - "Microsoft.Design", - "CA1004:GenericMethodsShouldProvideTypeParameter", - Justification = "This syntax is more convenient than the alternatives.")] - void Register(bool createInstanceImmediately) - where TClass : class; - - /// - /// Registers a given instance for a given type. - /// - /// The type that is being registered. - /// The factory method able to create the instance that - /// must be returned when the given type is resolved. - void Register(Func factory) - where TClass : class; - - /// - /// Registers a given instance for a given type with the possibility for immediate - /// creation of the instance. - /// - /// The type that is being registered. - /// The factory method able to create the instance that - /// must be returned when the given type is resolved. - /// If true, forces the creation of the default - /// instance of the provided class. - void Register(Func factory, bool createInstanceImmediately) - where TClass : class; - - /// - /// Registers a given instance for a given type and a given key. - /// - /// The type that is being registered. - /// The factory method able to create the instance that - /// must be returned when the given type is resolved. - /// The key for which the given instance is registered. - void Register(Func factory, string key) - where TClass : class; - - /// - /// Registers a given instance for a given type and a given key with the possibility for immediate - /// creation of the instance. - /// - /// The type that is being registered. - /// The factory method able to create the instance that - /// must be returned when the given type is resolved. - /// The key for which the given instance is registered. - /// If true, forces the creation of the default - /// instance of the provided class. - void Register( - Func factory, - string key, - bool createInstanceImmediately) - where TClass : class; - - /// - /// Resets the instance in its original states. This deletes all the - /// registrations. - /// - void Reset(); - - /// - /// Unregisters a class from the cache and removes all the previously - /// created instances. - /// - /// The class that must be removed. - [SuppressMessage( - "Microsoft.Design", - "CA1004:GenericMethodsShouldProvideTypeParameter", - Justification = "This syntax is more convenient than the alternatives.")] - void Unregister() - where TClass : class; - - /// - /// Removes the given instance from the cache. The class itself remains - /// registered and can be used to create other instances. - /// - /// The type of the instance to be removed. - /// The instance that must be removed. - void Unregister(TClass instance) - where TClass : class; - - /// - /// Removes the instance corresponding to the given key from the cache. The class itself remains - /// registered and can be used to create other instances. - /// - /// The type of the instance to be removed. - /// The key corresponding to the instance that must be removed. - [SuppressMessage( - "Microsoft.Design", - "CA1004:GenericMethodsShouldProvideTypeParameter", - Justification = "This syntax is more convenient than the alternatives.")] - void Unregister(string key) - where TClass : class; - } -} \ No newline at end of file diff --git a/DeviceSQL/IOC/PreferredConstructor.cs b/DeviceSQL/IOC/PreferredConstructor.cs deleted file mode 100644 index 1bf2921..0000000 --- a/DeviceSQL/IOC/PreferredConstructor.cs +++ /dev/null @@ -1,31 +0,0 @@ -// **************************************************************************** -// -// Copyright © GalaSoft Laurent Bugnion 2011-2016 -// -// **************************************************************************** -// Laurent Bugnion -// laurent@galasoft.ch -// 10.4.2011 -// GalaSoft.MvvmLight.Extras.Ioc -// http://www.mvvmlight.net -// -// See license.txt in this project or http://www.galasoft.ch/license_MIT.txt -// -// **************************************************************************** - -using System; - -namespace DeviceSQL.IOC -{ - /// - /// When used with the SimpleIoc container, specifies which constructor - /// should be used to instantiate when GetInstance is called. - /// If there is only one constructor in the class, this attribute is - /// not needed. - /// - //// [ClassInfo(typeof(SimpleIoc))] - [AttributeUsage(AttributeTargets.Constructor)] - public sealed class PreferredConstructorAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/DeviceSQL/IOC/SimpleIOC.cs b/DeviceSQL/IOC/SimpleIOC.cs deleted file mode 100644 index 55ba599..0000000 --- a/DeviceSQL/IOC/SimpleIOC.cs +++ /dev/null @@ -1,961 +0,0 @@ -// **************************************************************************** -// -// Copyright © GalaSoft Laurent Bugnion 2011-2016 -// -// **************************************************************************** -// Laurent Bugnion -// laurent@galasoft.ch -// 10.4.2011 -// GalaSoft.MvvmLight.Extras -// http://www.mvvmlight.net -// -// See license.txt in this project or http://www.galasoft.ch/license_MIT.txt -// -// BL0005 -// **************************************************************************** - -using DeviceSQL.ServiceLocation; -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Linq; -using System.Reflection; - -namespace DeviceSQL.IOC -{ - /// - /// A very simple IOC container with basic functionality needed to register and resolve - /// instances. If needed, this class can be replaced by another more elaborate - /// IOC container implementing the IServiceLocator interface. - /// The inspiration for this class is at https://gist.github.com/716137 but it has - /// been extended with additional features. - /// - //// [ClassInfo(typeof(SimpleIoc), - //// VersionString = "5.1.9", - //// DateString = "201502072030", - //// Description = "A very simple IOC container.", - //// UrlContacts = "http://www.galasoft.ch/contact_en.html", - //// Email = "laurent@galasoft.ch")] - [SuppressMessage( - "Microsoft.Naming", - "CA1704:IdentifiersShouldBeSpelledCorrectly", - MessageId = "Ioc")] - public class SimpleIOC : ISimpleIOC - { - private readonly Dictionary _constructorInfos - = new Dictionary(); - - private readonly string _defaultKey = Guid.NewGuid().ToString(); - - private readonly object[] _emptyArguments = new object[0]; - - private readonly Dictionary> _factories - = new Dictionary>(); - - private readonly Dictionary> _instancesRegistry - = new Dictionary>(); - - private readonly Dictionary _interfaceToClassMap - = new Dictionary(); - - private readonly object _syncLock = new object(); - - private static SimpleIOC _default; - - /// - /// This class' default instance. - /// - public static SimpleIOC Default - { - get - { - return _default ?? (_default = new SimpleIOC()); - } - } - - /// - /// Checks whether at least one instance of a given class is already created in the container. - /// - /// The class that is queried. - /// True if at least on instance of the class is already created, false otherwise. - public bool ContainsCreated() - { - return ContainsCreated(null); - } - - /// - /// Checks whether the instance with the given key is already created for a given class - /// in the container. - /// - /// The class that is queried. - /// The key that is queried. - /// True if the instance with the given key is already registered for the given class, - /// false otherwise. - public bool ContainsCreated(string key) - { - var classType = typeof(TClass); - - if (!_instancesRegistry.ContainsKey(classType)) - { - return false; - } - - if (string.IsNullOrEmpty(key)) - { - return _instancesRegistry[classType].Count > 0; - } - - return _instancesRegistry[classType].ContainsKey(key); - } - - /// - /// Gets a value indicating whether a given type T is already registered. - /// - /// The type that the method checks for. - /// True if the type is registered, false otherwise. - public bool IsRegistered() - { - var classType = typeof(T); - return _interfaceToClassMap.ContainsKey(classType); - } - - /// - /// Gets a value indicating whether a given type T and a give key - /// are already registered. - /// - /// The type that the method checks for. - /// The key that the method checks for. - /// True if the type and key are registered, false otherwise. - public bool IsRegistered(string key) - { - var classType = typeof(T); - - if (!_interfaceToClassMap.ContainsKey(classType) - || !_factories.ContainsKey(classType)) - { - return false; - } - - return _factories[classType].ContainsKey(key); - } - - /// - /// Registers a given type for a given interface. - /// - /// The interface for which instances will be resolved. - /// The type that must be used to create instances. - [SuppressMessage( - "Microsoft.Design", - "CA1004", - Justification = "This syntax is better than the alternatives.")] - public void Register() - where TClass : class - where TInterface : class - { - Register(false); - } - - /// - /// Registers a given type for a given interface with the possibility for immediate - /// creation of the instance. - /// - /// The interface for which instances will be resolved. - /// The type that must be used to create instances. - /// If true, forces the creation of the default - /// instance of the provided class. - [SuppressMessage( - "Microsoft.Design", - "CA1004", - Justification = "This syntax is better than the alternatives.")] - public void Register(bool createInstanceImmediately) - where TClass : class - where TInterface : class - { - lock (_syncLock) - { - var interfaceType = typeof(TInterface); - var classType = typeof(TClass); - - if (_interfaceToClassMap.ContainsKey(interfaceType)) - { - if (_interfaceToClassMap[interfaceType] != classType) - { - throw new InvalidOperationException( - string.Format( - CultureInfo.InvariantCulture, - "There is already a class registered for {0}.", - interfaceType.FullName)); - } - } - else - { - _interfaceToClassMap.Add(interfaceType, classType); - _constructorInfos.Add(classType, GetConstructorInfo(classType)); - } - - Func factory = MakeInstance; - DoRegister(interfaceType, factory, _defaultKey); - - if (createInstanceImmediately) - { - GetInstance(); - } - } - } - - /// - /// Registers a given type. - /// - /// The type that must be used to create instances. - [SuppressMessage( - "Microsoft.Design", - "CA1004", - Justification = "This syntax is better than the alternatives.")] - public void Register() - where TClass : class - { - Register(false); - } - - /// - /// Registers a given type with the possibility for immediate - /// creation of the instance. - /// - /// The type that must be used to create instances. - /// If true, forces the creation of the default - /// instance of the provided class. - [SuppressMessage( - "Microsoft.Design", - "CA1004", - Justification = "This syntax is better than the alternatives.")] - public void Register(bool createInstanceImmediately) - where TClass : class - { - var classType = typeof(TClass); -#if NETFX_CORE - if (classType.GetTypeInfo().IsInterface) -#else - if (classType.IsInterface) -#endif - { - throw new ArgumentException("An interface cannot be registered alone."); - } - - lock (_syncLock) - { - if (_factories.ContainsKey(classType) - && _factories[classType].ContainsKey(_defaultKey)) - { - if (!_constructorInfos.ContainsKey(classType)) - { - // Throw only if constructorinfos have not been - // registered, which means there is a default factory - // for this class. - throw new InvalidOperationException( - string.Format( - CultureInfo.InvariantCulture, - "Class {0} is already registered.", - classType)); - } - - return; - } - - if (!_interfaceToClassMap.ContainsKey(classType)) - { - _interfaceToClassMap.Add(classType, null); - } - - _constructorInfos.Add(classType, GetConstructorInfo(classType)); - Func factory = MakeInstance; - DoRegister(classType, factory, _defaultKey); - - if (createInstanceImmediately) - { - GetInstance(); - } - } - } - - /// - /// Registers a given instance for a given type. - /// - /// The type that is being registered. - /// The factory method able to create the instance that - /// must be returned when the given type is resolved. - public void Register(Func factory) - where TClass : class - { - Register(factory, false); - } - - /// - /// Registers a given instance for a given type with the possibility for immediate - /// creation of the instance. - /// - /// The type that is being registered. - /// The factory method able to create the instance that - /// must be returned when the given type is resolved. - /// If true, forces the creation of the default - /// instance of the provided class. - public void Register(Func factory, bool createInstanceImmediately) - where TClass : class - { - if (factory == null) - { - throw new ArgumentNullException("factory"); - } - - lock (_syncLock) - { - var classType = typeof(TClass); - - if (_factories.ContainsKey(classType) - && _factories[classType].ContainsKey(_defaultKey)) - { - throw new InvalidOperationException( - string.Format( - CultureInfo.InvariantCulture, - "There is already a factory registered for {0}.", - classType.FullName)); - } - - if (!_interfaceToClassMap.ContainsKey(classType)) - { - _interfaceToClassMap.Add(classType, null); - } - - DoRegister(classType, factory, _defaultKey); - - if (createInstanceImmediately) - { - GetInstance(); - } - } - } - - /// - /// Registers a given instance for a given type and a given key. - /// - /// The type that is being registered. - /// The factory method able to create the instance that - /// must be returned when the given type is resolved. - /// The key for which the given instance is registered. - public void Register(Func factory, string key) - where TClass : class - { - Register(factory, key, false); - } - - /// - /// Registers a given instance for a given type and a given key with the possibility for immediate - /// creation of the instance. - /// - /// The type that is being registered. - /// The factory method able to create the instance that - /// must be returned when the given type is resolved. - /// The key for which the given instance is registered. - /// If true, forces the creation of the default - /// instance of the provided class. - public void Register( - Func factory, - string key, - bool createInstanceImmediately) - where TClass : class - { - lock (_syncLock) - { - var classType = typeof(TClass); - - if (_factories.ContainsKey(classType) - && _factories[classType].ContainsKey(key)) - { - throw new InvalidOperationException( - string.Format( - CultureInfo.InvariantCulture, - "There is already a factory registered for {0} with key {1}.", - classType.FullName, - key)); - } - - if (!_interfaceToClassMap.ContainsKey(classType)) - { - _interfaceToClassMap.Add(classType, null); - } - - DoRegister(classType, factory, key); - - if (createInstanceImmediately) - { - GetInstance(key); - } - } - } - - /// - /// Resets the instance in its original states. This deletes all the - /// registrations. - /// - public void Reset() - { - _interfaceToClassMap.Clear(); - _instancesRegistry.Clear(); - _constructorInfos.Clear(); - _factories.Clear(); - } - - /// - /// Unregisters a class from the cache and removes all the previously - /// created instances. - /// - /// The class that must be removed. - [SuppressMessage( - "Microsoft.Design", - "CA1004", - Justification = "This syntax is better than the alternatives.")] - public void Unregister() - where TClass : class - { - lock (_syncLock) - { - var serviceType = typeof(TClass); - Type resolveTo; - - if (_interfaceToClassMap.ContainsKey(serviceType)) - { - resolveTo = _interfaceToClassMap[serviceType] ?? serviceType; - } - else - { - resolveTo = serviceType; - } - - if (_instancesRegistry.ContainsKey(serviceType)) - { - _instancesRegistry.Remove(serviceType); - } - - if (_interfaceToClassMap.ContainsKey(serviceType)) - { - _interfaceToClassMap.Remove(serviceType); - } - - if (_factories.ContainsKey(serviceType)) - { - _factories.Remove(serviceType); - } - - if (_constructorInfos.ContainsKey(resolveTo)) - { - _constructorInfos.Remove(resolveTo); - } - } - } - - /// - /// Removes the given instance from the cache. The class itself remains - /// registered and can be used to create other instances. - /// - /// The type of the instance to be removed. - /// The instance that must be removed. - public void Unregister(TClass instance) - where TClass : class - { - lock (_syncLock) - { - var classType = typeof(TClass); - - if (_instancesRegistry.ContainsKey(classType)) - { - var list = _instancesRegistry[classType]; - - var pairs = list.Where(pair => pair.Value == instance).ToList(); - for (var index = 0; index < pairs.Count(); index++) - { - var key = pairs[index].Key; - - list.Remove(key); - } - } - } - } - - /// - /// Removes the instance corresponding to the given key from the cache. The class itself remains - /// registered and can be used to create other instances. - /// - /// The type of the instance to be removed. - /// The key corresponding to the instance that must be removed. - [SuppressMessage( - "Microsoft.Design", - "CA1004", - Justification = "This syntax is better than the alternatives.")] - public void Unregister(string key) - where TClass : class - { - lock (_syncLock) - { - var classType = typeof(TClass); - - if (_instancesRegistry.ContainsKey(classType)) - { - var list = _instancesRegistry[classType]; - - var pairs = list.Where(pair => pair.Key == key).ToList(); - for (var index = 0; index < pairs.Count(); index++) - { - list.Remove(pairs[index].Key); - } - } - - if (_factories.ContainsKey(classType)) - { - if (_factories[classType].ContainsKey(key)) - { - _factories[classType].Remove(key); - } - } - } - } - - private object DoGetService(Type serviceType, string key, bool cache = true) - { - lock (_syncLock) - { - if (string.IsNullOrEmpty(key)) - { - key = _defaultKey; - } - - Dictionary instances = null; - - if (!_instancesRegistry.ContainsKey(serviceType)) - { - if (!_interfaceToClassMap.ContainsKey(serviceType)) - { - throw new ActivationException( - string.Format( - CultureInfo.InvariantCulture, - "Type not found in cache: {0}.", - serviceType.FullName)); - } - - if (cache) - { - instances = new Dictionary(); - _instancesRegistry.Add(serviceType, instances); - } - } - else - { - instances = _instancesRegistry[serviceType]; - } - - if (instances != null - && instances.ContainsKey(key)) - { - return instances[key]; - } - - object instance = null; - - if (_factories.ContainsKey(serviceType)) - { - if (_factories[serviceType].ContainsKey(key)) - { - instance = _factories[serviceType][key].DynamicInvoke(null); - } - else - { - if (_factories[serviceType].ContainsKey(_defaultKey)) - { - instance = _factories[serviceType][_defaultKey].DynamicInvoke(null); - } - else - { - throw new ActivationException( - string.Format( - CultureInfo.InvariantCulture, - "Type not found in cache without a key: {0}", - serviceType.FullName)); - } - } - } - - if (cache - && instances != null) - { - instances.Add(key, instance); - } - - return instance; - } - } - - private void DoRegister(Type classType, Func factory, string key) - { - if (_factories.ContainsKey(classType)) - { - if (_factories[classType].ContainsKey(key)) - { - // The class is already registered, ignore and continue. - return; - } - - _factories[classType].Add(key, factory); - } - else - { - var list = new Dictionary - { - { - key, - factory - } - }; - - _factories.Add(classType, list); - } - } - - private ConstructorInfo GetConstructorInfo(Type serviceType) - { - Type resolveTo; - - if (_interfaceToClassMap.ContainsKey(serviceType)) - { - resolveTo = _interfaceToClassMap[serviceType] ?? serviceType; - } - else - { - resolveTo = serviceType; - } - -#if NETFX_CORE - var constructorInfos = resolveTo.GetTypeInfo().DeclaredConstructors.Where(c => c.IsPublic).ToArray(); -#else - var constructorInfos = resolveTo.GetConstructors(); -#endif - - if (constructorInfos.Length > 1) - { - if (constructorInfos.Length > 2) - { - return GetPreferredConstructorInfo(constructorInfos, resolveTo); - } - - if (constructorInfos.FirstOrDefault(i => i.Name == ".cctor") == null) - { - return GetPreferredConstructorInfo(constructorInfos, resolveTo); - } - - var first = constructorInfos.FirstOrDefault(i => i.Name != ".cctor"); - - if (first == null - || !first.IsPublic) - { - throw new ActivationException( - string.Format( - CultureInfo.InvariantCulture, - "Cannot register: No public constructor found in {0}.", - resolveTo.Name)); - } - - return first; - } - - if (constructorInfos.Length == 0 - || (constructorInfos.Length == 1 - && !constructorInfos[0].IsPublic)) - { - throw new ActivationException( - string.Format( - CultureInfo.InvariantCulture, - "Cannot register: No public constructor found in {0}.", - resolveTo.Name)); - } - - return constructorInfos[0]; - } - - [SuppressMessage( - "Microsoft.Naming", - "CA2204:Literals should be spelled correctly", - MessageId = "PreferredConstructor")] - private static ConstructorInfo GetPreferredConstructorInfo(IEnumerable constructorInfos, Type resolveTo) - { - var preferredConstructorInfo - = (from t in constructorInfos -#if NETFX_CORE - let attribute = t.GetCustomAttribute(typeof(PreferredConstructorAttribute)) -#else - let attribute = Attribute.GetCustomAttribute(t, typeof(PreferredConstructorAttribute)) -#endif - where attribute != null - select t).FirstOrDefault(); - - if (preferredConstructorInfo == null) - { - throw new ActivationException( - string.Format( - CultureInfo.InvariantCulture, - "Cannot register: Multiple constructors found in {0} but none marked with PreferredConstructor.", - resolveTo.Name)); - } - - return preferredConstructorInfo; - } - - private TClass MakeInstance() - { - var serviceType = typeof(TClass); - - var constructor = _constructorInfos.ContainsKey(serviceType) - ? _constructorInfos[serviceType] - : GetConstructorInfo(serviceType); - - var parameterInfos = constructor.GetParameters(); - - if (parameterInfos.Length == 0) - { - return (TClass)constructor.Invoke(_emptyArguments); - } - - var parameters = new object[parameterInfos.Length]; - - foreach (var parameterInfo in parameterInfos) - { - parameters[parameterInfo.Position] = GetService(parameterInfo.ParameterType); - } - - return (TClass)constructor.Invoke(parameters); - } - - /// - /// Provides a way to get all the created instances of a given type available in the - /// cache. Registering a class or a factory does not automatically - /// create the corresponding instance! To create an instance, either register - /// the class or the factory with createInstanceImmediately set to true, - /// or call the GetInstance method before calling GetAllCreatedInstances. - /// Alternatively, use the GetAllInstances method, which auto-creates default - /// instances for all registered classes. - /// - /// The class of which all instances - /// must be returned. - /// All the already created instances of the given type. - public IEnumerable GetAllCreatedInstances(Type serviceType) - { - if (_instancesRegistry.ContainsKey(serviceType)) - { - return _instancesRegistry[serviceType].Values; - } - - return new List(); - } - - /// - /// Provides a way to get all the created instances of a given type available in the - /// cache. Registering a class or a factory does not automatically - /// create the corresponding instance! To create an instance, either register - /// the class or the factory with createInstanceImmediately set to true, - /// or call the GetInstance method before calling GetAllCreatedInstances. - /// Alternatively, use the GetAllInstances method, which auto-creates default - /// instances for all registered classes. - /// - /// The class of which all instances - /// must be returned. - /// All the already created instances of the given type. - public IEnumerable GetAllCreatedInstances() - { - var serviceType = typeof (TService); - return GetAllCreatedInstances(serviceType) - .Select(instance => (TService)instance); - } - - #region Implementation of IServiceProvider - - /// - /// Gets the service object of the specified type. - /// - /// If the type serviceType has not - /// been registered before calling this method. - /// - /// A service object of type . - /// - /// An object that specifies the type of service object to get. - public object GetService(Type serviceType) - { - return DoGetService(serviceType, _defaultKey); - } - - #endregion - - #region Implementation of IServiceLocator - - /// - /// Provides a way to get all the created instances of a given type available in the - /// cache. Calling this method auto-creates default - /// instances for all registered classes. - /// - /// The class of which all instances - /// must be returned. - /// All the instances of the given type. - public IEnumerable GetAllInstances(Type serviceType) - { - lock (_factories) - { - if (_factories.ContainsKey(serviceType)) - { - foreach (var factory in _factories[serviceType]) - { - GetInstance(serviceType, factory.Key); - } - } - } - - if (_instancesRegistry.ContainsKey(serviceType)) - { - return _instancesRegistry[serviceType].Values; - } - - - return new List(); - } - - /// - /// Provides a way to get all the created instances of a given type available in the - /// cache. Calling this method auto-creates default - /// instances for all registered classes. - /// - /// The class of which all instances - /// must be returned. - /// All the instances of the given type. - public IEnumerable GetAllInstances() - { - var serviceType = typeof(TService); - return GetAllInstances(serviceType) - .Select(instance => (TService)instance); - } - - /// - /// Provides a way to get an instance of a given type. If no instance had been instantiated - /// before, a new instance will be created. If an instance had already - /// been created, that same instance will be returned. - /// - /// If the type serviceType has not - /// been registered before calling this method. - /// The class of which an instance - /// must be returned. - /// An instance of the given type. - public object GetInstance(Type serviceType) - { - return DoGetService(serviceType, _defaultKey); - } - - /// - /// Provides a way to get an instance of a given type. This method - /// always returns a new instance and doesn't cache it in the IOC container. - /// - /// If the type serviceType has not - /// been registered before calling this method. - /// The class of which an instance - /// must be returned. - /// An instance of the given type. - public object GetInstanceWithoutCaching(Type serviceType) - { - return DoGetService(serviceType, _defaultKey, false); - } - - /// - /// Provides a way to get an instance of a given type corresponding - /// to a given key. If no instance had been instantiated with this - /// key before, a new instance will be created. If an instance had already - /// been created with the same key, that same instance will be returned. - /// - /// If the type serviceType has not - /// been registered before calling this method. - /// The class of which an instance must be returned. - /// The key uniquely identifying this instance. - /// An instance corresponding to the given type and key. - public object GetInstance(Type serviceType, string key) - { - return DoGetService(serviceType, key); - } - - /// - /// Provides a way to get an instance of a given type. This method - /// always returns a new instance and doesn't cache it in the IOC container. - /// - /// If the type serviceType has not - /// been registered before calling this method. - /// The class of which an instance must be returned. - /// The key uniquely identifying this instance. - /// An instance corresponding to the given type and key. - public object GetInstanceWithoutCaching(Type serviceType, string key) - { - return DoGetService(serviceType, key, false); - } - - /// - /// Provides a way to get an instance of a given type. If no instance had been instantiated - /// before, a new instance will be created. If an instance had already - /// been created, that same instance will be returned. - /// - /// If the type TService has not - /// been registered before calling this method. - /// The class of which an instance - /// must be returned. - /// An instance of the given type. - public TService GetInstance() - { - return (TService)DoGetService(typeof(TService), _defaultKey); - } - - /// - /// Provides a way to get an instance of a given type. This method - /// always returns a new instance and doesn't cache it in the IOC container. - /// - /// If the type TService has not - /// been registered before calling this method. - /// The class of which an instance - /// must be returned. - /// An instance of the given type. - public TService GetInstanceWithoutCaching() - { - return (TService)DoGetService(typeof(TService), _defaultKey, false); - } - - /// - /// Provides a way to get an instance of a given type corresponding - /// to a given key. If no instance had been instantiated with this - /// key before, a new instance will be created. If an instance had already - /// been created with the same key, that same instance will be returned. - /// - /// If the type TService has not - /// been registered before calling this method. - /// The class of which an instance must be returned. - /// The key uniquely identifying this instance. - /// An instance corresponding to the given type and key. - public TService GetInstance(string key) - { - return (TService)DoGetService(typeof(TService), key); - } - - /// - /// Provides a way to get an instance of a given type. This method - /// always returns a new instance and doesn't cache it in the IOC container. - /// - /// If the type TService has not - /// been registered before calling this method. - /// The class of which an instance must be returned. - /// The key uniquely identifying this instance. - /// An instance corresponding to the given type and key. - public TService GetInstanceWithoutCaching(string key) - { - return (TService)DoGetService(typeof(TService), key, false); - } - - #endregion - } -} \ No newline at end of file diff --git a/DeviceSQL/ServiceLocation/ActivationException.cs b/DeviceSQL/ServiceLocation/ActivationException.cs deleted file mode 100644 index 6224ab7..0000000 --- a/DeviceSQL/ServiceLocation/ActivationException.cs +++ /dev/null @@ -1,44 +0,0 @@ -#region Imported Types - -using System; - -#endregion - -namespace DeviceSQL.ServiceLocation -{ - /// - /// The standard exception thrown when a ServiceLocator has an error in resolving an object. - /// - public class ActivationException : Exception - { - /// - /// Initializes a new instance of the class. - /// - public ActivationException() - { - } - - /// - /// Initializes a new instance of the class with a specified error message. - /// - /// - /// The message that describes the error. - /// - public ActivationException(string message) : base(message) - { - } - - /// - /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. - /// - /// - /// The error message that explains the reason for the exception. - /// - /// - /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - /// - public ActivationException(string message, Exception innerException) : base(message, innerException) - { - } - } -} \ No newline at end of file diff --git a/DeviceSQL/ServiceLocation/IServiceLocator.cs b/DeviceSQL/ServiceLocation/IServiceLocator.cs deleted file mode 100644 index abcb9e3..0000000 --- a/DeviceSQL/ServiceLocation/IServiceLocator.cs +++ /dev/null @@ -1,75 +0,0 @@ -#region Imported Types - -using System; -using System.Collections.Generic; - -#endregion - -namespace DeviceSQL.ServiceLocation -{ - /// - /// The generic Service Locator interface. This interface is used - /// to retrieve services (instances identified by type and optional - /// name) from a container. - /// - public interface IServiceLocator : IServiceProvider - { - /// - /// Get all instances of the given currently - /// registered in the container. - /// - /// Type of object requested. - /// if there is are errors resolving - /// the service instance. - /// A sequence of instances of the requested . - IEnumerable GetAllInstances(Type serviceType); - - /// - /// Get all instances of the given currently - /// registered in the container. - /// - /// Type of object requested. - /// if there is are errors resolving - /// the service instance. - /// A sequence of instances of the requested . - IEnumerable GetAllInstances(); - - /// - /// Get an instance of the given . - /// - /// Type of object requested. - /// if there is an error resolving - /// the service instance. - /// The requested service instance. - object GetInstance(Type serviceType); - - /// - /// Get an instance of the given named . - /// - /// Type of object requested. - /// Name the object was registered with. - /// if there is an error resolving - /// the service instance. - /// The requested service instance. - object GetInstance(Type serviceType, string key); - - /// - /// Get an instance of the given . - /// - /// Type of object requested. - /// if there is are errors resolving - /// the service instance. - /// The requested service instance. - TService GetInstance(); - - /// - /// Get an instance of the given named . - /// - /// Type of object requested. - /// Name the object was registered with. - /// if there is are errors resolving - /// the service instance. - /// The requested service instance. - TService GetInstance(string key); - } -} \ No newline at end of file diff --git a/DeviceSQL/ServiceLocation/ServiceLocator.cs b/DeviceSQL/ServiceLocation/ServiceLocator.cs deleted file mode 100644 index b812366..0000000 --- a/DeviceSQL/ServiceLocation/ServiceLocator.cs +++ /dev/null @@ -1,52 +0,0 @@ -#region Imported Types - -using System; - -#endregion - -namespace DeviceSQL.ServiceLocation -{ - /// - /// This class provides the ambient container for this application. If your - /// framework defines such an ambient container, use ServiceLocator.Current - /// to get it. - /// - public static class ServiceLocator - { - private const string SERVICE_LOCATION_PROVIDER_NOT_SET_MESSAGE = "ServiceLocationProvider must be set."; - private static ServiceLocatorProvider currentProvider; - - /// - /// The current ambient container. - /// - public static IServiceLocator Current - { - get - { - if (!ServiceLocator.IsLocationProviderSet) - { - throw new InvalidOperationException(SERVICE_LOCATION_PROVIDER_NOT_SET_MESSAGE); - } - return ServiceLocator.currentProvider(); - } - } - - public static bool IsLocationProviderSet - { - get - { - return ServiceLocator.currentProvider != null; - } - } - - /// - /// Set the delegate that is used to retrieve the current container. - /// - /// Delegate that, when called, will return - /// the current ambient container. - public static void SetLocatorProvider(ServiceLocatorProvider newProvider) - { - ServiceLocator.currentProvider = newProvider; - } - } -} \ No newline at end of file diff --git a/DeviceSQL/ServiceLocation/ServiceLocatorImplBase.cs b/DeviceSQL/ServiceLocation/ServiceLocatorImplBase.cs deleted file mode 100644 index f5a3e23..0000000 --- a/DeviceSQL/ServiceLocation/ServiceLocatorImplBase.cs +++ /dev/null @@ -1,181 +0,0 @@ -#region Imported Types - -using System; -using System.Collections.Generic; -using System.Globalization; - -#endregion - -namespace DeviceSQL.ServiceLocation -{ - /// - /// This class is a helper that provides a default implementation - /// for most of the methods of . - /// - public abstract class ServiceLocatorImplBase : IServiceLocator, IServiceProvider - { - private const string ACTIVATION_EXCEPTION_MESSAGE = "Activation error occurred while trying to get instance of type {0}, key \"{1}\""; - private const string ACTIVATE_ALL_EXCEPTION_MESSAGE = "Activation error occurred while trying to get all instances of type {0}"; - protected ServiceLocatorImplBase() - { - } - - /// - /// When implemented by inheriting classes, this method will do the actual work of - /// resolving all the requested service instances. - /// - /// Type of service requested. - /// Sequence of service instance objects. - protected abstract IEnumerable DoGetAllInstances(Type serviceType); - - /// - /// When implemented by inheriting classes, this method will do the actual work of resolving - /// the requested service instance. - /// - /// Type of instance requested. - /// Name of registered service you want. May be null. - /// The requested service instance. - protected abstract object DoGetInstance(Type serviceType, string key); - - /// - /// Format the exception message for use in an - /// that occurs while resolving multiple service instances. - /// - /// The actual exception thrown by the implementation. - /// Type of service requested. - /// The formatted exception message string. - protected virtual string FormatActivateAllExceptionMessage(Exception actualException, Type serviceType) - { - CultureInfo currentUICulture = CultureInfo.CurrentUICulture; - string activateAllExceptionMessage = ACTIVATE_ALL_EXCEPTION_MESSAGE; - object[] name = new object[] { serviceType.Name }; - return string.Format(currentUICulture, activateAllExceptionMessage, name); - } - - /// - /// Format the exception message for use in an - /// that occurs while resolving a single service. - /// - /// The actual exception thrown by the implementation. - /// Type of service requested. - /// Name requested. - /// The formatted exception message string. - protected virtual string FormatActivationExceptionMessage(Exception actualException, Type serviceType, string key) - { - CultureInfo currentUICulture = CultureInfo.CurrentUICulture; - string activationExceptionMessage = ACTIVATION_EXCEPTION_MESSAGE; - object[] name = new object[] { serviceType.Name, key }; - return string.Format(currentUICulture, activationExceptionMessage, name); - } - - /// - /// Get all instances of the given currently - /// registered in the container. - /// - /// Type of object requested. - /// if there is are errors resolving - /// the service instance. - /// A sequence of instances of the requested . - public virtual IEnumerable GetAllInstances(Type serviceType) - { - IEnumerable objs; - try - { - objs = this.DoGetAllInstances(serviceType); - } - catch (Exception exception) - { - Exception ex = exception; - throw new ActivationException(this.FormatActivateAllExceptionMessage(ex, serviceType), ex); - } - return objs; - } - - /// - /// Get all instances of the given currently - /// registered in the container. - /// - /// Type of object requested. - /// if there is are errors resolving - /// the service instance. - /// A sequence of instances of the requested . - public virtual IEnumerable GetAllInstances() - { - foreach (object allInstance in this.GetAllInstances(typeof(TService))) - { - yield return (TService)allInstance; - } - } - - /// - /// Get an instance of the given . - /// - /// Type of object requested. - /// if there is an error resolving - /// the service instance. - /// The requested service instance. - public virtual object GetInstance(Type serviceType) - { - return this.GetInstance(serviceType, null); - } - - /// - /// Get an instance of the given named . - /// - /// Type of object requested. - /// Name the object was registered with. - /// if there is an error resolving - /// the service instance. - /// The requested service instance. - public virtual object GetInstance(Type serviceType, string key) - { - object obj; - try - { - obj = this.DoGetInstance(serviceType, key); - } - catch (Exception exception) - { - Exception ex = exception; - throw new ActivationException(this.FormatActivationExceptionMessage(ex, serviceType, key), ex); - } - return obj; - } - - /// - /// Get an instance of the given . - /// - /// Type of object requested. - /// if there is are errors resolving - /// the service instance. - /// The requested service instance. - public virtual TService GetInstance() - { - return (TService)this.GetInstance(typeof(TService), null); - } - - /// - /// Get an instance of the given named . - /// - /// Type of object requested. - /// Name the object was registered with. - /// if there is are errors resolving - /// the service instance. - /// The requested service instance. - public virtual TService GetInstance(string key) - { - return (TService)this.GetInstance(typeof(TService), key); - } - - /// - /// Implementation of . - /// - /// The requested service. - /// if there is an error in resolving the service instance. - /// The requested object. - public virtual object GetService(Type serviceType) - { - return this.GetInstance(serviceType, null); - } - } -} \ No newline at end of file diff --git a/DeviceSQL/ServiceLocation/ServiceLocatorProvider.cs b/DeviceSQL/ServiceLocation/ServiceLocatorProvider.cs deleted file mode 100644 index 5daa6d1..0000000 --- a/DeviceSQL/ServiceLocation/ServiceLocatorProvider.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace DeviceSQL.ServiceLocation -{ - /// - /// This delegate type is used to provide a method that will - /// return the current container. Used with the - /// static accessor class. - /// - /// An . - public delegate IServiceLocator ServiceLocatorProvider(); -} \ No newline at end of file diff --git a/DeviceSQL/Tables/FlowSQL/DifferentialPressureMeterProcessVariableAlarms.sql b/DeviceSQL/Tables/FlowSQL/DifferentialPressureMeterProcessVariableAlarms.sql deleted file mode 100644 index 0b47bbc..0000000 --- a/DeviceSQL/Tables/FlowSQL/DifferentialPressureMeterProcessVariableAlarms.sql +++ /dev/null @@ -1,26 +0,0 @@ -CREATE TABLE [FlowSQL].[DifferentialPressureMeterProcessVariableAlarms] ( - [MeterId] BIGINT NOT NULL, - [DateTimeStamp] DATETIMEOFFSET (7) NOT NULL, - [DifferentialPressure.LowLowAlarm] FLOAT (53) NOT NULL, - [DifferentialPressure.LowAlarm] FLOAT (53) NOT NULL, - [DifferentialPressure.HighAlarm] FLOAT (53) NOT NULL, - [DifferentialPressure.HighHighAlarm] FLOAT (53) NOT NULL, - [DifferentialPressure.RateAlarm] FLOAT (53) NOT NULL, - [DifferentialPressure.Deadband] FLOAT (53) NOT NULL, - [StaticPressure.LowLowAlarm] FLOAT (53) NOT NULL, - [StaticPressure.LowAlarm] FLOAT (53) NOT NULL, - [StaticPressure.HighAlarm] FLOAT (53) NOT NULL, - [StaticPressure.HighHighAlarm] FLOAT (53) NOT NULL, - [StaticPressure.RateAlarm] FLOAT (53) NOT NULL, - [StaticPressure.Deadband] FLOAT (53) NOT NULL, - [Temperature.LowLowAlarm] FLOAT (53) NOT NULL, - [Temperature.LowAlarm] FLOAT (53) NOT NULL, - [Temperature.HighAlarm] FLOAT (53) NOT NULL, - [Temperature.HighHighAlarm] FLOAT (53) NOT NULL, - [Temperature.RateAlarm] FLOAT (53) NOT NULL, - [Temperature.Deadband] FLOAT (53) NOT NULL, - [RowVersion] ROWVERSION NULL, - CONSTRAINT [PK_DifferentialPressureMeterProcessVariableAlarms] PRIMARY KEY CLUSTERED ([MeterId] ASC, [DateTimeStamp] ASC), - CONSTRAINT [FK_DifferentialPressureMeterProcessVariableAlarms_Meters] FOREIGN KEY ([MeterId]) REFERENCES [FlowSQL].[Meters] ([Id]) -); - diff --git a/DeviceSQL/Tables/FlowSQL/DifferentialPressureMeterProcessVariableValues.sql b/DeviceSQL/Tables/FlowSQL/DifferentialPressureMeterProcessVariableValues.sql deleted file mode 100644 index 3d11d58..0000000 --- a/DeviceSQL/Tables/FlowSQL/DifferentialPressureMeterProcessVariableValues.sql +++ /dev/null @@ -1,41 +0,0 @@ -CREATE TABLE [FlowSQL].[DifferentialPressureMeterProcessVariableValues] ( - [MeterId] BIGINT NOT NULL, - [DateTimeStamp] DATETIMEOFFSET (7) NOT NULL, - [DifferentialPressure.AlarmingEnabled] BIT NOT NULL, - [DifferentialPressure.ScanningEnabled] BIT NOT NULL, - [DifferentialPressure.ScanPeriod] INT NOT NULL, - [DifferentialPressure.Filter] INT NOT NULL, - [DifferentialPressure.Units] VARCHAR (30) NOT NULL, - [DifferentialPressure.Raw.Value] FLOAT (53) NOT NULL, - [DifferentialPressure.EU.Value] FLOAT (53) NOT NULL, - [DifferentialPressure.Raw.ZeroValue] INT NOT NULL, - [DifferentialPressure.Raw.SpanValue] INT NOT NULL, - [DifferentialPressure.EU.ZeroValue] FLOAT (53) NOT NULL, - [DifferentialPressure.EU.SpanValue] FLOAT (53) NOT NULL, - [StaticPressure.AlarmingEnabled] BIT NOT NULL, - [StaticPressure.ScanningEnabled] BIT NOT NULL, - [StaticPressure.ScanPeriod] INT NOT NULL, - [StaticPressure.Filter] INT NOT NULL, - [StaticPressure.Units] VARCHAR (30) NOT NULL, - [StaticPressure.Raw.Value] FLOAT (53) NOT NULL, - [StaticPressure.EU.Value] FLOAT (53) NOT NULL, - [StaticPressure.Raw.ZeroValue] INT NOT NULL, - [StaticPressure.Raw.SpanValue] INT NOT NULL, - [StaticPressure.EU.ZeroValue] FLOAT (53) NOT NULL, - [StaticPressure.EU.SpanValue] FLOAT (53) NOT NULL, - [Temperature.AlarmingEnabled] BIT NOT NULL, - [Temperature.ScanningEnabled] BIT NOT NULL, - [Temperature.ScanPeriod] INT NOT NULL, - [Temperature.Filter] INT NOT NULL, - [Temperature.Units] VARCHAR (30) NOT NULL, - [Temperature.Raw.Value] FLOAT (53) NOT NULL, - [Temperature.EU.Value] FLOAT (53) NOT NULL, - [Temperature.Raw.ZeroValue] INT NOT NULL, - [Temperature.Raw.SpanValue] INT NOT NULL, - [Temperature.EU.ZeroValue] FLOAT (53) NOT NULL, - [Temperature.EU.SpanValue] FLOAT (53) NOT NULL, - [RowVersion] ROWVERSION NULL, - CONSTRAINT [PK_DifferentialPressureMeterProcessVariableValues] PRIMARY KEY CLUSTERED ([MeterId] ASC, [DateTimeStamp] ASC), - CONSTRAINT [FK_DifferentialPressureMeterProcessVariableValues_Meters] FOREIGN KEY ([MeterId]) REFERENCES [FlowSQL].[Meters] ([Id]) -); - diff --git a/DeviceSQL/Tables/FlowSQL/MeterAttributes.sql b/DeviceSQL/Tables/FlowSQL/MeterAttributes.sql deleted file mode 100644 index c384b5c..0000000 --- a/DeviceSQL/Tables/FlowSQL/MeterAttributes.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE [FlowSQL].[MeterAttributes] ( - [MeterId] BIGINT NOT NULL, - [AttributeName] VARCHAR (255) NOT NULL, - [AttributeValue] SQL_VARIANT NULL, - [RowVersion] ROWVERSION NULL, - CONSTRAINT [PK_MeterAttributes] PRIMARY KEY CLUSTERED ([MeterId] ASC, [AttributeName] ASC), - CONSTRAINT [FK_MeterAttributes_Meters] FOREIGN KEY ([MeterId]) REFERENCES [FlowSQL].[Meters] ([Id]) -); - diff --git a/DeviceSQL/Tables/FlowSQL/Meters.sql b/DeviceSQL/Tables/FlowSQL/Meters.sql deleted file mode 100644 index a857346..0000000 --- a/DeviceSQL/Tables/FlowSQL/Meters.sql +++ /dev/null @@ -1,8 +0,0 @@ -CREATE TABLE [FlowSQL].[Meters] ( - [Id] BIGINT IDENTITY (1, 1) NOT NULL, - [Name] VARCHAR (255) NOT NULL, - [Description] VARCHAR (255) NOT NULL, - [RowVersion] ROWVERSION NULL, - CONSTRAINT [PK_Meters] PRIMARY KEY CLUSTERED ([Id] ASC) -); - diff --git a/DeviceSQL/Tables/ROCMaster/FloBoss.103.MeterHistory.sql b/DeviceSQL/Tables/ROCMaster/FloBoss.103.MeterHistory.sql deleted file mode 100644 index 4e36bf1..0000000 --- a/DeviceSQL/Tables/ROCMaster/FloBoss.103.MeterHistory.sql +++ /dev/null @@ -1,16 +0,0 @@ -CREATE TABLE [ROCMaster].[FloBoss.103.MeterHistory] ( - [Id] BIGINT IDENTITY (1, 1) NOT NULL, - [ROCMeterId] INT NOT NULL, - [FlowDuration] [ROCMaster].[HistoryRecord] NOT NULL, - [DIfferentialPressure] [ROCMaster].[HistoryRecord] NOT NULL, - [StaticPressure] [ROCMaster].[HistoryRecord] NOT NULL, - [Temperature] [ROCMaster].[HistoryRecord] NOT NULL, - [IMV] [ROCMaster].[HistoryRecord] NOT NULL, - [HwPf] [ROCMaster].[HistoryRecord] NOT NULL, - [Energy] [ROCMaster].[HistoryRecord] NOT NULL, - [Volume] [ROCMaster].[HistoryRecord] NOT NULL, - [RowVersion] ROWVERSION NULL, - CONSTRAINT [PK_FloBoss.103.MeterHistory] PRIMARY KEY CLUSTERED ([Id] ASC), - CONSTRAINT [FK_FloBoss.103.MeterHistory_ROCMeters] FOREIGN KEY ([Id]) REFERENCES [ROCMaster].[ROCMeters] ([Id]) -); - diff --git a/DeviceSQL/Tables/ROCMaster/FloBoss.103.MeterProcessVariableAlarms.sql b/DeviceSQL/Tables/ROCMaster/FloBoss.103.MeterProcessVariableAlarms.sql deleted file mode 100644 index 75a5af6..0000000 --- a/DeviceSQL/Tables/ROCMaster/FloBoss.103.MeterProcessVariableAlarms.sql +++ /dev/null @@ -1,26 +0,0 @@ -CREATE TABLE [ROCMaster].[FloBoss.103.MeterProcessVariableAlarms] ( - [ROCMeterId] BIGINT NOT NULL, - [DateTimeStamp] DATETIMEOFFSET (7) CONSTRAINT [DF_FloBoss.103.MeterProcessVariableAlarms_DateTimeStamp] DEFAULT (sysdatetime()) NOT NULL, - [DifferentialPressure.LowLowAlarm] [ROCMaster].[Parameter] NOT NULL, - [DifferentialPressure.LowAlarm] [ROCMaster].[Parameter] NOT NULL, - [DifferentialPressure.HighAlarm] [ROCMaster].[Parameter] NOT NULL, - [DifferentialPressure.HighHighAlarm] [ROCMaster].[Parameter] NOT NULL, - [DifferentialPressure.RateAlarm] [ROCMaster].[Parameter] NOT NULL, - [DifferentialPressure.Deadband] [ROCMaster].[Parameter] NOT NULL, - [StaticPressure.LowLowAlarm] [ROCMaster].[Parameter] NOT NULL, - [StaticPressure.LowAlarm] [ROCMaster].[Parameter] NOT NULL, - [StaticPressure.HighAlarm] [ROCMaster].[Parameter] NOT NULL, - [StaticPressure.HighHighAlarm] [ROCMaster].[Parameter] NOT NULL, - [StaticPressure.RateAlarm] [ROCMaster].[Parameter] NOT NULL, - [StaticPressure.Deadband] [ROCMaster].[Parameter] NOT NULL, - [Temperature.LowLowAlarm] [ROCMaster].[Parameter] NOT NULL, - [Temperature.LowAlarm] [ROCMaster].[Parameter] NOT NULL, - [Temperature.HighAlarm] [ROCMaster].[Parameter] NOT NULL, - [Temperature.HighHighAlarm] [ROCMaster].[Parameter] NOT NULL, - [Temperature.RateAlarm] [ROCMaster].[Parameter] NOT NULL, - [Temperature.Deadband] [ROCMaster].[Parameter] NOT NULL, - [RowVersion] ROWVERSION NOT NULL, - CONSTRAINT [PK_FloBoss.103.MeterProcessVariableAlarms_1] PRIMARY KEY CLUSTERED ([ROCMeterId] ASC), - CONSTRAINT [FK_FloBoss.103.MeterProcessVariableAlarms_ROCMeters] FOREIGN KEY ([ROCMeterId]) REFERENCES [ROCMaster].[ROCMeters] ([Id]) -); - diff --git a/DeviceSQL/Tables/ROCMaster/FloBoss.103.MeterProcessVariables.sql b/DeviceSQL/Tables/ROCMaster/FloBoss.103.MeterProcessVariables.sql deleted file mode 100644 index 938d01d..0000000 --- a/DeviceSQL/Tables/ROCMaster/FloBoss.103.MeterProcessVariables.sql +++ /dev/null @@ -1,46 +0,0 @@ -CREATE TABLE [ROCMaster].[FloBoss.103.MeterProcessVariables] ( - [ROCMeterId] BIGINT NOT NULL, - [DateTimeStamp] DATETIMEOFFSET (7) CONSTRAINT [DF_FloBoss.103.MeterProcessVariables_DateTimeStamp] DEFAULT (sysdatetime()) NOT NULL, - [DifferentialPressure.AlarmingEnabled] [ROCMaster].[Parameter] NOT NULL, - [DifferentialPressure.ScanningEnabled] [ROCMaster].[Parameter] NOT NULL, - [DifferentialPressure.ScanPeriod] [ROCMaster].[Parameter] NOT NULL, - [DifferentialPressure.Filter] [ROCMaster].[Parameter] NOT NULL, - [DifferentialPressure.Units] [ROCMaster].[Parameter] NOT NULL, - [DifferentialPressure.Raw.Value] [ROCMaster].[Parameter] NOT NULL, - [DifferentialPressure.EU.Value] [ROCMaster].[Parameter] NOT NULL, - [DifferentialPressure.Raw.ZeroValue] [ROCMaster].[Parameter] NOT NULL, - [DifferentialPressure.Raw.SpanValue] [ROCMaster].[Parameter] NOT NULL, - [[DifferentialPressure.EU.ZeroValue] [ROCMaster].[Parameter] NOT NULL, - [DifferentialPressure.EU.SpanValue] [ROCMaster].[Parameter] NOT NULL, - [StaticPressure.AlarmingEnabled] [ROCMaster].[Parameter] NOT NULL, - [StaticPressurePressure.ScanningEnabled] [ROCMaster].[Parameter] NOT NULL, - [StaticPressurePressure.ScanPeriod] [ROCMaster].[Parameter] NOT NULL, - [StaticPressurePressure.Filter] [ROCMaster].[Parameter] NOT NULL, - [StaticPressurePressure.Units] [ROCMaster].[Parameter] NOT NULL, - [StaticPressure.Raw.Value] [ROCMaster].[Parameter] NOT NULL, - [StaticPressure.EU.Value] [ROCMaster].[Parameter] NOT NULL, - [StaticPressure.Raw.ZeroValue] [ROCMaster].[Parameter] NOT NULL, - [StaticPressure.Raw.SpanValue] [ROCMaster].[Parameter] NOT NULL, - [StaticPressure.EU.ZeroValue] [ROCMaster].[Parameter] NOT NULL, - [StaticPressure.EU.SpanValue] [ROCMaster].[Parameter] NOT NULL, - [Temperature.AlarmingEnabled] [ROCMaster].[Parameter] NOT NULL, - [Temperature.ScanningEnabled] [ROCMaster].[Parameter] NOT NULL, - [Temperature.ScanPeriod] [ROCMaster].[Parameter] NOT NULL, - [Temperature.Filter] [ROCMaster].[Parameter] NOT NULL, - [Temperature.Units] [ROCMaster].[Parameter] NOT NULL, - [Temperature.Raw.Value] [ROCMaster].[Parameter] NOT NULL, - [Temperature.EU.Value] [ROCMaster].[Parameter] NOT NULL, - [Temperature.Raw.ZeroValue] [ROCMaster].[Parameter] NOT NULL, - [Temperature.Raw.SpanValue] [ROCMaster].[Parameter] NOT NULL, - [Temperature.EU.ZeroValue] [ROCMaster].[Parameter] NOT NULL, - [Temperature.EU.SpanValue] [ROCMaster].[Parameter] NOT NULL, - [RowVersion] ROWVERSION NULL, - CONSTRAINT [PK_FloBoss.103.MeterProcessVariables_1] PRIMARY KEY CLUSTERED ([ROCMeterId] ASC), - CONSTRAINT [FK_FloBoss.103.MeterProcessVariables_ROCMeters] FOREIGN KEY ([ROCMeterId]) REFERENCES [ROCMaster].[ROCMeters] ([Id]) -); - - -GO -CREATE NONCLUSTERED INDEX [IX_FloBoss.103.MeterProcessVariables] - ON [ROCMaster].[FloBoss.103.MeterProcessVariables]([ROCMeterId] ASC, [DateTimeStamp] ASC); - diff --git a/DeviceSQL/Tables/ROCMaster/ROCChannelGroup.sql b/DeviceSQL/Tables/ROCMaster/ROCChannelGroup.sql deleted file mode 100644 index 6cc901d..0000000 --- a/DeviceSQL/Tables/ROCMaster/ROCChannelGroup.sql +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE [ROCMaster].[ROCChannelGroup] ( - [Id] INT IDENTITY (1, 1) NOT NULL, - [Name] VARCHAR (255) NOT NULL, - [Timeout] INT NOT NULL, - [HostAddress] TINYINT NOT NULL, - [HostGroup] TINYINT NOT NULL, - [RowVersion] ROWVERSION NULL, - CONSTRAINT [PK_ROCChannelGroup] PRIMARY KEY CLUSTERED ([Id] ASC) -); - diff --git a/DeviceSQL/Tables/ROCMaster/ROCChannels.sql b/DeviceSQL/Tables/ROCMaster/ROCChannels.sql deleted file mode 100644 index cc2326d..0000000 --- a/DeviceSQL/Tables/ROCMaster/ROCChannels.sql +++ /dev/null @@ -1,12 +0,0 @@ -CREATE TABLE [ROCMaster].[ROCChannels] ( - [Id] BIGINT IDENTITY (1, 1) NOT NULL, - [Name] VARCHAR (1024) NOT NULL, - [IsSerialPortChannel] BIT NOT NULL, - [PortName] VARCHAR (8) NOT NULL, - [BaudRate] INT NOT NULL, - [HostName] VARCHAR (255) NOT NULL, - [HostPort] INT NOT NULL, - [RowVersion] ROWVERSION NULL, - CONSTRAINT [PK_ROCChannels] PRIMARY KEY CLUSTERED ([Id] ASC) -); - diff --git a/DeviceSQL/Tables/ROCMaster/ROCMeters.sql b/DeviceSQL/Tables/ROCMaster/ROCMeters.sql deleted file mode 100644 index 68263d5..0000000 --- a/DeviceSQL/Tables/ROCMaster/ROCMeters.sql +++ /dev/null @@ -1,14 +0,0 @@ -CREATE TABLE [ROCMaster].[ROCMeters] ( - [Id] BIGINT NOT NULL, - [Name] VARCHAR (255) NOT NULL, - [Description] VARCHAR (255) NOT NULL, - [ROCChannelId] BIGINT NOT NULL, - [ROCChannelGroupId] INT NOT NULL, - [DeviceAddress] TINYINT NOT NULL, - [DeviceGroup] TINYINT NOT NULL, - [RowVersion] ROWVERSION NULL, - CONSTRAINT [PK_ROCMeters] PRIMARY KEY CLUSTERED ([Id] ASC), - CONSTRAINT [FK_ROCMeters_ROCChannelGroup] FOREIGN KEY ([ROCChannelGroupId]) REFERENCES [ROCMaster].[ROCChannelGroup] ([Id]), - CONSTRAINT [FK_ROCMeters_ROCChannels] FOREIGN KEY ([ROCChannelId]) REFERENCES [ROCMaster].[ROCChannels] ([Id]) -); - diff --git a/DeviceSQL/Watchdog/Worker.cs b/DeviceSQL/Watchdog/Worker.cs deleted file mode 100644 index ebd9d2e..0000000 --- a/DeviceSQL/Watchdog/Worker.cs +++ /dev/null @@ -1,144 +0,0 @@ -#region Imported Types - -using DeviceSQL.Device; -using DeviceSQL.IO.Channels; -using DeviceSQL.IOC; -using DeviceSQL.ServiceLocation; -using System; -using System.Collections.Concurrent; -using System.Diagnostics; -using System.Linq; -using System.Threading; - -#endregion - -namespace DeviceSQL.Watchdog -{ - public static class Worker - { - #region Fields - - private static volatile bool isRunning; - private static volatile bool stopRequested; - private static volatile int watchdogCounter; - public readonly static BlockingCollection Channels = new BlockingCollection(); - public readonly static BlockingCollection Devices = new BlockingCollection(); - public readonly static SimpleIOC MainContainer = SimpleIOC.Default; - - #endregion - - #region Properties - - public static int WatchdogCounter - { - get - { - return watchdogCounter; - } - } - - public static bool IsAlive - { - get - { - return isRunning; - } - } - - #endregion - - #region Watchdog Methods - - public static void Run() - { - if (isRunning) - { - return; - } - stopRequested = false; - try - { - ServiceLocator.SetLocatorProvider(() => MainContainer); - MainContainer.Register>(() => { return Channels; }); - MainContainer.Register>(() => { return Devices; }); - - while (!stopRequested) - { - isRunning = true; - if (MainContainer != SimpleIOC.Default) - { - Trace.TraceWarning("SimpleIOC \"Default\" object reference changed"); - } - if (Channels != MainContainer.GetInstance>()) - { - Trace.TraceWarning("Channels object reference changed"); - } - if (Devices != MainContainer.GetInstance>()) - { - Trace.TraceWarning("Devices object reference changed"); - } - if (watchdogCounter >= (int.MaxValue - 1)) - { - watchdogCounter = 0; - } - else - { - watchdogCounter++; - } - TimedThreadBlocker.Wait(300); - } - } - catch (ThreadAbortException taex) - { - Trace.TraceError(string.Format("Watchdog thread aborted: {0}", taex.Message)); - } - finally - { - if (isRunning) - { - isRunning = false; - var channelList = Channels.ToList(); - var deviceList = Devices.ToList(); - channelList.ToList().ForEach((channel) => - { - try - { - channel.Dispose(); - Channels.TryTake(out channel); - } - catch (Exception ex) - { - Trace.TraceError(string.Format("Error removing channel: {0}", ex.Message)); - } - }); - deviceList.ToList().ForEach((device) => - { - try - { - Devices.TryTake(out device); - } - catch (Exception ex) - { - Trace.TraceError(string.Format("Error removing device: {0}", ex.Message)); - } - }); - MainContainer.Unregister>(); - MainContainer.Unregister>(); - } - } - - } - - public static void Stop() - { - while (isRunning) - { - stopRequested = true; - TimedThreadBlocker.Wait(100); - } - isRunning = false; - } - - #endregion - } -} From e9663201efdab6cb4889dda3118655a0a43ef50f Mon Sep 17 00:00:00 2001 From: Jason Craig Date: Mon, 20 Aug 2018 19:33:48 -0600 Subject: [PATCH 2/7] Update ReadMe.md --- Version 1.0/ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Version 1.0/ReadMe.md b/Version 1.0/ReadMe.md index f4ff6c5..e9bfab3 100644 --- a/Version 1.0/ReadMe.md +++ b/Version 1.0/ReadMe.md @@ -17,4 +17,4 @@ ##### CREATE LOGIN [DeviceSqlClrLogin] FROM ASYMMETRIC KEY [DeviceSqlKey] ##### GRANT UNSAFE ASSEMBLY TO [DeviceSqlClrLogin] - +You must enable the Lock Pages In Memory option: https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/enable-the-lock-pages-in-memory-option-windows?view=sql-server-2017 From b58a570918cc29187231a63e69793d49196a8dc6 Mon Sep 17 00:00:00 2001 From: Jason Craig Date: Tue, 24 Sep 2019 02:42:29 -0600 Subject: [PATCH 3/7] Add OPROC DeviceSQL Service --- .../DeviceSQL-Key.snk => DeviceSQL-Key.snk | Bin .../DeviceSQL.ChannelManager.sqlproj | 71 ++ .../Properties/AssemblyInfo.cs | 24 + .../DeviceSQL.DeviceManager.sqlproj | 72 ++ .../Properties/AssemblyInfo.cs | 24 + .../Device/IMaster.cs | 0 .../Device/IMessage.cs | 0 .../DeviceSQL.Devices.Common.csproj | 41 +- .../IO/Channels/ChannelTraceEventArgs.cs | 23 + .../IO/Channels/ChannelTraceListener.cs | 6 +- .../IO/Channels/HexConverter.cs | 5 + .../IO/Channels/IChannel.cs | 2 + .../IO/Channels/IMuxChannel.cs | 3 +- .../IO/Channels/SerialPortChannel.cs | 1 + .../IO/Channels/SerialPortMuxChannel.cs | 142 +++ .../IO/Channels/TcpChannel.cs | 18 +- .../IO/Channels/TcpMuxChannel.cs | 54 +- .../IO/Channels/TimedThreadBlocker.cs | 0 .../IO/Channels/Transport/ITransport.cs | 0 .../Properties/AssemblyInfo.cs | 13 +- DeviceSQL.Devices.Common/packages.config | 4 + .../Crc16.cs | 0 .../Data/BooleanRegister.cs | 0 .../Data/CoilRegister.cs | 0 .../Data/DiscreteInputRegister.cs | 0 .../Data/EventArchiveRecord.cs | 2 +- .../Data/FloatRegister.cs | 4 +- .../Data/HistoryArchiveRecord.cs | 2 +- .../Data/HoldingRegister.cs | 0 .../Data/IModbusRegisterData.cs | 0 .../Data/InputRegister.cs | 0 .../Data/LongRegister.cs | 4 +- .../Data/ModbusAddress.cs | 0 .../Data/ModbusRegister.cs | 2 +- .../Data/ShortRegister.cs | 2 +- .../Data/StringRegister.cs | 4 +- .../Device.cs | 0 .../DeviceSQL.Devices.Modbus.csproj | 110 ++ .../IO/Transport/Transport.cs | 0 .../Message/IModbusMessage.cs | 0 .../Message/IModbusRequestMessage.cs | 0 .../Message/IModbusResponseMessage.cs | 0 .../Message/ModbusErrorResponse.cs | 0 .../Message/ModbusMessage.cs | 0 .../Message/ModbusMessageFactory.cs | 0 .../Message/ReadCoilRegistersRequest.cs | 0 .../Message/ReadCoilRegistersResponse.cs | 0 .../ReadDiscreteInputRegistersRequest.cs | 0 .../ReadDiscreteInputRegistersResponse.cs | 0 .../Message/ReadEventArchiveRequest.cs | 0 .../Message/ReadEventArchiveResponse.cs | 0 .../Message/ReadFloatsRequest.cs | 0 .../Message/ReadFloatsResponse.cs | 0 .../Message/ReadHistoryArchiveRequest.cs | 0 .../Message/ReadHistoryArchiveResponse.cs | 0 .../Message/ReadHoldingRegistersRequest.cs | 0 .../Message/ReadHoldingRegistersResponse.cs | 0 .../Message/ReadInputRegistersRequest.cs | 0 .../Message/ReadInputRegistersResponse.cs | 0 .../Message/ReadLongsRequest.cs | 0 .../Message/ReadLongsResponse.cs | 0 .../Message/ReadShortsRequest.cs | 0 .../Message/ReadShortsResponse.cs | 0 .../Message/ReadStringRequest.cs | 0 .../Message/ReadStringResponse.cs | 0 .../Message/WriteBooleanRequest.cs | 0 .../Message/WriteBooleanResponse.cs | 0 .../Message/WriteFloatsRequest.cs | 0 .../Message/WriteFloatsResponse.cs | 0 .../ModbusConverter.cs | 0 .../ModbusMaster.cs | 0 .../ModbusSlaveException.cs | 0 .../Properties/AssemblyInfo.cs | 37 + .../Data/Ac10Parameter.cs | 12 +- .../Data/Ac12Parameter.cs | 4 + .../Data/Ac20Parameter.cs | 4 + .../Data/Ac30Parameter.cs | 4 + .../Data/Ac3Parameter.cs | 4 + .../Data/Ac40Parameter.cs | 4 + .../Data/Ac7Parameter.cs | 4 + .../Data/AlarmRecord.cs | 8 +- .../Data/ArchiveInfo.cs | 6 +- .../Data/AuditLogRecord.cs | 4 + .../Data/BinParameter.cs | 4 + .../Data/DoubleParameter.cs | 4 + .../Data/EventRecord.cs | 8 +- .../Data/FlpParameter.cs | 4 + .../Data/FstCodeChunk.cs | 4 + .../Data/FstHeaderInfo.cs | 6 +- .../Data/HistoryPointConfiguration.cs | 6 +- .../Data/HistoryRecord.cs | 4 + .../Data/IRocParameterData.cs | 4 + .../Data/Int16Parameter.cs | 4 + .../Data/Int32Parameter.cs | 4 + .../Data/Int8Parameter.cs | 4 + .../Data/Parameter.cs | 4 + .../Data/ParameterType.cs | 6 +- .../Data/RocPlusAlarmRecord.cs | 4 + .../Data/RocPlusEventRecord.cs | 6 +- .../Data/RocPlusHistoryRecord.cs | 4 + .../Data/TimeParameter.cs | 4 + .../ROC => DeviceSQL.Devices.ROC}/Data/Tlp.cs | 6 +- .../Data/TlpParameter.cs | 6 +- .../Data/UInt16Parameter.cs | 4 + .../Data/UInt32Parameter.cs | 4 + .../Data/UInt8Parameter.cs | 6 +- .../ROC => DeviceSQL.Devices.ROC}/Device.cs | 0 .../DeviceSQL.Devices.ROC.csproj | 156 +++ .../FST/Arguments/ArgumentBase.cs | 0 .../FST/Arguments/ArgumentDataType.cs | 0 .../FST/Arguments/ArgumentType.cs | 0 .../FST/Arguments/DatabasePoint.cs | 3 +- .../DatabasePointOrConstantValueArgument.cs | 0 .../FST/Arguments/NullArgument.cs | 0 .../FST/Instructions/AddInstruction.cs | 0 .../FST/Instructions/InstructionBase.cs | 0 .../FST/Instructions/InstructionCategory.cs | 0 .../FST/Instructions/InstructionType.cs | 0 .../IO/Transport/Transport.cs | 0 .../Message/IRocMessage.cs | 0 .../Message/IRocRequestMessage.cs | 0 .../Message/IRocResponseMessage.cs | 0 .../Message/OpCode007Request.cs | 0 .../Message/OpCode007Response.cs | 0 .../Message/OpCode008Request.cs | 0 .../Message/OpCode008Response.cs | 0 .../Message/OpCode017Request.cs | 0 .../Message/OpCode017Response.cs | 0 .../Message/OpCode080Function.cs | 0 .../Message/OpCode080Request.cs | 0 .../Message/OpCode080Response.cs | 0 .../Message/OpCode118Request.cs | 0 .../Message/OpCode118Response.cs | 0 .../Message/OpCode119Request.cs | 0 .../Message/OpCode119Response.cs | 0 .../Message/OpCode120Request.cs | 0 .../Message/OpCode120Response.cs | 0 .../Message/OpCode121Request.cs | 0 .../Message/OpCode121Response.cs | 0 .../Message/OpCode122Request.cs | 0 .../Message/OpCode122Response.cs | 0 .../Message/OpCode126Request.cs | 0 .../Message/OpCode126Response.cs | 0 .../Message/OpCode130Request.cs | 0 .../Message/OpCode130Response.cs | 0 .../Message/OpCode131Request.cs | 0 .../Message/OpCode131Response.cs | 0 .../Message/OpCode132Request.cs | 0 .../Message/OpCode132Response.cs | 0 .../Message/OpCode136Request.cs | 0 .../Message/OpCode136Response.cs | 0 .../Message/OpCode139Request.cs | 0 .../Message/OpCode139Response.cs | 0 .../Message/OpCode165Request .cs | 0 .../Message/OpCode165Response.cs | 0 .../Message/OpCode166Request.cs | 0 .../Message/OpCode166Response.cs | 0 .../Message/OpCode167Request.cs | 0 .../Message/OpCode167Response.cs | 0 .../Message/OpCode180Request.cs | 0 .../Message/OpCode180Response.cs | 0 .../Message/OpCode181Request.cs | 0 .../Message/OpCode181Response.cs | 0 .../Message/OpCode255Response.cs | 0 .../Message/ParameterDatabase.cs | 6 +- .../Message/RocMessage.cs | 0 .../Message/RocMessageFactory.cs | 0 .../OpCode255Exception.cs | 0 .../Properties/AssemblyInfo.cs | 13 +- .../ROCMaster.cs | 0 .../Utility/Crc16.cs | 0 DeviceSQL.Devices/Device/ROC/Crc16.cs | 110 -- DeviceSQL.Devices/DeviceSQL.Devices.csproj | 206 ---- .../IO/Channels/ChannelTraceEventArgs.cs | 23 - .../IO/Channels/SerialPortMuxChannel.cs | 139 --- .../DeviceSQL.ModbusMaster.sqlproj | 100 ++ DeviceSQL.ModbusMaster/Functions/ReadCoils.cs | 22 + .../Functions/ReadDiscreteInputs.cs | 22 + .../Functions/ReadEventArchiveRecords.cs | 21 + .../Functions/ReadFloats.cs | 22 + .../Functions/ReadHistoryArchiveRecord.cs | 22 + .../Functions/ReadHoldings.cs | 22 + .../Functions/ReadInputs.cs | 22 + DeviceSQL.ModbusMaster/Functions/ReadLongs.cs | 22 + .../Functions/ReadShorts.cs | 22 + .../Functions/ReadString.cs | 23 + .../Functions/WriteBoolean.cs | 22 + .../Functions/WriteFloats.cs | 22 + .../Properties/AssemblyInfo.cs | 24 + .../Schemas/ModbusMaster.sql | 1 + .../DeviceSQL.ROCMaster.sqlproj | 131 +++ .../Functions/ClearAuditLogEventFlags.cs | 19 + DeviceSQL.ROCMaster/Functions/GetAlarms.cs | 21 + .../Functions/GetArchiveInfo.cs | 21 + .../Functions/GetAuditLogRecords.cs | 21 + .../Functions/GetCurrentROCPlusAlarmIndex.cs | 19 + .../Functions/GetCurrentROCPlusEventIndex.cs | 19 + .../GetCurrentROCPlusHistorySegmentIndex.cs | 19 + .../Functions/GetDoubleValue.cs | 21 + DeviceSQL.ROCMaster/Functions/GetEvents.cs | 21 + .../Functions/GetFloatValue.cs | 22 + .../Functions/GetFstInformation.cs | 44 + DeviceSQL.ROCMaster/Functions/GetHistory.cs | 21 + .../Functions/GetInt16Value.cs | 21 + .../Functions/GetInt32Value.cs | 21 + DeviceSQL.ROCMaster/Functions/GetInt8Value.cs | 21 + .../Functions/GetMinutelyHistory.cs | 22 + .../Functions/GetROCPlusAlarms.cs | 21 + .../GetROCPlusConfiguredHistoryPoints.cs | 21 + .../Functions/GetROCPlusEvents.cs | 21 + .../Functions/GetROCPlusHistory.cs | 21 + .../GetROCPlusHistoryByHistoryPointArray.cs | 21 + .../Functions/GetRealTimeClockValue.cs | 19 + .../GetRealTimeClockValueWithCentury.cs | 19 + .../Functions/GetStringValue.cs | 46 + DeviceSQL.ROCMaster/Functions/GetTimeValue.cs | 21 + .../Functions/GetUInt16Value.cs | 21 + .../Functions/GetUInt32Value.cs | 21 + .../Functions/GetUInt8Value.cs | 21 + .../Functions/ReadParameters.cs | 101 ++ .../Functions/SetFloatValue.cs | 21 + .../Functions/SetInt16Value.cs | 21 + .../Functions/SetInt32Value.cs | 21 + DeviceSQL.ROCMaster/Functions/SetInt8Value.cs | 21 + .../Functions/SetOperatorIdentification.cs | 22 + .../Functions/SetRealTimeClock.cs | 20 + .../Functions/SetStringValue.cs | 48 + DeviceSQL.ROCMaster/Functions/SetTimeValue.cs | 21 + .../Functions/SetUInt16Value.cs | 21 + .../Functions/SetUInt32Value.cs | 21 + .../Functions/SetUInt8Value.cs | 21 + .../Functions/WriteParameters.cs | 93 ++ .../Properties/AssemblyInfo.cs | 24 + .../Schemas/ROCMaster.sql | 0 DeviceSQL.SQLTypes.Modbus/BooleanRegister.cs | 131 +++ .../BooleanRegisterArray.cs | 165 +++ DeviceSQL.SQLTypes.Modbus/CoilRegister.cs | 131 +++ .../CoilRegisterArray.cs | 164 +++ .../DeviceSQL.SQLTypes.Modbus.csproj | 122 +++ .../DiscreteInputRegister.cs | 131 +++ .../DiscreteInputRegisterArray.cs | 165 +++ .../EventArchiveRecord.cs | 145 +++ .../EventArchiveRecordArray.cs | 165 +++ DeviceSQL.SQLTypes.Modbus/FloatRegister.cs | 147 +++ .../FloatRegisterArray.cs | 165 +++ .../HistoryArchiveRecord.cs | 140 +++ .../HistoryArchiveRecordArray.cs | 165 +++ DeviceSQL.SQLTypes.Modbus/HoldingRegister.cs | 139 +++ .../HoldingRegisterArray.cs | 208 ++++ DeviceSQL.SQLTypes.Modbus/InputRegister.cs | 139 +++ .../InputRegisterArray.cs | 208 ++++ DeviceSQL.SQLTypes.Modbus/LongRegister.cs | 147 +++ .../LongRegisterArray.cs | 166 +++ DeviceSQL.SQLTypes.Modbus/ModbusAddress.cs | 118 +++ .../Properties/AssemblyInfo.cs | 23 +- DeviceSQL.SQLTypes.Modbus/ShortRegister.cs | 139 +++ .../ShortRegisterArray.cs | 165 +++ DeviceSQL.SQLTypes.Modbus/StringRegister.cs | 141 +++ .../StringRegisterArray.cs | 165 +++ DeviceSQL.SQLTypes.ROC/AlarmRecord.cs | 163 +++ DeviceSQL.SQLTypes.ROC/AlarmRecordArray.cs | 162 +++ DeviceSQL.SQLTypes.ROC/ArchiveInformation.cs | 224 ++++ DeviceSQL.SQLTypes.ROC/AuditLogRecord.cs | 384 +++++++ DeviceSQL.SQLTypes.ROC/AuditLogRecordArray.cs | 162 +++ DeviceSQL.SQLTypes.ROC/DeviceSQL-Key.snk | Bin 0 -> 596 bytes .../DeviceSQL.SQLTypes.ROC.csproj | 180 ++++ DeviceSQL.SQLTypes.ROC/EventRecord.cs | 370 +++++++ DeviceSQL.SQLTypes.ROC/EventRecordArray.cs | 162 +++ DeviceSQL.SQLTypes.ROC/FSTInformation.cs | 163 +++ DeviceSQL.SQLTypes.ROC/HistoryRecord.cs | 145 +++ DeviceSQL.SQLTypes.ROC/HistoryRecordArray.cs | 162 +++ DeviceSQL.SQLTypes.ROC/Parameter.cs | 464 +++++++++ DeviceSQL.SQLTypes.ROC/ParameterArray.cs | 166 +++ .../Properties/AssemblyInfo.cs | 13 +- DeviceSQL.SQLTypes.ROC/ROCPlusAlarmRecord.cs | 250 +++++ .../ROCPlusAlarmRecordArray.cs | 162 +++ DeviceSQL.SQLTypes.ROC/ROCPlusEventRecord.cs | 363 +++++++ .../ROCPlusEventRecordArray.cs | 162 +++ .../ROCPlusHistoryPointArray.cs | 159 +++ .../ROCPlusHistoryRecord.cs | 157 +++ .../ROCPlusHistoryRecordArray.cs | 162 +++ DeviceSQL.SQLTypes/DeviceSQL.SQLTypes.csproj | 3 +- DeviceSQL.SQLTypes/Properties/AssemblyInfo.cs | 8 +- DeviceSQL.Service/API/ChannelController.cs | 128 +++ DeviceSQL.Service/App.config | 34 +- DeviceSQL.Service/DeviceSQL.Service.csproj | 89 +- ...signer.cs => DeviceSqlService.Designer.cs} | 9 +- DeviceSQL.Service/DeviceSqlService.cs | 66 ++ .../DeviceSqlService.resx | 16 +- DeviceSQL.Service/IOC/ISimpleIOC.cs | 228 +++++ DeviceSQL.Service/IOC/PreferredConstructor.cs | 31 + DeviceSQL.Service/IOC/SimpleIOC.cs | 961 ++++++++++++++++++ DeviceSQL.Service/Program.cs | 2 +- .../ProjectInstaller.Designer.cs | 6 +- DeviceSQL.Service/ProjectInstaller.resx | 2 +- DeviceSQL.Service/Properties/AssemblyInfo.cs | 9 +- .../Properties/Settings.Designer.cs | 31 +- .../Properties/Settings.settings | 9 + DeviceSQL.Service/Service1.cs | 28 - .../ServiceLocation/ActivationException.cs | 44 + .../ServiceLocation/IServiceLocator.cs | 75 ++ .../ServiceLocation/ServiceLocator.cs | 52 + .../ServiceLocation/ServiceLocatorImplBase.cs | 181 ++++ .../ServiceLocation/ServiceLocatorProvider.cs | 10 + DeviceSQL.Service/Startup.cs | 16 + DeviceSQL.Service/packages.config | 13 + DeviceSQL.Services/App.config | 43 - DeviceSQL.Services/DeviceSQL.Services.csproj | 83 -- DeviceSQL.Services/IService.cs | 23 - DeviceSQL.Services/Service.cs | 39 - DeviceSQL.TestHarness/App.config | 6 - .../DeviceSQL.TestHarness.csproj | 87 -- DeviceSQL.TestHarness/Program.cs | 17 - .../SerialPortChannelTest.cs | 47 - DeviceSQL.TestHarness/TcpChannelTest.cs | 36 - .../App.config | 6 - .../Program.cs | 53 - .../App.config | 6 - .../App.xaml | 17 - .../App.xaml.cs | 24 - .../Converter/BoolToVisibilityConverter.cs | 24 - .../NegatedBoolToVisibilityConverter.cs | 24 - ...L.Utilities.RealFLOMappingGenerator.csproj | 337 ------ .../Interop/HelpDocument.cs | 19 - .../Interop/Main.cs | 13 - .../Key.snk | Bin 596 -> 0 bytes .../MainWindow.xaml | 169 --- .../MainWindow.xaml.cs | 87 -- .../Model/DataService.cs | 175 ---- .../Model/DialogService.cs | 191 ---- .../Model/Enron/Archive.cs | 19 - .../Model/Enron/ArchiveField.cs | 13 - .../Model/Enron/Event.cs | 14 - .../Model/Enron/Register.cs | 13 - .../Model/Map.cs | 67 -- .../Model/TeleBUS/Archive.cs | 13 - .../Model/TeleBUS/ArchiveCommand.cs | 13 - .../Model/TeleBUS/ArchiveField.cs | 14 - .../Model/TeleBUS/ConfigurationCommand.cs | 13 - .../Model/TeleBUS/Event.cs | 14 - .../Model/TeleBUS/Register.cs | 14 - .../Properties/AssemblyInfo.cs | 55 - .../Properties/Resources.Designer.cs | 71 -- .../Properties/Settings.settings | 7 - .../Properties/app.manifest | 70 -- .../RealFLO.ico | Bin 372526 -> 0 bytes .../RealFLO_24x24.png | Bin 351 -> 0 bytes .../Resources/Images/RealFLO.ico | Bin 372526 -> 0 bytes .../Resources/Images/RealFLO_24x24.png | Bin 577 -> 0 bytes .../Resources/Images/RealFLO_32x32.png | Bin 677 -> 0 bytes .../Resources/Scripts/rfm.index.js | 3 - .../Resources/Styles/rfm.style.css | 84 -- .../ViewModel/Enron/ArchiveViewModel.cs | 35 - .../ViewModel/Enron/EventViewModel.cs | 35 - .../ViewModel/Enron/RegisterViewModel.cs | 37 - .../ViewModel/ExportMapWizardViewModel.cs | 13 - .../ViewModel/MainViewModel.cs | 638 ------------ .../ViewModel/NewMapWizardViewModel.cs | 140 --- .../ViewModel/TeleBUS/ArchiveViewModel.cs | 35 - .../ViewModel/TeleBUS/EventViewModel.cs | 35 - .../ViewModel/TeleBUS/RegisterViewModel.cs | 35 - .../ViewModel/TrackableViewModelBase.cs | 74 -- .../ViewModel/ViewModelLocator.cs | 68 -- .../Wizard/NewMapWizard.xaml | 134 --- .../Wizard/NewMapWizard.xaml.cs | 34 - .../packages.config | 7 - DeviceSQL.sln | 162 +-- DeviceSQL/DeviceSQL.sqlproj | 18 +- DeviceSQL/Properties/AssemblyInfo.cs | 9 +- DeviceSQL/Schemas/ChannelManager.sql | 1 - DeviceSQL/Schemas/DeviceManager.sql | 1 - DeviceSQL/Schemas/ModbusMaster.sql | 1 - DeviceSQL/Schemas/Watchdog.sql | 1 - 373 files changed, 12661 insertions(+), 4067 deletions(-) rename DeviceSQL/DeviceSQL-Key.snk => DeviceSQL-Key.snk (100%) create mode 100644 DeviceSQL.ChannelManager/DeviceSQL.ChannelManager.sqlproj create mode 100644 DeviceSQL.ChannelManager/Properties/AssemblyInfo.cs create mode 100644 DeviceSQL.DeviceManager/DeviceSQL.DeviceManager.sqlproj create mode 100644 DeviceSQL.DeviceManager/Properties/AssemblyInfo.cs rename {DeviceSQL.Devices => DeviceSQL.Devices.Common}/Device/IMaster.cs (100%) rename {DeviceSQL.Devices => DeviceSQL.Devices.Common}/Device/IMessage.cs (100%) rename DeviceSQL.Utilities.DeploymentScriptFormatter/DeviceSQL.Utilities.DeploymentScriptFormatter.csproj => DeviceSQL.Devices.Common/DeviceSQL.Devices.Common.csproj (53%) create mode 100644 DeviceSQL.Devices.Common/IO/Channels/ChannelTraceEventArgs.cs rename {DeviceSQL.Devices => DeviceSQL.Devices.Common}/IO/Channels/ChannelTraceListener.cs (93%) rename {DeviceSQL.Devices => DeviceSQL.Devices.Common}/IO/Channels/HexConverter.cs (86%) rename {DeviceSQL.Devices => DeviceSQL.Devices.Common}/IO/Channels/IChannel.cs (92%) rename {DeviceSQL.Devices => DeviceSQL.Devices.Common}/IO/Channels/IMuxChannel.cs (71%) rename {DeviceSQL.Devices => DeviceSQL.Devices.Common}/IO/Channels/SerialPortChannel.cs (99%) create mode 100644 DeviceSQL.Devices.Common/IO/Channels/SerialPortMuxChannel.cs rename {DeviceSQL.Devices => DeviceSQL.Devices.Common}/IO/Channels/TcpChannel.cs (97%) rename {DeviceSQL.Devices => DeviceSQL.Devices.Common}/IO/Channels/TcpMuxChannel.cs (89%) rename {DeviceSQL.Devices => DeviceSQL.Devices.Common}/IO/Channels/TimedThreadBlocker.cs (100%) rename {DeviceSQL.Devices => DeviceSQL.Devices.Common}/IO/Channels/Transport/ITransport.cs (100%) rename {DeviceSQL.Devices => DeviceSQL.Devices.Common}/Properties/AssemblyInfo.cs (74%) create mode 100644 DeviceSQL.Devices.Common/packages.config rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Crc16.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Data/BooleanRegister.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Data/CoilRegister.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Data/DiscreteInputRegister.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Data/EventArchiveRecord.cs (98%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Data/FloatRegister.cs (98%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Data/HistoryArchiveRecord.cs (97%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Data/HoldingRegister.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Data/IModbusRegisterData.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Data/InputRegister.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Data/LongRegister.cs (98%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Data/ModbusAddress.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Data/ModbusRegister.cs (98%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Data/ShortRegister.cs (98%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Data/StringRegister.cs (96%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Device.cs (100%) create mode 100644 DeviceSQL.Devices.Modbus/DeviceSQL.Devices.Modbus.csproj rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/IO/Transport/Transport.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/IModbusMessage.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/IModbusRequestMessage.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/IModbusResponseMessage.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ModbusErrorResponse.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ModbusMessage.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ModbusMessageFactory.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadCoilRegistersRequest.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadCoilRegistersResponse.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadDiscreteInputRegistersRequest.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadDiscreteInputRegistersResponse.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadEventArchiveRequest.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadEventArchiveResponse.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadFloatsRequest.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadFloatsResponse.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadHistoryArchiveRequest.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadHistoryArchiveResponse.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadHoldingRegistersRequest.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadHoldingRegistersResponse.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadInputRegistersRequest.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadInputRegistersResponse.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadLongsRequest.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadLongsResponse.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadShortsRequest.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadShortsResponse.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadStringRequest.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/ReadStringResponse.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/WriteBooleanRequest.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/WriteBooleanResponse.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/WriteFloatsRequest.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/Message/WriteFloatsResponse.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/ModbusConverter.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/ModbusMaster.cs (100%) rename {DeviceSQL.Devices/Device/Modbus => DeviceSQL.Devices.Modbus}/ModbusSlaveException.cs (100%) create mode 100644 DeviceSQL.Devices.Modbus/Properties/AssemblyInfo.cs rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/Ac10Parameter.cs (86%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/Ac12Parameter.cs (93%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/Ac20Parameter.cs (93%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/Ac30Parameter.cs (93%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/Ac3Parameter.cs (93%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/Ac40Parameter.cs (93%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/Ac7Parameter.cs (93%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/AlarmRecord.cs (99%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/ArchiveInfo.cs (96%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/AuditLogRecord.cs (91%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/BinParameter.cs (92%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/DoubleParameter.cs (96%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/EventRecord.cs (99%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/FlpParameter.cs (96%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/FstCodeChunk.cs (91%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/FstHeaderInfo.cs (86%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/HistoryPointConfiguration.cs (88%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/HistoryRecord.cs (96%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/IRocParameterData.cs (80%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/Int16Parameter.cs (92%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/Int32Parameter.cs (92%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/Int8Parameter.cs (93%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/Parameter.cs (97%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/ParameterType.cs (83%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/RocPlusAlarmRecord.cs (98%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/RocPlusEventRecord.cs (99%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/RocPlusHistoryRecord.cs (95%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/TimeParameter.cs (93%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/Tlp.cs (95%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/TlpParameter.cs (87%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/UInt16Parameter.cs (92%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/UInt32Parameter.cs (93%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Data/UInt8Parameter.cs (85%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Device.cs (100%) create mode 100644 DeviceSQL.Devices.ROC/DeviceSQL.Devices.ROC.csproj rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/FST/Arguments/ArgumentBase.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/FST/Arguments/ArgumentDataType.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/FST/Arguments/ArgumentType.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/FST/Arguments/DatabasePoint.cs (93%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/FST/Arguments/DatabasePointOrConstantValueArgument.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/FST/Arguments/NullArgument.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/FST/Instructions/AddInstruction.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/FST/Instructions/InstructionBase.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/FST/Instructions/InstructionCategory.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/FST/Instructions/InstructionType.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/IO/Transport/Transport.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/IRocMessage.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/IRocRequestMessage.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/IRocResponseMessage.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode007Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode007Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode008Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode008Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode017Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode017Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode080Function.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode080Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode080Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode118Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode118Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode119Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode119Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode120Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode120Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode121Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode121Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode122Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode122Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode126Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode126Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode130Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode130Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode131Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode131Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode132Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode132Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode136Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode136Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode139Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode139Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode165Request .cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode165Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode166Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode166Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode167Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode167Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode180Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode180Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode181Request.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode181Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/OpCode255Response.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/ParameterDatabase.cs (99%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/RocMessage.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Message/RocMessageFactory.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/OpCode255Exception.cs (100%) rename {DeviceSQL.TestHarness => DeviceSQL.Devices.ROC}/Properties/AssemblyInfo.cs (74%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/ROCMaster.cs (100%) rename {DeviceSQL.Devices/Device/ROC => DeviceSQL.Devices.ROC}/Utility/Crc16.cs (100%) delete mode 100644 DeviceSQL.Devices/Device/ROC/Crc16.cs delete mode 100644 DeviceSQL.Devices/DeviceSQL.Devices.csproj delete mode 100644 DeviceSQL.Devices/IO/Channels/ChannelTraceEventArgs.cs delete mode 100644 DeviceSQL.Devices/IO/Channels/SerialPortMuxChannel.cs create mode 100644 DeviceSQL.ModbusMaster/DeviceSQL.ModbusMaster.sqlproj create mode 100644 DeviceSQL.ModbusMaster/Functions/ReadCoils.cs create mode 100644 DeviceSQL.ModbusMaster/Functions/ReadDiscreteInputs.cs create mode 100644 DeviceSQL.ModbusMaster/Functions/ReadEventArchiveRecords.cs create mode 100644 DeviceSQL.ModbusMaster/Functions/ReadFloats.cs create mode 100644 DeviceSQL.ModbusMaster/Functions/ReadHistoryArchiveRecord.cs create mode 100644 DeviceSQL.ModbusMaster/Functions/ReadHoldings.cs create mode 100644 DeviceSQL.ModbusMaster/Functions/ReadInputs.cs create mode 100644 DeviceSQL.ModbusMaster/Functions/ReadLongs.cs create mode 100644 DeviceSQL.ModbusMaster/Functions/ReadShorts.cs create mode 100644 DeviceSQL.ModbusMaster/Functions/ReadString.cs create mode 100644 DeviceSQL.ModbusMaster/Functions/WriteBoolean.cs create mode 100644 DeviceSQL.ModbusMaster/Functions/WriteFloats.cs create mode 100644 DeviceSQL.ModbusMaster/Properties/AssemblyInfo.cs create mode 100644 DeviceSQL.ModbusMaster/Schemas/ModbusMaster.sql create mode 100644 DeviceSQL.ROCMaster/DeviceSQL.ROCMaster.sqlproj create mode 100644 DeviceSQL.ROCMaster/Functions/ClearAuditLogEventFlags.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetAlarms.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetArchiveInfo.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetAuditLogRecords.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetCurrentROCPlusAlarmIndex.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetCurrentROCPlusEventIndex.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetCurrentROCPlusHistorySegmentIndex.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetDoubleValue.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetEvents.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetFloatValue.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetFstInformation.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetHistory.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetInt16Value.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetInt32Value.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetInt8Value.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetMinutelyHistory.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetROCPlusAlarms.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetROCPlusConfiguredHistoryPoints.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetROCPlusEvents.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetROCPlusHistory.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetROCPlusHistoryByHistoryPointArray.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetRealTimeClockValue.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetRealTimeClockValueWithCentury.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetStringValue.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetTimeValue.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetUInt16Value.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetUInt32Value.cs create mode 100644 DeviceSQL.ROCMaster/Functions/GetUInt8Value.cs create mode 100644 DeviceSQL.ROCMaster/Functions/ReadParameters.cs create mode 100644 DeviceSQL.ROCMaster/Functions/SetFloatValue.cs create mode 100644 DeviceSQL.ROCMaster/Functions/SetInt16Value.cs create mode 100644 DeviceSQL.ROCMaster/Functions/SetInt32Value.cs create mode 100644 DeviceSQL.ROCMaster/Functions/SetInt8Value.cs create mode 100644 DeviceSQL.ROCMaster/Functions/SetOperatorIdentification.cs create mode 100644 DeviceSQL.ROCMaster/Functions/SetRealTimeClock.cs create mode 100644 DeviceSQL.ROCMaster/Functions/SetStringValue.cs create mode 100644 DeviceSQL.ROCMaster/Functions/SetTimeValue.cs create mode 100644 DeviceSQL.ROCMaster/Functions/SetUInt16Value.cs create mode 100644 DeviceSQL.ROCMaster/Functions/SetUInt32Value.cs create mode 100644 DeviceSQL.ROCMaster/Functions/SetUInt8Value.cs create mode 100644 DeviceSQL.ROCMaster/Functions/WriteParameters.cs create mode 100644 DeviceSQL.ROCMaster/Properties/AssemblyInfo.cs rename {DeviceSQL => DeviceSQL.ROCMaster}/Schemas/ROCMaster.sql (100%) create mode 100644 DeviceSQL.SQLTypes.Modbus/BooleanRegister.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/BooleanRegisterArray.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/CoilRegister.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/CoilRegisterArray.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/DeviceSQL.SQLTypes.Modbus.csproj create mode 100644 DeviceSQL.SQLTypes.Modbus/DiscreteInputRegister.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/DiscreteInputRegisterArray.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/EventArchiveRecord.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/EventArchiveRecordArray.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/FloatRegister.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/FloatRegisterArray.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/HistoryArchiveRecord.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/HistoryArchiveRecordArray.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/HoldingRegister.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/HoldingRegisterArray.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/InputRegister.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/InputRegisterArray.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/LongRegister.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/LongRegisterArray.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/ModbusAddress.cs rename {DeviceSQL.Services => DeviceSQL.SQLTypes.Modbus}/Properties/AssemblyInfo.cs (69%) create mode 100644 DeviceSQL.SQLTypes.Modbus/ShortRegister.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/ShortRegisterArray.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/StringRegister.cs create mode 100644 DeviceSQL.SQLTypes.Modbus/StringRegisterArray.cs create mode 100644 DeviceSQL.SQLTypes.ROC/AlarmRecord.cs create mode 100644 DeviceSQL.SQLTypes.ROC/AlarmRecordArray.cs create mode 100644 DeviceSQL.SQLTypes.ROC/ArchiveInformation.cs create mode 100644 DeviceSQL.SQLTypes.ROC/AuditLogRecord.cs create mode 100644 DeviceSQL.SQLTypes.ROC/AuditLogRecordArray.cs create mode 100644 DeviceSQL.SQLTypes.ROC/DeviceSQL-Key.snk create mode 100644 DeviceSQL.SQLTypes.ROC/DeviceSQL.SQLTypes.ROC.csproj create mode 100644 DeviceSQL.SQLTypes.ROC/EventRecord.cs create mode 100644 DeviceSQL.SQLTypes.ROC/EventRecordArray.cs create mode 100644 DeviceSQL.SQLTypes.ROC/FSTInformation.cs create mode 100644 DeviceSQL.SQLTypes.ROC/HistoryRecord.cs create mode 100644 DeviceSQL.SQLTypes.ROC/HistoryRecordArray.cs create mode 100644 DeviceSQL.SQLTypes.ROC/Parameter.cs create mode 100644 DeviceSQL.SQLTypes.ROC/ParameterArray.cs rename {DeviceSQL.Utilities.DeploymentScriptFormatter => DeviceSQL.SQLTypes.ROC}/Properties/AssemblyInfo.cs (74%) create mode 100644 DeviceSQL.SQLTypes.ROC/ROCPlusAlarmRecord.cs create mode 100644 DeviceSQL.SQLTypes.ROC/ROCPlusAlarmRecordArray.cs create mode 100644 DeviceSQL.SQLTypes.ROC/ROCPlusEventRecord.cs create mode 100644 DeviceSQL.SQLTypes.ROC/ROCPlusEventRecordArray.cs create mode 100644 DeviceSQL.SQLTypes.ROC/ROCPlusHistoryPointArray.cs create mode 100644 DeviceSQL.SQLTypes.ROC/ROCPlusHistoryRecord.cs create mode 100644 DeviceSQL.SQLTypes.ROC/ROCPlusHistoryRecordArray.cs create mode 100644 DeviceSQL.Service/API/ChannelController.cs rename DeviceSQL.Service/{Service1.Designer.cs => DeviceSqlService.Designer.cs} (86%) create mode 100644 DeviceSQL.Service/DeviceSqlService.cs rename DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/Resources.resx => DeviceSQL.Service/DeviceSqlService.resx (87%) create mode 100644 DeviceSQL.Service/IOC/ISimpleIOC.cs create mode 100644 DeviceSQL.Service/IOC/PreferredConstructor.cs create mode 100644 DeviceSQL.Service/IOC/SimpleIOC.cs rename {DeviceSQL.Utilities.RealFLOMappingGenerator => DeviceSQL.Service}/Properties/Settings.Designer.cs (60%) create mode 100644 DeviceSQL.Service/Properties/Settings.settings delete mode 100644 DeviceSQL.Service/Service1.cs create mode 100644 DeviceSQL.Service/ServiceLocation/ActivationException.cs create mode 100644 DeviceSQL.Service/ServiceLocation/IServiceLocator.cs create mode 100644 DeviceSQL.Service/ServiceLocation/ServiceLocator.cs create mode 100644 DeviceSQL.Service/ServiceLocation/ServiceLocatorImplBase.cs create mode 100644 DeviceSQL.Service/ServiceLocation/ServiceLocatorProvider.cs create mode 100644 DeviceSQL.Service/Startup.cs create mode 100644 DeviceSQL.Service/packages.config delete mode 100644 DeviceSQL.Services/App.config delete mode 100644 DeviceSQL.Services/DeviceSQL.Services.csproj delete mode 100644 DeviceSQL.Services/IService.cs delete mode 100644 DeviceSQL.Services/Service.cs delete mode 100644 DeviceSQL.TestHarness/App.config delete mode 100644 DeviceSQL.TestHarness/DeviceSQL.TestHarness.csproj delete mode 100644 DeviceSQL.TestHarness/Program.cs delete mode 100644 DeviceSQL.TestHarness/SerialPortChannelTest.cs delete mode 100644 DeviceSQL.TestHarness/TcpChannelTest.cs delete mode 100644 DeviceSQL.Utilities.DeploymentScriptFormatter/App.config delete mode 100644 DeviceSQL.Utilities.DeploymentScriptFormatter/Program.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/App.config delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/App.xaml delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/App.xaml.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Converter/BoolToVisibilityConverter.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Converter/NegatedBoolToVisibilityConverter.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/DeviceSQL.Utilities.RealFLOMappingGenerator.csproj delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Interop/HelpDocument.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Interop/Main.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Key.snk delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/MainWindow.xaml delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/MainWindow.xaml.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Model/DataService.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Model/DialogService.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Enron/Archive.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Enron/ArchiveField.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Enron/Event.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Enron/Register.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Map.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/Archive.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/ArchiveCommand.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/ArchiveField.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/ConfigurationCommand.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/Event.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/Register.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/AssemblyInfo.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/Resources.Designer.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/Settings.settings delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/app.manifest delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/RealFLO.ico delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/RealFLO_24x24.png delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Resources/Images/RealFLO.ico delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Resources/Images/RealFLO_24x24.png delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Resources/Images/RealFLO_32x32.png delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Resources/Scripts/rfm.index.js delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Resources/Styles/rfm.style.css delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/Enron/ArchiveViewModel.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/Enron/EventViewModel.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/Enron/RegisterViewModel.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/ExportMapWizardViewModel.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/MainViewModel.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/NewMapWizardViewModel.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/TeleBUS/ArchiveViewModel.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/TeleBUS/EventViewModel.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/TeleBUS/RegisterViewModel.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/TrackableViewModelBase.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/ViewModelLocator.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Wizard/NewMapWizard.xaml delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/Wizard/NewMapWizard.xaml.cs delete mode 100644 DeviceSQL.Utilities.RealFLOMappingGenerator/packages.config delete mode 100644 DeviceSQL/Schemas/ChannelManager.sql delete mode 100644 DeviceSQL/Schemas/DeviceManager.sql delete mode 100644 DeviceSQL/Schemas/ModbusMaster.sql delete mode 100644 DeviceSQL/Schemas/Watchdog.sql diff --git a/DeviceSQL/DeviceSQL-Key.snk b/DeviceSQL-Key.snk similarity index 100% rename from DeviceSQL/DeviceSQL-Key.snk rename to DeviceSQL-Key.snk diff --git a/DeviceSQL.ChannelManager/DeviceSQL.ChannelManager.sqlproj b/DeviceSQL.ChannelManager/DeviceSQL.ChannelManager.sqlproj new file mode 100644 index 0000000..2ccf90e --- /dev/null +++ b/DeviceSQL.ChannelManager/DeviceSQL.ChannelManager.sqlproj @@ -0,0 +1,71 @@ + + + + + Debug + AnyCPU + DeviceSQL.ChannelManager + 2.0 + 4.1 + {6393a621-3002-48ab-8de0-74a03ffc4afb} + Microsoft.Data.Tools.Schema.Sql.Sql140DatabaseSchemaProvider + Database + + + DeviceSQL.ChannelManager + DeviceSQL.ChannelManager + 1033, CI + BySchemaAndSchemaType + True + v4.8 + CS + Properties + False + True + True + ChannelManager + UNSAFE + False + ..\DeviceSQL-Key.snk + + + bin\Release\ + $(MSBuildProjectName).sql + False + pdbonly + true + false + true + prompt + 4 + + + bin\Debug\ + $(MSBuildProjectName).sql + false + true + full + false + true + true + prompt + 4 + + + 11.0 + + True + 11.0 + + + + + + + + + + + + + \ No newline at end of file diff --git a/DeviceSQL.ChannelManager/Properties/AssemblyInfo.cs b/DeviceSQL.ChannelManager/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..fe87538 --- /dev/null +++ b/DeviceSQL.ChannelManager/Properties/AssemblyInfo.cs @@ -0,0 +1,24 @@ +using System.Reflection; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with the SQLCLR assembly. +[assembly: AssemblyTitle("DeviceSQL.ChannelManager")] +[assembly: AssemblyDescription("DeviceSQL.ChannelManager")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("CloudSonix")] +[assembly: AssemblyProduct("DeviceSQL")] +[assembly: AssemblyCopyright("© CloudSonix. All rights reserved.")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: AssemblyKeyFileAttribute("../DeviceSQL-Key.snk")] + +// 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/DeviceSQL.DeviceManager/DeviceSQL.DeviceManager.sqlproj b/DeviceSQL.DeviceManager/DeviceSQL.DeviceManager.sqlproj new file mode 100644 index 0000000..85732f8 --- /dev/null +++ b/DeviceSQL.DeviceManager/DeviceSQL.DeviceManager.sqlproj @@ -0,0 +1,72 @@ + + + + + Debug + AnyCPU + DeviceSQL.DeviceManager + 2.0 + 4.1 + {0186afd4-f3e0-42c0-a6ba-58f704804c31} + Microsoft.Data.Tools.Schema.Sql.Sql140DatabaseSchemaProvider + Database + + + DeviceSQL.DeviceManager + DeviceSQL.DeviceManager + 1033, CI + BySchemaAndSchemaType + True + v4.8 + CS + Properties + False + True + True + DeviceManager + + UNSAFE + False + ..\DeviceSQL-Key.snk + + + bin\Release\ + $(MSBuildProjectName).sql + False + pdbonly + true + false + true + prompt + 4 + + + bin\Debug\ + $(MSBuildProjectName).sql + false + true + full + false + true + true + prompt + 4 + + + 11.0 + + True + 11.0 + + + + + + + + + + + + + \ No newline at end of file diff --git a/DeviceSQL.DeviceManager/Properties/AssemblyInfo.cs b/DeviceSQL.DeviceManager/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..358f75f --- /dev/null +++ b/DeviceSQL.DeviceManager/Properties/AssemblyInfo.cs @@ -0,0 +1,24 @@ +using System.Reflection; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with the SQLCLR assembly. +[assembly: AssemblyTitle("DeviceSQL.DeviceManager")] +[assembly: AssemblyDescription("DeviceSQL.DeviceManager")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("CloudSonix")] +[assembly: AssemblyProduct("DeviceSQL")] +[assembly: AssemblyCopyright("© CloudSonix. All rights reserved.")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: AssemblyKeyFileAttribute("../DeviceSQL-Key.snk")] + +// 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/DeviceSQL.Devices/Device/IMaster.cs b/DeviceSQL.Devices.Common/Device/IMaster.cs similarity index 100% rename from DeviceSQL.Devices/Device/IMaster.cs rename to DeviceSQL.Devices.Common/Device/IMaster.cs diff --git a/DeviceSQL.Devices/Device/IMessage.cs b/DeviceSQL.Devices.Common/Device/IMessage.cs similarity index 100% rename from DeviceSQL.Devices/Device/IMessage.cs rename to DeviceSQL.Devices.Common/Device/IMessage.cs diff --git a/DeviceSQL.Utilities.DeploymentScriptFormatter/DeviceSQL.Utilities.DeploymentScriptFormatter.csproj b/DeviceSQL.Devices.Common/DeviceSQL.Devices.Common.csproj similarity index 53% rename from DeviceSQL.Utilities.DeploymentScriptFormatter/DeviceSQL.Utilities.DeploymentScriptFormatter.csproj rename to DeviceSQL.Devices.Common/DeviceSQL.Devices.Common.csproj index fba2682..c0455b4 100644 --- a/DeviceSQL.Utilities.DeploymentScriptFormatter/DeviceSQL.Utilities.DeploymentScriptFormatter.csproj +++ b/DeviceSQL.Devices.Common/DeviceSQL.Devices.Common.csproj @@ -4,16 +4,16 @@ Debug AnyCPU - {0EA05DA7-635F-4018-9F33-0D3419374C9F} - Exe - DeviceSQL.Utilities.DeploymentScriptFormatter - DeviceSQL.Utilities.DeploymentScriptFormatter - v4.6.1 + {5DEADADF-BE60-4774-80C6-97B3A83FA289} + Library + Properties + DeviceSQL.Devices.Common + DeviceSQL.Devices.Common + v4.8 512 - true + true - AnyCPU true full false @@ -23,7 +23,6 @@ 4 - AnyCPU pdbonly true bin\Release\ @@ -31,7 +30,17 @@ prompt 4 + + false + + + + + + + ..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll + @@ -42,11 +51,23 @@ - + + + + + + + + + + + + + - + \ No newline at end of file diff --git a/DeviceSQL.Devices.Common/IO/Channels/ChannelTraceEventArgs.cs b/DeviceSQL.Devices.Common/IO/Channels/ChannelTraceEventArgs.cs new file mode 100644 index 0000000..9ac8cd6 --- /dev/null +++ b/DeviceSQL.Devices.Common/IO/Channels/ChannelTraceEventArgs.cs @@ -0,0 +1,23 @@ +#region Imported Types + +using System; +using System.Collections.Generic; +using System.Text; + +#endregion + +namespace DeviceSQL.IO.Channels +{ + public class ChannelTraceEventArgs : EventArgs + { + public DateTime MessageDateTimeStamp { get; set; } + public string Name { get; set; } + public DateTime StartTime { get; set; } + public string Operation { get; set; } + public double Duration { get; set; } + public int Sequence { get; set; } + public int Count { get; set; } + public string Data { get; set; } + public string ChannelType { get; set; } + } +} diff --git a/DeviceSQL.Devices/IO/Channels/ChannelTraceListener.cs b/DeviceSQL.Devices.Common/IO/Channels/ChannelTraceListener.cs similarity index 93% rename from DeviceSQL.Devices/IO/Channels/ChannelTraceListener.cs rename to DeviceSQL.Devices.Common/IO/Channels/ChannelTraceListener.cs index 5622e9c..29ef775 100644 --- a/DeviceSQL.Devices/IO/Channels/ChannelTraceListener.cs +++ b/DeviceSQL.Devices.Common/IO/Channels/ChannelTraceListener.cs @@ -8,12 +8,12 @@ namespace DeviceSQL.IO.Channels { - internal class ChannelTraceListener : TraceListener + public class ChannelTraceListener : TraceListener { #region Events - internal event EventHandler ChannelTraceMessageReceived; + public event EventHandler ChannelTraceMessageReceived; #endregion @@ -29,7 +29,7 @@ internal class ChannelTraceListener : TraceListener #endregion - internal ChannelTraceListener() + public ChannelTraceListener() { try { diff --git a/DeviceSQL.Devices/IO/Channels/HexConverter.cs b/DeviceSQL.Devices.Common/IO/Channels/HexConverter.cs similarity index 86% rename from DeviceSQL.Devices/IO/Channels/HexConverter.cs rename to DeviceSQL.Devices.Common/IO/Channels/HexConverter.cs index 80acd20..0771a47 100644 --- a/DeviceSQL.Devices/IO/Channels/HexConverter.cs +++ b/DeviceSQL.Devices.Common/IO/Channels/HexConverter.cs @@ -4,7 +4,12 @@ #endregion + +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.IO.Channels +#else namespace DeviceSQL.IO.Channels +#endif { public static class HexConverter { diff --git a/DeviceSQL.Devices/IO/Channels/IChannel.cs b/DeviceSQL.Devices.Common/IO/Channels/IChannel.cs similarity index 92% rename from DeviceSQL.Devices/IO/Channels/IChannel.cs rename to DeviceSQL.Devices.Common/IO/Channels/IChannel.cs index fd55b10..14ecab2 100644 --- a/DeviceSQL.Devices/IO/Channels/IChannel.cs +++ b/DeviceSQL.Devices.Common/IO/Channels/IChannel.cs @@ -1,5 +1,6 @@ #region Imported Types +using Newtonsoft.Json; using System; #endregion @@ -8,6 +9,7 @@ namespace DeviceSQL.IO.Channels { public interface IChannel : IDisposable { + [JsonIgnore] object LockObject { get; } string Name { get; set; } bool TracingEnabled { get; set; } diff --git a/DeviceSQL.Devices/IO/Channels/IMuxChannel.cs b/DeviceSQL.Devices.Common/IO/Channels/IMuxChannel.cs similarity index 71% rename from DeviceSQL.Devices/IO/Channels/IMuxChannel.cs rename to DeviceSQL.Devices.Common/IO/Channels/IMuxChannel.cs index c68b9b8..ff567ea 100644 --- a/DeviceSQL.Devices/IO/Channels/IMuxChannel.cs +++ b/DeviceSQL.Devices.Common/IO/Channels/IMuxChannel.cs @@ -2,8 +2,7 @@ namespace DeviceSQL.IO.Channels { public interface IMuxChannel : IChannel { - string SourceChannelName { get; set; } - IChannel SourceChannel { get; } + IChannel SourceChannel { get; set; } int RequestDelay { get; set; } int ResponseDelay { get; set; } int ResponseTimeout { get; set; } diff --git a/DeviceSQL.Devices/IO/Channels/SerialPortChannel.cs b/DeviceSQL.Devices.Common/IO/Channels/SerialPortChannel.cs similarity index 99% rename from DeviceSQL.Devices/IO/Channels/SerialPortChannel.cs rename to DeviceSQL.Devices.Common/IO/Channels/SerialPortChannel.cs index 2a35c6b..d36279d 100644 --- a/DeviceSQL.Devices/IO/Channels/SerialPortChannel.cs +++ b/DeviceSQL.Devices.Common/IO/Channels/SerialPortChannel.cs @@ -57,6 +57,7 @@ public bool TracingEnabled public SerialPort SerialPort { get { return serialPort; } + set { serialPort = value; } } public int ReadTimeout diff --git a/DeviceSQL.Devices.Common/IO/Channels/SerialPortMuxChannel.cs b/DeviceSQL.Devices.Common/IO/Channels/SerialPortMuxChannel.cs new file mode 100644 index 0000000..de31d78 --- /dev/null +++ b/DeviceSQL.Devices.Common/IO/Channels/SerialPortMuxChannel.cs @@ -0,0 +1,142 @@ +#region Imported Types + +using System; +using System.Diagnostics; +using System.IO.Ports; +using System.Linq; + +#endregion + +namespace DeviceSQL.IO.Channels +{ + namespace EnerWorx.ChannelService.IO.Channels + { + public class SerialPortMuxChannel : SerialPortChannel, IMuxChannel + { + + #region Fields + + private IChannel sourceChannel = null; + private int requestDelay = 0; + private int responseDelay = 0; + private int responseTimeout = 3000; + + #endregion + + #region Properties + + public IChannel SourceChannel + { + get + { + return sourceChannel; + } + set + { + if (!(value is IMuxChannel)) + { + sourceChannel = value; + } + else + { + throw new Exception("Source channel must not be a MUX channel"); + } + } + } + + public int RequestDelay + { + get + { + return requestDelay; + } + set + { + requestDelay = value; + } + } + + public int ResponseDelay + { + get + { + return responseDelay; + } + set + { + responseDelay = value; + } + } + + public int ResponseTimeout + { + get + { + return responseTimeout; + } + set + { + responseTimeout = value; + } + } + + #endregion + + #region Mux Methods + + public void Run() + { + SerialPort.DataReceived -= SerialPort_DataReceived; + SerialPort.DataReceived += SerialPort_DataReceived; + } + + public void Stop() + { + SerialPort.DataReceived -= SerialPort_DataReceived; + } + + #endregion + + #region Serial Port Events + + private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) + { + var startTime = DateTime.Now; + var lockObject = SourceChannel.LockObject; + lock (lockObject) + { + var masterStopWatch = new Stopwatch(); + var requestBytes = new byte[] { }; + + TimedThreadBlocker.Wait(requestDelay); + + requestBytes = new byte[SerialPort.BytesToRead]; + + if (requestBytes.Length > 0) + { + Read(ref requestBytes, 0, requestBytes.Length, 0); + SourceChannel.Write(ref requestBytes, 0, requestBytes.Length); + TimedThreadBlocker.Wait(responseDelay); + masterStopWatch.Start(); + + var sequence = 0; + while (SourceChannel.NumberOfBytesAvailable > 0 && responseTimeout > masterStopWatch.ElapsedMilliseconds) + { + var responseBytes = new byte[SourceChannel.NumberOfBytesAvailable]; + + SourceChannel.Read(ref responseBytes, 0, responseBytes.Length, sequence++); + Write(ref responseBytes, 0, responseBytes.Length); + } + + masterStopWatch.Stop(); + + } + } + } + + #endregion + + } + } +} + diff --git a/DeviceSQL.Devices/IO/Channels/TcpChannel.cs b/DeviceSQL.Devices.Common/IO/Channels/TcpChannel.cs similarity index 97% rename from DeviceSQL.Devices/IO/Channels/TcpChannel.cs rename to DeviceSQL.Devices.Common/IO/Channels/TcpChannel.cs index 9b450db..5bf70fa 100644 --- a/DeviceSQL.Devices/IO/Channels/TcpChannel.cs +++ b/DeviceSQL.Devices.Common/IO/Channels/TcpChannel.cs @@ -1,5 +1,6 @@ #region Imported Types +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; @@ -63,13 +64,13 @@ public int ConnectionRetryDelay set; } - internal int TcpClientReadTimeout + public int TcpClientReadTimeout { get; set; } - internal int TcpClientWriteTimeout + public int TcpClientWriteTimeout { get; set; @@ -87,16 +88,17 @@ public bool TracingEnabled } } - + [JsonIgnore] public TcpClient TcpClient { get { return tcpClient; } - internal set + set { tcpClient = value; } } + [JsonIgnore] public int ReadTimeout { get { return TcpClient.GetStream().ReadTimeout; } @@ -107,6 +109,7 @@ public int ReadTimeout } } + [JsonIgnore] public int WriteTimeout { get { return TcpClient.GetStream().WriteTimeout; } @@ -142,6 +145,7 @@ public string ConnectionString } } + [JsonIgnore] public int NumberOfBytesAvailable { get @@ -186,7 +190,7 @@ public void Write(ref byte[] buffer, int offset, int count) { throw exception; } - Connect: + Connect: currentConnectAttempts++; try { @@ -265,7 +269,7 @@ public int Read(ref byte[] buffer, int offset, int count, int sequence) Thread.Sleep(0); } - Finish: + Finish: timeoutStopWatch.Stop(); masterStopWatch.Stop(); @@ -302,7 +306,7 @@ public int Read(ref byte[] buffer, int offset, int count, int sequence) { throw exception; } - Connect: + Connect: currentConnectAttempts++; try { diff --git a/DeviceSQL.Devices/IO/Channels/TcpMuxChannel.cs b/DeviceSQL.Devices.Common/IO/Channels/TcpMuxChannel.cs similarity index 89% rename from DeviceSQL.Devices/IO/Channels/TcpMuxChannel.cs rename to DeviceSQL.Devices.Common/IO/Channels/TcpMuxChannel.cs index 340d24e..0923bc6 100644 --- a/DeviceSQL.Devices/IO/Channels/TcpMuxChannel.cs +++ b/DeviceSQL.Devices.Common/IO/Channels/TcpMuxChannel.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Net; using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; @@ -18,14 +19,15 @@ public class TcpMuxChannel : TcpChannel, IMuxChannel #region Fields private object lockObject = new object(); - private volatile int numberOfTcpClients = 0; + private volatile bool stopRequested; private volatile bool hasStopped; - private string sourceChannelName = ""; + private IChannel sourceChannel = null; private int requestDelay = 0; private int responseDelay = 0; private int responseTimeout = 3000; private int maximumNumberOfTcpClients = 5; + private int port = 1000; private TcpListener tcpListener; private List tcpClients = new List(); @@ -37,21 +39,21 @@ public IChannel SourceChannel { get { - return null; //DeviceSQL.Watchdog.Worker.Channels.FirstOrDefault(); - } - } - - public string SourceChannelName - { - get - { - return sourceChannelName; + return sourceChannel; } set { - sourceChannelName = value; + if (!(value is IMuxChannel)) + { + sourceChannel = value; + } + else + { + throw new Exception("Source channel must not be a MUX channel"); + } } } + public int RequestDelay { get @@ -100,6 +102,18 @@ public int MaximumNumberOfTcpClients } } + public int Port + { + get + { + return port; + } + set + { + port = value; + } + } + public IEnumerable TcpClients { get @@ -118,7 +132,10 @@ await Task.Factory.StartNew(() => { try { - + if (tcpListener == null) + { + tcpListener = new TcpListener(IPAddress.Any, 1001); + } tcpListener.Start(MaximumNumberOfTcpClients); stopRequested = false; hasStopped = false; @@ -126,13 +143,12 @@ await Task.Factory.StartNew(() => { try { - if (MaximumNumberOfTcpClients > numberOfTcpClients) + if (MaximumNumberOfTcpClients > tcpClients.Count) { var tcpClient = tcpListener.AcceptTcpClient(); var networkStream = tcpClient.GetStream(); var readBuffer = new byte[1500]; - Interlocked.Increment(ref numberOfTcpClients); tcpClient.Client.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.KeepAlive, true); tcpClients.Add(tcpClient); networkStream.BeginRead(readBuffer, 0, 0, new AsyncCallback(TcpClientBeginReadCallback), tcpClient); @@ -168,6 +184,7 @@ await Task.Factory.StartNew(() => private void TcpClientBeginReadCallback(IAsyncResult asyncResult) { + var clientRemoved = false; var tcpClient = asyncResult.AsyncState as TcpClient; try @@ -242,16 +259,19 @@ private void TcpClientBeginReadCallback(IAsyncResult asyncResult) try { tcpClients.Remove(tcpClient); + clientRemoved = true; } catch (Exception ex) { Trace.TraceError($"Error removing TCP Client from list: {ex.Message}"); } - - Interlocked.Decrement(ref numberOfTcpClients); } catch (Exception ex) { + if (!clientRemoved) + { + tcpClients.Remove(tcpClient); + } Trace.TraceError($"Error disposing TCP Client: {ex.Message}"); } } diff --git a/DeviceSQL.Devices/IO/Channels/TimedThreadBlocker.cs b/DeviceSQL.Devices.Common/IO/Channels/TimedThreadBlocker.cs similarity index 100% rename from DeviceSQL.Devices/IO/Channels/TimedThreadBlocker.cs rename to DeviceSQL.Devices.Common/IO/Channels/TimedThreadBlocker.cs diff --git a/DeviceSQL.Devices/IO/Channels/Transport/ITransport.cs b/DeviceSQL.Devices.Common/IO/Channels/Transport/ITransport.cs similarity index 100% rename from DeviceSQL.Devices/IO/Channels/Transport/ITransport.cs rename to DeviceSQL.Devices.Common/IO/Channels/Transport/ITransport.cs diff --git a/DeviceSQL.Devices/Properties/AssemblyInfo.cs b/DeviceSQL.Devices.Common/Properties/AssemblyInfo.cs similarity index 74% rename from DeviceSQL.Devices/Properties/AssemblyInfo.cs rename to DeviceSQL.Devices.Common/Properties/AssemblyInfo.cs index f720c30..38c7b19 100644 --- a/DeviceSQL.Devices/Properties/AssemblyInfo.cs +++ b/DeviceSQL.Devices.Common/Properties/AssemblyInfo.cs @@ -5,14 +5,15 @@ // 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("DeviceSQL.Devices")] -[assembly: AssemblyDescription("")] +[assembly: AssemblyTitle("DeviceSQL.Devices.Common")] +[assembly: AssemblyDescription("DeviceSQL.Devices.Common")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("DeviceSQL.Devices")] -[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyCompany("CloudSonix")] +[assembly: AssemblyProduct("DeviceSQL")] +[assembly: AssemblyCopyright("© CloudSonix. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] +[assembly: AssemblyKeyFileAttribute("../DeviceSQL-Key.snk")] // 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 @@ -20,7 +21,7 @@ [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("80ed4080-6fd1-492f-b70e-8c837b3dadc7")] +[assembly: Guid("5deadadf-be60-4774-80c6-97b3a83fa289")] // Version information for an assembly consists of the following four values: // diff --git a/DeviceSQL.Devices.Common/packages.config b/DeviceSQL.Devices.Common/packages.config new file mode 100644 index 0000000..d5b882e --- /dev/null +++ b/DeviceSQL.Devices.Common/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/DeviceSQL.Devices/Device/Modbus/Crc16.cs b/DeviceSQL.Devices.Modbus/Crc16.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Crc16.cs rename to DeviceSQL.Devices.Modbus/Crc16.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Data/BooleanRegister.cs b/DeviceSQL.Devices.Modbus/Data/BooleanRegister.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Data/BooleanRegister.cs rename to DeviceSQL.Devices.Modbus/Data/BooleanRegister.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Data/CoilRegister.cs b/DeviceSQL.Devices.Modbus/Data/CoilRegister.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Data/CoilRegister.cs rename to DeviceSQL.Devices.Modbus/Data/CoilRegister.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Data/DiscreteInputRegister.cs b/DeviceSQL.Devices.Modbus/Data/DiscreteInputRegister.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Data/DiscreteInputRegister.cs rename to DeviceSQL.Devices.Modbus/Data/DiscreteInputRegister.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Data/EventArchiveRecord.cs b/DeviceSQL.Devices.Modbus/Data/EventArchiveRecord.cs similarity index 98% rename from DeviceSQL.Devices/Device/Modbus/Data/EventArchiveRecord.cs rename to DeviceSQL.Devices.Modbus/Data/EventArchiveRecord.cs index 5c8ba15..e06aeac 100644 --- a/DeviceSQL.Devices/Device/Modbus/Data/EventArchiveRecord.cs +++ b/DeviceSQL.Devices.Modbus/Data/EventArchiveRecord.cs @@ -28,7 +28,7 @@ public byte[] Data #region Constructor(s) - internal EventArchiveRecord(ushort index, byte[] data) + public EventArchiveRecord(ushort index, byte[] data) { this.Index = Index; this.Data = data; diff --git a/DeviceSQL.Devices/Device/Modbus/Data/FloatRegister.cs b/DeviceSQL.Devices.Modbus/Data/FloatRegister.cs similarity index 98% rename from DeviceSQL.Devices/Device/Modbus/Data/FloatRegister.cs rename to DeviceSQL.Devices.Modbus/Data/FloatRegister.cs index a2c4484..0d586fa 100644 --- a/DeviceSQL.Devices/Device/Modbus/Data/FloatRegister.cs +++ b/DeviceSQL.Devices.Modbus/Data/FloatRegister.cs @@ -38,13 +38,13 @@ public FloatRegister(MODBUSAddress address, bool byteSwap, bool wordSwap) public bool WordSwap { get; - internal set; + set; } public bool ByteSwap { get; - internal set; + set; } public override System.Single Value diff --git a/DeviceSQL.Devices/Device/Modbus/Data/HistoryArchiveRecord.cs b/DeviceSQL.Devices.Modbus/Data/HistoryArchiveRecord.cs similarity index 97% rename from DeviceSQL.Devices/Device/Modbus/Data/HistoryArchiveRecord.cs rename to DeviceSQL.Devices.Modbus/Data/HistoryArchiveRecord.cs index 73df2e3..9fd5ba2 100644 --- a/DeviceSQL.Devices/Device/Modbus/Data/HistoryArchiveRecord.cs +++ b/DeviceSQL.Devices.Modbus/Data/HistoryArchiveRecord.cs @@ -28,7 +28,7 @@ public byte[] Data #region Constructor(s) - internal HistoryArchiveRecord(ushort index, byte[] data) + public HistoryArchiveRecord(ushort index, byte[] data) { this.Index = index; this.Data = data; diff --git a/DeviceSQL.Devices/Device/Modbus/Data/HoldingRegister.cs b/DeviceSQL.Devices.Modbus/Data/HoldingRegister.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Data/HoldingRegister.cs rename to DeviceSQL.Devices.Modbus/Data/HoldingRegister.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Data/IModbusRegisterData.cs b/DeviceSQL.Devices.Modbus/Data/IModbusRegisterData.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Data/IModbusRegisterData.cs rename to DeviceSQL.Devices.Modbus/Data/IModbusRegisterData.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Data/InputRegister.cs b/DeviceSQL.Devices.Modbus/Data/InputRegister.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Data/InputRegister.cs rename to DeviceSQL.Devices.Modbus/Data/InputRegister.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Data/LongRegister.cs b/DeviceSQL.Devices.Modbus/Data/LongRegister.cs similarity index 98% rename from DeviceSQL.Devices/Device/Modbus/Data/LongRegister.cs rename to DeviceSQL.Devices.Modbus/Data/LongRegister.cs index 7408fc4..ed76dc5 100644 --- a/DeviceSQL.Devices/Device/Modbus/Data/LongRegister.cs +++ b/DeviceSQL.Devices.Modbus/Data/LongRegister.cs @@ -38,13 +38,13 @@ public LongRegister(MODBUSAddress address, bool byteSwap, bool wordSwap) public bool WordSwap { get; - internal set; + set; } public bool ByteSwap { get; - internal set; + set; } public override System.Int32 Value diff --git a/DeviceSQL.Devices/Device/Modbus/Data/ModbusAddress.cs b/DeviceSQL.Devices.Modbus/Data/ModbusAddress.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Data/ModbusAddress.cs rename to DeviceSQL.Devices.Modbus/Data/ModbusAddress.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Data/ModbusRegister.cs b/DeviceSQL.Devices.Modbus/Data/ModbusRegister.cs similarity index 98% rename from DeviceSQL.Devices/Device/Modbus/Data/ModbusRegister.cs rename to DeviceSQL.Devices.Modbus/Data/ModbusRegister.cs index 2a1af99..c7d512c 100644 --- a/DeviceSQL.Devices/Device/Modbus/Data/ModbusRegister.cs +++ b/DeviceSQL.Devices.Modbus/Data/ModbusRegister.cs @@ -24,7 +24,7 @@ public MODBUSAddress Address set { this.address = value; } } - protected internal byte[] Data + public byte[] Data { get { diff --git a/DeviceSQL.Devices/Device/Modbus/Data/ShortRegister.cs b/DeviceSQL.Devices.Modbus/Data/ShortRegister.cs similarity index 98% rename from DeviceSQL.Devices/Device/Modbus/Data/ShortRegister.cs rename to DeviceSQL.Devices.Modbus/Data/ShortRegister.cs index 8f41300..b6a3d46 100644 --- a/DeviceSQL.Devices/Device/Modbus/Data/ShortRegister.cs +++ b/DeviceSQL.Devices.Modbus/Data/ShortRegister.cs @@ -37,7 +37,7 @@ public ShortRegister(MODBUSAddress address, bool byteSwap) public bool ByteSwap { get; - internal set; + set; } public override System.Int16 Value diff --git a/DeviceSQL.Devices/Device/Modbus/Data/StringRegister.cs b/DeviceSQL.Devices.Modbus/Data/StringRegister.cs similarity index 96% rename from DeviceSQL.Devices/Device/Modbus/Data/StringRegister.cs rename to DeviceSQL.Devices.Modbus/Data/StringRegister.cs index 092a748..8885470 100644 --- a/DeviceSQL.Devices/Device/Modbus/Data/StringRegister.cs +++ b/DeviceSQL.Devices.Modbus/Data/StringRegister.cs @@ -46,13 +46,13 @@ public byte Length public bool WordSwap { get; - internal set; + set; } public bool ByteSwap { get; - internal set; + set; } public override string Value diff --git a/DeviceSQL.Devices/Device/Modbus/Device.cs b/DeviceSQL.Devices.Modbus/Device.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Device.cs rename to DeviceSQL.Devices.Modbus/Device.cs diff --git a/DeviceSQL.Devices.Modbus/DeviceSQL.Devices.Modbus.csproj b/DeviceSQL.Devices.Modbus/DeviceSQL.Devices.Modbus.csproj new file mode 100644 index 0000000..e0df1f4 --- /dev/null +++ b/DeviceSQL.Devices.Modbus/DeviceSQL.Devices.Modbus.csproj @@ -0,0 +1,110 @@ + + + + + Debug + AnyCPU + {0869E7FE-4FAC-4FC5-A2A8-313F410CF8CD} + Library + Properties + DeviceSQL.Devices.Modbus + DeviceSQL.Devices.Modbus + v4.8 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {5deadadf-be60-4774-80c6-97b3a83fa289} + DeviceSQL.Devices.Common + + + + \ No newline at end of file diff --git a/DeviceSQL.Devices/Device/Modbus/IO/Transport/Transport.cs b/DeviceSQL.Devices.Modbus/IO/Transport/Transport.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/IO/Transport/Transport.cs rename to DeviceSQL.Devices.Modbus/IO/Transport/Transport.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/IModbusMessage.cs b/DeviceSQL.Devices.Modbus/Message/IModbusMessage.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/IModbusMessage.cs rename to DeviceSQL.Devices.Modbus/Message/IModbusMessage.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/IModbusRequestMessage.cs b/DeviceSQL.Devices.Modbus/Message/IModbusRequestMessage.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/IModbusRequestMessage.cs rename to DeviceSQL.Devices.Modbus/Message/IModbusRequestMessage.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/IModbusResponseMessage.cs b/DeviceSQL.Devices.Modbus/Message/IModbusResponseMessage.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/IModbusResponseMessage.cs rename to DeviceSQL.Devices.Modbus/Message/IModbusResponseMessage.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ModbusErrorResponse.cs b/DeviceSQL.Devices.Modbus/Message/ModbusErrorResponse.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ModbusErrorResponse.cs rename to DeviceSQL.Devices.Modbus/Message/ModbusErrorResponse.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ModbusMessage.cs b/DeviceSQL.Devices.Modbus/Message/ModbusMessage.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ModbusMessage.cs rename to DeviceSQL.Devices.Modbus/Message/ModbusMessage.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ModbusMessageFactory.cs b/DeviceSQL.Devices.Modbus/Message/ModbusMessageFactory.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ModbusMessageFactory.cs rename to DeviceSQL.Devices.Modbus/Message/ModbusMessageFactory.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadCoilRegistersRequest.cs b/DeviceSQL.Devices.Modbus/Message/ReadCoilRegistersRequest.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadCoilRegistersRequest.cs rename to DeviceSQL.Devices.Modbus/Message/ReadCoilRegistersRequest.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadCoilRegistersResponse.cs b/DeviceSQL.Devices.Modbus/Message/ReadCoilRegistersResponse.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadCoilRegistersResponse.cs rename to DeviceSQL.Devices.Modbus/Message/ReadCoilRegistersResponse.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadDiscreteInputRegistersRequest.cs b/DeviceSQL.Devices.Modbus/Message/ReadDiscreteInputRegistersRequest.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadDiscreteInputRegistersRequest.cs rename to DeviceSQL.Devices.Modbus/Message/ReadDiscreteInputRegistersRequest.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadDiscreteInputRegistersResponse.cs b/DeviceSQL.Devices.Modbus/Message/ReadDiscreteInputRegistersResponse.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadDiscreteInputRegistersResponse.cs rename to DeviceSQL.Devices.Modbus/Message/ReadDiscreteInputRegistersResponse.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadEventArchiveRequest.cs b/DeviceSQL.Devices.Modbus/Message/ReadEventArchiveRequest.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadEventArchiveRequest.cs rename to DeviceSQL.Devices.Modbus/Message/ReadEventArchiveRequest.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadEventArchiveResponse.cs b/DeviceSQL.Devices.Modbus/Message/ReadEventArchiveResponse.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadEventArchiveResponse.cs rename to DeviceSQL.Devices.Modbus/Message/ReadEventArchiveResponse.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadFloatsRequest.cs b/DeviceSQL.Devices.Modbus/Message/ReadFloatsRequest.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadFloatsRequest.cs rename to DeviceSQL.Devices.Modbus/Message/ReadFloatsRequest.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadFloatsResponse.cs b/DeviceSQL.Devices.Modbus/Message/ReadFloatsResponse.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadFloatsResponse.cs rename to DeviceSQL.Devices.Modbus/Message/ReadFloatsResponse.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadHistoryArchiveRequest.cs b/DeviceSQL.Devices.Modbus/Message/ReadHistoryArchiveRequest.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadHistoryArchiveRequest.cs rename to DeviceSQL.Devices.Modbus/Message/ReadHistoryArchiveRequest.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadHistoryArchiveResponse.cs b/DeviceSQL.Devices.Modbus/Message/ReadHistoryArchiveResponse.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadHistoryArchiveResponse.cs rename to DeviceSQL.Devices.Modbus/Message/ReadHistoryArchiveResponse.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadHoldingRegistersRequest.cs b/DeviceSQL.Devices.Modbus/Message/ReadHoldingRegistersRequest.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadHoldingRegistersRequest.cs rename to DeviceSQL.Devices.Modbus/Message/ReadHoldingRegistersRequest.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadHoldingRegistersResponse.cs b/DeviceSQL.Devices.Modbus/Message/ReadHoldingRegistersResponse.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadHoldingRegistersResponse.cs rename to DeviceSQL.Devices.Modbus/Message/ReadHoldingRegistersResponse.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadInputRegistersRequest.cs b/DeviceSQL.Devices.Modbus/Message/ReadInputRegistersRequest.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadInputRegistersRequest.cs rename to DeviceSQL.Devices.Modbus/Message/ReadInputRegistersRequest.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadInputRegistersResponse.cs b/DeviceSQL.Devices.Modbus/Message/ReadInputRegistersResponse.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadInputRegistersResponse.cs rename to DeviceSQL.Devices.Modbus/Message/ReadInputRegistersResponse.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadLongsRequest.cs b/DeviceSQL.Devices.Modbus/Message/ReadLongsRequest.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadLongsRequest.cs rename to DeviceSQL.Devices.Modbus/Message/ReadLongsRequest.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadLongsResponse.cs b/DeviceSQL.Devices.Modbus/Message/ReadLongsResponse.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadLongsResponse.cs rename to DeviceSQL.Devices.Modbus/Message/ReadLongsResponse.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadShortsRequest.cs b/DeviceSQL.Devices.Modbus/Message/ReadShortsRequest.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadShortsRequest.cs rename to DeviceSQL.Devices.Modbus/Message/ReadShortsRequest.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadShortsResponse.cs b/DeviceSQL.Devices.Modbus/Message/ReadShortsResponse.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadShortsResponse.cs rename to DeviceSQL.Devices.Modbus/Message/ReadShortsResponse.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadStringRequest.cs b/DeviceSQL.Devices.Modbus/Message/ReadStringRequest.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadStringRequest.cs rename to DeviceSQL.Devices.Modbus/Message/ReadStringRequest.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/ReadStringResponse.cs b/DeviceSQL.Devices.Modbus/Message/ReadStringResponse.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/ReadStringResponse.cs rename to DeviceSQL.Devices.Modbus/Message/ReadStringResponse.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/WriteBooleanRequest.cs b/DeviceSQL.Devices.Modbus/Message/WriteBooleanRequest.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/WriteBooleanRequest.cs rename to DeviceSQL.Devices.Modbus/Message/WriteBooleanRequest.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/WriteBooleanResponse.cs b/DeviceSQL.Devices.Modbus/Message/WriteBooleanResponse.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/WriteBooleanResponse.cs rename to DeviceSQL.Devices.Modbus/Message/WriteBooleanResponse.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/WriteFloatsRequest.cs b/DeviceSQL.Devices.Modbus/Message/WriteFloatsRequest.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/WriteFloatsRequest.cs rename to DeviceSQL.Devices.Modbus/Message/WriteFloatsRequest.cs diff --git a/DeviceSQL.Devices/Device/Modbus/Message/WriteFloatsResponse.cs b/DeviceSQL.Devices.Modbus/Message/WriteFloatsResponse.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/Message/WriteFloatsResponse.cs rename to DeviceSQL.Devices.Modbus/Message/WriteFloatsResponse.cs diff --git a/DeviceSQL.Devices/Device/Modbus/ModbusConverter.cs b/DeviceSQL.Devices.Modbus/ModbusConverter.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/ModbusConverter.cs rename to DeviceSQL.Devices.Modbus/ModbusConverter.cs diff --git a/DeviceSQL.Devices/Device/Modbus/ModbusMaster.cs b/DeviceSQL.Devices.Modbus/ModbusMaster.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/ModbusMaster.cs rename to DeviceSQL.Devices.Modbus/ModbusMaster.cs diff --git a/DeviceSQL.Devices/Device/Modbus/ModbusSlaveException.cs b/DeviceSQL.Devices.Modbus/ModbusSlaveException.cs similarity index 100% rename from DeviceSQL.Devices/Device/Modbus/ModbusSlaveException.cs rename to DeviceSQL.Devices.Modbus/ModbusSlaveException.cs diff --git a/DeviceSQL.Devices.Modbus/Properties/AssemblyInfo.cs b/DeviceSQL.Devices.Modbus/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..bc9b2fb --- /dev/null +++ b/DeviceSQL.Devices.Modbus/Properties/AssemblyInfo.cs @@ -0,0 +1,37 @@ +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("DeviceSQL.Devices.Modbus")] +[assembly: AssemblyDescription("DeviceSQL.Devices.Modbus")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("CloudSonix")] +[assembly: AssemblyProduct("DeviceSQL.Devices.Modbus")] +[assembly: AssemblyCopyright("© CloudSonix. All rights reserved.")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: AssemblyKeyFileAttribute("../DeviceSQL-Key.snk")] + +// 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("0869e7fe-4fac-4fc5-a2a8-313f410cf8cd")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/DeviceSQL.Devices/Device/ROC/Data/Ac10Parameter.cs b/DeviceSQL.Devices.ROC/Data/Ac10Parameter.cs similarity index 86% rename from DeviceSQL.Devices/Device/ROC/Data/Ac10Parameter.cs rename to DeviceSQL.Devices.ROC/Data/Ac10Parameter.cs index 364a7c2..6a37fa4 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/Ac10Parameter.cs +++ b/DeviceSQL.Devices.ROC/Data/Ac10Parameter.cs @@ -7,12 +7,16 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class Ac10Parameter : Parameter { - #region Constructor(s) +#region Constructor(s) public Ac10Parameter() : base() @@ -26,9 +30,9 @@ public Ac10Parameter(Tlp tlp) Value = ""; } - #endregion +#endregion - #region Properties +#region Properties public override string Value { @@ -42,7 +46,7 @@ public override string Value } } - #endregion +#endregion } } diff --git a/DeviceSQL.Devices/Device/ROC/Data/Ac12Parameter.cs b/DeviceSQL.Devices.ROC/Data/Ac12Parameter.cs similarity index 93% rename from DeviceSQL.Devices/Device/ROC/Data/Ac12Parameter.cs rename to DeviceSQL.Devices.ROC/Data/Ac12Parameter.cs index d399890..1d3e8cb 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/Ac12Parameter.cs +++ b/DeviceSQL.Devices.ROC/Data/Ac12Parameter.cs @@ -7,7 +7,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class Ac12Parameter : Parameter { diff --git a/DeviceSQL.Devices/Device/ROC/Data/Ac20Parameter.cs b/DeviceSQL.Devices.ROC/Data/Ac20Parameter.cs similarity index 93% rename from DeviceSQL.Devices/Device/ROC/Data/Ac20Parameter.cs rename to DeviceSQL.Devices.ROC/Data/Ac20Parameter.cs index 260b733..dc76911 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/Ac20Parameter.cs +++ b/DeviceSQL.Devices.ROC/Data/Ac20Parameter.cs @@ -7,7 +7,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class Ac20Parameter : Parameter { diff --git a/DeviceSQL.Devices/Device/ROC/Data/Ac30Parameter.cs b/DeviceSQL.Devices.ROC/Data/Ac30Parameter.cs similarity index 93% rename from DeviceSQL.Devices/Device/ROC/Data/Ac30Parameter.cs rename to DeviceSQL.Devices.ROC/Data/Ac30Parameter.cs index 1cc4962..3d78747 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/Ac30Parameter.cs +++ b/DeviceSQL.Devices.ROC/Data/Ac30Parameter.cs @@ -7,7 +7,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class Ac30Parameter : Parameter { diff --git a/DeviceSQL.Devices/Device/ROC/Data/Ac3Parameter.cs b/DeviceSQL.Devices.ROC/Data/Ac3Parameter.cs similarity index 93% rename from DeviceSQL.Devices/Device/ROC/Data/Ac3Parameter.cs rename to DeviceSQL.Devices.ROC/Data/Ac3Parameter.cs index 19083c7..fb7eeb6 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/Ac3Parameter.cs +++ b/DeviceSQL.Devices.ROC/Data/Ac3Parameter.cs @@ -7,7 +7,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class Ac3Parameter : Parameter { diff --git a/DeviceSQL.Devices/Device/ROC/Data/Ac40Parameter.cs b/DeviceSQL.Devices.ROC/Data/Ac40Parameter.cs similarity index 93% rename from DeviceSQL.Devices/Device/ROC/Data/Ac40Parameter.cs rename to DeviceSQL.Devices.ROC/Data/Ac40Parameter.cs index 0b8d047..93969af 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/Ac40Parameter.cs +++ b/DeviceSQL.Devices.ROC/Data/Ac40Parameter.cs @@ -7,7 +7,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class Ac40Parameter : Parameter { diff --git a/DeviceSQL.Devices/Device/ROC/Data/Ac7Parameter.cs b/DeviceSQL.Devices.ROC/Data/Ac7Parameter.cs similarity index 93% rename from DeviceSQL.Devices/Device/ROC/Data/Ac7Parameter.cs rename to DeviceSQL.Devices.ROC/Data/Ac7Parameter.cs index 2d5384b..85ba59d 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/Ac7Parameter.cs +++ b/DeviceSQL.Devices.ROC/Data/Ac7Parameter.cs @@ -7,7 +7,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class Ac7Parameter : Parameter { diff --git a/DeviceSQL.Devices/Device/ROC/Data/AlarmRecord.cs b/DeviceSQL.Devices.ROC/Data/AlarmRecord.cs similarity index 99% rename from DeviceSQL.Devices/Device/ROC/Data/AlarmRecord.cs rename to DeviceSQL.Devices.ROC/Data/AlarmRecord.cs index 1fdabf7..c97d0f9 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/AlarmRecord.cs +++ b/DeviceSQL.Devices.ROC/Data/AlarmRecord.cs @@ -8,7 +8,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { #region Enums @@ -73,8 +77,8 @@ public class AlarmRecord #region Fields - internal byte[] data; - internal ushort index; + public byte[] data; + public ushort index; #endregion diff --git a/DeviceSQL.Devices/Device/ROC/Data/ArchiveInfo.cs b/DeviceSQL.Devices.ROC/Data/ArchiveInfo.cs similarity index 96% rename from DeviceSQL.Devices/Device/ROC/Data/ArchiveInfo.cs rename to DeviceSQL.Devices.ROC/Data/ArchiveInfo.cs index 2651fd3..ed748fd 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/ArchiveInfo.cs +++ b/DeviceSQL.Devices.ROC/Data/ArchiveInfo.cs @@ -8,14 +8,18 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class ArchiveInfo { #region Fields - internal byte[] data; + public byte[] data; #endregion diff --git a/DeviceSQL.Devices/Device/ROC/Data/AuditLogRecord.cs b/DeviceSQL.Devices.ROC/Data/AuditLogRecord.cs similarity index 91% rename from DeviceSQL.Devices/Device/ROC/Data/AuditLogRecord.cs rename to DeviceSQL.Devices.ROC/Data/AuditLogRecord.cs index 8b8570e..1335f3a 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/AuditLogRecord.cs +++ b/DeviceSQL.Devices.ROC/Data/AuditLogRecord.cs @@ -4,7 +4,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class AuditLogRecord : EventRecord { diff --git a/DeviceSQL.Devices/Device/ROC/Data/BinParameter.cs b/DeviceSQL.Devices.ROC/Data/BinParameter.cs similarity index 92% rename from DeviceSQL.Devices/Device/ROC/Data/BinParameter.cs rename to DeviceSQL.Devices.ROC/Data/BinParameter.cs index 4f13b0c..3fb5b36 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/BinParameter.cs +++ b/DeviceSQL.Devices.ROC/Data/BinParameter.cs @@ -7,7 +7,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class BinParameter : Parameter { diff --git a/DeviceSQL.Devices/Device/ROC/Data/DoubleParameter.cs b/DeviceSQL.Devices.ROC/Data/DoubleParameter.cs similarity index 96% rename from DeviceSQL.Devices/Device/ROC/Data/DoubleParameter.cs rename to DeviceSQL.Devices.ROC/Data/DoubleParameter.cs index 5376602..28bb7ed 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/DoubleParameter.cs +++ b/DeviceSQL.Devices.ROC/Data/DoubleParameter.cs @@ -7,7 +7,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class DoubleParameter : Parameter { diff --git a/DeviceSQL.Devices/Device/ROC/Data/EventRecord.cs b/DeviceSQL.Devices.ROC/Data/EventRecord.cs similarity index 99% rename from DeviceSQL.Devices/Device/ROC/Data/EventRecord.cs rename to DeviceSQL.Devices.ROC/Data/EventRecord.cs index cf13ac5..48cc03f 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/EventRecord.cs +++ b/DeviceSQL.Devices.ROC/Data/EventRecord.cs @@ -8,7 +8,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { #region Enums @@ -70,8 +74,8 @@ public class EventRecord #region Fields - internal byte[] data; - internal ushort index; + public byte[] data; + public ushort index; #endregion diff --git a/DeviceSQL.Devices/Device/ROC/Data/FlpParameter.cs b/DeviceSQL.Devices.ROC/Data/FlpParameter.cs similarity index 96% rename from DeviceSQL.Devices/Device/ROC/Data/FlpParameter.cs rename to DeviceSQL.Devices.ROC/Data/FlpParameter.cs index 1a09076..7ae32fc 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/FlpParameter.cs +++ b/DeviceSQL.Devices.ROC/Data/FlpParameter.cs @@ -7,7 +7,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class FlpParameter : Parameter { diff --git a/DeviceSQL.Devices/Device/ROC/Data/FstCodeChunk.cs b/DeviceSQL.Devices.ROC/Data/FstCodeChunk.cs similarity index 91% rename from DeviceSQL.Devices/Device/ROC/Data/FstCodeChunk.cs rename to DeviceSQL.Devices.ROC/Data/FstCodeChunk.cs index 651c5e6..d75c5cb 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/FstCodeChunk.cs +++ b/DeviceSQL.Devices.ROC/Data/FstCodeChunk.cs @@ -4,7 +4,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class FstCodeChunk { diff --git a/DeviceSQL.Devices/Device/ROC/Data/FstHeaderInfo.cs b/DeviceSQL.Devices.ROC/Data/FstHeaderInfo.cs similarity index 86% rename from DeviceSQL.Devices/Device/ROC/Data/FstHeaderInfo.cs rename to DeviceSQL.Devices.ROC/Data/FstHeaderInfo.cs index eb9dba6..af5f252 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/FstHeaderInfo.cs +++ b/DeviceSQL.Devices.ROC/Data/FstHeaderInfo.cs @@ -1,4 +1,8 @@ -namespace DeviceSQL.Device.ROC.Data +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else +namespace DeviceSQL.Device.ROC.Data +#endif { public class FstHeaderInfo { diff --git a/DeviceSQL.Devices/Device/ROC/Data/HistoryPointConfiguration.cs b/DeviceSQL.Devices.ROC/Data/HistoryPointConfiguration.cs similarity index 88% rename from DeviceSQL.Devices/Device/ROC/Data/HistoryPointConfiguration.cs rename to DeviceSQL.Devices.ROC/Data/HistoryPointConfiguration.cs index 6ff95f4..18248ce 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/HistoryPointConfiguration.cs +++ b/DeviceSQL.Devices.ROC/Data/HistoryPointConfiguration.cs @@ -1,4 +1,8 @@ -namespace DeviceSQL.Device.ROC.Data +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else +namespace DeviceSQL.Device.ROC.Data +#endif { public class HistoryPointConfiguration { diff --git a/DeviceSQL.Devices/Device/ROC/Data/HistoryRecord.cs b/DeviceSQL.Devices.ROC/Data/HistoryRecord.cs similarity index 96% rename from DeviceSQL.Devices/Device/ROC/Data/HistoryRecord.cs rename to DeviceSQL.Devices.ROC/Data/HistoryRecord.cs index 10e9655..07dabca 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/HistoryRecord.cs +++ b/DeviceSQL.Devices.ROC/Data/HistoryRecord.cs @@ -7,7 +7,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public struct HistoryRecord { diff --git a/DeviceSQL.Devices/Device/ROC/Data/IRocParameterData.cs b/DeviceSQL.Devices.ROC/Data/IRocParameterData.cs similarity index 80% rename from DeviceSQL.Devices/Device/ROC/Data/IRocParameterData.cs rename to DeviceSQL.Devices.ROC/Data/IRocParameterData.cs index 9e2491f..76c9dcd 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/IRocParameterData.cs +++ b/DeviceSQL.Devices.ROC/Data/IRocParameterData.cs @@ -7,7 +7,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public interface IROCParameterData { diff --git a/DeviceSQL.Devices/Device/ROC/Data/Int16Parameter.cs b/DeviceSQL.Devices.ROC/Data/Int16Parameter.cs similarity index 92% rename from DeviceSQL.Devices/Device/ROC/Data/Int16Parameter.cs rename to DeviceSQL.Devices.ROC/Data/Int16Parameter.cs index bd62f93..d016264 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/Int16Parameter.cs +++ b/DeviceSQL.Devices.ROC/Data/Int16Parameter.cs @@ -7,7 +7,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class Int16Parameter : Parameter { diff --git a/DeviceSQL.Devices/Device/ROC/Data/Int32Parameter.cs b/DeviceSQL.Devices.ROC/Data/Int32Parameter.cs similarity index 92% rename from DeviceSQL.Devices/Device/ROC/Data/Int32Parameter.cs rename to DeviceSQL.Devices.ROC/Data/Int32Parameter.cs index 4464417..a0b80b6 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/Int32Parameter.cs +++ b/DeviceSQL.Devices.ROC/Data/Int32Parameter.cs @@ -7,7 +7,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class Int32Parameter : Parameter { diff --git a/DeviceSQL.Devices/Device/ROC/Data/Int8Parameter.cs b/DeviceSQL.Devices.ROC/Data/Int8Parameter.cs similarity index 93% rename from DeviceSQL.Devices/Device/ROC/Data/Int8Parameter.cs rename to DeviceSQL.Devices.ROC/Data/Int8Parameter.cs index 70e95d0..d48fd9e 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/Int8Parameter.cs +++ b/DeviceSQL.Devices.ROC/Data/Int8Parameter.cs @@ -7,7 +7,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class Int8Parameter : Parameter { diff --git a/DeviceSQL.Devices/Device/ROC/Data/Parameter.cs b/DeviceSQL.Devices.ROC/Data/Parameter.cs similarity index 97% rename from DeviceSQL.Devices/Device/ROC/Data/Parameter.cs rename to DeviceSQL.Devices.ROC/Data/Parameter.cs index 9d78949..4c8a1a2 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/Parameter.cs +++ b/DeviceSQL.Devices.ROC/Data/Parameter.cs @@ -7,7 +7,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public abstract class Parameter : IROCParameterData diff --git a/DeviceSQL.Devices/Device/ROC/Data/ParameterType.cs b/DeviceSQL.Devices.ROC/Data/ParameterType.cs similarity index 83% rename from DeviceSQL.Devices/Device/ROC/Data/ParameterType.cs rename to DeviceSQL.Devices.ROC/Data/ParameterType.cs index ff4625b..d6aa0d6 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/ParameterType.cs +++ b/DeviceSQL.Devices.ROC/Data/ParameterType.cs @@ -4,7 +4,11 @@ using System.Text; using System.Threading.Tasks; -namespace DeviceSQL.Devices.Device.ROC.Data +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else +namespace DeviceSQL.Device.ROC.Data +#endif { public enum ParameterType : byte { diff --git a/DeviceSQL.Devices/Device/ROC/Data/RocPlusAlarmRecord.cs b/DeviceSQL.Devices.ROC/Data/RocPlusAlarmRecord.cs similarity index 98% rename from DeviceSQL.Devices/Device/ROC/Data/RocPlusAlarmRecord.cs rename to DeviceSQL.Devices.ROC/Data/RocPlusAlarmRecord.cs index bd0c820..cbed84a 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/RocPlusAlarmRecord.cs +++ b/DeviceSQL.Devices.ROC/Data/RocPlusAlarmRecord.cs @@ -7,7 +7,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { #region Enums diff --git a/DeviceSQL.Devices/Device/ROC/Data/RocPlusEventRecord.cs b/DeviceSQL.Devices.ROC/Data/RocPlusEventRecord.cs similarity index 99% rename from DeviceSQL.Devices/Device/ROC/Data/RocPlusEventRecord.cs rename to DeviceSQL.Devices.ROC/Data/RocPlusEventRecord.cs index 4ac6e17..5c7258a 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/RocPlusEventRecord.cs +++ b/DeviceSQL.Devices.ROC/Data/RocPlusEventRecord.cs @@ -1,6 +1,6 @@ #region Imported Types -using DeviceSQL.Devices.Device.ROC.Data; + using System; using System.Collections.Generic; using System.Linq; @@ -8,7 +8,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { #region Enums diff --git a/DeviceSQL.Devices/Device/ROC/Data/RocPlusHistoryRecord.cs b/DeviceSQL.Devices.ROC/Data/RocPlusHistoryRecord.cs similarity index 95% rename from DeviceSQL.Devices/Device/ROC/Data/RocPlusHistoryRecord.cs rename to DeviceSQL.Devices.ROC/Data/RocPlusHistoryRecord.cs index 1d1848c..11b1a36 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/RocPlusHistoryRecord.cs +++ b/DeviceSQL.Devices.ROC/Data/RocPlusHistoryRecord.cs @@ -4,7 +4,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public struct ROCPlusHistoryRecord { diff --git a/DeviceSQL.Devices/Device/ROC/Data/TimeParameter.cs b/DeviceSQL.Devices.ROC/Data/TimeParameter.cs similarity index 93% rename from DeviceSQL.Devices/Device/ROC/Data/TimeParameter.cs rename to DeviceSQL.Devices.ROC/Data/TimeParameter.cs index 76d6bb2..945364e 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/TimeParameter.cs +++ b/DeviceSQL.Devices.ROC/Data/TimeParameter.cs @@ -4,7 +4,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class TimeParameter : Parameter { diff --git a/DeviceSQL.Devices/Device/ROC/Data/Tlp.cs b/DeviceSQL.Devices.ROC/Data/Tlp.cs similarity index 95% rename from DeviceSQL.Devices/Device/ROC/Data/Tlp.cs rename to DeviceSQL.Devices.ROC/Data/Tlp.cs index 69535f7..c5592f0 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/Tlp.cs +++ b/DeviceSQL.Devices.ROC/Data/Tlp.cs @@ -1,4 +1,8 @@ -namespace DeviceSQL.Device.ROC.Data +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else +namespace DeviceSQL.Device.ROC.Data +#endif { public class Tlp { diff --git a/DeviceSQL.Devices/Device/ROC/Data/TlpParameter.cs b/DeviceSQL.Devices.ROC/Data/TlpParameter.cs similarity index 87% rename from DeviceSQL.Devices/Device/ROC/Data/TlpParameter.cs rename to DeviceSQL.Devices.ROC/Data/TlpParameter.cs index 570e879..28458db 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/TlpParameter.cs +++ b/DeviceSQL.Devices.ROC/Data/TlpParameter.cs @@ -1,4 +1,8 @@ -namespace DeviceSQL.Device.ROC.Data +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else +namespace DeviceSQL.Device.ROC.Data +#endif { public class TlpParameter : Parameter { diff --git a/DeviceSQL.Devices/Device/ROC/Data/UInt16Parameter.cs b/DeviceSQL.Devices.ROC/Data/UInt16Parameter.cs similarity index 92% rename from DeviceSQL.Devices/Device/ROC/Data/UInt16Parameter.cs rename to DeviceSQL.Devices.ROC/Data/UInt16Parameter.cs index 3aa46dd..af55c2c 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/UInt16Parameter.cs +++ b/DeviceSQL.Devices.ROC/Data/UInt16Parameter.cs @@ -4,7 +4,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class UInt16Parameter : Parameter { diff --git a/DeviceSQL.Devices/Device/ROC/Data/UInt32Parameter.cs b/DeviceSQL.Devices.ROC/Data/UInt32Parameter.cs similarity index 93% rename from DeviceSQL.Devices/Device/ROC/Data/UInt32Parameter.cs rename to DeviceSQL.Devices.ROC/Data/UInt32Parameter.cs index 545b104..c296937 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/UInt32Parameter.cs +++ b/DeviceSQL.Devices.ROC/Data/UInt32Parameter.cs @@ -4,7 +4,11 @@ #endregion +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else namespace DeviceSQL.Device.ROC.Data +#endif { public class UInt32Parameter : Parameter { diff --git a/DeviceSQL.Devices/Device/ROC/Data/UInt8Parameter.cs b/DeviceSQL.Devices.ROC/Data/UInt8Parameter.cs similarity index 85% rename from DeviceSQL.Devices/Device/ROC/Data/UInt8Parameter.cs rename to DeviceSQL.Devices.ROC/Data/UInt8Parameter.cs index a3d43c1..73f5d91 100644 --- a/DeviceSQL.Devices/Device/ROC/Data/UInt8Parameter.cs +++ b/DeviceSQL.Devices.ROC/Data/UInt8Parameter.cs @@ -1,4 +1,8 @@ -namespace DeviceSQL.Device.ROC.Data +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else +namespace DeviceSQL.Device.ROC.Data +#endif { public class UInt8Parameter : Parameter { diff --git a/DeviceSQL.Devices/Device/ROC/Device.cs b/DeviceSQL.Devices.ROC/Device.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Device.cs rename to DeviceSQL.Devices.ROC/Device.cs diff --git a/DeviceSQL.Devices.ROC/DeviceSQL.Devices.ROC.csproj b/DeviceSQL.Devices.ROC/DeviceSQL.Devices.ROC.csproj new file mode 100644 index 0000000..9a7c817 --- /dev/null +++ b/DeviceSQL.Devices.ROC/DeviceSQL.Devices.ROC.csproj @@ -0,0 +1,156 @@ + + + + + Debug + AnyCPU + {AF0E4B64-F2C2-4459-A518-9AA905FF6F0F} + Library + Properties + DeviceSQL.Devices.ROC + DeviceSQL.Devices.ROC + v4.8 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {5deadadf-be60-4774-80c6-97b3a83fa289} + DeviceSQL.Devices.Common + + + + \ No newline at end of file diff --git a/DeviceSQL.Devices/Device/ROC/FST/Arguments/ArgumentBase.cs b/DeviceSQL.Devices.ROC/FST/Arguments/ArgumentBase.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/FST/Arguments/ArgumentBase.cs rename to DeviceSQL.Devices.ROC/FST/Arguments/ArgumentBase.cs diff --git a/DeviceSQL.Devices/Device/ROC/FST/Arguments/ArgumentDataType.cs b/DeviceSQL.Devices.ROC/FST/Arguments/ArgumentDataType.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/FST/Arguments/ArgumentDataType.cs rename to DeviceSQL.Devices.ROC/FST/Arguments/ArgumentDataType.cs diff --git a/DeviceSQL.Devices/Device/ROC/FST/Arguments/ArgumentType.cs b/DeviceSQL.Devices.ROC/FST/Arguments/ArgumentType.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/FST/Arguments/ArgumentType.cs rename to DeviceSQL.Devices.ROC/FST/Arguments/ArgumentType.cs diff --git a/DeviceSQL.Devices/Device/ROC/FST/Arguments/DatabasePoint.cs b/DeviceSQL.Devices.ROC/FST/Arguments/DatabasePoint.cs similarity index 93% rename from DeviceSQL.Devices/Device/ROC/FST/Arguments/DatabasePoint.cs rename to DeviceSQL.Devices.ROC/FST/Arguments/DatabasePoint.cs index 3491bba..196c287 100644 --- a/DeviceSQL.Devices/Device/ROC/FST/Arguments/DatabasePoint.cs +++ b/DeviceSQL.Devices.ROC/FST/Arguments/DatabasePoint.cs @@ -1,5 +1,4 @@ -using DeviceSQL.Devices.Device.ROC.Data; - + namespace DeviceSQL.Device.ROC.Data.FST.Arguments { public class DatabasePoint diff --git a/DeviceSQL.Devices/Device/ROC/FST/Arguments/DatabasePointOrConstantValueArgument.cs b/DeviceSQL.Devices.ROC/FST/Arguments/DatabasePointOrConstantValueArgument.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/FST/Arguments/DatabasePointOrConstantValueArgument.cs rename to DeviceSQL.Devices.ROC/FST/Arguments/DatabasePointOrConstantValueArgument.cs diff --git a/DeviceSQL.Devices/Device/ROC/FST/Arguments/NullArgument.cs b/DeviceSQL.Devices.ROC/FST/Arguments/NullArgument.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/FST/Arguments/NullArgument.cs rename to DeviceSQL.Devices.ROC/FST/Arguments/NullArgument.cs diff --git a/DeviceSQL.Devices/Device/ROC/FST/Instructions/AddInstruction.cs b/DeviceSQL.Devices.ROC/FST/Instructions/AddInstruction.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/FST/Instructions/AddInstruction.cs rename to DeviceSQL.Devices.ROC/FST/Instructions/AddInstruction.cs diff --git a/DeviceSQL.Devices/Device/ROC/FST/Instructions/InstructionBase.cs b/DeviceSQL.Devices.ROC/FST/Instructions/InstructionBase.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/FST/Instructions/InstructionBase.cs rename to DeviceSQL.Devices.ROC/FST/Instructions/InstructionBase.cs diff --git a/DeviceSQL.Devices/Device/ROC/FST/Instructions/InstructionCategory.cs b/DeviceSQL.Devices.ROC/FST/Instructions/InstructionCategory.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/FST/Instructions/InstructionCategory.cs rename to DeviceSQL.Devices.ROC/FST/Instructions/InstructionCategory.cs diff --git a/DeviceSQL.Devices/Device/ROC/FST/Instructions/InstructionType.cs b/DeviceSQL.Devices.ROC/FST/Instructions/InstructionType.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/FST/Instructions/InstructionType.cs rename to DeviceSQL.Devices.ROC/FST/Instructions/InstructionType.cs diff --git a/DeviceSQL.Devices/Device/ROC/IO/Transport/Transport.cs b/DeviceSQL.Devices.ROC/IO/Transport/Transport.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/IO/Transport/Transport.cs rename to DeviceSQL.Devices.ROC/IO/Transport/Transport.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/IRocMessage.cs b/DeviceSQL.Devices.ROC/Message/IRocMessage.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/IRocMessage.cs rename to DeviceSQL.Devices.ROC/Message/IRocMessage.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/IRocRequestMessage.cs b/DeviceSQL.Devices.ROC/Message/IRocRequestMessage.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/IRocRequestMessage.cs rename to DeviceSQL.Devices.ROC/Message/IRocRequestMessage.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/IRocResponseMessage.cs b/DeviceSQL.Devices.ROC/Message/IRocResponseMessage.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/IRocResponseMessage.cs rename to DeviceSQL.Devices.ROC/Message/IRocResponseMessage.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode007Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode007Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode007Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode007Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode007Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode007Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode007Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode007Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode008Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode008Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode008Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode008Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode008Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode008Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode008Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode008Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode017Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode017Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode017Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode017Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode017Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode017Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode017Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode017Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode080Function.cs b/DeviceSQL.Devices.ROC/Message/OpCode080Function.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode080Function.cs rename to DeviceSQL.Devices.ROC/Message/OpCode080Function.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode080Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode080Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode080Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode080Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode080Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode080Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode080Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode080Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode118Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode118Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode118Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode118Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode118Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode118Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode118Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode118Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode119Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode119Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode119Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode119Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode119Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode119Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode119Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode119Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode120Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode120Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode120Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode120Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode120Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode120Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode120Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode120Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode121Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode121Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode121Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode121Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode121Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode121Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode121Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode121Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode122Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode122Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode122Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode122Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode122Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode122Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode122Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode122Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode126Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode126Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode126Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode126Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode126Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode126Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode126Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode126Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode130Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode130Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode130Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode130Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode130Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode130Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode130Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode130Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode131Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode131Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode131Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode131Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode131Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode131Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode131Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode131Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode132Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode132Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode132Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode132Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode132Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode132Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode132Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode132Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode136Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode136Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode136Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode136Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode136Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode136Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode136Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode136Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode139Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode139Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode139Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode139Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode139Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode139Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode139Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode139Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode165Request .cs b/DeviceSQL.Devices.ROC/Message/OpCode165Request .cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode165Request .cs rename to DeviceSQL.Devices.ROC/Message/OpCode165Request .cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode165Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode165Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode165Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode165Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode166Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode166Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode166Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode166Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode166Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode166Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode166Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode166Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode167Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode167Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode167Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode167Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode167Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode167Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode167Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode167Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode180Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode180Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode180Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode180Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode180Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode180Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode180Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode180Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode181Request.cs b/DeviceSQL.Devices.ROC/Message/OpCode181Request.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode181Request.cs rename to DeviceSQL.Devices.ROC/Message/OpCode181Request.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode181Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode181Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode181Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode181Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/OpCode255Response.cs b/DeviceSQL.Devices.ROC/Message/OpCode255Response.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/OpCode255Response.cs rename to DeviceSQL.Devices.ROC/Message/OpCode255Response.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/ParameterDatabase.cs b/DeviceSQL.Devices.ROC/Message/ParameterDatabase.cs similarity index 99% rename from DeviceSQL.Devices/Device/ROC/Message/ParameterDatabase.cs rename to DeviceSQL.Devices.ROC/Message/ParameterDatabase.cs index 8ec0236..f4e5ced 100644 --- a/DeviceSQL.Devices/Device/ROC/Message/ParameterDatabase.cs +++ b/DeviceSQL.Devices.ROC/Message/ParameterDatabase.cs @@ -4,7 +4,11 @@ #endregion -namespace DeviceSQL.Device.ROC.Message +#if SQLTYPES +namespace DeviceSQL.SQLTypes.ROC.Data +#else +namespace DeviceSQL.Device.ROC.Data +#endif { public static class ParameterDatabase { diff --git a/DeviceSQL.Devices/Device/ROC/Message/RocMessage.cs b/DeviceSQL.Devices.ROC/Message/RocMessage.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/RocMessage.cs rename to DeviceSQL.Devices.ROC/Message/RocMessage.cs diff --git a/DeviceSQL.Devices/Device/ROC/Message/RocMessageFactory.cs b/DeviceSQL.Devices.ROC/Message/RocMessageFactory.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Message/RocMessageFactory.cs rename to DeviceSQL.Devices.ROC/Message/RocMessageFactory.cs diff --git a/DeviceSQL.Devices/Device/ROC/OpCode255Exception.cs b/DeviceSQL.Devices.ROC/OpCode255Exception.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/OpCode255Exception.cs rename to DeviceSQL.Devices.ROC/OpCode255Exception.cs diff --git a/DeviceSQL.TestHarness/Properties/AssemblyInfo.cs b/DeviceSQL.Devices.ROC/Properties/AssemblyInfo.cs similarity index 74% rename from DeviceSQL.TestHarness/Properties/AssemblyInfo.cs rename to DeviceSQL.Devices.ROC/Properties/AssemblyInfo.cs index 6b01e4f..40f2a06 100644 --- a/DeviceSQL.TestHarness/Properties/AssemblyInfo.cs +++ b/DeviceSQL.Devices.ROC/Properties/AssemblyInfo.cs @@ -5,14 +5,15 @@ // 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("DeviceSQL.TestHarness")] -[assembly: AssemblyDescription("")] +[assembly: AssemblyTitle("DeviceSQL.Devices.ROC")] +[assembly: AssemblyDescription("DeviceSQL.Devices.ROC")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("DeviceSQL.TestHarness")] -[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyCompany("CloudSonix")] +[assembly: AssemblyProduct("DeviceSQL")] +[assembly: AssemblyCopyright("© CloudSonix. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] +[assembly: AssemblyKeyFileAttribute("../DeviceSQL-Key.snk")] // 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 @@ -20,7 +21,7 @@ [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("ff09f40d-a515-4abb-9db1-21d9d1f2793e")] +[assembly: Guid("af0e4b64-f2c2-4459-a518-9aa905ff6f0f")] // Version information for an assembly consists of the following four values: // diff --git a/DeviceSQL.Devices/Device/ROC/ROCMaster.cs b/DeviceSQL.Devices.ROC/ROCMaster.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/ROCMaster.cs rename to DeviceSQL.Devices.ROC/ROCMaster.cs diff --git a/DeviceSQL.Devices/Device/ROC/Utility/Crc16.cs b/DeviceSQL.Devices.ROC/Utility/Crc16.cs similarity index 100% rename from DeviceSQL.Devices/Device/ROC/Utility/Crc16.cs rename to DeviceSQL.Devices.ROC/Utility/Crc16.cs diff --git a/DeviceSQL.Devices/Device/ROC/Crc16.cs b/DeviceSQL.Devices/Device/ROC/Crc16.cs deleted file mode 100644 index 54bae8a..0000000 --- a/DeviceSQL.Devices/Device/ROC/Crc16.cs +++ /dev/null @@ -1,110 +0,0 @@ -#region Imported Types - -using System; - -#endregion - -namespace DeviceSQL.Device.ROC.Utility -{ - public class CRC16 : System.Security.Cryptography.HashAlgorithm - { - - #region Fields - - protected System.UInt16 _crc; - - protected readonly static System.UInt16 _initialCondition = 0x0; - - /* Table of CRC values for high-order byte */ - protected readonly static byte[] _crcHiLookupTable = { - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, - 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, - 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, - 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, - 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, - 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, - 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, - 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, - 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, - 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 - }; - - /* Table of CRC values for low-order byte */ - protected readonly static byte[] _crcLoLookupTable = { - 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, - 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, - 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, - 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, - 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, - 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, - 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, - 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, - 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, - 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, - 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, - 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, - 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, - 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, - 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, - 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, - 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, - 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, - 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, - 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, - 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, - 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, - 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, - 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, - 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, - 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 - }; - - #endregion - - #region Overridden Methods - - public override void Initialize() - { - _crc = _initialCondition; - } - - protected override void HashCore(byte[] buffer, int offset, int count) - { - byte[] crc = BitConverter.GetBytes(_crc); - int nextByte = 0; - int uIndex; - for (int i = offset; i < count && i < buffer.Length; i++) - { - nextByte = (0xFF & ((int)buffer[i])); - uIndex = (crc[0] ^ nextByte); - crc[0] = (Convert.ToByte((crc[1] ^ _crcHiLookupTable[uIndex]))); - crc[1] = _crcLoLookupTable[uIndex]; - } - _crc = BitConverter.ToUInt16(crc, 0); - } - - protected override byte[] HashFinal() - { - return BitConverter.GetBytes(_crc); - } - - #endregion - - } -} diff --git a/DeviceSQL.Devices/DeviceSQL.Devices.csproj b/DeviceSQL.Devices/DeviceSQL.Devices.csproj deleted file mode 100644 index 0bc84fc..0000000 --- a/DeviceSQL.Devices/DeviceSQL.Devices.csproj +++ /dev/null @@ -1,206 +0,0 @@ - - - - - Debug - AnyCPU - {80ED4080-6FD1-492F-B70E-8C837B3DADC7} - Library - Properties - DeviceSQL.Devices - DeviceSQL.Devices - v4.6.1 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/DeviceSQL.Devices/IO/Channels/ChannelTraceEventArgs.cs b/DeviceSQL.Devices/IO/Channels/ChannelTraceEventArgs.cs deleted file mode 100644 index dcd1a99..0000000 --- a/DeviceSQL.Devices/IO/Channels/ChannelTraceEventArgs.cs +++ /dev/null @@ -1,23 +0,0 @@ -#region Imported Types - -using System; -using System.Collections.Generic; -using System.Text; - -#endregion - -namespace DeviceSQL.IO.Channels -{ - internal class ChannelTraceEventArgs : EventArgs - { - internal DateTime MessageDateTimeStamp { get; set; } - internal string Name { get; set; } - internal DateTime StartTime { get; set; } - internal string Operation { get; set; } - internal double Duration { get; set; } - internal int Sequence { get; set; } - internal int Count { get; set; } - internal string Data { get; set; } - internal string ChannelType { get; set; } - } -} diff --git a/DeviceSQL.Devices/IO/Channels/SerialPortMuxChannel.cs b/DeviceSQL.Devices/IO/Channels/SerialPortMuxChannel.cs deleted file mode 100644 index 29d18a3..0000000 --- a/DeviceSQL.Devices/IO/Channels/SerialPortMuxChannel.cs +++ /dev/null @@ -1,139 +0,0 @@ -#region Imported Types - -using System; -using System.Diagnostics; -using System.IO.Ports; -using System.Linq; - -#endregion - -namespace DeviceSQL.IO.Channels -{ - public class SerialPortMuxChannel : SerialPortChannel, IMuxChannel - { - - #region Fields - - private string sourceChannelName = ""; - private int requestDelay = 0; - private int responseDelay = 0; - private int responseTimeout = 3000; - - #endregion - - #region Properties - - public IChannel SourceChannel - { - get - { - return null;//return Watchdog.Worker.Channels.FirstOrDefault(channel => channel.Name == sourceChannelName); - } - } - - public string SourceChannelName - { - get - { - return sourceChannelName; - } - set - { - sourceChannelName = value; - } - } - - public int RequestDelay - { - get - { - return requestDelay; - } - set - { - requestDelay = value; - } - } - - public int ResponseDelay - { - get - { - return responseDelay; - } - set - { - responseDelay = value; - } - } - - public int ResponseTimeout - { - get - { - return responseTimeout; - } - set - { - responseTimeout = value; - } - } - - #endregion - - #region Mux Methods - - public void Run() - { - SerialPort.DataReceived -= SerialPort_DataReceived; - SerialPort.DataReceived += SerialPort_DataReceived; - } - - public void Stop() - { - SerialPort.DataReceived -= SerialPort_DataReceived; - } - - #endregion - - #region Serial Port Events - - private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) - { - var startTime = DateTime.Now; - var lockObject = SourceChannel.LockObject; - lock (lockObject) - { - var masterStopWatch = new Stopwatch(); - var requestBytes = new byte[] { }; - - TimedThreadBlocker.Wait(requestDelay); - - requestBytes = new byte[SerialPort.BytesToRead]; - - if (requestBytes.Length > 0) - { - Read(ref requestBytes, 0, requestBytes.Length, 0); - SourceChannel.Write(ref requestBytes, 0, requestBytes.Length); - TimedThreadBlocker.Wait(responseDelay); - masterStopWatch.Start(); - - var sequence = 0; - while (SourceChannel.NumberOfBytesAvailable > 0 && responseTimeout > masterStopWatch.ElapsedMilliseconds) - { - var responseBytes = new byte[SourceChannel.NumberOfBytesAvailable]; - - SourceChannel.Read(ref responseBytes, 0, responseBytes.Length, sequence++); - Write(ref responseBytes, 0, responseBytes.Length); - } - - masterStopWatch.Stop(); - - } - } - } - - #endregion - - } -} diff --git a/DeviceSQL.ModbusMaster/DeviceSQL.ModbusMaster.sqlproj b/DeviceSQL.ModbusMaster/DeviceSQL.ModbusMaster.sqlproj new file mode 100644 index 0000000..3b76adc --- /dev/null +++ b/DeviceSQL.ModbusMaster/DeviceSQL.ModbusMaster.sqlproj @@ -0,0 +1,100 @@ + + + + + Debug + AnyCPU + DeviceSQL.ModbusMaster + 2.0 + 4.1 + {bf99e0a7-f591-4629-8dd2-dda18b05e5f2} + Microsoft.Data.Tools.Schema.Sql.Sql140DatabaseSchemaProvider + Database + + + DeviceSQL.ModbusMaster + DeviceSQL.ModbusMaster + 1033, CI + BySchemaAndSchemaType + True + v4.8 + CS + Properties + False + True + True + ModbusMaster + + UNSAFE + False + ..\DeviceSQL-Key.snk + + + bin\Release\ + $(MSBuildProjectName).sql + False + pdbonly + true + false + true + prompt + 4 + + + bin\Debug\ + $(MSBuildProjectName).sql + false + true + full + false + true + true + prompt + 4 + + + 11.0 + + True + 11.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DeviceSQL.SQLTypes.Modbus + {cd45d76e-d2ed-4587-9873-f35ad24e42a5} + True + True + True + + + \ No newline at end of file diff --git a/DeviceSQL.ModbusMaster/Functions/ReadCoils.cs b/DeviceSQL.ModbusMaster/Functions/ReadCoils.cs new file mode 100644 index 0000000..d9cb1a9 --- /dev/null +++ b/DeviceSQL.ModbusMaster/Functions/ReadCoils.cs @@ -0,0 +1,22 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.Modbus; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class MODBUSMaster + { + [SqlFunction] + public static CoilRegisterArray ReadCoils(SqlString deviceName, CoilRegisterArray coilRegisterArray) + { + //var deviceNameValue = deviceName.Value; + //var coilRegisters = new List(coilRegisterArray.coilRegisters.Select(coilRegister => new Device.MODBUS.Data.CoilRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(coilRegister.Address.RelativeAddress.Value), coilRegister.Address.IsZeroBased.Value)))); + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadCoilRegisters(null, ref coilRegisters, null); + return CoilRegisterArray.Null; // new Types.MODBUSMaster.MODBUSMaster_CoilRegisterArray() { coilRegisters = coilRegisters.Select(coilRegister => new Types.MODBUSMaster.MODBUSMaster_CoilRegister() { Address = new Types.MODBUSMaster.MODBUSMaster_MODBUSAddress { RelativeAddress = coilRegister.Address.RelativeAddress, IsZeroBased = coilRegister.Address.IsZeroBased }, Data = coilRegister.Data }).ToList() }; + } + } +} diff --git a/DeviceSQL.ModbusMaster/Functions/ReadDiscreteInputs.cs b/DeviceSQL.ModbusMaster/Functions/ReadDiscreteInputs.cs new file mode 100644 index 0000000..b62b685 --- /dev/null +++ b/DeviceSQL.ModbusMaster/Functions/ReadDiscreteInputs.cs @@ -0,0 +1,22 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.Modbus; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class MODBUSMaster + { + [SqlFunction] + public static DiscreteInputRegisterArray ReadDiscreteInputs(SqlString deviceName, DiscreteInputRegisterArray discreteInputRegisterArray) + { + //var deviceNameValue = deviceName.Value; + //var discreteInputRegisters = new List(discreteInputRegisterArray.discreteInputRegisters.Select(discreteInputRegister => new Device.MODBUS.Data.DiscreteInputRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(discreteInputRegister.Address.RelativeAddress.Value), discreteInputRegister.Address.IsZeroBased.Value)))); + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadDiscreteInputRegisters(null, ref discreteInputRegisters, null); + return DiscreteInputRegisterArray.Null; // new Types.MODBUSMaster.MODBUSMaster_DiscreteInputRegisterArray() { discreteInputRegisters = discreteInputRegisters.Select(discreteInputRegister => new Types.MODBUSMaster.MODBUSMaster_DiscreteInputRegister() { Address = new Types.MODBUSMaster.MODBUSMaster_MODBUSAddress { RelativeAddress = discreteInputRegister.Address.RelativeAddress, IsZeroBased = discreteInputRegister.Address.IsZeroBased }, Data = discreteInputRegister.Data }).ToList() }; + } + } +} \ No newline at end of file diff --git a/DeviceSQL.ModbusMaster/Functions/ReadEventArchiveRecords.cs b/DeviceSQL.ModbusMaster/Functions/ReadEventArchiveRecords.cs new file mode 100644 index 0000000..460bee2 --- /dev/null +++ b/DeviceSQL.ModbusMaster/Functions/ReadEventArchiveRecords.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.Modbus; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class MODBUSMaster + { + [SqlFunction] + public static EventArchiveRecordArray ReadEventArchiveRecords(SqlString deviceName, ModbusAddress eventArchiveAddress, SqlInt32 index) + { + //var deviceNameValue = deviceName.Value; + //var eventArchiveRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadEventArchiveRecord(null, new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(eventArchiveAddress.RelativeAddress.Value), eventArchiveAddress.IsZeroBased.Value), Convert.ToUInt16(index.Value), null); + return EventArchiveRecordArray.Null; // new Types.MODBUSMaster.MODBUSMaster_EventArchiveRecordArray() { eventArchiveRecords = eventArchiveRecords.Select(ear => new Types.MODBUSMaster.MODBUSMaster_EventArchiveRecord() { Index = ear.Index, Data = ear.Data }).ToList() }; + } + } +} diff --git a/DeviceSQL.ModbusMaster/Functions/ReadFloats.cs b/DeviceSQL.ModbusMaster/Functions/ReadFloats.cs new file mode 100644 index 0000000..451f140 --- /dev/null +++ b/DeviceSQL.ModbusMaster/Functions/ReadFloats.cs @@ -0,0 +1,22 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.Modbus; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class MODBUSMaster + { + [SqlFunction] + public static FloatRegisterArray ReadFloats(SqlString deviceName, FloatRegisterArray floatRegisterArray) + { + //var deviceNameValue = deviceName.Value; + //var floatRegisters = new List(floatRegisterArray.floatRegisters.Select(floatRegister => new Device.MODBUS.Data.FloatRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(floatRegister.Address.RelativeAddress.Value), floatRegister.Address.IsZeroBased.Value), floatRegister.ByteSwap.Value, floatRegister.WordSwap.Value))); + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadFloatRegisters(null, ref floatRegisters, null); + return FloatRegisterArray.Null; // new Types.MODBUSMaster.MODBUSMaster_FloatRegisterArray() { floatRegisters = floatRegisters.Select(floatRegister => new Types.MODBUSMaster.MODBUSMaster_FloatRegister() { Address = new Types.MODBUSMaster.MODBUSMaster_MODBUSAddress { RelativeAddress = floatRegister.Address.RelativeAddress, IsZeroBased = floatRegister.Address.IsZeroBased }, Data = floatRegister.Data }).ToList() }; + } + } +} diff --git a/DeviceSQL.ModbusMaster/Functions/ReadHistoryArchiveRecord.cs b/DeviceSQL.ModbusMaster/Functions/ReadHistoryArchiveRecord.cs new file mode 100644 index 0000000..7ff040b --- /dev/null +++ b/DeviceSQL.ModbusMaster/Functions/ReadHistoryArchiveRecord.cs @@ -0,0 +1,22 @@ +#region Imported Types + + +using DeviceSQL.SQLTypes.Modbus; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class MODBUSMaster + { + [SqlFunction] + public static HistoryArchiveRecord ReadHistoryArchiveRecord(SqlString deviceName, ModbusAddress historyArchiveAddress, SqlInt32 index, SqlByte recordSize) + { + //var deviceNameValue = deviceName.Value; + //var historyArchiveRecord = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadHistoryArchiveRecord(null, new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(historyArchiveAddress.RelativeAddress.Value), historyArchiveAddress.IsZeroBased.Value), Convert.ToUInt16(index.Value), recordSize.Value, null); + return HistoryArchiveRecord.Null; // new Types.MODBUSMaster.MODBUSMaster_HistoryArchiveRecord() { Index = historyArchiveRecord.Index, Data = historyArchiveRecord.Data }; + } + } +} diff --git a/DeviceSQL.ModbusMaster/Functions/ReadHoldings.cs b/DeviceSQL.ModbusMaster/Functions/ReadHoldings.cs new file mode 100644 index 0000000..2682cba --- /dev/null +++ b/DeviceSQL.ModbusMaster/Functions/ReadHoldings.cs @@ -0,0 +1,22 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.Modbus; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class MODBUSMaster + { + [SqlFunction] + public static HoldingRegisterArray ReadHoldings(SqlString deviceName, HoldingRegisterArray holdingRegisterArray) + { + //var deviceNameValue = deviceName.Value; + //var holdingRegisters = new List(holdingRegisterArray.holdingRegisters.Select(holdingRegister => new Device.MODBUS.Data.HoldingRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(holdingRegister.Address.RelativeAddress.Value), holdingRegister.Address.IsZeroBased.Value), holdingRegister.ByteSwap.Value))); + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadHoldingRegisters(null, ref holdingRegisters, null); + return HoldingRegisterArray.Null; // new Types.MODBUSMaster.MODBUSMaster_HoldingRegisterArray() { holdingRegisters = holdingRegisters.Select(holdingRegister => new Types.MODBUSMaster.MODBUSMaster_HoldingRegister() { Address = new Types.MODBUSMaster.MODBUSMaster_MODBUSAddress { RelativeAddress = holdingRegister.Address.RelativeAddress, IsZeroBased = holdingRegister.Address.IsZeroBased }, ByteSwap = holdingRegister.ByteSwap, Data = holdingRegister.Data }).ToList() }; + } + } +} diff --git a/DeviceSQL.ModbusMaster/Functions/ReadInputs.cs b/DeviceSQL.ModbusMaster/Functions/ReadInputs.cs new file mode 100644 index 0000000..80441c9 --- /dev/null +++ b/DeviceSQL.ModbusMaster/Functions/ReadInputs.cs @@ -0,0 +1,22 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.Modbus; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class MODBUSMaster + { + [SqlFunction] + public static InputRegisterArray ReadInputs(SqlString deviceName, InputRegisterArray inputRegisterArray) + { + //var deviceNameValue = deviceName.Value; + // var inputRegisters = new List(inputRegisterArray.inputRegisters.Select(inputRegister => new Device.MODBUS.Data.InputRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(inputRegister.Address.RelativeAddress.Value), inputRegister.Address.IsZeroBased.Value), inputRegister.ByteSwap.Value))); + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadInputRegisters(null, ref inputRegisters, null); + return InputRegisterArray.Null; // new Types.MODBUSMaster.MODBUSMaster_InputRegisterArray() { inputRegisters = inputRegisters.Select(inputRegister => new Types.MODBUSMaster.MODBUSMaster_InputRegister() { Address = new Types.MODBUSMaster.MODBUSMaster_MODBUSAddress { RelativeAddress = inputRegister.Address.RelativeAddress, IsZeroBased = inputRegister.Address.IsZeroBased }, ByteSwap = inputRegister.ByteSwap, Data = inputRegister.Data }).ToList() }; + } + } +} diff --git a/DeviceSQL.ModbusMaster/Functions/ReadLongs.cs b/DeviceSQL.ModbusMaster/Functions/ReadLongs.cs new file mode 100644 index 0000000..307c8f7 --- /dev/null +++ b/DeviceSQL.ModbusMaster/Functions/ReadLongs.cs @@ -0,0 +1,22 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.Modbus; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class MODBUSMaster + { + [SqlFunction] + public static LongRegisterArray ReadLongs(SqlString deviceName, LongRegisterArray longRegisterArray) + { + // var deviceNameValue = deviceName.Value; + //var longRegisters = new List(longRegisterArray.longRegisters.Select(longRegister => new Device.MODBUS.Data.LongRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(longRegister.Address.RelativeAddress.Value), longRegister.Address.IsZeroBased.Value), longRegister.ByteSwap.Value, longRegister.WordSwap.Value))); + // (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadLongRegisters(null, ref longRegisters, null); + return LongRegisterArray.Null; // new Types.MODBUSMaster.MODBUSMaster_LongRegisterArray() { longRegisters = longRegisters.Select(floatRegister => new Types.MODBUSMaster.MODBUSMaster_LongRegister() { Address = new Types.MODBUSMaster.MODBUSMaster_MODBUSAddress { RelativeAddress = floatRegister.Address.RelativeAddress, IsZeroBased = floatRegister.Address.IsZeroBased }, Data = floatRegister.Data }).ToList() }; + } + } +} diff --git a/DeviceSQL.ModbusMaster/Functions/ReadShorts.cs b/DeviceSQL.ModbusMaster/Functions/ReadShorts.cs new file mode 100644 index 0000000..15d8192 --- /dev/null +++ b/DeviceSQL.ModbusMaster/Functions/ReadShorts.cs @@ -0,0 +1,22 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.Modbus; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class MODBUSMaster + { + [SqlFunction] + public static ShortRegisterArray ReadShorts(SqlString deviceName, ShortRegisterArray shortRegisterArray) + { + //var deviceNameValue = deviceName.Value; + //var shortRegisters = new List(shortRegisterArray.shortRegisters.Select(longRegister => new Device.MODBUS.Data.ShortRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(longRegister.Address.RelativeAddress.Value), longRegister.Address.IsZeroBased.Value), longRegister.ByteSwap.Value))); + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadShortRegisters(null, ref shortRegisters, null); + return ShortRegisterArray.Null; // new Types.MODBUSMaster.MODBUSMaster_ShortRegisterArray() { shortRegisters = shortRegisters.Select(shortRegister => new Types.MODBUSMaster.MODBUSMaster_ShortRegister() { Address = new Types.MODBUSMaster.MODBUSMaster_MODBUSAddress { RelativeAddress = shortRegister.Address.RelativeAddress, IsZeroBased = shortRegister.Address.IsZeroBased }, Data = shortRegister.Data }).ToList() }; + } + } +} diff --git a/DeviceSQL.ModbusMaster/Functions/ReadString.cs b/DeviceSQL.ModbusMaster/Functions/ReadString.cs new file mode 100644 index 0000000..43c6ac9 --- /dev/null +++ b/DeviceSQL.ModbusMaster/Functions/ReadString.cs @@ -0,0 +1,23 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.Modbus; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class MODBUSMaster + { + [SqlFunction] + public static StringRegister ReadString(SqlString deviceName, StringRegister stringRegister) + { + //var deviceNameValue = deviceName.Value; + // var stringRegisterValue = new Device.MODBUS.Data.StringRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(stringRegister.Address.RelativeAddress.Value), stringRegister.Address.IsZeroBased.Value), stringRegister.Length.Value); + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).ReadStringRegister(null, null, ref stringRegisterValue); + //stringRegister.Data = stringRegisterValue.Data; + return StringRegister.Null; // stringRegister; + } + } +} diff --git a/DeviceSQL.ModbusMaster/Functions/WriteBoolean.cs b/DeviceSQL.ModbusMaster/Functions/WriteBoolean.cs new file mode 100644 index 0000000..f61bd0e --- /dev/null +++ b/DeviceSQL.ModbusMaster/Functions/WriteBoolean.cs @@ -0,0 +1,22 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.Modbus; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class MODBUSMaster + { + [SqlFunction] + public static SqlBoolean WriteBoolean(SqlString deviceName, BooleanRegister booleanRegister) + { + ///var deviceNameValue = deviceName.Value; + //var booleanRegisterRaw = new Device.MODBUS.Data.BooleanRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(booleanRegister.Address.RelativeAddress.Value), booleanRegister.Address.IsZeroBased.Value)); + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).WriteBooleanRegister(null, booleanRegisterRaw, null); + return true; + } + } +} diff --git a/DeviceSQL.ModbusMaster/Functions/WriteFloats.cs b/DeviceSQL.ModbusMaster/Functions/WriteFloats.cs new file mode 100644 index 0000000..a5537a5 --- /dev/null +++ b/DeviceSQL.ModbusMaster/Functions/WriteFloats.cs @@ -0,0 +1,22 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.Modbus; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class MODBUSMaster + { + [SqlFunction] + public static SqlBoolean WriteFloats(SqlString deviceName, FloatRegisterArray floatRegisterArray) + { + //var deviceNameValue = deviceName.Value; + // var floatRegisters = new List(floatRegisterArray.floatRegisters.Select(floatRegister => new Device.MODBUS.Data.FloatRegister(new Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(floatRegister.Address.RelativeAddress.Value), floatRegister.Address.IsZeroBased.Value), floatRegister.ByteSwap.Value, floatRegister.WordSwap.Value))); + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.MODBUS.MODBUSMaster).WriteFloatRegisters(null, floatRegisters, null); + return true; + } + } +} diff --git a/DeviceSQL.ModbusMaster/Properties/AssemblyInfo.cs b/DeviceSQL.ModbusMaster/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..aa93103 --- /dev/null +++ b/DeviceSQL.ModbusMaster/Properties/AssemblyInfo.cs @@ -0,0 +1,24 @@ +using System.Reflection; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with the SQLCLR assembly. +[assembly: AssemblyTitle("DeviceSQL.ModbusMaster")] +[assembly: AssemblyDescription("DeviceSQL.ModbusMaster")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("CloudSonix")] +[assembly: AssemblyProduct("DeviceSQL")] +[assembly: AssemblyCopyright("© CloudSonix. All rights reserved.")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: AssemblyKeyFileAttribute("../DeviceSQL-Key.snk")] + +// 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/DeviceSQL.ModbusMaster/Schemas/ModbusMaster.sql b/DeviceSQL.ModbusMaster/Schemas/ModbusMaster.sql new file mode 100644 index 0000000..8169108 --- /dev/null +++ b/DeviceSQL.ModbusMaster/Schemas/ModbusMaster.sql @@ -0,0 +1 @@ +CREATE SCHEMA [ModbusMaster] diff --git a/DeviceSQL.ROCMaster/DeviceSQL.ROCMaster.sqlproj b/DeviceSQL.ROCMaster/DeviceSQL.ROCMaster.sqlproj new file mode 100644 index 0000000..929c152 --- /dev/null +++ b/DeviceSQL.ROCMaster/DeviceSQL.ROCMaster.sqlproj @@ -0,0 +1,131 @@ + + + + + Debug + AnyCPU + DeviceSQL.ROCMaster + 2.0 + 4.1 + {c5358adc-eca3-464d-aeb9-ce99048d4be3} + Microsoft.Data.Tools.Schema.Sql.Sql140DatabaseSchemaProvider + Database + + + DeviceSQL.ROCMaster + DeviceSQL.ROCMaster + 1033, CI + BySchemaAndSchemaType + True + v4.8 + CS + Properties + False + True + True + ROCMaster + + UNSAFE + False + ..\DeviceSQL-Key.snk + + + bin\Release\ + $(MSBuildProjectName).sql + False + pdbonly + true + false + true + prompt + 4 + + + bin\Debug\ + $(MSBuildProjectName).sql + false + true + full + false + true + true + prompt + 4 + + + 11.0 + + True + 11.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DeviceSQL.SQLTypes.ROC + {256ca566-5436-4543-bc13-d2480bee70c2} + True + True + True + UNSAFE + True + + + + + + \ No newline at end of file diff --git a/DeviceSQL.ROCMaster/Functions/ClearAuditLogEventFlags.cs b/DeviceSQL.ROCMaster/Functions/ClearAuditLogEventFlags.cs new file mode 100644 index 0000000..b9c719a --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/ClearAuditLogEventFlags.cs @@ -0,0 +1,19 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static int ClearAuditLogEventFlags(SqlString deviceName, byte numberOfAuditLogRecordsToClear, int startingAuditLogPointer) + { + //var deviceNameValue = deviceName.Value; + return 0; // (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ClearAuditLogEventFlags(null, null, null, null, numberOfAuditLogRecordsToClear, Convert.ToUInt16(startingAuditLogPointer)); + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetAlarms.cs b/DeviceSQL.ROCMaster/Functions/GetAlarms.cs new file mode 100644 index 0000000..8029dbe --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetAlarms.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static AlarmRecordArray GetAlarms(SqlString deviceName, byte count, int startIndex) + { + //var deviceNameValue = deviceName.Value; + //var alarmsRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetAlarms(null, null, null, null, count, Convert.ToUInt16(startIndex)); + return AlarmRecordArray.Null; // new Types.ROCMaster.ROCMaster_AlarmRecordArray() { alarmRecords = alarmsRecords.Select(a => new Types.ROCMaster.ROCMaster_AlarmRecord() { data = a.data, Index = a.Index }).ToList() }; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetArchiveInfo.cs b/DeviceSQL.ROCMaster/Functions/GetArchiveInfo.cs new file mode 100644 index 0000000..327a6c6 --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetArchiveInfo.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static ArchiveInformation GetArchiveInfo(SqlString deviceName) + { + //var deviceNameValue = deviceName.Value; + //var archiveInfo = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetArchiveInfo(null, null, null, null); + return ArchiveInformation.Null; // new Types.ROCMaster.ROCMaster_ArchiveInformation() { Data = archiveInfo.data }; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetAuditLogRecords.cs b/DeviceSQL.ROCMaster/Functions/GetAuditLogRecords.cs new file mode 100644 index 0000000..cee093e --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetAuditLogRecords.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static AuditLogRecordArray GetAuditLogRecords(SqlString deviceName, byte count, int startIndex) + { + //var deviceNameValue = deviceName.Value; + //var auditLogRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetAuditLogRecords(null, null, null, null, count, Convert.ToUInt16(startIndex)); + return AuditLogRecordArray.Null; // new Types.ROCMaster.ROCMaster_AuditLogRecordArray() { auditLogRecords = auditLogRecords.Select(e => new Types.ROCMaster.ROCMaster_AuditLogRecord() { Data = e.data, Index = e.Index }).ToList() }; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetCurrentROCPlusAlarmIndex.cs b/DeviceSQL.ROCMaster/Functions/GetCurrentROCPlusAlarmIndex.cs new file mode 100644 index 0000000..eb90159 --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetCurrentROCPlusAlarmIndex.cs @@ -0,0 +1,19 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static int GetCurrentROCPlusAlarmIndex(SqlString deviceName) + { + //var deviceNameValue = deviceName.Value; + return 0; // (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetCurrentROCPlusAlarmIndex(null, null, null, null); + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetCurrentROCPlusEventIndex.cs b/DeviceSQL.ROCMaster/Functions/GetCurrentROCPlusEventIndex.cs new file mode 100644 index 0000000..be7cbed --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetCurrentROCPlusEventIndex.cs @@ -0,0 +1,19 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static int GetCurrentROCPlusEventIndex(SqlString deviceName) + { + //var deviceNameValue = deviceName.Value; + return 0;// (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetCurrentROCPlusEventIndex(null, null, null, null); + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetCurrentROCPlusHistorySegmentIndex.cs b/DeviceSQL.ROCMaster/Functions/GetCurrentROCPlusHistorySegmentIndex.cs new file mode 100644 index 0000000..9372170 --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetCurrentROCPlusHistorySegmentIndex.cs @@ -0,0 +1,19 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static int GetCurrentROCPlusHistorySegmentIndex(SqlString deviceName, byte historySegment, byte historyType) + { + //var deviceNameValue = deviceName.Value; + return 0;// (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetCurrentROCPlusHistorySegmentIndex(null, null, null, null, historySegment, historyType); + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetDoubleValue.cs b/DeviceSQL.ROCMaster/Functions/GetDoubleValue.cs new file mode 100644 index 0000000..d61d3c1 --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetDoubleValue.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlDouble GetDoubleValue(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber) + { + //var deviceNameValue = deviceName.Value; + //var DoubleParameter = new DoubleParameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref DoubleParameter); + return 0;// DoubleParameter.NullableValue.HasValue ? DoubleParameter.Value : SqlDouble.Null; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetEvents.cs b/DeviceSQL.ROCMaster/Functions/GetEvents.cs new file mode 100644 index 0000000..885ff96 --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetEvents.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static EventRecordArray GetEvents(SqlString deviceName, byte count, int startIndex) + { + //var deviceNameValue = deviceName.Value; + //var eventRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetEvents(null, null, null, null, count, Convert.ToUInt16(startIndex)); + return EventRecordArray.Null; // new Types.ROCMaster.ROCMaster_EventRecordArray() { eventRecords = eventRecords.Select(e => new Types.ROCMaster.ROCMaster_EventRecord() { Data = e.data, Index = e.Index }).ToList() }; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetFloatValue.cs b/DeviceSQL.ROCMaster/Functions/GetFloatValue.cs new file mode 100644 index 0000000..5f3632c --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetFloatValue.cs @@ -0,0 +1,22 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlSingle GetFloatValue(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber) + { + //var deviceNameValue = deviceName.Value; + //var flpParameter = new FlpParameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref flpParameter); + return 0;// flpParameter.NullableValue.HasValue ? flpParameter.Value : SqlSingle.Null; + } + + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetFstInformation.cs b/DeviceSQL.ROCMaster/Functions/GetFstInformation.cs new file mode 100644 index 0000000..b9eedbe --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetFstInformation.cs @@ -0,0 +1,44 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static FSTInformation GetFstInformation(SqlString deviceName, SqlByte fstNumber) + { + //var deviceNameValue = deviceName.Value; + //var rocMaster = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster); + + //var fstHeaderInfo = rocMaster.GetFstHeaderInfo(null, null, null, null, fstNumber.Value); + //var fstSizeParameter = new UInt16Parameter(new Tlp(16, fstNumber.Value, 25)); + + //rocMaster.ReadParameter(null, null, null, null, ref fstSizeParameter); + + //var fstSize = fstSizeParameter.Value; + //var codeBytes = new List(); + + //while (fstSize > codeBytes.Count) + //{ + // codeBytes.AddRange(rocMaster.GetFstCodeChunk(null, null, null, null, 0, (byte)codeBytes.Count, (fstSize - codeBytes.Count) > 240 ? (byte)240 : (byte)(fstSize - codeBytes.Count)).CodeBytes); + //} + + //return new Types.ROCMaster.ROCMaster_FSTInformation() + //{ + // FSTNumber = fstNumber.Value, + // Version = fstHeaderInfo.Version, + // Description = fstHeaderInfo.Description, + // FSTCode = codeBytes.ToArray() + //}; + + return FSTInformation.Null; + } + + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetHistory.cs b/DeviceSQL.ROCMaster/Functions/GetHistory.cs new file mode 100644 index 0000000..92804dd --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetHistory.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static HistoryRecordArray GetHistory(SqlString deviceName, byte historicalRamArea, byte historyPointNumber, byte count, int startIndex) + { + //var deviceNameValue = deviceName.Value; + // var historyRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetHistory(null, null, null, null, historicalRamArea, historyPointNumber, count, Convert.ToUInt16(startIndex)); + return HistoryRecordArray.Null; // new Types.ROCMaster.ROCMaster_HistoryRecordArray() { historyRecords = historyRecords.Select(h => new Types.ROCMaster.ROCMaster_HistoryRecord() { HistorySegment = h.HistorySegment, HistoryPointNumber = h.HistoryPointNumber, Index = h.Index, Value = h.Value }).ToList() }; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetInt16Value.cs b/DeviceSQL.ROCMaster/Functions/GetInt16Value.cs new file mode 100644 index 0000000..f8bd14f --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetInt16Value.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlInt16 GetInt16Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber) + { + //var deviceNameValue = deviceName.Value; + //var int16Parameter = new Int16Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref int16Parameter); + return 0; // int16Parameter.Value; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetInt32Value.cs b/DeviceSQL.ROCMaster/Functions/GetInt32Value.cs new file mode 100644 index 0000000..e10720b --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetInt32Value.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlInt32 GetInt32Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber) + { + //var deviceNameValue = deviceName.Value; + //var int32Parameter = new Int32Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref int32Parameter); + return 0;// int32Parameter.Value; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetInt8Value.cs b/DeviceSQL.ROCMaster/Functions/GetInt8Value.cs new file mode 100644 index 0000000..2917e53 --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetInt8Value.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlInt16 GetInt8Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber) + { + //var deviceNameValue = deviceName.Value; + //var int8Parameter = new Int8Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); + // (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref int8Parameter); + return 0; // int8Parameter.Value; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetMinutelyHistory.cs b/DeviceSQL.ROCMaster/Functions/GetMinutelyHistory.cs new file mode 100644 index 0000000..c8098e9 --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetMinutelyHistory.cs @@ -0,0 +1,22 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; +using System.Linq; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static HistoryRecordArray GetMinutelyHistory(SqlString deviceName, byte historyPointNumber) + { + //var deviceNameValue = deviceName.Value; + //var historyRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetMinutelyHistory(null, null, null, null, historyPointNumber); + return HistoryRecordArray.Null; // new Types.ROCMaster.ROCMaster_HistoryRecordArray() { historyRecords = historyRecords.Select(h => new Types.ROCMaster.ROCMaster_HistoryRecord() { HistoryPointNumber = h.HistoryPointNumber, Index = h.Index, Value = h.Value }).ToList() }; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetROCPlusAlarms.cs b/DeviceSQL.ROCMaster/Functions/GetROCPlusAlarms.cs new file mode 100644 index 0000000..42c13ab --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetROCPlusAlarms.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static ROCPlusAlarmRecordArray GetROCPlusAlarms(SqlString deviceName, byte count, int startIndex) + { + //var deviceNameValue = deviceName.Value; + //var rocPlusAlarmRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetROCPlusAlarms(null, null, null, null, count, Convert.ToUInt16(startIndex)); + return ROCPlusAlarmRecordArray.Null; // new Types.ROCMaster.ROCMaster_ROCPlusAlarmRecordArray() { rocPlusAlarmRecords = rocPlusAlarmRecords.Select(a => new Types.ROCMaster.ROCMaster_ROCPlusAlarmRecord() { Data = a.data, Index = a.Index }).ToList() }; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetROCPlusConfiguredHistoryPoints.cs b/DeviceSQL.ROCMaster/Functions/GetROCPlusConfiguredHistoryPoints.cs new file mode 100644 index 0000000..62f170a --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetROCPlusConfiguredHistoryPoints.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static ROCPlusHistoryPointArray GetROCPlusConfiguredHistoryPoints(SqlString deviceName, byte historySegment) + { + //var deviceNameValue = deviceName.Value; + //var configuredHistoryPoints = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetROCPlusConfiguredHistoryPoints(null, null, null, null, historySegment); + return ROCPlusHistoryPointArray.Null; // new Types.ROCMaster.ROCMaster_ROCPlusHistoryPointArray() { historyPoints = configuredHistoryPoints }; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetROCPlusEvents.cs b/DeviceSQL.ROCMaster/Functions/GetROCPlusEvents.cs new file mode 100644 index 0000000..fdd0cec --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetROCPlusEvents.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static ROCPlusEventRecordArray GetROCPlusEvents(SqlString deviceName, byte count, int startIndex) + { + //var deviceNameValue = deviceName.Value; + //var rocPlusEventRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetROCPlusEvents(null, null, null, null, count, Convert.ToUInt16(startIndex)); + return ROCPlusEventRecordArray.Null; // new Types.ROCMaster.ROCMaster_ROCPlusEventRecordArray() { rocPlusEventRecords = rocPlusEventRecords.Select(e => new Types.ROCMaster.ROCMaster_ROCPlusEventRecord() { Data = e.data, Index = e.Index }).ToList() }; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetROCPlusHistory.cs b/DeviceSQL.ROCMaster/Functions/GetROCPlusHistory.cs new file mode 100644 index 0000000..5b48a19 --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetROCPlusHistory.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static ROCPlusHistoryRecordArray GetROCPlusHistory(SqlString deviceName, byte historySegment, int historyIndex, byte historyType, byte startingHistoryPoint, byte numberOfHistoryPoints, byte numberOfTimePeriods) + { + //var deviceNameValue = deviceName.Value; + //var rocPlusHistoryRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetROCPlusHistory(null, null, null, null, historySegment, Convert.ToUInt16(historyIndex), historyType, startingHistoryPoint, numberOfHistoryPoints, numberOfTimePeriods); + return ROCPlusHistoryRecordArray.Null; // new Types.ROCMaster.ROCMaster_ROCPlusHistoryRecordArray() { rocPlusHistoryRecords = rocPlusHistoryRecords.Select(h => new Types.ROCMaster.ROCMaster_ROCPlusHistoryRecord() { HistorySegment = h.HistorySegment, HistoryPointNumber = h.HistoryPointNumber, Index = h.Index, Value = h.Value }).ToList() }; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetROCPlusHistoryByHistoryPointArray.cs b/DeviceSQL.ROCMaster/Functions/GetROCPlusHistoryByHistoryPointArray.cs new file mode 100644 index 0000000..985443b --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetROCPlusHistoryByHistoryPointArray.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static ROCPlusHistoryRecordArray GetROCPlusHistoryByHistoryPointArray(SqlString deviceName, byte historySegment, int historyIndex, byte historyType, byte startingHistoryPoint, bool requestTimeStamps, byte numberOfHistoryPoints, ROCPlusHistoryPointArray requestedHistoryPoints, byte numberOfTimePeriods) + { + //var deviceNameValue = deviceName.Value; + //var rocPlusHistoryRecords = (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetROCPlusHistory(null, null, null, null, historySegment, Convert.ToUInt16(historyIndex), historyType, requestTimeStamps, requestedHistoryPoints.historyPoints, numberOfTimePeriods); + return ROCPlusHistoryRecordArray.Null; // new Types.ROCMaster.ROCMaster_ROCPlusHistoryRecordArray() { rocPlusHistoryRecords = rocPlusHistoryRecords.Select(h => new Types.ROCMaster.ROCMaster_ROCPlusHistoryRecord() { HistorySegment = h.HistorySegment, HistoryPointNumber = h.HistoryPointNumber, Index = h.Index, Value = h.Value }).ToList() }; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetRealTimeClockValue.cs b/DeviceSQL.ROCMaster/Functions/GetRealTimeClockValue.cs new file mode 100644 index 0000000..b8200e5 --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetRealTimeClockValue.cs @@ -0,0 +1,19 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlDateTime GetRealTimeClockValue(SqlString deviceName) + { + //var deviceNameValue = deviceName.Value; + return SqlDateTime.Null; // new SqlDateTime((DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetRealTimeClockValue(null, null, null, null)); + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetRealTimeClockValueWithCentury.cs b/DeviceSQL.ROCMaster/Functions/GetRealTimeClockValueWithCentury.cs new file mode 100644 index 0000000..5cef04a --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetRealTimeClockValueWithCentury.cs @@ -0,0 +1,19 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlDateTime GetRealTimeClockValueWithCentury(SqlString deviceName, SqlInt32 century) + { + //var deviceNameValue = deviceName.Value; + return SqlDateTime.Null; // new SqlDateTime((DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).GetRealTimeClockValue(null, null, null, null, Convert.ToUInt16(century.Value))); + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetStringValue.cs b/DeviceSQL.ROCMaster/Functions/GetStringValue.cs new file mode 100644 index 0000000..d713c19 --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetStringValue.cs @@ -0,0 +1,46 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlString GetStringValue(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlByte stringLength) + { + //var deviceNameValue = deviceName.Value; + + //if (10 >= stringLength) + //{ + // var ac10Parameter = new Ac10Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); + // (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref ac10Parameter); + // return ac10Parameter.Value; + //} + //else if (12 >= stringLength) + //{ + // var ac12Parameter = new Ac12Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); + // (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref ac12Parameter); + // return ac12Parameter.Value; + //} + //else if (20 >= stringLength) + //{ + // var ac20Parameter = new Ac20Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); + // (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref ac20Parameter); + // return ac20Parameter.Value; + //} + //else + //{ + // var ac30Parameter = new Ac30Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); + // (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref ac30Parameter); + // return ac30Parameter.Value; + //} + + return ""; + + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetTimeValue.cs b/DeviceSQL.ROCMaster/Functions/GetTimeValue.cs new file mode 100644 index 0000000..3afb752 --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetTimeValue.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlDateTime GetTimeValue(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber) + { + //var deviceNameValue = deviceName.Value; + //var timeParameter = new Device.ROC.Data.TimeParameter(new Device.ROC.Data.Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref timeParameter); + return SqlDateTime.Null; // timeParameter.Value; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetUInt16Value.cs b/DeviceSQL.ROCMaster/Functions/GetUInt16Value.cs new file mode 100644 index 0000000..703c78f --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetUInt16Value.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlInt32 GetUInt16Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber) + { + //var deviceNameValue = deviceName.Value; + //var uInt16Parameter = new UInt16Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref uInt16Parameter); + return 0; // uInt16Parameter.Value; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetUInt32Value.cs b/DeviceSQL.ROCMaster/Functions/GetUInt32Value.cs new file mode 100644 index 0000000..e4ea24d --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetUInt32Value.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlInt64 GetUInt32Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber) + { + //var deviceNameValue = deviceName.Value; + //var uInt32Parameter = new UInt32Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref uInt32Parameter); + return 0; // uInt32Parameter.Value; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/GetUInt8Value.cs b/DeviceSQL.ROCMaster/Functions/GetUInt8Value.cs new file mode 100644 index 0000000..3ebbff7 --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/GetUInt8Value.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlByte GetUInt8Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber) + { + //var deviceNameValue = deviceName.Value; + // var uInt8Parameter = new UInt8Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)); + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref uInt8Parameter); + return 0; // uInt8Parameter.Value; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/ReadParameters.cs b/DeviceSQL.ROCMaster/Functions/ReadParameters.cs new file mode 100644 index 0000000..326aba6 --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/ReadParameters.cs @@ -0,0 +1,101 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC; +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static ParameterArray ReadParameters(SqlString deviceName, ParameterArray parameterArray) + { + // var deviceNameValue = deviceName.Value; + // var parameters = new List(); + // var length = parameterArray.Length; + + // for (var parameterIndex = 0; length > parameterIndex; parameterIndex++) + // { + // var parameter = parameterArray.GetParameter(parameterIndex); + + // switch (parameter.RawType) + // { + // case ParameterType.AC3: + // parameters.Add(new Ac3Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.AC7: + // parameters.Add(new Ac7Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.AC10: + // parameters.Add(new Ac10Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.AC12: + // parameters.Add(new Ac12Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.AC20: + // parameters.Add(new Ac20Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.AC30: + // parameters.Add(new Ac30Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.AC40: + // parameters.Add(new Ac40Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.BIN: + // parameters.Add(new BinParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.FL: + // parameters.Add(new FlpParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.DOUBLE: + // parameters.Add(new DoubleParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.INT16: + // parameters.Add(new Int16Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.INT32: + // parameters.Add(new Int32Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.INT8: + // parameters.Add(new Int8Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.TLP: + // parameters.Add(new TlpParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.UINT16: + // parameters.Add(new UInt16Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.UINT32: + // parameters.Add(new UInt32Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.TIME: + // parameters.Add(new TimeParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.UINT8: + // parameters.Add(new UInt8Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // } + + // } + + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameters(null, null, null, null, ref parameters); + + + // for (var parameterIndex = 0; length > parameterIndex; parameterIndex++) + // { + // var parameter = parameterArray[parameterIndex]; + // parameter.RawValue = parameters[parameterIndex].Data; + // parameterArray[parameterIndex] = parameter; + // } + + // return parameterArray; + + return ParameterArray.Null; + + } + + } +} diff --git a/DeviceSQL.ROCMaster/Functions/SetFloatValue.cs b/DeviceSQL.ROCMaster/Functions/SetFloatValue.cs new file mode 100644 index 0000000..25b3e7e --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/SetFloatValue.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlBoolean SetFloatValue(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlSingle value) + { + //var deviceNameValue = deviceName.Value; + //var flpParameter = new FlpParameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = value.Value }; + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, flpParameter); + return true; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/SetInt16Value.cs b/DeviceSQL.ROCMaster/Functions/SetInt16Value.cs new file mode 100644 index 0000000..fd7cbd5 --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/SetInt16Value.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlBoolean SetInt16Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlInt16 value) + { + //var deviceNameValue = deviceName.Value; + //var int16Parameter = new Int16Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = value.Value }; + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, int16Parameter); + return true; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/SetInt32Value.cs b/DeviceSQL.ROCMaster/Functions/SetInt32Value.cs new file mode 100644 index 0000000..430d247 --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/SetInt32Value.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlBoolean SetInt32Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlInt32 value) + { + //var deviceNameValue = deviceName.Value; + //var int32Parameter = new Int32Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = value.Value }; + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, int32Parameter); + return true; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/SetInt8Value.cs b/DeviceSQL.ROCMaster/Functions/SetInt8Value.cs new file mode 100644 index 0000000..8acd86b --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/SetInt8Value.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlBoolean SetInt8Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlInt16 value) + { + //var deviceNameValue = deviceName.Value; + //var int8Parameter = new Int8Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = Convert.ToSByte(value.Value) }; + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as DeviceSQL.Device.ROC.ROCMaster).WriteParameter(null, null, null, null, int8Parameter); + return true; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/SetOperatorIdentification.cs b/DeviceSQL.ROCMaster/Functions/SetOperatorIdentification.cs new file mode 100644 index 0000000..4cb3286 --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/SetOperatorIdentification.cs @@ -0,0 +1,22 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.Linq; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlBoolean SetOperatorIdentification(SqlString deviceName, SqlString operatorId, SqlInt32 password) + { + //var deviceNameValue = deviceName.Value; + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).SetOperatorIdentification(null, null, null, null, operatorId.IsNull ? "LOI" : operatorId.Value, Convert.ToUInt16(password.IsNull ? 1000 : password.Value)); + return true; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/SetRealTimeClock.cs b/DeviceSQL.ROCMaster/Functions/SetRealTimeClock.cs new file mode 100644 index 0000000..3e9db2c --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/SetRealTimeClock.cs @@ -0,0 +1,20 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlBoolean SetRealTimeClock(SqlString deviceName, SqlDateTime dateTime) + { + //var deviceNameValue = deviceName.Value; + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).SetRealTimeClock(null, null, null, null, dateTime.Value); + return true; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/SetStringValue.cs b/DeviceSQL.ROCMaster/Functions/SetStringValue.cs new file mode 100644 index 0000000..5b4f5d0 --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/SetStringValue.cs @@ -0,0 +1,48 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; +using System.Linq; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlBoolean SetStringValue(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlByte stringLength, SqlString value) + { + //var deviceNameValue = deviceName.Value; + + //if (10 >= stringLength) + //{ + // var ac10Parameter = new Ac10Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = value.Value }; + // (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, ac10Parameter); + // return true; + //} + //else if (12 >= stringLength) + //{ + // var ac12Parameter = new Ac12Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = value.Value }; + // (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, ac12Parameter); + // return true; + //} + //else if (20 >= stringLength) + //{ + // var ac20Parameter = new Ac20Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = value.Value }; + // (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, ac20Parameter); + // return true; + //} + //else + //{ + // var ac30Parameter = new Ac30Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = value.Value }; + // (DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, ac30Parameter); + // return true; + //} + + return true; + + } + + } +} diff --git a/DeviceSQL.ROCMaster/Functions/SetTimeValue.cs b/DeviceSQL.ROCMaster/Functions/SetTimeValue.cs new file mode 100644 index 0000000..df7f04d --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/SetTimeValue.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlBoolean SetTimeValue(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlDateTime value) + { + //var deviceNameValue = deviceName.Value; + //var timeParameter = new TimeParameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = value.Value }; + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, timeParameter); + return true; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/SetUInt16Value.cs b/DeviceSQL.ROCMaster/Functions/SetUInt16Value.cs new file mode 100644 index 0000000..9ad2461 --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/SetUInt16Value.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlBoolean SetUInt16Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlInt32 value) + { + //var deviceNameValue = deviceName.Value; + //var uInt16Parameter = new UInt16Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = Convert.ToUInt16(value.Value) }; + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).ReadParameter(null, null, null, null, ref uInt16Parameter); + return true; + } + } +} \ No newline at end of file diff --git a/DeviceSQL.ROCMaster/Functions/SetUInt32Value.cs b/DeviceSQL.ROCMaster/Functions/SetUInt32Value.cs new file mode 100644 index 0000000..3925a3a --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/SetUInt32Value.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlBoolean SetUInt32Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlInt64 value) + { + //var deviceNameValue = deviceName.Value; + //var uInt32Parameter = new UInt32Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = Convert.ToUInt32(value.Value) }; + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, uInt32Parameter); + return true; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/SetUInt8Value.cs b/DeviceSQL.ROCMaster/Functions/SetUInt8Value.cs new file mode 100644 index 0000000..b2b796e --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/SetUInt8Value.cs @@ -0,0 +1,21 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System.Data.SqlTypes; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlBoolean SetUInt8Value(SqlString deviceName, SqlByte pointType, SqlByte logicalNumber, SqlByte parameterNumber, SqlByte value) + { + //var deviceNameValue = deviceName.Value; + //var uInt8Parameter = new UInt8Parameter(new Tlp(pointType.Value, logicalNumber.Value, parameterNumber.Value)) { Value = value.Value }; + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameter(null, null, null, null, uInt8Parameter); + return true; + } + } +} diff --git a/DeviceSQL.ROCMaster/Functions/WriteParameters.cs b/DeviceSQL.ROCMaster/Functions/WriteParameters.cs new file mode 100644 index 0000000..b05a8dc --- /dev/null +++ b/DeviceSQL.ROCMaster/Functions/WriteParameters.cs @@ -0,0 +1,93 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC; +using Microsoft.SqlServer.Server; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.Linq; + +#endregion + +namespace DeviceSQL.Functions +{ + public partial class ROCMaster + { + [SqlFunction] + public static SqlBoolean WriteParameters(SqlString deviceName, ParameterArray parameterArray) + { + // var deviceNameValue = deviceName.Value; + // var parameters = new List(); + // var length = parameterArray.Length; + + // for (var parameterIndex = 0; length > parameterIndex; parameterIndex++) + // { + // var parameter = parameterArray.GetParameter(parameterIndex); + + // switch (parameter.RawType) + // { + // case ParameterType.AC3: + // parameters.Add(new Ac3Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.AC7: + // parameters.Add(new Ac7Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.AC10: + // parameters.Add(new Ac10Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.AC12: + // parameters.Add(new Ac12Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.AC20: + // parameters.Add(new Ac20Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.AC30: + // parameters.Add(new Ac30Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.AC40: + // parameters.Add(new Ac40Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.BIN: + // parameters.Add(new BinParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.FL: + // parameters.Add(new FlpParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.DOUBLE: + // parameters.Add(new DoubleParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.INT16: + // parameters.Add(new Int16Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.INT32: + // parameters.Add(new Int32Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.INT8: + // parameters.Add(new Int8Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.TLP: + // parameters.Add(new TlpParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.UINT16: + // parameters.Add(new UInt16Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.UINT32: + // parameters.Add(new UInt32Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.TIME: + // parameters.Add(new TimeParameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // case ParameterType.UINT8: + // parameters.Add(new UInt8Parameter(new Tlp(parameter.PointType, parameter.LogicalNumber, parameter.Parameter)) { Data = parameter.RawValue }); + // break; + // } + + // } + + //(DeviceSQL.Watchdog.Worker.Devices.First(device => (device.Name == deviceNameValue)) as Device.ROC.ROCMaster).WriteParameters(null, null, null, null, parameters); + + return true; + + } + + } +} diff --git a/DeviceSQL.ROCMaster/Properties/AssemblyInfo.cs b/DeviceSQL.ROCMaster/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..d624602 --- /dev/null +++ b/DeviceSQL.ROCMaster/Properties/AssemblyInfo.cs @@ -0,0 +1,24 @@ +using System.Reflection; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with the SQLCLR assembly. +[assembly: AssemblyTitle("DeviceSQL.ROCMaster")] +[assembly: AssemblyDescription("DeviceSQL.ROCMaster")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("CloudSonix")] +[assembly: AssemblyProduct("DeviceSQL")] +[assembly: AssemblyCopyright("© CloudSonix. All rights reserved.")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: AssemblyKeyFileAttribute("../DeviceSQL-Key.snk")] + +// 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/DeviceSQL/Schemas/ROCMaster.sql b/DeviceSQL.ROCMaster/Schemas/ROCMaster.sql similarity index 100% rename from DeviceSQL/Schemas/ROCMaster.sql rename to DeviceSQL.ROCMaster/Schemas/ROCMaster.sql diff --git a/DeviceSQL.SQLTypes.Modbus/BooleanRegister.cs b/DeviceSQL.SQLTypes.Modbus/BooleanRegister.cs new file mode 100644 index 0000000..e00f631 --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/BooleanRegister.cs @@ -0,0 +1,131 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 8)] + public struct BooleanRegister : INullable, IBinarySerialize + { + + #region Fields + + internal byte[] data; + + #endregion + + #region Properties + + public SqlBinary Data + { + get + { + if (data == null) + { + data = new byte[1]; + } + return data; + } + set + { + data = value.Value; + } + } + + public ModbusAddress Address + { + get; + set; + } + + public bool IsNull + { + get; + private set; + } + + public SqlBoolean Value + { + get + { + return new DeviceSQL.Device.MODBUS.Data.BooleanRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(Address.RelativeAddress), Address.IsZeroBased.Value)).Value; + } + set + { + Data = new DeviceSQL.Device.MODBUS.Data.BooleanRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(Address.RelativeAddress), Address.IsZeroBased.Value)) { Value = value.Value }.Data; + } + } + + public static BooleanRegister Null + { + get + { + return (new BooleanRegister() { IsNull = true }); + } + } + + #endregion + + #region Helper Methods + + public override string ToString() + { + if (this.IsNull) + { + return "NULL"; + } + else + { + return string.Format("Address=[{0}];Value={1};", Address.ToString(), Value.Value); + } + } + + public static BooleanRegister Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedBooleanRegisterData = stringToParse.Value.Split(",".ToCharArray()); + var parsedBooleanRegister = new BooleanRegister() { Address = ModbusAddress.Parse(parsedBooleanRegisterData[0]), Value = bool.Parse(parsedBooleanRegisterData[1]) }; + return parsedBooleanRegister; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + + if (!IsNull) + { + Address.Read(binaryReader); + Data = binaryReader.ReadBytes(1); + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + + if (!IsNull) + { + Address.Write(binaryWriter); + binaryWriter.Write(Data.Value, 0, 1); + } + } + + #endregion + + } +} \ No newline at end of file diff --git a/DeviceSQL.SQLTypes.Modbus/BooleanRegisterArray.cs b/DeviceSQL.SQLTypes.Modbus/BooleanRegisterArray.cs new file mode 100644 index 0000000..5ba1379 --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/BooleanRegisterArray.cs @@ -0,0 +1,165 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct BooleanRegisterArray : INullable, IBinarySerialize + { + + #region Fields + + private List booleanRegisters; + + #endregion + + #region Properties + + internal BooleanRegister this[int index] + { + get + { + return BooleanRegisters[index]; + } + set + { + BooleanRegisters[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return BooleanRegisters.Count; + } + } + + #endregion + + #region Helper Methods + + private List BooleanRegisters + { + get + { + if (booleanRegisters == null) + { + booleanRegisters = new List(); + } + return booleanRegisters; + } + } + + public static BooleanRegisterArray Null + { + get + { + return (new BooleanRegisterArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", BooleanRegisters.Select(booleanRegister => booleanRegister.ToString())); + } + + public BooleanRegisterArray AddBooleanRegister(BooleanRegister booleanRegister) + { + BooleanRegisters.Add(booleanRegister); + return this; + } + + public static BooleanRegisterArray Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedBooleanRegisterArray = new BooleanRegisterArray() + { + booleanRegisters = new List() + }; + + var parsedString = stringToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedString.Length > i; i++) + { + parsedBooleanRegisterArray.BooleanRegisters.Add(BooleanRegister.Parse(parsedString[i])); + } + + return parsedBooleanRegisterArray; + } + + public BooleanRegister GetBooleanRegister(SqlInt32 index) + { + return BooleanRegisters[index.Value]; + } + + public static BooleanRegisterArray Empty() + { + var booleanRegisterArray = new BooleanRegisterArray() { booleanRegisters = new List() }; + return booleanRegisterArray; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + BooleanRegisters.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var booleanRegister = new BooleanRegister(); + booleanRegister.Read(binaryReader); + BooleanRegisters.Add(booleanRegister); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; BooleanRegisters.Count > i; i++) + { + BooleanRegisters[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} \ No newline at end of file diff --git a/DeviceSQL.SQLTypes.Modbus/CoilRegister.cs b/DeviceSQL.SQLTypes.Modbus/CoilRegister.cs new file mode 100644 index 0000000..d7e5218 --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/CoilRegister.cs @@ -0,0 +1,131 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 8)] + public struct CoilRegister : INullable, IBinarySerialize + { + + #region Fields + + internal byte[] data; + + #endregion + + #region Properties + + public SqlBinary Data + { + get + { + if (data == null) + { + data = new byte[1]; + } + return data; + } + set + { + data = value.Value; + } + } + + public ModbusAddress Address + { + get; + set; + } + + public bool IsNull + { + get; + private set; + } + + public SqlBoolean Value + { + get + { + return new DeviceSQL.Device.MODBUS.Data.CoilRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(Address.RelativeAddress), Address.IsZeroBased.Value)).Value; + } + set + { + Data = new DeviceSQL.Device.MODBUS.Data.CoilRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(Address.RelativeAddress), Address.IsZeroBased.Value)) { Value = value.Value }.Data; + } + } + + public static CoilRegister Null + { + get + { + return (new CoilRegister() { IsNull = true }); + } + } + + #endregion + + #region Helper Methods + + public override string ToString() + { + if (this.IsNull) + { + return "NULL"; + } + else + { + return string.Format("Address=[{0}];Value={1};", Address.ToString(), Value.Value); + } + } + + public static CoilRegister Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedCoilRegisterData = stringToParse.Value.Split(",".ToCharArray()); + var parsedCoilRegister = new CoilRegister() { Address = ModbusAddress.Parse(parsedCoilRegisterData[0]), Value = bool.Parse(parsedCoilRegisterData[1]) }; + return parsedCoilRegister; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + + if (!IsNull) + { + Address.Read(binaryReader); + Data = binaryReader.ReadBytes(1); + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + + if (!IsNull) + { + Address.Write(binaryWriter); + binaryWriter.Write(Data.Value, 0, 1); + } + } + + #endregion + + } +} \ No newline at end of file diff --git a/DeviceSQL.SQLTypes.Modbus/CoilRegisterArray.cs b/DeviceSQL.SQLTypes.Modbus/CoilRegisterArray.cs new file mode 100644 index 0000000..baad80a --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/CoilRegisterArray.cs @@ -0,0 +1,164 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct CoilRegisterArray : INullable, IBinarySerialize + { + + #region Fields + + internal List coilRegisters; + + #endregion + + #region Properties + + internal CoilRegister this[int index] + { + get + { + return CoilRegisters[index]; + } + set + { + CoilRegisters[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return CoilRegisters.Count; + } + } + + #endregion + + #region Helper Methods + + private List CoilRegisters + { + get + { + if (coilRegisters == null) + { + coilRegisters = new List(); + } + return coilRegisters; + } + } + + public static CoilRegisterArray Null + { + get + { + return (new CoilRegisterArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", CoilRegisters.Select(coilRegister => coilRegister.ToString())); + } + + public CoilRegisterArray AddCoilRegister(CoilRegister coilRegister) + { + CoilRegisters.Add(coilRegister); + return this; + } + + public static CoilRegisterArray Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedCoilRegisterArray = new CoilRegisterArray() + { + coilRegisters = new List() + }; + var parsedString = stringToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedString.Length > i; i++) + { + parsedCoilRegisterArray.CoilRegisters.Add(CoilRegister.Parse(parsedString[i])); + } + + return parsedCoilRegisterArray; + } + + public CoilRegister GetCoilRegister(SqlInt32 index) + { + return CoilRegisters[index.Value]; + } + + public static CoilRegisterArray Empty() + { + var coilRegisterArray = new CoilRegisterArray() { coilRegisters = new List() }; + return coilRegisterArray; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + CoilRegisters.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var coilRegister = new CoilRegister(); + coilRegister.Read(binaryReader); + CoilRegisters.Add(coilRegister); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; CoilRegisters.Count > i; i++) + { + CoilRegisters[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} \ No newline at end of file diff --git a/DeviceSQL.SQLTypes.Modbus/DeviceSQL.SQLTypes.Modbus.csproj b/DeviceSQL.SQLTypes.Modbus/DeviceSQL.SQLTypes.Modbus.csproj new file mode 100644 index 0000000..e974366 --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/DeviceSQL.SQLTypes.Modbus.csproj @@ -0,0 +1,122 @@ + + + + + Debug + AnyCPU + {CD45D76E-D2ED-4587-9873-F35AD24E42A5} + Library + Properties + DeviceSQL.SQLTypes.Modbus + DeviceSQL.SQLTypes.Modbus + v4.8 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + false + + + + + + + + + + + + + + + + + + Devices\BooleanRegister.cs + + + Devices\CoilRegister.cs + + + Devices\DiscreteInputRegister.cs + + + Devices\EventArchiveRecord.cs + + + Devices\FloatRegister.cs + + + Devices\HistoryArchiveRecord.cs + + + Devices\HoldingRegister.cs + + + Devices\IModbusRegisterData.cs + + + Devices\InputRegister.cs + + + Devices\LongRegister.cs + + + Devices\ModbusAddress.cs + + + Devices\ModbusRegister.cs + + + Devices\ShortRegister.cs + + + Devices\StringRegister.cs + + + Devices\ModbusConverter.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DeviceSQL.SQLTypes.Modbus/DiscreteInputRegister.cs b/DeviceSQL.SQLTypes.Modbus/DiscreteInputRegister.cs new file mode 100644 index 0000000..d1ed073 --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/DiscreteInputRegister.cs @@ -0,0 +1,131 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 8)] + public struct DiscreteInputRegister : INullable, IBinarySerialize + { + + #region Fields + + internal byte[] data; + + #endregion + + #region Properties + + public SqlBinary Data + { + get + { + if (data == null) + { + data = new byte[1]; + } + return data; + } + set + { + data = value.Value; + } + } + + public ModbusAddress Address + { + get; + set; + } + + public bool IsNull + { + get; + private set; + } + + public SqlBoolean Value + { + get + { + return new DeviceSQL.Device.MODBUS.Data.DiscreteInputRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(Address.RelativeAddress), Address.IsZeroBased.Value)).Value; + } + set + { + Data = new DeviceSQL.Device.MODBUS.Data.DiscreteInputRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(Address.RelativeAddress), Address.IsZeroBased.Value)) { Value = value.Value }.Data; + } + } + + public static DiscreteInputRegister Null + { + get + { + return (new DiscreteInputRegister() { IsNull = true }); + } + } + + #endregion + + #region Helper Methods + + public override string ToString() + { + if (this.IsNull) + { + return "NULL"; + } + else + { + return string.Format("Address=[{0}];Value={1};", Address.ToString(), Value.Value); + } + } + + public static DiscreteInputRegister Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedDiscreteInputRegisterData = stringToParse.Value.Split(",".ToCharArray()); + var parsedDiscreteInputRegister = new DiscreteInputRegister() { Address = ModbusAddress.Parse(parsedDiscreteInputRegisterData[0]), Value = bool.Parse(parsedDiscreteInputRegisterData[1]) }; + return parsedDiscreteInputRegister; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + + if (!IsNull) + { + Address.Read(binaryReader); + Data = binaryReader.ReadBytes(1); + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + + if (!IsNull) + { + Address.Write(binaryWriter); + binaryWriter.Write(Data.Value, 0, 1); + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.Modbus/DiscreteInputRegisterArray.cs b/DeviceSQL.SQLTypes.Modbus/DiscreteInputRegisterArray.cs new file mode 100644 index 0000000..406c48b --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/DiscreteInputRegisterArray.cs @@ -0,0 +1,165 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct DiscreteInputRegisterArray : INullable, IBinarySerialize + { + + #region Fields + + internal List discreteInputRegisters; + + #endregion + + #region Properties + + internal DiscreteInputRegister this[int index] + { + get + { + return DiscreteInputRegisters[index]; + } + set + { + DiscreteInputRegisters[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return DiscreteInputRegisters.Count; + } + } + + #endregion + + #region Helper Methods + + private List DiscreteInputRegisters + { + get + { + if (discreteInputRegisters == null) + { + discreteInputRegisters = new List(); + } + return discreteInputRegisters; + } + } + + public static DiscreteInputRegisterArray Null + { + get + { + return (new DiscreteInputRegisterArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", DiscreteInputRegisters.Select(discreteInputRegister => discreteInputRegister.ToString())); + } + + public DiscreteInputRegisterArray AddDiscreteInputRegister(DiscreteInputRegister discreteInputRegister) + { + DiscreteInputRegisters.Add(discreteInputRegister); + return this; + } + + public static DiscreteInputRegisterArray Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedDiscreteInputRegisterArray = new DiscreteInputRegisterArray() + { + discreteInputRegisters = new List() + }; + + var parsedString = stringToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedString.Length > i; i++) + { + parsedDiscreteInputRegisterArray.DiscreteInputRegisters.Add(DiscreteInputRegister.Parse(parsedString[i])); + } + + return parsedDiscreteInputRegisterArray; + } + + public DiscreteInputRegister GetDiscreteInputRegister(SqlInt32 index) + { + return DiscreteInputRegisters[index.Value]; + } + + public static DiscreteInputRegisterArray Empty() + { + var discreteInputRegisterArray = new DiscreteInputRegisterArray() { discreteInputRegisters = new List() }; + return discreteInputRegisterArray; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + DiscreteInputRegisters.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var discreteInputRegister = new DiscreteInputRegister(); + discreteInputRegister.Read(binaryReader); + DiscreteInputRegisters.Add(discreteInputRegister); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; DiscreteInputRegisters.Count > i; i++) + { + DiscreteInputRegisters[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.Modbus/EventArchiveRecord.cs b/DeviceSQL.SQLTypes.Modbus/EventArchiveRecord.cs new file mode 100644 index 0000000..534ce0a --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/EventArchiveRecord.cs @@ -0,0 +1,145 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 264)] + public struct EventArchiveRecord : INullable, IBinarySerialize + { + + #region Fields + + internal byte[] data; + + #endregion + + #region Properties + + public SqlBinary Data + { + get + { + if (data == null) + { + data = new byte[Length.Value]; + } + return data; + } + set + { + data = value.Value; + Length = data.Length; + } + } + + public SqlInt32 Index + { + get; + set; + } + + public SqlInt32 Length + { + get; + set; + } + + public bool IsNull + { + get; + private set; + } + + public SqlInt16 GetShortValue(SqlByte index, SqlBoolean byteSwap, SqlBoolean wordSwap) + { + return new DeviceSQL.Device.MODBUS.Data.EventArchiveRecord(Convert.ToUInt16(Index), Data.Value).GetShortValue(index.Value, byteSwap.Value); + } + + public static SqlDateTime GetDateTimeValue(SqlSingle dateValue, SqlSingle timeValue, SqlInt32 baseYear) + { + var dateTime = DeviceSQL.Device.MODBUS.Data.EventArchiveRecord.ParseNullableDateTimeValue(dateValue.Value, timeValue.Value, baseYear.Value); + return dateTime ?? SqlDateTime.Null; + } + + public SqlSingle GetFloatValue(SqlByte index, SqlBoolean byteSwap, SqlBoolean wordSwap) + { + var floatValue = new DeviceSQL.Device.MODBUS.Data.EventArchiveRecord(Convert.ToUInt16(Index), Data.Value).GetNullableFloatValue(index.Value, byteSwap.Value, wordSwap.Value); + return floatValue ?? SqlSingle.Null; + } + + public static EventArchiveRecord Null + { + get + { + return (new EventArchiveRecord() { IsNull = true }); + } + } + + #endregion + + #region Helper Methods + + public override string ToString() + { + if (this.IsNull) + { + return "NULL"; + } + else + { + return string.Format("Index={0};Length={1};Value={2};", Index, Length, Convert.ToBase64String(Data.Value)); + } + } + + public static EventArchiveRecord Parse(SqlString eventArchiveToParse) + { + if (eventArchiveToParse.IsNull) + { + return Null; + } + + var parsedEventArchiveRecordData = eventArchiveToParse.Value.Split(",".ToCharArray()); + var parsedEventArchiveRecord = new EventArchiveRecord() { Index = Int32.Parse(parsedEventArchiveRecordData[0]), Length = Int32.Parse(parsedEventArchiveRecordData[1]), Data = Convert.FromBase64String(parsedEventArchiveRecordData[2]) }; + return parsedEventArchiveRecord; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + + if (!IsNull) + { + Index = binaryReader.ReadInt32(); + Length = binaryReader.ReadByte(); + Data = binaryReader.ReadBytes(Length.Value); + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + + if (!IsNull) + { + binaryWriter.Write(Index.Value); + binaryWriter.Write(Length.Value); + binaryWriter.Write(Data.Value, 0, Length.Value); + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.Modbus/EventArchiveRecordArray.cs b/DeviceSQL.SQLTypes.Modbus/EventArchiveRecordArray.cs new file mode 100644 index 0000000..7e7d466 --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/EventArchiveRecordArray.cs @@ -0,0 +1,165 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct EventArchiveRecordArray : INullable, IBinarySerialize + { + + #region Fields + + internal List eventArchiveRecords; + + #endregion + + #region Properties + + internal EventArchiveRecord this[int index] + { + get + { + return EventArchiveRecords[index]; + } + set + { + EventArchiveRecords[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return EventArchiveRecords.Count; + } + } + + #endregion + + #region Helper Methods + + private List EventArchiveRecords + { + get + { + if (eventArchiveRecords == null) + { + eventArchiveRecords = new List(); + } + return eventArchiveRecords; + } + } + + public static EventArchiveRecordArray Null + { + get + { + return (new EventArchiveRecordArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", EventArchiveRecords.Select(eventArchiveRecord => eventArchiveRecord.ToString())); + } + + public EventArchiveRecordArray AddEventArchiveRecord(EventArchiveRecord eventArchiveRecord) + { + EventArchiveRecords.Add(eventArchiveRecord); + return this; + } + + public static EventArchiveRecordArray Parse(SqlString eventArchiveToParse) + { + if (eventArchiveToParse.IsNull) + { + return Null; + } + + var parsedEventArchiveRecordArray = new EventArchiveRecordArray() + { + eventArchiveRecords = new List() + }; + + var parsedEventArchive = eventArchiveToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedEventArchive.Length > i; i++) + { + parsedEventArchiveRecordArray.EventArchiveRecords.Add(EventArchiveRecord.Parse(parsedEventArchive[i])); + } + + return parsedEventArchiveRecordArray; + } + + public EventArchiveRecord GetEventArchiveRecord(SqlInt32 index) + { + return EventArchiveRecords[index.Value]; + } + + public static EventArchiveRecordArray Empty() + { + var eventArchiveRecordArray = new EventArchiveRecordArray() { eventArchiveRecords = new List() }; + return eventArchiveRecordArray; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + EventArchiveRecords.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var eventArchiveRecord = new EventArchiveRecord(); + eventArchiveRecord.Read(binaryReader); + EventArchiveRecords.Add(eventArchiveRecord); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; EventArchiveRecords.Count > i; i++) + { + EventArchiveRecords[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} \ No newline at end of file diff --git a/DeviceSQL.SQLTypes.Modbus/FloatRegister.cs b/DeviceSQL.SQLTypes.Modbus/FloatRegister.cs new file mode 100644 index 0000000..302e3e8 --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/FloatRegister.cs @@ -0,0 +1,147 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 13)] + public struct FloatRegister : INullable, IBinarySerialize + { + + #region Fields + + internal byte[] data; + + #endregion + + #region Properties + + public SqlBinary Data + { + get + { + if (data == null) + { + data = new byte[4]; + } + return data; + } + set + { + data = value.Value; + } + } + + public ModbusAddress Address + { + get; + set; + } + + public SqlBoolean ByteSwap + { + get; + set; + } + + public SqlBoolean WordSwap + { + get; + set; + } + + public bool IsNull + { + get; + private set; + } + + public SqlSingle Value + { + get + { + return new DeviceSQL.Device.MODBUS.Data.FloatRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(Address.RelativeAddress), Address.IsZeroBased.Value), ByteSwap.Value, WordSwap.Value).Value; + } + set + { + Data = new DeviceSQL.Device.MODBUS.Data.FloatRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(Address.RelativeAddress), Address.IsZeroBased.Value), ByteSwap.Value, WordSwap.Value) { Value = Convert.ToUInt16(value) }.Data; + } + } + + public static FloatRegister Null + { + get + { + return (new FloatRegister() { IsNull = true }); + } + } + + #endregion + + #region Helper Methods + + public override string ToString() + { + if (this.IsNull) + { + return "NULL"; + } + else + { + return string.Format("Address=[{0}];Byte Swap={1};Word Swap={2};Value={3};", Address.ToString(), ByteSwap.Value, Value.Value); + } + } + + public static FloatRegister Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedFloatRegisterData = stringToParse.Value.Split(",".ToCharArray()); + var parsedFloatRegister = new FloatRegister() { Address = ModbusAddress.Parse(parsedFloatRegisterData[0]), ByteSwap = bool.Parse(parsedFloatRegisterData[1]), WordSwap = bool.Parse(parsedFloatRegisterData[2]), Value = Int32.Parse(parsedFloatRegisterData[3]) }; + return parsedFloatRegister; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + + if (!IsNull) + { + Address.Read(binaryReader); + ByteSwap = binaryReader.ReadBoolean(); + WordSwap = binaryReader.ReadBoolean(); + Data = binaryReader.ReadBytes(4); + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + + if (!IsNull) + { + Address.Write(binaryWriter); + binaryWriter.Write(ByteSwap.Value); + binaryWriter.Write(WordSwap.Value); + binaryWriter.Write(Data.Value, 0, 4); + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.Modbus/FloatRegisterArray.cs b/DeviceSQL.SQLTypes.Modbus/FloatRegisterArray.cs new file mode 100644 index 0000000..d079736 --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/FloatRegisterArray.cs @@ -0,0 +1,165 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct FloatRegisterArray : INullable, IBinarySerialize + { + + #region Fields + + internal List floatRegisters; + + #endregion + + #region Properties + + internal FloatRegister this[int index] + { + get + { + return FloatRegisters[index]; + } + set + { + FloatRegisters[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return FloatRegisters.Count; + } + } + + #endregion + + #region Helper Methods + + private List FloatRegisters + { + get + { + if (floatRegisters == null) + { + floatRegisters = new List(); + } + return floatRegisters; + } + } + + public static FloatRegisterArray Null + { + get + { + return (new FloatRegisterArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", FloatRegisters.Select(floatRegister => floatRegister.ToString())); + } + + public FloatRegisterArray AddFloatRegister(FloatRegister floatRegister) + { + FloatRegisters.Add(floatRegister); + return this; + } + + public static FloatRegisterArray Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedFloatRegisterArray = new FloatRegisterArray() + { + floatRegisters = new List() + }; + + var parsedString = stringToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedString.Length > i; i++) + { + parsedFloatRegisterArray.FloatRegisters.Add(FloatRegister.Parse(parsedString[i])); + } + + return parsedFloatRegisterArray; + } + + public FloatRegister GetFloatRegister(SqlInt32 index) + { + return FloatRegisters[index.Value]; + } + + public static FloatRegisterArray Empty() + { + var floatRegisterArray = new FloatRegisterArray() { floatRegisters = new List() }; + return floatRegisterArray; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + FloatRegisters.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var floatRegister = new FloatRegister(); + floatRegister.Read(binaryReader); + FloatRegisters.Add(floatRegister); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; FloatRegisters.Count > i; i++) + { + FloatRegisters[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.Modbus/HistoryArchiveRecord.cs b/DeviceSQL.SQLTypes.Modbus/HistoryArchiveRecord.cs new file mode 100644 index 0000000..24e3710 --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/HistoryArchiveRecord.cs @@ -0,0 +1,140 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 264)] + public struct HistoryArchiveRecord : INullable, IBinarySerialize + { + + #region Fields + + internal byte[] data; + + #endregion + + #region Properties + + public SqlBinary Data + { + get + { + if (data == null) + { + data = new byte[Length.Value]; + } + return data; + } + set + { + data = value.Value; + Length = data.Length; + } + } + + public SqlInt32 Index + { + get; + set; + } + + public SqlInt32 Length + { + get; + set; + } + + public bool IsNull + { + get; + private set; + } + + public static HistoryArchiveRecord Null + { + get + { + return (new HistoryArchiveRecord() { IsNull = true }); + } + } + + #endregion + + #region Helper Methods + + public SqlSingle GetFloatValue(SqlByte index, SqlBoolean byteSwap, SqlBoolean wordSwap) + { + var floatValue = new DeviceSQL.Device.MODBUS.Data.HistoryArchiveRecord(Convert.ToUInt16(Index), Data.Value).GetNullableFloatValue(index.Value, byteSwap.Value, wordSwap.Value); + return floatValue ?? SqlSingle.Null; + } + + public static SqlDateTime GetDateTimeValue(SqlSingle dateValue, SqlSingle timeValue, SqlInt32 baseYear) + { + var dateTime = DeviceSQL.Device.MODBUS.Data.HistoryArchiveRecord.ParseNullableDateTimeValue(dateValue.Value, timeValue.Value, baseYear.Value); + return dateTime ?? SqlDateTime.Null; + } + + public override string ToString() + { + if (this.IsNull) + { + return "NULL"; + } + else + { + return string.Format("Index={0};Length={1};Value={2};", Index, Length, Convert.ToBase64String(Data.Value)); + } + } + + public static HistoryArchiveRecord Parse(SqlString historyArchiveToParse) + { + if (historyArchiveToParse.IsNull) + { + return Null; + } + + var parsedHistoryArchiveRecordData = historyArchiveToParse.Value.Split(",".ToCharArray()); + var parsedHistoryArchiveRecord = new HistoryArchiveRecord() { Index = Int32.Parse(parsedHistoryArchiveRecordData[0]), Length = Int32.Parse(parsedHistoryArchiveRecordData[1]), Data = Convert.FromBase64String(parsedHistoryArchiveRecordData[2]) }; + return parsedHistoryArchiveRecord; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + + if (!IsNull) + { + Index = binaryReader.ReadInt32(); + Length = binaryReader.ReadByte(); + Data = binaryReader.ReadBytes(Length.Value); + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + + if (!IsNull) + { + binaryWriter.Write(Index.Value); + binaryWriter.Write(Length.Value); + binaryWriter.Write(Data.Value, 0, Length.Value); + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.Modbus/HistoryArchiveRecordArray.cs b/DeviceSQL.SQLTypes.Modbus/HistoryArchiveRecordArray.cs new file mode 100644 index 0000000..e187bd4 --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/HistoryArchiveRecordArray.cs @@ -0,0 +1,165 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct HistoryArchiveRecordArray : INullable, IBinarySerialize + { + + #region Fields + + internal List historyArchiveRecords; + + #endregion + + #region Properties + + internal HistoryArchiveRecord this[int index] + { + get + { + return HistoryArchiveRecords[index]; + } + set + { + HistoryArchiveRecords[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return HistoryArchiveRecords.Count; + } + } + + #endregion + + #region Helper Methods + + private List HistoryArchiveRecords + { + get + { + if (historyArchiveRecords == null) + { + historyArchiveRecords = new List(); + } + return historyArchiveRecords; + } + } + + public static HistoryArchiveRecordArray Null + { + get + { + return (new HistoryArchiveRecordArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", HistoryArchiveRecords.Select(historyArchiveRecord => historyArchiveRecord.ToString())); + } + + public HistoryArchiveRecordArray AddHistoryArchiveRecord(HistoryArchiveRecord historyArchiveRecord) + { + HistoryArchiveRecords.Add(historyArchiveRecord); + return this; + } + + public static HistoryArchiveRecordArray Parse(SqlString historyArchiveToParse) + { + if (historyArchiveToParse.IsNull) + { + return Null; + } + + var parsedHistoryArchiveRecordArray = new HistoryArchiveRecordArray() + { + historyArchiveRecords = new List() + }; + + var parsedHistoryArchive = historyArchiveToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedHistoryArchive.Length > i; i++) + { + parsedHistoryArchiveRecordArray.HistoryArchiveRecords.Add(HistoryArchiveRecord.Parse(parsedHistoryArchive[i])); + } + + return parsedHistoryArchiveRecordArray; + } + + public HistoryArchiveRecord GetHistoryArchiveRecord(SqlInt32 index) + { + return HistoryArchiveRecords[index.Value]; + } + + public static HistoryArchiveRecordArray Empty() + { + var historyArchiveRecordArray = new HistoryArchiveRecordArray() { historyArchiveRecords = new List() }; + return historyArchiveRecordArray; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + HistoryArchiveRecords.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var historyArchiveRecord = new HistoryArchiveRecord(); + historyArchiveRecord.Read(binaryReader); + HistoryArchiveRecords.Add(historyArchiveRecord); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; HistoryArchiveRecords.Count > i; i++) + { + HistoryArchiveRecords[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} \ No newline at end of file diff --git a/DeviceSQL.SQLTypes.Modbus/HoldingRegister.cs b/DeviceSQL.SQLTypes.Modbus/HoldingRegister.cs new file mode 100644 index 0000000..d351384 --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/HoldingRegister.cs @@ -0,0 +1,139 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 10)] + public struct HoldingRegister : INullable, IBinarySerialize + { + + #region Fields + + internal byte[] data; + + #endregion + + #region Properties + + public SqlBinary Data + { + get + { + if (data == null) + { + data = new byte[2]; + } + return data; + } + set + { + data = value.Value; + } + } + + public ModbusAddress Address + { + get; + set; + } + + public SqlBoolean ByteSwap + { + get; + set; + } + + public bool IsNull + { + get; + private set; + } + + public SqlInt32 Value + { + get + { + return new DeviceSQL.Device.MODBUS.Data.HoldingRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(Address.RelativeAddress), Address.IsZeroBased.Value), ByteSwap.Value).Value; + } + set + { + Data = new DeviceSQL.Device.MODBUS.Data.HoldingRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(Address.RelativeAddress), Address.IsZeroBased.Value), ByteSwap.Value) { Value = Convert.ToUInt16((int)value) }.Data; + } + } + + public static HoldingRegister Null + { + get + { + return (new HoldingRegister() { IsNull = true }); + } + } + + #endregion + + #region Helper Methods + + public override string ToString() + { + if (this.IsNull) + { + return "NULL"; + } + else + { + return string.Format("Address=[{0}];Byte Swap={1};Value={2};", Address.ToString(), ByteSwap.Value, Value.Value); + } + } + + public static HoldingRegister Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedHoldingRegisterData = stringToParse.Value.Split(",".ToCharArray()); + var parsedHoldingRegister = new HoldingRegister() { Address = ModbusAddress.Parse(parsedHoldingRegisterData[0]), ByteSwap = bool.Parse(parsedHoldingRegisterData[1]), Value = UInt16.Parse(parsedHoldingRegisterData[2]) }; + return parsedHoldingRegister; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + + if (!IsNull) + { + Address.Read(binaryReader); + ByteSwap = binaryReader.ReadBoolean(); + Data = binaryReader.ReadBytes(2); + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + + if (!IsNull) + { + Address.Write(binaryWriter); + binaryWriter.Write(ByteSwap.Value); + binaryWriter.Write(Data.Value, 0, 2); + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.Modbus/HoldingRegisterArray.cs b/DeviceSQL.SQLTypes.Modbus/HoldingRegisterArray.cs new file mode 100644 index 0000000..063d337 --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/HoldingRegisterArray.cs @@ -0,0 +1,208 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct HoldingRegisterArray : INullable, IBinarySerialize + { + + #region Fields + + internal List holdingRegisters; + + #endregion + + #region Properties + + internal HoldingRegister this[int index] + { + get + { + return HoldingRegisters[index]; + } + set + { + HoldingRegisters[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return HoldingRegisters.Count; + } + } + + #endregion + + #region Helper Methods + + public SqlByte GetByte(SqlByte registerIndex, SqlInt32 offset) + { + return HoldingRegisters[registerIndex.Value].data[offset.Value]; + } + + public SqlBinary GetBytes(SqlByte registerIndex, SqlInt32 registerCount) + { + var bytes = new List(); + + for (var i = 0; registerCount.Value > i; i++) + { + bytes.AddRange(HoldingRegisters[i].Data.Value); + } + + return bytes.ToArray(); + + } + + public SqlInt16 GetShort(SqlByte registerIndex, SqlBoolean byteSwap) + { + var address = HoldingRegisters[registerIndex.Value].Address; + return new DeviceSQL.Device.MODBUS.Data.ShortRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(address.RelativeAddress.Value), address.IsZeroBased.Value)) { ByteSwap = byteSwap.Value, Data = holdingRegisters[Convert.ToByte(registerIndex.Value)].data }.Value; + } + + public SqlSingle GetFloat(SqlByte registerIndex, SqlBoolean byteSwap, SqlBoolean wordSwap) + { + var address = HoldingRegisters[registerIndex.Value].Address; + var floatRegisterValue = new DeviceSQL.Device.MODBUS.Data.FloatRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(address.RelativeAddress.Value), address.IsZeroBased.Value)) { ByteSwap = byteSwap.Value, WordSwap = wordSwap.Value, Data = holdingRegisters[Convert.ToByte(registerIndex.Value)].data.Concat(holdingRegisters[Convert.ToByte(registerIndex.Value + 1)].data).ToArray(), }.NullableValue; + return floatRegisterValue ?? SqlSingle.Null; + } + + public SqlInt32 GetLong(SqlByte registerIndex, SqlBoolean byteSwap, SqlBoolean wordSwap) + { + var address = HoldingRegisters[registerIndex.Value].Address; + return new DeviceSQL.Device.MODBUS.Data.LongRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(address.RelativeAddress.Value), address.IsZeroBased.Value)) { ByteSwap = byteSwap.Value, WordSwap = wordSwap.Value, Data = holdingRegisters[Convert.ToByte(registerIndex.Value)].data.Concat(holdingRegisters[Convert.ToByte(registerIndex.Value + 1)].data).ToArray(), }.Value; + } + + public SqlString GetString(SqlByte registerIndex, SqlBoolean byteSwap, SqlBoolean wordSwap, SqlByte length) + { + var address = HoldingRegisters[registerIndex.Value].Address; + return new DeviceSQL.Device.MODBUS.Data.StringRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(address.RelativeAddress.Value), address.IsZeroBased.Value), length.Value) { ByteSwap = byteSwap.Value, WordSwap = wordSwap.Value, Data = holdingRegisters[Convert.ToByte(registerIndex.Value)].data.Concat(holdingRegisters[Convert.ToByte(registerIndex.Value + 1)].data).ToArray(), }.Value; + } + + private List HoldingRegisters + { + get + { + if (holdingRegisters == null) + { + holdingRegisters = new List(); + } + return holdingRegisters; + } + } + + public static HoldingRegisterArray Null + { + get + { + return (new HoldingRegisterArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", HoldingRegisters.Select(holdingRegister => holdingRegister.ToString())); + } + + public HoldingRegisterArray AddHoldingRegister(HoldingRegister holdingRegister) + { + HoldingRegisters.Add(holdingRegister); + return this; + } + + public static HoldingRegisterArray Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedHoldingRegisterArray = new HoldingRegisterArray() + { + holdingRegisters = new List() + }; + + var parsedString = stringToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedString.Length > i; i++) + { + parsedHoldingRegisterArray.HoldingRegisters.Add(HoldingRegister.Parse(parsedString[i])); + } + + return parsedHoldingRegisterArray; + } + + public HoldingRegister GetHoldingRegister(SqlInt32 index) + { + return HoldingRegisters[index.Value]; + } + + public static HoldingRegisterArray Empty() + { + var holdingRegisterArray = new HoldingRegisterArray() { holdingRegisters = new List() }; + return holdingRegisterArray; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + HoldingRegisters.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var holdingRegister = new HoldingRegister(); + holdingRegister.Read(binaryReader); + HoldingRegisters.Add(holdingRegister); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; HoldingRegisters.Count > i; i++) + { + HoldingRegisters[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.Modbus/InputRegister.cs b/DeviceSQL.SQLTypes.Modbus/InputRegister.cs new file mode 100644 index 0000000..b688321 --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/InputRegister.cs @@ -0,0 +1,139 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 10)] + public struct InputRegister : INullable, IBinarySerialize + { + + #region Fields + + internal byte[] data; + + #endregion + + #region Properties + + public SqlBinary Data + { + get + { + if (data == null) + { + data = new byte[2]; + } + return data; + } + set + { + data = value.Value; + } + } + + public ModbusAddress Address + { + get; + set; + } + + public SqlBoolean ByteSwap + { + get; + set; + } + + public bool IsNull + { + get; + private set; + } + + public SqlInt32 Value + { + get + { + return new DeviceSQL.Device.MODBUS.Data.InputRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(Address.RelativeAddress), Address.IsZeroBased.Value), ByteSwap.Value).Value; + } + set + { + Data = new DeviceSQL.Device.MODBUS.Data.InputRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(Address.RelativeAddress), Address.IsZeroBased.Value), ByteSwap.Value) { Value = Convert.ToUInt16((int)value) }.Data; + } + } + + public static InputRegister Null + { + get + { + return (new InputRegister() { IsNull = true }); + } + } + + #endregion + + #region Helper Methods + + public override string ToString() + { + if (this.IsNull) + { + return "NULL"; + } + else + { + return string.Format("Address=[{0}];Byte Swap={1};Value={2};", Address.ToString(), ByteSwap.Value, Value.Value); + } + } + + public static InputRegister Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedInputRegisterData = stringToParse.Value.Split(",".ToCharArray()); + var parsedInputRegister = new InputRegister() { Address = ModbusAddress.Parse(parsedInputRegisterData[0]), ByteSwap = bool.Parse(parsedInputRegisterData[1]), Value = UInt16.Parse(parsedInputRegisterData[2]) }; + return parsedInputRegister; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + + if (!IsNull) + { + Address.Read(binaryReader); + ByteSwap = binaryReader.ReadBoolean(); + Data = binaryReader.ReadBytes(2); + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + + if (!IsNull) + { + Address.Write(binaryWriter); + binaryWriter.Write(ByteSwap.Value); + binaryWriter.Write(Data.Value, 0, 2); + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.Modbus/InputRegisterArray.cs b/DeviceSQL.SQLTypes.Modbus/InputRegisterArray.cs new file mode 100644 index 0000000..0930359 --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/InputRegisterArray.cs @@ -0,0 +1,208 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct InputRegisterArray : INullable, IBinarySerialize + { + + #region Fields + + internal List inputRegisters; + + #endregion + + #region Properties + + internal InputRegister this[int index] + { + get + { + return InputRegisters[index]; + } + set + { + InputRegisters[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return InputRegisters.Count; + } + } + + #endregion + + #region Helper Methods + + public SqlByte GetByte(SqlByte registerIndex, SqlInt32 offset) + { + return InputRegisters[registerIndex.Value].data[offset.Value]; + } + + public SqlBinary GetBytes(SqlByte registerIndex, SqlInt32 registerCount) + { + var bytes = new List(); + + for (var i = 0; registerCount.Value > i; i++) + { + bytes.AddRange(InputRegisters[i].Data.Value); + } + + return bytes.ToArray(); + + } + + public SqlInt16 GetShort(SqlByte registerIndex, SqlBoolean byteSwap) + { + var address = InputRegisters[registerIndex.Value].Address; + return new DeviceSQL.Device.MODBUS.Data.ShortRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(address.RelativeAddress.Value), address.IsZeroBased.Value)) { ByteSwap = byteSwap.Value, Data = inputRegisters[Convert.ToByte(registerIndex.Value)].data }.Value; + } + + public SqlSingle GetFloat(SqlByte registerIndex, SqlBoolean byteSwap, SqlBoolean wordSwap) + { + var address = InputRegisters[registerIndex.Value].Address; + var floatRegisterValue = new DeviceSQL.Device.MODBUS.Data.FloatRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(address.RelativeAddress.Value), address.IsZeroBased.Value)) { ByteSwap = byteSwap.Value, WordSwap = wordSwap.Value, Data = inputRegisters[Convert.ToByte(registerIndex.Value)].data.Concat(inputRegisters[Convert.ToByte(registerIndex.Value + 1)].data).ToArray(), }.NullableValue; + return floatRegisterValue ?? SqlSingle.Null; + } + + public SqlInt32 GetLong(SqlByte registerIndex, SqlBoolean byteSwap, SqlBoolean wordSwap) + { + var address = InputRegisters[registerIndex.Value].Address; + return new DeviceSQL.Device.MODBUS.Data.LongRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(address.RelativeAddress.Value), address.IsZeroBased.Value)) { ByteSwap = byteSwap.Value, WordSwap = wordSwap.Value, Data = inputRegisters[Convert.ToByte(registerIndex.Value)].data.Concat(inputRegisters[Convert.ToByte(registerIndex.Value + 1)].data).ToArray(), }.Value; + } + + public SqlString GetString(SqlByte registerIndex, SqlBoolean byteSwap, SqlBoolean wordSwap, SqlByte length) + { + var address = InputRegisters[registerIndex.Value].Address; + return new DeviceSQL.Device.MODBUS.Data.StringRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(address.RelativeAddress.Value), address.IsZeroBased.Value), length.Value) { ByteSwap = byteSwap.Value, WordSwap = wordSwap.Value, Data = inputRegisters[Convert.ToByte(registerIndex.Value)].data.Concat(inputRegisters[Convert.ToByte(registerIndex.Value + 1)].data).ToArray(), }.Value; + } + + private List InputRegisters + { + get + { + if (inputRegisters == null) + { + inputRegisters = new List(); + } + return inputRegisters; + } + } + + public static InputRegisterArray Null + { + get + { + return (new InputRegisterArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", InputRegisters.Select(inputRegister => inputRegister.ToString())); + } + + public InputRegisterArray AddInputRegister(InputRegister inputRegister) + { + InputRegisters.Add(inputRegister); + return this; + } + + public static InputRegisterArray Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedInputRegisterArray = new InputRegisterArray() + { + inputRegisters = new List() + }; + + var parsedString = stringToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedString.Length > i; i++) + { + parsedInputRegisterArray.InputRegisters.Add(InputRegister.Parse(parsedString[i])); + } + + return parsedInputRegisterArray; + } + + public InputRegister GetInputRegister(SqlInt32 index) + { + return InputRegisters[index.Value]; + } + + public static InputRegisterArray Empty() + { + var inputRegisterArray = new InputRegisterArray() { inputRegisters = new List() }; + return inputRegisterArray; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + InputRegisters.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var inputRegister = new InputRegister(); + inputRegister.Read(binaryReader); + InputRegisters.Add(inputRegister); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; InputRegisters.Count > i; i++) + { + InputRegisters[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} \ No newline at end of file diff --git a/DeviceSQL.SQLTypes.Modbus/LongRegister.cs b/DeviceSQL.SQLTypes.Modbus/LongRegister.cs new file mode 100644 index 0000000..e28fa93 --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/LongRegister.cs @@ -0,0 +1,147 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 13)] + public struct LongRegister : INullable, IBinarySerialize + { + + #region Fields + + internal byte[] data; + + #endregion + + #region Properties + + public SqlBinary Data + { + get + { + if (data == null) + { + data = new byte[4]; + } + return data; + } + set + { + data = value.Value; + } + } + + public ModbusAddress Address + { + get; + set; + } + + public SqlBoolean ByteSwap + { + get; + set; + } + + public SqlBoolean WordSwap + { + get; + set; + } + + public bool IsNull + { + get; + private set; + } + + public SqlInt32 Value + { + get + { + return new DeviceSQL.Device.MODBUS.Data.LongRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(Address.RelativeAddress), Address.IsZeroBased.Value), ByteSwap.Value, WordSwap.Value).Value; + } + set + { + Data = new DeviceSQL.Device.MODBUS.Data.LongRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(Address.RelativeAddress), Address.IsZeroBased.Value), ByteSwap.Value, WordSwap.Value) { Value = Convert.ToUInt16(value) }.Data; + } + } + + public static LongRegister Null + { + get + { + return (new LongRegister() { IsNull = true }); + } + } + + #endregion + + #region Helper Methods + + public override string ToString() + { + if (this.IsNull) + { + return "NULL"; + } + else + { + return string.Format("Address=[{0}];Byte Swap={1};Word Swap={2};Value={3};", Address.ToString(), ByteSwap.Value, WordSwap.Value, Value.Value); + } + } + + public static LongRegister Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedLongRegisterData = stringToParse.Value.Split(",".ToCharArray()); + var parsedLongRegister = new LongRegister() { Address = ModbusAddress.Parse(parsedLongRegisterData[0]), ByteSwap = bool.Parse(parsedLongRegisterData[1]), WordSwap = bool.Parse(parsedLongRegisterData[2]), Value = Int32.Parse(parsedLongRegisterData[3]) }; + return parsedLongRegister; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + + if (!IsNull) + { + Address.Read(binaryReader); + ByteSwap = binaryReader.ReadBoolean(); + WordSwap = binaryReader.ReadBoolean(); + Data = binaryReader.ReadBytes(4); + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + + if (!IsNull) + { + Address.Write(binaryWriter); + binaryWriter.Write(ByteSwap.Value); + binaryWriter.Write(WordSwap.Value); + binaryWriter.Write(Data.Value, 0, 4); + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.Modbus/LongRegisterArray.cs b/DeviceSQL.SQLTypes.Modbus/LongRegisterArray.cs new file mode 100644 index 0000000..83eb1fc --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/LongRegisterArray.cs @@ -0,0 +1,166 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct LongRegisterArray : INullable, IBinarySerialize + { + + #region Fields + + internal List longRegisters; + + #endregion + + #region Properties + + internal LongRegister this[int index] + { + get + { + return LongRegisters[index]; + } + set + { + LongRegisters[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return LongRegisters.Count; + } + } + + #endregion + + #region Helper Methods + + private List LongRegisters + { + get + { + if (longRegisters == null) + { + longRegisters = new List(); + } + return longRegisters; + } + } + + public static LongRegisterArray Null + { + get + { + return (new LongRegisterArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", LongRegisters.Select(longRegister => longRegister.ToString())); + } + + public LongRegisterArray AddLongRegister(LongRegister longRegister) + { + LongRegisters.Add(longRegister); + return this; + } + + public static LongRegisterArray Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedLongRegisterArray = new LongRegisterArray() + { + longRegisters = new List() + }; + + var parsedString = stringToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedString.Length > i; i++) + { + parsedLongRegisterArray.LongRegisters.Add(LongRegister.Parse(parsedString[i])); + } + + return parsedLongRegisterArray; + } + + public LongRegister GetLongRegister(SqlInt32 index) + { + return LongRegisters[index.Value]; + } + + public static LongRegisterArray Empty() + { + var longRegisterArray = new LongRegisterArray() { longRegisters = new List() }; + return longRegisterArray; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + LongRegisters.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var longRegister = new LongRegister(); + longRegister.Read(binaryReader); + LongRegisters.Add(longRegister); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; LongRegisters.Count > i; i++) + { + LongRegisters[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} + diff --git a/DeviceSQL.SQLTypes.Modbus/ModbusAddress.cs b/DeviceSQL.SQLTypes.Modbus/ModbusAddress.cs new file mode 100644 index 0000000..a244eb6 --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/ModbusAddress.cs @@ -0,0 +1,118 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 6)] + public struct ModbusAddress : INullable, IBinarySerialize + { + + #region Properties + + public SqlInt32 AbsoluteAddress + { + get + { + if (this.IsZeroBased) + { + return (ushort)(this.RelativeAddress - 1); + } + else + { + return (ushort)(this.RelativeAddress); + } + } + } + + public SqlInt32 RelativeAddress + { + get; + set; + } + + public SqlBoolean IsZeroBased + { + get; + set; + } + + public bool IsNull + { + get; + private set; + } + + public static ModbusAddress Null + { + get + { + return (new ModbusAddress() { IsNull = true }); + } + } + + #endregion + + #region Helper Methods + + public override string ToString() + { + if (this.IsNull) + { + return "NULL"; + } + else + { + return string.Format("Is Zero Based={0};Relative Address={1};Absolute Address={2}", IsZeroBased, RelativeAddress, AbsoluteAddress); + } + } + + public static ModbusAddress Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedMODBUSAddressData = stringToParse.Value.Split(";".ToCharArray()); + var parsedMODBUSAddress = new ModbusAddress() { IsZeroBased = bool.Parse(parsedMODBUSAddressData[0]), RelativeAddress = int.Parse(parsedMODBUSAddressData[1]) }; + return parsedMODBUSAddress; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + + if (!IsNull) + { + IsZeroBased = binaryReader.ReadBoolean(); + RelativeAddress = binaryReader.ReadInt32(); + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + + if (!IsNull) + { + binaryWriter.Write(IsZeroBased.Value); + binaryWriter.Write(RelativeAddress.Value); + } + } + + #endregion + + } +} \ No newline at end of file diff --git a/DeviceSQL.Services/Properties/AssemblyInfo.cs b/DeviceSQL.SQLTypes.Modbus/Properties/AssemblyInfo.cs similarity index 69% rename from DeviceSQL.Services/Properties/AssemblyInfo.cs rename to DeviceSQL.SQLTypes.Modbus/Properties/AssemblyInfo.cs index d295e60..2569f66 100644 --- a/DeviceSQL.Services/Properties/AssemblyInfo.cs +++ b/DeviceSQL.SQLTypes.Modbus/Properties/AssemblyInfo.cs @@ -2,34 +2,35 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// 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("DeviceSQL.Services")] -[assembly: AssemblyDescription("")] +[assembly: AssemblyTitle("DeviceSQL.SQLTypes.Modbus")] +[assembly: AssemblyDescription("DeviceSQL.SQLTypes.Modbus")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("DeviceSQL.Services")] -[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyCompany("CloudSonix")] +[assembly: AssemblyProduct("DeviceSQL")] +[assembly: AssemblyCopyright("© CloudSonix. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] +[assembly: AssemblyKeyFileAttribute("../DeviceSQL-Key.snk")] -// 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 +// 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("4136548d-5d58-4eeb-8876-d450adc62369")] +[assembly: Guid("cd45d76e-d2ed-4587-9873-f35ad24e42a5")] // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -// You can specify all the values or you can default the Build and Revision Numbers +// You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] diff --git a/DeviceSQL.SQLTypes.Modbus/ShortRegister.cs b/DeviceSQL.SQLTypes.Modbus/ShortRegister.cs new file mode 100644 index 0000000..b940a50 --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/ShortRegister.cs @@ -0,0 +1,139 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 10)] + public struct ShortRegister : INullable, IBinarySerialize + { + + #region Fields + + internal byte[] data; + + #endregion + + #region Properties + + public SqlBinary Data + { + get + { + if (data == null) + { + data = new byte[2]; + } + return data; + } + set + { + data = value.Value; + } + } + + public ModbusAddress Address + { + get; + set; + } + + public SqlBoolean ByteSwap + { + get; + set; + } + + public bool IsNull + { + get; + private set; + } + + public SqlInt32 Value + { + get + { + return new DeviceSQL.Device.MODBUS.Data.ShortRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(Address.RelativeAddress), Address.IsZeroBased.Value), ByteSwap.Value).Value; + } + set + { + Data = new DeviceSQL.Device.MODBUS.Data.ShortRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(Address.RelativeAddress), Address.IsZeroBased.Value), ByteSwap.Value) { Value = Convert.ToInt16((int)value.Value) }.Data; + } + } + + public static ShortRegister Null + { + get + { + return (new ShortRegister() { IsNull = true }); + } + } + + #endregion + + #region Helper Methods + + public override string ToString() + { + if (this.IsNull) + { + return "NULL"; + } + else + { + return string.Format("Address=[{0}];Byte Swap={1};Value={2};", Address.ToString(), ByteSwap.Value, Value.Value); + } + } + + public static ShortRegister Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedShortRegisterData = stringToParse.Value.Split(",".ToCharArray()); + var parsedShortRegister = new ShortRegister() { Address = ModbusAddress.Parse(parsedShortRegisterData[0]), ByteSwap = bool.Parse(parsedShortRegisterData[1]), Value = UInt16.Parse(parsedShortRegisterData[2]) }; + return parsedShortRegister; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + + if (!IsNull) + { + Address.Read(binaryReader); + ByteSwap = binaryReader.ReadBoolean(); + Data = binaryReader.ReadBytes(2); + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + + if (!IsNull) + { + Address.Write(binaryWriter); + binaryWriter.Write(ByteSwap.Value); + binaryWriter.Write(Data.Value, 0, 2); + } + } + + #endregion + + } +} \ No newline at end of file diff --git a/DeviceSQL.SQLTypes.Modbus/ShortRegisterArray.cs b/DeviceSQL.SQLTypes.Modbus/ShortRegisterArray.cs new file mode 100644 index 0000000..82d19ad --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/ShortRegisterArray.cs @@ -0,0 +1,165 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct ShortRegisterArray : INullable, IBinarySerialize + { + + #region Fields + + internal List shortRegisters; + + #endregion + + #region Properties + + internal ShortRegister this[int index] + { + get + { + return ShortRegisters[index]; + } + set + { + ShortRegisters[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return ShortRegisters.Count; + } + } + + #endregion + + #region Helper Methods + + private List ShortRegisters + { + get + { + if (shortRegisters == null) + { + shortRegisters = new List(); + } + return shortRegisters; + } + } + + public static ShortRegisterArray Null + { + get + { + return (new ShortRegisterArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", ShortRegisters.Select(shortRegister => shortRegister.ToString())); + } + + public ShortRegisterArray AddShortRegister(ShortRegister shortRegister) + { + ShortRegisters.Add(shortRegister); + return this; + } + + public static ShortRegisterArray Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedShortRegisterArray = new ShortRegisterArray() + { + shortRegisters = new List() + }; + + var parsedString = stringToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedString.Length > i; i++) + { + parsedShortRegisterArray.ShortRegisters.Add(ShortRegister.Parse(parsedString[i])); + } + + return parsedShortRegisterArray; + } + + public ShortRegister GetShortRegister(SqlInt32 index) + { + return ShortRegisters[index.Value]; + } + + public static ShortRegisterArray Empty() + { + var shortRegisterArray = new ShortRegisterArray() { shortRegisters = new List() }; + return shortRegisterArray; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + ShortRegisters.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var shortRegister = new ShortRegister(); + shortRegister.Read(binaryReader); + ShortRegisters.Add(shortRegister); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; ShortRegisters.Count > i; i++) + { + ShortRegisters[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} \ No newline at end of file diff --git a/DeviceSQL.SQLTypes.Modbus/StringRegister.cs b/DeviceSQL.SQLTypes.Modbus/StringRegister.cs new file mode 100644 index 0000000..2294bba --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/StringRegister.cs @@ -0,0 +1,141 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 264)] + public struct StringRegister : INullable, IBinarySerialize + { + + #region Fields + + internal byte[] data; + + #endregion + + #region Properties + + public SqlBinary Data + { + get + { + if (data == null) + { + data = new byte[Length.Value]; + } + return data; + } + set + { + data = value.Value; + Length = Convert.ToByte(data.Length); + } + } + + public SqlByte Length + { + get; + set; + } + + public ModbusAddress Address + { + get; + set; + } + + public bool IsNull + { + get; + private set; + } + + public SqlString Value + { + get + { + return new DeviceSQL.Device.MODBUS.Data.StringRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(Address.RelativeAddress), Address.IsZeroBased.Value), Length.Value).Value; + } + set + { + Data = new DeviceSQL.Device.MODBUS.Data.StringRegister(new DeviceSQL.Device.MODBUS.Data.MODBUSAddress(Convert.ToUInt16(Address.RelativeAddress), Address.IsZeroBased.Value), Length.Value) { Value = value.Value }.Data; + } + } + + public static StringRegister Null + { + get + { + return (new StringRegister() { IsNull = true }); + } + } + + #endregion + + #region Helper Methods + + public override string ToString() + { + if (this.IsNull) + { + return "NULL"; + } + else + { + return string.Format("Address=[{0}];Length={1};Value={2};", Address.ToString(), Length.Value, Value.Value); + } + } + + public static StringRegister Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedStringRegisterData = stringToParse.Value.Split(",".ToCharArray()); + var parsedStringRegister = new StringRegister() { Address = ModbusAddress.Parse(parsedStringRegisterData[0]), Length = byte.Parse(parsedStringRegisterData[1]), Value = parsedStringRegisterData[2] }; + return parsedStringRegister; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + + if (!IsNull) + { + Address.Read(binaryReader); + Length = binaryReader.ReadByte(); + Data = binaryReader.ReadBytes(Length.Value); + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + + if (!IsNull) + { + Address.Write(binaryWriter); + binaryWriter.Write(Length.Value); + binaryWriter.Write(Data.Value, 0, Length.Value); + } + } + + #endregion + + } +} + diff --git a/DeviceSQL.SQLTypes.Modbus/StringRegisterArray.cs b/DeviceSQL.SQLTypes.Modbus/StringRegisterArray.cs new file mode 100644 index 0000000..42b07db --- /dev/null +++ b/DeviceSQL.SQLTypes.Modbus/StringRegisterArray.cs @@ -0,0 +1,165 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.Modbus +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct StringRegisterArray : INullable, IBinarySerialize + { + + #region Fields + + internal List stringRegisters; + + #endregion + + #region Properties + + internal StringRegister this[int index] + { + get + { + return StringRegisters[index]; + } + set + { + StringRegisters[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return StringRegisters.Count; + } + } + + #endregion + + #region Helper Methods + + private List StringRegisters + { + get + { + if (stringRegisters == null) + { + stringRegisters = new List(); + } + return stringRegisters; + } + } + + public static StringRegisterArray Null + { + get + { + return (new StringRegisterArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", StringRegisters.Select(stringRegister => stringRegister.ToString())); + } + + public StringRegisterArray AddStringRegister(StringRegister stringRegister) + { + StringRegisters.Add(stringRegister); + return this; + } + + public static StringRegisterArray Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedStringRegisterArray = new StringRegisterArray() + { + stringRegisters = new List() + }; + + var parsedString = stringToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedString.Length > i; i++) + { + parsedStringRegisterArray.StringRegisters.Add(StringRegister.Parse(parsedString[i])); + } + + return parsedStringRegisterArray; + } + + public StringRegister GetStringRegister(SqlInt32 index) + { + return StringRegisters[index.Value]; + } + + public static StringRegisterArray Empty() + { + var stringRegisterArray = new StringRegisterArray() { stringRegisters = new List() }; + return stringRegisterArray; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + StringRegisters.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var stringRegister = new StringRegister(); + stringRegister.Read(binaryReader); + StringRegisters.Add(stringRegister); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; StringRegisters.Count > i; i++) + { + StringRegisters[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} \ No newline at end of file diff --git a/DeviceSQL.SQLTypes.ROC/AlarmRecord.cs b/DeviceSQL.SQLTypes.ROC/AlarmRecord.cs new file mode 100644 index 0000000..7ee1c6a --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/AlarmRecord.cs @@ -0,0 +1,163 @@ +#region Imported Types + + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 27)] + public struct AlarmRecord : INullable, IBinarySerialize + { + + #region Fields + + public byte[] data; + + #endregion + + #region Properties + + public bool IsNull + { + get; + internal set; + } + + public static AlarmRecord Null + { + get + { + return new AlarmRecord() { IsNull = true }; + } + } + + public SqlDateTime DateTimeStamp + { + get + { + var alarmRecord = new Data.AlarmRecord(Convert.ToUInt16(Index), Data); + return alarmRecord.DateTimeStamp.HasValue ? alarmRecord.DateTimeStamp.Value : SqlDateTime.Null; + } + } + + public int Index + { + get; + set; + } + + public string AlarmCode + { + get + { + return new Data.AlarmRecord(Convert.ToUInt16(Index), Data).AlarmCode.ToString(); + } + } + + public string AlarmClass + { + get + { + return new Data.AlarmRecord(Convert.ToUInt16(Index), Data).AlarmClass.ToString(); + } + } + + public string AlarmState + { + get + { + return new Data.AlarmRecord(Convert.ToUInt16(Index), Data).AlarmState.ToString(); + } + } + + public string Tag + { + get + { + return new Data.AlarmRecord(Convert.ToUInt16(Index), Data).Tag; + } + } + + public SqlSingle Value + { + get + { + var alarmRecord = new Data.AlarmRecord(Convert.ToUInt16(Index), Data); + return alarmRecord.NullableValue.HasValue ? alarmRecord.Value : SqlSingle.Null; + } + } + + public byte[] Data + { + get + { + if (data == null) + { + data = new byte[22]; + } + return data; + } + + internal set + { + data = value; + } + } + + #endregion + + #region Helper Methods + + public static AlarmRecord Parse(SqlString stringToParse) + { + var parsedEventRecord = stringToParse.Value.Split(",".ToCharArray()); + var base64Bytes = Convert.FromBase64String(parsedEventRecord[1]); + if (base64Bytes.Length == 22) + { + return new AlarmRecord() { Index = ushort.Parse(parsedEventRecord[0]), Data = base64Bytes }; + } + else + { + throw new ArgumentException("Input must be exactly 22 bytes"); + } + } + + public override string ToString() + { + return string.Format("{0},{1}", Index, Convert.ToBase64String(Data)); + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + Index = binaryReader.ReadInt32(); + if (!IsNull) + { + Data = binaryReader.ReadBytes(22); + } + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Index); + if (!IsNull) + { + binaryWriter.Write(Data, 0, 22); + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.ROC/AlarmRecordArray.cs b/DeviceSQL.SQLTypes.ROC/AlarmRecordArray.cs new file mode 100644 index 0000000..35bb11a --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/AlarmRecordArray.cs @@ -0,0 +1,162 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct AlarmRecordArray : INullable, IBinarySerialize + { + + #region Fields + + public List alarmRecords; + + #endregion + + #region Properties + + internal AlarmRecord this[int index] + { + get + { + return AlarmRecords[index]; + } + set + { + AlarmRecords[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return AlarmRecords.Count; + } + } + + #endregion + + #region Helper Methods + + private List AlarmRecords + { + get + { + if (alarmRecords == null) + { + alarmRecords = new List(); + } + return alarmRecords; + } + } + + public static AlarmRecordArray Null + { + get + { + return (new AlarmRecordArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", AlarmRecords.Select(parameter => parameter.ToString())); + } + + public AlarmRecordArray AddAlarmRecord(AlarmRecord alarmRecord) + { + AlarmRecords.Add(alarmRecord); + return this; + } + + public static AlarmRecordArray Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedROCAlarmRecords = new AlarmRecordArray(); + parsedROCAlarmRecords.alarmRecords = new List(); + var parsedString = stringToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedString.Length > i; i++) + { + parsedROCAlarmRecords.alarmRecords.Add(AlarmRecord.Parse(parsedString[i])); + } + + return parsedROCAlarmRecords; + } + + public AlarmRecord GetAlarmRecord(SqlInt32 index) + { + return AlarmRecords[index.Value]; + } + + public static AlarmRecordArray Empty() + { + var alarmRecordArray = new AlarmRecordArray { alarmRecords = new List() }; + return alarmRecordArray; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + AlarmRecords.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var alarmRecord = new AlarmRecord(); + alarmRecord.Read(binaryReader); + AlarmRecords.Add(alarmRecord); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; AlarmRecords.Count > i; i++) + { + AlarmRecords[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.ROC/ArchiveInformation.cs b/DeviceSQL.SQLTypes.ROC/ArchiveInformation.cs new file mode 100644 index 0000000..44d9bd9 --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/ArchiveInformation.cs @@ -0,0 +1,224 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC.Data; +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 27)] + public struct ArchiveInformation : INullable, IBinarySerialize + { + + #region Fields + + private byte[] data; + + #endregion + + #region Properties + + public bool IsNull + { + get; + internal set; + } + + public static ArchiveInformation Null + { + get + { + return new ArchiveInformation() { IsNull = true }; + } + } + + public byte[] Data + { + get + { + if (data == null) + { + data = new byte[26]; + } + return data; + } + set + { + data = value; + } + } + + public int AlarmLogPointer + { + get + { + return new ArchiveInfo(Data).AlarmLogPointer; + } + } + + public int EventLogPointer + { + get + { + return new ArchiveInfo(Data).EventLogPointer; + } + } + + public int BaseRamCurrentHistoricalHour + { + get + { + return new ArchiveInfo(Data).BaseRamCurrentHistoricalHour; + } + } + + public int BaseRam1CurrentHistoricalHour + { + get + { + return new ArchiveInfo(Data).BaseRam1CurrentHistoricalHour; + } + } + + public int BaseRam2CurrentHistoricalHour + { + get + { + return new ArchiveInfo(Data).BaseRam2CurrentHistoricalHour; + } + } + + public byte BaseRamCurrentHistoricalDay + { + get + { + return new ArchiveInfo(Data).BaseRamCurrentHistoricalDay; + } + } + + public byte Base1RamCurrentHistoricalDay + { + get + { + return new ArchiveInfo(Data).Base1RamCurrentHistoricalDay; + } + } + + public byte BaseRam2CurrentHistoricalDay + { + get + { + return new ArchiveInfo(Data).BaseRam2CurrentHistoricalDay; + } + } + + public int MaximumNumberOfAlarms + { + get + { + return new ArchiveInfo(Data).MaximumNumberOfAlarms; + } + } + + public int MaximumNumberOfEvents + { + get + { + return new ArchiveInfo(Data).MaximumNumberOfEvents; + } + } + + public byte BaseRamNumberOfDays + { + get + { + return new ArchiveInfo(Data).BaseRamNumberOfDays; + } + } + + public byte BaseRam1NumberOfDays + { + get + { + return new ArchiveInfo(Data).BaseRam1NumberOfDays; + } + } + + public byte BaseRam2NumberOfDays + { + get + { + return new ArchiveInfo(Data).BaseRam2NumberOfDays; + } + } + + public int CurrentAuditLogPointer + { + get + { + return new ArchiveInfo(Data).CurrentAuditLogPointer; + } + } + + public byte MinutesPerHistoricalPeriod + { + get + { + return new ArchiveInfo(Data).MinutesPerHistoricalPeriod; + } + } + + #endregion + + #region Helper Methods + + public static ArchiveInformation Parse(SqlString stringToParse) + { + var base64Bytes = Convert.FromBase64String(stringToParse.Value); + if (base64Bytes.Length == 24) + { + return new ArchiveInformation() { Data = base64Bytes }; + } + else + { + throw new ArgumentException("Input must be exactly 24 bytes"); + } + } + + public override string ToString() + { + return Convert.ToBase64String(Data); + } + + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + if (!IsNull) + { + Data = binaryReader.ReadBytes(26); + } + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + if (!IsNull) + { + binaryWriter.Write(Data, 0, 26); + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.ROC/AuditLogRecord.cs b/DeviceSQL.SQLTypes.ROC/AuditLogRecord.cs new file mode 100644 index 0000000..72adfee --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/AuditLogRecord.cs @@ -0,0 +1,384 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC.Data; +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 29)] + public struct AuditLogRecord : INullable, IBinarySerialize + { + + #region Fields + + private byte[] data; + + #endregion + + #region Properties + + public bool IsNull + { + get; + internal set; + } + + public static AuditLogRecord Null + { + get + { + return new AuditLogRecord() { IsNull = true }; + } + } + + public byte[] Data + { + get + { + if (data == null) + { + data = new byte[24]; + } + return data; + } + + set + { + data = value; + } + } + + public SqlDateTime DateTimeStamp + { + get + { + var dateTimeStamp = new Data.AuditLogRecord(Convert.ToUInt16(Index), Data).DateTimeStamp; + return dateTimeStamp.HasValue ? dateTimeStamp.Value : SqlDateTime.Null; + } + } + + public int Index + { + get; + set; + } + + public SqlByte FstNumber + { + get + { + var fstNumber = new Data.AuditLogRecord(Convert.ToUInt16(Index), Data).FstNumber; + return fstNumber.HasValue ? fstNumber.Value : SqlByte.Null; + } + } + + public SqlByte PointType + { + get + { + var pointType = new Data.AuditLogRecord(Convert.ToUInt16(Index), Data).PointType; + return pointType.HasValue ? pointType.Value : SqlByte.Null; + } + } + + public SqlByte LogicalNumber + { + get + { + var logicalNumber = new Data.AuditLogRecord(Convert.ToUInt16(Index), Data).LogicalNumber; + return logicalNumber.HasValue ? logicalNumber.Value : SqlByte.Null; + } + } + + public SqlByte ParameterNumber + { + get + { + var parameterNumber = new Data.AuditLogRecord(Convert.ToUInt16(Index), Data).ParameterNumber; + return parameterNumber.HasValue ? parameterNumber.Value : SqlByte.Null; + } + } + + public SqlInt32 Tag + { + get + { + var tag = new Data.AuditLogRecord(Convert.ToUInt16(Index), Data).Tag; + return tag.HasValue ? tag.Value : SqlInt32.Null; + } + } + + public SqlDateTime PowerRemovedDateTime + { + get + { + var powerRemovedDateTime = new Data.AuditLogRecord(Convert.ToUInt16(Index), Data).PowerRemovedDateTime; + return powerRemovedDateTime.HasValue ? powerRemovedDateTime.Value : SqlDateTime.Null; + } + } + + public SqlString CalibrationPointType + { + get + { + var calibrationPointType = new Data.AuditLogRecord(Convert.ToUInt16(Index), Data).CalibrationPointType; + return calibrationPointType.HasValue ? calibrationPointType.Value.ToString() : SqlString.Null; + } + + } + + public SqlString CalibrationMultivariableSensorInput + { + get + { + var calibrationMultivariableSensorInput = new Data.AuditLogRecord(Convert.ToUInt16(Index), Data).CalibrationMultivariableSensorInput; + return calibrationMultivariableSensorInput.HasValue ? calibrationMultivariableSensorInput.Value.ToString() : SqlString.Null; + } + } + + public SqlString CalibrationType + { + get + { + var calibrationType = new Data.AuditLogRecord(Convert.ToUInt16(Index), Data).CalibrationType; + return calibrationType.HasValue ? calibrationType.Value.ToString() : SqlString.Null; + } + } + + public SqlString EventCode + { + get + { + return new Data.AuditLogRecord(Convert.ToUInt16(Index), Data).EventCode.ToString(); + } + } + + public SqlString OperatorId + { + get + { + return new Data.AuditLogRecord(Convert.ToUInt16(Index), Data).OperatorId; + } + } + + public SqlString EventText + { + get + { + return new Data.AuditLogRecord(Convert.ToUInt16(Index), Data).EventText; + } + } + + public SqlBinary OldValue + { + get + { + return new Data.AuditLogRecord(Convert.ToUInt16(Index), Data).OldValue; + } + } + + public SqlSingle FstFloatValue + { + get + { + var fstFloatValue = new Data.AuditLogRecord(Convert.ToUInt16(Index), Data).FstFloatValue; + return fstFloatValue.HasValue ? fstFloatValue.Value : SqlSingle.Null; + } + } + + public SqlBinary NewValue + { + get + { + return new Data.AuditLogRecord(Convert.ToUInt16(Index), Data).NewValue; + } + } + + public Parameter OldParameterValue + { + get + { + if (!PointType.IsNull && !ParameterNumber.IsNull) + { + var pointType = PointType.Value; + var parameterNumber = ParameterNumber.Value; + var parameterDefinition = ParameterDatabase.ParameterDefinitions.Where(pd => pd.PointType == pointType && pd.Parameter == parameterNumber).FirstOrDefault(); + switch (parameterDefinition.DataType) + { + case "AC": + switch (parameterDefinition.Length) + { + case 3: + return new Parameter() { RawType = ParameterType.AC3, RawValue = OldValue.Value.Take(3).ToArray() }; + default: + return Parameter.Null; + } + case "BIN": + return new Parameter() { RawType = ParameterType.BIN, RawValue = OldValue.Value.Take(1).ToArray() }; + case "FL": + return new Parameter() { RawType = ParameterType.FL, RawValue = OldValue.Value }; + case "INT16": + return new Parameter() { RawType = ParameterType.INT16, RawValue = OldValue.Value.Take(2).ToArray() }; + case "INT32": + return new Parameter() { RawType = ParameterType.INT32, RawValue = OldValue.Value }; + case "INT8": + return new Parameter() { RawType = ParameterType.INT8, RawValue = OldValue.Value.Take(1).ToArray() }; + case "TLP": + return new Parameter() { RawType = ParameterType.TLP, RawValue = OldValue.Value.Take(3).ToArray() }; + case "UINT16": + return new Parameter() { RawType = ParameterType.UINT16, RawValue = OldValue.Value.Take(2).ToArray() }; + case "UINT32": + return new Parameter() { RawType = ParameterType.UINT32, RawValue = OldValue.Value }; + case "TIME": + return new Parameter() { RawType = ParameterType.TIME, RawValue = OldValue.Value }; + case "UINT8": + return new Parameter() { RawType = ParameterType.UINT8, RawValue = OldValue.Value.Take(1).ToArray() }; + default: + return Parameter.Null; + } + + } + else + { + return Parameter.Null; + } + } + } + + public Parameter NewParameterValue + { + get + { + if (!PointType.IsNull && !ParameterNumber.IsNull) + { + var pointType = PointType.Value; + var parameterNumber = ParameterNumber.Value; + var parameterDefinition = ParameterDatabase.ParameterDefinitions.Where(pd => pd.PointType == pointType && pd.Parameter == parameterNumber).FirstOrDefault(); + switch (parameterDefinition.DataType) + { + case "AC": + switch (parameterDefinition.Length) + { + case 3: + return new Parameter() { RawType = ParameterType.AC3, RawValue = NewValue.Value.Take(3).ToArray() }; + case 7: + return new Parameter() { RawType = ParameterType.AC7, RawValue = NewValue.Value.Union(new byte[3]).ToArray() }; + case 10: + return new Parameter() { RawType = ParameterType.AC10, RawValue = OldValue.Value.Union(NewValue.Value).Union(BitConverter.GetBytes(Convert.ToUInt16(Tag.Value))).ToArray() }; + case 12: + return new Parameter() { RawType = ParameterType.AC12, RawValue = OldValue.Value.Union(NewValue.Value).Union(BitConverter.GetBytes(Convert.ToUInt16(Tag.Value))).Union(new byte[2]).ToArray() }; + case 20: + return new Parameter() { RawType = ParameterType.AC20, RawValue = OldValue.Value.Union(NewValue.Value).Union(BitConverter.GetBytes(Convert.ToUInt16(Tag.Value))).Union(new byte[10]).ToArray() }; + case 30: + return new Parameter() { RawType = ParameterType.AC30, RawValue = OldValue.Value.Union(NewValue.Value).Union(BitConverter.GetBytes(Convert.ToUInt16(Tag.Value))).Union(new byte[20]).ToArray() }; + case 40: + return new Parameter() { RawType = ParameterType.AC40, RawValue = OldValue.Value.Union(NewValue.Value).Union(BitConverter.GetBytes(Convert.ToUInt16(Tag.Value))).Union(new byte[30]).ToArray() }; + default: + return Parameter.Null; + } + case "BIN": + return new Parameter() { RawType = ParameterType.BIN, RawValue = NewValue.Value.Take(1).ToArray() }; + case "FL": + return new Parameter() { RawType = ParameterType.FL, RawValue = NewValue.Value }; + case "INT16": + return new Parameter() { RawType = ParameterType.INT16, RawValue = NewValue.Value.Take(2).ToArray() }; + case "INT32": + return new Parameter() { RawType = ParameterType.INT32, RawValue = NewValue.Value }; + case "INT8": + return new Parameter() { RawType = ParameterType.INT8, RawValue = NewValue.Value.Take(1).ToArray() }; + case "TLP": + return new Parameter() { RawType = ParameterType.TLP, RawValue = NewValue.Value.Take(3).ToArray() }; + case "UINT16": + return new Parameter() { RawType = ParameterType.UINT16, RawValue = NewValue.Value.Take(2).ToArray() }; + case "UINT32": + return new Parameter() { RawType = ParameterType.UINT32, RawValue = NewValue.Value }; + case "TIME": + return new Parameter() { RawType = ParameterType.TIME, RawValue = NewValue.Value }; + case "UINT8": + return new Parameter() { RawType = ParameterType.UINT8, RawValue = NewValue.Value.Take(1).ToArray() }; + default: + return Parameter.Null; + } + + } + else + { + return Parameter.Null; + } + } + } + + public SqlInt32 SequenceNumber + { + get + { + return new Data.AuditLogRecord(Convert.ToUInt16(Index), Data).SequenceNumber; + } + } + + public SqlBoolean EventNotSaved + { + get + { + return new Data.AuditLogRecord(Convert.ToUInt16(Index), Data).EventNotSaved; + } + } + + #endregion + + #region Helper Methods + + public static AuditLogRecord Parse(SqlString stringToParse) + { + var parsedAuditLogRecord = stringToParse.Value.Split(",".ToCharArray()); + var base64Bytes = Convert.FromBase64String(parsedAuditLogRecord[1]); + if (base64Bytes.Length == 24) + { + return new AuditLogRecord() { Index = ushort.Parse(parsedAuditLogRecord[0]), Data = base64Bytes }; + } + else + { + throw new ArgumentException("Input must be exactly 24 bytes"); + } + } + + public override string ToString() + { + return string.Format("{0},{1}", Index, Convert.ToBase64String(Data)); + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + Index = binaryReader.ReadInt32(); + if (!IsNull) + { + Data = binaryReader.ReadBytes(24); + } + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Index); + if (!IsNull) + { + binaryWriter.Write(Data, 0, 24); + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.ROC/AuditLogRecordArray.cs b/DeviceSQL.SQLTypes.ROC/AuditLogRecordArray.cs new file mode 100644 index 0000000..c927301 --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/AuditLogRecordArray.cs @@ -0,0 +1,162 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct AuditLogRecordArray : INullable, IBinarySerialize + { + + #region Fields + + public List auditLogRecords; + + #endregion + + #region Properties + + internal AuditLogRecord this[int index] + { + get + { + return AuditLogRecords[index]; + } + set + { + AuditLogRecords[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return AuditLogRecords.Count; + } + } + + #endregion + + #region Helper Methods + + private List AuditLogRecords + { + get + { + if (auditLogRecords == null) + { + auditLogRecords = new List(); + } + return auditLogRecords; + } + } + + public static AuditLogRecordArray Null + { + get + { + return (new AuditLogRecordArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", AuditLogRecords.Select(parameter => parameter.ToString())); + } + + public AuditLogRecordArray AddAuditLogRecord(AuditLogRecord auditLogRecord) + { + AuditLogRecords.Add(auditLogRecord); + return this; + } + + public static AuditLogRecordArray Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedROCAuditLogRecords = new AuditLogRecordArray(); + parsedROCAuditLogRecords.auditLogRecords = new List(); + var parsedString = stringToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedString.Length > i; i++) + { + parsedROCAuditLogRecords.auditLogRecords.Add(AuditLogRecord.Parse(parsedString[i])); + } + + return parsedROCAuditLogRecords; + } + + public AuditLogRecord GetAuditLogRecord(SqlInt32 index) + { + return AuditLogRecords[index.Value]; + } + + public static AuditLogRecordArray Empty() + { + var auditLogRecordArray = new AuditLogRecordArray { auditLogRecords = new List() }; + return auditLogRecordArray; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + AuditLogRecords.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var auditLogRecord = new AuditLogRecord(); + auditLogRecord.Read(binaryReader); + AuditLogRecords.Add(auditLogRecord); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; AuditLogRecords.Count > i; i++) + { + AuditLogRecords[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.ROC/DeviceSQL-Key.snk b/DeviceSQL.SQLTypes.ROC/DeviceSQL-Key.snk new file mode 100644 index 0000000000000000000000000000000000000000..ca3f567d3db455012c7a66637eb8907a9bd39d44 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50098$3?T13rv#%l>UIbqk#p{58IfWR*mMso z35imLh~|o$i|a}az~~Ok&l)dIi`{OB{V!qDTifFO$xRBhW~0sbwmPijIEv4R!%(RjfFE&EojhhT!V&j_B^IeW zV#`La%_!PJnD%F6N3rP`$o~^Fy2wdyv7EP+L#1~z{1xP!AkRQcB`03g#7S&t0)}IL z+1Epb80)U{)P%|_*Yz8s3rh*V^zg!7;*W}oP*GNcT{J|&13%Ah{>+glLcBqh`{|vm zLf@GUP0RzD0o8A<%=HgZ^1a`>BfZrpthf<-xXxWJvsMZ~5;-;uRxmK{_K?WuqnHkh zp(h(zK%aFOW-vvZ8~zuFS(Q(^YyXGcZ^!I6fxW;;$jyi)$*{)V74W91fhaYJUmq}j zr6GShK_NN0Y{j6f@$7N%_j2Rf(SnCZg&es!9^bWfLd-p$PI19aOL=@MtaP3Wvq;$N zh56f(Nl`2MF5TV{5>`YaI+eeG|Okc$y3vX>T`J4%L5{dsk5Lr=(kTMTk>qj-eB7HEw8oeY7grK_}ZNn i5@M^L8hg6VVbYdh7UBjqUTc{15F2df9dF?|#?53oE+$?8 literal 0 HcmV?d00001 diff --git a/DeviceSQL.SQLTypes.ROC/DeviceSQL.SQLTypes.ROC.csproj b/DeviceSQL.SQLTypes.ROC/DeviceSQL.SQLTypes.ROC.csproj new file mode 100644 index 0000000..7462f17 --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/DeviceSQL.SQLTypes.ROC.csproj @@ -0,0 +1,180 @@ + + + + + Debug + AnyCPU + {256CA566-5436-4543-BC13-D2480BEE70C2} + Library + Properties + DeviceSQL.SQLTypes.ROC + DeviceSQL.SQLTypes.ROC + v4.8 + 512 + true + + + true + full + false + bin\Debug\ + TRACE;DEBUG;SQLTYPES + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + false + + + DeviceSQL-Key.snk + + + + + + + + + + + + + + Common\HexConverter.cs + + + Devices\Ac10Parameter.cs + + + Devices\Ac12Parameter.cs + + + Devices\Ac20Parameter.cs + + + Devices\Ac30Parameter.cs + + + Devices\Ac3Parameter.cs + + + Devices\Ac40Parameter.cs + + + Devices\Ac7Parameter.cs + + + Devices\AlarmRecord.cs + + + Devices\ArchiveInfo.cs + + + Devices\AuditLogRecord.cs + + + Devices\BinParameter.cs + + + Devices\DoubleParameter.cs + + + Devices\EventRecord.cs + + + Devices\FlpParameter.cs + + + Devices\FstCodeChunk.cs + + + Devices\FstHeaderInfo.cs + + + Devices\HistoryPointConfiguration.cs + + + Devices\HistoryRecord.cs + + + Devices\Int16Parameter.cs + + + Devices\Int32Parameter.cs + + + Devices\Int8Parameter.cs + + + Devices\IRocParameterData.cs + + + Devices\Parameter.cs + + + Devices\ParameterType.cs + + + Devices\RocPlusAlarmRecord.cs + + + Devices\RocPlusEventRecord.cs + + + Devices\RocPlusHistoryRecord.cs + + + Devices\TimeParameter.cs + + + Devices\Tlp.cs + + + Devices\TlpParameter.cs + + + Devices\UInt16Parameter.cs + + + Devices\UInt32Parameter.cs + + + Devices\UInt8Parameter.cs + + + Devices\ParameterDatabase.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DeviceSQL.SQLTypes.ROC/EventRecord.cs b/DeviceSQL.SQLTypes.ROC/EventRecord.cs new file mode 100644 index 0000000..3d12b6e --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/EventRecord.cs @@ -0,0 +1,370 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC.Data; + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 27)] + public struct EventRecord : INullable, IBinarySerialize + { + + #region Fields + + private byte[] data; + + #endregion + + #region Properties + + public bool IsNull + { + get; + internal set; + } + + public static EventRecord Null + { + get + { + return new EventRecord() { IsNull = true }; + } + } + + public byte[] Data + { + get + { + if (data == null) + { + data = new byte[22]; + } + return data; + } + + internal set + { + data = value; + } + } + + public SqlDateTime DateTimeStamp + { + get + { + var dateTimeStamp = new Data.EventRecord(Convert.ToUInt16(Index), Data).DateTimeStamp; + return dateTimeStamp.HasValue ? dateTimeStamp.Value : SqlDateTime.Null; + } + } + + public int Index + { + get; + internal set; + } + + public SqlByte FstNumber + { + get + { + var fstNumber = new Data.EventRecord(Convert.ToUInt16(Index), Data).FstNumber; + return fstNumber.HasValue ? fstNumber.Value : SqlByte.Null; + } + } + + public SqlByte PointType + { + get + { + var pointType = new Data.EventRecord(Convert.ToUInt16(Index), Data).PointType; + return pointType.HasValue ? pointType.Value : SqlByte.Null; + } + } + + public SqlByte LogicalNumber + { + get + { + var logicalNumber = new Data.EventRecord(Convert.ToUInt16(Index), Data).LogicalNumber; + return logicalNumber.HasValue ? logicalNumber.Value : SqlByte.Null; + } + } + + public SqlByte ParameterNumber + { + get + { + var parameterNumber = new Data.EventRecord(Convert.ToUInt16(Index), Data).ParameterNumber; + return parameterNumber.HasValue ? parameterNumber.Value : SqlByte.Null; + } + } + + public SqlInt32 Tag + { + get + { + var tag = new Data.EventRecord(Convert.ToUInt16(Index), Data).Tag; + return tag.HasValue ? tag.Value : SqlInt32.Null; + } + } + + public SqlDateTime PowerRemovedDateTime + { + get + { + var powerRemovedDateTime = new Data.EventRecord(Convert.ToUInt16(Index), Data).PowerRemovedDateTime; + return powerRemovedDateTime.HasValue ? powerRemovedDateTime.Value : SqlDateTime.Null; + } + } + + public SqlString CalibrationPointType + { + get + { + var calibrationPointType = new Data.EventRecord(Convert.ToUInt16(Index), Data).CalibrationPointType; + return calibrationPointType.HasValue ? calibrationPointType.Value.ToString() : SqlString.Null; + } + + } + + public SqlString CalibrationMultivariableSensorInput + { + get + { + var calibrationMultivariableSensorInput = new Data.EventRecord(Convert.ToUInt16(Index), Data).CalibrationMultivariableSensorInput; + return calibrationMultivariableSensorInput.HasValue ? calibrationMultivariableSensorInput.Value.ToString() : SqlString.Null; + } + } + + public SqlString CalibrationType + { + get + { + var calibrationType = new Data.EventRecord(Convert.ToUInt16(Index), Data).CalibrationType; + return calibrationType.HasValue ? calibrationType.Value.ToString() : SqlString.Null; + } + } + + public SqlString EventCode + { + get + { + return new Data.EventRecord(Convert.ToUInt16(Index), Data).EventCode.ToString(); + } + } + + public SqlString OperatorId + { + get + { + return new Data.EventRecord(Convert.ToUInt16(Index), Data).OperatorId; + } + } + + public SqlString EventText + { + get + { + return new Data.EventRecord(Convert.ToUInt16(Index), Data).EventText; + } + } + + public SqlBinary OldValue + { + get + { + return new Data.EventRecord(Convert.ToUInt16(Index), Data).OldValue; + } + } + + public SqlSingle FstFloatValue + { + get + { + var fstFloatValue = new Data.EventRecord(Convert.ToUInt16(Index), Data).FstFloatValue; + return fstFloatValue.HasValue ? fstFloatValue.Value : SqlSingle.Null; + } + } + + public SqlBinary NewValue + { + get + { + return new Data.EventRecord(Convert.ToUInt16(Index), Data).NewValue; + } + } + + public Parameter OldParameterValue + { + get + { + if (!PointType.IsNull && !ParameterNumber.IsNull) + { + var pointType = PointType.Value; + var parameterNumber = ParameterNumber.Value; + var parameterDefinition = ParameterDatabase.ParameterDefinitions.Where(pd => pd.PointType == pointType && pd.Parameter == parameterNumber).FirstOrDefault(); + switch (parameterDefinition.DataType) + { + case "AC": + switch (parameterDefinition.Length) + { + case 3: + return new Parameter() { RawType = ParameterType.AC3, RawValue = OldValue.Value.Take(3).ToArray() }; + default: + return Parameter.Null; + } + case "BIN": + return new Parameter() { RawType = ParameterType.BIN, RawValue = OldValue.Value.Take(1).ToArray() }; + case "FL": + return new Parameter() { RawType = ParameterType.FL, RawValue = OldValue.Value }; + case "INT16": + return new Parameter() { RawType = ParameterType.INT16, RawValue = OldValue.Value.Take(2).ToArray() }; + case "INT32": + return new Parameter() { RawType = ParameterType.INT32, RawValue = OldValue.Value }; + case "INT8": + return new Parameter() { RawType = ParameterType.INT8, RawValue = OldValue.Value.Take(1).ToArray() }; + case "TLP": + return new Parameter() { RawType = ParameterType.TLP, RawValue = OldValue.Value.Take(3).ToArray() }; + case "UINT16": + return new Parameter() { RawType = ParameterType.UINT16, RawValue = OldValue.Value.Take(2).ToArray() }; + case "UINT32": + return new Parameter() { RawType = ParameterType.UINT32, RawValue = OldValue.Value }; + case "TIME": + return new Parameter() { RawType = ParameterType.TIME, RawValue = OldValue.Value }; + case "UINT8": + return new Parameter() { RawType = ParameterType.UINT8, RawValue = OldValue.Value.Take(1).ToArray() }; + default: + return Parameter.Null; + } + + } + else + { + return Parameter.Null; + } + } + } + + public Parameter NewParameterValue + { + get + { + if (!PointType.IsNull && !ParameterNumber.IsNull) + { + var pointType = PointType.Value; + var parameterNumber = ParameterNumber.Value; + var parameterDefinition = ParameterDatabase.ParameterDefinitions.Where(pd => pd.PointType == pointType && pd.Parameter == parameterNumber).FirstOrDefault(); + switch (parameterDefinition.DataType) + { + case "AC": + switch (parameterDefinition.Length) + { + case 3: + return new Parameter() { RawType = ParameterType.AC3, RawValue = NewValue.Value.Take(3).ToArray() }; + case 7: + return new Parameter() { RawType = ParameterType.AC7, RawValue = NewValue.Value.Union(new byte[3]).ToArray() }; + case 10: + return new Parameter() { RawType = ParameterType.AC10, RawValue = OldValue.Value.Union(NewValue.Value).Union(BitConverter.GetBytes(Convert.ToUInt16(Tag.Value))).ToArray() }; + case 12: + return new Parameter() { RawType = ParameterType.AC12, RawValue = OldValue.Value.Union(NewValue.Value).Union(BitConverter.GetBytes(Convert.ToUInt16(Tag.Value))).Union(new byte[2]).ToArray() }; + case 20: + return new Parameter() { RawType = ParameterType.AC20, RawValue = OldValue.Value.Union(NewValue.Value).Union(BitConverter.GetBytes(Convert.ToUInt16(Tag.Value))).Union(new byte[10]).ToArray() }; + case 30: + return new Parameter() { RawType = ParameterType.AC30, RawValue = OldValue.Value.Union(NewValue.Value).Union(BitConverter.GetBytes(Convert.ToUInt16(Tag.Value))).Union(new byte[20]).ToArray() }; + case 40: + return new Parameter() { RawType = ParameterType.AC40, RawValue = OldValue.Value.Union(NewValue.Value).Union(BitConverter.GetBytes(Convert.ToUInt16(Tag.Value))).Union(new byte[30]).ToArray() }; + default: + return Parameter.Null; + } + case "BIN": + return new Parameter() { RawType = ParameterType.BIN, RawValue = NewValue.Value.Take(1).ToArray() }; + case "FL": + return new Parameter() { RawType = ParameterType.FL, RawValue = NewValue.Value }; + case "INT16": + return new Parameter() { RawType = ParameterType.INT16, RawValue = NewValue.Value.Take(2).ToArray() }; + case "INT32": + return new Parameter() { RawType = ParameterType.INT32, RawValue = NewValue.Value }; + case "INT8": + return new Parameter() { RawType = ParameterType.INT8, RawValue = NewValue.Value.Take(1).ToArray() }; + case "TLP": + return new Parameter() { RawType = ParameterType.TLP, RawValue = NewValue.Value.Take(3).ToArray() }; + case "UINT16": + return new Parameter() { RawType = ParameterType.UINT16, RawValue = NewValue.Value.Take(2).ToArray() }; + case "UINT32": + return new Parameter() { RawType = ParameterType.UINT32, RawValue = NewValue.Value }; + case "TIME": + return new Parameter() { RawType = ParameterType.TIME, RawValue = NewValue.Value }; + case "UINT8": + return new Parameter() { RawType = ParameterType.UINT8, RawValue = NewValue.Value.Take(1).ToArray() }; + default: + return Parameter.Null; + } + + } + else + { + return Parameter.Null; + } + } + } + + #endregion + + #region Helper Methods + + public static EventRecord Parse(SqlString stringToParse) + { + var parsedEventRecord = stringToParse.Value.Split(",".ToCharArray()); + var base64Bytes = Convert.FromBase64String(parsedEventRecord[1]); + if (base64Bytes.Length == 22) + { + return new EventRecord() { Index = ushort.Parse(parsedEventRecord[0]), Data = base64Bytes }; + } + else + { + throw new ArgumentException("Input must be exactly 22 bytes"); + } + } + + public override string ToString() + { + return string.Format("{0},{1}", Index, Convert.ToBase64String(Data)); + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + Index = binaryReader.ReadInt32(); + if (!IsNull) + { + Data = binaryReader.ReadBytes(22); + } + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Index); + if (!IsNull) + { + binaryWriter.Write(Data, 0, 22); + } + } + + #endregion + + } + +} diff --git a/DeviceSQL.SQLTypes.ROC/EventRecordArray.cs b/DeviceSQL.SQLTypes.ROC/EventRecordArray.cs new file mode 100644 index 0000000..fce59aa --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/EventRecordArray.cs @@ -0,0 +1,162 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct EventRecordArray : INullable, IBinarySerialize + { + + #region Fields + + internal List eventRecords; + + #endregion + + #region Properties + + internal EventRecord this[int index] + { + get + { + return EventRecords[index]; + } + set + { + EventRecords[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return EventRecords.Count; + } + } + + #endregion + + #region Helper Methods + + private List EventRecords + { + get + { + if (eventRecords == null) + { + eventRecords = new List(); + } + return eventRecords; + } + } + + public static EventRecordArray Null + { + get + { + return (new EventRecordArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", EventRecords.Select(parameter => parameter.ToString())); + } + + public EventRecordArray AddEventRecord(EventRecord eventRecord) + { + EventRecords.Add(eventRecord); + return this; + } + + public static EventRecordArray Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedROCEventRecords = new EventRecordArray(); + parsedROCEventRecords.eventRecords = new List(); + var parsedString = stringToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedString.Length > i; i++) + { + parsedROCEventRecords.eventRecords.Add(EventRecord.Parse(parsedString[i])); + } + + return parsedROCEventRecords; + } + + public EventRecord GetEventRecord(SqlInt32 index) + { + return EventRecords[index.Value]; + } + + public static EventRecordArray Empty() + { + var eventRecordArray = new EventRecordArray { eventRecords = new List() }; + return eventRecordArray; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + EventRecords.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var eventRecord = new EventRecord(); + eventRecord.Read(binaryReader); + EventRecords.Add(eventRecord); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; EventRecords.Count > i; i++) + { + EventRecords[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.ROC/FSTInformation.cs b/DeviceSQL.SQLTypes.ROC/FSTInformation.cs new file mode 100644 index 0000000..28ed7bf --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/FSTInformation.cs @@ -0,0 +1,163 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct FSTInformation : INullable, IBinarySerialize + { + + #region Fields + + private byte fstNumber; + private string version; + private string description; + private byte[] fstCode; + + #endregion + + #region Properties + + public bool IsNull + { + get; + internal set; + } + + public static FSTInformation Null + { + get + { + return new FSTInformation() { IsNull = true }; + } + } + + public byte FSTNumber + { + get + { + return fstNumber; + } + set + { + fstNumber = value; + } + } + + public string Version + { + get + { + return version; + } + set + { + version = value; + } + } + + public string Description + { + get + { + return description; + } + set + { + description = value; + } + } + + public byte[] FSTCode + { + get + { + if (fstCode == null) + { + fstCode = new byte[0]; + } + return fstCode; + } + set + { + fstCode = value; + } + } + + public int Length + { + get + { + return fstCode.Length; + } + } + + public string SHA256Hash + { + get + { + return IO.Channels.HexConverter.ToHexString(System.Security.Cryptography.SHA256.Create().ComputeHash(fstCode)); + } + } + + #endregion + + #region Helper Methods + + public static FSTInformation Parse(SqlString stringToParse) + { + var parsedString = stringToParse.Value.Split(",".ToCharArray()); + var fstNumber = byte.Parse(parsedString[0]); + var version = parsedString[1]; + var description = parsedString[2]; + var fstCode = Convert.FromBase64String(parsedString[3]); + return new FSTInformation() { fstNumber = fstNumber, version = version, description = description, fstCode = fstCode }; + } + + public override string ToString() + { + return string.Format("{0},{1},{2},{3}", FSTNumber, Version, Description, Convert.ToBase64String(FSTCode)); + } + + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + if (!IsNull) + { + fstNumber = binaryReader.ReadByte(); + version = binaryReader.ReadString(); + description = binaryReader.ReadString(); + var fstCodeLength = binaryReader.ReadUInt16(); + fstCode = binaryReader.ReadBytes(fstCodeLength); + } + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + if (!IsNull) + { + binaryWriter.Write(fstNumber); + binaryWriter.Write(version); + binaryWriter.Write(description); + binaryWriter.Write(Convert.ToUInt16(fstCode.Length)); + binaryWriter.Write(fstCode); + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.ROC/HistoryRecord.cs b/DeviceSQL.SQLTypes.ROC/HistoryRecord.cs new file mode 100644 index 0000000..d5a70ef --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/HistoryRecord.cs @@ -0,0 +1,145 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC.Data; +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 11)] + public struct HistoryRecord : INullable, IBinarySerialize + { + + #region Fields + + public byte[] value; + + #endregion + + #region Properties + + public bool IsNull + { + get; + internal set; + } + + public static HistoryRecord Null + { + get + { + return new HistoryRecord() { IsNull = true }; + } + } + + public byte HistorySegment + { + get; + internal set; + } + + public byte HistoryPointNumber + { + get; + internal set; + } + + public int Index + { + get; + internal set; + } + + public byte[] Value + { + get + { + if (value == null) + { + value = new byte[4]; + } + return value; + } + internal set + { + this.value = value; + } + } + + #endregion + + #region Helper Methods + + public static HistoryRecord Parse(SqlString stringToParse) + { + var parsedHistoryRecord = stringToParse.Value.Split(",".ToCharArray()); + var base64Bytes = Convert.FromBase64String(parsedHistoryRecord[3]); + if (base64Bytes.Length == 4) + { + return new HistoryRecord() { Index = ushort.Parse(parsedHistoryRecord[0]), HistorySegment = byte.Parse(parsedHistoryRecord[1]), HistoryPointNumber = byte.Parse(parsedHistoryRecord[2]), value = base64Bytes }; + } + else + { + throw new ArgumentException("Input must be exactly 4 bytes"); + } + } + + public override string ToString() + { + return string.Format("{0},{1},{2},{3}", Index, HistorySegment, HistoryPointNumber, Convert.ToBase64String(Value)); + } + + public SqlDateTime ToDateTimeStamp(DateTime deviceDateTime) + { + var dateTimeStamp = new Data.HistoryRecord() { HistoryPointNumber = this.HistoryPointNumber, HistorySegment = this.HistorySegment, Index = this.Index, Value = this.Value }.ToDateTimeStamp(deviceDateTime); + return dateTimeStamp.HasValue ? dateTimeStamp.Value : SqlDateTime.Null; + } + + public DateTime ToExtendedTimeStamp() + { + return new HistoryRecord() { HistoryPointNumber = this.HistoryPointNumber, HistorySegment = this.HistorySegment, Index = this.Index, Value = this.Value }.ToExtendedTimeStamp(); + } + + public SqlSingle ToFloat() + { + var floatValue = new Data.HistoryRecord() { HistoryPointNumber = this.HistoryPointNumber, HistorySegment = this.HistorySegment, Index = this.Index, Value = this.Value }.ToNullableFloat(); + return floatValue.HasValue ? floatValue.Value : SqlSingle.Null; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + if (!IsNull) + { + Index = binaryReader.ReadInt32(); + HistorySegment = binaryReader.ReadByte(); + HistoryPointNumber = binaryReader.ReadByte(); + Value = binaryReader.ReadBytes(4); + } + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Index); + binaryWriter.Write(HistorySegment); + binaryWriter.Write(HistoryPointNumber); + if (!IsNull) + { + binaryWriter.Write(Value, 0, 4); + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.ROC/HistoryRecordArray.cs b/DeviceSQL.SQLTypes.ROC/HistoryRecordArray.cs new file mode 100644 index 0000000..958a0fe --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/HistoryRecordArray.cs @@ -0,0 +1,162 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct HistoryRecordArray : INullable, IBinarySerialize + { + + #region Fields + + internal List historyRecords; + + #endregion + + #region Properties + + internal HistoryRecord this[int index] + { + get + { + return HistoryRecords[index]; + } + set + { + HistoryRecords[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return HistoryRecords.Count; + } + } + + #endregion + + #region Helper Methods + + private List HistoryRecords + { + get + { + if (historyRecords == null) + { + historyRecords = new List(); + } + return historyRecords; + } + } + + public static HistoryRecordArray Null + { + get + { + return (new HistoryRecordArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", HistoryRecords.Select(parameter => parameter.ToString())); + } + + public HistoryRecordArray AddHistoryRecord(HistoryRecord historyRecord) + { + HistoryRecords.Add(historyRecord); + return this; + } + + public static HistoryRecordArray Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedROCHistoryRecords = new HistoryRecordArray(); + parsedROCHistoryRecords.historyRecords = new List(); + var parsedString = stringToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedString.Length > i; i++) + { + parsedROCHistoryRecords.historyRecords.Add(HistoryRecord.Parse(parsedString[i])); + } + + return parsedROCHistoryRecords; + } + + public HistoryRecord GetHistoryRecord(SqlInt32 index) + { + return HistoryRecords[index.Value]; + } + + public static HistoryRecordArray Empty() + { + var historyRecord = new HistoryRecordArray { historyRecords = new List() }; + return historyRecord; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + HistoryRecords.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var historyRecord = new HistoryRecord(); + historyRecord.Read(binaryReader); + HistoryRecords.Add(historyRecord); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; HistoryRecords.Count > i; i++) + { + HistoryRecords[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.ROC/Parameter.cs b/DeviceSQL.SQLTypes.ROC/Parameter.cs new file mode 100644 index 0000000..d4c1492 --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/Parameter.cs @@ -0,0 +1,464 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC.Data; + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 61)] + public struct Parameter : INullable, IBinarySerialize + { + + #region Fields + + private byte parameterType; + private byte[] rawValue; + + #endregion + + #region Properties + + public bool IsNull + { + get; + private set; + } + + public static Parameter Null + { + get + { + return (new Parameter() { IsNull = true }); + } + } + + public byte PointType + { + get; set; + } + + public byte LogicalNumber + { + get; set; + } + + public byte ParameterNumber + { + get; set; + } + + public string Type + { + get + { + return RawType.ToString(); + } + } + + internal ParameterType RawType + { + get + { + return (ParameterType)parameterType; + } + set + { + parameterType = (byte)value; + } + } + + internal byte[] RawValue + { + get + { + if (rawValue == null) + { + switch ((ParameterType)parameterType) + { + case ParameterType.AC3: + rawValue = new byte[3]; + break; + case ParameterType.AC7: + rawValue = new byte[3]; + break; + case ParameterType.AC10: + rawValue = new byte[10]; + break; + case ParameterType.AC12: + rawValue = new byte[12]; + break; + case ParameterType.AC20: + rawValue = new byte[20]; + break; + case ParameterType.AC30: + rawValue = new byte[30]; + break; + case ParameterType.AC40: + rawValue = new byte[40]; + break; + case ParameterType.BIN: + rawValue = new byte[1]; + break; + case ParameterType.FL: + rawValue = new byte[4]; + break; + case ParameterType.DOUBLE: + rawValue = new byte[8]; + break; + case ParameterType.INT16: + rawValue = new byte[2]; + break; + case ParameterType.INT32: + rawValue = new byte[4]; + break; + case ParameterType.INT8: + rawValue = new byte[1]; + break; + case ParameterType.TLP: + rawValue = new byte[3]; + break; + case ParameterType.UINT16: + rawValue = new byte[2]; + break; + case ParameterType.UINT32: + rawValue = new byte[4]; + break; + case ParameterType.TIME: + rawValue = new byte[4]; + break; + case ParameterType.UINT8: + rawValue = new byte[10]; + break; + } + } + + return rawValue; + } + set + { + rawValue = value; + } + } + + #endregion + + #region Helper Methods + + public override string ToString() + { + if (this.IsNull) + { + return "NULL"; + } + else + { + switch ((ParameterType)parameterType) + { + case ParameterType.AC3: + return (new Ac3Parameter() { Data = RawValue }).Value; + case ParameterType.AC7: + return (new Ac7Parameter() { Data = RawValue }).Value; + case ParameterType.AC10: + return (new Ac10Parameter() { Data = RawValue }).Value; + case ParameterType.AC12: + return (new Ac12Parameter() { Data = RawValue }).Value; + case ParameterType.AC20: + return (new Ac20Parameter() { Data = RawValue }).Value; + case ParameterType.AC30: + return (new Ac30Parameter() { Data = RawValue }).Value; + case ParameterType.AC40: + return (new Ac40Parameter() { Data = RawValue }).Value; + case ParameterType.BIN: + return (new BinParameter() { Data = RawValue }).Value.ToString(); + case ParameterType.FL: + return (new FlpParameter() { Data = RawValue }).Value.ToString(); + case ParameterType.DOUBLE: + return (new DoubleParameter() { Data = RawValue }).Value.ToString(); + case ParameterType.INT16: + return (new Int16Parameter() { Data = RawValue }).Value.ToString(); + case ParameterType.INT32: + return (new Int32Parameter() { Data = RawValue }).Value.ToString(); + case ParameterType.INT8: + return (new Int8Parameter() { Data = RawValue }).Value.ToString(); + case ParameterType.TLP: + { + var tlpParameter = new TlpParameter() { Data = RawValue }; + return string.Format("{0}.{1}.{2}", tlpParameter.Value.PointType.ToString(), tlpParameter.Value.LogicalNumber.ToString(), tlpParameter.Value.Parameter.ToString()); + } + case ParameterType.UINT16: + return (new UInt16Parameter() { Data = RawValue }).Value.ToString(); + case ParameterType.UINT32: + return (new Int32Parameter() { Data = RawValue }).Value.ToString(); + case ParameterType.TIME: + return (new TimeParameter() { Data = RawValue }).Value.ToString(); + case ParameterType.UINT8: + return (new UInt8Parameter() { Data = RawValue }).Value.ToString(); + default: + return "NULL"; + } + } + } + + public SqlByte ToBin() + { + return (new BinParameter() { Data = RawValue }).Value; + } + + public SqlByte ToUInt8() + { + return (new UInt8Parameter() { Data = RawValue }).Value; + } + + public SqlInt16 ToInt8() + { + return (new Int8Parameter() { Data = RawValue }).Value; + } + + public SqlInt16 ToInt16() + { + return (new Int16Parameter() { Data = RawValue }).Value; + } + public SqlInt32 ToUInt16() + { + return (new UInt16Parameter() { Data = RawValue }).Value; + } + + public SqlInt32 ToInt32() + { + return (new Int32Parameter() { Data = RawValue }).Value; + } + + public SqlInt64 ToUInt32() + { + return (new UInt32Parameter() { Data = RawValue }).Value; + } + + public SqlDateTime ToTime() + { + return (new TimeParameter() { Data = RawValue }).Value; + } + + public SqlSingle ToFl() + { + var flpValue = new FlpParameter() { Data = RawValue }.NullableValue; + return flpValue.HasValue ? flpValue.Value : SqlSingle.Null; + } + + public SqlDouble ToDouble() + { + var doubleValue = new DoubleParameter() { Data = RawValue }.NullableValue; + return doubleValue.HasValue ? doubleValue.Value : SqlDouble.Null; + } + + public static Parameter Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedROCPointData = stringToParse.Value.Split(",".ToCharArray()); + var parsedROCParameter = new Parameter() { PointType = byte.Parse(parsedROCPointData[0]), LogicalNumber = byte.Parse(parsedROCPointData[1]), ParameterNumber = byte.Parse(parsedROCPointData[2]) }; + + parsedROCParameter.parameterType = (byte)((ParameterType)Enum.Parse(typeof(ParameterType), parsedROCPointData[3])); + + switch (parsedROCPointData[3]) + { + case "AC3": + parsedROCParameter.rawValue = (new Ac3Parameter() { Value = parsedROCPointData[4] }).Data; + break; + case "AC7": + parsedROCParameter.rawValue = (new Ac7Parameter() { Value = parsedROCPointData[4] }).Data; + break; + case "AC10": + parsedROCParameter.rawValue = (new Ac10Parameter() { Value = parsedROCPointData[4] }).Data; + break; + case "AC12": + parsedROCParameter.rawValue = (new Ac12Parameter() { Value = parsedROCPointData[4] }).Data; + break; + case "AC20": + parsedROCParameter.rawValue = (new Ac20Parameter() { Value = parsedROCPointData[4] }).Data; + break; + case "AC30": + parsedROCParameter.rawValue = (new Ac30Parameter() { Value = parsedROCPointData[4] }).Data; + break; + case "AC40": + parsedROCParameter.rawValue = (new Ac40Parameter() { Value = parsedROCPointData[4] }).Data; + break; + case "BIN": + parsedROCParameter.rawValue = (new BinParameter() { Value = byte.Parse(parsedROCPointData[4]) }).Data; + break; + case "FL": + parsedROCParameter.rawValue = (new FlpParameter() { Value = float.Parse(parsedROCPointData[4]) }).Data; + break; + case "DOUBLE": + parsedROCParameter.rawValue = (new DoubleParameter() { Value = double.Parse(parsedROCPointData[8]) }).Data; + break; + case "INT16": + parsedROCParameter.rawValue = (new Int16Parameter() { Value = short.Parse(parsedROCPointData[4]) }).Data; + break; + case "INT32": + parsedROCParameter.rawValue = (new Int32Parameter() { Value = int.Parse(parsedROCPointData[4]) }).Data; + break; + case "Int8": + parsedROCParameter.rawValue = (new Int8Parameter() { Value = SByte.Parse(parsedROCPointData[4]) }).Data; + break; + case "TLP": + { + var parsedTlp = parsedROCPointData[4].Split(".".ToCharArray()); + parsedROCParameter.rawValue = (new TlpParameter() { Value = new Tlp(byte.Parse(parsedTlp[0]), byte.Parse(parsedTlp[1]), byte.Parse(parsedTlp[2])) }).Data; + } + break; + case "UINT16": + parsedROCParameter.rawValue = (new UInt16Parameter() { Value = ushort.Parse(parsedROCPointData[4]) }).Data; + break; + case "UINT32": + parsedROCParameter.rawValue = (new UInt32Parameter() { Value = uint.Parse(parsedROCPointData[4]) }).Data; + break; + case "TIME": + parsedROCParameter.rawValue = (new TimeParameter() { Value = (new DateTime(1970, 01, 01).AddSeconds(uint.Parse(parsedROCPointData[4]))) }).Data; + break; + case "UINT8": + parsedROCParameter.rawValue = (new UInt8Parameter() { Value = byte.Parse(parsedROCPointData[4]) }).Data; + break; + } + return parsedROCParameter; + } + + public static Parameter ParseTlp(byte pointType, byte logicalNumber, byte parameter, byte pointTypeValue, byte logicalNumberValue, byte parameterValue) + { + return new Parameter() { PointType = pointType, LogicalNumber = logicalNumber, ParameterNumber = parameter, parameterType = (byte)ParameterType.TLP, rawValue = (new TlpParameter() { Value = new Tlp(pointTypeValue, logicalNumberValue, parameterValue) }).Data }; + } + + public static Parameter ParseAc3(byte pointType, byte logicalNumber, byte parameter, string value) + { + return new Parameter() { PointType = pointType, LogicalNumber = logicalNumber, ParameterNumber = parameter, parameterType = (byte)ParameterType.AC3, rawValue = (new Ac3Parameter() { Value = value }).Data }; + } + + public static Parameter ParseAc7(byte pointType, byte logicalNumber, byte parameter, string value) + { + return new Parameter() { PointType = pointType, LogicalNumber = logicalNumber, ParameterNumber = parameter, parameterType = (byte)ParameterType.AC7, rawValue = (new Ac3Parameter() { Value = value }).Data }; + } + + public static Parameter ParseAc10(byte pointType, byte logicalNumber, byte parameter, string value) + { + return new Parameter() { PointType = pointType, LogicalNumber = logicalNumber, ParameterNumber = parameter, parameterType = (byte)ParameterType.AC10, rawValue = (new Ac10Parameter() { Value = value }).Data }; + } + + public static Parameter ParseAc12(byte pointType, byte logicalNumber, byte parameter, string value) + { + return new Parameter() { PointType = pointType, LogicalNumber = logicalNumber, ParameterNumber = parameter, parameterType = (byte)ParameterType.AC12, rawValue = (new Ac12Parameter() { Value = value }).Data }; + } + + public static Parameter ParseAc20(byte pointType, byte logicalNumber, byte parameter, string value) + { + return new Parameter() { PointType = pointType, LogicalNumber = logicalNumber, ParameterNumber = parameter, parameterType = (byte)ParameterType.AC20, rawValue = (new Ac20Parameter() { Value = value }).Data }; + } + + public static Parameter ParseAc30(byte pointType, byte logicalNumber, byte parameter, string value) + { + return new Parameter() { PointType = pointType, LogicalNumber = logicalNumber, ParameterNumber = parameter, parameterType = (byte)ParameterType.AC30, rawValue = (new Ac30Parameter() { Value = value }).Data }; + } + + public static Parameter ParseAc40(byte pointType, byte logicalNumber, byte parameter, string value) + { + return new Parameter() { PointType = pointType, LogicalNumber = logicalNumber, ParameterNumber = parameter, parameterType = (byte)ParameterType.AC40, rawValue = (new Ac40Parameter() { Value = value }).Data }; + } + + public static Parameter ParseBin(byte pointType, byte logicalNumber, byte parameter, byte value) + { + return new Parameter() { PointType = pointType, LogicalNumber = logicalNumber, ParameterNumber = parameter, parameterType = (byte)ParameterType.BIN, rawValue = (new BinParameter() { Value = value }).Data }; + } + + public static Parameter ParseInt8(byte pointType, byte logicalNumber, byte parameter, short value) + { + return new Parameter() { PointType = pointType, LogicalNumber = logicalNumber, ParameterNumber = parameter, parameterType = (byte)ParameterType.INT8, rawValue = (new Int8Parameter() { Value = Convert.ToSByte(value) }).Data }; + } + + public static Parameter ParseUInt8(byte pointType, byte logicalNumber, byte parameter, byte value) + { + return new Parameter() { PointType = pointType, LogicalNumber = logicalNumber, ParameterNumber = parameter, parameterType = (byte)ParameterType.UINT8, rawValue = (new UInt8Parameter() { Value = value }).Data }; + } + + public static Parameter ParseInt16(byte pointType, byte logicalNumber, byte parameter, short value) + { + return new Parameter() { PointType = pointType, LogicalNumber = logicalNumber, ParameterNumber = parameter, parameterType = (byte)ParameterType.INT16, rawValue = (new Int16Parameter() { Value = value }).Data }; + } + + public static Parameter ParseUInt16(byte pointType, byte logicalNumber, byte parameter, int value) + { + return new Parameter() { PointType = pointType, LogicalNumber = logicalNumber, ParameterNumber = parameter, parameterType = (byte)ParameterType.UINT16, rawValue = (new UInt16Parameter() { Value = Convert.ToUInt16(value) }).Data }; + } + + public static Parameter ParseInt32(byte pointType, byte logicalNumber, byte parameter, int value) + { + return new Parameter() { PointType = pointType, LogicalNumber = logicalNumber, ParameterNumber = parameter, parameterType = (byte)ParameterType.INT32, rawValue = (new Int32Parameter() { Value = value }).Data }; + } + + public static Parameter ParseUInt32(byte pointType, byte logicalNumber, byte parameter, long value) + { + return new Parameter() { PointType = pointType, LogicalNumber = logicalNumber, ParameterNumber = parameter, parameterType = (byte)ParameterType.UINT32, rawValue = (new UInt32Parameter() { Value = Convert.ToUInt32(value) }).Data }; + } + + public static Parameter ParseTime(byte pointType, byte logicalNumber, byte parameter, DateTime value) + { + return new Parameter() { PointType = pointType, LogicalNumber = logicalNumber, ParameterNumber = parameter, parameterType = (byte)ParameterType.TIME, rawValue = (new TimeParameter() { Value = value }).Data }; + } + + public static Parameter ParseFl(byte pointType, byte logicalNumber, byte parameter, float value) + { + return new Parameter() { PointType = pointType, LogicalNumber = logicalNumber, ParameterNumber = parameter, parameterType = (byte)ParameterType.FL, rawValue = (new FlpParameter() { Value = value }).Data }; + } + + public static Parameter ParseDouble(byte pointType, byte logicalNumber, byte parameter, double value) + { + return new Parameter() { PointType = pointType, LogicalNumber = logicalNumber, ParameterNumber = parameter, parameterType = (byte)ParameterType.DOUBLE, rawValue = (new DoubleParameter() { Value = value }).Data }; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + + if (!IsNull) + { + PointType = binaryReader.ReadByte(); + LogicalNumber = binaryReader.ReadByte(); + ParameterNumber = binaryReader.ReadByte(); + parameterType = binaryReader.ReadByte(); + rawValue = new byte[binaryReader.ReadInt32()]; + binaryReader.Read(rawValue, 0, rawValue.Length); + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + + if (!IsNull) + { + binaryWriter.Write(PointType); + binaryWriter.Write(LogicalNumber); + binaryWriter.Write(ParameterNumber); + binaryWriter.Write(parameterType); + binaryWriter.Write(RawValue.Length); + binaryWriter.Write(RawValue); + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.ROC/ParameterArray.cs b/DeviceSQL.SQLTypes.ROC/ParameterArray.cs new file mode 100644 index 0000000..104eec0 --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/ParameterArray.cs @@ -0,0 +1,166 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct ParameterArray : INullable, IBinarySerialize + { + + #region Fields + + private List parameters; + + #endregion + + #region Properties + + internal Parameter this[int index] + { + get + { + return Parameters[index]; + } + set + { + Parameters[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return Parameters.Count; + } + } + + #endregion + + #region Helper Methods + + private List Parameters + { + get + { + if (parameters == null) + { + parameters = new List(); + } + return parameters; + } + } + + public static ParameterArray Null + { + get + { + return (new ParameterArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", Parameters.Select(parameter => parameter.ToString())); + } + + public ParameterArray AddParameter(Parameter parameter) + { + Parameters.Add(parameter); + return this; + } + + public static ParameterArray Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedROCParameterArray = new ParameterArray() + { + parameters = new List() + }; + + var parsedString = stringToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedString.Length > i; i++) + { + parsedROCParameterArray.Parameters.Add(Parameter.Parse(parsedString[i])); + } + + return parsedROCParameterArray; + } + + public Parameter GetParameter(SqlInt32 index) + { + return Parameters[index.Value]; + } + + public static ParameterArray Empty() + { + var rocParameterArray = new ParameterArray() { parameters = new List() }; + return rocParameterArray; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + Parameters.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var parameter = new Parameter(); + parameter.Read(binaryReader); + Parameters.Add(parameter); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; Parameters.Count > i; i++) + { + Parameters[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} diff --git a/DeviceSQL.Utilities.DeploymentScriptFormatter/Properties/AssemblyInfo.cs b/DeviceSQL.SQLTypes.ROC/Properties/AssemblyInfo.cs similarity index 74% rename from DeviceSQL.Utilities.DeploymentScriptFormatter/Properties/AssemblyInfo.cs rename to DeviceSQL.SQLTypes.ROC/Properties/AssemblyInfo.cs index a6d38c3..bbfd0f7 100644 --- a/DeviceSQL.Utilities.DeploymentScriptFormatter/Properties/AssemblyInfo.cs +++ b/DeviceSQL.SQLTypes.ROC/Properties/AssemblyInfo.cs @@ -5,14 +5,15 @@ // 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("DeviceSQL.Utilities.DeploymentScriptFormatter")] -[assembly: AssemblyDescription("")] +[assembly: AssemblyTitle("DeviceSQL.SQLTypes.ROC")] +[assembly: AssemblyDescription("DeviceSQL.SQLTypes.ROC")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("DeviceSQL.Utilities.DeploymentScriptFormatter")] -[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyCompany("CloudSonix")] +[assembly: AssemblyProduct("DeviceSQL")] +[assembly: AssemblyCopyright("© CloudSonix. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] +[assembly: AssemblyKeyFileAttribute("../DeviceSQL-Key.snk")] // 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 @@ -20,7 +21,7 @@ [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("0ea05da7-635f-4018-9f33-0d3419374c9f")] +[assembly: Guid("256ca566-5436-4543-bc13-d2480bee70c2")] // Version information for an assembly consists of the following four values: // diff --git a/DeviceSQL.SQLTypes.ROC/ROCPlusAlarmRecord.cs b/DeviceSQL.SQLTypes.ROC/ROCPlusAlarmRecord.cs new file mode 100644 index 0000000..7d252c8 --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/ROCPlusAlarmRecord.cs @@ -0,0 +1,250 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC.Data; + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 28)] + public struct ROCPlusAlarmRecord : INullable, IBinarySerialize + { + + #region Fields + + private byte[] data; + + #endregion + + #region Properties + + public bool IsNull + { + get; + internal set; + } + + public static ROCPlusAlarmRecord Null + { + get + { + return new ROCPlusAlarmRecord() { IsNull = true }; + } + } + + public byte[] Data + { + get + { + if (data == null) + { + data = new byte[23]; + } + return data; + } + + internal set + { + data = value; + } + } + + public int Index + { + get; + internal set; + } + + public SqlDateTime DateTimeStamp + { + get + { + var dateTimeStamp = new Data.ROCPlusAlarmRecord(Convert.ToUInt16(Index), Data).DateTimeStamp; + return dateTimeStamp.HasValue ? dateTimeStamp.Value : SqlDateTime.Null; + } + } + + public SqlString AlarmSrbxState + { + get + { + return new Data.ROCPlusAlarmRecord(Convert.ToUInt16(Index), Data).AlarmSrbxState.ToString(); + } + } + + public SqlString AlarmCondition + { + get + { + return new Data.ROCPlusAlarmRecord(Convert.ToUInt16(Index), Data).AlarmCondition.ToString(); + } + } + + public SqlString AlarmType + { + get + { + return new Data.ROCPlusAlarmRecord(Convert.ToUInt16(Index), Data).AlarmType.ToString(); + } + } + + public SqlString AlarmCode + { + get + { + var alarmCode = new Data.ROCPlusAlarmRecord(Convert.ToUInt16(Index), Data).AlarmCode; + return alarmCode.HasValue ? alarmCode.Value.ToString() : SqlString.Null; + } + } + + public string AlarmDescription + { + get + { + return new Data.ROCPlusAlarmRecord(Convert.ToUInt16(Index), Data).AlarmDescription; + } + } + + internal Tlp Tlp + { + get + { + return new Data.ROCPlusAlarmRecord(Convert.ToUInt16(Index), Data).Tlp; + } + } + + public SqlByte PointType + { + get + { + return Tlp.PointType; + } + } + + public SqlByte LogicalNumber + { + get + { + return Tlp.LogicalNumber; + } + } + + public SqlByte ParameterNumber + { + get + { + return Tlp.Parameter; + } + } + + public Parameter ParameterValue + { + get + { + if (!PointType.IsNull && !ParameterNumber.IsNull) + { + var pointType = PointType.Value; + var parameterNumber = ParameterNumber.Value; + var parameterDefinition = ParameterDatabase.ParameterDefinitions.Where(pd => pd.PointType == pointType && pd.Parameter == parameterNumber).FirstOrDefault(); + var data = new Data.ROCPlusAlarmRecord(Convert.ToUInt16(Index), Data).data.Skip(19).Take(4).ToArray(); + switch (parameterDefinition.DataType) + { + case "BIN": + return new Parameter() { RawType = ParameterType.BIN, RawValue = data.Take(1).ToArray() }; + case "FL": + return new Parameter() { RawType = ParameterType.FL, RawValue = data }; + case "INT16": + return new Parameter() { RawType = ParameterType.INT16, RawValue = data.Take(2).ToArray() }; + case "INT32": + return new Parameter() { RawType = ParameterType.INT32, RawValue = data }; + case "INT8": + return new Parameter() { RawType = ParameterType.INT8, RawValue = data.Take(1).ToArray() }; + case "TLP": + return new Parameter() { RawType = ParameterType.TLP, RawValue = data.Take(3).ToArray() }; + case "UINT16": + return new Parameter() { RawType = ParameterType.UINT16, RawValue = data.Take(2).ToArray() }; + case "UINT32": + return new Parameter() { RawType = ParameterType.UINT32, RawValue = data }; + case "TIME": + return new Parameter() { RawType = ParameterType.TIME, RawValue = data }; + case "UINT8": + return new Parameter() { RawType = ParameterType.UINT8, RawValue = data.Take(1).ToArray() }; + default: + return Parameter.Null; + } + + } + else + { + return Parameter.Null; + } + } + } + + public SqlSingle Value + { + get + { + var value = new Data.ROCPlusAlarmRecord(Convert.ToUInt16(Index), Data).Value; + return value.HasValue ? value.Value : SqlSingle.Null; + } + } + + #endregion + + #region Helper Methods + + public static ROCPlusAlarmRecord Parse(SqlString stringToParse) + { + var parsedROCPlusAlarmRecord = stringToParse.Value.Split(",".ToCharArray()); + var base64Bytes = Convert.FromBase64String(parsedROCPlusAlarmRecord[1]); + if (base64Bytes.Length == 23) + { + return new ROCPlusAlarmRecord() { Index = ushort.Parse(parsedROCPlusAlarmRecord[0]), Data = base64Bytes }; + } + else + { + throw new ArgumentException("Input must be exactly 23 bytes"); + } + } + + public override string ToString() + { + return string.Format("{0},{1}", Index, Convert.ToBase64String(Data)); + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + Index = binaryReader.ReadInt32(); + if (!IsNull) + { + Data = binaryReader.ReadBytes(23); + } + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Index); + if (!IsNull) + { + binaryWriter.Write(Data, 0, 23); + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.ROC/ROCPlusAlarmRecordArray.cs b/DeviceSQL.SQLTypes.ROC/ROCPlusAlarmRecordArray.cs new file mode 100644 index 0000000..36f629c --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/ROCPlusAlarmRecordArray.cs @@ -0,0 +1,162 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct ROCPlusAlarmRecordArray : INullable, IBinarySerialize + { + + #region Fields + + internal List rocPlusAlarmRecords; + + #endregion + + #region Properties + + internal ROCPlusAlarmRecord this[int index] + { + get + { + return ROCPlusAlarmRecords[index]; + } + set + { + ROCPlusAlarmRecords[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return ROCPlusAlarmRecords.Count; + } + } + + #endregion + + #region Helper Methods + + private List ROCPlusAlarmRecords + { + get + { + if (rocPlusAlarmRecords == null) + { + rocPlusAlarmRecords = new List(); + } + return rocPlusAlarmRecords; + } + } + + public static ROCPlusAlarmRecordArray Null + { + get + { + return (new ROCPlusAlarmRecordArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", ROCPlusAlarmRecords.Select(parameter => parameter.ToString())); + } + + public ROCPlusAlarmRecordArray AddROCPlusAlarmRecord(ROCPlusAlarmRecord rocPlusAlarmRecord) + { + ROCPlusAlarmRecords.Add(rocPlusAlarmRecord); + return this; + } + + public static ROCPlusAlarmRecordArray Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedROCPlusAlarmRecords = new ROCPlusAlarmRecordArray(); + parsedROCPlusAlarmRecords.rocPlusAlarmRecords = new List(); + var parsedString = stringToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedString.Length > i; i++) + { + parsedROCPlusAlarmRecords.rocPlusAlarmRecords.Add(ROCPlusAlarmRecord.Parse(parsedString[i])); + } + + return parsedROCPlusAlarmRecords; + } + + public ROCPlusAlarmRecord GetROCPlusAlarmRecord(SqlInt32 index) + { + return ROCPlusAlarmRecords[index.Value]; + } + + public static ROCPlusAlarmRecordArray Empty() + { + var rocPlusAlarmRecord = new ROCPlusAlarmRecordArray { rocPlusAlarmRecords = new List() }; + return rocPlusAlarmRecord; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + ROCPlusAlarmRecords.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var rocPLusAlarmRecord = new ROCPlusAlarmRecord(); + rocPLusAlarmRecord.Read(binaryReader); + ROCPlusAlarmRecords.Add(rocPLusAlarmRecord); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; ROCPlusAlarmRecords.Count > i; i++) + { + ROCPlusAlarmRecords[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.ROC/ROCPlusEventRecord.cs b/DeviceSQL.SQLTypes.ROC/ROCPlusEventRecord.cs new file mode 100644 index 0000000..c21ced7 --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/ROCPlusEventRecord.cs @@ -0,0 +1,363 @@ +#region Imported Types + +using DeviceSQL.SQLTypes.ROC.Data; + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 27)] + public struct ROCPlusEventRecord : INullable, IBinarySerialize + { + + #region Fields + + private byte[] data; + + #endregion + + #region Properties + + public bool IsNull + { + get; + internal set; + } + + public static ROCPlusEventRecord Null + { + get + { + return new ROCPlusEventRecord() { IsNull = true }; + } + } + + public byte[] Data + { + get + { + if (data == null) + { + data = new byte[22]; + } + return data; + } + + internal set + { + data = value; + } + } + + public int Index + { + get; + internal set; + } + + public SqlDateTime DateTimeStamp + { + get + { + var dateTimeStamp = new Data.ROCPlusEventRecord(Convert.ToUInt16(Index), Data).DateTimeStamp; + return dateTimeStamp.HasValue ? dateTimeStamp.Value : SqlDateTime.Null; + } + } + + public SqlString EventType + { + get + { + return new Data.ROCPlusEventRecord(Convert.ToUInt16(Index), Data).EventType.ToString(); + } + } + + public SqlString EventCode + { + get + { + var eventCode = new Data.ROCPlusEventRecord(Convert.ToUInt16(Index), Data).EventCode; + return eventCode.HasValue ? eventCode.Value.ToString() : SqlString.Null; + } + } + + public string OperatorId + { + get + { + return new Data.ROCPlusEventRecord(Convert.ToUInt16(Index), Data).OperatorId; + } + } + + internal Tlp Tlp + { + get + { + return new Data.ROCPlusEventRecord(Convert.ToUInt16(Index), Data).Tlp; + } + } + + public SqlByte PointType + { + get + { + return Tlp.PointType; + } + } + + public SqlByte LogicalNumber + { + get + { + return Tlp.LogicalNumber; + } + } + + public SqlByte Parameter + { + get + { + return Tlp.Parameter; + } + } + + public SqlString DataType + { + get + { + var dataType = new Data.ROCPlusEventRecord(Convert.ToUInt16(Index), Data).DataType; + return dataType.HasValue ? dataType.Value.ToString() : SqlString.Null; + } + } + + public SqlBinary OldValue + { + get + { + return new Data.ROCPlusEventRecord(Convert.ToUInt16(Index), Data).OldValue; + } + } + + public SqlBinary NewValue + { + get + { + return new Data.ROCPlusEventRecord(Convert.ToUInt16(Index), Data).NewValue; + } + } + + public SqlInt32 Spare + { + get + { + return new Data.ROCPlusEventRecord(Convert.ToUInt16(Index), Data).Spare; + } + } + + public SqlString Description + { + get + { + return new Data.ROCPlusEventRecord(Convert.ToUInt16(Index), Data).Description; + } + } + + public SqlByte FstNumber + { + get + { + var fstNumber = new Data.ROCPlusEventRecord(Convert.ToUInt16(Index), Data).FstNumber; + return fstNumber.HasValue ? fstNumber.Value : SqlByte.Null; + } + } + + public SqlSingle FstValue + { + get + { + var fstValue = new Data.ROCPlusEventRecord(Convert.ToUInt16(Index), Data).FstValue; + return fstValue.HasValue ? fstValue.Value : SqlSingle.Null; + } + } + + public SqlDateTime DateTimeValue + { + get + { + var dateTimeValue = new Data.ROCPlusEventRecord(Convert.ToUInt16(Index), Data).DateTimeValue; + return dateTimeValue.HasValue ? dateTimeValue.Value : SqlDateTime.Null; + } + } + + public SqlSingle CalibrationRawValue + { + get + { + var calibrationRawValue = new Data.ROCPlusEventRecord(Convert.ToUInt16(Index), Data).CalibrationRawValue; + return calibrationRawValue.HasValue ? calibrationRawValue.Value : SqlSingle.Null; + } + } + + public SqlSingle CalibrationCalibratedValue + { + get + { + var calibrationCalibratedValue = new Data.ROCPlusEventRecord(Convert.ToUInt16(Index), Data).CalibrationCalibratedValue; + return calibrationCalibratedValue.HasValue ? calibrationCalibratedValue.Value : SqlSingle.Null; + } + } + + public Parameter OldParameterValue + { + get + { + if (!PointType.IsNull && !Parameter.IsNull) + { + switch (new Data.ROCPlusEventRecord(Convert.ToUInt16(Index), Data).DataType) + { + case ParameterType.AC3: + return new Parameter() { RawType = ParameterType.AC3, RawValue = OldValue.Value.Take(3).ToArray() }; + case ParameterType.BIN: + return new Parameter() { RawType = ParameterType.BIN, RawValue = OldValue.Value.Take(1).ToArray() }; + case ParameterType.FL: + return new Parameter() { RawType = ParameterType.FL, RawValue = OldValue.Value }; + case ParameterType.INT16: + return new Parameter() { RawType = ParameterType.INT16, RawValue = OldValue.Value.Take(2).ToArray() }; + case ParameterType.INT32: + return new Parameter() { RawType = ParameterType.INT32, RawValue = OldValue.Value }; + case ParameterType.INT8: + return new Parameter() { RawType = ParameterType.INT8, RawValue = OldValue.Value.Take(1).ToArray() }; + case ParameterType.TLP: + return new Parameter() { RawType = ParameterType.TLP, RawValue = OldValue.Value.Take(3).ToArray() }; + case ParameterType.UINT16: + return new Parameter() { RawType = ParameterType.UINT16, RawValue = OldValue.Value.Take(2).ToArray() }; + case ParameterType.UINT32: + return new Parameter() { RawType = ParameterType.UINT32, RawValue = OldValue.Value }; + case ParameterType.TIME: + return new Parameter() { RawType = ParameterType.TIME, RawValue = OldValue.Value }; + case ParameterType.UINT8: + return new Parameter() { RawType = ParameterType.UINT8, RawValue = OldValue.Value.Take(1).ToArray() }; + default: + return ROC.Parameter.Null; + } + } + else + { + return ROC.Parameter.Null; + } + } + } + + public Parameter NewParameterValue + { + get + { + if (!PointType.IsNull && !Parameter.IsNull) + { + switch (new Data.ROCPlusEventRecord(Convert.ToUInt16(Index), Data).DataType) + { + case ParameterType.AC3: + return new Parameter() { RawType = ParameterType.AC3, RawValue = NewValue.Value.Take(3).ToArray() }; + case ParameterType.AC7: + return new Parameter() { RawType = ParameterType.AC7, RawValue = NewValue.Value.Union(new byte[3]).ToArray() }; + case ParameterType.AC10: + return new Parameter() { RawType = ParameterType.AC10, RawValue = NewValue.Value.Union(OldValue.Value).Union(BitConverter.GetBytes(Convert.ToUInt16(Spare.Value))).ToArray() }; + case ParameterType.AC12: + return new Parameter() { RawType = ParameterType.AC12, RawValue = NewValue.Value.Union(OldValue.Value).Union(BitConverter.GetBytes(Convert.ToUInt16(Spare.Value))).Union(new byte[2]).ToArray() }; + case ParameterType.AC20: + return new Parameter() { RawType = ParameterType.AC20, RawValue = NewValue.Value.Union(OldValue.Value).Union(BitConverter.GetBytes(Convert.ToUInt16(Spare.Value))).Union(new byte[10]).ToArray() }; + case ParameterType.AC30: + return new Parameter() { RawType = ParameterType.AC30, RawValue = NewValue.Value.Union(OldValue.Value).Union(BitConverter.GetBytes(Convert.ToUInt16(Spare.Value))).Union(new byte[20]).ToArray() }; + case ParameterType.AC40: + return new Parameter() { RawType = ParameterType.AC40, RawValue = NewValue.Value.Union(OldValue.Value).Union(BitConverter.GetBytes(Convert.ToUInt16(Spare.Value))).Union(new byte[30]).ToArray() }; + case ParameterType.BIN: + return new Parameter() { RawType = ParameterType.BIN, RawValue = NewValue.Value.Take(1).ToArray() }; + case ParameterType.FL: + return new Parameter() { RawType = ParameterType.FL, RawValue = NewValue.Value }; + case ParameterType.DOUBLE: + return new Parameter() { RawType = ParameterType.DOUBLE, RawValue = NewValue.Value.Union(OldValue.Value).ToArray() }; + case ParameterType.INT16: + return new Parameter() { RawType = ParameterType.INT16, RawValue = NewValue.Value.Take(2).ToArray() }; + case ParameterType.INT32: + return new Parameter() { RawType = ParameterType.INT32, RawValue = NewValue.Value }; + case ParameterType.INT8: + return new Parameter() { RawType = ParameterType.INT8, RawValue = NewValue.Value.Take(1).ToArray() }; + case ParameterType.TLP: + return new Parameter() { RawType = ParameterType.TLP, RawValue = NewValue.Value.Take(3).ToArray() }; + case ParameterType.UINT16: + return new Parameter() { RawType = ParameterType.UINT16, RawValue = NewValue.Value.Take(2).ToArray() }; + case ParameterType.UINT32: + return new Parameter() { RawType = ParameterType.UINT32, RawValue = NewValue.Value }; + case ParameterType.TIME: + return new Parameter() { RawType = ParameterType.TIME, RawValue = NewValue.Value }; + case ParameterType.UINT8: + return new Parameter() { RawType = ParameterType.UINT8, RawValue = NewValue.Value.Take(1).ToArray() }; + default: + return ROC.Parameter.Null; + } + } + else + { + return ROC.Parameter.Null; + } + } + } + + #endregion + + #region Helper Methods + + public static ROCPlusEventRecord Parse(SqlString stringToParse) + { + var parsedEventRecord = stringToParse.Value.Split(",".ToCharArray()); + var base64Bytes = Convert.FromBase64String(parsedEventRecord[1]); + if (base64Bytes.Length == 22) + { + return new ROCPlusEventRecord() { Index = ushort.Parse(parsedEventRecord[0]), Data = base64Bytes }; + } + else + { + throw new ArgumentException("Input must be exactly 22 bytes"); + } + } + + public override string ToString() + { + return string.Format("{0},{1}", Index, Convert.ToBase64String(Data)); + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + Index = binaryReader.ReadInt32(); + if (!IsNull) + { + Data = binaryReader.ReadBytes(22); + } + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Index); + if (!IsNull) + { + binaryWriter.Write(Data, 0, 22); + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.ROC/ROCPlusEventRecordArray.cs b/DeviceSQL.SQLTypes.ROC/ROCPlusEventRecordArray.cs new file mode 100644 index 0000000..bb925cc --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/ROCPlusEventRecordArray.cs @@ -0,0 +1,162 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct ROCPlusEventRecordArray : INullable, IBinarySerialize + { + + #region Fields + + internal List rocPlusEventRecords; + + #endregion + + #region Properties + + internal ROCPlusEventRecord this[int index] + { + get + { + return ROCPlusEventRecords[index]; + } + set + { + ROCPlusEventRecords[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return ROCPlusEventRecords.Count; + } + } + + #endregion + + #region Helper Methods + + private List ROCPlusEventRecords + { + get + { + if (rocPlusEventRecords == null) + { + rocPlusEventRecords = new List(); + } + return rocPlusEventRecords; + } + } + + public static ROCPlusEventRecordArray Null + { + get + { + return (new ROCPlusEventRecordArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", ROCPlusEventRecords.Select(parameter => parameter.ToString())); + } + + public ROCPlusEventRecordArray AddROCPlusEventRecord(ROCPlusEventRecord rocPlusEventRecord) + { + ROCPlusEventRecords.Add(rocPlusEventRecord); + return this; + } + + public static ROCPlusEventRecordArray Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedROCPlusEventRecords = new ROCPlusEventRecordArray(); + parsedROCPlusEventRecords.rocPlusEventRecords = new List(); + var parsedString = stringToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedString.Length > i; i++) + { + parsedROCPlusEventRecords.rocPlusEventRecords.Add(ROCPlusEventRecord.Parse(parsedString[i])); + } + + return parsedROCPlusEventRecords; + } + + public ROCPlusEventRecord GetROCPlusEventRecord(SqlInt32 index) + { + return ROCPlusEventRecords[index.Value]; + } + + public static EventRecordArray Empty() + { + var eventRecord = new EventRecordArray { eventRecords = new List() }; + return eventRecord; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + ROCPlusEventRecords.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var rocPlusEventRecord = new ROCPlusEventRecord(); + rocPlusEventRecord.Read(binaryReader); + ROCPlusEventRecords.Add(rocPlusEventRecord); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; ROCPlusEventRecords.Count > i; i++) + { + ROCPlusEventRecords[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.ROC/ROCPlusHistoryPointArray.cs b/DeviceSQL.SQLTypes.ROC/ROCPlusHistoryPointArray.cs new file mode 100644 index 0000000..b1b5317 --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/ROCPlusHistoryPointArray.cs @@ -0,0 +1,159 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct ROCPlusHistoryPointArray : INullable, IBinarySerialize + { + + #region Fields + + internal List historyPoints; + + #endregion + + #region Properties + + internal byte this[int index] + { + get + { + return HistoryPoints[index]; + } + set + { + HistoryPoints[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return HistoryPoints.Count; + } + } + + #endregion + + #region Helper Methods + + private List HistoryPoints + { + get + { + if (historyPoints == null) + { + historyPoints = new List(); + } + return historyPoints; + } + } + + public static ROCPlusHistoryPointArray Null + { + get + { + return (new ROCPlusHistoryPointArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", HistoryPoints.Select(parameter => parameter.ToString())); + } + + public ROCPlusHistoryPointArray AddHistoryPoint(byte historyPoint) + { + HistoryPoints.Add(historyPoint); + return this; + } + + public static ROCPlusHistoryPointArray Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedROCPlusHistoryPointArray = new ROCPlusHistoryPointArray(); + parsedROCPlusHistoryPointArray.historyPoints = new List(); + var parsedString = stringToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedString.Length > i; i++) + { + parsedROCPlusHistoryPointArray.HistoryPoints.Add(byte.Parse(parsedString[i])); + } + + return parsedROCPlusHistoryPointArray; + } + + public byte GetHistoryPoint(SqlInt32 index) + { + return HistoryPoints[index.Value]; + } + + public static ROCPlusHistoryPointArray Empty() + { + var rocPlusHistoryPointArray = new ROCPlusHistoryPointArray() { historyPoints = new List() }; + return rocPlusHistoryPointArray; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + HistoryPoints.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + HistoryPoints.Add(binaryReader.ReadByte()); + } + } + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; HistoryPoints.Count > i; i++) + { + binaryWriter.Write(HistoryPoints[i]); + } + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.ROC/ROCPlusHistoryRecord.cs b/DeviceSQL.SQLTypes.ROC/ROCPlusHistoryRecord.cs new file mode 100644 index 0000000..f6af00a --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/ROCPlusHistoryRecord.cs @@ -0,0 +1,157 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Data.SqlTypes; +using System.IO; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = 15)] + public struct ROCPlusHistoryRecord : INullable, IBinarySerialize + { + + #region Fields + + public byte[] value; + + #endregion + + #region Properties + + public bool IsNull + { + get; + internal set; + } + + public bool HasTimeStamp + { + get + { + return Length == 8; + } + } + + public static ROCPlusHistoryRecord Null + { + get + { + return new ROCPlusHistoryRecord() { IsNull = true }; + } + } + + public byte HistorySegment + { + get; + internal set; + } + + public byte HistoryPointNumber + { + get; + internal set; + } + + public int Index + { + get; + internal set; + } + + public int Length + { + get + { + return Value.Length; + } + } + + public byte[] Value + { + get + { + if (value == null) + { + value = new byte[8]; + } + return value; + } + internal set + { + this.value = value; + } + } + + #endregion + + #region Helper Methods + + public SqlDateTime ToDateTimeStamp(DateTime deviceDateTime) + { + var dateTimeStamp = new Data.ROCPlusHistoryRecord() { HistoryPointNumber = this.HistoryPointNumber, HistorySegment = this.HistorySegment, Index = this.Index, Value = this.Value }.DateTimeStamp; + return dateTimeStamp.HasValue ? dateTimeStamp.Value : SqlDateTime.Null; + } + + public SqlSingle ToFloat() + { + var floatValue = new Data.ROCPlusHistoryRecord() { HistoryPointNumber = this.HistoryPointNumber, HistorySegment = this.HistorySegment, Index = this.Index, Value = this.Value }.ToNullableFloat(); + return floatValue.HasValue ? floatValue.Value : SqlSingle.Null; + } + + public static ROCPlusHistoryRecord Parse(SqlString stringToParse) + { + var parsedROCPlusHistoryRecord = stringToParse.Value.Split(",".ToCharArray()); + var base64Bytes = Convert.FromBase64String(parsedROCPlusHistoryRecord[3]); + if (base64Bytes.Length == 8 || base64Bytes.Length == 4) + { + return new ROCPlusHistoryRecord() { Index = ushort.Parse(parsedROCPlusHistoryRecord[0]), HistorySegment = byte.Parse(parsedROCPlusHistoryRecord[1]), HistoryPointNumber = byte.Parse(parsedROCPlusHistoryRecord[2]), value = base64Bytes }; + } + else + { + throw new ArgumentException("Input must be exactly 8 or 4 bytes"); + } + } + + public override string ToString() + { + return string.Format("{0},{1},{2},{3}", Index, HistorySegment, HistoryPointNumber, Convert.ToBase64String(Value)); + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + IsNull = binaryReader.ReadBoolean(); + if (!IsNull) + { + var length = binaryReader.ReadInt32(); + Index = binaryReader.ReadInt32(); + HistorySegment = binaryReader.ReadByte(); + HistoryPointNumber = binaryReader.ReadByte(); + Value = binaryReader.ReadBytes(length); + } + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + if (!IsNull) + { + binaryWriter.Write(Length); + binaryWriter.Write(Index); + binaryWriter.Write(HistorySegment); + binaryWriter.Write(HistoryPointNumber); + binaryWriter.Write(Value, 0, Length); + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes.ROC/ROCPlusHistoryRecordArray.cs b/DeviceSQL.SQLTypes.ROC/ROCPlusHistoryRecordArray.cs new file mode 100644 index 0000000..bd3f74f --- /dev/null +++ b/DeviceSQL.SQLTypes.ROC/ROCPlusHistoryRecordArray.cs @@ -0,0 +1,162 @@ +#region Imported Types + +using Microsoft.SqlServer.Server; +using System; +using System.Collections.Generic; +using System.Data.SqlTypes; +using System.IO; +using System.Linq; + +#endregion + +namespace DeviceSQL.SQLTypes.ROC +{ + [Serializable()] + [SqlUserDefinedType(Format.UserDefined, IsByteOrdered = false, IsFixedLength = false, MaxByteSize = -1)] + public struct ROCPlusHistoryRecordArray : INullable, IBinarySerialize + { + + #region Fields + + internal List rocPlusHistoryRecords; + + #endregion + + #region Properties + + internal ROCPlusHistoryRecord this[int index] + { + get + { + return ROCPlusHistoryRecords[index]; + } + set + { + ROCPlusHistoryRecords[index] = value; + } + } + + public bool IsNull + { + get; + internal set; + } + + public int Length + { + get + { + return ROCPlusHistoryRecords.Count; + } + } + + #endregion + + #region Helper Methods + + private List ROCPlusHistoryRecords + { + get + { + if (rocPlusHistoryRecords == null) + { + rocPlusHistoryRecords = new List(); + } + return rocPlusHistoryRecords; + } + } + + public static ROCPlusHistoryRecordArray Null + { + get + { + return (new ROCPlusHistoryRecordArray() { IsNull = true }); + } + } + + public override string ToString() + { + return string.Join("|", ROCPlusHistoryRecords.Select(parameter => parameter.ToString())); + } + + public ROCPlusHistoryRecordArray AddROCPlusHistoryRecord(ROCPlusHistoryRecord rocPlusHistoryRecord) + { + ROCPlusHistoryRecords.Add(rocPlusHistoryRecord); + return this; + } + + public static ROCPlusHistoryRecordArray Parse(SqlString stringToParse) + { + if (stringToParse.IsNull) + { + return Null; + } + + var parsedROCPlusHistoryRecords = new ROCPlusHistoryRecordArray(); + parsedROCPlusHistoryRecords.rocPlusHistoryRecords = new List(); + var parsedString = stringToParse.Value.Split("|".ToCharArray()); + + for (var i = 0; parsedString.Length > i; i++) + { + parsedROCPlusHistoryRecords.rocPlusHistoryRecords.Add(ROCPlusHistoryRecord.Parse(parsedString[i])); + } + + return parsedROCPlusHistoryRecords; + } + + public ROCPlusHistoryRecord GetROCPlusHistoryRecord(SqlInt32 index) + { + return ROCPlusHistoryRecords[index.Value]; + } + + public static ROCPlusHistoryRecordArray Empty() + { + var rocPlusHistoryRecord = new ROCPlusHistoryRecordArray { rocPlusHistoryRecords = new List() }; + return rocPlusHistoryRecord; + } + + #endregion + + #region Serialization Methods + + public void Read(BinaryReader binaryReader) + { + ROCPlusHistoryRecords.Clear(); + IsNull = binaryReader.ReadBoolean(); + + if (IsNull) + { + return; + } + else + { + var length = binaryReader.ReadInt32(); + + for (var i = 0; length > i; i++) + { + var rocPlusHistoryRecord = new ROCPlusHistoryRecord(); + rocPlusHistoryRecord.Read(binaryReader); + ROCPlusHistoryRecords.Add(rocPlusHistoryRecord); + } + } + + } + + public void Write(BinaryWriter binaryWriter) + { + binaryWriter.Write(IsNull); + binaryWriter.Write(Length); + + if (Length > 0) + { + for (var i = 0; ROCPlusHistoryRecords.Count > i; i++) + { + ROCPlusHistoryRecords[i].Write(binaryWriter); + } + } + } + + #endregion + + } +} diff --git a/DeviceSQL.SQLTypes/DeviceSQL.SQLTypes.csproj b/DeviceSQL.SQLTypes/DeviceSQL.SQLTypes.csproj index 03465fd..94f23de 100644 --- a/DeviceSQL.SQLTypes/DeviceSQL.SQLTypes.csproj +++ b/DeviceSQL.SQLTypes/DeviceSQL.SQLTypes.csproj @@ -9,8 +9,9 @@ Properties DeviceSQL.SQLTypes DeviceSQL.SQLTypes - v4.6.1 + v4.8 512 + true diff --git a/DeviceSQL.SQLTypes/Properties/AssemblyInfo.cs b/DeviceSQL.SQLTypes/Properties/AssemblyInfo.cs index b3df95d..e2577ec 100644 --- a/DeviceSQL.SQLTypes/Properties/AssemblyInfo.cs +++ b/DeviceSQL.SQLTypes/Properties/AssemblyInfo.cs @@ -6,11 +6,11 @@ // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("DeviceSQL.SQLTypes")] -[assembly: AssemblyDescription("")] +[assembly: AssemblyDescription("DeviceSQL.SQLTypes")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("DeviceSQL.SQLTypes")] -[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyCompany("CloudSonix")] +[assembly: AssemblyProduct("DeviceSQL")] +[assembly: AssemblyCopyright("© CloudSonix. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/DeviceSQL.Service/API/ChannelController.cs b/DeviceSQL.Service/API/ChannelController.cs new file mode 100644 index 0000000..629fa43 --- /dev/null +++ b/DeviceSQL.Service/API/ChannelController.cs @@ -0,0 +1,128 @@ +using DeviceSQL.IO.Channels; +using DeviceSQL.Service.IOC; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; +using System.Web.Http; + +namespace DeviceSQL.Service.API +{ + public class ChannelController : ApiController + { + + public ConcurrentDictionary ChannelConcurrentDictionary + { + get + { + return SimpleIOC.Default.GetInstance>(); + } + } + + public EventLog EventLog + { + get + { + return SimpleIOC.Default.GetInstance(); + } + } + + [HttpGet] + [Route("api/Channels/GetChannels")] + public IEnumerable GetChannels() + { + foreach (var channelKeyValuePair in ChannelConcurrentDictionary) + { + yield return channelKeyValuePair.Value; + } + } + + [HttpGet] + [Route("api/Channels/RemoveChannel")] + public void RemoveChannel(string channelName) + { + if (ChannelConcurrentDictionary.TryRemove(channelName, out IChannel channel)) + { + try + { + channel.Dispose(); + } + catch (Exception ex) + { + EventLog.WriteEntry($"Error disposing channel: {ex.Message}", EventLogEntryType.Error); + throw new Exception($"Error disposing channel: {ex.Message}"); + } + } + else + { + EventLog.WriteEntry("Channel does not exist", EventLogEntryType.Error); + throw new Exception("Channel does not exist"); + } + } + + [HttpGet] + [Route("api/Channels/AddTcpChannel")] + public void AddTcpChannel(string channelName, string hostName, int hostPort, int connectionAttempts, int connectionRetryDelay, int readTimeout, int writeTimeout) + { + int currentConnectAttempts = 0; + TcpChannel tcpChannel; + + + + try + { + tcpChannel = new TcpChannel() + { + HostName = hostName, + HostPort = hostPort, + ConnectionAttempts = connectionAttempts, + ConnectionRetryDelay = connectionRetryDelay, + TcpClientReadTimeout = readTimeout, + TcpClientWriteTimeout = writeTimeout + }; + + if (ChannelConcurrentDictionary.TryAdd(channelName, tcpChannel)) + { + + Connect: + currentConnectAttempts++; + + try + { + tcpChannel.TcpClient = new TcpClient(); + tcpChannel.TcpClient.Connect(tcpChannel.HostName, tcpChannel.HostPort); + tcpChannel.ReadTimeout = tcpChannel.TcpClientReadTimeout; + tcpChannel.WriteTimeout = tcpChannel.TcpClientWriteTimeout; + } + catch (SocketException) + { + if (currentConnectAttempts > tcpChannel.ConnectionAttempts) + { + throw new Exception("Unable to connect to host"); + } + else + { + System.Threading.Thread.Sleep(tcpChannel.ConnectionRetryDelay); + goto Connect; + } + } + } + else + { + EventLog.WriteEntry("TCP channel already exists", EventLogEntryType.Error); + throw new Exception("TCP channel already exists"); + } + } + catch (Exception ex) + { + EventLog.WriteEntry($"Error creating TCP channel: {ex.Message}", EventLogEntryType.Error); + throw new Exception($"Error creating TCP channel: {ex.Message}"); + } + } + } +} diff --git a/DeviceSQL.Service/App.config b/DeviceSQL.Service/App.config index 731f6de..f72ba73 100644 --- a/DeviceSQL.Service/App.config +++ b/DeviceSQL.Service/App.config @@ -1,6 +1,30 @@ - + - - - - \ No newline at end of file + + +
+ + + + + + + + + http://localhost:8080 + + + + + + + + + + + + + + + + diff --git a/DeviceSQL.Service/DeviceSQL.Service.csproj b/DeviceSQL.Service/DeviceSQL.Service.csproj index 64c375a..985f3b1 100644 --- a/DeviceSQL.Service/DeviceSQL.Service.csproj +++ b/DeviceSQL.Service/DeviceSQL.Service.csproj @@ -8,9 +8,10 @@ WinExe DeviceSQL.Service DeviceSQL.Service - v4.6.1 + v4.8 512 true + AnyCPU @@ -31,11 +32,46 @@ prompt 4 + + false + + + + + + + ..\packages\Microsoft.Owin.4.0.1\lib\net45\Microsoft.Owin.dll + + + ..\packages\Microsoft.Owin.Diagnostics.4.0.1\lib\net45\Microsoft.Owin.Diagnostics.dll + + + ..\packages\Microsoft.Owin.Host.HttpListener.4.0.1\lib\net45\Microsoft.Owin.Host.HttpListener.dll + + + ..\packages\Microsoft.Owin.Hosting.4.0.1\lib\net45\Microsoft.Owin.Hosting.dll + + + ..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll + + + ..\packages\Owin.1.0\lib\net40\Owin.dll + + + ..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll + + + + ..\packages\Microsoft.AspNet.WebApi.Core.5.2.7\lib\net45\System.Web.Http.dll + + + ..\packages\Microsoft.AspNet.WebApi.Owin.5.2.7\lib\net45\System.Web.Http.Owin.dll + @@ -45,28 +81,73 @@ + + + + Component ProjectInstaller.cs - + Component - - Service1.cs + + DeviceSqlService.cs + + True + True + Settings.settings + + + + + + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + DeviceSqlService.cs + ProjectInstaller.cs + + + {5deadadf-be60-4774-80c6-97b3a83fa289} + DeviceSQL.Devices.Common + + + {0869e7fe-4fac-4fc5-a2a8-313f410cf8cd} + DeviceSQL.Devices.Modbus + + + {af0e4b64-f2c2-4459-a518-9aa905ff6f0f} + DeviceSQL.Devices.ROC + + + {256ca566-5436-4543-bc13-d2480bee70c2} + DeviceSQL.SQLTypes.ROC + + + + + + \ No newline at end of file diff --git a/DeviceSQL.Service/Service1.Designer.cs b/DeviceSQL.Service/DeviceSqlService.Designer.cs similarity index 86% rename from DeviceSQL.Service/Service1.Designer.cs rename to DeviceSQL.Service/DeviceSqlService.Designer.cs index d644fb8..d018be2 100644 --- a/DeviceSQL.Service/Service1.Designer.cs +++ b/DeviceSQL.Service/DeviceSqlService.Designer.cs @@ -1,6 +1,6 @@ namespace DeviceSQL.Service { - partial class Service1 + partial class DeviceSqlService { /// /// Required designer variable. @@ -28,8 +28,11 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - components = new System.ComponentModel.Container(); - this.ServiceName = "Service1"; + // + // DeviceSqlService + // + this.ServiceName = "DeviceSqlSvc"; + } #endregion diff --git a/DeviceSQL.Service/DeviceSqlService.cs b/DeviceSQL.Service/DeviceSqlService.cs new file mode 100644 index 0000000..16f6f98 --- /dev/null +++ b/DeviceSQL.Service/DeviceSqlService.cs @@ -0,0 +1,66 @@ +using DeviceSQL.Device; +using DeviceSQL.IO.Channels; +using DeviceSQL.Service.IOC; +using Microsoft.Owin.Hosting; +using System; +using System.Collections.Concurrent; +using System.Diagnostics; +using System.ServiceProcess; + +namespace DeviceSQL.Service +{ + public partial class DeviceSqlService : ServiceBase + { + + private IDisposable webAppServer = null; + + public DeviceSqlService() + { + InitializeComponent(); + } + + protected override void OnStart(string[] args) + { + SimpleIOC.Default.Register(() => { return new ConcurrentDictionary(); }); + SimpleIOC.Default.Register(() => { return new ConcurrentDictionary(); }); + SimpleIOC.Default.Register(() => { return EventLog; }); + webAppServer = WebApp.Start(url: Properties.Settings.Default.BaseAddress); + } + + protected override void OnStop() + { + if (webAppServer != null) + { + try + { + webAppServer.Dispose(); + } + catch (Exception ex) + { + EventLog.WriteEntry($"Unable to dispose web app server: {ex.Message}", EventLogEntryType.Error); + } + } + + if (SimpleIOC.Default.ContainsCreated>()) + { + + var channelConcurrentDictionary = SimpleIOC.Default.GetInstance>(); + + foreach (var channelKeyValuePair in channelConcurrentDictionary) + { + try + { + channelKeyValuePair.Value.Dispose(); + } + catch (Exception ex) + { + EventLog.WriteEntry($"Unable to dispose channel: {ex.Message}", EventLogEntryType.Error); + } + } + } + + base.OnStop(); + + } + } +} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/Resources.resx b/DeviceSQL.Service/DeviceSqlService.resx similarity index 87% rename from DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/Resources.resx rename to DeviceSQL.Service/DeviceSqlService.resx index af7dbeb..e5858cc 100644 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/Resources.resx +++ b/DeviceSQL.Service/DeviceSqlService.resx @@ -46,7 +46,7 @@ mimetype: application/x-microsoft.net.object.binary.base64 value : The object must be serialized with - : System.Serialization.Formatters.Binary.BinaryFormatter + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : and then encoded with base64 encoding. mimetype: application/x-microsoft.net.object.soap.base64 @@ -60,6 +60,7 @@ : and then encoded with base64 encoding. --> + @@ -68,9 +69,10 @@ - + + @@ -85,9 +87,10 @@ - + + @@ -109,9 +112,12 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + False + \ No newline at end of file diff --git a/DeviceSQL.Service/IOC/ISimpleIOC.cs b/DeviceSQL.Service/IOC/ISimpleIOC.cs new file mode 100644 index 0000000..54fec51 --- /dev/null +++ b/DeviceSQL.Service/IOC/ISimpleIOC.cs @@ -0,0 +1,228 @@ +// **************************************************************************** +// +// Copyright © GalaSoft Laurent Bugnion 2011-2016 +// +// **************************************************************************** +// Laurent Bugnion +// laurent@galasoft.ch +// 10.4.2011 +// GalaSoft.MvvmLight.Extras.Ioc +// http://www.mvvmlight.net +// +// See license.txt in this project or http://www.galasoft.ch/license_MIT.txt +// +// **************************************************************************** + + +using DeviceSQL.Service.ServiceLocation; +using System; +using System.Diagnostics.CodeAnalysis; + + +namespace DeviceSQL.Service.IOC +{ + /// + /// A very simple IOC container with basic functionality needed to register and resolve + /// instances. If needed, this class can be replaced by another more elaborate + /// IOC container implementing the IServiceLocator interface. + /// The inspiration for this class is at https://gist.github.com/716137 but it has + /// been extended with additional features. + /// + //// [ClassInfo(typeof(SimpleIoc))] + [SuppressMessage( + "Microsoft.Naming", + "CA1704:IdentifiersShouldBeSpelledCorrectly", + MessageId = "Ioc")] + public interface ISimpleIOC : IServiceLocator + { + /// + /// Checks whether at least one instance of a given class is already created in the container. + /// + /// The class that is queried. + /// True if at least on instance of the class is already created, false otherwise. + [SuppressMessage( + "Microsoft.Design", + "CA1004:GenericMethodsShouldProvideTypeParameter", + Justification = "This syntax is more convenient than the alternatives.")] + bool ContainsCreated(); + + /// + /// Checks whether the instance with the given key is already created for a given class + /// in the container. + /// + /// The class that is queried. + /// The key that is queried. + /// True if the instance with the given key is already registered for the given class, + /// false otherwise. + [SuppressMessage( + "Microsoft.Design", + "CA1004:GenericMethodsShouldProvideTypeParameter", + Justification = "This syntax is more convenient than the alternatives.")] + bool ContainsCreated(string key); + + /// + /// Gets a value indicating whether a given type T is already registered. + /// + /// The type that the method checks for. + /// True if the type is registered, false otherwise. + [SuppressMessage( + "Microsoft.Design", + "CA1004:GenericMethodsShouldProvideTypeParameter", + Justification = "This syntax is more convenient than the alternatives.")] + bool IsRegistered(); + + /// + /// Gets a value indicating whether a given type T and a give key + /// are already registered. + /// + /// The type that the method checks for. + /// The key that the method checks for. + /// True if the type and key are registered, false otherwise. + [SuppressMessage( + "Microsoft.Design", + "CA1004:GenericMethodsShouldProvideTypeParameter", + Justification = "This syntax is more convenient than the alternatives.")] + bool IsRegistered(string key); + + /// + /// Registers a given type for a given interface. + /// + /// The interface for which instances will be resolved. + /// The type that must be used to create instances. + [SuppressMessage( + "Microsoft.Design", + "CA1004:GenericMethodsShouldProvideTypeParameter", + Justification = "This syntax is more convenient than the alternatives.")] + void Register() + where TClass : class + where TInterface : class; + + /// + /// Registers a given type for a given interface with the possibility for immediate + /// creation of the instance. + /// + /// The interface for which instances will be resolved. + /// The type that must be used to create instances. + /// If true, forces the creation of the default + /// instance of the provided class. + [SuppressMessage( + "Microsoft.Design", + "CA1004:GenericMethodsShouldProvideTypeParameter", + Justification = "This syntax is more convenient than the alternatives.")] + void Register(bool createInstanceImmediately) + where TClass : class + where TInterface : class; + + /// + /// Registers a given type. + /// + /// The type that must be used to create instances. + [SuppressMessage( + "Microsoft.Design", + "CA1004:GenericMethodsShouldProvideTypeParameter", + Justification = "This syntax is more convenient than the alternatives.")] + void Register() + where TClass : class; + + /// + /// Registers a given type with the possibility for immediate + /// creation of the instance. + /// + /// The type that must be used to create instances. + /// If true, forces the creation of the default + /// instance of the provided class. + [SuppressMessage( + "Microsoft.Design", + "CA1004:GenericMethodsShouldProvideTypeParameter", + Justification = "This syntax is more convenient than the alternatives.")] + void Register(bool createInstanceImmediately) + where TClass : class; + + /// + /// Registers a given instance for a given type. + /// + /// The type that is being registered. + /// The factory method able to create the instance that + /// must be returned when the given type is resolved. + void Register(Func factory) + where TClass : class; + + /// + /// Registers a given instance for a given type with the possibility for immediate + /// creation of the instance. + /// + /// The type that is being registered. + /// The factory method able to create the instance that + /// must be returned when the given type is resolved. + /// If true, forces the creation of the default + /// instance of the provided class. + void Register(Func factory, bool createInstanceImmediately) + where TClass : class; + + /// + /// Registers a given instance for a given type and a given key. + /// + /// The type that is being registered. + /// The factory method able to create the instance that + /// must be returned when the given type is resolved. + /// The key for which the given instance is registered. + void Register(Func factory, string key) + where TClass : class; + + /// + /// Registers a given instance for a given type and a given key with the possibility for immediate + /// creation of the instance. + /// + /// The type that is being registered. + /// The factory method able to create the instance that + /// must be returned when the given type is resolved. + /// The key for which the given instance is registered. + /// If true, forces the creation of the default + /// instance of the provided class. + void Register( + Func factory, + string key, + bool createInstanceImmediately) + where TClass : class; + + /// + /// Resets the instance in its original states. This deletes all the + /// registrations. + /// + void Reset(); + + /// + /// Unregisters a class from the cache and removes all the previously + /// created instances. + /// + /// The class that must be removed. + [SuppressMessage( + "Microsoft.Design", + "CA1004:GenericMethodsShouldProvideTypeParameter", + Justification = "This syntax is more convenient than the alternatives.")] + void Unregister() + where TClass : class; + + /// + /// Removes the given instance from the cache. The class itself remains + /// registered and can be used to create other instances. + /// + /// The type of the instance to be removed. + /// The instance that must be removed. + void Unregister(TClass instance) + where TClass : class; + + /// + /// Removes the instance corresponding to the given key from the cache. The class itself remains + /// registered and can be used to create other instances. + /// + /// The type of the instance to be removed. + /// The key corresponding to the instance that must be removed. + [SuppressMessage( + "Microsoft.Design", + "CA1004:GenericMethodsShouldProvideTypeParameter", + Justification = "This syntax is more convenient than the alternatives.")] + void Unregister(string key) + where TClass : class; + } +} \ No newline at end of file diff --git a/DeviceSQL.Service/IOC/PreferredConstructor.cs b/DeviceSQL.Service/IOC/PreferredConstructor.cs new file mode 100644 index 0000000..aa69001 --- /dev/null +++ b/DeviceSQL.Service/IOC/PreferredConstructor.cs @@ -0,0 +1,31 @@ +// **************************************************************************** +// +// Copyright © GalaSoft Laurent Bugnion 2011-2016 +// +// **************************************************************************** +// Laurent Bugnion +// laurent@galasoft.ch +// 10.4.2011 +// GalaSoft.MvvmLight.Extras.Ioc +// http://www.mvvmlight.net +// +// See license.txt in this project or http://www.galasoft.ch/license_MIT.txt +// +// **************************************************************************** + +using System; + +namespace DeviceSQL.Service.IOC +{ + /// + /// When used with the SimpleIoc container, specifies which constructor + /// should be used to instantiate when GetInstance is called. + /// If there is only one constructor in the class, this attribute is + /// not needed. + /// + //// [ClassInfo(typeof(SimpleIoc))] + [AttributeUsage(AttributeTargets.Constructor)] + public sealed class PreferredConstructorAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/DeviceSQL.Service/IOC/SimpleIOC.cs b/DeviceSQL.Service/IOC/SimpleIOC.cs new file mode 100644 index 0000000..f34aa08 --- /dev/null +++ b/DeviceSQL.Service/IOC/SimpleIOC.cs @@ -0,0 +1,961 @@ +// **************************************************************************** +// +// Copyright © GalaSoft Laurent Bugnion 2011-2016 +// +// **************************************************************************** +// Laurent Bugnion +// laurent@galasoft.ch +// 10.4.2011 +// GalaSoft.MvvmLight.Extras +// http://www.mvvmlight.net +// +// See license.txt in this project or http://www.galasoft.ch/license_MIT.txt +// +// BL0005 +// **************************************************************************** + +using DeviceSQL.Service.ServiceLocation; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Linq; +using System.Reflection; + +namespace DeviceSQL.Service.IOC +{ + /// + /// A very simple IOC container with basic functionality needed to register and resolve + /// instances. If needed, this class can be replaced by another more elaborate + /// IOC container implementing the IServiceLocator interface. + /// The inspiration for this class is at https://gist.github.com/716137 but it has + /// been extended with additional features. + /// + //// [ClassInfo(typeof(SimpleIoc), + //// VersionString = "5.1.9", + //// DateString = "201502072030", + //// Description = "A very simple IOC container.", + //// UrlContacts = "http://www.galasoft.ch/contact_en.html", + //// Email = "laurent@galasoft.ch")] + [SuppressMessage( + "Microsoft.Naming", + "CA1704:IdentifiersShouldBeSpelledCorrectly", + MessageId = "Ioc")] + public class SimpleIOC : ISimpleIOC + { + private readonly Dictionary _constructorInfos + = new Dictionary(); + + private readonly string _defaultKey = Guid.NewGuid().ToString(); + + private readonly object[] _emptyArguments = new object[0]; + + private readonly Dictionary> _factories + = new Dictionary>(); + + private readonly Dictionary> _instancesRegistry + = new Dictionary>(); + + private readonly Dictionary _interfaceToClassMap + = new Dictionary(); + + private readonly object _syncLock = new object(); + + private static SimpleIOC _default; + + /// + /// This class' default instance. + /// + public static SimpleIOC Default + { + get + { + return _default ?? (_default = new SimpleIOC()); + } + } + + /// + /// Checks whether at least one instance of a given class is already created in the container. + /// + /// The class that is queried. + /// True if at least on instance of the class is already created, false otherwise. + public bool ContainsCreated() + { + return ContainsCreated(null); + } + + /// + /// Checks whether the instance with the given key is already created for a given class + /// in the container. + /// + /// The class that is queried. + /// The key that is queried. + /// True if the instance with the given key is already registered for the given class, + /// false otherwise. + public bool ContainsCreated(string key) + { + var classType = typeof(TClass); + + if (!_instancesRegistry.ContainsKey(classType)) + { + return false; + } + + if (string.IsNullOrEmpty(key)) + { + return _instancesRegistry[classType].Count > 0; + } + + return _instancesRegistry[classType].ContainsKey(key); + } + + /// + /// Gets a value indicating whether a given type T is already registered. + /// + /// The type that the method checks for. + /// True if the type is registered, false otherwise. + public bool IsRegistered() + { + var classType = typeof(T); + return _interfaceToClassMap.ContainsKey(classType); + } + + /// + /// Gets a value indicating whether a given type T and a give key + /// are already registered. + /// + /// The type that the method checks for. + /// The key that the method checks for. + /// True if the type and key are registered, false otherwise. + public bool IsRegistered(string key) + { + var classType = typeof(T); + + if (!_interfaceToClassMap.ContainsKey(classType) + || !_factories.ContainsKey(classType)) + { + return false; + } + + return _factories[classType].ContainsKey(key); + } + + /// + /// Registers a given type for a given interface. + /// + /// The interface for which instances will be resolved. + /// The type that must be used to create instances. + [SuppressMessage( + "Microsoft.Design", + "CA1004", + Justification = "This syntax is better than the alternatives.")] + public void Register() + where TClass : class + where TInterface : class + { + Register(false); + } + + /// + /// Registers a given type for a given interface with the possibility for immediate + /// creation of the instance. + /// + /// The interface for which instances will be resolved. + /// The type that must be used to create instances. + /// If true, forces the creation of the default + /// instance of the provided class. + [SuppressMessage( + "Microsoft.Design", + "CA1004", + Justification = "This syntax is better than the alternatives.")] + public void Register(bool createInstanceImmediately) + where TClass : class + where TInterface : class + { + lock (_syncLock) + { + var interfaceType = typeof(TInterface); + var classType = typeof(TClass); + + if (_interfaceToClassMap.ContainsKey(interfaceType)) + { + if (_interfaceToClassMap[interfaceType] != classType) + { + throw new InvalidOperationException( + string.Format( + CultureInfo.InvariantCulture, + "There is already a class registered for {0}.", + interfaceType.FullName)); + } + } + else + { + _interfaceToClassMap.Add(interfaceType, classType); + _constructorInfos.Add(classType, GetConstructorInfo(classType)); + } + + Func factory = MakeInstance; + DoRegister(interfaceType, factory, _defaultKey); + + if (createInstanceImmediately) + { + GetInstance(); + } + } + } + + /// + /// Registers a given type. + /// + /// The type that must be used to create instances. + [SuppressMessage( + "Microsoft.Design", + "CA1004", + Justification = "This syntax is better than the alternatives.")] + public void Register() + where TClass : class + { + Register(false); + } + + /// + /// Registers a given type with the possibility for immediate + /// creation of the instance. + /// + /// The type that must be used to create instances. + /// If true, forces the creation of the default + /// instance of the provided class. + [SuppressMessage( + "Microsoft.Design", + "CA1004", + Justification = "This syntax is better than the alternatives.")] + public void Register(bool createInstanceImmediately) + where TClass : class + { + var classType = typeof(TClass); +#if NETFX_CORE + if (classType.GetTypeInfo().IsInterface) +#else + if (classType.IsInterface) +#endif + { + throw new ArgumentException("An interface cannot be registered alone."); + } + + lock (_syncLock) + { + if (_factories.ContainsKey(classType) + && _factories[classType].ContainsKey(_defaultKey)) + { + if (!_constructorInfos.ContainsKey(classType)) + { + // Throw only if constructorinfos have not been + // registered, which means there is a default factory + // for this class. + throw new InvalidOperationException( + string.Format( + CultureInfo.InvariantCulture, + "Class {0} is already registered.", + classType)); + } + + return; + } + + if (!_interfaceToClassMap.ContainsKey(classType)) + { + _interfaceToClassMap.Add(classType, null); + } + + _constructorInfos.Add(classType, GetConstructorInfo(classType)); + Func factory = MakeInstance; + DoRegister(classType, factory, _defaultKey); + + if (createInstanceImmediately) + { + GetInstance(); + } + } + } + + /// + /// Registers a given instance for a given type. + /// + /// The type that is being registered. + /// The factory method able to create the instance that + /// must be returned when the given type is resolved. + public void Register(Func factory) + where TClass : class + { + Register(factory, false); + } + + /// + /// Registers a given instance for a given type with the possibility for immediate + /// creation of the instance. + /// + /// The type that is being registered. + /// The factory method able to create the instance that + /// must be returned when the given type is resolved. + /// If true, forces the creation of the default + /// instance of the provided class. + public void Register(Func factory, bool createInstanceImmediately) + where TClass : class + { + if (factory == null) + { + throw new ArgumentNullException("factory"); + } + + lock (_syncLock) + { + var classType = typeof(TClass); + + if (_factories.ContainsKey(classType) + && _factories[classType].ContainsKey(_defaultKey)) + { + throw new InvalidOperationException( + string.Format( + CultureInfo.InvariantCulture, + "There is already a factory registered for {0}.", + classType.FullName)); + } + + if (!_interfaceToClassMap.ContainsKey(classType)) + { + _interfaceToClassMap.Add(classType, null); + } + + DoRegister(classType, factory, _defaultKey); + + if (createInstanceImmediately) + { + GetInstance(); + } + } + } + + /// + /// Registers a given instance for a given type and a given key. + /// + /// The type that is being registered. + /// The factory method able to create the instance that + /// must be returned when the given type is resolved. + /// The key for which the given instance is registered. + public void Register(Func factory, string key) + where TClass : class + { + Register(factory, key, false); + } + + /// + /// Registers a given instance for a given type and a given key with the possibility for immediate + /// creation of the instance. + /// + /// The type that is being registered. + /// The factory method able to create the instance that + /// must be returned when the given type is resolved. + /// The key for which the given instance is registered. + /// If true, forces the creation of the default + /// instance of the provided class. + public void Register( + Func factory, + string key, + bool createInstanceImmediately) + where TClass : class + { + lock (_syncLock) + { + var classType = typeof(TClass); + + if (_factories.ContainsKey(classType) + && _factories[classType].ContainsKey(key)) + { + throw new InvalidOperationException( + string.Format( + CultureInfo.InvariantCulture, + "There is already a factory registered for {0} with key {1}.", + classType.FullName, + key)); + } + + if (!_interfaceToClassMap.ContainsKey(classType)) + { + _interfaceToClassMap.Add(classType, null); + } + + DoRegister(classType, factory, key); + + if (createInstanceImmediately) + { + GetInstance(key); + } + } + } + + /// + /// Resets the instance in its original states. This deletes all the + /// registrations. + /// + public void Reset() + { + _interfaceToClassMap.Clear(); + _instancesRegistry.Clear(); + _constructorInfos.Clear(); + _factories.Clear(); + } + + /// + /// Unregisters a class from the cache and removes all the previously + /// created instances. + /// + /// The class that must be removed. + [SuppressMessage( + "Microsoft.Design", + "CA1004", + Justification = "This syntax is better than the alternatives.")] + public void Unregister() + where TClass : class + { + lock (_syncLock) + { + var serviceType = typeof(TClass); + Type resolveTo; + + if (_interfaceToClassMap.ContainsKey(serviceType)) + { + resolveTo = _interfaceToClassMap[serviceType] ?? serviceType; + } + else + { + resolveTo = serviceType; + } + + if (_instancesRegistry.ContainsKey(serviceType)) + { + _instancesRegistry.Remove(serviceType); + } + + if (_interfaceToClassMap.ContainsKey(serviceType)) + { + _interfaceToClassMap.Remove(serviceType); + } + + if (_factories.ContainsKey(serviceType)) + { + _factories.Remove(serviceType); + } + + if (_constructorInfos.ContainsKey(resolveTo)) + { + _constructorInfos.Remove(resolveTo); + } + } + } + + /// + /// Removes the given instance from the cache. The class itself remains + /// registered and can be used to create other instances. + /// + /// The type of the instance to be removed. + /// The instance that must be removed. + public void Unregister(TClass instance) + where TClass : class + { + lock (_syncLock) + { + var classType = typeof(TClass); + + if (_instancesRegistry.ContainsKey(classType)) + { + var list = _instancesRegistry[classType]; + + var pairs = list.Where(pair => pair.Value == instance).ToList(); + for (var index = 0; index < pairs.Count(); index++) + { + var key = pairs[index].Key; + + list.Remove(key); + } + } + } + } + + /// + /// Removes the instance corresponding to the given key from the cache. The class itself remains + /// registered and can be used to create other instances. + /// + /// The type of the instance to be removed. + /// The key corresponding to the instance that must be removed. + [SuppressMessage( + "Microsoft.Design", + "CA1004", + Justification = "This syntax is better than the alternatives.")] + public void Unregister(string key) + where TClass : class + { + lock (_syncLock) + { + var classType = typeof(TClass); + + if (_instancesRegistry.ContainsKey(classType)) + { + var list = _instancesRegistry[classType]; + + var pairs = list.Where(pair => pair.Key == key).ToList(); + for (var index = 0; index < pairs.Count(); index++) + { + list.Remove(pairs[index].Key); + } + } + + if (_factories.ContainsKey(classType)) + { + if (_factories[classType].ContainsKey(key)) + { + _factories[classType].Remove(key); + } + } + } + } + + private object DoGetService(Type serviceType, string key, bool cache = true) + { + lock (_syncLock) + { + if (string.IsNullOrEmpty(key)) + { + key = _defaultKey; + } + + Dictionary instances = null; + + if (!_instancesRegistry.ContainsKey(serviceType)) + { + if (!_interfaceToClassMap.ContainsKey(serviceType)) + { + throw new ActivationException( + string.Format( + CultureInfo.InvariantCulture, + "Type not found in cache: {0}.", + serviceType.FullName)); + } + + if (cache) + { + instances = new Dictionary(); + _instancesRegistry.Add(serviceType, instances); + } + } + else + { + instances = _instancesRegistry[serviceType]; + } + + if (instances != null + && instances.ContainsKey(key)) + { + return instances[key]; + } + + object instance = null; + + if (_factories.ContainsKey(serviceType)) + { + if (_factories[serviceType].ContainsKey(key)) + { + instance = _factories[serviceType][key].DynamicInvoke(null); + } + else + { + if (_factories[serviceType].ContainsKey(_defaultKey)) + { + instance = _factories[serviceType][_defaultKey].DynamicInvoke(null); + } + else + { + throw new ActivationException( + string.Format( + CultureInfo.InvariantCulture, + "Type not found in cache without a key: {0}", + serviceType.FullName)); + } + } + } + + if (cache + && instances != null) + { + instances.Add(key, instance); + } + + return instance; + } + } + + private void DoRegister(Type classType, Func factory, string key) + { + if (_factories.ContainsKey(classType)) + { + if (_factories[classType].ContainsKey(key)) + { + // The class is already registered, ignore and continue. + return; + } + + _factories[classType].Add(key, factory); + } + else + { + var list = new Dictionary + { + { + key, + factory + } + }; + + _factories.Add(classType, list); + } + } + + private ConstructorInfo GetConstructorInfo(Type serviceType) + { + Type resolveTo; + + if (_interfaceToClassMap.ContainsKey(serviceType)) + { + resolveTo = _interfaceToClassMap[serviceType] ?? serviceType; + } + else + { + resolveTo = serviceType; + } + +#if NETFX_CORE + var constructorInfos = resolveTo.GetTypeInfo().DeclaredConstructors.Where(c => c.IsPublic).ToArray(); +#else + var constructorInfos = resolveTo.GetConstructors(); +#endif + + if (constructorInfos.Length > 1) + { + if (constructorInfos.Length > 2) + { + return GetPreferredConstructorInfo(constructorInfos, resolveTo); + } + + if (constructorInfos.FirstOrDefault(i => i.Name == ".cctor") == null) + { + return GetPreferredConstructorInfo(constructorInfos, resolveTo); + } + + var first = constructorInfos.FirstOrDefault(i => i.Name != ".cctor"); + + if (first == null + || !first.IsPublic) + { + throw new ActivationException( + string.Format( + CultureInfo.InvariantCulture, + "Cannot register: No public constructor found in {0}.", + resolveTo.Name)); + } + + return first; + } + + if (constructorInfos.Length == 0 + || (constructorInfos.Length == 1 + && !constructorInfos[0].IsPublic)) + { + throw new ActivationException( + string.Format( + CultureInfo.InvariantCulture, + "Cannot register: No public constructor found in {0}.", + resolveTo.Name)); + } + + return constructorInfos[0]; + } + + [SuppressMessage( + "Microsoft.Naming", + "CA2204:Literals should be spelled correctly", + MessageId = "PreferredConstructor")] + private static ConstructorInfo GetPreferredConstructorInfo(IEnumerable constructorInfos, Type resolveTo) + { + var preferredConstructorInfo + = (from t in constructorInfos +#if NETFX_CORE + let attribute = t.GetCustomAttribute(typeof(PreferredConstructorAttribute)) +#else + let attribute = Attribute.GetCustomAttribute(t, typeof(PreferredConstructorAttribute)) +#endif + where attribute != null + select t).FirstOrDefault(); + + if (preferredConstructorInfo == null) + { + throw new ActivationException( + string.Format( + CultureInfo.InvariantCulture, + "Cannot register: Multiple constructors found in {0} but none marked with PreferredConstructor.", + resolveTo.Name)); + } + + return preferredConstructorInfo; + } + + private TClass MakeInstance() + { + var serviceType = typeof(TClass); + + var constructor = _constructorInfos.ContainsKey(serviceType) + ? _constructorInfos[serviceType] + : GetConstructorInfo(serviceType); + + var parameterInfos = constructor.GetParameters(); + + if (parameterInfos.Length == 0) + { + return (TClass)constructor.Invoke(_emptyArguments); + } + + var parameters = new object[parameterInfos.Length]; + + foreach (var parameterInfo in parameterInfos) + { + parameters[parameterInfo.Position] = GetService(parameterInfo.ParameterType); + } + + return (TClass)constructor.Invoke(parameters); + } + + /// + /// Provides a way to get all the created instances of a given type available in the + /// cache. Registering a class or a factory does not automatically + /// create the corresponding instance! To create an instance, either register + /// the class or the factory with createInstanceImmediately set to true, + /// or call the GetInstance method before calling GetAllCreatedInstances. + /// Alternatively, use the GetAllInstances method, which auto-creates default + /// instances for all registered classes. + /// + /// The class of which all instances + /// must be returned. + /// All the already created instances of the given type. + public IEnumerable GetAllCreatedInstances(Type serviceType) + { + if (_instancesRegistry.ContainsKey(serviceType)) + { + return _instancesRegistry[serviceType].Values; + } + + return new List(); + } + + /// + /// Provides a way to get all the created instances of a given type available in the + /// cache. Registering a class or a factory does not automatically + /// create the corresponding instance! To create an instance, either register + /// the class or the factory with createInstanceImmediately set to true, + /// or call the GetInstance method before calling GetAllCreatedInstances. + /// Alternatively, use the GetAllInstances method, which auto-creates default + /// instances for all registered classes. + /// + /// The class of which all instances + /// must be returned. + /// All the already created instances of the given type. + public IEnumerable GetAllCreatedInstances() + { + var serviceType = typeof (TService); + return GetAllCreatedInstances(serviceType) + .Select(instance => (TService)instance); + } + + #region Implementation of IServiceProvider + + /// + /// Gets the service object of the specified type. + /// + /// If the type serviceType has not + /// been registered before calling this method. + /// + /// A service object of type . + /// + /// An object that specifies the type of service object to get. + public object GetService(Type serviceType) + { + return DoGetService(serviceType, _defaultKey); + } + + #endregion + + #region Implementation of IServiceLocator + + /// + /// Provides a way to get all the created instances of a given type available in the + /// cache. Calling this method auto-creates default + /// instances for all registered classes. + /// + /// The class of which all instances + /// must be returned. + /// All the instances of the given type. + public IEnumerable GetAllInstances(Type serviceType) + { + lock (_factories) + { + if (_factories.ContainsKey(serviceType)) + { + foreach (var factory in _factories[serviceType]) + { + GetInstance(serviceType, factory.Key); + } + } + } + + if (_instancesRegistry.ContainsKey(serviceType)) + { + return _instancesRegistry[serviceType].Values; + } + + + return new List(); + } + + /// + /// Provides a way to get all the created instances of a given type available in the + /// cache. Calling this method auto-creates default + /// instances for all registered classes. + /// + /// The class of which all instances + /// must be returned. + /// All the instances of the given type. + public IEnumerable GetAllInstances() + { + var serviceType = typeof(TService); + return GetAllInstances(serviceType) + .Select(instance => (TService)instance); + } + + /// + /// Provides a way to get an instance of a given type. If no instance had been instantiated + /// before, a new instance will be created. If an instance had already + /// been created, that same instance will be returned. + /// + /// If the type serviceType has not + /// been registered before calling this method. + /// The class of which an instance + /// must be returned. + /// An instance of the given type. + public object GetInstance(Type serviceType) + { + return DoGetService(serviceType, _defaultKey); + } + + /// + /// Provides a way to get an instance of a given type. This method + /// always returns a new instance and doesn't cache it in the IOC container. + /// + /// If the type serviceType has not + /// been registered before calling this method. + /// The class of which an instance + /// must be returned. + /// An instance of the given type. + public object GetInstanceWithoutCaching(Type serviceType) + { + return DoGetService(serviceType, _defaultKey, false); + } + + /// + /// Provides a way to get an instance of a given type corresponding + /// to a given key. If no instance had been instantiated with this + /// key before, a new instance will be created. If an instance had already + /// been created with the same key, that same instance will be returned. + /// + /// If the type serviceType has not + /// been registered before calling this method. + /// The class of which an instance must be returned. + /// The key uniquely identifying this instance. + /// An instance corresponding to the given type and key. + public object GetInstance(Type serviceType, string key) + { + return DoGetService(serviceType, key); + } + + /// + /// Provides a way to get an instance of a given type. This method + /// always returns a new instance and doesn't cache it in the IOC container. + /// + /// If the type serviceType has not + /// been registered before calling this method. + /// The class of which an instance must be returned. + /// The key uniquely identifying this instance. + /// An instance corresponding to the given type and key. + public object GetInstanceWithoutCaching(Type serviceType, string key) + { + return DoGetService(serviceType, key, false); + } + + /// + /// Provides a way to get an instance of a given type. If no instance had been instantiated + /// before, a new instance will be created. If an instance had already + /// been created, that same instance will be returned. + /// + /// If the type TService has not + /// been registered before calling this method. + /// The class of which an instance + /// must be returned. + /// An instance of the given type. + public TService GetInstance() + { + return (TService)DoGetService(typeof(TService), _defaultKey); + } + + /// + /// Provides a way to get an instance of a given type. This method + /// always returns a new instance and doesn't cache it in the IOC container. + /// + /// If the type TService has not + /// been registered before calling this method. + /// The class of which an instance + /// must be returned. + /// An instance of the given type. + public TService GetInstanceWithoutCaching() + { + return (TService)DoGetService(typeof(TService), _defaultKey, false); + } + + /// + /// Provides a way to get an instance of a given type corresponding + /// to a given key. If no instance had been instantiated with this + /// key before, a new instance will be created. If an instance had already + /// been created with the same key, that same instance will be returned. + /// + /// If the type TService has not + /// been registered before calling this method. + /// The class of which an instance must be returned. + /// The key uniquely identifying this instance. + /// An instance corresponding to the given type and key. + public TService GetInstance(string key) + { + return (TService)DoGetService(typeof(TService), key); + } + + /// + /// Provides a way to get an instance of a given type. This method + /// always returns a new instance and doesn't cache it in the IOC container. + /// + /// If the type TService has not + /// been registered before calling this method. + /// The class of which an instance must be returned. + /// The key uniquely identifying this instance. + /// An instance corresponding to the given type and key. + public TService GetInstanceWithoutCaching(string key) + { + return (TService)DoGetService(typeof(TService), key, false); + } + + #endregion + } +} \ No newline at end of file diff --git a/DeviceSQL.Service/Program.cs b/DeviceSQL.Service/Program.cs index cf9c86e..70e2ce3 100644 --- a/DeviceSQL.Service/Program.cs +++ b/DeviceSQL.Service/Program.cs @@ -17,7 +17,7 @@ static void Main() ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { - new Service1() + new DeviceSqlService() }; ServiceBase.Run(ServicesToRun); } diff --git a/DeviceSQL.Service/ProjectInstaller.Designer.cs b/DeviceSQL.Service/ProjectInstaller.Designer.cs index 5f66bd6..4a98b7d 100644 --- a/DeviceSQL.Service/ProjectInstaller.Designer.cs +++ b/DeviceSQL.Service/ProjectInstaller.Designer.cs @@ -33,12 +33,16 @@ private void InitializeComponent() // // serviceProcessInstaller // + this.serviceProcessInstaller.Account = System.ServiceProcess.ServiceAccount.NetworkService; this.serviceProcessInstaller.Password = null; this.serviceProcessInstaller.Username = null; // // serviceInstaller // - this.serviceInstaller.ServiceName = "Service1"; + this.serviceInstaller.Description = "DeviceSQL Web API REST Services"; + this.serviceInstaller.DisplayName = "DeviceSQL Service"; + this.serviceInstaller.ServiceName = "DeviceSqlSvc"; + this.serviceInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic; // // ProjectInstaller // diff --git a/DeviceSQL.Service/ProjectInstaller.resx b/DeviceSQL.Service/ProjectInstaller.resx index 2c076de..f92835d 100644 --- a/DeviceSQL.Service/ProjectInstaller.resx +++ b/DeviceSQL.Service/ProjectInstaller.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 17, 17 + 17, 65 196, 17 diff --git a/DeviceSQL.Service/Properties/AssemblyInfo.cs b/DeviceSQL.Service/Properties/AssemblyInfo.cs index b9c1f13..c971418 100644 --- a/DeviceSQL.Service/Properties/AssemblyInfo.cs +++ b/DeviceSQL.Service/Properties/AssemblyInfo.cs @@ -6,13 +6,14 @@ // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("DeviceSQL.Service")] -[assembly: AssemblyDescription("")] +[assembly: AssemblyDescription("DeviceSQL.Service")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("DeviceSQL.Service")] -[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyCompany("CloudSonix")] +[assembly: AssemblyProduct("DeviceSQL")] +[assembly: AssemblyCopyright("© CloudSonix. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] +[assembly: AssemblyKeyFile("../DeviceSQL-Key.snk")] // 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 diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/Settings.Designer.cs b/DeviceSQL.Service/Properties/Settings.Designer.cs similarity index 60% rename from DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/Settings.Designer.cs rename to DeviceSQL.Service/Properties/Settings.Designer.cs index f7bf38d..834a47d 100644 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/Settings.Designer.cs +++ b/DeviceSQL.Service/Properties/Settings.Designer.cs @@ -8,23 +8,28 @@ // //------------------------------------------------------------------------------ -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Properties -{ - - +namespace DeviceSQL.Service.Properties { + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase - { - + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.2.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default - { - get - { + + public static Settings Default { + get { return defaultInstance; } } + + [global::System.Configuration.ApplicationScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("http://localhost:8080")] + public string BaseAddress { + get { + return ((string)(this["BaseAddress"])); + } + } } } diff --git a/DeviceSQL.Service/Properties/Settings.settings b/DeviceSQL.Service/Properties/Settings.settings new file mode 100644 index 0000000..467b977 --- /dev/null +++ b/DeviceSQL.Service/Properties/Settings.settings @@ -0,0 +1,9 @@ + + + + + + http://localhost:8080 + + + \ No newline at end of file diff --git a/DeviceSQL.Service/Service1.cs b/DeviceSQL.Service/Service1.cs deleted file mode 100644 index e900e1d..0000000 --- a/DeviceSQL.Service/Service1.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Diagnostics; -using System.Linq; -using System.ServiceProcess; -using System.Text; -using System.Threading.Tasks; - -namespace DeviceSQL.Service -{ - public partial class Service1 : ServiceBase - { - public Service1() - { - InitializeComponent(); - } - - protected override void OnStart(string[] args) - { - } - - protected override void OnStop() - { - } - } -} diff --git a/DeviceSQL.Service/ServiceLocation/ActivationException.cs b/DeviceSQL.Service/ServiceLocation/ActivationException.cs new file mode 100644 index 0000000..54c7e32 --- /dev/null +++ b/DeviceSQL.Service/ServiceLocation/ActivationException.cs @@ -0,0 +1,44 @@ +#region Imported Types + +using System; + +#endregion + +namespace DeviceSQL.Service.ServiceLocation +{ + /// + /// The standard exception thrown when a ServiceLocator has an error in resolving an object. + /// + public class ActivationException : Exception + { + /// + /// Initializes a new instance of the class. + /// + public ActivationException() + { + } + + /// + /// Initializes a new instance of the class with a specified error message. + /// + /// + /// The message that describes the error. + /// + public ActivationException(string message) : base(message) + { + } + + /// + /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. + /// + /// + /// The error message that explains the reason for the exception. + /// + /// + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + /// + public ActivationException(string message, Exception innerException) : base(message, innerException) + { + } + } +} \ No newline at end of file diff --git a/DeviceSQL.Service/ServiceLocation/IServiceLocator.cs b/DeviceSQL.Service/ServiceLocation/IServiceLocator.cs new file mode 100644 index 0000000..92eae8f --- /dev/null +++ b/DeviceSQL.Service/ServiceLocation/IServiceLocator.cs @@ -0,0 +1,75 @@ +#region Imported Types + +using System; +using System.Collections.Generic; + +#endregion + +namespace DeviceSQL.Service.ServiceLocation +{ + /// + /// The generic Service Locator interface. This interface is used + /// to retrieve services (instances identified by type and optional + /// name) from a container. + /// + public interface IServiceLocator : IServiceProvider + { + /// + /// Get all instances of the given currently + /// registered in the container. + /// + /// Type of object requested. + /// if there is are errors resolving + /// the service instance. + /// A sequence of instances of the requested . + IEnumerable GetAllInstances(Type serviceType); + + /// + /// Get all instances of the given currently + /// registered in the container. + /// + /// Type of object requested. + /// if there is are errors resolving + /// the service instance. + /// A sequence of instances of the requested . + IEnumerable GetAllInstances(); + + /// + /// Get an instance of the given . + /// + /// Type of object requested. + /// if there is an error resolving + /// the service instance. + /// The requested service instance. + object GetInstance(Type serviceType); + + /// + /// Get an instance of the given named . + /// + /// Type of object requested. + /// Name the object was registered with. + /// if there is an error resolving + /// the service instance. + /// The requested service instance. + object GetInstance(Type serviceType, string key); + + /// + /// Get an instance of the given . + /// + /// Type of object requested. + /// if there is are errors resolving + /// the service instance. + /// The requested service instance. + TService GetInstance(); + + /// + /// Get an instance of the given named . + /// + /// Type of object requested. + /// Name the object was registered with. + /// if there is are errors resolving + /// the service instance. + /// The requested service instance. + TService GetInstance(string key); + } +} \ No newline at end of file diff --git a/DeviceSQL.Service/ServiceLocation/ServiceLocator.cs b/DeviceSQL.Service/ServiceLocation/ServiceLocator.cs new file mode 100644 index 0000000..4582b5d --- /dev/null +++ b/DeviceSQL.Service/ServiceLocation/ServiceLocator.cs @@ -0,0 +1,52 @@ +#region Imported Types + +using System; + +#endregion + +namespace DeviceSQL.Service.ServiceLocation +{ + /// + /// This class provides the ambient container for this application. If your + /// framework defines such an ambient container, use ServiceLocator.Current + /// to get it. + /// + public static class ServiceLocator + { + private const string SERVICE_LOCATION_PROVIDER_NOT_SET_MESSAGE = "ServiceLocationProvider must be set."; + private static ServiceLocatorProvider currentProvider; + + /// + /// The current ambient container. + /// + public static IServiceLocator Current + { + get + { + if (!ServiceLocator.IsLocationProviderSet) + { + throw new InvalidOperationException(SERVICE_LOCATION_PROVIDER_NOT_SET_MESSAGE); + } + return ServiceLocator.currentProvider(); + } + } + + public static bool IsLocationProviderSet + { + get + { + return ServiceLocator.currentProvider != null; + } + } + + /// + /// Set the delegate that is used to retrieve the current container. + /// + /// Delegate that, when called, will return + /// the current ambient container. + public static void SetLocatorProvider(ServiceLocatorProvider newProvider) + { + ServiceLocator.currentProvider = newProvider; + } + } +} \ No newline at end of file diff --git a/DeviceSQL.Service/ServiceLocation/ServiceLocatorImplBase.cs b/DeviceSQL.Service/ServiceLocation/ServiceLocatorImplBase.cs new file mode 100644 index 0000000..b9524ae --- /dev/null +++ b/DeviceSQL.Service/ServiceLocation/ServiceLocatorImplBase.cs @@ -0,0 +1,181 @@ +#region Imported Types + +using System; +using System.Collections.Generic; +using System.Globalization; + +#endregion + +namespace DeviceSQL.Service.ServiceLocation +{ + /// + /// This class is a helper that provides a default implementation + /// for most of the methods of . + /// + public abstract class ServiceLocatorImplBase : IServiceLocator, IServiceProvider + { + private const string ACTIVATION_EXCEPTION_MESSAGE = "Activation error occurred while trying to get instance of type {0}, key \"{1}\""; + private const string ACTIVATE_ALL_EXCEPTION_MESSAGE = "Activation error occurred while trying to get all instances of type {0}"; + protected ServiceLocatorImplBase() + { + } + + /// + /// When implemented by inheriting classes, this method will do the actual work of + /// resolving all the requested service instances. + /// + /// Type of service requested. + /// Sequence of service instance objects. + protected abstract IEnumerable DoGetAllInstances(Type serviceType); + + /// + /// When implemented by inheriting classes, this method will do the actual work of resolving + /// the requested service instance. + /// + /// Type of instance requested. + /// Name of registered service you want. May be null. + /// The requested service instance. + protected abstract object DoGetInstance(Type serviceType, string key); + + /// + /// Format the exception message for use in an + /// that occurs while resolving multiple service instances. + /// + /// The actual exception thrown by the implementation. + /// Type of service requested. + /// The formatted exception message string. + protected virtual string FormatActivateAllExceptionMessage(Exception actualException, Type serviceType) + { + CultureInfo currentUICulture = CultureInfo.CurrentUICulture; + string activateAllExceptionMessage = ACTIVATE_ALL_EXCEPTION_MESSAGE; + object[] name = new object[] { serviceType.Name }; + return string.Format(currentUICulture, activateAllExceptionMessage, name); + } + + /// + /// Format the exception message for use in an + /// that occurs while resolving a single service. + /// + /// The actual exception thrown by the implementation. + /// Type of service requested. + /// Name requested. + /// The formatted exception message string. + protected virtual string FormatActivationExceptionMessage(Exception actualException, Type serviceType, string key) + { + CultureInfo currentUICulture = CultureInfo.CurrentUICulture; + string activationExceptionMessage = ACTIVATION_EXCEPTION_MESSAGE; + object[] name = new object[] { serviceType.Name, key }; + return string.Format(currentUICulture, activationExceptionMessage, name); + } + + /// + /// Get all instances of the given currently + /// registered in the container. + /// + /// Type of object requested. + /// if there is are errors resolving + /// the service instance. + /// A sequence of instances of the requested . + public virtual IEnumerable GetAllInstances(Type serviceType) + { + IEnumerable objs; + try + { + objs = this.DoGetAllInstances(serviceType); + } + catch (Exception exception) + { + Exception ex = exception; + throw new ActivationException(this.FormatActivateAllExceptionMessage(ex, serviceType), ex); + } + return objs; + } + + /// + /// Get all instances of the given currently + /// registered in the container. + /// + /// Type of object requested. + /// if there is are errors resolving + /// the service instance. + /// A sequence of instances of the requested . + public virtual IEnumerable GetAllInstances() + { + foreach (object allInstance in this.GetAllInstances(typeof(TService))) + { + yield return (TService)allInstance; + } + } + + /// + /// Get an instance of the given . + /// + /// Type of object requested. + /// if there is an error resolving + /// the service instance. + /// The requested service instance. + public virtual object GetInstance(Type serviceType) + { + return this.GetInstance(serviceType, null); + } + + /// + /// Get an instance of the given named . + /// + /// Type of object requested. + /// Name the object was registered with. + /// if there is an error resolving + /// the service instance. + /// The requested service instance. + public virtual object GetInstance(Type serviceType, string key) + { + object obj; + try + { + obj = this.DoGetInstance(serviceType, key); + } + catch (Exception exception) + { + Exception ex = exception; + throw new ActivationException(this.FormatActivationExceptionMessage(ex, serviceType, key), ex); + } + return obj; + } + + /// + /// Get an instance of the given . + /// + /// Type of object requested. + /// if there is are errors resolving + /// the service instance. + /// The requested service instance. + public virtual TService GetInstance() + { + return (TService)this.GetInstance(typeof(TService), null); + } + + /// + /// Get an instance of the given named . + /// + /// Type of object requested. + /// Name the object was registered with. + /// if there is are errors resolving + /// the service instance. + /// The requested service instance. + public virtual TService GetInstance(string key) + { + return (TService)this.GetInstance(typeof(TService), key); + } + + /// + /// Implementation of . + /// + /// The requested service. + /// if there is an error in resolving the service instance. + /// The requested object. + public virtual object GetService(Type serviceType) + { + return this.GetInstance(serviceType, null); + } + } +} \ No newline at end of file diff --git a/DeviceSQL.Service/ServiceLocation/ServiceLocatorProvider.cs b/DeviceSQL.Service/ServiceLocation/ServiceLocatorProvider.cs new file mode 100644 index 0000000..a819a53 --- /dev/null +++ b/DeviceSQL.Service/ServiceLocation/ServiceLocatorProvider.cs @@ -0,0 +1,10 @@ +namespace DeviceSQL.Service.ServiceLocation +{ + /// + /// This delegate type is used to provide a method that will + /// return the current container. Used with the + /// static accessor class. + /// + /// An . + public delegate IServiceLocator ServiceLocatorProvider(); +} \ No newline at end of file diff --git a/DeviceSQL.Service/Startup.cs b/DeviceSQL.Service/Startup.cs new file mode 100644 index 0000000..06948ab --- /dev/null +++ b/DeviceSQL.Service/Startup.cs @@ -0,0 +1,16 @@ +using Owin; +using System.Web.Http; + +namespace DeviceSQL.Service +{ + public class Startup + { + public void Configuration(IAppBuilder appBuilder) + { + var httpConfiguration = new HttpConfiguration(); + + httpConfiguration.MapHttpAttributeRoutes(); + appBuilder.UseWebApi(httpConfiguration); + } + } +} diff --git a/DeviceSQL.Service/packages.config b/DeviceSQL.Service/packages.config new file mode 100644 index 0000000..9110882 --- /dev/null +++ b/DeviceSQL.Service/packages.config @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/DeviceSQL.Services/App.config b/DeviceSQL.Services/App.config deleted file mode 100644 index 14efc92..0000000 --- a/DeviceSQL.Services/App.config +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/DeviceSQL.Services/DeviceSQL.Services.csproj b/DeviceSQL.Services/DeviceSQL.Services.csproj deleted file mode 100644 index 5c25c6b..0000000 --- a/DeviceSQL.Services/DeviceSQL.Services.csproj +++ /dev/null @@ -1,83 +0,0 @@ - - - - Debug - AnyCPU - 8.0.50727 - 2.0 - {4136548D-5D58-4EEB-8876-D450ADC62369} - Library - Properties - DeviceSQL.Services - DeviceSQL.Services - {3D9AD99F-2412-4246-B90B-4EAA41C64699};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - /client:"WcfTestClient.exe" - v4.6.1 - True - True - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - {80ed4080-6fd1-492f-b70e-8c837b3dadc7} - DeviceSQL.Devices - - - - - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio - $(VSToolsPath)\WCF - - - - - - - True - - - - - - \ No newline at end of file diff --git a/DeviceSQL.Services/IService.cs b/DeviceSQL.Services/IService.cs deleted file mode 100644 index be482a3..0000000 --- a/DeviceSQL.Services/IService.cs +++ /dev/null @@ -1,23 +0,0 @@ -using DeviceSQL.Device; -using DeviceSQL.IO.Channels; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; -using System.ServiceModel; -using System.Text; - -namespace DeviceSQL.Services -{ - [ServiceContract] - public interface IService - { - [OperationContract] - List GetChannels(); - - [OperationContract] - List GetDevices(); - - } - -} diff --git a/DeviceSQL.Services/Service.cs b/DeviceSQL.Services/Service.cs deleted file mode 100644 index 4b8a4b6..0000000 --- a/DeviceSQL.Services/Service.cs +++ /dev/null @@ -1,39 +0,0 @@ -using DeviceSQL.Device; -using DeviceSQL.IO.Channels; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; -using System.ServiceModel; -using System.Text; - -namespace DeviceSQL.Services -{ - [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] - public class Service : IService - { - - #region Fields - - public static Dictionary Channels = new Dictionary(); - public static Dictionary Devices = new Dictionary(); - - public List GetChannels() - { - throw new NotImplementedException(); - } - - public List GetDevices() - { - throw new NotImplementedException(); - } - - #endregion - - #region Service Methods - - - #endregion - - } -} diff --git a/DeviceSQL.TestHarness/App.config b/DeviceSQL.TestHarness/App.config deleted file mode 100644 index 731f6de..0000000 --- a/DeviceSQL.TestHarness/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/DeviceSQL.TestHarness/DeviceSQL.TestHarness.csproj b/DeviceSQL.TestHarness/DeviceSQL.TestHarness.csproj deleted file mode 100644 index 1315d74..0000000 --- a/DeviceSQL.TestHarness/DeviceSQL.TestHarness.csproj +++ /dev/null @@ -1,87 +0,0 @@ - - - - - Debug - AnyCPU - {FF09F40D-A515-4ABB-9DB1-21D9D1F2793E} - Exe - DeviceSQL.TestHarness - DeviceSQL.TestHarness - v4.6.1 - 512 - true - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - {cb6f0884-5a58-432a-800e-4abfeeab6f46} - DeviceSQL - - - - - False - Microsoft .NET Framework 4.6.1 %28x86 and x64%29 - true - - - False - .NET Framework 3.5 SP1 - false - - - - \ No newline at end of file diff --git a/DeviceSQL.TestHarness/Program.cs b/DeviceSQL.TestHarness/Program.cs deleted file mode 100644 index 58e1d45..0000000 --- a/DeviceSQL.TestHarness/Program.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data.SqlTypes; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DeviceSQL.TestHarness -{ - class Program - { - static void Main(string[] args) - { - TcpChannelTest.Test(); - } - } -} diff --git a/DeviceSQL.TestHarness/SerialPortChannelTest.cs b/DeviceSQL.TestHarness/SerialPortChannelTest.cs deleted file mode 100644 index cd0ea99..0000000 --- a/DeviceSQL.TestHarness/SerialPortChannelTest.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DeviceSQL.TestHarness -{ - class SerialPortChannelTest - { - public static void Test() - { - using (var serialPortChannel = new IO.Channels.SerialPortChannel() - { - Name = "com1://localhost", - ReadTimeout = 5000, - WriteTimeout = 5000, - TracingEnabled = true - }) - { - var rocMaster = new Device.ROC.ROCMaster(serialPortChannel) - { - Name = "FB103-01", - DeviceAddress = 1, - DeviceGroup = 2, - HostAddress = 3, - HostGroup = 1 - }; - - rocMaster.Transport.NumberOfRetries = 3; - - serialPortChannel.SerialPort.BaudRate = 19200; - serialPortChannel.SerialPort.DataBits = 8; - serialPortChannel.SerialPort.Parity = System.IO.Ports.Parity.None; - serialPortChannel.SerialPort.StopBits = System.IO.Ports.StopBits.One; - serialPortChannel.SerialPort.Handshake = System.IO.Ports.Handshake.None; - - serialPortChannel.SerialPort.Open(); - - var deviceRealTimeClockValue = rocMaster.GetRealTimeClockValue(null, null, null, null, 2000); - - serialPortChannel.SerialPort.Close(); - - } - } - } -} diff --git a/DeviceSQL.TestHarness/TcpChannelTest.cs b/DeviceSQL.TestHarness/TcpChannelTest.cs deleted file mode 100644 index 3ff8282..0000000 --- a/DeviceSQL.TestHarness/TcpChannelTest.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DeviceSQL.TestHarness -{ - class TcpChannelTest - { - public static void Test() - { - - - - - DeviceSQL.Functions.ChannelManager.ChannelManager_RegisterTcpChannel("tcp://96.53.12.52:4000", "96.53.12.52", 4000, 5, 5000, 5000, 5000); - - DeviceSQL.Functions.DeviceManager.DeviceManager_RegisterROCMaster("tcp://96.53.12.52:4000", "FB103-01", 1, 2, 3, 1, 5, 200, 0, 0); - - var index = 0; - - while (1000 > index) - { - var deviceDateTime = DeviceSQL.Functions.ROCMaster.ROCMaster_GetRealTimeClockValueWithCentury("FB103-01", 2000); - Console.WriteLine(deviceDateTime); - } - - DeviceSQL.Functions.DeviceManager.DeviceManager_UnregisterDevice("FB103-01"); - - DeviceSQL.Functions.ChannelManager.ChannelManager_UnregisterChannel("tcp://96.53.12.52:4000"); - - index++; - } - } -} diff --git a/DeviceSQL.Utilities.DeploymentScriptFormatter/App.config b/DeviceSQL.Utilities.DeploymentScriptFormatter/App.config deleted file mode 100644 index 731f6de..0000000 --- a/DeviceSQL.Utilities.DeploymentScriptFormatter/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/DeviceSQL.Utilities.DeploymentScriptFormatter/Program.cs b/DeviceSQL.Utilities.DeploymentScriptFormatter/Program.cs deleted file mode 100644 index fd92727..0000000 --- a/DeviceSQL.Utilities.DeploymentScriptFormatter/Program.cs +++ /dev/null @@ -1,53 +0,0 @@ -#region Imported Types - -using System; -using System.IO; - -#endregion - -namespace DeviceSQL.Utilities.DeploymentScriptFormatter -{ - class Program - { - static void Main(string[] args) - { - try - { - // This utility requires the user to copy the SQL publish output to "|>GitHub\DeviceSQL\Version 1.0\Install Script.sql" - // If only Microsoft would add a new SQLCLR Attribute to define which schema the object belongs to (the project is bound to a single schema for the CLR objects). - - var installScriptFolderName = @"..\..\..\Version 1.0\"; - var installScriptFileName = @"..\..\..\Version 1.0\Install Script.sql"; - var installScriptText = ""; - using (var streamReader = File.OpenText(installScriptFileName)) - { - installScriptText = streamReader.ReadToEnd(); - } - - installScriptText = $"CREATE DATABASE [DeviceSQL] \r\n" + - "\r\n" + - "GO \r\n" + - "USE [DeviceSQL] \r\n" + - "\r\n" + - $"{installScriptText.Substring(installScriptText.IndexOf("PRINT N'Creating [ChannelManager]...';"))}"; - - installScriptText = installScriptText.Substring(0, installScriptText.IndexOf("DECLARE @VarDecimalSupported AS BIT;")); - - installScriptText = installScriptText.Replace("[dbo].[Watchdog_", "[Watchdog].[").Replace("[dbo].[ChannelManager_", "[ChannelManager].[").Replace("[dbo].[DeviceManager_", "[DeviceManager].[").Replace("[dbo].[MODBUSMaster_", "[MODBUSMaster].[").Replace("[dbo].[ROCMaster_", "[ROCMaster].["); - - File.WriteAllText(installScriptFolderName + "Install Script.sql", installScriptText); - - Console.WriteLine("Formatting Completed"); - - Console.ReadKey(); - - } - catch (Exception ex) - { - Console.WriteLine($"Formatting Error: {ex.Message}"); - - Console.ReadKey(); - } - } - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/App.config b/DeviceSQL.Utilities.RealFLOMappingGenerator/App.config deleted file mode 100644 index 731f6de..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/App.xaml b/DeviceSQL.Utilities.RealFLOMappingGenerator/App.xaml deleted file mode 100644 index 7a5e709..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/App.xaml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/App.xaml.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/App.xaml.cs deleted file mode 100644 index 9ddb1ab..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/App.xaml.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Imported Types - -using DeviceSQL.Utilities.RealFLOMappingGenerator.Model; -using DeviceSQL.Utilities.RealFLOMappingGenerator.ViewModel; -using GalaSoft.MvvmLight.Ioc; -using Microsoft.Practices.ServiceLocation; -using System.Windows; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator -{ - public partial class App : Application - { - private void Application_Startup(object sender, StartupEventArgs e) - { - ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); - } - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Converter/BoolToVisibilityConverter.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Converter/BoolToVisibilityConverter.cs deleted file mode 100644 index 5ae0519..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Converter/BoolToVisibilityConverter.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Imported Types - -using System; -using System.Globalization; -using System.Windows; -using System.Windows.Data; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Converter -{ - public class BoolToVisibilityConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - return ((bool?)value).GetValueOrDefault() ? Visibility.Visible : Visibility.Collapsed; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Converter/NegatedBoolToVisibilityConverter.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Converter/NegatedBoolToVisibilityConverter.cs deleted file mode 100644 index 1c0f764..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Converter/NegatedBoolToVisibilityConverter.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Imported Types - -using System; -using System.Globalization; -using System.Windows; -using System.Windows.Data; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Converter -{ - public class NegatedBoolToVisibilityConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - return (!(bool?)value).GetValueOrDefault() ? Visibility.Visible : Visibility.Collapsed; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/DeviceSQL.Utilities.RealFLOMappingGenerator.csproj b/DeviceSQL.Utilities.RealFLOMappingGenerator/DeviceSQL.Utilities.RealFLOMappingGenerator.csproj deleted file mode 100644 index 865cc90..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/DeviceSQL.Utilities.RealFLOMappingGenerator.csproj +++ /dev/null @@ -1,337 +0,0 @@ - - - - - Debug - AnyCPU - {6037A772-F9F9-420A-B04E-24E4B646911A} - WinExe - DeviceSQL.Utilities.RealFLOMappingGenerator - DeviceSQL.Utilities.RealFLOMappingGenerator - v4.6.1 - 512 - {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 4 - true - true - C:\Users\jason\Documents\GitHub\DeviceSQL\Version 1.0\Utilities\RealFLO Mapping Generator\ - true - Web - true - Foreground - 7 - Days - false - false - true - http://liwt-app01.cloudapp.net/DeviceSQL/RealFLOMappingGenerator/ - http://localhost/DeviceSQL.Utilities.RealFLOMappingGenerator/ - https://github.com/jasonrichardcraig/DeviceSQL/blob/master/ReadMe.md - en-US - RealFLO Mapping Generator - Jason Richard Craig - DeviceSQL - true - publish.htm - true - 5 - 1.0.0.%2a - true - true - true - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - Resources\Images\RealFLO.ico - - - CAE5F5BEE4170D26B52B0960F9D7628C18AAE939 - - - DeviceSQL.Utilities.RealFLOMappingGenerator_TemporaryKey.pfx - - - true - - - true - - - true - - - Key.snk - - - Internet - - - Properties\app.manifest - - - - ..\packages\CommonServiceLocator.2.0.2\lib\net45\CommonServiceLocator.dll - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\EQATEC.Analytics.Monitor.dll - True - - - ..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.dll - - - ..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.Extras.dll - - - ..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.Platform.dll - - - ..\packages\HtmlAgilityPack.1.6.11\lib\Net45\HtmlAgilityPack.dll - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\SharpDX\SharpDX.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\SharpDX\SharpDX.D3DCompiler.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\SharpDX\SharpDX.Direct2D1.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\SharpDX\SharpDX.Direct3D10.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\SharpDX\SharpDX.Direct3D9.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\SharpDX\SharpDX.DXGI.dll - True - - - - - ..\packages\MvvmLightLibs.5.3.0.0\lib\net45\System.Windows.Interactivity.dll - - - - - - - - - 4.0 - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\Telerik.Windows.Cloud.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\Telerik.Windows.Controls.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\Telerik.Windows.Controls.Docking.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\Telerik.Windows.Controls.FileDialogs.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\Telerik.Windows.Controls.FixedDocumentViewers.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\Telerik.Windows.Controls.GridView.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\Telerik.Windows.Controls.Input.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\Telerik.Windows.Controls.Navigation.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\Telerik.Windows.Controls.RibbonView.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\Telerik.Windows.Data.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\Telerik.Windows.Diagrams.Core.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\Telerik.Windows.Documents.Core.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\Telerik.Windows.Documents.Fixed.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\Telerik.Windows.Documents.Spreadsheet.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\Telerik.Windows.Themes.Office2016Touch.dll - True - - - ..\lib\RCWPF\2017.3.1018.45.NoXaml\Telerik.Windows.Zip.dll - True - - - - - - - - MSBuild:Compile - Designer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NewMapWizard.xaml - - - MSBuild:Compile - Designer - - - App.xaml - Code - - - MainWindow.xaml - Code - - - Designer - MSBuild:Compile - - - - - Code - - - True - True - Resources.resx - - - True - Settings.settings - True - - - ResXFileCodeGenerator - Resources.Designer.cs - - - - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - - - - - - - - - - - - - - - - - False - Microsoft .NET Framework 4.6.1 %28x86 and x64%29 - true - - - False - .NET Framework 3.5 SP1 - false - - - - - False - RealFLO Map - RealFLOMappingGenerator - RealFLO.ico - - - - - - - - - \ No newline at end of file diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Interop/HelpDocument.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Interop/HelpDocument.cs deleted file mode 100644 index 97ec9a1..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Interop/HelpDocument.cs +++ /dev/null @@ -1,19 +0,0 @@ -#region Imported Types - -using DeviceSQL.Utilities.RealFLOMappingGenerator.ViewModel; -using Microsoft.Practices.ServiceLocation; -using System.Runtime.InteropServices; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Interop -{ - [ComVisible(true)] - public class HelpDocument - { - public void NavigateMain(string source) - { - ServiceLocator.Current.GetInstance().NavigateMainWebBrowserCommand.Execute(source); - } - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Interop/Main.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Interop/Main.cs deleted file mode 100644 index c959d7d..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Interop/Main.cs +++ /dev/null @@ -1,13 +0,0 @@ -#region Imported Types - -using System.Runtime.InteropServices; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Interop -{ - [ComVisible(true)] - public class Main - { - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Key.snk b/DeviceSQL.Utilities.RealFLOMappingGenerator/Key.snk deleted file mode 100644 index 316e8340cd29d498e246ece81c754e470341e172..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096&&DJ=n=0#AY;E@r^*wd{P-e&78AUWuM zl6=jRWHK+4aB6dxxZ=jAm(uTni^S1$hn-eqKhmE*CZ-N2D;Gp8XM4{e=xskzkq8K` zX*^Y6PDtTbTA;XVt^#tI44g_%Fu=4Tx;+Tcc;1G$l35m6r11ua8W7zidb|+T+x6Q= zv|UhL!|h-w7rLAuO~xrjWSWBpFla;VKS0Fq-C-wRaFBmS9TXVeINdIc!FMdx3MO|R z+4^8y=lb|Lur%y9UghsLoP&3B82z-QCzrl`&@xTj5&08&8P8D!y?PmuA()Lf-8V*T zPPpJpXA`v<;si0M%9!}(58GONKEHZMtz%4c}wa?ut zCaB&`yL12J8P_!UOT6sg zB@* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/MainWindow.xaml.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/MainWindow.xaml.cs deleted file mode 100644 index 30b0a85..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/MainWindow.xaml.cs +++ /dev/null @@ -1,87 +0,0 @@ -#region Imported Types - -using DeviceSQL.Utilities.RealFLOMappingGenerator.ViewModel; -using Microsoft.Practices.ServiceLocation; -using System.Windows; -using System.Windows.Navigation; -using System; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator -{ - public partial class MainWindow : Window - { - - #region Constructor - - public MainWindow() - { - InitializeComponent(); - } - - #endregion - - #region Base Class Events - - private void Window_Loaded(object sender, RoutedEventArgs e) - { - var mainViewModel = ServiceLocator.Current.GetInstance(); - mainViewModel.NavigateHelpDocumentWebBrowserCommand = new GalaSoft.MvvmLight.CommandWpf.RelayCommand(NavigateHelpDocumentWebBrowser); - mainViewModel.NavigateMainWebBrowserCommand = new GalaSoft.MvvmLight.CommandWpf.RelayCommand(NavigateMainWebBrowser); - MainWebBrowser.Navigate("about:blank"); - HelpDocumentWebBrowser.Navigate("about:blank"); - } - - #endregion - - #region Web Browser Events - - private void MainWebBrowser_Navigating(object sender, NavigatingCancelEventArgs e) - { - - } - - private void MainWebBrowser_Navigated(object sender, NavigationEventArgs e) - { - var mainViewModel = ServiceLocator.Current.GetInstance(); - if (mainViewModel.MainWebBrowserObjectForScripting != MainWebBrowser.ObjectForScripting) - { - MainWebBrowser.ObjectForScripting = mainViewModel.MainWebBrowserObjectForScripting; - } - } - - private void HelpDocumentWebBrowser_Navigating(object sender, NavigatingCancelEventArgs e) - { - - } - - private void HelpDocumentWebBrowser_Navigated(object sender, NavigationEventArgs e) - { - var mainViewModel = ServiceLocator.Current.GetInstance(); - if (mainViewModel.HelpDocumentWebBrowserObjectForScripting != HelpDocumentWebBrowser.ObjectForScripting) - { - HelpDocumentWebBrowser.ObjectForScripting = mainViewModel.HelpDocumentWebBrowserObjectForScripting; - } - } - - #endregion - - #region Navigation Methods - - private void NavigateMainWebBrowser(string source) - { - MainWebBrowser.Navigate(source); - } - - private void NavigateHelpDocumentWebBrowser(string source) - { - HelpDocumentWebBrowser.Navigate(source); - } - - #endregion - - } - -} - diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/DataService.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/DataService.cs deleted file mode 100644 index a7871c5..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/DataService.cs +++ /dev/null @@ -1,175 +0,0 @@ -#region Imported Types - -using HtmlAgilityPack; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.Serialization.Formatters.Binary; -using System.Windows; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Model -{ - public class DataService - { - - public string GetVersion() - { - return Assembly.GetEntryAssembly().GetName().Version.ToString(); - } - - public Map NewMap(string fileName, string chmFileName) - { - var map = new Map() - { - Id = Guid.NewGuid(), - HelpFileBytes = File.ReadAllBytes(chmFileName), - EnronArchives = new List(), - EnronEvents = new List(), - EnronRegisters = new List(), - TeleBUSArchives = new List(), - TeleBUSEvents = new List(), - TeleBUSRegisters = new List() - }; - return map; - } - - public Map LoadMap(string fileName) - { - using (var fileStream = new FileStream(fileName, FileMode.Open)) - { - return new BinaryFormatter().Deserialize(fileStream) as Map; - } - } - - public void SaveMap(Map map, string fileName) - { - using (var fileStream = new FileStream(fileName, FileMode.OpenOrCreate)) - { - new BinaryFormatter().Serialize(fileStream, map); - } - } - - public void ExtractCHMFile(Map map, out string chmFileName, out string decompiledCHMFolderName) - { - var formattedMapId = map.Id.ToString().Replace("-", ""); - var chmFolderName = $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\RealFLOMappingGenerator"; - - chmFileName = $"{chmFolderName}\\rfm.{formattedMapId}.chm"; - decompiledCHMFolderName = $"{chmFolderName}\\rfm.{formattedMapId}.decompiled"; - - if (!Directory.Exists(chmFolderName)) - { - Directory.CreateDirectory(chmFolderName); - } - - if (!Directory.Exists(decompiledCHMFolderName)) - { - Directory.CreateDirectory(decompiledCHMFolderName); - } - - File.WriteAllBytes(chmFileName, map.HelpFileBytes); - - using (var process = Process.Start("hh.exe", $" -decompile {decompiledCHMFolderName} {chmFileName}")) - { - if (process.WaitForExit(30000)) - { - using (var styleFileStream = File.Create($"{decompiledCHMFolderName}\\rfm.style.css")) - using (var treeFileStream = File.Create($"{decompiledCHMFolderName}\\rfm.index.js")) - { - Application.GetResourceStream(new Uri("Resources/Styles/rfm.style.css", UriKind.RelativeOrAbsolute)).Stream.CopyTo(styleFileStream); - Application.GetResourceStream(new Uri("Resources/Scripts/rfm.index.js", UriKind.RelativeOrAbsolute)).Stream.CopyTo(treeFileStream); - } - - foreach (var htmFileInfo in new DirectoryInfo(decompiledCHMFolderName).GetFiles("*.htm", SearchOption.AllDirectories)) - { - var chmHTMLDocument = new HtmlDocument(); - - chmHTMLDocument.Load(htmFileInfo.FullName); - File.WriteAllText(htmFileInfo.FullName, $"\r\n{ chmHTMLDocument.DocumentNode.InnerHtml }", System.Text.Encoding.UTF8); - } - } - else - { - throw new TimeoutException("HTML help decompiler timed out"); - } - } - } - - public string CreateIndexHTMLDocument(string chmFolderName) - { - var hhcFileInfo = new DirectoryInfo(chmFolderName).EnumerateFiles("*.hhc").FirstOrDefault(); - - if (hhcFileInfo != null) - { - var hhcHTMLDocument = new HtmlDocument(); - var destinationHHCFileName = $"{hhcFileInfo.DirectoryName}\\rfm.index.html"; - var defaultSource = ""; - - //file:///C:/Users/jason/Desktop/Realflo%20Reference%20Manual.htm - - hhcHTMLDocument.OptionUseIdAttribute = true; - hhcHTMLDocument.OptionOutputAsXml = true; - hhcHTMLDocument.Load(hhcFileInfo.FullName); - - hhcHTMLDocument.DocumentNode.ChildNodes.Where(node => node.Name == "#comment" && node.InnerText.StartsWith(""), htmlNode.FirstChild); - } - - hhcHTMLDocument.DocumentNode.SelectSingleNode("//head").AppendChild(HtmlNode.CreateNode("")); - hhcHTMLDocument.DocumentNode.SelectSingleNode("//head").AppendChild(HtmlNode.CreateNode("")); - hhcHTMLDocument.DocumentNode.SelectSingleNode("//head").AppendChild(HtmlNode.CreateNode("")); - hhcHTMLDocument.DocumentNode.SelectSingleNode("//head").AppendChild(HtmlNode.CreateNode("")); - - foreach (var objectHTMLNode in hhcHTMLDocument.DocumentNode.SelectNodes("//object")) - { - switch (objectHTMLNode.GetAttributeValue("type", null)) - { - case "text/sitemap": - { - var name = objectHTMLNode.ChildNodes.FirstOrDefault(htmlNode => htmlNode.NodeType == HtmlNodeType.Element && htmlNode.Name == "param" && htmlNode.GetAttributeValue("name", "") == "Name")?.GetAttributeValue("value", ""); - var imageNumber = objectHTMLNode.ChildNodes.FirstOrDefault(htmlNode => htmlNode.NodeType == HtmlNodeType.Element && htmlNode.Name == "param" && htmlNode.GetAttributeValue("name", "") == "ImageNumber")?.GetAttributeValue("value", ""); - var local = objectHTMLNode.ChildNodes.FirstOrDefault(htmlNode => htmlNode.NodeType == HtmlNodeType.Element && htmlNode.Name == "param" && htmlNode.GetAttributeValue("name", "") == "Local")?.GetAttributeValue("value", ""); - - objectHTMLNode.Name = "a"; - objectHTMLNode.InnerHtml = name; - objectHTMLNode.Attributes.Add("href", $"#_{local}_"); - objectHTMLNode.Attributes.Add("onclick", $"javascript: window.external.NavigateMain('{chmFolderName.Replace("\\","\\\\")}\\\\{local}');"); - - if(defaultSource == "") - { - defaultSource = $"{chmFolderName}\\{local}"; - } - } - break; - default: - { - objectHTMLNode.RemoveAllChildren(); - objectHTMLNode.Remove(); - } - break; - } - } - - hhcHTMLDocument.DocumentNode.SelectSingleNode("//head").AppendChild(HtmlNode.CreateNode($"")); - - File.WriteAllText(destinationHHCFileName, $"\r\n\r\n{ hhcHTMLDocument.DocumentNode.InnerHtml }", System.Text.Encoding.UTF8); - - return destinationHHCFileName; - } - else - { - return null; - } - } - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/DialogService.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/DialogService.cs deleted file mode 100644 index 74bef13..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/DialogService.cs +++ /dev/null @@ -1,191 +0,0 @@ -#region Imported Types - -using DeviceSQL.Utilities.RealFLOMappingGenerator.ViewModel; -using Microsoft.Practices.ServiceLocation; -using Microsoft.Win32; -using System; -using System.IO; -using Telerik.Windows.Controls; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Model -{ - public class DialogService - { - - #region Properties - - public DataService DataService - { - get - { - return ServiceLocator.Current.GetInstance(); - } - } - - #endregion - - #region Dialog Methods - - public void ShowErrorMessage(string errorMessage) - { - RadWindow.Alert(errorMessage); - } - - public string OpenCreateMapFileDialog() - { - var saveFileDialog = new SaveFileDialog() - { - Title = "Set Map File Destination", - FileName = "RealFLO Map.rfm", - InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), - DefaultExt = ".chm", - Filter = "RealFLO Map Files|*.rfm", - OverwritePrompt = true, - CreatePrompt = true, - ValidateNames = true, - CheckPathExists = true, - }; - - var dialogResult = saveFileDialog.ShowDialog(); - - if (dialogResult.HasValue && dialogResult.Value) - { - try - { - using (var fileStream = File.Create(saveFileDialog.FileName)) - { - return saveFileDialog.FileName; - } - } - catch (Exception ex) - { - ShowErrorMessage($"Error creating map file: {ex.Message}"); - return null; - } - - } - else - { - return null; - } - - } - - public string OpenSelectRealFLOHelpFileDialog(string fileName) - { - - var fileInfo = new FileInfo(fileName); - - var openFileDialog = new OpenFileDialog() - { - Title = "Select RealFLO Help File", - FileName = fileInfo.Name, - InitialDirectory = fileInfo.DirectoryName, - DefaultExt = ".chm", - Filter = "Help Files|*.chm" - }; - - var dialogResult = openFileDialog.ShowDialog(); - - if (dialogResult.HasValue && dialogResult.Value) - { - return openFileDialog.FileName; - } - else - { - return null; - } - } - - public bool? ShowSaveBeforeProceedingDialog() - { - var dialogResult = (bool?)null; - var dialogParameters = new DialogParameters() - { - Content = "Would you like to save before proceeding?", - OkButtonContent = "Yes", - CancelButtonContent = "No", - Closed = (s, e) => - { - dialogResult = e.DialogResult; - } - }; - - RadWindow.Confirm(dialogParameters); - - return dialogResult; - - } - - public Map OpenNewMapWizardDialog() - { - var newMapWizard = new Wizard.NewMapWizard() - { - Owner = App.Current.MainWindow - }; - - var dialogResult = newMapWizard.ShowDialog(); - - if (dialogResult.HasValue && dialogResult.Value) - { - try - { - var newMapWizardViewModel = ServiceLocator.Current.GetInstance(); - - return DataService.NewMap(newMapWizardViewModel.FileName, newMapWizardViewModel.CHMFileName); - - } - catch (Exception ex) - { - var dialogParameters = new DialogParameters() - { - Content = $"Error creating new map: {ex.Message}" - }; - - RadWindow.Alert(dialogParameters); - return null; - } - } - else - { - return null; - } - } - - public Map OpenMapFileDialog() - { - - var openFileDialog = new OpenFileDialog() - { - Title = "Select RealFLO Map File", - InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), - DefaultExt = ".rfm", - Filter = "RealFLO Map Files|*.rfm" - }; - - var dialogResult = openFileDialog.ShowDialog(); - - if (dialogResult.HasValue && dialogResult.Value) - { - try - { - return DataService.LoadMap(openFileDialog.FileName); - } - catch (Exception ex) - { - ShowErrorMessage($"Error opening map file: {ex.Message}"); - } - return null; - } - else - { - return null; - } - } - - #endregion - - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Enron/Archive.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Enron/Archive.cs deleted file mode 100644 index d45f49b..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Enron/Archive.cs +++ /dev/null @@ -1,19 +0,0 @@ -#region Imported Types - -using System; -using System.Collections.Generic; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Model.Enron -{ - [Serializable] - public class Archive - { - public List Fields - { - get; - set; - } - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Enron/ArchiveField.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Enron/ArchiveField.cs deleted file mode 100644 index 1e94155..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Enron/ArchiveField.cs +++ /dev/null @@ -1,13 +0,0 @@ -#region Imported Types - -using System; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Model.TeleBUS -{ - public class ArchiveField - { - - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Enron/Event.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Enron/Event.cs deleted file mode 100644 index 238a9df..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Enron/Event.cs +++ /dev/null @@ -1,14 +0,0 @@ -#region Imported Types - -using System; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Model.Enron -{ - [Serializable] - public class Event - { - - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Enron/Register.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Enron/Register.cs deleted file mode 100644 index f9ca9f7..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Enron/Register.cs +++ /dev/null @@ -1,13 +0,0 @@ -#region Imported Types - -using System; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Model.Enron -{ - [Serializable] - public class Register - { - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Map.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Map.cs deleted file mode 100644 index bc391fd..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/Map.cs +++ /dev/null @@ -1,67 +0,0 @@ -#region Imported Types - -using System; -using System.Collections.Generic; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Model -{ - [Serializable] - public class Map - { - - #region Properties - - public Guid Id - { - get; - set; - } - - public byte[] HelpFileBytes - { - get; - set; - } - - public List EnronRegisters - { - get; - set; - } - - public List TeleBUSRegisters - { - get; - set; - } - - public List EnronArchives - { - get; - set; - } - - public List TeleBUSArchives - { - get; - set; - } - - public List EnronEvents - { - get; - set; - } - - public List TeleBUSEvents - { - get; - set; - } - - #endregion - - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/Archive.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/Archive.cs deleted file mode 100644 index 3caa0c2..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/Archive.cs +++ /dev/null @@ -1,13 +0,0 @@ -#region Imported Types - -using System; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Model.TeleBUS -{ - [Serializable] - public class Archive - { - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/ArchiveCommand.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/ArchiveCommand.cs deleted file mode 100644 index feed439..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/ArchiveCommand.cs +++ /dev/null @@ -1,13 +0,0 @@ -#region Imported Types - -using System; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Model.TeleBUS -{ - [Serializable] - public class ArchiveCommand - { - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/ArchiveField.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/ArchiveField.cs deleted file mode 100644 index 8e5bf7c..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/ArchiveField.cs +++ /dev/null @@ -1,14 +0,0 @@ -#region Imported Types - -using System; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Model.Enron -{ - [Serializable] - public class ArchiveField - { - - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/ConfigurationCommand.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/ConfigurationCommand.cs deleted file mode 100644 index fa437a2..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/ConfigurationCommand.cs +++ /dev/null @@ -1,13 +0,0 @@ -#region Imported Types - -using System; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Model.TeleBUS -{ - [Serializable] - public class ConfigurationCommand - { - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/Event.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/Event.cs deleted file mode 100644 index 00ad842..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/Event.cs +++ /dev/null @@ -1,14 +0,0 @@ -#region Imported Types - -using System; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Model.TeleBUS -{ - [Serializable] - public class Event - { - - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/Register.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/Register.cs deleted file mode 100644 index f4e4bee..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Model/TeleBUS/Register.cs +++ /dev/null @@ -1,14 +0,0 @@ -#region Imported Types - -using System; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Model.TeleBUS -{ - [Serializable] - public class Register - { - - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/AssemblyInfo.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/AssemblyInfo.cs deleted file mode 100644 index 8097267..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Reflection; -using System.Resources; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Windows; - -// 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("DeviceSQL.Utilities.RealFLOMappingGenerator")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("DeviceSQL.Utilities.RealFLOMappingGenerator")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[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)] - -//In order to begin building localizable applications, set -//CultureYouAreCodingWith in your .csproj file -//inside a . For example, if you are using US english -//in your source files, set the to en-US. Then uncomment -//the NeutralResourceLanguage attribute below. Update the "en-US" in -//the line below to match the UICulture setting in the project file. - -//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] - - -[assembly: ThemeInfo( - ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located - //(used if a resource is not found in the page, - // or application resource dictionaries) - ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located - //(used if a resource is not found in the page, - // app, or any theme specific resource dictionaries) -)] - - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/Resources.Designer.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/Resources.Designer.cs deleted file mode 100644 index 42ded07..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/Resources.Designer.cs +++ /dev/null @@ -1,71 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Properties -{ - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources - { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() - { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager - { - get - { - if ((resourceMan == null)) - { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DeviceSQL.Utilities.RealFLOMappingGenerator.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture - { - get - { - return resourceCulture; - } - set - { - resourceCulture = value; - } - } - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/Settings.settings b/DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/Settings.settings deleted file mode 100644 index 033d7a5..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/app.manifest b/DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/app.manifest deleted file mode 100644 index f0a58bd..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Properties/app.manifest +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/RealFLO.ico b/DeviceSQL.Utilities.RealFLOMappingGenerator/RealFLO.ico deleted file mode 100644 index 49da11f4f0c47ea23faaa3b0484e571ba64320f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 372526 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 diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/RealFLO_24x24.png b/DeviceSQL.Utilities.RealFLOMappingGenerator/RealFLO_24x24.png deleted file mode 100644 index 2ec04c2308db5d55c1af688df42445581254dd8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 351 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 diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Resources/Images/RealFLO_24x24.png b/DeviceSQL.Utilities.RealFLOMappingGenerator/Resources/Images/RealFLO_24x24.png deleted file mode 100644 index a3df78fc4500efc847cf7e37c7117128c95d921b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 577 zcmV-H0>1r;P)WFU8GbZ8()Nlj2>E@cM*00E^*L_t(Y$IX^KNW)MR zg}=m9+gFT(acUux(9D8Pb#ibMyBg4~AUG@StaNj5(n+Cn=MLSREIJ3=3U+D-wHoP< zt%Ek$pJ-a1;2m!se7T%+&wEO3XSv58mO9B{Md*JAh-~h%cyY_@%7%Qv%u)=IIsjlk zottQqKmd_CKoL66r~4>EC$hOK51nS;akhMmq;_zOp0??^Abn8_@)~XzUW?HnJ@<6XsaZru89Dr)X=(*1$0BIU@>(#Ng zl?HgPRnbgqXsWo(2_8lOnwg;O+{gj6oieHsBV?@sFuSsWBJ{vIsJ}(TT=LWJQ9FYo zbmr5!uWZ^2q=ojggW`m&RoYIOZv6p()?LZ#t47@0k6!^ZOR*90G&2Ff)3NRK8s|p< z82Nke`#9bDU=I+rvlB;g)Xw_q*8eH(d#H6P4zKx>fy2W~*00Cx*4WsN+8KWhdTt}I z{rp_ia~u8u%}lV6%};&*zFZvoi|iK80w<*JQoc5LD_#!XC;#eIF-?5{ueXVaj>i@g P00000NkvXXu0mjf&8Pl} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Resources/Images/RealFLO_32x32.png b/DeviceSQL.Utilities.RealFLOMappingGenerator/Resources/Images/RealFLO_32x32.png deleted file mode 100644 index 906aac068b5a0eb0e3e838d3a8391377e299946e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 677 zcmV;W0$TlvP)WFU8GbZ8()Nlj2>E@cM*00Id~L_t(o!_}8POyXb| z$Nz6BAHI6kp`AJ~VXiYqCzvpC^7xY>Bm8Z|I&vyy-_wB~tADD$`i7ZGXo3JrMk$4qDnvPhSy&FL0 zQ6f~qV!?!@>X1|&oznN|dSGs23zDh>04U2Nr0LTG2x&Sf%fs%p&@G<;0OoUr=>brd z2LN=-Cuo~R44QRBk{QTxLp%VX3Zg0I`Fbb*a~oUY0b=P*0Ko0pPuQK-(|HMYr-eu| zBOV}!*jR%cH_*4LFP7-U04U32srYNCr0Q7swg*BLC_9I47*z8ra5t2LW_sVM zjvNV9K<~-M}gKZaZv2gmnl`NKKh^E+>PWbhW6O*~#dP#b< zKkg_W0f?rUTT(&m+#KdIj}45udP@0RP#zqE1vjT?iWKI>01}U0C=+5 zPugbD6Zf$I-SV+7Ex!kbJ>%wR7lXDpkw5Rh;lu#6M0RGzwL}(=h0n1ki53zq00000 LNkvXXu0mjf-(e#Z diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Resources/Scripts/rfm.index.js b/DeviceSQL.Utilities.RealFLOMappingGenerator/Resources/Scripts/rfm.index.js deleted file mode 100644 index bc0153a..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Resources/Scripts/rfm.index.js +++ /dev/null @@ -1,3 +0,0 @@ -$(document).ready(function () { - window.external.NavigateMain(defaultSource); -}); diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Resources/Styles/rfm.style.css b/DeviceSQL.Utilities.RealFLOMappingGenerator/Resources/Styles/rfm.style.css deleted file mode 100644 index 56759d9..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Resources/Styles/rfm.style.css +++ /dev/null @@ -1,84 +0,0 @@ -body, a { - color: #3B4C56; - font-family: sans-serif; - font-size: 14px; - text-decoration: none; -} - -#logo { - width: 505px; - margin: 0 auto; - text-align: center; -} - -#pgtitle { - margin: 0px 0px 20px; - font-size: 18pt; -} - -a { - cursor: pointer; -} - -.tree ul { - list-style: none outside none; -} - -.tree li a { - line-height: 25px; -} - -.tree > ul > li > a { - color: #3B4C56; - display: block; - font-weight: normal; - position: relative; - text-decoration: none; -} - -.tree li.parent > a { - padding: 0 0 0 28px; -} - - .tree li.parent > a:before { - background-image: url("../images/plus_minus_icons.png"); - background-position: 25px center; - content: ""; - display: block; - height: 21px; - left: 0; - position: absolute; - top: 2px; - vertical-align: middle; - width: 23px; - } - -.tree ul li.active > a:before { - background-position: 0 center; -} - -.tree ul li ul { - border-left: 1px solid #D9DADB; - display: none; - margin: 0 0 0 12px; - overflow: hidden; - padding: 0 0 0 25px; -} - - .tree ul li ul li { - position: relative; - } - - .tree ul li ul li:before { - border-bottom: 1px dashed #E2E2E3; - content: ""; - left: -20px; - position: absolute; - top: 12px; - width: 15px; - } - -#wrapper { - margin: 0 auto; - width: 300px; -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/Enron/ArchiveViewModel.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/Enron/ArchiveViewModel.cs deleted file mode 100644 index abd2fa1..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/Enron/ArchiveViewModel.cs +++ /dev/null @@ -1,35 +0,0 @@ -#region Imported Types - -using DeviceSQL.Utilities.RealFLOMappingGenerator.Model.Enron; -using GalaSoft.MvvmLight; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.ViewModel.Enron -{ - public class ArchiveViewModel : TrackableViewModelBase - { - #region Fields - - private Archive archive; - - #endregion - - #region Properties - - public Archive Archive - { - get - { - return archive; - } - set - { - archive = value; - RaisePropertyChanged("Archive"); - } - } - - #endregion - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/Enron/EventViewModel.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/Enron/EventViewModel.cs deleted file mode 100644 index 105e4a4..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/Enron/EventViewModel.cs +++ /dev/null @@ -1,35 +0,0 @@ -#region Imported Types - -using DeviceSQL.Utilities.RealFLOMappingGenerator.Model.Enron; -using GalaSoft.MvvmLight; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.ViewModel.Enron -{ - public class EventViewModel : TrackableViewModelBase - { - #region Fields - - private Event _event; - - #endregion - - #region Imported Types - - public Event Event - { - get - { - return _event; - } - set - { - _event = value; - RaisePropertyChanged("Event"); - } - } - - #endregion - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/Enron/RegisterViewModel.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/Enron/RegisterViewModel.cs deleted file mode 100644 index c2e7da0..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/Enron/RegisterViewModel.cs +++ /dev/null @@ -1,37 +0,0 @@ -#region Imported Types - -using DeviceSQL.Utilities.RealFLOMappingGenerator.Model.Enron; -using GalaSoft.MvvmLight; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.ViewModel.Enron -{ - public class RegisterViewModel : TrackableViewModelBase - { - - #region Fields - - private Register register; - - #endregion - - #region Imported Types - - public Register Register - { - get - { - return register; - } - set - { - register = value; - RaisePropertyChanged("Register"); - } - } - - #endregion - - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/ExportMapWizardViewModel.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/ExportMapWizardViewModel.cs deleted file mode 100644 index ea48dce..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/ExportMapWizardViewModel.cs +++ /dev/null @@ -1,13 +0,0 @@ -#region Imported Types - -using DeviceSQL.Utilities.RealFLOMappingGenerator.Model; -using GalaSoft.MvvmLight; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.ViewModel -{ - public class ExportMapWizardViewModel : ViewModelBase - { - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/MainViewModel.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/MainViewModel.cs deleted file mode 100644 index 4685bba..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/MainViewModel.cs +++ /dev/null @@ -1,638 +0,0 @@ -#region Imported Types - -using DeviceSQL.Utilities.RealFLOMappingGenerator.Model; -using GalaSoft.MvvmLight; -using GalaSoft.MvvmLight.CommandWpf; -using Microsoft.Practices.ServiceLocation; -using System; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.IO; -using System.Linq; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.ViewModel -{ - public class MainViewModel : ViewModelBase - { - - #region Fields - - private Guid id; - private byte[] helpFileBytes; - private string currentMapFileName; - private string currentCHMFileName; - private string currentCHMFolderName; - private string mainWebBrowserPanelHeaderText = "about:blank"; - private Interop.Main mainWebBrowserObjectForScripting; - private Interop.HelpDocument helpDocumentWebBrowserObjectForScripting; - private ObservableCollection enronRegisterViewModels; - private ObservableCollection enronArchiveViewModels; - private ObservableCollection enronEventViewModels; - private ObservableCollection teleBUSRegisterViewModels; - private ObservableCollection teleBUSArchiveViewModels; - private ObservableCollection teleBUSEventViewModels; - private bool hasChanged; - - #endregion - - #region Properties - - public Guid Id - { - get - { - return id; - } - set - { - id = value; - RaisePropertyChanged("Id"); - } - } - - public byte[] HelpFileBytes - { - get - { - return helpFileBytes; - } - set - { - helpFileBytes = value; - RaisePropertyChanged("HelpFileBytes"); - } - } - - public DialogService DialogService - { - get - { - return ServiceLocator.Current.GetInstance(); - } - } - - public DataService DataService - { - get - { - return ServiceLocator.Current.GetInstance(); - } - } - - public ObservableCollection EnronRegisterViewModels - { - get - { - return enronRegisterViewModels; - } - set - { - if (enronRegisterViewModels != null) - { - enronRegisterViewModels.CollectionChanged -= EnronRegisterViewModels_CollectionChanged; - } - - enronRegisterViewModels = value; - - if (enronRegisterViewModels != null) - { - enronRegisterViewModels.CollectionChanged += EnronRegisterViewModels_CollectionChanged; - } - } - } - - public ObservableCollection EnronArchiveViewModels - { - get - { - return enronArchiveViewModels; - } - set - { - if (enronArchiveViewModels != null) - { - enronArchiveViewModels.CollectionChanged -= EnronArchiveViewModels_CollectionChanged; - } - - enronArchiveViewModels = value; - - if (enronArchiveViewModels != null) - { - enronArchiveViewModels.CollectionChanged += EnronArchiveViewModels_CollectionChanged; - } - } - } - - public ObservableCollection EnronEventViewModels - { - get - { - return enronEventViewModels; - } - set - { - if (enronEventViewModels != null) - { - enronEventViewModels.CollectionChanged -= EnronEventViewModels_CollectionChanged; - } - - enronEventViewModels = value; - - if (enronEventViewModels != null) - { - enronEventViewModels.CollectionChanged += EnronEventViewModels_CollectionChanged; - } - } - } - - public ObservableCollection TeleBUSRegisterViewModels - { - get - { - return teleBUSRegisterViewModels; - } - set - { - if (teleBUSRegisterViewModels != null) - { - teleBUSRegisterViewModels.CollectionChanged -= TeleBUSRegisterViewModels_CollectionChanged; - } - - teleBUSRegisterViewModels = value; - - if (teleBUSRegisterViewModels != null) - { - teleBUSRegisterViewModels.CollectionChanged += TeleBUSRegisterViewModels_CollectionChanged; - } - } - } - - public ObservableCollection TeleBUSArchiveViewModels - { - get - { - return teleBUSArchiveViewModels; - } - set - { - if (teleBUSArchiveViewModels != null) - { - teleBUSArchiveViewModels.CollectionChanged -= TeleBUSArchiveViewModels_CollectionChanged; - } - - teleBUSArchiveViewModels = value; - - if (teleBUSArchiveViewModels != null) - { - teleBUSArchiveViewModels.CollectionChanged += TeleBUSArchiveViewModels_CollectionChanged; - } - } - } - - public ObservableCollection TeleBUSEventViewModels - { - get - { - return teleBUSEventViewModels; - } - set - { - if (teleBUSEventViewModels != null) - { - teleBUSEventViewModels.CollectionChanged -= TeleBUSEventViewModels_CollectionChanged; - } - - teleBUSEventViewModels = value; - - if (teleBUSEventViewModels != null) - { - teleBUSEventViewModels.CollectionChanged += TeleBUSEventViewModels_CollectionChanged; - } - } - } - - public string Version - { - get - { - return DataService.GetVersion(); - } - } - - public Interop.Main MainWebBrowserObjectForScripting - { - get - { - return mainWebBrowserObjectForScripting; - } - set - { - mainWebBrowserObjectForScripting = value; - RaisePropertyChanged("MainWebBrowserObjectForScripting"); - } - } - - public Interop.HelpDocument HelpDocumentWebBrowserObjectForScripting - { - get - { - return helpDocumentWebBrowserObjectForScripting; - } - set - { - helpDocumentWebBrowserObjectForScripting = value; - RaisePropertyChanged("HelpDocumentWebBrowserObjectForScripting"); - } - } - - public RelayCommand NewCommand - { - get; - set; - } - - public RelayCommand OpenCommand - { - get; - set; - } - - public RelayCommand SaveCommand - { - get; - set; - } - - public RelayCommand ExportCommand - { - get; - set; - } - - public RelayCommand CloseCommand - { - get; - set; - } - - public RelayCommand NavigateHelpDocumentWebBrowserCommand - { - get; - set; - } - - public RelayCommand NavigateMainWebBrowserCommand - { - get; - set; - } - - public string MainWebBrowserPanelHeaderText - { - get - { - return mainWebBrowserPanelHeaderText; - } - set - { - mainWebBrowserPanelHeaderText = value; - RaisePropertyChanged("MainWebBrowserPanelHeaderText"); - } - } - - public bool CurrentMapFileExists - { - get - { - return File.Exists(CurrentCHMFileName); - } - } - - public string CurrentMapFileName - { - get - { - return currentMapFileName; - } - set - { - currentMapFileName = value; - RaisePropertyChanged("CurrentMapFileName"); - } - } - - public string CurrentCHMFileName - { - get - { - return currentCHMFileName; - } - set - { - currentCHMFileName = value; - RaisePropertyChanged("CurrentCHMFileName"); - } - } - - public string CurrentCHMFolderName - { - get - { - return currentCHMFolderName; - } - set - { - currentCHMFolderName = value; - RaisePropertyChanged("CurrentCHMFolderName"); - } - } - - public bool HasChanged - { - get - { - return hasChanged; - } - set - { - hasChanged = value; - RaisePropertyChanged("HasChanged"); - } - } - - #endregion - - #region Constructor - - public MainViewModel() - { - NewCommand = new RelayCommand(New); - OpenCommand = new RelayCommand(Open); - SaveCommand = new RelayCommand(Save, CanSave); - ExportCommand = new RelayCommand(Export, CanExport); - CloseCommand = new RelayCommand(Close, CanClose); - MainWebBrowserObjectForScripting = new Interop.Main(); - HelpDocumentWebBrowserObjectForScripting = new Interop.HelpDocument(); - } - - #endregion - - #region Command Methods - - private void New() - { - if (CanSave()) - { - var showSaveBeforeProceedingDialogResult = DialogService.ShowSaveBeforeProceedingDialog(); - if (showSaveBeforeProceedingDialogResult.HasValue) - { - if (showSaveBeforeProceedingDialogResult.Value) - { - Save(); - } - } - else - { - return; - } - } - - var map = DialogService.OpenNewMapWizardDialog(); - - if (map != null) - { - LoadMap(map); - } - } - - private void Open() - { - var map = DialogService.OpenMapFileDialog(); - if (map != null) - { - LoadMap(map); - } - } - private bool CanSave() - { - return HasChanged; - } - - private void Save() - { - try - { - var map = new Map() - { - Id = Id, - HelpFileBytes = HelpFileBytes, - EnronRegisters = EnronRegisterViewModels?.Select(enronRegisterViewModel => enronRegisterViewModel.Register).ToList(), - EnronArchives = EnronArchiveViewModels?.Select(enronArchiveViewModel => enronArchiveViewModel.Archive).ToList(), - EnronEvents = EnronEventViewModels?.Select(enronEventViewModel => enronEventViewModel.Event).ToList(), - TeleBUSRegisters = TeleBUSRegisterViewModels?.Select(teleBUSRegisterViewModel => teleBUSRegisterViewModel.Register).ToList(), - TeleBUSArchives = teleBUSArchiveViewModels?.Select(teleBUSArchiveViewModel => teleBUSArchiveViewModel.Archive).ToList(), - TeleBUSEvents = TeleBUSEventViewModels?.Select(teleBUSEventViewModel => teleBUSEventViewModel.Event).ToList() - }; - DataService.SaveMap(map, CurrentMapFileName); - } - catch (Exception ex) - { - DialogService.ShowErrorMessage($"Error saving map: {ex.Message}"); - } - } - - private bool CanExport() - { - return false; - } - - private void Export() - { - - } - - private bool CanClose() - { - return !Id.Equals(Guid.Empty); - } - - private void Close() - { - if (CanSave()) - { - var showSaveBeforeProceedingDialogResult = DialogService.ShowSaveBeforeProceedingDialog(); - if (showSaveBeforeProceedingDialogResult.HasValue) - { - if (showSaveBeforeProceedingDialogResult.Value) - { - Save(); - } - } - else - { - return; - } - } - Id = Guid.Empty; - CurrentMapFileName = null; - CurrentCHMFileName = null; - HelpFileBytes = new byte[] { }; - EnronArchiveViewModels = new ObservableCollection(); - EnronRegisterViewModels = new ObservableCollection(); - EnronEventViewModels = new ObservableCollection(); - TeleBUSArchiveViewModels = new ObservableCollection(); - TeleBUSRegisterViewModels = new ObservableCollection(); - TeleBUSEventViewModels = new ObservableCollection(); - } - - #endregion - - #region Observable Collection Events - - private void EnronRegisterViewModels_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) - { - switch (e.Action) - { - case NotifyCollectionChangedAction.Add: - break; - case NotifyCollectionChangedAction.Move: - break; - case NotifyCollectionChangedAction.Remove: - break; - case NotifyCollectionChangedAction.Replace: - break; - case NotifyCollectionChangedAction.Reset: - break; - } - } - - private void EnronArchiveViewModels_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) - { - switch (e.Action) - { - case NotifyCollectionChangedAction.Add: - break; - case NotifyCollectionChangedAction.Move: - break; - case NotifyCollectionChangedAction.Remove: - break; - case NotifyCollectionChangedAction.Replace: - break; - case NotifyCollectionChangedAction.Reset: - break; - } - } - - private void EnronEventViewModels_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) - { - switch (e.Action) - { - case NotifyCollectionChangedAction.Add: - break; - case NotifyCollectionChangedAction.Move: - break; - case NotifyCollectionChangedAction.Remove: - break; - case NotifyCollectionChangedAction.Replace: - break; - case NotifyCollectionChangedAction.Reset: - break; - } - } - - private void TeleBUSRegisterViewModels_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) - { - switch (e.Action) - { - case NotifyCollectionChangedAction.Add: - break; - case NotifyCollectionChangedAction.Move: - break; - case NotifyCollectionChangedAction.Remove: - break; - case NotifyCollectionChangedAction.Replace: - break; - case NotifyCollectionChangedAction.Reset: - break; - } - } - - private void TeleBUSArchiveViewModels_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) - { - switch (e.Action) - { - case NotifyCollectionChangedAction.Add: - break; - case NotifyCollectionChangedAction.Move: - break; - case NotifyCollectionChangedAction.Remove: - break; - case NotifyCollectionChangedAction.Replace: - break; - case NotifyCollectionChangedAction.Reset: - break; - } - } - - private void TeleBUSEventViewModels_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) - { - switch (e.Action) - { - case NotifyCollectionChangedAction.Add: - break; - case NotifyCollectionChangedAction.Move: - break; - case NotifyCollectionChangedAction.Remove: - break; - case NotifyCollectionChangedAction.Replace: - break; - case NotifyCollectionChangedAction.Reset: - break; - } - } - - #endregion - - #region Helper Methods - - private void LoadMap(Map map) - { - if (map != null) - { - try - { - Id = map.Id; - DataService.ExtractCHMFile(map, out currentCHMFileName, out currentCHMFolderName); - HelpFileBytes = map.HelpFileBytes; - EnronArchiveViewModels = new ObservableCollection(map.EnronArchives.Select(enronArchive => new Enron.ArchiveViewModel() { Archive = enronArchive })); - EnronRegisterViewModels = new ObservableCollection(map.EnronRegisters.Select(enronArchive => new Enron.RegisterViewModel() { Register = enronArchive })); - EnronEventViewModels = new ObservableCollection(map.EnronEvents.Select(enronEvent => new Enron.EventViewModel() { Event = enronEvent })); - TeleBUSArchiveViewModels = new ObservableCollection(map.TeleBUSArchives.Select(teleBUSArchive => new TeleBUS.ArchiveViewModel() { Archive = teleBUSArchive })); - TeleBUSRegisterViewModels = new ObservableCollection(map.TeleBUSRegisters.Select(teleBUSArchive => new TeleBUS.RegisterViewModel() { Register = teleBUSArchive })); - TeleBUSEventViewModels = new ObservableCollection(map.TeleBUSEvents.Select(teleBUSEvent => new TeleBUS.EventViewModel() { Event = teleBUSEvent })); - - var indexHTMLDocumentFileName = DataService.CreateIndexHTMLDocument(currentCHMFolderName); - - if (indexHTMLDocumentFileName != null) - { - NavigateHelpDocumentWebBrowserCommand.Execute(indexHTMLDocumentFileName); - } - else - { - DialogService.ShowErrorMessage("Unable to create index HTML document"); - Close(); - } - } - catch (Exception ex) - { - DialogService.ShowErrorMessage($"Error loading map: {ex.Message}"); - } - } - } - - #endregion - - } -} \ No newline at end of file diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/NewMapWizardViewModel.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/NewMapWizardViewModel.cs deleted file mode 100644 index b6d383b..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/NewMapWizardViewModel.cs +++ /dev/null @@ -1,140 +0,0 @@ -#region Imported Types - -using System; -using GalaSoft.MvvmLight; -using GalaSoft.MvvmLight.CommandWpf; -using DeviceSQL.Utilities.RealFLOMappingGenerator.Model; -using Microsoft.Practices.ServiceLocation; -using System.IO; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.ViewModel -{ - public class NewMapWizardViewModel : ViewModelBase - { - - #region Fields - - private string fileName; - private string chmFileName = @"C:\Program Files (x86)\Schneider Electric\Realflo\Help\Realflo Reference Manual.chm"; - - #endregion - - #region Properties - - public DataService DataService - { - get - { - return ServiceLocator.Current.GetInstance(); - } - } - - public DialogService DialogService - { - get - { - return ServiceLocator.Current.GetInstance(); - } - } - - public RelayCommand SelectRealFLOHelpFileCommand - { - get; - set; - } - - public RelayCommand SelectMapFileNameCommand - { - get; - set; - } - - public bool FileExists - { - get - { - return File.Exists(FileName); - } - } - - public string FileName - { - get - { - return fileName; - } - set - { - fileName = value; - RaisePropertyChanged("FileName"); - RaisePropertyChanged("FileExists"); - } - } - - public bool CHMFileExists - { - get - { - return File.Exists(CHMFileName); - } - } - - public string CHMFileName - { - get - { - return chmFileName; - } - set - { - chmFileName = value; - RaisePropertyChanged("CHMFileName"); - RaisePropertyChanged("CHMFileExists"); - } - } - - #endregion - - #region Constructor - - public NewMapWizardViewModel() - { - SelectRealFLOHelpFileCommand = new RelayCommand(SelectRealFLOHelpFile); - SelectMapFileNameCommand = new RelayCommand(SelectMapFileName); - } - - #endregion - - #region Command Methods - - private void SelectRealFLOHelpFile() - { - var selectedCHMFile = DialogService.OpenSelectRealFLOHelpFileDialog(CHMFileName); - if(selectedCHMFile!= null) - { - CHMFileName = selectedCHMFile; - } - } - - private void SelectMapFileName() - { - var selectedMapFileName = DialogService.OpenCreateMapFileDialog(); - - if(selectedMapFileName != null) - { - FileName = selectedMapFileName; - } - else - { - FileName = null; - CHMFileName = null; - } - - } - - #endregion - - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/TeleBUS/ArchiveViewModel.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/TeleBUS/ArchiveViewModel.cs deleted file mode 100644 index 96f7511..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/TeleBUS/ArchiveViewModel.cs +++ /dev/null @@ -1,35 +0,0 @@ -#region Imported Types - -using DeviceSQL.Utilities.RealFLOMappingGenerator.Model.TeleBUS; -using GalaSoft.MvvmLight; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.ViewModel.TeleBUS -{ - public class ArchiveViewModel : TrackableViewModelBase - { - #region Fields - - private Archive archive; - - #endregion - - #region Imported Types - - public Archive Archive - { - get - { - return archive; - } - set - { - archive = value; - RaisePropertyChanged("Archive"); - } - } - - #endregion - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/TeleBUS/EventViewModel.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/TeleBUS/EventViewModel.cs deleted file mode 100644 index 5f1d4b7..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/TeleBUS/EventViewModel.cs +++ /dev/null @@ -1,35 +0,0 @@ -#region Imported Types - -using DeviceSQL.Utilities.RealFLOMappingGenerator.Model.TeleBUS; -using GalaSoft.MvvmLight; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.ViewModel.TeleBUS -{ - public class EventViewModel : TrackableViewModelBase - { - #region Fields - - private Event _event; - - #endregion - - #region Imported Types - - public Event Event - { - get - { - return _event; - } - set - { - _event = value; - RaisePropertyChanged("Event"); - } - } - - #endregion - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/TeleBUS/RegisterViewModel.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/TeleBUS/RegisterViewModel.cs deleted file mode 100644 index 7a30cf9..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/TeleBUS/RegisterViewModel.cs +++ /dev/null @@ -1,35 +0,0 @@ -#region Imported Types - -using DeviceSQL.Utilities.RealFLOMappingGenerator.Model.TeleBUS; -using GalaSoft.MvvmLight; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.ViewModel.TeleBUS -{ - public class RegisterViewModel : TrackableViewModelBase - { - #region Fields - - private Register register; - - #endregion - - #region Imported Types - - public Register Register - { - get - { - return register; - } - set - { - register = value; - RaisePropertyChanged("Register"); - } - } - - #endregion - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/TrackableViewModelBase.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/TrackableViewModelBase.cs deleted file mode 100644 index 0bada95..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/TrackableViewModelBase.cs +++ /dev/null @@ -1,74 +0,0 @@ -#region Imported Types - -using System.Runtime.CompilerServices; -using GalaSoft.MvvmLight; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.ViewModel -{ - public class TrackableViewModelBase : ViewModelBase - { - - #region Fields - - private bool hasChanged; - private TrackableViewModelBase parent; - - #endregion - - #region Properties - - public bool HasChanged - { - get - { - return hasChanged; - } - set - { - hasChanged = value; - RaisePropertyChanged("HasChanged"); - } - } - - public TrackableViewModelBase Parent - { - get - { - return parent; - } - } - - #endregion - - #region Constructor(s) - - public TrackableViewModelBase() - { - } - - public TrackableViewModelBase(TrackableViewModelBase parent) - { - this.parent = parent; - } - - #endregion - - #region Overrides - - public override void RaisePropertyChanged([CallerMemberName] string propertyName = null) - { - HasChanged = true; - if (parent != null) - { - parent.HasChanged = true; - } - base.RaisePropertyChanged(propertyName); - } - - #endregion - - - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/ViewModelLocator.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/ViewModelLocator.cs deleted file mode 100644 index f645007..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/ViewModel/ViewModelLocator.cs +++ /dev/null @@ -1,68 +0,0 @@ -#region Imported Types - -using GalaSoft.MvvmLight; -using Microsoft.Practices.ServiceLocation; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.ViewModel -{ - public class ViewModelLocator - { - public ViewModelLocator() - { - - } - - public ExportMapWizardViewModel ExportMapWizard - { - get - { - if (!ViewModelBase.IsInDesignModeStatic) - { - return ServiceLocator.Current.GetInstance(); - } - else - { - return null; - } - - } - } - - public NewMapWizardViewModel NewMapWizard - { - get - { - if (!ViewModelBase.IsInDesignModeStatic) - { - return ServiceLocator.Current.GetInstance(); - } - else - { - return null; - } - } - } - - public MainViewModel Main - { - get - { - if (!ViewModelBase.IsInDesignModeStatic) - { - return ServiceLocator.Current.GetInstance(); - } - else - { - return null; - } - } - } - - public static void Cleanup() - { - - } - } -} \ No newline at end of file diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Wizard/NewMapWizard.xaml b/DeviceSQL.Utilities.RealFLOMappingGenerator/Wizard/NewMapWizard.xaml deleted file mode 100644 index 7896ea5..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Wizard/NewMapWizard.xaml +++ /dev/null @@ -1,134 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/Wizard/NewMapWizard.xaml.cs b/DeviceSQL.Utilities.RealFLOMappingGenerator/Wizard/NewMapWizard.xaml.cs deleted file mode 100644 index bd50a86..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/Wizard/NewMapWizard.xaml.cs +++ /dev/null @@ -1,34 +0,0 @@ -#region Imported Types - -using DeviceSQL.Utilities.RealFLOMappingGenerator.ViewModel; -using Microsoft.Practices.ServiceLocation; -using System.Windows; - -#endregion - -namespace DeviceSQL.Utilities.RealFLOMappingGenerator.Wizard -{ - public partial class NewMapWizard : Window - { - - #region Constructor(s) - - public NewMapWizard() - { - InitializeComponent(); - } - - #endregion - - #region Wizard Events - - private void RadWizard_Finish(object sender, Telerik.Windows.Controls.NavigationButtonsEventArgs e) - { - DialogResult = true; - Close(); - } - - #endregion - - } -} diff --git a/DeviceSQL.Utilities.RealFLOMappingGenerator/packages.config b/DeviceSQL.Utilities.RealFLOMappingGenerator/packages.config deleted file mode 100644 index c36c606..0000000 --- a/DeviceSQL.Utilities.RealFLOMappingGenerator/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/DeviceSQL.sln b/DeviceSQL.sln index 8155053..b830189 100644 --- a/DeviceSQL.sln +++ b/DeviceSQL.sln @@ -1,25 +1,31 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27130.2026 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29306.81 MinimumVisualStudioVersion = 10.0.40219.1 Project("{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}") = "DeviceSQL", "DeviceSQL\DeviceSQL.sqlproj", "{CB6F0884-5A58-432A-800E-4ABFEEAB6F46}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.TestHarness", "DeviceSQL.TestHarness\DeviceSQL.TestHarness.csproj", "{FF09F40D-A515-4ABB-9DB1-21D9D1F2793E}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.DatabaseSetupUtility", "DeviceSQL.DatabaseSetupUtility\DeviceSQL.DatabaseSetupUtility.csproj", "{22929CF0-D02A-47D9-A308-D1D5497BF42B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.Utilities.DeploymentScriptFormatter", "DeviceSQL.Utilities.DeploymentScriptFormatter\DeviceSQL.Utilities.DeploymentScriptFormatter.csproj", "{0EA05DA7-635F-4018-9F33-0D3419374C9F}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.Service", "DeviceSQL.Service\DeviceSQL.Service.csproj", "{F7B38332-A678-424C-A67E-25CF36C2430D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.Utilities.RealFLOMappingGenerator", "DeviceSQL.Utilities.RealFLOMappingGenerator\DeviceSQL.Utilities.RealFLOMappingGenerator.csproj", "{6037A772-F9F9-420A-B04E-24E4B646911A}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.Devices.ROC", "DeviceSQL.Devices.ROC\DeviceSQL.Devices.ROC.csproj", "{AF0E4B64-F2C2-4459-A518-9AA905FF6F0F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.DatabaseSetupUtility", "DeviceSQL.DatabaseSetupUtility\DeviceSQL.DatabaseSetupUtility.csproj", "{22929CF0-D02A-47D9-A308-D1D5497BF42B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.Devices.Modbus", "DeviceSQL.Devices.Modbus\DeviceSQL.Devices.Modbus.csproj", "{0869E7FE-4FAC-4FC5-A2A8-313F410CF8CD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.Services", "DeviceSQL.Services\DeviceSQL.Services.csproj", "{4136548D-5D58-4EEB-8876-D450ADC62369}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.Devices.Common", "DeviceSQL.Devices.Common\DeviceSQL.Devices.Common.csproj", "{5DEADADF-BE60-4774-80C6-97B3A83FA289}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.Service", "DeviceSQL.Service\DeviceSQL.Service.csproj", "{F7B38332-A678-424C-A67E-25CF36C2430D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.SQLTypes.ROC", "DeviceSQL.SQLTypes.ROC\DeviceSQL.SQLTypes.ROC.csproj", "{256CA566-5436-4543-BC13-D2480BEE70C2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.SQLTypes.Modbus", "DeviceSQL.SQLTypes.Modbus\DeviceSQL.SQLTypes.Modbus.csproj", "{CD45D76E-D2ED-4587-9873-F35AD24E42A5}" +EndProject +Project("{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}") = "DeviceSQL.ChannelManager", "DeviceSQL.ChannelManager\DeviceSQL.ChannelManager.sqlproj", "{6393A621-3002-48AB-8DE0-74A03FFC4AFB}" +EndProject +Project("{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}") = "DeviceSQL.ROCMaster", "DeviceSQL.ROCMaster\DeviceSQL.ROCMaster.sqlproj", "{C5358ADC-ECA3-464D-AEB9-CE99048D4BE3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.Devices", "DeviceSQL.Devices\DeviceSQL.Devices.csproj", "{80ED4080-6FD1-492F-B70E-8C837B3DADC7}" +Project("{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}") = "DeviceSQL.ModbusMaster", "DeviceSQL.ModbusMaster\DeviceSQL.ModbusMaster.sqlproj", "{BF99E0A7-F591-4629-8DD2-DDA18B05E5F2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceSQL.SQLTypes", "DeviceSQL.SQLTypes\DeviceSQL.SQLTypes.csproj", "{91B62CD7-190B-4727-B1EB-66B51913709D}" +Project("{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}") = "DeviceSQL.DeviceManager", "DeviceSQL.DeviceManager\DeviceSQL.DeviceManager.sqlproj", "{0186AFD4-F3E0-42C0-A6BA-58F704804C31}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -41,30 +47,6 @@ Global {CB6F0884-5A58-432A-800E-4ABFEEAB6F46}.Release|x86.ActiveCfg = Release|Any CPU {CB6F0884-5A58-432A-800E-4ABFEEAB6F46}.Release|x86.Build.0 = Release|Any CPU {CB6F0884-5A58-432A-800E-4ABFEEAB6F46}.Release|x86.Deploy.0 = Release|Any CPU - {FF09F40D-A515-4ABB-9DB1-21D9D1F2793E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FF09F40D-A515-4ABB-9DB1-21D9D1F2793E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FF09F40D-A515-4ABB-9DB1-21D9D1F2793E}.Debug|x86.ActiveCfg = Debug|Any CPU - {FF09F40D-A515-4ABB-9DB1-21D9D1F2793E}.Debug|x86.Build.0 = Debug|Any CPU - {FF09F40D-A515-4ABB-9DB1-21D9D1F2793E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FF09F40D-A515-4ABB-9DB1-21D9D1F2793E}.Release|Any CPU.Build.0 = Release|Any CPU - {FF09F40D-A515-4ABB-9DB1-21D9D1F2793E}.Release|x86.ActiveCfg = Release|Any CPU - {FF09F40D-A515-4ABB-9DB1-21D9D1F2793E}.Release|x86.Build.0 = Release|Any CPU - {0EA05DA7-635F-4018-9F33-0D3419374C9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0EA05DA7-635F-4018-9F33-0D3419374C9F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0EA05DA7-635F-4018-9F33-0D3419374C9F}.Debug|x86.ActiveCfg = Debug|Any CPU - {0EA05DA7-635F-4018-9F33-0D3419374C9F}.Debug|x86.Build.0 = Debug|Any CPU - {0EA05DA7-635F-4018-9F33-0D3419374C9F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0EA05DA7-635F-4018-9F33-0D3419374C9F}.Release|Any CPU.Build.0 = Release|Any CPU - {0EA05DA7-635F-4018-9F33-0D3419374C9F}.Release|x86.ActiveCfg = Release|Any CPU - {0EA05DA7-635F-4018-9F33-0D3419374C9F}.Release|x86.Build.0 = Release|Any CPU - {6037A772-F9F9-420A-B04E-24E4B646911A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6037A772-F9F9-420A-B04E-24E4B646911A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6037A772-F9F9-420A-B04E-24E4B646911A}.Debug|x86.ActiveCfg = Debug|Any CPU - {6037A772-F9F9-420A-B04E-24E4B646911A}.Debug|x86.Build.0 = Debug|Any CPU - {6037A772-F9F9-420A-B04E-24E4B646911A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6037A772-F9F9-420A-B04E-24E4B646911A}.Release|Any CPU.Build.0 = Release|Any CPU - {6037A772-F9F9-420A-B04E-24E4B646911A}.Release|x86.ActiveCfg = Release|Any CPU - {6037A772-F9F9-420A-B04E-24E4B646911A}.Release|x86.Build.0 = Release|Any CPU {22929CF0-D02A-47D9-A308-D1D5497BF42B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {22929CF0-D02A-47D9-A308-D1D5497BF42B}.Debug|Any CPU.Build.0 = Debug|Any CPU {22929CF0-D02A-47D9-A308-D1D5497BF42B}.Debug|x86.ActiveCfg = Debug|Any CPU @@ -73,14 +55,6 @@ Global {22929CF0-D02A-47D9-A308-D1D5497BF42B}.Release|Any CPU.Build.0 = Release|Any CPU {22929CF0-D02A-47D9-A308-D1D5497BF42B}.Release|x86.ActiveCfg = Release|Any CPU {22929CF0-D02A-47D9-A308-D1D5497BF42B}.Release|x86.Build.0 = Release|Any CPU - {4136548D-5D58-4EEB-8876-D450ADC62369}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4136548D-5D58-4EEB-8876-D450ADC62369}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4136548D-5D58-4EEB-8876-D450ADC62369}.Debug|x86.ActiveCfg = Debug|Any CPU - {4136548D-5D58-4EEB-8876-D450ADC62369}.Debug|x86.Build.0 = Debug|Any CPU - {4136548D-5D58-4EEB-8876-D450ADC62369}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4136548D-5D58-4EEB-8876-D450ADC62369}.Release|Any CPU.Build.0 = Release|Any CPU - {4136548D-5D58-4EEB-8876-D450ADC62369}.Release|x86.ActiveCfg = Release|Any CPU - {4136548D-5D58-4EEB-8876-D450ADC62369}.Release|x86.Build.0 = Release|Any CPU {F7B38332-A678-424C-A67E-25CF36C2430D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F7B38332-A678-424C-A67E-25CF36C2430D}.Debug|Any CPU.Build.0 = Debug|Any CPU {F7B38332-A678-424C-A67E-25CF36C2430D}.Debug|x86.ActiveCfg = Debug|Any CPU @@ -89,22 +63,94 @@ Global {F7B38332-A678-424C-A67E-25CF36C2430D}.Release|Any CPU.Build.0 = Release|Any CPU {F7B38332-A678-424C-A67E-25CF36C2430D}.Release|x86.ActiveCfg = Release|Any CPU {F7B38332-A678-424C-A67E-25CF36C2430D}.Release|x86.Build.0 = Release|Any CPU - {80ED4080-6FD1-492F-B70E-8C837B3DADC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {80ED4080-6FD1-492F-B70E-8C837B3DADC7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {80ED4080-6FD1-492F-B70E-8C837B3DADC7}.Debug|x86.ActiveCfg = Debug|Any CPU - {80ED4080-6FD1-492F-B70E-8C837B3DADC7}.Debug|x86.Build.0 = Debug|Any CPU - {80ED4080-6FD1-492F-B70E-8C837B3DADC7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {80ED4080-6FD1-492F-B70E-8C837B3DADC7}.Release|Any CPU.Build.0 = Release|Any CPU - {80ED4080-6FD1-492F-B70E-8C837B3DADC7}.Release|x86.ActiveCfg = Release|Any CPU - {80ED4080-6FD1-492F-B70E-8C837B3DADC7}.Release|x86.Build.0 = Release|Any CPU - {91B62CD7-190B-4727-B1EB-66B51913709D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {91B62CD7-190B-4727-B1EB-66B51913709D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {91B62CD7-190B-4727-B1EB-66B51913709D}.Debug|x86.ActiveCfg = Debug|Any CPU - {91B62CD7-190B-4727-B1EB-66B51913709D}.Debug|x86.Build.0 = Debug|Any CPU - {91B62CD7-190B-4727-B1EB-66B51913709D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {91B62CD7-190B-4727-B1EB-66B51913709D}.Release|Any CPU.Build.0 = Release|Any CPU - {91B62CD7-190B-4727-B1EB-66B51913709D}.Release|x86.ActiveCfg = Release|Any CPU - {91B62CD7-190B-4727-B1EB-66B51913709D}.Release|x86.Build.0 = Release|Any CPU + {AF0E4B64-F2C2-4459-A518-9AA905FF6F0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF0E4B64-F2C2-4459-A518-9AA905FF6F0F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF0E4B64-F2C2-4459-A518-9AA905FF6F0F}.Debug|x86.ActiveCfg = Debug|Any CPU + {AF0E4B64-F2C2-4459-A518-9AA905FF6F0F}.Debug|x86.Build.0 = Debug|Any CPU + {AF0E4B64-F2C2-4459-A518-9AA905FF6F0F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF0E4B64-F2C2-4459-A518-9AA905FF6F0F}.Release|Any CPU.Build.0 = Release|Any CPU + {AF0E4B64-F2C2-4459-A518-9AA905FF6F0F}.Release|x86.ActiveCfg = Release|Any CPU + {AF0E4B64-F2C2-4459-A518-9AA905FF6F0F}.Release|x86.Build.0 = Release|Any CPU + {0869E7FE-4FAC-4FC5-A2A8-313F410CF8CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0869E7FE-4FAC-4FC5-A2A8-313F410CF8CD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0869E7FE-4FAC-4FC5-A2A8-313F410CF8CD}.Debug|x86.ActiveCfg = Debug|Any CPU + {0869E7FE-4FAC-4FC5-A2A8-313F410CF8CD}.Debug|x86.Build.0 = Debug|Any CPU + {0869E7FE-4FAC-4FC5-A2A8-313F410CF8CD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0869E7FE-4FAC-4FC5-A2A8-313F410CF8CD}.Release|Any CPU.Build.0 = Release|Any CPU + {0869E7FE-4FAC-4FC5-A2A8-313F410CF8CD}.Release|x86.ActiveCfg = Release|Any CPU + {0869E7FE-4FAC-4FC5-A2A8-313F410CF8CD}.Release|x86.Build.0 = Release|Any CPU + {5DEADADF-BE60-4774-80C6-97B3A83FA289}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5DEADADF-BE60-4774-80C6-97B3A83FA289}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5DEADADF-BE60-4774-80C6-97B3A83FA289}.Debug|x86.ActiveCfg = Debug|Any CPU + {5DEADADF-BE60-4774-80C6-97B3A83FA289}.Debug|x86.Build.0 = Debug|Any CPU + {5DEADADF-BE60-4774-80C6-97B3A83FA289}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5DEADADF-BE60-4774-80C6-97B3A83FA289}.Release|Any CPU.Build.0 = Release|Any CPU + {5DEADADF-BE60-4774-80C6-97B3A83FA289}.Release|x86.ActiveCfg = Release|Any CPU + {5DEADADF-BE60-4774-80C6-97B3A83FA289}.Release|x86.Build.0 = Release|Any CPU + {256CA566-5436-4543-BC13-D2480BEE70C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {256CA566-5436-4543-BC13-D2480BEE70C2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {256CA566-5436-4543-BC13-D2480BEE70C2}.Debug|x86.ActiveCfg = Debug|Any CPU + {256CA566-5436-4543-BC13-D2480BEE70C2}.Debug|x86.Build.0 = Debug|Any CPU + {256CA566-5436-4543-BC13-D2480BEE70C2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {256CA566-5436-4543-BC13-D2480BEE70C2}.Release|Any CPU.Build.0 = Release|Any CPU + {256CA566-5436-4543-BC13-D2480BEE70C2}.Release|x86.ActiveCfg = Release|Any CPU + {256CA566-5436-4543-BC13-D2480BEE70C2}.Release|x86.Build.0 = Release|Any CPU + {CD45D76E-D2ED-4587-9873-F35AD24E42A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CD45D76E-D2ED-4587-9873-F35AD24E42A5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CD45D76E-D2ED-4587-9873-F35AD24E42A5}.Debug|x86.ActiveCfg = Debug|Any CPU + {CD45D76E-D2ED-4587-9873-F35AD24E42A5}.Debug|x86.Build.0 = Debug|Any CPU + {CD45D76E-D2ED-4587-9873-F35AD24E42A5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CD45D76E-D2ED-4587-9873-F35AD24E42A5}.Release|Any CPU.Build.0 = Release|Any CPU + {CD45D76E-D2ED-4587-9873-F35AD24E42A5}.Release|x86.ActiveCfg = Release|Any CPU + {CD45D76E-D2ED-4587-9873-F35AD24E42A5}.Release|x86.Build.0 = Release|Any CPU + {6393A621-3002-48AB-8DE0-74A03FFC4AFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6393A621-3002-48AB-8DE0-74A03FFC4AFB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6393A621-3002-48AB-8DE0-74A03FFC4AFB}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {6393A621-3002-48AB-8DE0-74A03FFC4AFB}.Debug|x86.ActiveCfg = Debug|Any CPU + {6393A621-3002-48AB-8DE0-74A03FFC4AFB}.Debug|x86.Build.0 = Debug|Any CPU + {6393A621-3002-48AB-8DE0-74A03FFC4AFB}.Debug|x86.Deploy.0 = Debug|Any CPU + {6393A621-3002-48AB-8DE0-74A03FFC4AFB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6393A621-3002-48AB-8DE0-74A03FFC4AFB}.Release|Any CPU.Build.0 = Release|Any CPU + {6393A621-3002-48AB-8DE0-74A03FFC4AFB}.Release|Any CPU.Deploy.0 = Release|Any CPU + {6393A621-3002-48AB-8DE0-74A03FFC4AFB}.Release|x86.ActiveCfg = Release|Any CPU + {6393A621-3002-48AB-8DE0-74A03FFC4AFB}.Release|x86.Build.0 = Release|Any CPU + {6393A621-3002-48AB-8DE0-74A03FFC4AFB}.Release|x86.Deploy.0 = Release|Any CPU + {C5358ADC-ECA3-464D-AEB9-CE99048D4BE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C5358ADC-ECA3-464D-AEB9-CE99048D4BE3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C5358ADC-ECA3-464D-AEB9-CE99048D4BE3}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {C5358ADC-ECA3-464D-AEB9-CE99048D4BE3}.Debug|x86.ActiveCfg = Debug|Any CPU + {C5358ADC-ECA3-464D-AEB9-CE99048D4BE3}.Debug|x86.Build.0 = Debug|Any CPU + {C5358ADC-ECA3-464D-AEB9-CE99048D4BE3}.Debug|x86.Deploy.0 = Debug|Any CPU + {C5358ADC-ECA3-464D-AEB9-CE99048D4BE3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C5358ADC-ECA3-464D-AEB9-CE99048D4BE3}.Release|Any CPU.Build.0 = Release|Any CPU + {C5358ADC-ECA3-464D-AEB9-CE99048D4BE3}.Release|Any CPU.Deploy.0 = Release|Any CPU + {C5358ADC-ECA3-464D-AEB9-CE99048D4BE3}.Release|x86.ActiveCfg = Release|Any CPU + {C5358ADC-ECA3-464D-AEB9-CE99048D4BE3}.Release|x86.Build.0 = Release|Any CPU + {C5358ADC-ECA3-464D-AEB9-CE99048D4BE3}.Release|x86.Deploy.0 = Release|Any CPU + {BF99E0A7-F591-4629-8DD2-DDA18B05E5F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BF99E0A7-F591-4629-8DD2-DDA18B05E5F2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BF99E0A7-F591-4629-8DD2-DDA18B05E5F2}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {BF99E0A7-F591-4629-8DD2-DDA18B05E5F2}.Debug|x86.ActiveCfg = Debug|Any CPU + {BF99E0A7-F591-4629-8DD2-DDA18B05E5F2}.Debug|x86.Build.0 = Debug|Any CPU + {BF99E0A7-F591-4629-8DD2-DDA18B05E5F2}.Debug|x86.Deploy.0 = Debug|Any CPU + {BF99E0A7-F591-4629-8DD2-DDA18B05E5F2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BF99E0A7-F591-4629-8DD2-DDA18B05E5F2}.Release|Any CPU.Build.0 = Release|Any CPU + {BF99E0A7-F591-4629-8DD2-DDA18B05E5F2}.Release|Any CPU.Deploy.0 = Release|Any CPU + {BF99E0A7-F591-4629-8DD2-DDA18B05E5F2}.Release|x86.ActiveCfg = Release|Any CPU + {BF99E0A7-F591-4629-8DD2-DDA18B05E5F2}.Release|x86.Build.0 = Release|Any CPU + {BF99E0A7-F591-4629-8DD2-DDA18B05E5F2}.Release|x86.Deploy.0 = Release|Any CPU + {0186AFD4-F3E0-42C0-A6BA-58F704804C31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0186AFD4-F3E0-42C0-A6BA-58F704804C31}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0186AFD4-F3E0-42C0-A6BA-58F704804C31}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {0186AFD4-F3E0-42C0-A6BA-58F704804C31}.Debug|x86.ActiveCfg = Debug|Any CPU + {0186AFD4-F3E0-42C0-A6BA-58F704804C31}.Debug|x86.Build.0 = Debug|Any CPU + {0186AFD4-F3E0-42C0-A6BA-58F704804C31}.Debug|x86.Deploy.0 = Debug|Any CPU + {0186AFD4-F3E0-42C0-A6BA-58F704804C31}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0186AFD4-F3E0-42C0-A6BA-58F704804C31}.Release|Any CPU.Build.0 = Release|Any CPU + {0186AFD4-F3E0-42C0-A6BA-58F704804C31}.Release|Any CPU.Deploy.0 = Release|Any CPU + {0186AFD4-F3E0-42C0-A6BA-58F704804C31}.Release|x86.ActiveCfg = Release|Any CPU + {0186AFD4-F3E0-42C0-A6BA-58F704804C31}.Release|x86.Build.0 = Release|Any CPU + {0186AFD4-F3E0-42C0-A6BA-58F704804C31}.Release|x86.Deploy.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/DeviceSQL/DeviceSQL.sqlproj b/DeviceSQL/DeviceSQL.sqlproj index afb9f04..590f94a 100644 --- a/DeviceSQL/DeviceSQL.sqlproj +++ b/DeviceSQL/DeviceSQL.sqlproj @@ -8,7 +8,7 @@ 2.0 4.1 {cb6f0884-5a58-432a-800e-4abfeeab6f46} - Microsoft.Data.Tools.Schema.Sql.Sql130DatabaseSchemaProvider + Microsoft.Data.Tools.Schema.Sql.Sql140DatabaseSchemaProvider Database @@ -17,16 +17,17 @@ 1033, CI BySchemaAndSchemaType True - v4.6.1 + v4.8 CS Properties False True True UNSAFE - True - DeviceSQL-Key.snk + False + ..\DeviceSQL-Key.snk False + bin\Release\ @@ -62,7 +63,6 @@ - @@ -74,16 +74,8 @@ - - - - - - - - \ No newline at end of file diff --git a/DeviceSQL/Properties/AssemblyInfo.cs b/DeviceSQL/Properties/AssemblyInfo.cs index a90746f..f25f370 100644 --- a/DeviceSQL/Properties/AssemblyInfo.cs +++ b/DeviceSQL/Properties/AssemblyInfo.cs @@ -3,14 +3,15 @@ // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with the SQLCLR assembly. -[assembly: AssemblyTitle("DeviceSQL libraries")] -[assembly: AssemblyDescription("SQL Server libraries for communicating with anything")] +[assembly: AssemblyTitle("DeviceSQL")] +[assembly: AssemblyDescription("DeviceSQL")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("DeviceSQL")] +[assembly: AssemblyCompany("CloudSonix")] [assembly: AssemblyProduct("DeviceSQL")] -[assembly: AssemblyCopyright("2017 DeviceSQL")] +[assembly: AssemblyCopyright("© CloudSonix. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] +[assembly: AssemblyKeyFileAttribute("../DeviceSQL-Key.snk")] // Version information for an assembly consists of the following four values: // diff --git a/DeviceSQL/Schemas/ChannelManager.sql b/DeviceSQL/Schemas/ChannelManager.sql deleted file mode 100644 index c37a8ce..0000000 --- a/DeviceSQL/Schemas/ChannelManager.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE SCHEMA [ChannelManager] diff --git a/DeviceSQL/Schemas/DeviceManager.sql b/DeviceSQL/Schemas/DeviceManager.sql deleted file mode 100644 index c45b236..0000000 --- a/DeviceSQL/Schemas/DeviceManager.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE SCHEMA [DeviceManager] diff --git a/DeviceSQL/Schemas/ModbusMaster.sql b/DeviceSQL/Schemas/ModbusMaster.sql deleted file mode 100644 index ced978d..0000000 --- a/DeviceSQL/Schemas/ModbusMaster.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE SCHEMA [MODBUSMaster] diff --git a/DeviceSQL/Schemas/Watchdog.sql b/DeviceSQL/Schemas/Watchdog.sql deleted file mode 100644 index b7bb5f6..0000000 --- a/DeviceSQL/Schemas/Watchdog.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE SCHEMA [Watchdog] From d39a105f9d948cac45cd6e99d29a5f45f23c041a Mon Sep 17 00:00:00 2001 From: Jason Craig Date: Mon, 16 Dec 2019 23:08:27 -0700 Subject: [PATCH 4/7] ... ... --- ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index ab12f0f..82053cf 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -6,4 +6,4 @@ [Version 1.0 Now Available for Download](https://github.com/jasonrichardcraig/DeviceSQL/tree/master/Version%201.0 "1.0") -#### Support (Mountain Time): 403-618-6945 | Jason.Craig@Outlook.com | Skype - JasonRichardCraig +#### Support (Mountain Time): +1-587-693-1776 | Jason.Craig@Outlook.com | Skype - JasonRichardCraig From 184d973f15b8dbaa6fd5aeb5b043b80f34722ccb Mon Sep 17 00:00:00 2001 From: Jason Craig Date: Fri, 11 Sep 2020 00:28:15 -0400 Subject: [PATCH 5/7] Update ReadMe.md --- ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index 82053cf..7ade83a 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -6,4 +6,4 @@ [Version 1.0 Now Available for Download](https://github.com/jasonrichardcraig/DeviceSQL/tree/master/Version%201.0 "1.0") -#### Support (Mountain Time): +1-587-693-1776 | Jason.Craig@Outlook.com | Skype - JasonRichardCraig +#### Support (Mountain Time): +1-587-731-1776 | Jason.Craig@Outlook.com | Skype - JasonRichardCraig From e9a9687540bbf91b7957988cbaff0644dd4684c1 Mon Sep 17 00:00:00 2001 From: Jason Craig Date: Fri, 11 Sep 2020 23:06:54 -0400 Subject: [PATCH 6/7] Update ReadMe.md --- ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index 7ade83a..bbd551d 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -6,4 +6,4 @@ [Version 1.0 Now Available for Download](https://github.com/jasonrichardcraig/DeviceSQL/tree/master/Version%201.0 "1.0") -#### Support (Mountain Time): +1-587-731-1776 | Jason.Craig@Outlook.com | Skype - JasonRichardCraig +#### Support (Eastern Standard Time): +1-587-731-1776 | Jason.Craig@Outlook.com | Skype - JasonRichardCraig From e913f0d6fe3e0ce480e944f9068a79d4fdb1c353 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Dec 2022 06:08:40 +0000 Subject: [PATCH 7/7] Bump Newtonsoft.Json from 12.0.2 to 13.0.2 in /DeviceSQL.Devices.Common Bumps [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json) from 12.0.2 to 13.0.2. - [Release notes](https://github.com/JamesNK/Newtonsoft.Json/releases) - [Commits](https://github.com/JamesNK/Newtonsoft.Json/compare/12.0.2...13.0.2) --- updated-dependencies: - dependency-name: Newtonsoft.Json dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- DeviceSQL.Devices.Common/packages.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DeviceSQL.Devices.Common/packages.config b/DeviceSQL.Devices.Common/packages.config index d5b882e..4de699c 100644 --- a/DeviceSQL.Devices.Common/packages.config +++ b/DeviceSQL.Devices.Common/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file