17 Commits

Author SHA1 Message Date
Patrick McDonagh
464b8f488f Changes to driver 2016-08-04 12:59:15 -05:00
Patrick McDonagh
523e6c435e Adds a sample modbus map for M1 configuration 2016-07-15 17:01:18 -05:00
Patrick McDonagh
c876eb53c9 No longer need pycomm_micro since my changes are now in pycomm 2016-07-15 17:00:52 -05:00
Patrick McDonagh
0f0bbdd061 Fixes ipp reading from Micro800 using class instances 2016-07-15 17:00:22 -05:00
Patrick McDonagh
d1440a9a36 Merge branch 'master' of http://bitbucket.poconsole.net/scm/ipp/e300-ipp 2016-07-15 09:01:45 -05:00
Patrick McDonagh
ae209c7b39 Adds error tracking to micro800 write tag 2016-07-14 18:55:12 -05:00
Patrick McDonagh
8bec0aafd4 Updated ipp.py to use new pycomm functions and Channel class instances 2016-07-14 18:32:04 -05:00
Patrick McDonagh
5b2b8571a7 Added pickle_to_class.py for converting pickled tags to class instances 2016-07-14 17:45:11 -05:00
Patrick McDonagh
6ee3662342 Changes time to Epoch time (See HPU-60), adds alarm channels to driver, trip limit reached tags 2016-07-13 16:12:19 -05:00
Patrick McDonagh
37605fe41d Writes 1 to cmd_Write after setting an E300 parameter 2016-07-13 08:04:43 -05:00
Patrick McDonagh
3602d40d9b Removes warning enables for E300 configuration parameters that do not have warnings 2016-07-13 08:04:09 -05:00
Patrick McDonagh
38bfdb5312 Fix for IPP-49. Timer was being told to run, but timer cycle was never started when powering up 2016-06-17 10:01:33 -05:00
Patrick McDonagh
1240e53f15 Fixes IPP-47. Timer no longer acts like a fault being cleared 2016-06-15 14:36:36 -05:00
Patrick McDonagh
875a9ad405 Merged branch master into master 2016-06-14 19:02:31 -05:00
Patrick McDonagh
9d97df075b Closes IPP-42. Trip and Warning History 2016-06-14 19:02:11 -05:00
Patrick McDonagh
82177cafed Fixes Wrong IO mapping after accidentally saving the Demo Unit program 2016-06-08 09:41:49 -05:00
Patrick McDonagh
c641ae64c7 Fixes IPP-46. DH Intake pressure is now automatically offset by -14PSI to show true pressure 2016-06-06 12:11:31 -05:00
93 changed files with 3634 additions and 5806 deletions

View File

@@ -3,4 +3,4 @@
1::0002-0003::CONTROLLER: 0 error(s), 0 warning(s)
0::0021-0003::Checking database...
0::0007-0003::-------------------- Build project: CONTROLLER --------------------
1::0002-0003::CONTROLLER: 0 error(s), 0 warning(s)
1::0002-0003::CONTROLLER: 0 error(s), 1 warning(s)

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<DevicePreferences xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Micro800ConnectionPath>WIN8VM!AB_ETHIP-1\10.10.10.31</Micro800ConnectionPath>
<Micro800ConnectionPath>PMCDONAGH-SURF!AB_ETH-1\10.20.4.5</Micro800ConnectionPath>
</DevicePreferences>

View File

@@ -8,7 +8,7 @@
<DLGRCP_VarVA>
<DLGRCP_VarVA>
<ArrayLength>1</ArrayLength>
<VirtualAddress>1376</VirtualAddress>
<VirtualAddress>1368</VirtualAddress>
<Name>DH_IntakeTemperature</Name>
<Index>1</Index>
<ISaDataType>REAL</ISaDataType>
@@ -18,7 +18,7 @@
</DLGRCP_VarVA>
<DLGRCP_VarVA>
<ArrayLength>1</ArrayLength>
<VirtualAddress>1380</VirtualAddress>
<VirtualAddress>1372</VirtualAddress>
<Name>DH_IntakePressure</Name>
<Index>2</Index>
<ISaDataType>REAL</ISaDataType>
@@ -28,7 +28,7 @@
</DLGRCP_VarVA>
<DLGRCP_VarVA>
<ArrayLength>1</ArrayLength>
<VirtualAddress>2189</VirtualAddress>
<VirtualAddress>2181</VirtualAddress>
<Name>DH_DownholeStatus</Name>
<Index>3</Index>
<ISaDataType>STRING</ISaDataType>

View File

@@ -45,8 +45,6 @@ Controller.Micro820.Micro820._IO_EM_DO_05 FALSE
Controller.Micro820.Micro820._IO_EM_DO_06 FALSE
Controller.Micro820.Micro820._IO_P1_AI_00
Controller.Micro820.Micro820._IO_P1_AI_01
Controller.Micro820.Micro820._IO_P1_AI_02
Controller.Micro820.Micro820._IO_P1_AI_03
Controller.Micro820.Micro820.alarm_DHPressure
Controller.Micro820.Micro820.alarm_DHTemperature
Controller.Micro820.Micro820.alarm_E300
@@ -208,6 +206,24 @@ Controller.Micro820.Micro820.cmd_Run FALSE
Controller.Micro820.Micro820.cmd_TimerRun
Controller.Micro820.Micro820.Contactor_Status FALSE
Controller.Micro820.Micro820.Control.cmd_AutoModeTimerStart
Controller.Micro820.Micro820.Control.Epoch_Time_1.day_seconds
Controller.Micro820.Micro820.Control.Epoch_Time_1.Epoch
Controller.Micro820.Micro820.Control.Epoch_Time_1.hour_seconds
Controller.Micro820.Micro820.Control.Epoch_Time_1.min_seconds
Controller.Micro820.Micro820.Control.Epoch_Time_1.prev_months_days
Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.Enable
Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCBatLow
Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCData.Day
Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCData.DayOfWeek
Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCData.Hours
Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCData.Minutes
Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCData.Month
Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCData.Seconds
Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCData.Year
Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCEnabled
Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCPresent
Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_ENABLED
Controller.Micro820.Micro820.Control.Epoch_Time_1.year_seconds
Controller.Micro820.Micro820.Control.LinearScale_Pressure.b 300.0
Controller.Micro820.Micro820.Control.LinearScale_Pressure.EU_Max 300.0
Controller.Micro820.Micro820.Control.LinearScale_Pressure.EU_Min 300.0
@@ -6188,6 +6204,8 @@ Controller.Micro820.Micro820.sts_TimerCycleActive
Controller.Micro820.Micro820.sts_TimerRunTimeSet
Controller.Micro820.Micro820.sts_TimerWaitTimeSet
Controller.Micro820.Micro820.sts_TripCountIncreased
Controller.Micro820.Micro820.sts_TripLimitOLReached
Controller.Micro820.Micro820.sts_TripLimitReached
Controller.Micro820.Micro820.Temp_Shutdown 75.0
Controller.Micro820.Micro820.Temp_Shutdown_Enabled FALSE
Controller.Micro820.Micro820.Temp_Startup 75.0
1 Controller.Micro820.Micro820.__SYSVA_ABORT_CYCLE FALSE
45 Controller.Micro820.Micro820._IO_EM_DO_06 FALSE
46 Controller.Micro820.Micro820._IO_P1_AI_00
47 Controller.Micro820.Micro820._IO_P1_AI_01
Controller.Micro820.Micro820._IO_P1_AI_02
Controller.Micro820.Micro820._IO_P1_AI_03
48 Controller.Micro820.Micro820.alarm_DHPressure
49 Controller.Micro820.Micro820.alarm_DHTemperature
50 Controller.Micro820.Micro820.alarm_E300
206 Controller.Micro820.Micro820.cmd_TimerRun
207 Controller.Micro820.Micro820.Contactor_Status FALSE
208 Controller.Micro820.Micro820.Control.cmd_AutoModeTimerStart
209 Controller.Micro820.Micro820.Control.Epoch_Time_1.day_seconds
210 Controller.Micro820.Micro820.Control.Epoch_Time_1.Epoch
211 Controller.Micro820.Micro820.Control.Epoch_Time_1.hour_seconds
212 Controller.Micro820.Micro820.Control.Epoch_Time_1.min_seconds
213 Controller.Micro820.Micro820.Control.Epoch_Time_1.prev_months_days
214 Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.Enable
215 Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCBatLow
216 Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCData.Day
217 Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCData.DayOfWeek
218 Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCData.Hours
219 Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCData.Minutes
220 Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCData.Month
221 Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCData.Seconds
222 Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCData.Year
223 Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCEnabled
224 Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_1.RTCPresent
225 Controller.Micro820.Micro820.Control.Epoch_Time_1.RTC_READ_ENABLED
226 Controller.Micro820.Micro820.Control.Epoch_Time_1.year_seconds
227 Controller.Micro820.Micro820.Control.LinearScale_Pressure.b 300.0
228 Controller.Micro820.Micro820.Control.LinearScale_Pressure.EU_Max 300.0
229 Controller.Micro820.Micro820.Control.LinearScale_Pressure.EU_Min 300.0
6204 Controller.Micro820.Micro820.sts_TimerRunTimeSet
6205 Controller.Micro820.Micro820.sts_TimerWaitTimeSet
6206 Controller.Micro820.Micro820.sts_TripCountIncreased
6207 Controller.Micro820.Micro820.sts_TripLimitOLReached
6208 Controller.Micro820.Micro820.sts_TripLimitReached
6209 Controller.Micro820.Micro820.Temp_Shutdown 75.0
6210 Controller.Micro820.Micro820.Temp_Shutdown_Enabled FALSE
6211 Controller.Micro820.Micro820.Temp_Startup 75.0

View File

@@ -1,473 +1,473 @@
<modbusServer Version="2.0">
<modbusRegister name="DISCRETES_INPUTS">
<mapping variable="Auto_Mode" parent="Micro820" dataType="Bool" address="100001" va="0x478">
<mapping variable="Auto_Mode" parent="Micro820" dataType="Bool" address="100001" va="0x470">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="Test_Mode" parent="Micro820" dataType="Bool" address="100002" va="0x482">
<mapping variable="Test_Mode" parent="Micro820" dataType="Bool" address="100002" va="0x47a">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="Hand_Mode" parent="Micro820" dataType="Bool" address="100003" va="0x477">
<mapping variable="Hand_Mode" parent="Micro820" dataType="Bool" address="100003" va="0x46f">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="Contactor_Status" parent="Micro820" dataType="Bool" address="100004" va="0x47a">
<mapping variable="Contactor_Status" parent="Micro820" dataType="Bool" address="100004" va="0x472">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="Start_Permissive" parent="Micro820" dataType="Bool" address="100005" va="0x46c">
<mapping variable="Start_Permissive" parent="Micro820" dataType="Bool" address="100005" va="0x464">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="Run_Permissive" parent="Micro820" dataType="Bool" address="100006" va="0x46d">
<mapping variable="Run_Permissive" parent="Micro820" dataType="Bool" address="100006" va="0x465">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_READ" parent="Micro820" dataType="Bool" address="100007" va="0x47b">
<mapping variable="cfg_READ" parent="Micro820" dataType="Bool" address="100007" va="0x473">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_WRITE" parent="Micro820" dataType="Bool" address="100009" va="0x47c">
<mapping variable="cfg_WRITE" parent="Micro820" dataType="Bool" address="100009" va="0x474">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="TripStatus" parent="Micro820" dataType="Bool" address="100010" va="0x480">
<mapping variable="TripStatus" parent="Micro820" dataType="Bool" address="100010" va="0x478">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="WarningStatus" parent="Micro820" dataType="Bool" address="100011" va="0x481">
<mapping variable="WarningStatus" parent="Micro820" dataType="Bool" address="100011" va="0x479">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="OverloadTrip" parent="Micro820" dataType="Bool" address="100012" va="0x47f">
<mapping variable="OverloadTrip" parent="Micro820" dataType="Bool" address="100012" va="0x477">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="VoltageOK" parent="Micro820" dataType="Bool" address="100013" va="0x483">
<mapping variable="VoltageOK" parent="Micro820" dataType="Bool" address="100013" va="0x47b">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="TripResetCmd" parent="Micro820" dataType="Bool" address="100014" va="0x47e">
<mapping variable="TripResetCmd" parent="Micro820" dataType="Bool" address="100014" va="0x476">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="DigitalInput_Status_0" parent="Micro820" dataType="Bool" address="100015" va="0x466">
<mapping variable="DigitalInput_Status_0" parent="Micro820" dataType="Bool" address="100015" va="0x45e">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="DigitalInput_Status_1" parent="Micro820" dataType="Bool" address="100016" va="0x467">
<mapping variable="DigitalInput_Status_1" parent="Micro820" dataType="Bool" address="100016" va="0x45f">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="DigitalInput_Status_2" parent="Micro820" dataType="Bool" address="100017" va="0x468">
<mapping variable="DigitalInput_Status_2" parent="Micro820" dataType="Bool" address="100017" va="0x460">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="DigitalInput_Status_3" parent="Micro820" dataType="Bool" address="100018" va="0x469">
<mapping variable="DigitalInput_Status_3" parent="Micro820" dataType="Bool" address="100018" va="0x461">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="DigitalInput_Status_4" parent="Micro820" dataType="Bool" address="100019" va="0x470">
<mapping variable="DigitalInput_Status_4" parent="Micro820" dataType="Bool" address="100019" va="0x468">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="DigitalInput_Status_5" parent="Micro820" dataType="Bool" address="100020" va="0x46f">
<mapping variable="DigitalInput_Status_5" parent="Micro820" dataType="Bool" address="100020" va="0x467">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="Temp_Shutdown_Enabled" parent="Micro820" dataType="Bool" address="100021" va="0x471">
<mapping variable="Temp_Shutdown_Enabled" parent="Micro820" dataType="Bool" address="100021" va="0x469">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="Pressure_Shutdown_Enabled" parent="Micro820" dataType="Bool" address="100022" va="0x473">
<mapping variable="Pressure_Shutdown_Enabled" parent="Micro820" dataType="Bool" address="100022" va="0x46b">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="Temp_Startup_Enabled" parent="Micro820" dataType="Bool" address="100023" va="0x472">
<mapping variable="Temp_Startup_Enabled" parent="Micro820" dataType="Bool" address="100023" va="0x46a">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="Pressure_Startup_Enabled" parent="Micro820" dataType="Bool" address="100024" va="0x474">
<mapping variable="Pressure_Startup_Enabled" parent="Micro820" dataType="Bool" address="100024" va="0x46c">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="Start_Command" parent="Micro820" dataType="Bool" address="100025" va="0x46a">
<mapping variable="Start_Command" parent="Micro820" dataType="Bool" address="100025" va="0x462">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="Stop_Command" parent="Micro820" dataType="Bool" address="100026" va="0x46b">
<mapping variable="Stop_Command" parent="Micro820" dataType="Bool" address="100026" va="0x463">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="Pressure_Switch_Enabled" parent="Micro820" dataType="Bool" address="100027" va="0x4a4">
<mapping variable="Pressure_Switch_Enabled" parent="Micro820" dataType="Bool" address="100027" va="0x49c">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="Downhole_Tool_Enabled" parent="Micro820" dataType="Bool" address="100028" va="0x4a5">
<mapping variable="Downhole_Tool_Enabled" parent="Micro820" dataType="Bool" address="100028" va="0x49d">
<MBVarInfo ElemType="Bool" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_GF_GroundFaultInhibitTime" parent="Micro820" dataType="USInt" address="100056" va="0x4d1">
<mapping variable="cfg_GF_GroundFaultInhibitTime" parent="Micro820" dataType="USInt" address="100056" va="0x4cb">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_I_CurrentImbalanceInhibitTime" parent="Micro820" dataType="USInt" address="100064" va="0x4d8">
<mapping variable="cfg_I_CurrentImbalanceInhibitTime" parent="Micro820" dataType="USInt" address="100064" va="0x4d2">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_I_CurrentImbalanceInhibitTime" parent="Micro820" dataType="USInt" address="100072" va="0x4d8">
<mapping variable="cfg_I_CurrentImbalanceInhibitTime" parent="Micro820" dataType="USInt" address="100072" va="0x4d2">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_I_CurrentImbalanceTripDelay" parent="Micro820" dataType="USInt" address="100080" va="0x4d9">
<mapping variable="cfg_I_CurrentImbalanceTripDelay" parent="Micro820" dataType="USInt" address="100080" va="0x4d3">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_I_CurrentImbalanceTripLevel" parent="Micro820" dataType="USInt" address="100088" va="0x4da">
<mapping variable="cfg_I_CurrentImbalanceTripLevel" parent="Micro820" dataType="USInt" address="100088" va="0x4d4">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_I_CurrentImbalanceWarningLevel" parent="Micro820" dataType="USInt" address="100096" va="0x4db">
<mapping variable="cfg_I_CurrentImbalanceWarningLevel" parent="Micro820" dataType="USInt" address="100096" va="0x4d5">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_I_JamInhibitTime" parent="Micro820" dataType="USInt" address="100104" va="0x4d3">
<mapping variable="cfg_I_JamInhibitTime" parent="Micro820" dataType="USInt" address="100104" va="0x4cd">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_I_JamTripDelay" parent="Micro820" dataType="USInt" address="100112" va="0x4d4">
<mapping variable="cfg_I_JamTripDelay" parent="Micro820" dataType="USInt" address="100112" va="0x4ce">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_I_LineLossInhibitTime" parent="Micro820" dataType="USInt" address="100120" va="0x4ea">
<mapping variable="cfg_I_LineLossInhibitTime" parent="Micro820" dataType="USInt" address="100120" va="0x4e4">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_I_OvercurrentInhibitTime" parent="Micro820" dataType="USInt" address="100128" va="0x4e3">
<mapping variable="cfg_I_OvercurrentInhibitTime" parent="Micro820" dataType="USInt" address="100128" va="0x4dd">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_I_OvercurrentTripLevel" parent="Micro820" dataType="USInt" address="100136" va="0x50c">
<mapping variable="cfg_I_OvercurrentTripLevel" parent="Micro820" dataType="USInt" address="100136" va="0x506">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_I_OvercurrentWarningLevel" parent="Micro820" dataType="USInt" address="100144" va="0x50d">
<mapping variable="cfg_I_OvercurrentWarningLevel" parent="Micro820" dataType="USInt" address="100144" va="0x507">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_I_StallEnabledTime" parent="Micro820" dataType="USInt" address="100152" va="0x4d2">
<mapping variable="cfg_I_StallEnabledTime" parent="Micro820" dataType="USInt" address="100152" va="0x4cc">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_I_TripEnableCurrent" parent="Micro820" dataType="UInt" address="100160" va="0x528">
<mapping variable="cfg_I_TripEnableCurrent" parent="Micro820" dataType="UInt" address="100160" va="0x522">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="cfg_I_UndercurrentInhibitTime" parent="Micro820" dataType="USInt" address="100176" va="0x4dc">
<mapping variable="cfg_I_UndercurrentInhibitTime" parent="Micro820" dataType="USInt" address="100176" va="0x4d6">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_C_WarningEnableControl" parent="Micro820" dataType="UInt" address="100184" va="0x536">
<mapping variable="cfg_C_WarningEnableControl" parent="Micro820" dataType="UInt" address="100184" va="0x530">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="cfg_I_UndercurrentTripLevel" parent="Micro820" dataType="USInt" address="100200" va="0x50a">
<mapping variable="cfg_I_UndercurrentTripLevel" parent="Micro820" dataType="USInt" address="100200" va="0x504">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_I_UndercurrentWarningLevel" parent="Micro820" dataType="USInt" address="100208" va="0x50b">
<mapping variable="cfg_I_UndercurrentWarningLevel" parent="Micro820" dataType="USInt" address="100208" va="0x505">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_I_UnderloadInhibitTime" parent="Micro820" dataType="USInt" address="100216" va="0x4d5">
<mapping variable="cfg_I_UnderloadInhibitTime" parent="Micro820" dataType="USInt" address="100216" va="0x4cf">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_I_UnderloadTripLevel" parent="Micro820" dataType="USInt" address="100224" va="0x4d6">
<mapping variable="cfg_I_UnderloadTripLevel" parent="Micro820" dataType="USInt" address="100224" va="0x4d0">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_I_UnderloadWarningLevel" parent="Micro820" dataType="USInt" address="100232" va="0x4d7">
<mapping variable="cfg_I_UnderloadWarningLevel" parent="Micro820" dataType="USInt" address="100232" va="0x4d1">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_I_WarningEnableCurrent" parent="Micro820" dataType="UInt" address="100240" va="0x530">
<mapping variable="cfg_I_WarningEnableCurrent" parent="Micro820" dataType="UInt" address="100240" va="0x52a">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="cfg_PL_PhaseLossInhibitTime" parent="Micro820" dataType="USInt" address="100256" va="0x4d0">
<mapping variable="cfg_PL_PhaseLossInhibitTime" parent="Micro820" dataType="USInt" address="100256" va="0x4ca">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_TCU_OLResetLevel" parent="Micro820" dataType="USInt" address="100264" va="0x4ce">
<mapping variable="cfg_TCU_OLResetLevel" parent="Micro820" dataType="USInt" address="100264" va="0x4c8">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_TCU_OLWarningLevel" parent="Micro820" dataType="USInt" address="100272" va="0x4cf">
<mapping variable="cfg_TCU_OLWarningLevel" parent="Micro820" dataType="USInt" address="100272" va="0x4c9">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_TCU_TripClass" parent="Micro820" dataType="USInt" address="100280" va="0x4cd">
<mapping variable="cfg_TCU_TripClass" parent="Micro820" dataType="USInt" address="100280" va="0x4c7">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_V_OverfrequencyInhibitTime" parent="Micro820" dataType="USInt" address="100288" va="0x4f6">
<mapping variable="cfg_V_OverfrequencyInhibitTime" parent="Micro820" dataType="USInt" address="100288" va="0x4f0">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_V_OverfrequencyTripLevel" parent="Micro820" dataType="USInt" address="100296" va="0x4f7">
<mapping variable="cfg_V_OverfrequencyTripLevel" parent="Micro820" dataType="USInt" address="100296" va="0x4f1">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_V_OverfrequencyWarningLevel" parent="Micro820" dataType="USInt" address="100304" va="0x4f8">
<mapping variable="cfg_V_OverfrequencyWarningLevel" parent="Micro820" dataType="USInt" address="100304" va="0x4f2">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_V_OvervoltageInhibitTime" parent="Micro820" dataType="USInt" address="100312" va="0x4ed">
<mapping variable="cfg_V_OvervoltageInhibitTime" parent="Micro820" dataType="USInt" address="100312" va="0x4e7">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_V_PhaseRotationInhibitTime" parent="Micro820" dataType="USInt" address="100320" va="0x4ee">
<mapping variable="cfg_V_PhaseRotationInhibitTime" parent="Micro820" dataType="USInt" address="100320" va="0x4e8">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_V_PhaseRotationTripType" parent="Micro820" dataType="USInt" address="100328" va="0x4ef">
<mapping variable="cfg_V_PhaseRotationTripType" parent="Micro820" dataType="USInt" address="100328" va="0x4e9">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_V_TripEnableVoltage" parent="Micro820" dataType="UInt" address="100336" va="0x52a">
<mapping variable="cfg_V_TripEnableVoltage" parent="Micro820" dataType="UInt" address="100336" va="0x524">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="cfg_V_UnderfrequencyInhibitTime" parent="Micro820" dataType="USInt" address="100352" va="0x4f3">
<mapping variable="cfg_V_UnderfrequencyInhibitTime" parent="Micro820" dataType="USInt" address="100352" va="0x4ed">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_V_UnderfrequencyTripLevel" parent="Micro820" dataType="USInt" address="100360" va="0x4f4">
<mapping variable="cfg_V_UnderfrequencyTripLevel" parent="Micro820" dataType="USInt" address="100360" va="0x4ee">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_V_UnderfrequencyWarningLevel" parent="Micro820" dataType="USInt" address="100368" va="0x4f5">
<mapping variable="cfg_V_UnderfrequencyWarningLevel" parent="Micro820" dataType="USInt" address="100368" va="0x4ef">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_V_UndervoltageInhibitTime" parent="Micro820" dataType="USInt" address="100376" va="0x4ec">
<mapping variable="cfg_V_UndervoltageInhibitTime" parent="Micro820" dataType="USInt" address="100376" va="0x4e6">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_V_VoltageImbalanceInhibitTime" parent="Micro820" dataType="USInt" address="100384" va="0x4f0">
<mapping variable="cfg_V_VoltageImbalanceInhibitTime" parent="Micro820" dataType="USInt" address="100384" va="0x4ea">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_V_VoltageImbalanceTripLevel" parent="Micro820" dataType="USInt" address="100392" va="0x4f1">
<mapping variable="cfg_V_VoltageImbalanceTripLevel" parent="Micro820" dataType="USInt" address="100392" va="0x4eb">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_V_VoltageImbalanceWarningLevel" parent="Micro820" dataType="USInt" address="100400" va="0x4f2">
<mapping variable="cfg_V_VoltageImbalanceWarningLevel" parent="Micro820" dataType="USInt" address="100400" va="0x4ec">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_V_VoltageMode" parent="Micro820" dataType="USInt" address="100408" va="0x4eb">
<mapping variable="cfg_V_VoltageMode" parent="Micro820" dataType="USInt" address="100408" va="0x4e5">
<MBVarInfo ElemType="USInt" SubElemType="Any" DataTypeSize="1" />
</mapping>
<mapping variable="cfg_V_WarningEnableVoltage" parent="Micro820" dataType="UInt" address="100416" va="0x532">
<mapping variable="cfg_V_WarningEnableVoltage" parent="Micro820" dataType="UInt" address="100416" va="0x52c">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="TripStatusControl_INT" parent="Micro820" dataType="UInt" address="100432" va="0x54c">
<mapping variable="TripStatusControl_INT" parent="Micro820" dataType="UInt" address="100432" va="0x546">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="TripStatusCurrent_INT" parent="Micro820" dataType="UInt" address="100448" va="0x546">
<mapping variable="TripStatusCurrent_INT" parent="Micro820" dataType="UInt" address="100448" va="0x540">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="TripStatusPower_INT" parent="Micro820" dataType="UInt" address="100464" va="0x54a">
<mapping variable="TripStatusPower_INT" parent="Micro820" dataType="UInt" address="100464" va="0x544">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="TripStatusVoltage_INT" parent="Micro820" dataType="UInt" address="100480" va="0x548">
<mapping variable="TripStatusVoltage_INT" parent="Micro820" dataType="UInt" address="100480" va="0x542">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="WarningStatusControl_INT" parent="Micro820" dataType="UInt" address="100496" va="0x554">
<mapping variable="WarningStatusControl_INT" parent="Micro820" dataType="UInt" address="100496" va="0x54e">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="WarningStatusCurrent_INT" parent="Micro820" dataType="UInt" address="100512" va="0x54e">
<mapping variable="WarningStatusCurrent_INT" parent="Micro820" dataType="UInt" address="100512" va="0x548">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="WarningStatusPower_INT" parent="Micro820" dataType="UInt" address="100528" va="0x552">
<mapping variable="WarningStatusPower_INT" parent="Micro820" dataType="UInt" address="100528" va="0x54c">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="WarningStatusVoltage_INT" parent="Micro820" dataType="UInt" address="100544" va="0x550">
<mapping variable="WarningStatusVoltage_INT" parent="Micro820" dataType="UInt" address="100544" va="0x54a">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
</modbusRegister>
<modbusRegister name="HOLDING_REGISTERS">
<mapping variable="cfg_C_FLASetting" parent="Micro820" dataType="Real" address="400001" va="0x588">
<mapping variable="cfg_C_FLASetting" parent="Micro820" dataType="Real" address="400001" va="0x580">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="cfg_C_TripEnableControl" parent="Micro820" dataType="UInt" address="400003" va="0x52e">
<mapping variable="cfg_C_TripEnableControl" parent="Micro820" dataType="UInt" address="400003" va="0x528">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="cfg_GF_GroundFaultTripDelay" parent="Micro820" dataType="Real" address="400005" va="0x590">
<mapping variable="cfg_GF_GroundFaultTripDelay" parent="Micro820" dataType="Real" address="400005" va="0x588">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="cfg_GF_GroundFaultTripLevel" parent="Micro820" dataType="Real" address="400007" va="0x594">
<mapping variable="cfg_GF_GroundFaultTripLevel" parent="Micro820" dataType="Real" address="400007" va="0x58c">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="cfg_GF_GroundFaultWarningDelay" parent="Micro820" dataType="Real" address="400009" va="0x598">
<mapping variable="cfg_GF_GroundFaultWarningDelay" parent="Micro820" dataType="Real" address="400009" va="0x590">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="cfg_I_CTPrimary" parent="Micro820" dataType="UInt" address="400011" va="0x53e">
<mapping variable="cfg_I_CTPrimary" parent="Micro820" dataType="UInt" address="400011" va="0x538">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="cfg_I_CTSecondary" parent="Micro820" dataType="UInt" address="400012" va="0x540">
<mapping variable="cfg_I_CTSecondary" parent="Micro820" dataType="UInt" address="400012" va="0x53a">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="cfg_I_JamTripLevel" parent="Micro820" dataType="UInt" address="400013" va="0x53a">
<mapping variable="cfg_I_JamTripLevel" parent="Micro820" dataType="UInt" address="400013" va="0x534">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="cfg_I_JamWarningLevel" parent="Micro820" dataType="UInt" address="400014" va="0x53c">
<mapping variable="cfg_I_JamWarningLevel" parent="Micro820" dataType="UInt" address="400014" va="0x536">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="cfg_I_LineLossTripDelay" parent="Micro820" dataType="Real" address="400015" va="0x65c">
<mapping variable="cfg_I_LineLossTripDelay" parent="Micro820" dataType="Real" address="400015" va="0x654">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="cfg_I_OvercurrentTripDelay" parent="Micro820" dataType="Real" address="400017" va="0x660">
<mapping variable="cfg_I_OvercurrentTripDelay" parent="Micro820" dataType="Real" address="400017" va="0x658">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="cfg_I_UndercurrentTripDelay" parent="Micro820" dataType="Real" address="400019" va="0x658">
<mapping variable="cfg_I_UndercurrentTripDelay" parent="Micro820" dataType="Real" address="400019" va="0x650">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="cfg_I_UnderloadTripDelay" parent="Micro820" dataType="Real" address="400021" va="0x5a0">
<mapping variable="cfg_I_UnderloadTripDelay" parent="Micro820" dataType="Real" address="400021" va="0x598">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="cfg_PL_PhaseLossTripDelay" parent="Micro820" dataType="Real" address="400023" va="0x58c">
<mapping variable="cfg_PL_PhaseLossTripDelay" parent="Micro820" dataType="Real" address="400023" va="0x584">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="cfg_V_OverfrequencyTripDelay" parent="Micro820" dataType="Real" address="400025" va="0x5e8">
<mapping variable="cfg_V_OverfrequencyTripDelay" parent="Micro820" dataType="Real" address="400025" va="0x5e0">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="cfg_V_OvervoltageTripDelay" parent="Micro820" dataType="Real" address="400027" va="0x5d4">
<mapping variable="cfg_V_OvervoltageTripDelay" parent="Micro820" dataType="Real" address="400027" va="0x5cc">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="cfg_V_OvervoltageTripLevel" parent="Micro820" dataType="Real" address="400029" va="0x5d8">
<mapping variable="cfg_V_OvervoltageTripLevel" parent="Micro820" dataType="Real" address="400029" va="0x5d0">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="cfg_V_OvervoltageWarningLevel" parent="Micro820" dataType="Real" address="400031" va="0x5dc">
<mapping variable="cfg_V_OvervoltageWarningLevel" parent="Micro820" dataType="Real" address="400031" va="0x5d4">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="cfg_V_PTPrimary" parent="Micro820" dataType="UInt" address="400033" va="0x542">
<mapping variable="cfg_V_PTPrimary" parent="Micro820" dataType="UInt" address="400033" va="0x53c">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="cfg_V_PTSecondary" parent="Micro820" dataType="UInt" address="400034" va="0x544">
<mapping variable="cfg_V_PTSecondary" parent="Micro820" dataType="UInt" address="400034" va="0x53e">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="cfg_V_UnderfrequencyTripDelay" parent="Micro820" dataType="Real" address="400035" va="0x5e4">
<mapping variable="cfg_V_UnderfrequencyTripDelay" parent="Micro820" dataType="Real" address="400035" va="0x5dc">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="cfg_V_UndervoltageTripDelay" parent="Micro820" dataType="Real" address="400037" va="0x5c8">
<mapping variable="cfg_V_UndervoltageTripDelay" parent="Micro820" dataType="Real" address="400037" va="0x5c0">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="cfg_V_UndervoltageTripLevel" parent="Micro820" dataType="Real" address="400039" va="0x5cc">
<mapping variable="cfg_V_UndervoltageTripLevel" parent="Micro820" dataType="Real" address="400039" va="0x5c4">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="cfg_V_UndervoltageWarningLevel" parent="Micro820" dataType="Real" address="400041" va="0x5d0">
<mapping variable="cfg_V_UndervoltageWarningLevel" parent="Micro820" dataType="Real" address="400041" va="0x5c8">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="cfg_V_VoltageImbalanceTripDelay" parent="Micro820" dataType="Real" address="400043" va="0x5e0">
<mapping variable="cfg_V_VoltageImbalanceTripDelay" parent="Micro820" dataType="Real" address="400043" va="0x5d8">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="DH_DischargePressure" parent="Micro820" dataType="UInt" address="400045" va="0x512">
<mapping variable="DH_DischargePressure" parent="Micro820" dataType="UInt" address="400045" va="0x50c">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="DH_DischargeTemperature" parent="Micro820" dataType="UInt" address="400046" va="0x510">
<mapping variable="DH_DischargeTemperature" parent="Micro820" dataType="UInt" address="400046" va="0x50a">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="DH_DownholeStatus_INT" parent="Micro820" dataType="UInt" address="400047" va="0x526">
<mapping variable="DH_DownholeStatus_INT" parent="Micro820" dataType="UInt" address="400047" va="0x520">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="DH_IntakePressure" parent="Micro820" dataType="Real" address="400048" va="0x564">
<mapping variable="DH_IntakePressure" parent="Micro820" dataType="Real" address="400048" va="0x55c">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="DH_IntakeTemperature" parent="Micro820" dataType="Real" address="400050" va="0x560">
<mapping variable="DH_IntakeTemperature" parent="Micro820" dataType="Real" address="400050" va="0x558">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="DH_MaxIntakePressure_Forever" parent="Micro820" dataType="UInt" address="400052" va="0x524">
<mapping variable="DH_MaxIntakePressure_Forever" parent="Micro820" dataType="UInt" address="400052" va="0x51e">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="DH_MaxIntakePressure_Startup" parent="Micro820" dataType="UInt" address="400053" va="0x51e">
<mapping variable="DH_MaxIntakePressure_Startup" parent="Micro820" dataType="UInt" address="400053" va="0x518">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="DH_MaxIntakeTemperature_Forever" parent="Micro820" dataType="Real" address="400054" va="0x584">
<mapping variable="DH_MaxIntakeTemperature_Forever" parent="Micro820" dataType="Real" address="400054" va="0x57c">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="DH_MaxIntakeTemperature_Startup" parent="Micro820" dataType="Real" address="400056" va="0x580">
<mapping variable="DH_MaxIntakeTemperature_Startup" parent="Micro820" dataType="Real" address="400056" va="0x578">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="DH_NumChannels" parent="Micro820" dataType="UInt" address="400058" va="0x51a">
<mapping variable="DH_NumChannels" parent="Micro820" dataType="UInt" address="400058" va="0x514">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="DH_PSIRating" parent="Micro820" dataType="UInt" address="400059" va="0x522">
<mapping variable="DH_PSIRating" parent="Micro820" dataType="UInt" address="400059" va="0x51c">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="DH_ToolType" parent="Micro820" dataType="UInt" address="400060" va="0x520">
<mapping variable="DH_ToolType" parent="Micro820" dataType="UInt" address="400060" va="0x51a">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="DH_ToolVoltage" parent="Micro820" dataType="UInt" address="400061" va="0x51c">
<mapping variable="DH_ToolVoltage" parent="Micro820" dataType="UInt" address="400061" va="0x516">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="DH_VibrationX" parent="Micro820" dataType="UInt" address="400062" va="0x514">
<mapping variable="DH_VibrationX" parent="Micro820" dataType="UInt" address="400062" va="0x50e">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="DH_VibrationY" parent="Micro820" dataType="UInt" address="400063" va="0x516">
<mapping variable="DH_VibrationY" parent="Micro820" dataType="UInt" address="400063" va="0x510">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="DH_WindingTemperature" parent="Micro820" dataType="UInt" address="400064" va="0x50e">
<mapping variable="DH_WindingTemperature" parent="Micro820" dataType="UInt" address="400064" va="0x508">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="E300_kWh" parent="Micro820" dataType="Real" address="400065" va="0x578">
<mapping variable="E300_kWh" parent="Micro820" dataType="Real" address="400065" va="0x570">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_kWh_Regen" parent="Micro820" dataType="Real" address="400067" va="0x57c">
<mapping variable="E300_kWh_Regen" parent="Micro820" dataType="Real" address="400067" va="0x574">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_SCAN_RATE" parent="Micro820" dataType="UInt" address="400069" va="0x518">
<mapping variable="E300_SCAN_RATE" parent="Micro820" dataType="UInt" address="400069" va="0x512">
<MBVarInfo ElemType="UInt" SubElemType="Any" DataTypeSize="2" />
</mapping>
<mapping variable="Pressure_Shutdown" parent="Micro820" dataType="Real" address="400070" va="0x570">
<mapping variable="Pressure_Shutdown" parent="Micro820" dataType="Real" address="400070" va="0x568">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="Pressure_Startup" parent="Micro820" dataType="Real" address="400072" va="0x574">
<mapping variable="Pressure_Startup" parent="Micro820" dataType="Real" address="400072" va="0x56c">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="Temp_Shutdown" parent="Micro820" dataType="Real" address="400074" va="0x568">
<mapping variable="Temp_Shutdown" parent="Micro820" dataType="Real" address="400074" va="0x560">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="Temp_Startup" parent="Micro820" dataType="Real" address="400076" va="0x56c">
<mapping variable="Temp_Startup" parent="Micro820" dataType="Real" address="400076" va="0x564">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_LineFrequency" parent="Micro820" dataType="Real" address="400078" va="0x664">
<mapping variable="E300_LineFrequency" parent="Micro820" dataType="Real" address="400078" va="0x65c">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L1Current" parent="Micro820" dataType="Real" address="400080" va="0x668">
<mapping variable="E300_L1Current" parent="Micro820" dataType="Real" address="400080" va="0x660">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L2Current" parent="Micro820" dataType="Real" address="400082" va="0x66c">
<mapping variable="E300_L2Current" parent="Micro820" dataType="Real" address="400082" va="0x664">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L3Current" parent="Micro820" dataType="Real" address="400084" va="0x670">
<mapping variable="E300_L3Current" parent="Micro820" dataType="Real" address="400084" va="0x668">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_AverageCurrent" parent="Micro820" dataType="Real" address="400086" va="0x674">
<mapping variable="E300_AverageCurrent" parent="Micro820" dataType="Real" address="400086" va="0x66c">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_PercentCurrentUnbalance" parent="Micro820" dataType="Real" address="400088" va="0x678">
<mapping variable="E300_PercentCurrentUnbalance" parent="Micro820" dataType="Real" address="400088" va="0x670">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L1NVoltage" parent="Micro820" dataType="Real" address="400090" va="0x67c">
<mapping variable="E300_L1NVoltage" parent="Micro820" dataType="Real" address="400090" va="0x674">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L2NVoltage" parent="Micro820" dataType="Real" address="400092" va="0x680">
<mapping variable="E300_L2NVoltage" parent="Micro820" dataType="Real" address="400092" va="0x678">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L3NVoltage" parent="Micro820" dataType="Real" address="400094" va="0x684">
<mapping variable="E300_L3NVoltage" parent="Micro820" dataType="Real" address="400094" va="0x67c">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_AverageLNVoltage" parent="Micro820" dataType="Real" address="400096" va="0x688">
<mapping variable="E300_AverageLNVoltage" parent="Micro820" dataType="Real" address="400096" va="0x680">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L1L2Voltage" parent="Micro820" dataType="Real" address="400098" va="0x68c">
<mapping variable="E300_L1L2Voltage" parent="Micro820" dataType="Real" address="400098" va="0x684">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L2L3Voltage" parent="Micro820" dataType="Real" address="400100" va="0x690">
<mapping variable="E300_L2L3Voltage" parent="Micro820" dataType="Real" address="400100" va="0x688">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L3L1Voltage" parent="Micro820" dataType="Real" address="400102" va="0x694">
<mapping variable="E300_L3L1Voltage" parent="Micro820" dataType="Real" address="400102" va="0x68c">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_AverageLLVoltage" parent="Micro820" dataType="Real" address="400104" va="0x698">
<mapping variable="E300_AverageLLVoltage" parent="Micro820" dataType="Real" address="400104" va="0x690">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L1RealPower" parent="Micro820" dataType="Real" address="400106" va="0x6a0">
<mapping variable="E300_L1RealPower" parent="Micro820" dataType="Real" address="400106" va="0x698">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L2RealPower" parent="Micro820" dataType="Real" address="400108" va="0x6a4">
<mapping variable="E300_L2RealPower" parent="Micro820" dataType="Real" address="400108" va="0x69c">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L3RealPower" parent="Micro820" dataType="Real" address="400110" va="0x6a8">
<mapping variable="E300_L3RealPower" parent="Micro820" dataType="Real" address="400110" va="0x6a0">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_TotalRealPower" parent="Micro820" dataType="Real" address="400112" va="0x6ac">
<mapping variable="E300_TotalRealPower" parent="Micro820" dataType="Real" address="400112" va="0x6a4">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L1ReactivePower" parent="Micro820" dataType="Real" address="400114" va="0x6b0">
<mapping variable="E300_L1ReactivePower" parent="Micro820" dataType="Real" address="400114" va="0x6a8">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L2ReactivePower" parent="Micro820" dataType="Real" address="400116" va="0x6b4">
<mapping variable="E300_L2ReactivePower" parent="Micro820" dataType="Real" address="400116" va="0x6ac">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L3ReactivePower" parent="Micro820" dataType="Real" address="400118" va="0x6b8">
<mapping variable="E300_L3ReactivePower" parent="Micro820" dataType="Real" address="400118" va="0x6b0">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_TotalReactivePower" parent="Micro820" dataType="Real" address="400120" va="0x6bc">
<mapping variable="E300_TotalReactivePower" parent="Micro820" dataType="Real" address="400120" va="0x6b4">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L1ApparentPower" parent="Micro820" dataType="Real" address="400122" va="0x6c0">
<mapping variable="E300_L1ApparentPower" parent="Micro820" dataType="Real" address="400122" va="0x6b8">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L2ApparentPower" parent="Micro820" dataType="Real" address="400124" va="0x6c4">
<mapping variable="E300_L2ApparentPower" parent="Micro820" dataType="Real" address="400124" va="0x6bc">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L3ApparentPower" parent="Micro820" dataType="Real" address="400126" va="0x6c8">
<mapping variable="E300_L3ApparentPower" parent="Micro820" dataType="Real" address="400126" va="0x6c0">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_TotalApparentPower" parent="Micro820" dataType="Real" address="400128" va="0x6cc">
<mapping variable="E300_TotalApparentPower" parent="Micro820" dataType="Real" address="400128" va="0x6c4">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L1TruePowerFactor" parent="Micro820" dataType="Real" address="400130" va="0x6d0">
<mapping variable="E300_L1TruePowerFactor" parent="Micro820" dataType="Real" address="400130" va="0x6c8">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L2TruePowerFactor" parent="Micro820" dataType="Real" address="400132" va="0x6d4">
<mapping variable="E300_L2TruePowerFactor" parent="Micro820" dataType="Real" address="400132" va="0x6cc">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_L3TruePowerFactor" parent="Micro820" dataType="Real" address="400134" va="0x6d8">
<mapping variable="E300_L3TruePowerFactor" parent="Micro820" dataType="Real" address="400134" va="0x6d0">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="E300_ThreePhaseTruePowerFactor" parent="Micro820" dataType="Real" address="400136" va="0x6dc">
<mapping variable="E300_ThreePhaseTruePowerFactor" parent="Micro820" dataType="Real" address="400136" va="0x6d4">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
<mapping variable="Pressure_In" parent="Micro820" dataType="Real" address="400138" va="0x6e0">
<mapping variable="Pressure_In" parent="Micro820" dataType="Real" address="400138" va="0x6d8">
<MBVarInfo ElemType="Real" SubElemType="Any" DataTypeSize="4" />
</mapping>
</modbusRegister>

View File

@@ -1 +1 @@
CONTROL(161):FB,LINEARSCALE(159);F,RIGHT();F,MOD();
CONTROL(161):FB,EPOCH_TIME(163);FB,LINEARSCALE(159);F,RIGHT();F,MOD();

View File

@@ -1,13 +1,14 @@
_PUSH_PAR __SYSVA_CYCLEDATE
__TMPI1 := _CALL ANY_TO_TIME
__TMPI1 := __TMPI1 / __CDINT000003E8
__FBL_RET := _PUSHCALLFB EPOCH_TIME EPOCH_TIME_1
__TMPULI1 := EPOCH_TIME_1 [ __CDINT00000004 ]
_PUSH_PAR __TMPULI1
__TMPI1 := _CALL ANY_TO_ULINT
TIME_CURRENTTIME := __TMPI1
__TMPB1 := _NOT TEST_MODE
_IF _NOT __TMPB1 _GOTO __LAB1
CONTACTOR_STATUS := DIGITALINPUT_STATUS_2
START_BUTTON := DIGITALINPUT_STATUS_3
AUTO_MODE := DIGITALINPUT_STATUS_4
HAND_MODE := DIGITALINPUT_STATUS_5
CONTACTOR_STATUS := DIGITALINPUT_STATUS_0
START_BUTTON := DIGITALINPUT_STATUS_1
AUTO_MODE := DIGITALINPUT_STATUS_2
HAND_MODE := DIGITALINPUT_STATUS_3
_PUSH_PAR _IO_P1_AI_00
__TMPR3 := _CALL ANY_TO_UINT
__TMPR__LINEARSCALE__RAW_INP := __TMPR3
@@ -57,6 +58,7 @@ __TMPI1 := __TMPI1 * __CDINT00000002
__TMPUIN1 := MODBUS_READ0 [ __TMPI1 ]
_PUSH_PAR __TMPUIN1
__TMPR3 := _CALL ANY_TO_UINT
__TMPR3 := __TMPR3 - __TMPR5
DH_INTAKEPRESSURE := __TMPR3
__TMPI1 := __CDINT0000000A - __CDINT00000001
__TMPI1 := __TMPI1 * __CDINT00000002
@@ -81,13 +83,12 @@ __TMPI1 := __CDINT00000063 - __CDINT00000001
__TMPI1 := __TMPI1 * __CDINT00000002
__TMPUIN1 := MODBUS_READ0 [ __TMPI1 ]
DH_DOWNHOLESTATUS_INT := __TMPUIN1
__TMPR3 := DH_INTAKEPRESSURE - __TMPR5
__TMPR8 := __TMPR6 / __TMPR7
__TMPR3 := __TMPR3 * __TMPR8
__TMPR3 := __TMPR6 / __TMPR7
__TMPR8 := DH_INTAKEPRESSURE * __TMPR3
__TMPR9 := __TMPR6 / CFG_SPECIFICGRAVITY
__TMPR3 := __TMPR3 * __TMPR9
__TMPR3 := __TMPR3 + CFG_DHSENSORDISTTOINTAKE
DH_FLUID_LEVEL := __TMPR3
__TMPR8 := __TMPR8 * __TMPR9
__TMPR8 := __TMPR8 + CFG_DHSENSORDISTTOINTAKE
DH_FLUID_LEVEL := __TMPR8
__TMPI1 := __CDINT00000063 - __CDINT00000001
__TMPI1 := __TMPI1 * __CDINT00000002
__TMPUIN1 := MODBUS_READ0 [ __TMPI1 ]
@@ -283,15 +284,19 @@ __TMPB1 := VAL_OVERLOADTRIPCOUNT > CFG_OVERLOADTRIPCOUNTLIMIT
_IF _NOT __TMPB1 _GOTO __LAB20
RESTART_ALLOWED := FALSE
DEVICE_STATUS := __TMPM12
STS_TRIPLIMITOLREACHED := TRUE
_GOTO __LAB21
__LAB20 :
STS_TRIPLIMITOLREACHED := FALSE
__LAB21 :
__TMPB1 := VAL_TRIPCOUNT > CFG_TRIPCOUNTLIMIT
_IF _NOT __TMPB1 _GOTO __LAB22
RESTART_ALLOWED := FALSE
DEVICE_STATUS := __TMPM13
STS_TRIPLIMITREACHED := TRUE
_GOTO __LAB23
__LAB22 :
STS_TRIPLIMITREACHED := FALSE
__LAB23 :
__TMPB1 := START_COMMAND _OR START_BUTTON
__TMPB1 := __TMPB1 _AND START_PERMISSIVE
@@ -311,17 +316,22 @@ __TMPB1 := _NOT OVERLOADTRIP
__TMPB2 := AUTO_MODE _AND __TMPB1
__TMPB3 := _NOT CMD_RUN
__TMPB2 := __TMPB2 _AND __TMPB3
__TMPB4 := STS_TIMERCYCLEACTIVE _AND CMD_TIMERRUN
__TMPB5 := _NOT STS_TIMERCYCLEACTIVE
__TMPB4 := __TMPB4 _OR __TMPB5
__TMPB2 := __TMPB2 _AND __TMPB4
__TMPB2 := __TMPB2 _AND RESTART_ALLOWED
_IF _NOT __TMPB2 _GOTO __LAB28
__TMPI1 := TIME_CURRENTTIME - SHUTDOWN_TIME
__TMPB4 := __TMPI1 > DOWNTIME_TIME_PARAMETER
_IF _NOT __TMPB4 _GOTO __LAB29
__TMPB5 := _NOT RESTART_COMMAND
_IF _NOT __TMPB5 _GOTO __LAB2a
__TMPB6 := __TMPI1 > DOWNTIME_TIME_PARAMETER
_IF _NOT __TMPB6 _GOTO __LAB29
__TMPB7 := _NOT RESTART_COMMAND
_IF _NOT __TMPB7 _GOTO __LAB2a
TRIPRESETCMD := TRUE
RESTART_COMMAND := TRUE
_IF _NOT CFG_TIMERMODEENABLED _GOTO __LAB2b
CMD_TIMERRUN := TRUE
STS_TIMERCYCLEACTIVE := TRUE
_GOTO __LAB2c
__LAB2b :
__LAB2c :
@@ -378,6 +388,7 @@ _IF _NOT __TMPB4 _GOTO __LAB36
RESTART_COMMAND := TRUE
_IF _NOT CFG_TIMERMODEENABLED _GOTO __LAB37
CMD_TIMERRUN := TRUE
STS_TIMERCYCLEACTIVE := TRUE
_GOTO __LAB38
__LAB37 :
__LAB38 :
@@ -592,6 +603,8 @@ __TMPB1 := _NOT CFG_TIMERMODEENABLED
__TMPB1 := __TMPB1 _OR STOP_COMMAND
_IF _NOT __TMPB1 _GOTO __LAB65
CMD_TIMERRUN := FALSE
STS_TIMERRUNTIMESET := FALSE
STS_TIMERWAITTIMESET := FALSE
_GOTO __LAB66
__LAB65 :
__LAB66 :

View File

@@ -0,0 +1 @@
COMPILED

View File

@@ -1,13 +1,16 @@
PROGRAM Control
(* CURRENT TIME IN SECONDS... this doesn't really correlate to anything other than a second counter *)
time_CurrentTime := ANY_TO_DINT( __SYSVA_CYCLEDATE) / 1000;
(* time_CurrentTime := ANY_TO_DINT( __SYSVA_CYCLEDATE) / 1000;*)
Epoch_Time_1(TRUE);
time_CurrentTime := ANY_TO_DINT(Epoch_Time_1.Epoch);
(*IO Mapping*)
IF NOT Test_Mode THEN
Contactor_Status := DigitalInput_Status_2;
Start_Button := DigitalInput_Status_3;
Auto_Mode := DigitalInput_Status_4;
Hand_Mode := DigitalInput_Status_5;
Contactor_Status := DigitalInput_Status_0;
Start_Button := DigitalInput_Status_1;
Auto_Mode := DigitalInput_Status_2;
Hand_Mode := DigitalInput_Status_3;
LinearScale_Pressure(13107.0, 65535.0, Pressure_EU_Min, Pressure_EU_Max, ANY_TO_REAL(_IO_P1_AI_00));
Pressure_In := LinearScale_Pressure.EU_Out;
ELSE
@@ -41,13 +44,13 @@ E300_kWh_Regen := ANY_TO_REAL(E300.RealEnergyGeneratedOdometer);
IF Downhole_Tool_Enabled THEN
(*Modbus Mapping*)
DH_IntakeTemperature := ANY_TO_REAL(Modbus_Read0[2]) / 10.0;
DH_IntakePressure := ANY_TO_REAL(Modbus_Read0[3]);
DH_IntakePressure := ANY_TO_REAL(Modbus_Read0[3]) - 14.0;
DH_NumChannels := Modbus_Read0[10];
DH_ToolVoltage := Modbus_Read0[11];
DH_MaxIntakeTemperature_Startup := ANY_TO_REAL(Modbus_Read0[40]) / 10.0;
DH_MaxIntakePressure_Startup := Modbus_Read0[41];
DH_DownholeStatus_INT := Modbus_Read0[99];
DH_Fluid_Level := (DH_IntakePressure - 14.0) * (1.0 / 0.433) * (1.0 / cfg_SpecificGravity) + cfg_DHSensorDistToIntake;
DH_Fluid_Level := DH_IntakePressure * (1.0 / 0.433) * (1.0 / cfg_SpecificGravity) + cfg_DHSensorDistToIntake;
CASE Modbus_Read0[99] OF
0: DH_DownholeStatus := 'OK';
@@ -154,11 +157,17 @@ END_IF;
IF val_OverloadTripCount > cfg_OverloadTripCountLimit THEN
Restart_Allowed := FALSE;
Device_Status := 'Not able to restart - Overload Limit';
sts_TripLimitOLReached := TRUE;
ELSE
sts_TripLimitOLReached := FALSE;
END_IF;
IF val_TripCount > cfg_TripCountLimit THEN
Restart_Allowed := FALSE;
Device_Status := 'Not able to restart - Trip Limit';
sts_TripLimitReached := TRUE;
ELSE
sts_TripLimitReached := FALSE;
END_IF;
(* If the pump hasn't been started by the user, don't allow it to auto-restart *)
@@ -173,13 +182,19 @@ IF (Start_Command OR Start_Button) AND Start_Permissive THEN
END_IF;
(* If run permissive goes false, do not allow a restart for a specified amount of time *)
IF (Auto_Mode AND (NOT OverloadTrip) AND NOT cmd_Run AND Restart_Allowed) THEN
IF (Auto_Mode AND
(NOT OverloadTrip) AND
(NOT cmd_Run) AND
((sts_TimerCycleActive AND cmd_TimerRun) OR (NOT sts_TimerCycleActive)) AND
Restart_Allowed) THEN
IF (time_CurrentTime - Shutdown_Time) > Downtime_Time_Parameter THEN
IF (NOT Restart_Command) THEN
TripResetCmd := TRUE;
Restart_Command := TRUE;
IF cfg_TimerModeEnabled THEN
cmd_TimerRun := TRUE;
sts_TimerCycleActive := TRUE;
END_IF;
END_IF;
ELSE
@@ -197,12 +212,17 @@ IF (Auto_Mode AND (NOT OverloadTrip) AND NOT cmd_Run AND Restart_Allowed) THEN
END_IF;
END_IF;
ELSIF (Auto_Mode AND OverloadTrip AND NOT cmd_Run AND Restart_Allowed) THEN
ELSIF (Auto_Mode AND
OverloadTrip AND
(NOT cmd_Run) AND
Restart_Allowed) THEN
IF (time_CurrentTime - Shutdown_Time) > Downtime_Time_Parameter_OL THEN
IF (NOT Restart_Command) THEN
Restart_Command := True;
IF cfg_TimerModeEnabled THEN
cmd_TimerRun := TRUE;
sts_TimerCycleActive := TRUE;
END_IF;
END_IF;
ELSE
@@ -332,6 +352,8 @@ END_IF;
IF NOT cfg_TimerModeEnabled OR Stop_Command THEN
cmd_TimerRun := FALSE;
sts_TimerRunTimeSet := FALSE;
sts_TimerWaitTimeSet := FALSE;
END_IF;

View File

@@ -18,3 +18,4 @@ SINT_TO_USINT
WRITEE300CONFIG
WRITEE300TRIPRESET
LINEARSCALE
EPOCH_TIME

View File

@@ -0,0 +1 @@
EPOCH_TIME(163):F,MOD();

View File

@@ -0,0 +1,144 @@
__TMPV1 := __EPOCH_TIME [ __DINT_NULL ]
__TMPB1 := __TMPV1 [ __DINT_NULL ]
__TMPV2 := __EPOCH_TIME [ __CDINT0000000C ]
__TMPB__RTC_READ__ENABLE := __TMPB1
__FBL_RET := _PUSHCALLFB RTC_READ __TMPV2
__TMPI1 := __CDINT00000002 + __CDINT00000002
__TMPI2 := __CDINT0000000C + __TMPI1
__TMPUIN1 := __EPOCH_TIME [ __TMPI2 ]
_PUSH_PAR __TMPUIN1
__TMPI3 := _CALL ANY_TO_UINT
__TMPB2 := __TMPI3 <> __CDINT00000001
_IF __TMPB2 _GOTO __LAB2
__EPOCH_TIME [ __CDINT00000020 ] := __UINT_NULL
_GOTO __LAB1
__LAB2 :
__TMPB2 := __TMPI3 <> __CDINT00000002
_IF __TMPB2 _GOTO __LAB3
__EPOCH_TIME [ __CDINT00000020 ] := __CUINT0000001F
_GOTO __LAB1
__LAB3 :
__TMPB2 := __TMPI3 <> __CDINT00000003
_IF __TMPB2 _GOTO __LAB4
__EPOCH_TIME [ __CDINT00000020 ] := __CUINT0000003B
_GOTO __LAB1
__LAB4 :
__TMPB2 := __TMPI3 <> __CDINT00000004
_IF __TMPB2 _GOTO __LAB5
__EPOCH_TIME [ __CDINT00000020 ] := __CUINT0000005A
_GOTO __LAB1
__LAB5 :
__TMPB2 := __TMPI3 <> __CDINT00000005
_IF __TMPB2 _GOTO __LAB6
__EPOCH_TIME [ __CDINT00000020 ] := __CUINT00000079
_GOTO __LAB1
__LAB6 :
__TMPB2 := __TMPI3 <> __CDINT00000006
_IF __TMPB2 _GOTO __LAB7
__EPOCH_TIME [ __CDINT00000020 ] := __CUINT00000097
_GOTO __LAB1
__LAB7 :
__TMPB2 := __TMPI3 <> __CDINT00000007
_IF __TMPB2 _GOTO __LAB8
__EPOCH_TIME [ __CDINT00000020 ] := __CUINT000000B5
_GOTO __LAB1
__LAB8 :
__TMPB2 := __TMPI3 <> __CDINT00000008
_IF __TMPB2 _GOTO __LAB9
__EPOCH_TIME [ __CDINT00000020 ] := __CUINT000000D4
_GOTO __LAB1
__LAB9 :
__TMPB2 := __TMPI3 <> __CDINT00000009
_IF __TMPB2 _GOTO __LABa
__EPOCH_TIME [ __CDINT00000020 ] := __CUINT000000F3
_GOTO __LAB1
__LABa :
__TMPB2 := __TMPI3 <> __CDINT0000000A
_IF __TMPB2 _GOTO __LABb
__EPOCH_TIME [ __CDINT00000020 ] := __CUINT00000111
_GOTO __LAB1
__LABb :
__TMPB2 := __TMPI3 <> __CDINT0000000B
_IF __TMPB2 _GOTO __LABc
__EPOCH_TIME [ __CDINT00000020 ] := __CUINT00000130
_GOTO __LAB1
__LABc :
__TMPB2 := __TMPI3 <> __CDINT0000000C
_IF __TMPB2 _GOTO __LABd
__EPOCH_TIME [ __CDINT00000020 ] := __CUINT0000014E
_GOTO __LAB1
__LABd :
__LAB1 :
__TMPI1 := __CDINT00000002 + __DINT_NULL
__TMPI2 := __CDINT0000000C + __TMPI1
__TMPUIN1 := __EPOCH_TIME [ __TMPI2 ]
_PUSH_PAR __TMPUIN1
__TMPI3 := _CALL ANY_TO_UINT
_PUSH_PAR __TMPI3
_PUSH_PAR __CDINT00000004
__TMPI4 := _CALL MOD
__TMPB2 := __TMPI4 = __DINT_NULL
_IF _NOT __TMPB2 _GOTO __LABe
__TMPI5 := __CDINT00000002 + __CDINT00000002
__TMPI6 := __CDINT0000000C + __TMPI5
__TMPUIN2 := __EPOCH_TIME [ __TMPI6 ]
__TMPB3 := __TMPUIN2 > __CUINT00000002
_IF _NOT __TMPB3 _GOTO __LABf
__TMPUIN3 := __EPOCH_TIME [ __CDINT00000020 ]
__TMPUIN3 := __TMPUIN3 + __CUINT00000001
__EPOCH_TIME [ __CDINT00000020 ] := __TMPUIN3
_GOTO __LAB10
__LABf :
__LAB10 :
_GOTO __LAB11
__LABe :
__LAB11 :
__TMPI1 := __CDINT00000002 + __DINT_NULL
__TMPI2 := __CDINT0000000C + __TMPI1
__TMPUIN1 := __EPOCH_TIME [ __TMPI2 ]
_PUSH_PAR __CDINT000007B2
__TMPUIN2 := _CALL ANY_TO_DINT
__TMPUIN1 := __TMPUIN1 - __TMPUIN2
_PUSH_PAR __TMPUIN1
__TMPULI1 := _CALL ANY_TO_UINT
_PUSH_PAR __CDINT01E1853E
__TMPULI2 := _CALL ANY_TO_DINT
__TMPULI1 := __TMPULI1 * __TMPULI2
__EPOCH_TIME [ __CDINT00000024 ] := __TMPULI1
__TMPUIN1 := __EPOCH_TIME [ __CDINT00000020 ]
__TMPI1 := __CDINT00000002 + __CDINT00000004
__TMPI2 := __CDINT0000000C + __TMPI1
__TMPUIN2 := __EPOCH_TIME [ __TMPI2 ]
__TMPUIN1 := __TMPUIN1 + __TMPUIN2
_PUSH_PAR __CDINT00015180
__TMPUIN3 := _CALL ANY_TO_DINT
__TMPUIN1 := __TMPUIN1 * __TMPUIN3
_PUSH_PAR __TMPUIN1
__TMPULI1 := _CALL ANY_TO_UINT
__EPOCH_TIME [ __CDINT0000002C ] := __TMPULI1
__TMPI1 := __CDINT00000002 + __CDINT00000006
__TMPI2 := __CDINT0000000C + __TMPI1
__TMPUIN1 := __EPOCH_TIME [ __TMPI2 ]
__TMPUIN1 := __TMPUIN1 * __CUINT00000E10
_PUSH_PAR __TMPUIN1
__TMPULI1 := _CALL ANY_TO_UINT
__EPOCH_TIME [ __CDINT0000003C ] := __TMPULI1
__TMPI1 := __CDINT00000002 + __CDINT00000008
__TMPI2 := __CDINT0000000C + __TMPI1
__TMPUIN1 := __EPOCH_TIME [ __TMPI2 ]
__TMPUIN1 := __TMPUIN1 * __CUINT0000003C
_PUSH_PAR __TMPUIN1
__TMPULI1 := _CALL ANY_TO_UINT
__EPOCH_TIME [ __CDINT00000034 ] := __TMPULI1
__TMPULI1 := __EPOCH_TIME [ __CDINT00000024 ]
__TMPULI2 := __EPOCH_TIME [ __CDINT0000002C ]
__TMPULI1 := __TMPULI1 + __TMPULI2
__TMPULI3 := __EPOCH_TIME [ __CDINT0000003C ]
__TMPULI1 := __TMPULI1 + __TMPULI3
__TMPI1 := __CDINT00000002 + __CDINT0000000A
__TMPI2 := __CDINT0000000C + __TMPI1
__TMPUIN1 := __EPOCH_TIME [ __TMPI2 ]
_PUSH_PAR __TMPUIN1
__TMPULI4 := _CALL ANY_TO_UINT
__TMPULI1 := __TMPULI1 + __TMPULI4
__EPOCH_TIME [ __CDINT00000004 ] := __TMPULI1

Binary file not shown.

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Root Version="6">
<LanguageContainerStyle CommentTextColor="Green" CommentFont="Courier New, 10pt" PonctuationTextColor="Black" PonctuationFont="Courier New, 10pt" IdentifierTextColor="Black" IdentifierFont="Courier New, 10pt" OperatorTextColor="Black" OperatorFont="Courier New, 10pt" ReservedWordTextColor="Fuchsia" ReservedWordFont="Courier New, 10pt" PouTextColor="BlueViolet" PouFont="Courier New, 10pt" NumberTextColor="Firebrick" NumberFont="Courier New, 10pt" StringTextColor="Gray" StringFont="Courier New, 10pt" EditorTextAreaBackgroundColor="White" EditorFont="Courier New, 10pt" Index="0" />
</Root>

View File

@@ -0,0 +1,30 @@
FUNCTION_BLOCK Epoch_Time
RTC_READ_1(RTC_READ_ENABLED);
CASE RTC_READ_1.RTCData.Month OF
1: prev_months_days := 0;
2: prev_months_days := 31;
3: prev_months_days := 59;
4: prev_months_days := 90;
5: prev_months_days := 121;
6: prev_months_days := 151;
7: prev_months_days := 181;
8: prev_months_days := 212;
9: prev_months_days := 243;
10: prev_months_days := 273;
11: prev_months_days := 304;
12: prev_months_days := 334;
END_CASE;
IF MOD(ANY_TO_DINT(RTC_READ_1.RTCData.Year), 4) = 0 THEN
IF RTC_READ_1.RTCData.Month > 2 THEN
prev_months_days := prev_months_days + 1;
END_IF;
END_IF;
year_seconds := ANY_TO_ULINT(RTC_READ_1.RTCData.Year - ANY_TO_UINT(1970)) * ANY_TO_ULINT(31556926);
day_seconds := ANY_TO_ULINT((prev_months_days + RTC_READ_1.RTCData.Day) * ANY_TO_UINT(86400));
hour_seconds := ANY_TO_ULINT(RTC_READ_1.RTCData.Hours * 3600);
min_seconds := ANY_TO_ULINT(RTC_READ_1.RTCData.Minutes * 60);
Epoch := year_seconds + day_seconds + hour_Seconds + ANY_TO_ULINT(RTC_READ_1.RTCData.Seconds);
END_FUNCTION_BLOCK

View File

@@ -72,6 +72,7 @@ E300_OUTPUT.FBEN@E300DATA,E300_OUTPUT_ENABLE,BOOL
E300_OUTPUT.IPADDRESS@E300DATA,E300_IP_ADDRESS,STRING
E300_OUTPUT.OUTPUTNUMBER@E300DATA,E300_OUTPUT_NUMBER,USINT
E300_OUTPUT.OUTPUTSETTING@E300DATA,CMD_RUN,BOOL
EPOCH_TIME_1.RTC_READ_ENABLED@CONTROL,TRUE,BOOL
D2S_FLASETTING.INP_DINT@E300DATA,__TMPUDI__UDINT_TO_USINT__INP_DINT,UDINT
WRITEE300CONFIGDATA.FBEN_FTRIG.CLK@E300DATA,__TMPB__F_TRIG__CLK,BOOL
E300_OUTPUT.OUTPUTSETTING_FTRIG.CLK@E300DATA,__TMPB__F_TRIG__CLK,BOOL
@@ -199,6 +200,7 @@ U2S_UNDERPFLAGTRIPLEVEL.SINT_SRC_1@E300DATA,__TMPUSI__USINT_TO_SINT__SINT_SRC_1,
U2S_UNDERPFLAGWARNINGLEVEL.SINT_SRC_1@E300DATA,__TMPUSI__USINT_TO_SINT__SINT_SRC_1,USINT
U2S_OVERPFLAGTRIPLEVEL.SINT_SRC_1@E300DATA,__TMPUSI__USINT_TO_SINT__SINT_SRC_1,USINT
U2S_OVERPFLAGWARNINGLEVEL.SINT_SRC_1@E300DATA,__TMPUSI__USINT_TO_SINT__SINT_SRC_1,USINT
EPOCH_TIME_1.RTC_READ_1.ENABLE@CONTROL,__TMPB__RTC_READ__ENABLE,BOOL
RTRIG_AUTOMODE.CLK@CONTROL,AUTO_MODE,BOOL
WRITEE300CONFIGDATA.MSGOBJREAD_Q_RTRIG.CLK@E300DATA,__TMPB__R_TRIG__CLK,BOOL
WRITEE300CONFIGDATA.FBEN_RTRIG.CLK@E300DATA,__TMPB__R_TRIG__CLK,BOOL

View File

@@ -1,17 +1,18 @@
USINT_TO_DINT:
USINT_TO_UINT:
USINT_TO_DINT:
USINT_TO_SINT:
READE300CONFIG:
EPOCH_TIME:
READE300TRIPRESET:
READE300CONFIG:
WRITEE300TRIPRESET:
READE300IO:
WRITEE300CONFIG:
RA_E300_OUTPUT_CONTROL:
UINT_TO_USINT:
READE300PARAM:
RA_E300_OUTPUT_CONTROL:
USINT_TO_UDINT:
READE300PARAM:
UDINT_TO_USINT:
RA_CIP_ELECTRICAL_ENERGY_OBJ:
LINEARSCALE:
SINT_TO_USINT:
RA_CIP_ELECTRICAL_ENERGY_OBJ:
DINT_TO_USINT:
SINT_TO_USINT:

View File

@@ -1,47 +1,51 @@
0::0046-0003::-------------------- Pre-build resource: MICRO820 Configuration: MICRO820 --------------
0::0044-0003::Pre-compiling for 2080LC2020QWBI
0::0000-0003::RA_CIP_ELECTRICAL_ENERGY_OBJ
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\RA_CIP_ELECTRICAL_ENERGY_OBJ:0000-0003::RA_E300_OUTPUT_CONTROL
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\RA_E300_OUTPUT_CONTROL:0000-0003::READE300IO
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READE300IO:0000-0003::READE300CONFIG
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READE300CONFIG:0000-0003::READE300TRIPRESET
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READE300TRIPRESET:0000-0003::READE300PARAM
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READE300PARAM:0000-0003::USINT_TO_UDINT
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\USINT_TO_UDINT:0000-0003::USINT_TO_DINT
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\USINT_TO_DINT:0000-0003::USINT_TO_UINT
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\USINT_TO_UINT:0000-0003::USINT_TO_SINT
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\USINT_TO_SINT:0000-0003::UDINT_TO_USINT
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\UDINT_TO_USINT:0000-0003::DINT_TO_USINT
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\DINT_TO_USINT:0000-0003::UINT_TO_USINT
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\UINT_TO_USINT:0000-0003::SINT_TO_USINT
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\SINT_TO_USINT:0000-0003::WRITEE300CONFIG
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\WRITEE300CONFIG:0000-0003::WRITEE300TRIPRESET
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\WRITEE300TRIPRESET:0000-0003::LINEARSCALE
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\LINEARSCALE:0000-0003::READDOWNHOLEDATA
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READDOWNHOLEDATA:0000-0003::CONTROL
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\CONTROL:0000-0003::E300DATA
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\E300DATA:0002-0003::MICRO820: 0 error(s), 0 warning(s)
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\RA_CIP_ELECTRICAL_ENERGY_OBJ:0000-0003::RA_E300_OUTPUT_CONTROL
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\RA_E300_OUTPUT_CONTROL:0000-0003::READE300IO
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READE300IO:0000-0003::READE300CONFIG
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READE300CONFIG:0000-0003::READE300TRIPRESET
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READE300TRIPRESET:0000-0003::READE300PARAM
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READE300PARAM:0000-0003::USINT_TO_UDINT
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\USINT_TO_UDINT:0000-0003::USINT_TO_DINT
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\USINT_TO_DINT:0000-0003::USINT_TO_UINT
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\USINT_TO_UINT:0000-0003::USINT_TO_SINT
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\USINT_TO_SINT:0000-0003::UDINT_TO_USINT
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\UDINT_TO_USINT:0000-0003::DINT_TO_USINT
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\DINT_TO_USINT:0000-0003::UINT_TO_USINT
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\UINT_TO_USINT:0000-0003::SINT_TO_USINT
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\SINT_TO_USINT:0000-0003::WRITEE300CONFIG
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\WRITEE300CONFIG:0000-0003::WRITEE300TRIPRESET
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\WRITEE300TRIPRESET:0000-0003::LINEARSCALE
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\LINEARSCALE:0000-0003::EPOCH_TIME
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\EPOCH_TIME:0000-0003::READDOWNHOLEDATA
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READDOWNHOLEDATA:0000-0003::CONTROL
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\CONTROL:0000-0003::E300DATA
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\E300DATA:0002-0003::MICRO820: 0 error(s), 0 warning(s)
0::0006-0003::-------------------- Build resource: MICRO820 Configuration: MICRO820 --------------
0::0001-0003::Compiling for 2080LC2020QWBI
0::0000-0003::RA_CIP_ELECTRICAL_ENERGY_OBJ
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\RA_CIP_ELECTRICAL_ENERGY_OBJ:0000-0003::RA_E300_OUTPUT_CONTROL
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\RA_E300_OUTPUT_CONTROL:0000-0003::READE300IO
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READE300IO:0000-0003::READE300CONFIG
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READE300CONFIG:0000-0003::READE300TRIPRESET
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READE300TRIPRESET:0000-0003::READE300PARAM
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READE300PARAM:0000-0003::USINT_TO_UDINT
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\USINT_TO_UDINT:0000-0003::USINT_TO_DINT
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\USINT_TO_DINT:0000-0003::USINT_TO_UINT
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\USINT_TO_UINT:0000-0003::USINT_TO_SINT
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\USINT_TO_SINT:0000-0003::UDINT_TO_USINT
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\UDINT_TO_USINT:0000-0003::DINT_TO_USINT
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\DINT_TO_USINT:0000-0003::UINT_TO_USINT
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\UINT_TO_USINT:0000-0003::SINT_TO_USINT
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\SINT_TO_USINT:0000-0003::WRITEE300CONFIG
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\WRITEE300CONFIG:0000-0003::WRITEE300TRIPRESET
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\WRITEE300TRIPRESET:0000-0003::LINEARSCALE
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\LINEARSCALE:0000-0003::READDOWNHOLEDATA
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READDOWNHOLEDATA:0000-0003::CONTROL
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\CONTROL:0000-0003::E300DATA
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\E300DATA:0003-0003::Linking for 2080LC2020QWBI
0:C:\USERS\PATRICK\HENRY_PUMP\E300-IPP\CONTROLLER\CONTROLLER\MICRO820\MICRO820\E300DATA:0002-0003::MICRO820: 0 error(s), 0 warning(s)
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\RA_CIP_ELECTRICAL_ENERGY_OBJ:0000-0003::RA_E300_OUTPUT_CONTROL
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\RA_E300_OUTPUT_CONTROL:0000-0003::READE300IO
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READE300IO:0000-0003::READE300CONFIG
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READE300CONFIG:0000-0003::READE300TRIPRESET
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READE300TRIPRESET:0000-0003::READE300PARAM
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READE300PARAM:0000-0003::USINT_TO_UDINT
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\USINT_TO_UDINT:0000-0003::USINT_TO_DINT
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\USINT_TO_DINT:0000-0003::USINT_TO_UINT
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\USINT_TO_UINT:0000-0003::USINT_TO_SINT
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\USINT_TO_SINT:0000-0003::UDINT_TO_USINT
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\UDINT_TO_USINT:0000-0003::DINT_TO_USINT
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\DINT_TO_USINT:0000-0003::UINT_TO_USINT
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\UINT_TO_USINT:0000-0003::SINT_TO_USINT
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\SINT_TO_USINT:0000-0003::WRITEE300CONFIG
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\WRITEE300CONFIG:0000-0003::WRITEE300TRIPRESET
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\WRITEE300TRIPRESET:0000-0003::LINEARSCALE
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\LINEARSCALE:0000-0003::EPOCH_TIME
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\EPOCH_TIME:0000-0003::READDOWNHOLEDATA
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\READDOWNHOLEDATA:0000-0003::CONTROL
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\CONTROL:0000-0003::E300DATA
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\E300DATA:0003-0003::Linking for 2080LC2020QWBI
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\E300DATA:0,0:0039-0001::WARNING: The structure of the user defined function block instance EPOCH_TIME_1@CONTROL has changed and will be reinitialized.
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\E300DATA:0002-0003:: 0 error(s), 1 warning(s)
0:C:\USERS\PATRICK\DOCUMENTS\HENRY_PUMP\IPP_PANEL\CONTROLLER\CONTROLLER\MICRO820\MICRO820\E300DATA:0002-0003::MICRO820: 0 error(s), 1 warning(s)

View File

@@ -2,11 +2,12 @@ USINT_TO_UDINT(149):
DINT_TO_USINT(154):
UINT_TO_USINT(155):
READE300TRIPRESET(147):FB,MSG_CIPGENERIC();FB,R_TRIG();FB,COP();FB,F_TRIG();
E300DATA(162):FB,RA_CIP_ELECTRICAL_ENERGY_OBJ(143);FB,RA_E300_OUTPUT_CONTROL(144);FB,READE300IO(145);FB,READE300PARAM(148);FB,USINT_TO_UINT(151);FB,WRITEE300TRIPRESET(158);FB,READE300CONFIG(146);FB,USINT_TO_UDINT(149);FB,USINT_TO_DINT(150);FB,USINT_TO_SINT(152);FB,UDINT_TO_USINT(153);FB,UINT_TO_USINT(155);FB,DINT_TO_USINT(154);FB,SINT_TO_USINT(156);FB,WRITEE300CONFIG(157);
RA_E300_OUTPUT_CONTROL(144):FB,MSG_CIPGENERIC();FB,R_TRIG();FB,F_TRIG();FB,COP();
E300DATA(162):FB,RA_CIP_ELECTRICAL_ENERGY_OBJ(143);FB,RA_E300_OUTPUT_CONTROL(144);FB,READE300IO(145);FB,READE300PARAM(148);FB,USINT_TO_UINT(151);FB,WRITEE300TRIPRESET(158);FB,READE300CONFIG(146);FB,USINT_TO_UDINT(149);FB,USINT_TO_DINT(150);FB,USINT_TO_SINT(152);FB,UDINT_TO_USINT(153);FB,UINT_TO_USINT(155);FB,DINT_TO_USINT(154);FB,SINT_TO_USINT(156);FB,WRITEE300CONFIG(157);
READE300PARAM(148):FB,MSG_CIPGENERIC();FB,R_TRIG();FB,COP();FB,F_TRIG();
USINT_TO_UINT(151):
CONTROL(161):FB,LINEARSCALE(159);
CONTROL(161):FB,EPOCH_TIME(163);FB,LINEARSCALE(159);
EPOCH_TIME(163):FB,RTC_READ();
USINT_TO_SINT(152):
READE300IO(145):FB,MSG_CIPGENERIC();FB,R_TRIG();FB,COP();FB,F_TRIG();
LINEARSCALE(159):

View File

@@ -1,10 +1,10 @@
[MEMORY]
Offset0=0x4488
Offset1=0x5488
Offset2=0x5488
Offset3=0x5488
Memory Usage Estimate(Code)=0x9B70
Memory Usage Estimate(Data)=0x9CE0
Offset0=0x44AC
Offset1=0x54AC
Offset2=0x54AC
Offset3=0x54AC
Memory Usage Estimate(Code)=0x9FA0
Memory Usage Estimate(Data)=0x9D58
Memory Usage Estimate(Retain)=0x50
Memory Usage Estimate(Temporary variables)=0x2854
Memory Usage Estimate(Temporary variables)=0x28B4
Offset4=0x414

View File

@@ -0,0 +1,10 @@
[MEMORY]
Offset0=0x44AC
Offset1=0x54AC
Offset2=0x54AC
Offset3=0x54AC
Memory Usage Estimate(Code)=0x9FA0
Memory Usage Estimate(Data)=0x9D58
Memory Usage Estimate(Retain)=0x50
Memory Usage Estimate(Temporary variables)=0x28B4
Offset4=0x414

View File

@@ -0,0 +1,28 @@
[MODIF]
POU=Y
TYPE=Y
LEVEL1=Y
IO=Y
RETAIN=Y
INSTDEF=Y
VARDEF=Y
INIT_INST=Y
ADD_DEL=Y
VARSIZE=Y
IO_DEF=Y
LAST_VA=Y
[RESULT]
ON_LINE=Y
TBL_CONF=Y
CRC_ORG=0x7D4DADCF
CRC_OLD=0x7D4DADCF
CRC_NEW=0x53836E8
DAT_ORG=1468428437
DAT_OLD=1468428437
DAT_NEW=1468429755
VER_ORG=84
VER_OLD=84
VER_NEW=85
CRC_ALL_OLD=0x8082E219
CRC_ALL_NEW=0x5026B093

View File

@@ -1,9 +1,9 @@
[MEMORY]
Memory Usage Estimate(Temporary variables)=0x2854
Memory Usage Estimate(Temporary variables)=0x28BC
Biggest online change user variable memory block size=0x800
Currently added user variables=0x0
Total data size=0x6CDC
User variables size=0x4488
Maximum size for temporary variables=0x4854
Memory Usage Estimate(Data)=0x9CDC
Free memory for user variables=0x1000
Currently added user variables=0x44
Total data size=0x6D88
User variables size=0x44CC
Maximum size for temporary variables=0x48A8
Memory Usage Estimate(Data)=0x9D54
Free memory for user variables=0xFE0

View File

@@ -0,0 +1,9 @@
[MEMORY]
Memory Usage Estimate(Temporary variables)=0x28BC
Biggest online change user variable memory block size=0x800
Currently added user variables=0x44
Total data size=0x6D88
User variables size=0x44CC
Maximum size for temporary variables=0x48A8
Memory Usage Estimate(Data)=0x9D54
Free memory for user variables=0xFE0

View File

@@ -1,2 +1,3 @@
<INPUT>,EPOCH_TIME_1@CONTROL,EPOCH_TIME,RTC_READ_ENABLED,TRUE,BOOL
<INPUT>,LINEARSCALE_PRESSURE@CONTROL,LINEARSCALE,RAW_MIN,__TMPR1@CONTROL,REAL,RAW_MAX,__TMPR2@CONTROL,REAL,EU_MIN,PRESSURE_EU_MIN,REAL,EU_MAX,PRESSURE_EU_MAX,REAL,RAW_INP,__TMPR__LINEARSCALE__RAW_INP,REAL
<INPUT>,RTRIG_AUTOMODE@CONTROL,R_TRIG,CLK,AUTO_MODE,BOOL

View File

@@ -0,0 +1 @@
<SUBINPUT>,EPOCH_TIME,RTC_READ_1,RTC_READ,ENABLE,__TMPB__RTC_READ__ENABLE,BOOL

View File

@@ -0,0 +1,75 @@
[__DEFIO_CPXDVC]
Nb = 2
NotMDF = 0, 1, AB_, OPTIMUS_, IO_Base
MDF = -1
RIdx = 0
NotMDF = 101, 1, AB_, OPTIMUS_, IOUP_Analog
MDF = -1
RIdx = 0
[__DEFIO_SPLDVC]
Nb = 6
NotMDF = 0, 0, 1, AB_, OPTIMUS_, digitOut_Base
MDF = -1
RIdx = 0, 0
NotMDF = 0, 1, 1, AB_, OPTIMUS_, digitIn_Base
MDF = -1
RIdx = 0, 0
NotMDF = 0, 2, 1, AB_, OPTIMUS_, analogIn_Base
MDF = -1
RIdx = 0, 0
NotMDF = 0, 3, 1, AB_, OPTIMUS_, analogOut_Base
MDF = -1
RIdx = 0, 0
NotMDF = 101, 0, 1, AB_, OPTIMUS_, analogOut_UP
MDF = -1
RIdx = 0, 1
NotMDF = 101, 1, 1, AB_, OPTIMUS_, analogIn_UP
MDF = -1
RIdx = 0, 1
[__DEFIO_CHAN]
RIdx = 0, 0, 0
Nb = 7
MDF = 1\1, 1, 0, 0, -1, _IO_EM_DO_00
MDF = 1\1, 1, 0, 1, -1, _IO_EM_DO_01
MDF = 1\1, 1, 0, 2, -1, _IO_EM_DO_02
MDF = 1\1, 1, 0, 3, -1, _IO_EM_DO_03
MDF = 1\1, 1, 0, 4, -1, _IO_EM_DO_04
MDF = 1\1, 1, 0, 5, -1, _IO_EM_DO_05
MDF = 1\1, 1, 0, 6, -1, _IO_EM_DO_06
RIdx = 0, 0, 1
Nb = 12
MDF = 1\1, 1, 0, 0, -1, _IO_EM_DI_00
MDF = 1\1, 1, 0, 1, -1, _IO_EM_DI_01
MDF = 1\1, 1, 0, 2, -1, _IO_EM_DI_02
MDF = 1\1, 1, 0, 3, -1, _IO_EM_DI_03
MDF = 1\1, 1, 0, 4, -1, _IO_EM_DI_04
MDF = 1\1, 1, 0, 5, -1, _IO_EM_DI_05
MDF = 1\1, 1, 0, 6, -1, _IO_EM_DI_06
MDF = 1\1, 1, 0, 7, -1, _IO_EM_DI_07
MDF = 1\1, 1, 0, 8, -1, _IO_EM_DI_08
MDF = 1\1, 1, 0, 9, -1, _IO_EM_DI_09
MDF = 1\1, 1, 0, 10, -1, _IO_EM_DI_10
MDF = 1\1, 1, 0, 11, -1, _IO_EM_DI_11
RIdx = 0, 0, 2
Nb = 4
MDF = 1\1, 1, 0, 0, -1, _IO_EM_AI_00
MDF = 1\1, 1, 0, 1, -1, _IO_EM_AI_01
MDF = 1\1, 1, 0, 2, -1, _IO_EM_AI_02
MDF = 1\1, 1, 0, 3, -1, _IO_EM_AI_03
RIdx = 0, 0, 3
Nb = 1
MDF = 1\1, 1, 0, 0, -1, _IO_EM_AO_00
RIdx = 0, 1, 4
Nb = 0
RIdx = 0, 1, 5
Nb = 2
MDF = 1\1, 0, 0, 0, -1, _IO_P1_AI_00
MDF = 1\1, 0, 0, 1, -1, _IO_P1_AI_01
[__READONLY_VALUES]
Nb = 0

View File

@@ -66,11 +66,9 @@ MDF = 1\1, 1, 0, 0, -1, _IO_EM_AO_00
RIdx = 0, 1, 4
Nb = 0
RIdx = 0, 1, 5
Nb = 4
Nb = 2
MDF = 1\1, 0, 0, 0, -1, _IO_P1_AI_00
MDF = 1\1, 0, 0, 1, -1, _IO_P1_AI_01
MDF = 1\1, 0, 0, 2, -1, _IO_P1_AI_02
MDF = 1\1, 0, 0, 3, -1, _IO_P1_AI_03
[__READONLY_VALUES]

View File

@@ -0,0 +1,3 @@
[MEMORY]
Code Space Free Memory=0x16FD0
Code Space Requirement=0x63D0

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<ProjectElements>
<AcfElementGuid Guid="0665f1e9-fb03-48de-86da-7c7f08fe0360" />
<AcfElementGuid Guid="1f8f8d8a-87f5-4e34-b071-ff772e5f5dfd" />
<AcfElementGuid Guid="22fb9760-076e-482b-bcbe-c8fd6362439b" />
<AcfElementGuid Guid="2e293809-2592-4360-9ef5-9e938bc7b980" />
<AcfElementGuid Guid="492b32e2-63c3-46f8-afeb-6d9e6b76da86" />

View File

@@ -3,6 +3,9 @@
<AcfElementGuid Guid="0665f1e9-fb03-48de-86da-7c7f08fe0360">
<File>ReadE300Param.AcfMlge</File>
</AcfElementGuid>
<AcfElementGuid Guid="1f8f8d8a-87f5-4e34-b071-ff772e5f5dfd">
<File>Epoch_Time.AcfMlge</File>
</AcfElementGuid>
<AcfElementGuid Guid="22fb9760-076e-482b-bcbe-c8fd6362439b">
<File>E300Data.AcfMlge</File>
</AcfElementGuid>

View File

@@ -701,9 +701,7 @@
<td><!--Trip Enabled-->
<input type="toggle" data-checkedValue="1" data-uncheckedValue="0" data-valueupdate="tripenabledistall" data-channelId='<%= channels["ipp.tripenabledistall"].channelId %>' data-techName='<%=channels["ipp.tripenabledistall"].techName %>' data-name='ipp.tripenabledistall' id="<%= channels["ipp.tripenabledistall"].channelId %>" name="<%= channels["ipp.tripenabledistall"].channelId %>">
</td>
<td><!--Warning Enabled-->
<input type="toggle" data-checkedValue="1" data-uncheckedValue="0" data-valueupdate="warningenabledistall" data-channelId='<%= channels["ipp.warningenabledistall"].channelId %>' data-techName='<%=channels["ipp.warningenabledistall"].techName %>' data-name='ipp.warningenabledistall' id="<%= channels["ipp.warningenabledistall"].channelId %>" name="<%= channels["ipp.warningenabledistall"].channelId %>">
</td>
<td><!--Warning Enabled--></td>
<td> <!-- Startup Delay -->
<input class="form-control" data-channelId='<%= channels["ipp.cfgistallenabledtime"].channelId %>'
data-techName='<%=channels["ipp.cfgistallenabledtime"].techName %>'
@@ -731,9 +729,7 @@
<td><!--Trip Enabled-->
<input type="toggle" data-checkedValue="1" data-uncheckedValue="0" data-valueupdate="tripenablediphaseloss" data-channelId='<%= channels["ipp.tripenablediphaseloss"].channelId %>' data-techName='<%=channels["ipp.tripenablediphaseloss"].techName %>' data-name='ipp.tripenablediphaseloss' id="<%= channels["ipp.tripenablediphaseloss"].channelId %>" name="<%= channels["ipp.tripenablediphaseloss"].channelId %>">
</td>
<td><!--Warning Enabled-->
<input type="toggle" data-checkedValue="1" data-uncheckedValue="0" data-valueupdate="warningenablediphaseloss" data-channelId='<%= channels["ipp.warningenablediphaseloss"].channelId %>' data-techName='<%=channels["ipp.warningenablediphaseloss"].techName %>' data-name='ipp.warningenablediphaseloss' id="<%= channels["ipp.warningenablediphaseloss"].channelId %>" name="<%= channels["ipp.warningenablediphaseloss"].channelId %>">
</td>
<td><!--Warning Enabled--></td>
<td> <!-- Startup Delay -->
<input class="form-control" data-channelId='<%= channels["ipp.cfgplphaselossinhibittime"].channelId %>'
data-techName='<%=channels["ipp.cfgplphaselossinhibittime"].techName %>'
@@ -761,9 +757,7 @@
<td><!--Trip Enabled-->
<input type="toggle" data-checkedValue="1" data-uncheckedValue="0" data-valueupdate="tripenabledilineloss" data-channelId='<%= channels["ipp.tripenabledilineloss"].channelId %>' data-techName='<%=channels["ipp.tripenabledilineloss"].techName %>' data-name='ipp.tripenabledilineloss' id="<%= channels["ipp.tripenabledilineloss"].channelId %>" name="<%= channels["ipp.tripenabledilineloss"].channelId %>">
</td>
<td><!--Warning Enabled-->
<input type="toggle" data-checkedValue="1" data-uncheckedValue="0" data-valueupdate="warningenabledilineloss" data-channelId='<%= channels["ipp.warningenabledilineloss"].channelId %>' data-techName='<%=channels["ipp.warningenabledilineloss"].techName %>' data-name='ipp.warningenabledilineloss' id="<%= channels["ipp.warningenabledilineloss"].channelId %>" name="<%= channels["ipp.warningenabledilineloss"].channelId %>">
</td>
<td><!--Warning Enabled--></td>
<td> <!-- Startup Delay -->
<input class="form-control" data-channelId='<%= channels["ipp.cfgilinelossinhibittime"].channelId %>'
data-techName='<%=channels["ipp.cfgilinelossinhibittime"].techName %>'

View File

@@ -4,8 +4,11 @@
<div class='col-xs-4 text-center'>
<h2>Fluid Level</h2>
<div class="gauge-box">
<div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge-dhfluidlevel" data-chart="solidgauge" data-nodename="ipp.dhfluidlevel" data-units="ft" data-min="0" data-max="600" data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B" data-valuefontsize="18px"></div>
<span data-timeupdate="dhfluidlevel"><%= channels["ipp.dhfluidlevel"].timestamp %></span>
<!-- <div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge-dhfluidlevel" data-chart="solidgauge" data-nodename="ipp.dhfluidlevel" data-units="ft" data-min="0" data-max="600" data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B" data-valuefontsize="18px"></div>
<span data-timeupdate="dhfluidlevel"><%= channels["ipp.dhfluidlevel"].timestamp %></span> -->
<div style="height: 170px; background: transparent; margin: 0 auto;">
<gauge type="angular" channel="ipp.dhfluidlevel" max="600" />
</div>
</div>
</div>
<div class='col-xs-8'>

View File

@@ -147,6 +147,49 @@
</div>
</div>
<div class="row row-flex">
<div class='col-xs-12' style="padding-top: 1em; margin-bottom: 1em;">
<div class="input-daterange input-group" id="datepicker">
<input data-chartid="dynamicChart" id="fromDate" data-daysofhistory="2" type="text" class="form-control" name="start">
<span class="input-group-addon">to</span>
<input class="form-control" data-chartid="dynamicChart" id="toDate" type="text" name="end">
<span class='input-group-btn'>
<a href="#!" data-chartid="dynamicChart" data-otherchartids="statusTimeline" class="btn chart-update btn-theme" id="runButton">Run</a>
</span>
</div>
</div>
<hr>
<div class="col-md-6">
<h1>TRIP HISTORY</h1>
<table class="table table-responsive" id="triptable">
<thead>
<tr>
<th>Timestamp</th>
<th>Condition</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<div class="col-md-6">
<h1>WARNING HISTORY</h1>
<table class="table table-responsive" id="warningtable">
<thead>
<tr>
<th>Timestamp</th>
<th>Condition</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<style>
@@ -199,3 +242,163 @@
flex-direction: column;
}
</style>
<script>
var tripData = [];
var maps = {
current: {
0: 'None',
1: 'Overload',
2: 'Phase Loss',
4: 'Ground Fault',
8: 'Stall',
16: 'Jam',
32: 'Underload',
64: 'Current Imbalance',
128: 'L1 Undercurrent',
256: 'L2 Undercurrent',
512: 'L3 Undercurrent',
1024: 'L1 Overcurrent',
2048: 'L2 Overcurrent',
4096: 'L3 Overcurrent',
8192: 'L1 Line Loss',
16384: 'L2 Line Loss',
32768: 'L3 Line Loss'
},
voltage: {
0: 'None',
1: 'Undervoltage',
2: 'Overvoltage',
4: 'Voltage Unbalance',
8: 'Phase Rotation',
16: 'Overfrequency'
},
control: {
0: 'None',
1: 'Test Trip',
2: 'DLX Trip',
4: 'PTC Trip',
8: 'Operator Station Trip',
16: 'Remote Trip',
32: 'Blocked Start Trip',
64: 'Hardware Fault Trip',
128: 'Config Trip',
256: 'Option Match Trip',
512: 'DLX FB Timeout Trip',
1024: 'Expansion Bus Trip',
2048: 'Reserved',
4096: 'Reserved',
8192: 'NVS Trip',
16384: 'Test Mode Trip'
},
power: {
0: 'None',
1: 'Under kW',
2: 'Over kW',
4: 'Under kVAR Consumed',
8: 'Over kVAR Consumed',
16: 'Under kVAR Generated',
32: 'Over kVAR Generated',
64: 'Under kVA',
128: 'Over kVA',
256: 'Under PF Lag',
512: 'Over PF Lag',
1024: 'Under PF Lead',
2048: 'Over PF Lead'
},
};
var nodeID = <%= node.nodeId %>;
var nodeType = '<%= node.nodetypeName %>';
var channelData = {
tripstatuscurrentint: {channelId: <%= channels['ipp.tripstatuscurrentint'].channelId %>, typ: 'current', table: 'triptable'},
tripstatuscontrolint: {channelId: <%= channels['ipp.tripstatuscontrolint'].channelId %>, typ: 'control', table: 'triptable'},
tripstatusvoltageint: {channelId: <%= channels['ipp.tripstatusvoltageint'].channelId %>, typ: 'voltage', table: 'triptable'},
tripstatuspowerint: {channelId: <%= channels['ipp.tripstatuspowerint'].channelId %>, typ: 'power', table: 'triptable'},
warningstatuscurrentint: {channelId: <%= channels['ipp.warningstatuscurrentint'].channelId %>, typ: 'current', table: 'warningtable'},
warningstatuscontrolint: {channelId: <%= channels['ipp.warningstatuscontrolint'].channelId %>, typ: 'control', table: 'warningtable'},
warningstatusvoltageint: {channelId: <%= channels['ipp.warningstatusvoltageint'].channelId %>, typ: 'voltage', table: 'warningtable'},
warningstatuspowerint: {channelId: <%= channels['ipp.warningstatuspowerint'].channelId %>, typ: 'power', table: 'warningtable'}
}
var pad2 = function(str){
return ("00" + str).slice(-2);
}
var formatDate = function(d){
return pad2(d.getUTCMonth() + 1) + "/" + pad2(d.getUTCDate()) + "/" + d.getUTCFullYear() + " " + pad2(d.getUTCHours()) + ":" + pad2(d.getUTCMinutes()) + ":" + pad2(d.getUTCSeconds());
};
var getDate = function(str){
var c1 = new Date(str);
var c2 = (c1.getTime() / 1000);
c2 = Math.floor(c2);
return c2.toString();
};
var updateTable = function(chData, chName){
// var endDate = new Date();
// var end = Math.floor(endDate.getTime() / 1000);
// var start = end - 86400;
var start = $('#datepicker').find('#fromDate');
//console.log({start:start.val()});
dateString = start.val().replace(/-/g, "/");
start = getDate(dateString);
var end = $('#datepicker').find('#toDate');
//console.log({end:end.val()});
dateString = end.val().replace(/-/g, "/");
end = parseInt(getDate(dateString)) + 86400;
var apiData = "&nodelist[0][nodeId]=" + nodeID.toString() + "&nodelist[0][channelId]=" + chData['channelId'].toString();
apiData += "&start=" + start + "&end=" + end;
console.log(apiData);
$.ajax({
url: "http://www.pocloud.io/api2/Nodechannels",
data: apiData,
dataType: "json",
type: "GET",
success: function(data) {
var dataPoints = data.listofstreams[0];
for(var i = dataPoints.stream.length-1; i > 0; i--){
var dpt = dataPoints.stream[i];
var timestamp = new Date(dpt.x * 1000);
var val = maps[chData.typ][parseInt(dpt.y)];
if (val !== 'None'){
// channelData[chName]['values'].push({t:timestamp, val:val});
tripData.push({t:timestamp, val:val, table: chData.table});
}
}
}
});
};
var prepTable = function(){
// tripData = [];
for (var channel in channelData){
if(channelData.hasOwnProperty(channel)){
updateTable(channelData[channel], channel);
}
}
var sortedTripData = tripData.sort(function(a,b){return b.t-a.t;});
$('#triptable > tbody:last-child').html("");
$('#warningtable > tbody:last-child').html("");
for (var i = 0; i < sortedTripData.length; i++){
// console.log(sortedTripData[i]);
$('#'+ sortedTripData[i].table + ' > tbody:last-child').append("<tr><td>" + formatDate(sortedTripData[i].t) + '</td><td>' + sortedTripData[i].val + '</td></tr>');
}
return true;
};
$(document).ready(function(){
$("#runButton").click(function(){
// tripData = [];
prepTable();
});
prepTable();
console.log(tripData);
});
</script>

View File

@@ -2,16 +2,92 @@
import threading
import time
import pickle
from device_base import deviceBase
import micro800 as u800
min_upload_time = 30
addr = '10.20.4.5'
channels = {}
class Channel():
def read(self):
valData = u800.readMicroTag(self.device_addr, self.tag)
if valData:
nowVal = valData[0]
if self.map_obj:
nowVal = self.map_obj[nowVal]
self.data_type = valData[1]
if self.data_type == "BOOL":
if self.last_value == "":
self.sendFn(self.name, nowVal, 0)
self.last_time_uploaded = time.time()
self.last_value = nowVal
elif (not (self.last_value == nowVal)) or ((time.time() - self.last_time_uploaded) > self.max_time_between_uploads):
self.sendFn(self.name, nowVal, 0)
self.last_time_uploaded = time.time()
self.last_value = nowVal
if (self.data_type == "REAL") or (self.data_type[-3:] == "INT"):
if self.last_value == "":
self.sendFn(self.name, nowVal, 0)
self.last_time_uploaded = time.time()
self.last_value = nowVal
elif (abs(self.last_value - nowVal) > self.change_threshold) or ((time.time() - self.last_time_uploaded) > self.max_time_between_uploads):
self.sendFn(self.name, nowVal, 0)
self.last_time_uploaded = time.time()
self.last_value = nowVal
return True
return False
def __init__(self, name, tag, max_time_between_uploads, sendFn, change_threshold=0.0, e300_param=False, writeable=False, map_obj=None):
global addr
self.name = name
self.tag = tag
self.data_type = ''
self.last_value = ''
self.last_time_uploaded = 0
self.change_threshold = change_threshold
self.max_time_between_uploads = int(max_time_between_uploads)
self.sendFn = sendFn
self.device_addr = addr
self.writeable = bool(writeable)
self.map_obj = map_obj
self.e300_param = e300_param
self.read()
def write(self, val, handshake=None, handshake_val=None):
if self.writeable:
h = handshake
hval = handshake_val
if h is None:
if u800.writeMicroTag(self.device_addr, self.tag, val, handshake=self.tag, handshake_val=val):
self.sendFn(self.name, val, time.time())
self.last_value = val
return True
else:
return False
else:
return u800.writeMicroTag(self.device_addr, self.tag, val, handshake=h, handshake_val=hval)
else:
print("NOT ALLOWED TO WRITE TO {}".format(self.name))
return False
class start(threading.Thread, deviceBase):
channels = {}
def writeTag_WriteE300(self, addr, tag, val):
c = u800.Driver()
if c.open(addr):
try:
cv = c.read_tag(tag)
wt = c.write_tag(tag, val, cv[1])
write_E300 = c.write_tag("cfg_WRITE", 1, "BOOL")
print("wt= {}, write_E300 = {}".format(wt, write_E300))
return wt and write_E300
except Exception:
err = c.get_status()
c.close()
print err
return False
c.close()
def updateGPS(self):
gps = self.mcu.gps
@@ -19,14 +95,217 @@ class start(threading.Thread, deviceBase):
self.sendtodb("gps", gps, 0)
def setupChannels(self):
with open('drivers/ipp_channels.p', 'rb') as ch_f:
self.channels = pickle.load(ch_f)
print("Channel List\n================")
for x in self.channels.keys():
print x
print("================")
global channels
channels = {
# 'automode': Channel('automode', 'Auto_Mode', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
# 'cfgcflasetting': Channel('cfgcflasetting', 'cfg_C_FLASetting', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
# 'cfgcleartripcountafter': Channel('cfgcleartripcountafter', 'cfg_ClearTripCountAfter', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'cfggfgroundfaultinhibittime': Channel('cfggfgroundfaultinhibittime', 'cfg_GF_GroundFaultInhibitTime', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfggfgroundfaulttripdelay': Channel('cfggfgroundfaulttripdelay', 'cfg_GF_GroundFaultTripDelay', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfggfgroundfaulttriplevel': Channel('cfggfgroundfaulttriplevel', 'cfg_GF_GroundFaultTripLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfggfgroundfaultwarningdelay': Channel('cfggfgroundfaultwarningdelay', 'cfg_GF_GroundFaultWarningDelay', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfggfgroundfaultwarninglevel': Channel('cfggfgroundfaultwarninglevel', 'cfg_GF_GroundFaultWarningLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgictprimary': Channel('cfgictprimary', 'cfg_I_CTPrimary', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgictsecondary': Channel('cfgictsecondary', 'cfg_I_CTSecondary', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgicurrentimbalanceinhibittim': Channel('cfgicurrentimbalanceinhibittim', 'cfg_I_CurrentImbalanceInhibitTime', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgicurrentimbalancetripdelay': Channel('cfgicurrentimbalancetripdelay', 'cfg_I_CurrentImbalanceTripDelay', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgicurrentimbalancetriplevel': Channel('cfgicurrentimbalancetriplevel', 'cfg_I_CurrentImbalanceTripLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgicurrentimbalancewarninglev': Channel('cfgicurrentimbalancewarninglev', 'cfg_I_CurrentImbalanceWarningLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgijaminhibittime': Channel('cfgijaminhibittime', 'cfg_I_JamInhibitTime', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgijamtripdelay': Channel('cfgijamtripdelay', 'cfg_I_JamTripDelay', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgijamtriplevel': Channel('cfgijamtriplevel', 'cfg_I_JamTripLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgijamwarninglevel': Channel('cfgijamwarninglevel', 'cfg_I_JamWarningLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgilinelossinhibittime': Channel('cfgilinelossinhibittime', 'cfg_I_LineLossInhibitTime', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgilinelosstripdelay': Channel('cfgilinelosstripdelay', 'cfg_I_LineLossTripDelay', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgiovercurrentinhibittime': Channel('cfgiovercurrentinhibittime', 'cfg_I_OvercurrentInhibitTime', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgiovercurrenttripdelay': Channel('cfgiovercurrenttripdelay', 'cfg_I_OvercurrentTripDelay', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgiovercurrenttriplevel': Channel('cfgiovercurrenttriplevel', 'cfg_I_OvercurrentTripLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgiovercurrentwarninglevel': Channel('cfgiovercurrentwarninglevel', 'cfg_I_OvercurrentWarningLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgistallenabledtime': Channel('cfgistallenabledtime', 'cfg_I_StallEnabledTime', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgistalltriplevel': Channel('cfgistalltriplevel', 'cfg_I_StallTripLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgiundercurrentinhibittime': Channel('cfgiundercurrentinhibittime', 'cfg_I_UndercurrentInhibitTime', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgiundercurrenttripdelay': Channel('cfgiundercurrenttripdelay', 'cfg_I_UndercurrentTripDelay', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgiundercurrenttriplevel': Channel('cfgiundercurrenttriplevel', 'cfg_I_UndercurrentTripLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgiundercurrentwarninglevel': Channel('cfgiundercurrentwarninglevel', 'cfg_I_UndercurrentWarningLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgiunderloadinhibittime': Channel('cfgiunderloadinhibittime', 'cfg_I_UnderloadInhibitTime', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgiunderloadtripdelay': Channel('cfgiunderloadtripdelay', 'cfg_I_UnderloadTripDelay', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgiunderloadtriplevel': Channel('cfgiunderloadtriplevel', 'cfg_I_UnderloadTripLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgiunderloadwarninglevel': Channel('cfgiunderloadwarninglevel', 'cfg_I_UnderloadWarningLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgoverloadtripcountlimit': Channel('cfgoverloadtripcountlimit', 'cfg_OverloadTripCountLimit', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'cfgplphaselossinhibittime': Channel('cfgplphaselossinhibittime', 'cfg_PL_PhaseLossInhibitTime', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgplphaselosstripdelay': Channel('cfgplphaselosstripdelay', 'cfg_PL_PhaseLossTripDelay', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgread': Channel('cfgread', 'cfg_READ', 86400, self.sendtodbJSON, writeable=True, e300_param=False),
'cfgspecificgravity': Channel('cfgspecificgravity', 'cfg_SpecificGravity', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'cfgtcuolresetlevel': Channel('cfgtcuolresetlevel', 'cfg_TCU_OLResetLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgtcuolwarninglevel': Channel('cfgtcuolwarninglevel', 'cfg_TCU_OLWarningLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgtcutripclass': Channel('cfgtcutripclass', 'cfg_TCU_TripClass', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgtimermodeenabled': Channel('cfgtimermodeenabled', 'cfg_TimerModeEnabled', 86400, self.sendtodbJSON, writeable=True, e300_param=False),
'cfgtimerruntime': Channel('cfgtimerruntime', 'cfg_TimerRunTime', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'cfgtimerwaittime': Channel('cfgtimerwaittime', 'cfg_TimerWaitTime', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'cfgtripcountlimit': Channel('cfgtripcountlimit', 'cfg_TripCountLimit', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'cfgvoverfrequencyinhibittime': Channel('cfgvoverfrequencyinhibittime', 'cfg_V_OverfrequencyInhibitTime', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvoverfrequencytripdelay': Channel('cfgvoverfrequencytripdelay', 'cfg_V_OverfrequencyTripDelay', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvoverfrequencytriplevel': Channel('cfgvoverfrequencytriplevel', 'cfg_V_OverfrequencyTripLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvoverfrequencywarninglevel': Channel('cfgvoverfrequencywarninglevel', 'cfg_V_OverfrequencyWarningLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvovervoltageinhibittime': Channel('cfgvovervoltageinhibittime', 'cfg_V_OvervoltageInhibitTime', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvovervoltagetripdelay': Channel('cfgvovervoltagetripdelay', 'cfg_V_OvervoltageTripDelay', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvovervoltagetriplevel': Channel('cfgvovervoltagetriplevel', 'cfg_V_OvervoltageTripLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvovervoltagewarninglevel': Channel('cfgvovervoltagewarninglevel', 'cfg_V_OvervoltageWarningLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvphaserotationinhibittime': Channel('cfgvphaserotationinhibittime', 'cfg_V_PhaseRotationInhibitTime', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvphaserotationtriptype': Channel('cfgvphaserotationtriptype', 'cfg_V_PhaseRotationTripType', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvptprimary': Channel('cfgvptprimary', 'cfg_V_PTPrimary', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvptsecondary': Channel('cfgvptsecondary', 'cfg_V_PTSecondary', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvunderfrequencyinhibittime': Channel('cfgvunderfrequencyinhibittime', 'cfg_V_UnderfrequencyInhibitTime', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvunderfrequencytripdelay': Channel('cfgvunderfrequencytripdelay', 'cfg_V_UnderfrequencyTripDelay', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvunderfrequencytriplevel': Channel('cfgvunderfrequencytriplevel', 'cfg_V_UnderfrequencyTripLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvunderfrequencywarninglevel': Channel('cfgvunderfrequencywarninglevel', 'cfg_V_UnderfrequencyWarningLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvundervoltageinhibittime': Channel('cfgvundervoltageinhibittime', 'cfg_V_UndervoltageInhibitTime', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvundervoltagetripdelay': Channel('cfgvundervoltagetripdelay', 'cfg_V_UndervoltageTripDelay', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvundervoltagetriplevel': Channel('cfgvundervoltagetriplevel', 'cfg_V_UndervoltageTripLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvundervoltagewarninglevel': Channel('cfgvundervoltagewarninglevel', 'cfg_V_UndervoltageWarningLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvvoltageimbalanceinhibittim': Channel('cfgvvoltageimbalanceinhibittim', 'cfg_V_VoltageImbalanceInhibitTime', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvvoltageimbalancetripdelay': Channel('cfgvvoltageimbalancetripdelay', 'cfg_V_VoltageImbalanceTripDelay', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvvoltageimbalancetriplevel': Channel('cfgvvoltageimbalancetriplevel', 'cfg_V_VoltageImbalanceTripLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvvoltageimbalancewarninglev': Channel('cfgvvoltageimbalancewarninglev', 'cfg_V_VoltageImbalanceWarningLevel', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgvvoltagemode': Channel('cfgvvoltagemode', 'cfg_V_VoltageMode', 86400, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=True),
'cfgwrite': Channel('cfgwrite', 'cfg_WRITE', 86400, self.sendtodbJSON, writeable=True, e300_param=False),
'contactorstatus': Channel('contactorstatus', 'Contactor_Status', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'dhdownholestatusint': Channel('dhdownholestatusint', 'DH_DownholeStatus_INT', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'dhfluidlevel': Channel('dhfluidlevel', 'DH_Fluid_Level', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'dhintakepressure': Channel('dhintakepressure', 'DH_IntakePressure', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'dhintaketemperature': Channel('dhintaketemperature', 'DH_IntakeTemperature', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'dhmaxintakepressureforever': Channel('dhmaxintakepressureforever', 'DH_MaxIntakePressure_Forever', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'dhmaxintakepressurestartup': Channel('dhmaxintakepressurestartup', 'DH_MaxIntakePressure_Startup', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'dhmaxintaketemperatureforever': Channel('dhmaxintaketemperatureforever', 'DH_MaxIntakeTemperature_Forever', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'dhmaxintaketemperaturestartup': Channel('dhmaxintaketemperaturestartup', 'DH_MaxIntakeTemperature_Startup', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'dhnumchannels': Channel('dhnumchannels', 'DH_NumChannels', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'dhpsirating': Channel('dhpsirating', 'DH_PSIRating', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'dhtooltype': Channel('dhtooltype', 'DH_ToolType', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'dhtoolvoltage': Channel('dhtoolvoltage', 'DH_ToolVoltage', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'downholetoolenabled': Channel('downholetoolenabled', 'Downhole_Tool_Enabled', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'downtimetimeparameter': Channel('downtimetimeparameter', 'Downtime_Time_Parameter', 3600, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'downtimetimeparameterol': Channel('downtimetimeparameterol', 'Downtime_Time_Parameter_OL', 3600, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'e300averagecurrent': Channel('e300averagecurrent', 'E300_AverageCurrent', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300averagellvoltage': Channel('e300averagellvoltage', 'E300_AverageLLVoltage', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300averagelnvoltage': Channel('e300averagelnvoltage', 'E300_AverageLNVoltage', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300kwh': Channel('e300kwh', 'E300_kWh', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300kwhregen': Channel('e300kwhregen', 'E300_kWh_Regen', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l1apparentpower': Channel('e300l1apparentpower', 'E300_L1ApparentPower', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l1current': Channel('e300l1current', 'E300_L1Current', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l1l2voltage': Channel('e300l1l2voltage', 'E300_L1L2Voltage', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l1nvoltage': Channel('e300l1nvoltage', 'E300_L1NVoltage', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l1reactivepower': Channel('e300l1reactivepower', 'E300_L1ReactivePower', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l1realpower': Channel('e300l1realpower', 'E300_L1RealPower', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l1truepowerfactor': Channel('e300l1truepowerfactor', 'E300_L1TruePowerFactor', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l2apparentpower': Channel('e300l2apparentpower', 'E300_L2ApparentPower', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l2current': Channel('e300l2current', 'E300_L2Current', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l2l3voltage': Channel('e300l2l3voltage', 'E300_L2L3Voltage', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l2nvoltage': Channel('e300l2nvoltage', 'E300_L2NVoltage', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l2reactivepower': Channel('e300l2reactivepower', 'E300_L2ReactivePower', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l2realpower': Channel('e300l2realpower', 'E300_L2RealPower', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l2truepowerfactor': Channel('e300l2truepowerfactor', 'E300_L2TruePowerFactor', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l3apparentpower': Channel('e300l3apparentpower', 'E300_L3ApparentPower', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l3current': Channel('e300l3current', 'E300_L3Current', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l3l1voltage': Channel('e300l3l1voltage', 'E300_L3L1Voltage', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l3nvoltage': Channel('e300l3nvoltage', 'E300_L3NVoltage', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l3reactivepower': Channel('e300l3reactivepower', 'E300_L3ReactivePower', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l3realpower': Channel('e300l3realpower', 'E300_L3RealPower', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300l3truepowerfactor': Channel('e300l3truepowerfactor', 'E300_L3TruePowerFactor', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300linefrequency': Channel('e300linefrequency', 'E300_LineFrequency', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300percentcurrentunbalance': Channel('e300percentcurrentunbalance', 'E300_PercentCurrentUnbalance', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300percentvoltageunbalance': Channel('e300percentvoltageunbalance', 'E300_PercentVoltageUnbalance', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300threephasetruepowerfactor': Channel('e300threephasetruepowerfactor', 'E300_ThreePhaseTruePowerFactor', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300totalapparentpower': Channel('e300totalapparentpower', 'E300_TotalApparentPower', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300totalreactivepower': Channel('e300totalreactivepower', 'E300_TotalReactivePower', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'e300totalrealpower': Channel('e300totalrealpower', 'E300_TotalRealPower', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'handmode': Channel('handmode', 'Hand_Mode', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'overloadtrip': Channel('overloadtrip', 'OverloadTrip', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'pressurealarmdelay': Channel('pressurealarmdelay', 'Pressure_Alarm_Delay', 3600, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'pressurealarmstartupdelay': Channel('pressurealarmstartupdelay', 'Pressure_Alarm_Startup_Delay', 3600, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'pressureeumax': Channel('pressureeumax', 'Pressure_EU_Max', 3600, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'pressureeumin': Channel('pressureeumin', 'Pressure_EU_Min', 3600, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'pressurehi': Channel('pressurehi', 'Pressure_Hi', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'pressurehisp': Channel('pressurehisp', 'Pressure_Hi_SP', 3600, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'pressurein': Channel('pressurein', 'Pressure_In', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'pressurelo': Channel('pressurelo', 'Pressure_Lo', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'pressurelosp': Channel('pressurelosp', 'Pressure_Lo_SP', 3600, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'pressureok': Channel('pressureok', 'Pressure_OK', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'pressureshutdown': Channel('pressureshutdown', 'Pressure_Shutdown', 3600, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'pressureshutdownenabled': Channel('pressureshutdownenabled', 'Pressure_Shutdown_Enabled', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'pressurestartup': Channel('pressurestartup', 'Pressure_Startup', 3600, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'pressurestartupenabled': Channel('pressurestartupenabled', 'Pressure_Startup_Enabled', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'pressureswitchenabled': Channel('pressureswitchenabled', 'Pressure_Switch_Enabled', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'pressuretransducerenabled': Channel('pressuretransducerenabled', 'Pressure_Transducer_Enabled', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'rpmode': Channel('rpmode', 'RP_Mode', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'rppressure': Channel('rppressure', 'RP_Pressure', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'rptemperature': Channel('rptemperature', 'RP_Temperature', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'rptrip': Channel('rptrip', 'RP_Trip', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'rptubingpressure': Channel('rptubingpressure', 'RP_TubingPressure', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'runpermissive': Channel('runpermissive', 'Run_Permissive', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'spmode': Channel('spmode', 'SP_Mode', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'sppressure': Channel('sppressure', 'SP_Pressure', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'sptemperature': Channel('sptemperature', 'SP_Temperature', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'sptrip': Channel('sptrip', 'SP_Trip', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'spvoltage': Channel('spvoltage', 'SP_Voltage', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'startbutton': Channel('startbutton', 'Start_Button', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'startcommand': Channel('startcommand', 'Start_Command', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'startpermissive': Channel('startpermissive', 'Start_Permissive', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'stopcommand': Channel('stopcommand', 'Stop_Command', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tempshutdown': Channel('tempshutdown', 'Temp_Shutdown', 3600, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'tempshutdownenabled': Channel('tempshutdownenabled', 'Temp_Shutdown_Enabled', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tempstartup': Channel('tempstartup', 'Temp_Startup', 3600, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'tempstartupenabled': Channel('tempstartupenabled', 'Temp_Startup_Enabled', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'testmode': Channel('testmode', 'Test_Mode', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'tripenabledicurrentimbalance': Channel('tripenabledicurrentimbalance', 'TripEnabled_I_CurrentImbalance', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tripenabledigroundfault': Channel('tripenabledigroundfault', 'TripEnabled_I_GroundFault', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tripenabledijam': Channel('tripenabledijam', 'TripEnabled_I_Jam', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tripenabledilineloss': Channel('tripenabledilineloss', 'TripEnabled_I_LineLoss', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tripenablediovercurrent': Channel('tripenablediovercurrent', 'TripEnabled_I_Overcurrent', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tripenabledioverload': Channel('tripenabledioverload', 'TripEnabled_I_Overload', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tripenablediphaseloss': Channel('tripenablediphaseloss', 'TripEnabled_I_PhaseLoss', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tripenabledistall': Channel('tripenabledistall', 'TripEnabled_I_Stall', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tripenablediundercurrent': Channel('tripenablediundercurrent', 'TripEnabled_I_Undercurrent', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tripenablediunderload': Channel('tripenablediunderload', 'TripEnabled_I_Underload', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tripenablevoverfrequency': Channel('tripenablevoverfrequency', 'TripEnable_V_Overfrequency', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tripenablevovervoltage': Channel('tripenablevovervoltage', 'TripEnable_V_Overvoltage', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tripenablevphaserotation': Channel('tripenablevphaserotation', 'TripEnable_V_PhaseRotation', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tripenablevunderfrequency': Channel('tripenablevunderfrequency', 'TripEnable_V_Underfrequency', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tripenablevundervoltage': Channel('tripenablevundervoltage', 'TripEnable_V_Undervoltage', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tripenablevvoltageunbalance': Channel('tripenablevvoltageunbalance', 'TripEnable_V_VoltageUnbalance', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tripresetcmd': Channel('tripresetcmd', 'TripResetCmd', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'tripstatus': Channel('tripstatus', 'TripStatus', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'tripstatuscontrolint': Channel('tripstatuscontrolint', 'TripStatusControl_INT', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'tripstatuscurrentint': Channel('tripstatuscurrentint', 'TripStatusCurrent_INT', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'tripstatuspowerint': Channel('tripstatuspowerint', 'TripStatusPower_INT', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'tripstatusvoltageint': Channel('tripstatusvoltageint', 'TripStatusVoltage_INT', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'valoverloadtripcount': Channel('valoverloadtripcount', 'val_OverloadTripCount', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'valtripcount': Channel('valtripcount', 'val_TripCount', 3600, self.sendtodbJSON, writeable=False, change_threshold=1.0, e300_param=False),
'voltageok': Channel('voltageok', 'VoltageOK', 3600, self.sendtodbJSON, writeable=False, e300_param=False),
'warningenabledicurrentimbalanc': Channel('warningenabledicurrentimbalanc', 'WarningEnabled_I_CurrentImbalance', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'warningenabledigroundfault': Channel('warningenabledigroundfault', 'WarningEnabled_I_GroundFault', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'warningenabledijam': Channel('warningenabledijam', 'WarningEnabled_I_Jam', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'warningenabledilineloss': Channel('warningenabledilineloss', 'WarningEnabled_I_LineLoss', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'warningenablediovercurrent': Channel('warningenablediovercurrent', 'WarningEnabled_I_Overcurrent', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'warningenabledioverload': Channel('warningenabledioverload', 'WarningEnabled_I_Overload', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'warningenablediphaseloss': Channel('warningenablediphaseloss', 'WarningEnabled_I_PhaseLoss', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'warningenabledistall': Channel('warningenabledistall', 'WarningEnabled_I_Stall', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'warningenablediundercurrent': Channel('warningenablediundercurrent', 'WarningEnabled_I_Undercurrent', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'warningenablediunderload': Channel('warningenablediunderload', 'WarningEnabled_I_Underload', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'warningenablevoverfrequency': Channel('warningenablevoverfrequency', 'WarningEnable_V_Overfrequency', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'warningenablevovervoltage': Channel('warningenablevovervoltage', 'WarningEnable_V_Overvoltage', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'warningenablevphaserotation': Channel('warningenablevphaserotation', 'WarningEnable_V_PhaseRotation', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'warningenablevunderfrequency': Channel('warningenablevunderfrequency', 'WarningEnable_V_Underfrequency', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'warningenablevundervoltage': Channel('warningenablevundervoltage', 'WarningEnable_V_Undervoltage', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'warningenablevvoltageunbalance': Channel('warningenablevvoltageunbalance', 'WarningEnable_V_VoltageUnbalance', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'warningstatus': Channel('warningstatus', 'WarningStatus', 3600, self.sendtodbJSON, writeable=True, e300_param=False),
'warningstatuscontrolint': Channel('warningstatuscontrolint', 'WarningStatusControl_INT', 3600, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'warningstatuscurrentint': Channel('warningstatuscurrentint', 'WarningStatusCurrent_INT', 3600, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'warningstatuspowerint': Channel('warningstatuspowerint', 'WarningStatusPower_INT', 3600, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
'warningstatusvoltageint': Channel('warningstatusvoltageint', 'WarningStatusVoltage_INT', 3600, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),
}
def __init__(self, name=None, number=None, mac=None, Q=None, mcu=None, companyId=None, offset=None, mqtt=None, Nodes=None):
global addr
threading.Thread.__init__(self)
deviceBase.__init__(self, name=name, number=number, mac=mac, Q=Q, mcu=mcu, companyId=companyId, offset=offset, mqtt=mqtt, Nodes=Nodes)
@@ -45,39 +324,16 @@ class start(threading.Thread, deviceBase):
self.channels["status"]["last_value"] = ""
def run(self):
global channels
print("****************\n*************\nEXECUTING RUN\n********************\n****************")
self.runLoopStatus = ""
last_OK_state = 0
while True:
if len(self.channels) > 0:
if len(channels) > 0:
try:
for i in self.channels:
for i in channels:
channels[i].read()
runLoopStatus = i
# print("reading {0}".format(i))
valData = u800.readMicroTag(self.device_address, self.channels[i]['tag'])
# print(valData)
if valData:
nowVal = round(valData[0], 4)
ch = self.channels[i]
if ch['data_type'] == "BOOL":
if ch['last_value'] == "":
self.sendtodbJSON(i, nowVal, 0)
ch['last_time_uploaded'] = time.time()
ch['last_value'] = nowVal
elif (not (ch['last_value'] == nowVal)) or ((time.time() - ch['last_time_uploaded']) > ch['max_time_between_uploads']):
self.sendtodbJSON(i, nowVal, 0)
ch['last_time_uploaded'] = time.time()
ch['last_value'] = nowVal
if (ch['data_type'] == "REAL") or (ch['data_type'][-3:] == "INT"):
if ch['last_value'] == "":
self.sendtodbJSON(i, nowVal, 0)
ch['last_time_uploaded'] = time.time()
ch['last_value'] = nowVal
elif (abs(ch['last_value'] - nowVal) > ch['change_amount']) or ((time.time() - ch['last_time_uploaded']) > ch['max_time_between_uploads']):
self.sendtodbJSON(i, nowVal, 0)
ch['last_time_uploaded'] = time.time()
ch['last_value'] = nowVal
runLoopStatus = "Complete"
OK_state = 1
if not OK_state == last_OK_state:
@@ -93,517 +349,18 @@ class start(threading.Thread, deviceBase):
print "Error during {0} of run loop: {1}\nWill try again in {2} seconds...".format(runLoopStatus, e, sleep_timer)
time.sleep(sleep_timer)
else:
print("Apparently no self.channels... length shows {0}".format(len(self.channels)))
print self.channels
print("Apparently no channels... length shows {0}".format(len(channels)))
self.setupChannels()
time.sleep(30)
def write_vfdconfig(self):
print("Writing config to drive")
return u800.writeMicroTag(addr, 'VFD_Write', 1)
def vfdipp_sync(self, name, value):
def ipp_sync(self, name, value):
self.sendtodb("connected", "true", 0)
return True
def vfdipp_address(self, name, value):
self.device_address = value
return True
def vfdipp_gpsUpdate(self, name, value):
self.updateGPS()
return True
# ======== AUTOMATICALLY GENERATED TAG WRITE FUNCTIONS BELOW HERE ===========
def ipp_cfgcflasetting(self, name, value):
print('trying to set cfg_C_FLASetting to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_C_FLASetting', float(value))
def ipp_cfgcleartripcountafter(self, name, value):
print('trying to set cfg_ClearTripCountAfter to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_ClearTripCountAfter', int(value))
def ipp_cfgctripenablecontrol(self, name, value):
print('trying to set cfg_C_TripEnableControl to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_C_TripEnableControl', int(value))
def ipp_cfgcwarningenablecontrol(self, name, value):
print('trying to set cfg_C_WarningEnableControl to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_C_WarningEnableControl', int(value))
def ipp_cfggfgroundfaultinhibittime(self, name, value):
print('trying to set cfg_GF_GroundFaultInhibitTime to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_GF_GroundFaultInhibitTime', int(value))
def ipp_cfggfgroundfaulttripdelay(self, name, value):
print('trying to set cfg_GF_GroundFaultTripDelay to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_GF_GroundFaultTripDelay', float(value))
def ipp_cfggfgroundfaulttriplevel(self, name, value):
print('trying to set cfg_GF_GroundFaultTripLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_GF_GroundFaultTripLevel', float(value))
def ipp_cfggfgroundfaultwarningdelay(self, name, value):
print('trying to set cfg_GF_GroundFaultWarningDelay to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_GF_GroundFaultWarningDelay', float(value))
def ipp_cfggfgroundfaultwarninglevel(self, name, value):
print('trying to set cfg_GF_GroundFaultWarningLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_GF_GroundFaultWarningLevel', float(value))
def ipp_cfgictprimary(self, name, value):
print('trying to set cfg_I_CTPrimary to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_CTPrimary', int(value))
def ipp_cfgictsecondary(self, name, value):
print('trying to set cfg_I_CTSecondary to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_CTSecondary', int(value))
def ipp_cfgicurrentimbalanceinhibittim(self, name, value):
print('trying to set cfg_I_CurrentImbalanceInhibitTime to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_CurrentImbalanceInhibitTime', int(value))
def ipp_cfgicurrentimbalancetripdelay(self, name, value):
print('trying to set cfg_I_CurrentImbalanceTripDelay to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_CurrentImbalanceTripDelay', int(value))
def ipp_cfgicurrentimbalancetriplevel(self, name, value):
print('trying to set cfg_I_CurrentImbalanceTripLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_CurrentImbalanceTripLevel', int(value))
def ipp_cfgicurrentimbalancewarninglev(self, name, value):
print('trying to set cfg_I_CurrentImbalanceWarningLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_CurrentImbalanceWarningLevel', int(value))
def ipp_cfgijaminhibittime(self, name, value):
print('trying to set cfg_I_JamInhibitTime to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_JamInhibitTime', int(value))
def ipp_cfgijamtripdelay(self, name, value):
print('trying to set cfg_I_JamTripDelay to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_JamTripDelay', int(value))
def ipp_cfgijamwarninglevel(self, name, value):
print('trying to set cfg_I_JamWarningLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_JamWarningLevel', int(value))
def ipp_cfgilinelossinhibittime(self, name, value):
print('trying to set cfg_I_LineLossInhibitTime to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_LineLossInhibitTime', int(value))
def ipp_cfgilinelosstripdelay(self, name, value):
print('trying to set cfg_I_LineLossTripDelay to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_LineLossTripDelay', float(value))
def ipp_cfgiovercurrentinhibittime(self, name, value):
print('trying to set cfg_I_OvercurrentInhibitTime to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_OvercurrentInhibitTime', int(value))
def ipp_cfgiovercurrenttripdelay(self, name, value):
print('trying to set cfg_I_OvercurrentTripDelay to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_OvercurrentTripDelay', float(value))
def ipp_cfgiovercurrenttriplevel(self, name, value):
print('trying to set cfg_I_OvercurrentTripLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_OvercurrentTripLevel', int(value))
def ipp_cfgiovercurrentwarninglevel(self, name, value):
print('trying to set cfg_I_OvercurrentWarningLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_OvercurrentWarningLevel', int(value))
def ipp_cfgistallenabledtime(self, name, value):
print('trying to set cfg_I_StallEnabledTime to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_StallEnabledTime', int(value))
def ipp_cfgistalltriplevel(self, name, value):
print('trying to set cfg_I_StallTripLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_StallTripLevel', int(value))
def ipp_cfgiundercurrentinhibittime(self, name, value):
print('trying to set cfg_I_UndercurrentInhibitTime to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_UndercurrentInhibitTime', int(value))
def ipp_cfgiundercurrenttripdelay(self, name, value):
print('trying to set cfg_I_UndercurrentTripDelay to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_UndercurrentTripDelay', float(value))
def ipp_cfgiundercurrenttriplevel(self, name, value):
print('trying to set cfg_I_UndercurrentTripLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_UndercurrentTripLevel', int(value))
def ipp_cfgiundercurrentwarninglevel(self, name, value):
print('trying to set cfg_I_UndercurrentWarningLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_UndercurrentWarningLevel', int(value))
def ipp_cfgiunderloadinhibittime(self, name, value):
print('trying to set cfg_I_UnderloadInhibitTime to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_UnderloadInhibitTime', int(value))
def ipp_cfgiunderloadtripdelay(self, name, value):
print('trying to set cfg_I_UnderloadTripDelay to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_UnderloadTripDelay', float(value))
def ipp_cfgiunderloadtriplevel(self, name, value):
print('trying to set cfg_I_UnderloadTripLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_UnderloadTripLevel', int(value))
def ipp_cfgiunderloadwarninglevel(self, name, value):
print('trying to set cfg_I_UnderloadWarningLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_I_UnderloadWarningLevel', int(value))
def ipp_cfgoverloadtripcountlimit(self, name, value):
print('trying to set cfg_OverloadTripCountLimit to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_OverloadTripCountLimit', int(value))
def ipp_cfgplphaselossinhibittime(self, name, value):
print('trying to set cfg_PL_PhaseLossInhibitTime to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_PL_PhaseLossInhibitTime', int(value))
def ipp_cfgplphaselosstripdelay(self, name, value):
print('trying to set cfg_PL_PhaseLossTripDelay to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_PL_PhaseLossTripDelay', float(value))
def ipp_cfgread(self, name, value):
print('trying to set cfg_READ to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_READ', int(value))
def ipp_cfgspecificgravity(self, name, value):
print('trying to set cfg_SpecificGravity to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_SpecificGravity', float(value))
def ipp_cfgtcutripclass(self, name, value):
print('trying to set cfg_TCU_TripClass to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_TCU_TripClass', int(value))
def ipp_cfgtimermodeenabled(self, name, value):
print('trying to set cfg_TimerModeEnabled to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_TimerModeEnabled', int(value))
def ipp_cfgtimerruntime(self, name, value):
print('trying to set cfg_TimerRunTime to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_TimerRunTime', int(value))
def ipp_cfgtimerwaittime(self, name, value):
print('trying to set cfg_TimerWaitTime to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_TimerWaitTime', int(value))
def ipp_cfgtripcountlimit(self, name, value):
print('trying to set cfg_TripCountLimit to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_TripCountLimit', int(value))
def ipp_cfgvoverfrequencyinhibittime(self, name, value):
print('trying to set cfg_V_OverfrequencyInhibitTime to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_OverfrequencyInhibitTime', int(value))
def ipp_cfgvoverfrequencytripdelay(self, name, value):
print('trying to set cfg_V_OverfrequencyTripDelay to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_OverfrequencyTripDelay', float(value))
def ipp_cfgvoverfrequencytriplevel(self, name, value):
print('trying to set cfg_V_OverfrequencyTripLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_OverfrequencyTripLevel', int(value))
def ipp_cfgvoverfrequencywarninglevel(self, name, value):
print('trying to set cfg_V_OverfrequencyWarningLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_OverfrequencyWarningLevel', int(value))
def ipp_cfgvovervoltageinhibittime(self, name, value):
print('trying to set cfg_V_OvervoltageInhibitTime to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_OvervoltageInhibitTime', int(value))
def ipp_cfgvovervoltagetripdelay(self, name, value):
print('trying to set cfg_V_OvervoltageTripDelay to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_OvervoltageTripDelay', float(value))
def ipp_cfgvovervoltagetriplevel(self, name, value):
print('trying to set cfg_V_OvervoltageTripLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_OvervoltageTripLevel', float(value))
def ipp_cfgvovervoltagewarninglevel(self, name, value):
print('trying to set cfg_V_OvervoltageWarningLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_OvervoltageWarningLevel', float(value))
def ipp_cfgvphaserotationinhibittime(self, name, value):
print('trying to set cfg_V_PhaseRotationInhibitTime to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_PhaseRotationInhibitTime', int(value))
def ipp_cfgvphaserotationtriptype(self, name, value):
print('trying to set cfg_V_PhaseRotationTripType to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_PhaseRotationTripType', int(value))
def ipp_cfgvptprimary(self, name, value):
print('trying to set cfg_V_PTPrimary to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_PTPrimary', int(value))
def ipp_cfgvptsecondary(self, name, value):
print('trying to set cfg_V_PTSecondary to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_PTSecondary', int(value))
def ipp_cfgvunderfrequencyinhibittime(self, name, value):
print('trying to set cfg_V_UnderfrequencyInhibitTime to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_UnderfrequencyInhibitTime', int(value))
def ipp_cfgvunderfrequencytripdelay(self, name, value):
print('trying to set cfg_V_UnderfrequencyTripDelay to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_UnderfrequencyTripDelay', float(value))
def ipp_cfgvunderfrequencytriplevel(self, name, value):
print('trying to set cfg_V_UnderfrequencyTripLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_UnderfrequencyTripLevel', int(value))
def ipp_cfgvunderfrequencywarninglevel(self, name, value):
print('trying to set cfg_V_UnderfrequencyWarningLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_UnderfrequencyWarningLevel', int(value))
def ipp_cfgvundervoltageinhibittime(self, name, value):
print('trying to set cfg_V_UndervoltageInhibitTime to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_UndervoltageInhibitTime', int(value))
def ipp_cfgvundervoltagetripdelay(self, name, value):
print('trying to set cfg_V_UndervoltageTripDelay to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_UndervoltageTripDelay', float(value))
def ipp_cfgvundervoltagetriplevel(self, name, value):
print('trying to set cfg_V_UndervoltageTripLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_UndervoltageTripLevel', float(value))
def ipp_cfgvundervoltagewarninglevel(self, name, value):
print('trying to set cfg_V_UndervoltageWarningLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_UndervoltageWarningLevel', float(value))
def ipp_cfgvvoltageimbalanceinhibittim(self, name, value):
print('trying to set cfg_V_VoltageImbalanceInhibitTime to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_VoltageImbalanceInhibitTime', int(value))
def ipp_cfgvvoltageimbalancetripdelay(self, name, value):
print('trying to set cfg_V_VoltageImbalanceTripDelay to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_VoltageImbalanceTripDelay', float(value))
def ipp_cfgvvoltageimbalancetriplevel(self, name, value):
print('trying to set cfg_V_VoltageImbalanceTripLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_VoltageImbalanceTripLevel', int(value))
def ipp_cfgvvoltageimbalancewarninglev(self, name, value):
print('trying to set cfg_V_VoltageImbalanceWarningLevel to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_VoltageImbalanceWarningLevel', int(value))
def ipp_cfgvvoltagemode(self, name, value):
print('trying to set cfg_V_VoltageMode to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_V_VoltageMode', int(value))
def ipp_cfgwrite(self, name, value):
print('trying to set cfg_WRITE to {}'.format(value))
return u800.writeMicroTag(addr, 'cfg_WRITE', int(value))
def ipp_downtimetimeparameter(self, name, value):
print('trying to set Downtime_Time_Parameter to {}'.format(value))
return u800.writeMicroTag(addr, 'Downtime_Time_Parameter', int(value))
def ipp_downtimetimeparameterol(self, name, value):
print('trying to set Downtime_Time_Parameter_OL to {}'.format(value))
return u800.writeMicroTag(addr, 'Downtime_Time_Parameter_OL', int(value))
def ipp_pressurealarmdelay(self, name, value):
print('trying to set Pressure_Alarm_Delay to {}'.format(value))
return u800.writeMicroTag(addr, 'Pressure_Alarm_Delay', int(value))
def ipp_pressurealarmstartupdelay(self, name, value):
print('trying to set Pressure_Alarm_Startup_Delay to {}'.format(value))
return u800.writeMicroTag(addr, 'Pressure_Alarm_Startup_Delay', int(value))
def ipp_pressureeumax(self, name, value):
print('trying to set Pressure_EU_Max to {}'.format(value))
return u800.writeMicroTag(addr, 'Pressure_EU_Max', float(value))
def ipp_pressureeumin(self, name, value):
print('trying to set Pressure_EU_Min to {}'.format(value))
return u800.writeMicroTag(addr, 'Pressure_EU_Min', float(value))
def ipp_pressurehisp(self, name, value):
print('trying to set Pressure_Hi_SP to {}'.format(value))
return u800.writeMicroTag(addr, 'Pressure_Hi_SP', float(value))
def ipp_pressurelosp(self, name, value):
print('trying to set Pressure_Lo_SP to {}'.format(value))
return u800.writeMicroTag(addr, 'Pressure_Lo_SP', float(value))
def ipp_pressureshutdown(self, name, value):
print('trying to set Pressure_Shutdown to {}'.format(value))
return u800.writeMicroTag(addr, 'Pressure_Shutdown', float(value))
def ipp_pressureshutdownenabled(self, name, value):
print('trying to set Pressure_Shutdown_Enabled to {}'.format(value))
return u800.writeMicroTag(addr, 'Pressure_Shutdown_Enabled', int(value))
def ipp_pressurestartup(self, name, value):
print('trying to set Pressure_Startup to {}'.format(value))
return u800.writeMicroTag(addr, 'Pressure_Startup', float(value))
def ipp_pressurestartupenabled(self, name, value):
print('trying to set Pressure_Startup_Enabled to {}'.format(value))
return u800.writeMicroTag(addr, 'Pressure_Startup_Enabled', int(value))
def ipp_pressureswitchenabled(self, name, value):
print('trying to set Pressure_Switch_Enabled to {}'.format(value))
return u800.writeMicroTag(addr, 'Pressure_Switch_Enabled', int(value))
def ipp_pressuretransducerenabled(self, name, value):
print('trying to set Pressure_Transducer_Enabled to {}'.format(value))
return u800.writeMicroTag(addr, 'Pressure_Transducer_Enabled', int(value))
def ipp_startcommand(self, name, value):
print('trying to set Start_Command to {}'.format(value))
return u800.writeMicroTag(addr, 'Start_Command', int(value))
def ipp_stopcommand(self, name, value):
print('trying to set Stop_Command to {}'.format(value))
return u800.writeMicroTag(addr, 'Stop_Command', int(value))
def ipp_tempshutdown(self, name, value):
print('trying to set Temp_Shutdown to {}'.format(value))
return u800.writeMicroTag(addr, 'Temp_Shutdown', float(value))
def ipp_tempshutdownenabled(self, name, value):
print('trying to set Temp_Shutdown_Enabled to {}'.format(value))
return u800.writeMicroTag(addr, 'Temp_Shutdown_Enabled', int(value))
def ipp_tempstartup(self, name, value):
print('trying to set Temp_Startup to {}'.format(value))
return u800.writeMicroTag(addr, 'Temp_Startup', float(value))
def ipp_tempstartupenabled(self, name, value):
print('trying to set Temp_Startup_Enabled to {}'.format(value))
return u800.writeMicroTag(addr, 'Temp_Startup_Enabled', int(value))
def ipp_tripenabledicurrentimbalance(self, name, value):
print('trying to set TripEnabled_I_CurrentImbalance to {}'.format(value))
return u800.writeMicroTag(addr, 'TripEnabled_I_CurrentImbalance', int(value))
def ipp_tripenabledigroundfault(self, name, value):
print('trying to set TripEnabled_I_GroundFault to {}'.format(value))
return u800.writeMicroTag(addr, 'TripEnabled_I_GroundFault', int(value))
def ipp_tripenabledijam(self, name, value):
print('trying to set TripEnabled_I_Jam to {}'.format(value))
return u800.writeMicroTag(addr, 'TripEnabled_I_Jam', int(value))
def ipp_tripenabledilineloss(self, name, value):
print('trying to set TripEnabled_I_LineLoss to {}'.format(value))
return u800.writeMicroTag(addr, 'TripEnabled_I_LineLoss', int(value))
def ipp_tripenablediovercurrent(self, name, value):
print('trying to set TripEnabled_I_Overcurrent to {}'.format(value))
return u800.writeMicroTag(addr, 'TripEnabled_I_Overcurrent', int(value))
def ipp_tripenabledioverload(self, name, value):
print('trying to set TripEnabled_I_Overload to {}'.format(value))
return u800.writeMicroTag(addr, 'TripEnabled_I_Overload', int(value))
def ipp_tripenablediphaseloss(self, name, value):
print('trying to set TripEnabled_I_PhaseLoss to {}'.format(value))
return u800.writeMicroTag(addr, 'TripEnabled_I_PhaseLoss', int(value))
def ipp_tripenabledistall(self, name, value):
print('trying to set TripEnabled_I_Stall to {}'.format(value))
return u800.writeMicroTag(addr, 'TripEnabled_I_Stall', int(value))
def ipp_tripenablediundercurrent(self, name, value):
print('trying to set TripEnabled_I_Undercurrent to {}'.format(value))
return u800.writeMicroTag(addr, 'TripEnabled_I_Undercurrent', int(value))
def ipp_tripenablediunderload(self, name, value):
print('trying to set TripEnabled_I_Underload to {}'.format(value))
return u800.writeMicroTag(addr, 'TripEnabled_I_Underload', int(value))
def ipp_tripenablevoverfrequency(self, name, value):
print('trying to set TripEnable_V_Overfrequency to {}'.format(value))
return u800.writeMicroTag(addr, 'TripEnable_V_Overfrequency', int(value))
def ipp_tripenablevovervoltage(self, name, value):
print('trying to set TripEnable_V_Overvoltage to {}'.format(value))
return u800.writeMicroTag(addr, 'TripEnable_V_Overvoltage', int(value))
def ipp_tripenablevphaserotation(self, name, value):
print('trying to set TripEnable_V_PhaseRotation to {}'.format(value))
return u800.writeMicroTag(addr, 'TripEnable_V_PhaseRotation', int(value))
def ipp_tripenablevunderfrequency(self, name, value):
print('trying to set TripEnable_V_Underfrequency to {}'.format(value))
return u800.writeMicroTag(addr, 'TripEnable_V_Underfrequency', int(value))
def ipp_tripenablevundervoltage(self, name, value):
print('trying to set TripEnable_V_Undervoltage to {}'.format(value))
return u800.writeMicroTag(addr, 'TripEnable_V_Undervoltage', int(value))
def ipp_tripenablevvoltageunbalance(self, name, value):
print('trying to set TripEnable_V_VoltageUnbalance to {}'.format(value))
return u800.writeMicroTag(addr, 'TripEnable_V_VoltageUnbalance', int(value))
def ipp_tripresetcmd(self, name, value):
print('trying to set TripResetCmd to {}'.format(value))
return u800.writeMicroTag(addr, 'TripResetCmd', int(value))
def ipp_warningenabledicurrentimbalanc(self, name, value):
print('trying to set WarningEnabled_I_CurrentImbalance to {}'.format(value))
return u800.writeMicroTag(addr, 'WarningEnabled_I_CurrentImbalance', int(value))
def ipp_warningenabledigroundfault(self, name, value):
print('trying to set WarningEnabled_I_GroundFault to {}'.format(value))
return u800.writeMicroTag(addr, 'WarningEnabled_I_GroundFault', int(value))
def ipp_warningenabledijam(self, name, value):
print('trying to set WarningEnabled_I_Jam to {}'.format(value))
return u800.writeMicroTag(addr, 'WarningEnabled_I_Jam', int(value))
def ipp_warningenabledilineloss(self, name, value):
print('trying to set WarningEnabled_I_LineLoss to {}'.format(value))
return u800.writeMicroTag(addr, 'WarningEnabled_I_LineLoss', int(value))
def ipp_warningenablediovercurrent(self, name, value):
print('trying to set WarningEnabled_I_Overcurrent to {}'.format(value))
return u800.writeMicroTag(addr, 'WarningEnabled_I_Overcurrent', int(value))
def ipp_warningenabledioverload(self, name, value):
print('trying to set WarningEnabled_I_Overload to {}'.format(value))
return u800.writeMicroTag(addr, 'WarningEnabled_I_Overload', int(value))
def ipp_warningenablediphaseloss(self, name, value):
print('trying to set WarningEnabled_I_PhaseLoss to {}'.format(value))
return u800.writeMicroTag(addr, 'WarningEnabled_I_PhaseLoss', int(value))
def ipp_warningenabledistall(self, name, value):
print('trying to set WarningEnabled_I_Stall to {}'.format(value))
return u800.writeMicroTag(addr, 'WarningEnabled_I_Stall', int(value))
def ipp_warningenablediundercurrent(self, name, value):
print('trying to set WarningEnabled_I_Undercurrent to {}'.format(value))
return u800.writeMicroTag(addr, 'WarningEnabled_I_Undercurrent', int(value))
def ipp_warningenablediunderload(self, name, value):
print('trying to set WarningEnabled_I_Underload to {}'.format(value))
return u800.writeMicroTag(addr, 'WarningEnabled_I_Underload', int(value))
def ipp_warningenablevoverfrequency(self, name, value):
print('trying to set WarningEnable_V_Overfrequency to {}'.format(value))
return u800.writeMicroTag(addr, 'WarningEnable_V_Overfrequency', int(value))
def ipp_warningenablevovervoltage(self, name, value):
print('trying to set WarningEnable_V_Overvoltage to {}'.format(value))
return u800.writeMicroTag(addr, 'WarningEnable_V_Overvoltage', int(value))
def ipp_warningenablevphaserotation(self, name, value):
print('trying to set WarningEnable_V_PhaseRotation to {}'.format(value))
return u800.writeMicroTag(addr, 'WarningEnable_V_PhaseRotation', int(value))
def ipp_warningenablevunderfrequency(self, name, value):
print('trying to set WarningEnable_V_Underfrequency to {}'.format(value))
return u800.writeMicroTag(addr, 'WarningEnable_V_Underfrequency', int(value))
def ipp_warningenablevundervoltage(self, name, value):
print('trying to set WarningEnable_V_Undervoltage to {}'.format(value))
return u800.writeMicroTag(addr, 'WarningEnable_V_Undervoltage', int(value))
def ipp_warningenablevvoltageunbalance(self, name, value):
print('trying to set WarningEnable_V_VoltageUnbalance to {}'.format(value))
return u800.writeMicroTag(addr, 'WarningEnable_V_VoltageUnbalance', int(value))
def genericSet(self, name, value, id):
global channels
try:
print("Trying to set {} to {}".format(channels[name].tag, value))
return channels[name].write(value)
except Exception, e:
print("Exception during genericSet: {}".format(e))

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -1,62 +1,47 @@
from pycomm_micro.ab_comm.clx import Driver as u800Driver
import logging
from pycomm.ab_comm.clx import Driver as u800Driver
import sys
def readMicroTag(addr, tag):
logging.basicConfig(
filename="u800Driver.log",
format="%(levelname)-10s %(asctime)s %(message)s",
level=logging.DEBUG
)
addr = str(addr)
tag = str(tag)
c = u800Driver()
if c.open(addr):
if c.open(addr, True):
try:
v = c.read_tag(tag)
# print(v)
return v
except Exception as e:
except Exception:
err = c.get_status()
c.close()
print err
print("Error with {}: {}".format(tag, err))
pass
c.close()
def getTagType(addr, tag):
logging.basicConfig(
filename="u800Driver.log",
format="%(levelname)-10s %(asctime)s %(message)s",
level=logging.DEBUG
)
c = u800Driver()
if c.open(addr):
if c.open(addr, True):
try:
return c.read_tag(tag)[1]
except Exception as e:
except Exception:
err = c.get_status()
c.close()
print err
pass
c.close()
def writeMicroTag(addr, tag, val):
logging.basicConfig(
filename="u800Driver.log",
format="%(levelname)-10s %(asctime)s %(message)s",
level=logging.DEBUG
)
c = u800Driver()
if c.open(addr):
def writeMicroTag(addr, tag, val):
c = u800Driver()
if c.open(addr, True):
try:
#typ = getTagType(addr, tag)
# typ = getTagType(addr, tag)
cv = c.read_tag(tag)
wt = c.write_tag(tag, val, cv[1])
# print(wt)
return wt
except Exception as e:
except Exception:
err = c.get_status()
c.close()
print err
@@ -65,22 +50,16 @@ def writeMicroTag(addr, tag, val):
def readMicroTagList(addr, tList):
logging.basicConfig(
filename="u800Driver.log",
format="%(levelname)-10s %(asctime)s %(message)s",
level=logging.DEBUG
)
c = u800Driver()
if c.open(addr):
if c.open(addr, True):
vals = []
try:
for t in tList:
v = c.read_tag(t)
vals.append({"tag":t,"val":v[0], "type":v[1]})
vals.append({"tag": t, "val": v[0], "type": v[1]})
# print(v)
# print("{0} - {1}".format(t, v))
except Exception as e:
except Exception:
err = c.get_status()
c.close()
print err

115
POCloud_Driver/modbusMap.py Normal file
View File

@@ -0,0 +1,115 @@
modbusMap = {
'1': {
'c': u'ETHERNET/IP',
'b': u'10.20.4.5',
'addresses': {
u'300': {
u'2-3': {
u'bytary': None,
u'vm': None,
u'ct': u'number',
u'le': u'16',
u'grp': u'3600',
u'la': 0,
u'chn':
u'automode',
u'un': u'1',
u'dn': u'M1',
u'da': u'300',
u'lrt': 1468595216.996952,
u'r': u'0-1',
u'a': u'Auto_Mode',
u'c': u'0.5',
u'misc_u': u'',
u'f': u'1',
u'mrt': u'60',
u'm': u'none',
'm1ch': u'2-3',
u's': u'On',
u'mv': u'0',
u't': u'int'
}, u'2-1': {
u'bytary': None,
u'vm': None,
u'ct': u'number',
u'le': u'16',
u'grp': u'86400',
u'la': None,
u'chn': u'cfggfgroundfaultinhibittime',
u'un': u'1',
u'dn': u'M1',
u'da': u'300',
u'lrt': u'0',
u'r': u'0-100',
u'a': u'cfg_GF_GroundFaultInhibitTime',
u'c': u'0',
u'misc_u': u'sec',
u'f': u'1',
u'mrt': u'60',
u'm': u'none',
'm1ch': u'2-1',
u's': u'On',
u'mv': u'0',
u't': u'int'
}, u'2-4': {
u'bytary': None,
u'vm': None,
u'ct': u'number',
u'le': u'16',
u'grp': u'86400',
u'la': 10.0,
u'chn': u'cfgcflasetting',
u'un': u'1',
u'dn': u'M1',
u'da': u'300',
u'lrt': 1468595218.131659,
u'r': u'0-200',
u'a': u'cfg_C_FLASetting',
u'c': u'0.5',
u'misc_u': u'A',
u'f': u'1',
u'mrt': u'60',
u'm': u'none',
'm1ch': u'2-4',
u's': u'On',
u'mv': u'0',
u't': u'int'
}, u'2-5': {
u'bytary': None,
u'vm': None,
u'ct': u'number',
u'le': u'16',
u'grp': u'86400',
u'la': 60,
u'chn': u'cfgcleartripcountafter',
u'un': u'1',
u'dn': u'M1',
u'da': u'300',
u'lrt': 1468595210.837538,
u'r': u'0-86400',
u'a': u'cfg_ClearTripCountAfter',
u'c': u'0',
u'misc_u': u'sec',
u'f': u'1',
u'mrt': u'60',
u'm': u'none',
'm1ch': u'2-5',
u's': u'On',
u'mv': u'0',
u't': u'int'
}
}
},
'f': u'Off',
'p': u'',
's': u'1'
},
'2': {
'c': u'none',
'b': u'9600',
'addresses': {},
'f': u'Off',
'p': u'none',
's': u'1'
}
}

View File

@@ -0,0 +1,10 @@
import pickle
with open("ipp_channels.p", 'rb') as picklefile:
channels = pickle.load(picklefile)
for chname in sorted(channels):
ch = channels[chname]
if ch['data_type'] == "BOOL":
print("'{0}': Channel('{0}', '{1}', {2}, self.sendtodbJSON, writeable=True, e300_param=False),".format(chname, ch['tag'], ch['max_time_between_uploads']))
else:
print("'{0}': Channel('{0}', '{1}', {2}, self.sendtodbJSON, writeable=True, change_threshold=1.0, e300_param=False),".format(chname, ch['tag'], ch['max_time_between_uploads']))

View File

@@ -1 +0,0 @@
__author__ = 'agostino'

View File

@@ -1,2 +0,0 @@
__author__ = 'agostino'
import logging

View File

@@ -1,847 +0,0 @@
# -*- coding: utf-8 -*-
#
# clx.py - Ethernet/IP Client for Rockwell PLCs
#
#
# Copyright (c) 2014 Agostino Ruscito <ruscito@gmail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
from pycomm_micro.cip.cip_base import *
from pycomm_micro.common import setup_logger
import logging
class Driver(Base):
"""
This Ethernet/IP client is based on Rockwell specification. Please refer to the link below for details.
http://literature.rockwellautomation.com/idc/groups/literature/documents/pm/1756-pm020_-en-p.pdf
The following services have been implemented:
- Read Tag Service (0x4c)
- Read Tag Fragment Service (0x52)
- Write Tag Service (0x4d)
- Write Tag Fragment Service (0x53)
- Multiple Service Packet (0x0a)
The client has been successfully tested with the following PLCs:
- CompactLogix 5330ERM
- CompactLogix 5370
- ControlLogix 5572 and 1756-EN2T Module
"""
def __init__(self, debug=False, filename=None):
if debug:
super(Driver, self).__init__(setup_logger('ab_comm.clx', logging.DEBUG, filename))
else:
super(Driver, self).__init__(setup_logger('ab_comm.clx', logging.INFO, filename))
self._buffer = {}
self._get_template_in_progress = False
self.__version__ = '0.2'
def get_last_tag_read(self):
""" Return the last tag read by a multi request read
:return: A tuple (tag name, value, type)
"""
return self._last_tag_read
def get_last_tag_write(self):
""" Return the last tag write by a multi request write
:return: A tuple (tag name, 'GOOD') if the write was successful otherwise (tag name, 'BAD')
"""
return self._last_tag_write
def _parse_instance_attribute_list(self, start_tag_ptr, status):
""" extract the tags list from the message received
:param start_tag_ptr: The point in the message string where the tag list begin
:param status: The status of the message receives
"""
tags_returned = self._reply[start_tag_ptr:]
tags_returned_length = len(tags_returned)
idx = 0
instance = 0
count = 0
try:
while idx < tags_returned_length:
instance = unpack_dint(tags_returned[idx:idx+4])
idx += 4
tag_length = unpack_uint(tags_returned[idx:idx+2])
idx += 2
tag_name = tags_returned[idx:idx+tag_length]
idx += tag_length
symbol_type = unpack_uint(tags_returned[idx:idx+2])
idx += 2
count += 1
self._tag_list.append({'instance_id': instance,
'tag_name': tag_name,
'symbol_type': symbol_type})
except Exception as e:
raise DataError(e)
if status == SUCCESS:
self._last_instance = -1
elif status == 0x06:
self._last_instance = instance + 1
else:
self._status = (1, 'unknown status during _parse_tag_list')
self._last_instance = -1
def _parse_structure_makeup_attributes(self, start_tag_ptr, status):
""" extract the tags list from the message received
:param start_tag_ptr: The point in the message string where the tag list begin
:param status: The status of the message receives
"""
self._buffer = {}
if status != SUCCESS:
self._buffer['Error'] = status
return
attribute = self._reply[start_tag_ptr:]
idx = 4
try:
if unpack_uint(attribute[idx:idx + 2]) == SUCCESS:
idx += 2
self._buffer['object_definition_size'] = unpack_dint(attribute[idx:idx + 4])
else:
self._buffer['Error'] = 'object_definition Error'
return
idx += 6
if unpack_uint(attribute[idx:idx + 2]) == SUCCESS:
idx += 2
self._buffer['structure_size'] = unpack_dint(attribute[idx:idx + 4])
else:
self._buffer['Error'] = 'structure Error'
return
idx += 6
if unpack_uint(attribute[idx:idx + 2]) == SUCCESS:
idx += 2
self._buffer['member_count'] = unpack_uint(attribute[idx:idx + 2])
else:
self._buffer['Error'] = 'member_count Error'
return
idx += 4
if unpack_uint(attribute[idx:idx + 2]) == SUCCESS:
idx += 2
self._buffer['structure_handle'] = unpack_uint(attribute[idx:idx + 2])
else:
self._buffer['Error'] = 'structure_handle Error'
return
return self._buffer
except Exception as e:
raise DataError(e)
def _parse_template(self, start_tag_ptr, status):
""" extract the tags list from the message received
:param start_tag_ptr: The point in the message string where the tag list begin
:param status: The status of the message receives
"""
tags_returned = self._reply[start_tag_ptr:]
bytes_received = len(tags_returned)
self._buffer += tags_returned
if status == SUCCESS:
self._get_template_in_progress = False
elif status == 0x06:
self._byte_offset += bytes_received
else:
self._status = (1, 'unknown status {0} during _parse_template'.format(status))
self.logger.warning(self._status)
self._last_instance = -1
def _parse_fragment(self, start_ptr, status):
""" parse the fragment returned by a fragment service.
:param start_ptr: Where the fragment start within the replay
:param status: status field used to decide if keep parsing or stop
"""
try:
data_type = unpack_uint(self._reply[start_ptr:start_ptr+2])
fragment_returned = self._reply[start_ptr+2:]
except Exception as e:
raise DataError(e)
fragment_returned_length = len(fragment_returned)
idx = 0
while idx < fragment_returned_length:
try:
typ = I_DATA_TYPE[data_type]
value = UNPACK_DATA_FUNCTION[typ](fragment_returned[idx:idx+DATA_FUNCTION_SIZE[typ]])
idx += DATA_FUNCTION_SIZE[typ]
except Exception as e:
raise DataError(e)
self._tag_list.append((self._last_position, value))
self._last_position += 1
if status == SUCCESS:
self._byte_offset = -1
elif status == 0x06:
self._byte_offset += fragment_returned_length
else:
self._status = (2, 'unknown status during _parse_fragment')
self._byte_offset = -1
def _parse_multiple_request_read(self, tags):
""" parse the message received from a multi request read:
For each tag parsed, the information extracted includes the tag name, the value read and the data type.
Those information are appended to the tag list as tuple
:return: the tag list
"""
offset = 50
position = 50
try:
number_of_service_replies = unpack_uint(self._reply[offset:offset+2])
tag_list = []
for index in range(number_of_service_replies):
position += 2
start = offset + unpack_uint(self._reply[position:position+2])
general_status = unpack_usint(self._reply[start+2:start+3])
if general_status == 0:
data_type = unpack_uint(self._reply[start+4:start+6])
value_begin = start + 6
value_end = value_begin + DATA_FUNCTION_SIZE[I_DATA_TYPE[data_type]]
value = self._reply[value_begin:value_end]
self._last_tag_read = (tags[index], UNPACK_DATA_FUNCTION[I_DATA_TYPE[data_type]](value),
I_DATA_TYPE[data_type])
else:
self._last_tag_read = (tags[index], None, None)
tag_list.append(self._last_tag_read)
return tag_list
except Exception as e:
raise DataError(e)
def _parse_multiple_request_write(self, tags):
""" parse the message received from a multi request writ:
For each tag parsed, the information extracted includes the tag name and the status of the writing.
Those information are appended to the tag list as tuple
:return: the tag list
"""
offset = 50
position = 50
try:
number_of_service_replies = unpack_uint(self._reply[offset:offset+2])
tag_list = []
for index in range(number_of_service_replies):
position += 2
start = offset + unpack_uint(self._reply[position:position+2])
general_status = unpack_usint(self._reply[start+2:start+3])
if general_status == 0:
self._last_tag_write = (tags[index] + ('GOOD',))
else:
self._last_tag_write = (tags[index] + ('BAD',))
tag_list.append(self._last_tag_write)
return tag_list
except Exception as e:
raise DataError(e)
def _check_reply(self):
""" check the replayed message for error
"""
self._more_packets_available = False
try:
if self._reply is None:
self._status = (3, '%s without reply' % REPLAY_INFO[unpack_dint(self._message[:2])])
return False
# Get the type of command
typ = unpack_uint(self._reply[:2])
# Encapsulation status check
if unpack_dint(self._reply[8:12]) != SUCCESS:
self._status = (3, "{0} reply status:{1}".format(REPLAY_INFO[typ],
SERVICE_STATUS[unpack_dint(self._reply[8:12])]))
return False
# Command Specific Status check
if typ == unpack_uint(ENCAPSULATION_COMMAND["send_rr_data"]):
status = unpack_usint(self._reply[42:43])
if status != SUCCESS:
self._status = (3, "send_rr_data reply:{0} - Extend status:{1}".format(
SERVICE_STATUS[status], get_extended_status(self._reply, 42)))
return False
else:
return True
elif typ == unpack_uint(ENCAPSULATION_COMMAND["send_unit_data"]):
status = unpack_usint(self._reply[48:49])
if unpack_usint(self._reply[46:47]) == I_TAG_SERVICES_REPLY["Read Tag Fragmented"]:
self._parse_fragment(50, status)
return True
if unpack_usint(self._reply[46:47]) == I_TAG_SERVICES_REPLY["Get Instance Attributes List"]:
self._parse_instance_attribute_list(50, status)
return True
if unpack_usint(self._reply[46:47]) == I_TAG_SERVICES_REPLY["Get Attributes"]:
self._parse_structure_makeup_attributes(50, status)
return True
if unpack_usint(self._reply[46:47]) == I_TAG_SERVICES_REPLY["Read Template"] and \
self._get_template_in_progress:
self._parse_template(50, status)
return True
if status == 0x06:
self._status = (3, "Insufficient Packet Space")
self._more_packets_available = True
elif status != SUCCESS:
self._status = (3, "send_unit_data reply:{0} - Extend status:{1}".format(
SERVICE_STATUS[status], get_extended_status(self._reply, 48)))
return False
else:
return True
return True
except Exception as e:
raise DataError(e)
def read_tag(self, tag):
""" read tag from a connected plc
Possible combination can be passed to this method:
- ('Counts') a single tag name
- (['ControlWord']) a list with one tag or many
- (['parts', 'ControlWord', 'Counts'])
At the moment there is not a strong validation for the argument passed. The user should verify
the correctness of the format passed.
:return: None is returned in case of error otherwise the tag list is returned
"""
multi_requests = False
if isinstance(tag, list):
multi_requests = True
if not self._target_is_connected:
if not self.forward_open():
self._status = (6, "Target did not connected. read_tag will not be executed.")
self.logger.warning(self._status)
raise Error("Target did not connected. read_tag will not be executed.")
# multi_requests = False
if multi_requests:
rp_list = []
for t in tag:
rp = create_tag_rp(t, multi_requests=True)
if rp is None:
self._status = (6, "Cannot create tag {0} request packet. read_tag will not be executed.".format(tag))
raise DataError("Cannot create tag {0} request packet. read_tag will not be executed.".format(tag))
else:
rp_list.append(chr(TAG_SERVICES_REQUEST['Read Tag']) + rp + pack_uint(1))
message_request = build_multiple_service(rp_list, Base._get_sequence())
else:
rp = create_tag_rp(tag)
if rp is None:
self._status = (6, "Cannot create tag {0} request packet. read_tag will not be executed.".format(tag))
return None
else:
# Creating the Message Request Packet
message_request = [
pack_uint(Base._get_sequence()),
chr(TAG_SERVICES_REQUEST['Read Tag']), # the Request Service
chr(len(rp) / 2), # the Request Path Size length in word
rp, # the request path
pack_uint(1)
]
if self.send_unit_data(
build_common_packet_format(
DATA_ITEM['Connected'],
''.join(message_request),
ADDRESS_ITEM['Connection Based'],
addr_data=self._target_cid,
)) is None:
raise DataError("send_unit_data returned not valid data")
if multi_requests:
return self._parse_multiple_request_read(tag)
else:
# Get the data type
data_type = unpack_uint(self._reply[50:52])
# print I_DATA_TYPE[data_type]
try:
return UNPACK_DATA_FUNCTION[I_DATA_TYPE[data_type]](self._reply[52:]), I_DATA_TYPE[data_type]
except Exception as e:
raise DataError(e)
def read_array(self, tag, counts):
""" read array of atomic data type from a connected plc
At the moment there is not a strong validation for the argument passed. The user should verify
the correctness of the format passed.
:param tag: the name of the tag to read
:param counts: the number of element to read
:return: None is returned in case of error otherwise the tag list is returned
"""
if not self._target_is_connected:
if not self.forward_open():
self._status = (7, "Target did not connected. read_tag will not be executed.")
self.logger.warning(self._status)
raise Error("Target did not connected. read_tag will not be executed.")
self._byte_offset = 0
self._last_position = 0
self._tag_list = []
while self._byte_offset != -1:
rp = create_tag_rp(tag)
if rp is None:
self._status = (7, "Cannot create tag {0} request packet. read_tag will not be executed.".format(tag))
return None
else:
# Creating the Message Request Packet
message_request = [
pack_uint(Base._get_sequence()),
chr(TAG_SERVICES_REQUEST["Read Tag Fragmented"]), # the Request Service
chr(len(rp) / 2), # the Request Path Size length in word
rp, # the request path
pack_uint(counts),
pack_dint(self._byte_offset)
]
if self.send_unit_data(
build_common_packet_format(
DATA_ITEM['Connected'],
''.join(message_request),
ADDRESS_ITEM['Connection Based'],
addr_data=self._target_cid,
)) is None:
raise DataError("send_unit_data returned not valid data")
return self._tag_list
def write_tag(self, tag, value=None, typ=None):
""" write tag/tags from a connected plc
Possible combination can be passed to this method:
- ('tag name', Value, data type) as single parameters or inside a tuple
- ([('tag name', Value, data type), ('tag name2', Value, data type)]) as array of tuples
At the moment there is not a strong validation for the argument passed. The user should verify
the correctness of the format passed.
The type accepted are:
- BOOL
- SINT
- INT'
- DINT
- REAL
- LINT
- BYTE
- WORD
- DWORD
- LWORD
:param tag: tag name, or an array of tuple containing (tag name, value, data type)
:param value: the value to write or none if tag is an array of tuple or a tuple
:param typ: the type of the tag to write or none if tag is an array of tuple or a tuple
:return: None is returned in case of error otherwise the tag list is returned
"""
multi_requests = False
if isinstance(tag, list):
multi_requests = True
if not self._target_is_connected:
if not self.forward_open():
self._status = (8, "Target did not connected. write_tag will not be executed.")
self.logger.warning(self._status)
raise Error("Target did not connected. write_tag will not be executed.")
if multi_requests:
rp_list = []
tag_to_remove = []
idx = 0
for name, value, typ in tag:
# Create the request path to wrap the tag name
rp = create_tag_rp(name, multi_requests=True)
if rp is None:
self._status = (8, "Cannot create tag{0} req. packet. write_tag will not be executed".format(tag))
return None
else:
try: # Trying to add the rp to the request path list
val = PACK_DATA_FUNCTION[typ](value)
rp_list.append(
chr(TAG_SERVICES_REQUEST['Write Tag'])
+ rp
+ pack_uint(S_DATA_TYPE[typ])
+ pack_uint(1)
+ val
)
idx += 1
except (LookupError, struct.error) as e:
self._status = (8, "Tag:{0} type:{1} removed from write list. Error:{2}.".format(name, typ, e))
# The tag in idx position need to be removed from the rp list because has some kind of error
tag_to_remove.append(idx)
# Remove the tags that have not been inserted in the request path list
for position in tag_to_remove:
del tag[position]
# Create the message request
message_request = build_multiple_service(rp_list, Base._get_sequence())
else:
if isinstance(tag, tuple):
name, value, typ = tag
else:
name = tag
rp = create_tag_rp(name)
if rp is None:
self._status = (8, "Cannot create tag {0} request packet. write_tag will not be executed.".format(tag))
self.logger.warning(self._status)
return None
else:
# Creating the Message Request Packet
message_request = [
pack_uint(Base._get_sequence()),
chr(TAG_SERVICES_REQUEST["Write Tag"]), # the Request Service
chr(len(rp) / 2), # the Request Path Size length in word
rp, # the request path
pack_uint(S_DATA_TYPE[typ]), # data type
pack_uint(1), # Add the number of tag to write
PACK_DATA_FUNCTION[typ](value)
]
ret_val = self.send_unit_data(
build_common_packet_format(
DATA_ITEM['Connected'],
''.join(message_request),
ADDRESS_ITEM['Connection Based'],
addr_data=self._target_cid,
)
)
if multi_requests:
return self._parse_multiple_request_write(tag)
else:
if ret_val is None:
raise DataError("send_unit_data returned not valid data")
return ret_val
def write_array(self, tag, data_type, values):
""" write array of atomic data type from a connected plc
At the moment there is not a strong validation for the argument passed. The user should verify
the correctness of the format passed.
:param tag: the name of the tag to read
:param data_type: the type of tag to write
:param values: the array of values to write
"""
if not isinstance(values, list):
self._status = (9, "A list of tags must be passed to write_array.")
self.logger.warning(self._status)
raise DataError("A list of tags must be passed to write_array.")
if not self._target_is_connected:
if not self.forward_open():
self._status = (9, "Target did not connected. write_array will not be executed.")
self.logger.warning(self._status)
raise Error("Target did not connected. write_array will not be executed.")
array_of_values = ""
byte_size = 0
byte_offset = 0
for i, value in enumerate(values):
array_of_values += PACK_DATA_FUNCTION[data_type](value)
byte_size += DATA_FUNCTION_SIZE[data_type]
if byte_size >= 450 or i == len(values)-1:
# create the message and send the fragment
rp = create_tag_rp(tag)
if rp is None:
self._status = (9, "Cannot create tag {0} request packet. \
write_array will not be executed.".format(tag))
return None
else:
# Creating the Message Request Packet
message_request = [
pack_uint(Base._get_sequence()),
chr(TAG_SERVICES_REQUEST["Write Tag Fragmented"]), # the Request Service
chr(len(rp) / 2), # the Request Path Size length in word
rp, # the request path
pack_uint(S_DATA_TYPE[data_type]), # Data type to write
pack_uint(len(values)), # Number of elements to write
pack_dint(byte_offset),
array_of_values # Fragment of elements to write
]
byte_offset += byte_size
if self.send_unit_data(
build_common_packet_format(
DATA_ITEM['Connected'],
''.join(message_request),
ADDRESS_ITEM['Connection Based'],
addr_data=self._target_cid,
)) is None:
raise DataError("send_unit_data returned not valid data")
array_of_values = ""
byte_size = 0
def _get_instance_attribute_list_service(self):
""" Step 1: Finding user-created controller scope tags in a Logix5000 controller
This service returns instance IDs for each created instance of the symbol class, along with a list
of the attribute data associated with the requested attribute
"""
try:
if not self._target_is_connected:
if not self.forward_open():
self._status = (10, "Target did not connected. get_tag_list will not be executed.")
self.logger.warning(self._status)
raise Error("Target did not connected. get_tag_list will not be executed.")
self._last_instance = 0
self._get_template_in_progress = True
while self._last_instance != -1:
# Creating the Message Request Packet
message_request = [
pack_uint(Base._get_sequence()),
chr(TAG_SERVICES_REQUEST['Get Instance Attributes List']), # STEP 1
# the Request Path Size length in word
chr(3),
# Request Path ( 20 6B 25 00 Instance )
CLASS_ID["8-bit"], # Class id = 20 from spec 0x20
CLASS_CODE["Symbol Object"], # Logical segment: Symbolic Object 0x6B
INSTANCE_ID["16-bit"], # Instance Segment: 16 Bit instance 0x25
'\x00',
pack_uint(self._last_instance), # The instance
# Request Data
pack_uint(2), # Number of attributes to retrieve
pack_uint(1), # Attribute 1: Symbol name
pack_uint(2) # Attribute 2: Symbol type
]
if self.send_unit_data(
build_common_packet_format(
DATA_ITEM['Connected'],
''.join(message_request),
ADDRESS_ITEM['Connection Based'],
addr_data=self._target_cid,
)) is None:
raise DataError("send_unit_data returned not valid data")
self._get_template_in_progress = False
except Exception as e:
raise DataError(e)
def _get_structure_makeup(self, instance_id):
"""
get the structure makeup for a specific structure
"""
if not self._target_is_connected:
if not self.forward_open():
self._status = (10, "Target did not connected. get_tag_list will not be executed.")
self.logger.warning(self._status)
raise Error("Target did not connected. get_tag_list will not be executed.")
message_request = [
pack_uint(self._get_sequence()),
chr(TAG_SERVICES_REQUEST['Get Attributes']),
chr(3), # Request Path ( 20 6B 25 00 Instance )
CLASS_ID["8-bit"], # Class id = 20 from spec 0x20
CLASS_CODE["Template Object"], # Logical segment: Template Object 0x6C
INSTANCE_ID["16-bit"], # Instance Segment: 16 Bit instance 0x25
'\x00',
pack_uint(instance_id),
pack_uint(4), # Number of attributes
pack_uint(4), # Template Object Definition Size UDINT
pack_uint(5), # Template Structure Size UDINT
pack_uint(2), # Template Member Count UINT
pack_uint(1) # Structure Handle We can use this to read and write UINT
]
if self.send_unit_data(
build_common_packet_format(DATA_ITEM['Connected'],
''.join(message_request), ADDRESS_ITEM['Connection Based'],
addr_data=self._target_cid,)) is None:
raise DataError("send_unit_data returned not valid data")
return self._buffer
def _read_template(self, instance_id, object_definition_size):
""" get a list of the tags in the plc
"""
if not self._target_is_connected:
if not self.forward_open():
self._status = (10, "Target did not connected. get_tag_list will not be executed.")
self.logger.warning(self._status)
raise Error("Target did not connected. get_tag_list will not be executed.")
self._byte_offset = 0
self._buffer = ""
self._get_template_in_progress = True
try:
while self._get_template_in_progress:
# Creating the Message Request Packet
message_request = [
pack_uint(self._get_sequence()),
chr(TAG_SERVICES_REQUEST['Read Template']),
chr(3), # Request Path ( 20 6B 25 00 Instance )
CLASS_ID["8-bit"], # Class id = 20 from spec 0x20
CLASS_CODE["Template Object"], # Logical segment: Template Object 0x6C
INSTANCE_ID["16-bit"], # Instance Segment: 16 Bit instance 0x25
'\x00',
pack_uint(instance_id),
pack_dint(self._byte_offset), # Offset
pack_uint(((object_definition_size * 4)-23) - self._byte_offset)
]
if not self.send_unit_data(
build_common_packet_format(DATA_ITEM['Connected'], ''.join(message_request),
ADDRESS_ITEM['Connection Based'], addr_data=self._target_cid,)):
raise DataError("send_unit_data returned not valid data")
self._get_template_in_progress = False
return self._buffer
except Exception as e:
raise DataError(e)
def _isolating_user_tag(self):
try:
lst = self._tag_list
self._tag_list = []
for tag in lst:
if tag['tag_name'].find(':') != -1 or tag['tag_name'].find('__') != -1:
continue
if tag['symbol_type'] & 0b0001000000000000:
continue
dimension = tag['symbol_type'] & 0b0110000000000000 >> 13
template_instance_id = tag['symbol_type'] & 0b0000111111111111
if tag['symbol_type'] & 0b1000000000000000 :
tag_type = 'struct'
data_type = 'user-created'
self._tag_list.append({'instance_id': tag['instance_id'],
'template_instance_id': template_instance_id,
'tag_name': tag['tag_name'],
'dim': dimension,
'tag_type': tag_type,
'data_type': data_type,
'template': {},
'udt': {}})
else:
tag_type = 'atomic'
data_type = I_DATA_TYPE[template_instance_id]
self._tag_list.append({'instance_id': tag['instance_id'],
'tag_name': tag['tag_name'],
'dim': dimension,
'tag_type': tag_type,
'data_type': data_type})
except Exception as e:
raise DataError(e)
def _parse_udt_raw(self, tag):
try:
buff = self._read_template(tag['template_instance_id'], tag['template']['object_definition_size'])
member_count = tag['template']['member_count']
names = buff.split('\00')
lst = []
tag['udt']['name'] = 'Not an user defined structure'
for name in names:
if len(name) > 1:
if name.find(';') != -1:
tag['udt']['name'] = name[:name.find(';')]
elif name.find('ZZZZZZZZZZ') != -1:
continue
elif name.isalpha():
lst.append(name)
else:
continue
tag['udt']['internal_tags'] = lst
type_list = []
for i in xrange(member_count):
# skip member 1
if i != 0:
array_size = unpack_uint(buff[:2])
try:
data_type = I_DATA_TYPE[unpack_uint(buff[2:4])]
except Exception:
data_type = "None"
offset = unpack_dint(buff[4:8])
type_list.append((array_size, data_type, offset))
buff = buff[8:]
tag['udt']['data_type'] = type_list
except Exception as e:
raise DataError(e)
def get_tag_list(self):
self._tag_list = []
# Step 1
self._get_instance_attribute_list_service()
# Step 2
self._isolating_user_tag()
# Step 3
for tag in self._tag_list:
if tag['tag_type'] == 'struct':
tag['template'] = self._get_structure_makeup(tag['template_instance_id'])
for idx, tag in enumerate(self._tag_list):
# print (tag)
if tag['tag_type'] == 'struct':
self._parse_udt_raw(tag)
# Step 4
return self._tag_list

View File

@@ -1,446 +0,0 @@
# -*- coding: utf-8 -*-
#
# clx.py - Ethernet/IP Client for Rockwell PLCs
#
#
# Copyright (c) 2014 Agostino Ruscito <ruscito@gmail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
from pycomm_micro.cip.cip_base import *
from pycomm_micro.common import setup_logger
import re
import logging
import math
def parse_tag(tag):
t = re.search(r"(?P<file_type>[CT])(?P<file_number>\d{1,3})"
r"(:)(?P<element_number>\d{1,3})"
r"(.)(?P<sub_element>ACC|PRE|EN|DN|TT|CU|CD|DN|OV|UN|UA)", tag, flags=re.IGNORECASE)
if t:
if (1 <= int(t.group('file_number')) <= 255) \
and (0 <= int(t.group('element_number')) <= 255):
return True, t.group(0), {'file_type': t.group('file_type').upper(),
'file_number': t.group('file_number'),
'element_number': t.group('element_number'),
'sub_element': PCCC_CT[t.group('sub_element').upper()],
'read_func': '\xa2',
'write_func': '\xab',
'address_field': 3}
t = re.search(r"(?P<file_type>[FBN])(?P<file_number>\d{1,3})"
r"(:)(?P<element_number>\d{1,3})"
r"(/(?P<sub_element>\d{1,2}))?",
tag, flags=re.IGNORECASE)
if t:
if t.group('sub_element') is not None:
if (1 <= int(t.group('file_number')) <= 255) \
and (0 <= int(t.group('element_number')) <= 255) \
and (0 <= int(t.group('sub_element')) <= 15):
return True, t.group(0), {'file_type': t.group('file_type').upper(),
'file_number': t.group('file_number'),
'element_number': t.group('element_number'),
'sub_element': t.group('sub_element'),
'read_func': '\xa2',
'write_func': '\xab',
'address_field': 3}
else:
if (1 <= int(t.group('file_number')) <= 255) \
and (0 <= int(t.group('element_number')) <= 255):
return True, t.group(0), {'file_type': t.group('file_type').upper(),
'file_number': t.group('file_number'),
'element_number': t.group('element_number'),
'sub_element': t.group('sub_element'),
'read_func': '\xa2',
'write_func': '\xab',
'address_field': 2}
t = re.search(r"(?P<file_type>[IO])(:)(?P<file_number>\d{1,3})"
r"(.)(?P<element_number>\d{1,3})"
r"(/(?P<sub_element>\d{1,2}))?", tag, flags=re.IGNORECASE)
if t:
if t.group('sub_element') is not None:
if (0 <= int(t.group('file_number')) <= 255) \
and (0 <= int(t.group('element_number')) <= 255) \
and (0 <= int(t.group('sub_element')) <= 15):
return True, t.group(0), {'file_type': t.group('file_type').upper(),
'file_number': t.group('file_number'),
'element_number': t.group('element_number'),
'sub_element': t.group('sub_element'),
'read_func': '\xa2',
'write_func': '\xab',
'address_field': 3}
else:
if (0 <= int(t.group('file_number')) <= 255) \
and (0 <= int(t.group('element_number')) <= 255):
return True, t.group(0), {'file_type': t.group('file_type').upper(),
'file_number': t.group('file_number'),
'element_number': t.group('element_number'),
'read_func': '\xa2',
'write_func': '\xab',
'address_field': 2}
t = re.search(r"(?P<file_type>S)"
r"(:)(?P<element_number>\d{1,3})"
r"(/(?P<sub_element>\d{1,2}))?", tag, flags=re.IGNORECASE)
if t:
if t.group('sub_element') is not None:
if (0 <= int(t.group('element_number')) <= 255) \
and (0 <= int(t.group('sub_element')) <= 15):
return True, t.group(0), {'file_type': t.group('file_type').upper(),
'file_number': '2',
'element_number': t.group('element_number'),
'sub_element': t.group('sub_element'),
'read_func': '\xa2',
'write_func': '\xab',
'address_field': 3}
else:
if 0 <= int(t.group('element_number')) <= 255:
return True, t.group(0), {'file_type': t.group('file_type').upper(),
'file_number': '2',
'element_number': t.group('element_number'),
'read_func': '\xa2',
'write_func': '\xab',
'address_field': 2}
t = re.search(r"(?P<file_type>B)(?P<file_number>\d{1,3})"
r"(/)(?P<element_number>\d{1,4})",
tag, flags=re.IGNORECASE)
if t:
if (1 <= int(t.group('file_number')) <= 255) \
and (0 <= int(t.group('element_number')) <= 4095):
bit_position = int(t.group('element_number'))
element_number = bit_position / 16
sub_element = bit_position - (element_number * 16)
return True, t.group(0), {'file_type': t.group('file_type').upper(),
'file_number': t.group('file_number'),
'element_number': element_number,
'sub_element': sub_element,
'read_func': '\xa2',
'write_func': '\xab',
'address_field': 3}
return False, tag
class Driver(Base):
"""
SLC/PLC_5 Implementation
"""
def __init__(self, debug=False, filename=None):
if debug:
super(Driver, self).__init__(setup_logger('ab_comm.slc', logging.DEBUG, filename))
else:
super(Driver, self).__init__(setup_logger('ab_comm.slc', logging.INFO, filename))
self.__version__ = '0.1'
self._last_sequence = 0
def _check_reply(self):
"""
check the replayed message for error
"""
self._more_packets_available = False
try:
if self._reply is None:
self._status = (3, '%s without reply' % REPLAY_INFO[unpack_dint(self._message[:2])])
return False
# Get the type of command
typ = unpack_uint(self._reply[:2])
# Encapsulation status check
if unpack_dint(self._reply[8:12]) != SUCCESS:
self._status = (3, "{0} reply status:{1}".format(REPLAY_INFO[typ],
SERVICE_STATUS[unpack_dint(self._reply[8:12])]))
return False
# Command Specific Status check
if typ == unpack_uint(ENCAPSULATION_COMMAND["send_rr_data"]):
status = unpack_usint(self._reply[42:43])
if status != SUCCESS:
self._status = (3, "send_rr_data reply:{0} - Extend status:{1}".format(
SERVICE_STATUS[status], get_extended_status(self._reply, 42)))
return False
else:
return True
elif typ == unpack_uint(ENCAPSULATION_COMMAND["send_unit_data"]):
status = unpack_usint(self._reply[48:49])
if unpack_usint(self._reply[46:47]) == I_TAG_SERVICES_REPLY["Read Tag Fragmented"]:
self._parse_fragment(50, status)
return True
if unpack_usint(self._reply[46:47]) == I_TAG_SERVICES_REPLY["Get Instance Attributes List"]:
self._parse_tag_list(50, status)
return True
if status == 0x06:
self._status = (3, "Insufficient Packet Space")
self._more_packets_available = True
elif status != SUCCESS:
self._status = (3, "send_unit_data reply:{0} - Extend status:{1}".format(
SERVICE_STATUS[status], get_extended_status(self._reply, 48)))
return False
else:
return True
return True
except Exception as e:
raise DataError(e)
def read_tag(self, tag, n=1):
""" read tag from a connected plc
Possible combination can be passed to this method:
print c.read_tag('F8:0', 3) return a list of 3 registers starting from F8:0
print c.read_tag('F8:0') return one value
It is possible to read status bit
:return: None is returned in case of error
"""
res = parse_tag(tag)
if not res[0]:
self._status = (1000, "Error parsing the tag passed to read_tag({0},{1})".format(tag, n))
self.logger.warning(self._status)
raise DataError("Error parsing the tag passed to read_tag({0},{1})".format(tag, n))
bit_read = False
bit_position = 0
sub_element = 0
if int(res[2]['address_field'] == 3):
bit_read = True
bit_position = int(res[2]['sub_element'])
if not self._target_is_connected:
if not self.forward_open():
self._status = (5, "Target did not connected. read_tag will not be executed.")
self.logger.warning(self._status)
raise Error("Target did not connected. read_tag will not be executed.")
data_size = PCCC_DATA_SIZE[res[2]['file_type']]
# Creating the Message Request Packet
self._last_sequence = pack_uint(Base._get_sequence())
message_request = [
self._last_sequence,
'\x4b',
'\x02',
CLASS_ID["8-bit"],
PATH["PCCC"],
'\x07',
self.attribs['vid'],
self.attribs['vsn'],
'\x0f',
'\x00',
self._last_sequence[1],
self._last_sequence[0],
res[2]['read_func'],
pack_usint(data_size * n),
pack_usint(int(res[2]['file_number'])),
PCCC_DATA_TYPE[res[2]['file_type']],
pack_usint(int(res[2]['element_number'])),
pack_usint(sub_element)
]
self.logger.debug("SLC read_tag({0},{1})".format(tag, n))
if self.send_unit_data(
build_common_packet_format(
DATA_ITEM['Connected'],
''.join(message_request),
ADDRESS_ITEM['Connection Based'],
addr_data=self._target_cid,)):
sts = int(unpack_usint(self._reply[58]))
try:
if sts != 0:
sts_txt = PCCC_ERROR_CODE[sts]
self._status = (1000, "Error({0}) returned from read_tag({1},{2})".format(sts_txt, tag, n))
self.logger.warning(self._status)
raise DataError("Error({0}) returned from read_tag({1},{2})".format(sts_txt, tag, n))
new_value = 61
if bit_read:
if res[2]['file_type'] == 'T' or res[2]['file_type'] == 'C':
if bit_position == PCCC_CT['PRE']:
return UNPACK_PCCC_DATA_FUNCTION[res[2]['file_type']](
self._reply[new_value+2:new_value+2+data_size])
elif bit_position == PCCC_CT['ACC']:
return UNPACK_PCCC_DATA_FUNCTION[res[2]['file_type']](
self._reply[new_value+4:new_value+4+data_size])
tag_value = UNPACK_PCCC_DATA_FUNCTION[res[2]['file_type']](
self._reply[new_value:new_value+data_size])
return get_bit(tag_value, bit_position)
else:
values_list = []
while len(self._reply[new_value:]) >= data_size:
values_list.append(
UNPACK_PCCC_DATA_FUNCTION[res[2]['file_type']](self._reply[new_value:new_value+data_size])
)
new_value = new_value+data_size
if len(values_list) > 1:
return values_list
else:
return values_list[0]
except Exception as e:
self._status = (1000, "Error({0}) parsing the data returned from read_tag({1},{2})".format(e, tag, n))
self.logger.warning(self._status)
raise DataError("Error({0}) parsing the data returned from read_tag({1},{2})".format(e, tag, n))
else:
raise DataError("send_unit_data returned not valid data")
def write_tag(self, tag, value):
""" write tag from a connected plc
Possible combination can be passed to this method:
c.write_tag('N7:0', [-30, 32767, -32767])
c.write_tag('N7:0', 21)
c.read_tag('N7:0', 10)
It is not possible to write status bit
:return: None is returned in case of error
"""
res = parse_tag(tag)
if not res[0]:
self._status = (1000, "Error parsing the tag passed to read_tag({0},{1})".format(tag, value))
self.logger.warning(self._status)
raise DataError("Error parsing the tag passed to read_tag({0},{1})".format(tag, value))
if isinstance(value, list) and int(res[2]['address_field'] == 3):
self._status = (1000, "Function's parameters error. read_tag({0},{1})".format(tag, value))
self.logger.warning(self._status)
raise DataError("Function's parameters error. read_tag({0},{1})".format(tag, value))
if isinstance(value, list) and int(res[2]['address_field'] == 3):
self._status = (1000, "Function's parameters error. read_tag({0},{1})".format(tag, value))
self.logger.warning(self._status)
raise DataError("Function's parameters error. read_tag({0},{1})".format(tag, value))
bit_field = False
bit_position = 0
sub_element = 0
if int(res[2]['address_field'] == 3):
bit_field = True
bit_position = int(res[2]['sub_element'])
values_list = ''
else:
values_list = '\xff\xff'
multi_requests = False
if isinstance(value, list):
multi_requests = True
if not self._target_is_connected:
if not self.forward_open():
self._status = (1000, "Target did not connected. write_tag will not be executed.")
self.logger.warning(self._status)
raise Error("Target did not connected. write_tag will not be executed.")
try:
n = 0
if multi_requests:
data_size = PCCC_DATA_SIZE[res[2]['file_type']]
for v in value:
values_list += PACK_PCCC_DATA_FUNCTION[res[2]['file_type']](v)
n += 1
else:
n = 1
if bit_field:
data_size = 2
if (res[2]['file_type'] == 'T' or res[2]['file_type'] == 'C') \
and (bit_position == PCCC_CT['PRE'] or bit_position == PCCC_CT['ACC']):
sub_element = bit_position
values_list = '\xff\xff' + PACK_PCCC_DATA_FUNCTION[res[2]['file_type']](value)
else:
sub_element = 0
if value > 0:
values_list = pack_uint(math.pow(2, bit_position)) + pack_uint(math.pow(2, bit_position))
else:
values_list = pack_uint(math.pow(2, bit_position)) + pack_uint(0)
else:
values_list += PACK_PCCC_DATA_FUNCTION[res[2]['file_type']](value)
data_size = PCCC_DATA_SIZE[res[2]['file_type']]
except Exception as e:
self._status = (1000, "Error({0}) packing the values to write to the"
"SLC write_tag({1},{2})".format(e, tag, value))
self.logger.warning(self._status)
raise DataError("Error({0}) packing the values to write to the "
"SLC write_tag({1},{2})".format(e, tag, value))
data_to_write = values_list
# Creating the Message Request Packet
self._last_sequence = pack_uint(Base._get_sequence())
message_request = [
self._last_sequence,
'\x4b',
'\x02',
CLASS_ID["8-bit"],
PATH["PCCC"],
'\x07',
self.attribs['vid'],
self.attribs['vsn'],
'\x0f',
'\x00',
self._last_sequence[1],
self._last_sequence[0],
res[2]['write_func'],
pack_usint(data_size * n),
pack_usint(int(res[2]['file_number'])),
PCCC_DATA_TYPE[res[2]['file_type']],
pack_usint(int(res[2]['element_number'])),
pack_usint(sub_element)
]
self.logger.debug("SLC write_tag({0},{1})".format(tag, value))
if self.send_unit_data(
build_common_packet_format(
DATA_ITEM['Connected'],
''.join(message_request) + data_to_write,
ADDRESS_ITEM['Connection Based'],
addr_data=self._target_cid,)):
sts = int(unpack_usint(self._reply[58]))
try:
if sts != 0:
sts_txt = PCCC_ERROR_CODE[sts]
self._status = (1000, "Error({0}) returned from SLC write_tag({1},{2})".format(sts_txt, tag, value))
self.logger.warning(self._status)
raise DataError("Error({0}) returned from SLC write_tag({1},{2})".format(sts_txt, tag, value))
return True
except Exception as e:
self._status = (1000, "Error({0}) parsing the data returned from "
"SLC write_tag({1},{2})".format(e, tag, value))
self.logger.warning(self._status)
raise DataError("Error({0}) parsing the data returned from "
"SLC write_tag({1},{2})".format(e, tag, value))
else:
raise DataError("send_unit_data returned not valid data")

View File

@@ -1 +0,0 @@
__author__ = 'agostino'

View File

@@ -1,827 +0,0 @@
# -*- coding: utf-8 -*-
#
# cip_base.py - A set of classes methods and structures used to implement Ethernet/IP
#
#
# Copyright (c) 2014 Agostino Ruscito <ruscito@gmail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
import struct
import socket
from os import getpid
from pycomm_micro.cip.cip_const import *
from pycomm_micro.common import PycommError
class CommError(PycommError):
pass
class DataError(PycommError):
pass
def pack_sint(n):
return struct.pack('b', n)
def pack_usint(n):
return struct.pack('B', n)
def pack_int(n):
"""pack 16 bit into 2 bytes little endian"""
return struct.pack('<h', n)
def pack_uint(n):
"""pack 16 bit into 2 bytes little endian"""
# print("N: {0}".format(n))
return struct.pack('<H', n)
def pack_dint(n):
"""pack 32 bit into 4 bytes little endian"""
return struct.pack('<i', n)
def pack_real(r):
"""unpack 4 bytes little endian to int"""
return struct.pack('<f', r)
def pack_lint(l):
"""unpack 4 bytes little endian to int"""
return struct.unpack('<q', l)
def unpack_bool(st):
if int(struct.unpack('B', st[0])[0]) == 0:
return 0
return 1
def unpack_sint(st):
return int(struct.unpack('b', st[0])[0])
def unpack_usint(st):
return int(struct.unpack('B', st[0])[0])
def unpack_int(st):
"""unpack 2 bytes little endian to int"""
return int(struct.unpack('<h', st[0:2])[0])
def unpack_uint(st):
"""unpack 2 bytes little endian to int"""
return int(struct.unpack('<H', st[0:2])[0])
def unpack_dint(st):
"""unpack 4 bytes little endian to int"""
return int(struct.unpack('<i', st[0:4])[0])
def unpack_real(st):
"""unpack 4 bytes little endian to int"""
return float(struct.unpack('<f', st[0:4])[0])
def unpack_lreal(st):
"""unpack 8 bytes little endian to int"""
return float(struct.unpack('<f', st[0:8])[0])
def unpack_lint(st):
"""unpack 4 bytes little endian to int"""
return int(struct.unpack('<q', st[0:8])[0])
def get_bit(value, idx):
""":returns value of bit at position idx"""
return (value & (1 << idx)) != 0
PACK_DATA_FUNCTION = {
'BOOL': pack_sint,
'SINT': pack_sint, # Signed 8-bit integer
'INT': pack_int, # Signed 16-bit integer
'UINT': pack_uint, # Unsigned 16-bit integer
'USINT': pack_usint, # Unsigned 8-bit integer
'DINT': pack_dint, # Signed 32-bit integer
'REAL': pack_real, # 32-bit floating point
'LREAL': pack_real, # 32-bit floating point
'LINT': pack_lint,
'BYTE': pack_sint, # byte string 8-bits
'WORD': pack_uint, # byte string 16-bits
'DWORD': pack_dint, # byte string 32-bits
'LWORD': pack_lint # byte string 64-bits
}
UNPACK_DATA_FUNCTION = {
'BOOL': unpack_bool,
'SINT': unpack_sint, # Signed 8-bit integer
'INT': unpack_int, # Signed 16-bit integer
'UINT': unpack_uint, # Unsigned 16-bit
'USINT': unpack_usint, # Unsigned 8-bit integer
'DINT': unpack_dint, # Signed 32-bit integer
'UDINT': unpack_dint, # Signed 32-bit integer
'REAL': unpack_real, # 32-bit floating point,
'LREAL': unpack_lreal, # 32-bit floating point,
'LINT': unpack_lint,
'BYTE': unpack_sint, # byte string 8-bits
'WORD': unpack_uint, # byte string 16-bits
'DWORD': unpack_dint, # byte string 32-bits
'LWORD': unpack_lint # byte string 64-bits
}
DATA_FUNCTION_SIZE = {
'BOOL': 1,
'SINT': 1, # Signed 8-bit integer
'INT': 2, # Signed 16-bit integer
'UINT': 2, # Unsigned 16-bit integer
'DINT': 4, # Signed 32-bit integer
'REAL': 4, # 32-bit floating point
'LINT': 8,
'BYTE': 1, # byte string 8-bits
'WORD': 2, # byte string 16-bits
'DWORD': 4, # byte string 32-bits
'LWORD': 8 # byte string 64-bits
}
UNPACK_PCCC_DATA_FUNCTION = {
'N': unpack_int,
'B': unpack_int,
'T': unpack_int,
'C': unpack_int,
'S': unpack_int,
'F': unpack_real,
'A': unpack_sint,
'R': unpack_dint,
'O': unpack_int,
'I': unpack_int
}
PACK_PCCC_DATA_FUNCTION = {
'N': pack_int,
'B': pack_int,
'T': pack_int,
'C': pack_int,
'S': pack_int,
'F': pack_real,
'A': pack_sint,
'R': pack_dint,
'O': pack_int,
'I': pack_int
}
def print_bytes_line(msg):
out = ''
for ch in msg:
out += "{:0>2x}".format(ord(ch))
return out
def print_bytes_msg(msg, info=''):
out = info
new_line = True
line = 0
column = 0
for idx, ch in enumerate(msg):
if new_line:
out += "\n({:0>4d}) ".format(line * 10)
new_line = False
out += "{:0>2x} ".format(ord(ch))
if column == 9:
new_line = True
column = 0
line += 1
else:
column += 1
return out
def get_extended_status(msg, start):
status = unpack_usint(msg[start:start+1])
# send_rr_data
# 42 General Status
# 43 Size of additional status
# 44..n additional status
# send_unit_data
# 48 General Status
# 49 Size of additional status
# 50..n additional status
extended_status_size = (unpack_usint(msg[start+1:start+2]))*2
extended_status = 0
if extended_status_size != 0:
# There is an additional status
if extended_status_size == 1:
extended_status = unpack_usint(msg[start+2:start+3])
elif extended_status_size == 2:
extended_status = unpack_uint(msg[start+2:start+4])
elif extended_status_size == 4:
extended_status = unpack_dint(msg[start+2:start+6])
else:
return 'Extended Status Size Unknown'
try:
return '{0}'.format(EXTEND_CODES[status][extended_status])
except LookupError:
return "Extended Status info not present"
def create_tag_rp(tag, multi_requests=False):
""" Create tag Request Packet
It returns the request packed wrapped around the tag passed.
If any error it returns none
"""
tags = tag.split('.')
rp = []
index = []
for tag in tags:
add_index = False
# Check if is an array tag
if tag.find('[') != -1:
# Remove the last square bracket
tag = tag[:len(tag)-1]
# Isolate the value inside bracket
inside_value = tag[tag.find('[')+1:]
# Now split the inside value in case part of multidimensional array
index = inside_value.split(',')
# Flag the existence of one o more index
add_index = True
# Get only the tag part
tag = tag[:tag.find('[')]
tag_length = len(tag)
# Create the request path
rp.append(EXTENDED_SYMBOL) # ANSI Ext. symbolic segment
rp.append(chr(tag_length)) # Length of the tag
# Add the tag to the Request path
for char in tag:
rp.append(char)
# Add pad byte because total length of Request path must be word-aligned
if tag_length % 2:
rp.append(PADDING_BYTE)
# Add any index
if add_index:
for idx in index:
val = int(idx)
if val <= 0xff:
rp.append(ELEMENT_ID["8-bit"])
rp.append(pack_usint(val))
elif val <= 0xffff:
rp.append(ELEMENT_ID["16-bit"]+PADDING_BYTE)
rp.append(pack_uint(val))
elif val <= 0xfffffffff:
rp.append(ELEMENT_ID["32-bit"]+PADDING_BYTE)
rp.append(pack_dint(val))
else:
# Cannot create a valid request packet
return None
# At this point the Request Path is completed,
if multi_requests:
request_path = chr(len(rp)/2) + ''.join(rp)
else:
request_path = ''.join(rp)
return request_path
def build_common_packet_format(message_type, message, addr_type, addr_data=None, timeout=10):
""" build_common_packet_format
It creates the common part for a CIP message. Check Volume 2 (page 2.22) of CIP specification for reference
"""
msg = pack_dint(0) # Interface Handle: shall be 0 for CIP
msg += pack_uint(timeout) # timeout
msg += pack_uint(2) # Item count: should be at list 2 (Address and Data)
msg += addr_type # Address Item Type ID
if addr_data is not None:
msg += pack_uint(len(addr_data)) # Address Item Length
msg += addr_data
else:
msg += pack_uint(0) # Address Item Length
msg += message_type # Data Type ID
msg += pack_uint(len(message)) # Data Item Length
msg += message
return msg
def build_multiple_service(rp_list, sequence=None):
mr = []
if sequence is not None:
mr.append(pack_uint(sequence))
mr.append(chr(TAG_SERVICES_REQUEST["Multiple Service Packet"])) # the Request Service
mr.append(pack_usint(2)) # the Request Path Size length in word
mr.append(CLASS_ID["8-bit"])
mr.append(CLASS_CODE["Message Router"])
mr.append(INSTANCE_ID["8-bit"])
mr.append(pack_usint(1)) # Instance 1
mr.append(pack_uint(len(rp_list))) # Number of service contained in the request
# Offset calculation
offset = (len(rp_list) * 2) + 2
for index, rp in enumerate(rp_list):
if index == 0:
mr.append(pack_uint(offset)) # Starting offset
else:
mr.append(pack_uint(offset))
offset += len(rp)
for rp in rp_list:
mr.append(rp)
return mr
def parse_multiple_request(message, tags, typ):
""" parse_multi_request
This function should be used to parse the message replayed to a multi request service rapped around the
send_unit_data message.
:param message: the full message returned from the PLC
:param tags: The list of tags to be read
:param typ: to specify if multi request service READ or WRITE
:return: a list of tuple in the format [ (tag name, value, data type), ( tag name, value, data type) ].
In case of error the tuple will be (tag name, None, None)
"""
offset = 50
position = 50
number_of_service_replies = unpack_uint(message[offset:offset+2])
tag_list = []
for index in range(number_of_service_replies):
position += 2
start = offset + unpack_uint(message[position:position+2])
general_status = unpack_usint(message[start+2:start+3])
if general_status == 0:
if typ == "READ":
data_type = unpack_uint(message[start+4:start+6])
try:
value_begin = start + 6
value_end = value_begin + DATA_FUNCTION_SIZE[I_DATA_TYPE[data_type]]
value = message[value_begin:value_end]
tag_list.append((tags[index],
UNPACK_DATA_FUNCTION[I_DATA_TYPE[data_type]](value),
I_DATA_TYPE[data_type]))
except LookupError:
tag_list.append((tags[index], None, None))
else:
tag_list.append((tags[index] + ('GOOD',)))
else:
if typ == "READ":
tag_list.append((tags[index], None, None))
else:
tag_list.append((tags[index] + ('BAD',)))
return tag_list
class Socket:
def __init__(self, timeout=5.0):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.settimeout(timeout)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
def connect(self, host, port):
try:
self.sock.connect((host, port))
except socket.timeout:
raise CommError("Socket timeout during connection.")
def send(self, msg, timeout=0):
if timeout != 0:
self.sock.settimeout(timeout)
total_sent = 0
while total_sent < len(msg):
try:
sent = self.sock.send(msg[total_sent:])
if sent == 0:
raise CommError("socket connection broken.")
total_sent += sent
except socket.error:
raise CommError("socket connection broken.")
return total_sent
def receive(self, timeout=0):
if timeout != 0:
self.sock.settimeout(timeout)
msg_len = 28
chunks = []
bytes_recd = 0
one_shot = True
while bytes_recd < msg_len:
try:
chunk = self.sock.recv(min(msg_len - bytes_recd, 2048))
if chunk == '':
raise CommError("socket connection broken.")
if one_shot:
data_size = int(struct.unpack('<H', chunk[2:4])[0]) # Length
msg_len = HEADER_SIZE + data_size
one_shot = False
chunks.append(chunk)
bytes_recd += len(chunk)
except socket.error as e:
raise CommError(e)
return ''.join(chunks)
def close(self):
self.sock.close()
def parse_symbol_type(symbol):
""" parse_symbol_type
It parse the symbol to Rockwell Spec
:param symbol: the symbol associated to a tag
:return: A tuple containing information about the tag
"""
pass
return None
class Base(object):
_sequence = 0
def __init__(self, logging):
if Base._sequence == 0:
Base._sequence = getpid()
else:
Base._sequence = Base._get_sequence()
self.logger = logging
self.__version__ = '0.1'
self.__sock = None
self._session = 0
self._connection_opened = False
self._reply = None
self._message = None
self._target_cid = None
self._target_is_connected = False
self._tag_list = []
self._buffer = {}
self._device_description = "Device Unknown"
self._last_instance = 0
self._byte_offset = 0
self._last_position = 0
self._more_packets_available = False
self._last_tag_read = ()
self._last_tag_write = ()
self._status = (0, "")
# self.attribs = {'context': '_pycomm_', 'protocol version': 1, 'rpi': 5000, 'port': 0xAF12, 'timeout': 10,
# 'backplane': 1, 'cpu slot': 0, 'option': 0, 'cid': '\x27\x04\x19\x71', 'csn': '\x27\x04',
# 'vid': '\x09\x10', 'vsn': '\x09\x10\x19\x71', 'name': 'Base', 'ip address': None}
self.attribs = {'context': '_pycomm_', 'protocol version': 1, 'rpi': 5000, 'port': 0xAF12, 'timeout': 10,
'backplane': 0, 'cpu slot': 0, 'option': 0, 'cid': '\x27\x04\x19\x71', 'csn': '\x27\x04',
'vid': '\x09\x10', 'vsn': '\x09\x10\x19\x71', 'name': 'Base', 'ip address': None}
def __len__(self):
return len(self.attribs)
def __getitem__(self, key):
return self.attribs[key]
def __setitem__(self, key, value):
self.attribs[key] = value
def __delitem__(self, key):
try:
del self.attribs[key]
except LookupError:
pass
def __iter__(self):
return iter(self.attribs)
def __contains__(self, item):
return item in self.attribs
def _check_reply(self):
raise Socket.ImplementationError("The method has not been implemented")
@staticmethod
def _get_sequence():
""" Increase and return the sequence used with connected messages
:return: The New sequence
"""
if Base._sequence < 65535:
Base._sequence += 1
else:
Base._sequence = getpid()
return Base._sequence
def nop(self):
""" No replay command
A NOP provides a way for either an originator or target to determine if the TCP connection is still open.
"""
self._message = self.build_header(ENCAPSULATION_COMMAND['nop'], 0)
self._send()
def __repr__(self):
return self._device_description
def description(self):
return self._device_description
def list_identity(self):
""" ListIdentity command to locate and identify potential target
return true if the replay contains the device description
"""
self._message = self.build_header(ENCAPSULATION_COMMAND['list_identity'], 0)
self._send()
self._receive()
if self._check_reply():
try:
self._device_description = self._reply[63:-1]
return True
except Exception as e:
raise CommError(e)
return False
def send_rr_data(self, msg):
""" SendRRData transfer an encapsulated request/reply packet between the originator and target
:param msg: The message to be send to the target
:return: the replay received from the target
"""
self._message = self.build_header(ENCAPSULATION_COMMAND["send_rr_data"], len(msg))
self._message += msg
self._send()
self._receive()
return self._check_reply()
def send_unit_data(self, msg):
""" SendUnitData send encapsulated connected messages.
:param msg: The message to be send to the target
:return: the replay received from the target
"""
self._message = self.build_header(ENCAPSULATION_COMMAND["send_unit_data"], len(msg))
self._message += msg
self._send()
self._receive()
return self._check_reply()
def get_status(self):
""" Get the last status/error
This method can be used after any call to get any details in case of error
:return: A tuple containing (error group, error message)
"""
return self._status
def clear(self):
""" Clear the last status/error
:return: return am empty tuple
"""
self._status = (0, "")
def build_header(self, command, length):
""" Build the encapsulate message header
The header is 24 bytes fixed length, and includes the command and the length of the optional data portion.
:return: the headre
"""
try:
h = command # Command UINT
h += pack_uint(length) # Length UINT
h += pack_dint(self._session) # Session Handle UDINT
h += pack_dint(0) # Status UDINT
h += self.attribs['context'] # Sender Context 8 bytes
h += pack_dint(self.attribs['option']) # Option UDINT
return h
except Exception as e:
raise CommError(e)
def register_session(self):
""" Register a new session with the communication partner
:return: None if any error, otherwise return the session number
"""
if self._session:
return self._session
self._session = 0
self._message = self.build_header(ENCAPSULATION_COMMAND['register_session'], 4)
self._message += pack_uint(self.attribs['protocol version'])
self._message += pack_uint(0)
self._send()
self._receive()
if self._check_reply():
self._session = unpack_dint(self._reply[4:8])
self.logger.debug("Session ={0} has been registered.".format(print_bytes_line(self._reply[4:8])))
return self._session
self._status = 'Warning ! the session has not been registered.'
self.logger.warning(self._status)
return None
def forward_open(self):
""" CIP implementation of the forward open message
Refer to ODVA documentation Volume 1 3-5.5.2
:return: False if any error in the replayed message
"""
if self._session == 0:
self._status = (4, "A session need to be registered before to call forward_open.")
raise CommError("A session need to be registered before to call forward open")
forward_open_msg = [
FORWARD_OPEN,
pack_usint(2),
CLASS_ID["8-bit"],
CLASS_CODE["Connection Manager"], # Volume 1: 5-1
INSTANCE_ID["8-bit"],
CONNECTION_MANAGER_INSTANCE['Open Request'],
PRIORITY,
TIMEOUT_TICKS,
pack_dint(0),
self.attribs['cid'],
self.attribs['csn'],
self.attribs['vid'],
self.attribs['vsn'],
TIMEOUT_MULTIPLIER,
'\x00\x00\x00',
pack_dint(self.attribs['rpi'] * 1000),
pack_uint(CONNECTION_PARAMETER['Default']),
pack_dint(self.attribs['rpi'] * 1000),
pack_uint(CONNECTION_PARAMETER['Default']),
TRANSPORT_CLASS, # Transport Class
# CONNECTION_SIZE['Backplane'],
CONNECTION_SIZE['Direct Network'],
# pack_usint(self.attribs['backplane']),
# pack_usint(self.attribs['cpu slot']),
CLASS_ID["8-bit"],
CLASS_CODE["Message Router"],
INSTANCE_ID["8-bit"],
pack_usint(1)
]
if self.send_rr_data(
build_common_packet_format(DATA_ITEM['Unconnected'], ''.join(forward_open_msg), ADDRESS_ITEM['UCMM'],)):
self._target_cid = self._reply[44:48]
self._target_is_connected = True
return True
self._status = (4, "forward_open returned False")
return False
def forward_close(self):
""" CIP implementation of the forward close message
Each connection opened with the froward open message need to be closed.
Refer to ODVA documentation Volume 1 3-5.5.3
:return: False if any error in the replayed message
"""
if self._session == 0:
self._status = (5, "A session need to be registered before to call forward_close.")
raise CommError("A session need to be registered before to call forward_close.")
# print ("Backplane:{0}\nCPU:{1}".format(self.attribs['backplane'], self.attribs['cpu slot']))
forward_close_msg = [
FORWARD_CLOSE,
pack_usint(2),
CLASS_ID["8-bit"],
CLASS_CODE["Connection Manager"], # Volume 1: 5-1
INSTANCE_ID["8-bit"],
CONNECTION_MANAGER_INSTANCE['Open Request'],
PRIORITY,
TIMEOUT_TICKS,
self.attribs['csn'],
self.attribs['vid'],
self.attribs['vsn'],
CONNECTION_SIZE['Direct Network'],
# CONNECTION_SIZE['Backplane'],
'\x00', # Reserved
# pack_usint(self.attribs['backplane']),
# pack_usint(self.attribs['cpu slot']),
CLASS_ID["8-bit"],
CLASS_CODE["Message Router"],
INSTANCE_ID["8-bit"],
pack_usint(1)
]
if self.send_rr_data(
build_common_packet_format(DATA_ITEM['Unconnected'], ''.join(forward_close_msg), ADDRESS_ITEM['UCMM'])):
self._target_is_connected = False
return True
self._status = (5, "forward_close returned False")
self.logger.warning(self._status)
return False
def un_register_session(self):
""" Un-register a connection
"""
self._message = self.build_header(ENCAPSULATION_COMMAND['unregister_session'], 0)
self._send()
self._session = None
def _send(self):
"""
socket send
:return: true if no error otherwise false
"""
try:
self.logger.debug(print_bytes_msg(self._message, '-------------- SEND --------------'))
self.__sock.send(self._message)
except Exception as e:
#self.clean_up()
raise CommError(e)
def _receive(self):
"""
socket receive
:return: true if no error otherwise false
"""
try:
self._reply = self.__sock.receive()
self.logger.debug(print_bytes_msg(self._reply, '----------- RECEIVE -----------'))
except Exception as e:
#self.clean_up()
raise CommError(e)
def open(self, ip_address):
"""
socket open
:return: true if no error otherwise false
"""
# handle the socket layer
if not self._connection_opened:
try:
if self.__sock is None:
self.__sock = Socket()
self.__sock.connect(ip_address, self.attribs['port'])
self._connection_opened = True
self.attribs['ip address'] = ip_address
if self.register_session() is None:
self._status = (13, "Session not registered")
return False
self.forward_close()
return True
except Exception as e:
#self.clean_up()
raise CommError(e)
def close(self):
"""
socket close
:return: true if no error otherwise false
"""
try:
if self._target_is_connected:
self.forward_close()
if self._session != 0:
self.un_register_session()
if self.__sock:
self.__sock.close()
except Exception as e:
raise CommError(e)
self.clean_up()
def clean_up(self):
self.__sock = None
self._target_is_connected = False
self._session = 0
self._connection_opened = False
def is_connected(self):
return self._connection_opened

View File

@@ -1,482 +0,0 @@
# -*- coding: utf-8 -*-
#
# cip_const.py - A set of structures and constants used to implement the Ethernet/IP protocol
#
#
# Copyright (c) 2014 Agostino Ruscito <ruscito@gmail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
ELEMENT_ID = {
"8-bit": '\x28',
"16-bit": '\x29',
"32-bit": '\x2a'
}
CLASS_ID = {
"8-bit": '\x20',
"16-bit": '\x21',
}
INSTANCE_ID = {
"8-bit": '\x24',
"16-bit": '\x25'
}
ATTRIBUTE_ID = {
"8-bit": '\x30',
"16-bit": '\x31'
}
# Path are combined as:
# CLASS_ID + PATHS
# For example PCCC path is CLASS_ID["8-bit"]+PATH["PCCC"] -> 0x20, 0x67, 0x24, 0x01.
PATH = {
'Connection Manager': '\x06\x24\x01',
'Router': '\x02\x24\x01',
'Backplane Data Type': '\x66\x24\x01',
'PCCC': '\x67\x24\x01',
'DHCP Channel A': '\xa6\x24\x01\x01\x2c\x01',
'DHCP Channel B': '\xa6\x24\x01\x02\x2c\x01'
}
ENCAPSULATION_COMMAND = { # Volume 2: 2-3.2 Command Field UINT 2 byte
"nop": '\x00\x00',
"list_targets": '\x01\x00',
"list_services": '\x04\x00',
"list_identity": '\x63\x00',
"list_interfaces": '\x64\x00',
"register_session": '\x65\x00',
"unregister_session": '\x66\x00',
"send_rr_data": '\x6F\x00',
"send_unit_data": '\x70\x00'
}
"""
When a tag is created, an instance of the Symbol Object (Class ID 0x6B) is created
inside the controller.
When a UDT is created, an instance of the Template object (Class ID 0x6C) is
created to hold information about the structure makeup.
"""
CLASS_CODE = {
"Message Router": '\x02', # Volume 1: 5-1
"Symbol Object": '\x6b',
"Template Object": '\x6c',
"Connection Manager": '\x06' # Volume 1: 3-5
}
CONNECTION_MANAGER_INSTANCE = {
'Open Request': '\x01',
'Open Format Rejected': '\x02',
'Open Resource Rejected': '\x03',
'Open Other Rejected': '\x04',
'Close Request': '\x05',
'Close Format Request': '\x06',
'Close Other Request': '\x07',
'Connection Timeout': '\x08'
}
TAG_SERVICES_REQUEST = {
"Read Tag": 0x4c,
"Read Tag Fragmented": 0x52,
"Write Tag": 0x4d,
"Write Tag Fragmented": 0x53,
"Read Modify Write Tag": 0x4e,
"Multiple Service Packet": 0x0a,
"Get Instance Attributes List": 0x55,
"Get Attributes": 0x03,
"Read Template": 0x4c,
}
TAG_SERVICES_REPLY = {
0xcc: "Read Tag",
0xd2: "Read Tag Fragmented",
0xcd: "Write Tag",
0xd3: "Write Tag Fragmented",
0xce: "Read Modify Write Tag",
0x8a: "Multiple Service Packet",
0xd5: "Get Instance Attributes List",
0x83: "Get Attributes",
0xcc: "Read Template"
}
I_TAG_SERVICES_REPLY = {
"Read Tag": 0xcc,
"Read Tag Fragmented": 0xd2,
"Write Tag": 0xcd,
"Write Tag Fragmented": 0xd3,
"Read Modify Write Tag": 0xce,
"Multiple Service Packet": 0x8a,
"Get Instance Attributes List": 0xd5,
"Get Attributes": 0x83,
"Read Template": 0xcc
}
"""
EtherNet/IP Encapsulation Error Codes
Standard CIP Encapsulation Error returned in the cip message header
"""
STATUS = {
0x0000: "Success",
0x0001: "The sender issued an invalid or unsupported encapsulation command",
0x0002: "Insufficient memory",
0x0003: "Poorly formed or incorrect data in the data portion",
0x0064: "An originator used an invalid session handle when sending an encapsulation message to the target",
0x0065: "The target received a message of invalid length",
0x0069: "Unsupported Protocol Version"
}
"""
MSG Error Codes:
The following error codes have been taken from:
Rockwell Automation Publication
1756-RM003P-EN-P - December 2014
"""
SERVICE_STATUS = {
0x01: "Connection failure (see extended status)",
0x02: "Insufficient resource",
0x03: "Invalid value",
0x04: "IOI syntax error. A syntax error was detected decoding the Request Path (see extended status)",
0x05: "Destination unknown, class unsupported, instance \nundefined or structure element undefined (see extended status)",
0x06: "Insufficient Packet Space",
0x07: "Connection lost",
0x08: "Service not supported",
0x09: "Error in data segment or invalid attribute value",
0x0A: "Attribute list error",
0x0B: "State already exist",
0x0C: "Object state conflict",
0x0D: "Object already exist",
0x0E: "Attribute not settable",
0x0F: "Permission denied",
0x10: "Device state conflict",
0x11: "Reply data too large",
0x12: "Fragmentation of a primitive value",
0x13: "Insufficient command data",
0x14: "Attribute not supported",
0x15: "Too much data",
0x1A: "Bridge request too large",
0x1B: "Bridge response too large",
0x1C: "Attribute list shortage",
0x1D: "Invalid attribute list",
0x1E: "Request service error",
0x1F: "Connection related failure (see extended status)",
0x22: "Invalid reply received",
0x25: "Key segment error",
0x26: "Invalid IOI error",
0x27: "Unexpected attribute in list",
0x28: "DeviceNet error - invalid member ID",
0x29: "DeviceNet error - member not settable",
0xD1: "Module not in run state",
0xFB: "Message port not supported",
0xFC: "Message unsupported data type",
0xFD: "Message uninitialized",
0xFE: "Message timeout",
0xff: "General Error (see extended status)"
}
EXTEND_CODES = {
0x01: {
0x0100: "Connection in use",
0x0103: "Transport not supported",
0x0106: "Ownership conflict",
0x0107: "Connection not found",
0x0108: "Invalid connection type",
0x0109: "Invalid connection size",
0x0110: "Module not configured",
0x0111: "EPR not supported",
0x0114: "Wrong module",
0x0115: "Wrong device type",
0x0116: "Wrong revision",
0x0118: "Invalid configuration format",
0x011A: "Application out of connections",
0x0203: "Connection timeout",
0x0204: "Unconnected message timeout",
0x0205: "Unconnected send parameter error",
0x0206: "Message too large",
0x0301: "No buffer memory",
0x0302: "Bandwidth not available",
0x0303: "No screeners available",
0x0305: "Signature match",
0x0311: "Port not available",
0x0312: "Link address not available",
0x0315: "Invalid segment type",
0x0317: "Connection not scheduled"
},
0x04: {
0x0000: "Extended status out of memory",
0x0001: "Extended status out of instances"
},
0x05: {
0x0000: "Extended status out of memory",
0x0001: "Extended status out of instances"
},
0x1F: {
0x0203: "Connection timeout"
},
0xff: {
0x7: "Wrong data type",
0x2001: "Excessive IOI",
0x2002: "Bad parameter value",
0x2018: "Semaphore reject",
0x201B: "Size too small",
0x201C: "Invalid size",
0x2100: "Privilege failure",
0x2101: "Invalid keyswitch position",
0x2102: "Password invalid",
0x2103: "No password issued",
0x2104: "Address out of range",
0x2105: "Address and how many out of range",
0x2106: "Data in use",
0x2107: "Type is invalid or not supported",
0x2108: "Controller in upload or download mode",
0x2109: "Attempt to change number of array dimensions",
0x210A: "Invalid symbol name",
0x210B: "Symbol does not exist",
0x210E: "Search failed",
0x210F: "Task cannot start",
0x2110: "Unable to write",
0x2111: "Unable to read",
0x2112: "Shared routine not editable",
0x2113: "Controller in faulted mode",
0x2114: "Run mode inhibited"
}
}
DATA_ITEM = {
'Connected': '\xb1\x00',
'Unconnected': '\xb2\x00'
}
ADDRESS_ITEM = {
'Connection Based': '\xa1\x00',
'Null': '\x00\x00',
'UCMM': '\x00\x00'
}
UCMM = {
'Interface Handle': 0,
'Item Count': 2,
'Address Type ID': 0,
'Address Length': 0,
'Data Type ID': 0x00b2
}
CONNECTION_SIZE = {
'Backplane': '\x03', # CLX
'Direct Network': '\x02'
}
HEADER_SIZE = 24
EXTENDED_SYMBOL = '\x91'
BOOL_ONE = 0xff
REQUEST_SERVICE = 0
REQUEST_PATH_SIZE = 1
REQUEST_PATH = 2
SUCCESS = 0
INSUFFICIENT_PACKETS = 6
OFFSET_MESSAGE_REQUEST = 40
FORWARD_CLOSE = '\x4e'
UNCONNECTED_SEND = '\x52'
FORWARD_OPEN = '\x54'
LARGE_FORWARD_OPEN = '\x5b'
GET_CONNECTION_DATA = '\x56'
SEARCH_CONNECTION_DATA = '\x57'
GET_CONNECTION_OWNER = '\x5a'
MR_SERVICE_SIZE = 2
PADDING_BYTE = '\x00'
PRIORITY = '\x0a'
TIMEOUT_TICKS = '\x05'
TIMEOUT_MULTIPLIER = '\x01'
TRANSPORT_CLASS = '\xa3'
CONNECTION_PARAMETER = {
'PLC5': 0x4302,
'SLC500': 0x4302,
'CNET': 0x4320,
'DHP': 0x4302,
'Default': 0x43f8,
}
"""
Atomic Data Type:
Bit = Bool
Bit array = DWORD (32-bit boolean aray)
8-bit integer = SINT
16-bit integer = UINT
32-bit integer = DINT
32-bit float = REAL
64-bit integer = LINT
From Rockwell Automation Publication 1756-PM020C-EN-P November 2012:
When reading a BOOL tag, the values returned for 0 and 1 are 0 and 0xff, respectively.
"""
S_DATA_TYPE = {
'BOOL': 0xc1,
'SINT': 0xc2, # Signed 8-bit integer
'INT': 0xc3, # Signed 16-bit integer
'DINT': 0xc4, # Signed 32-bit integer
'LINT': 0xc5, # Signed 64-bit integer
'USINT': 0xc6, # Unsigned 8-bit integer
'UINT': 0xc7, # Unsigned 16-bit integer
'UDINT': 0xc8, # Unsigned 32-bit integer
'ULINT': 0xc9, # Unsigned 64-bit integer
'REAL': 0xca, # 32-bit floating point
'LREAL': 0xcb, # 64-bit floating point
'STIME': 0xcc, # Synchronous time
'DATE': 0xcd,
'TIME_OF_DAY': 0xce,
'DATE_AND_TIME': 0xcf,
'STRING': 0xd0, # character string (1 byte per character)
'BYTE': 0xd1, # byte string 8-bits
'WORD': 0xd2, # byte string 16-bits
'DWORD': 0xd3, # byte string 32-bits
'LWORD': 0xd4, # byte string 64-bits
'STRING2': 0xd5, # character string (2 byte per character)
'FTIME': 0xd6, # Duration high resolution
'LTIME': 0xd7, # Duration long
'ITIME': 0xd8, # Duration short
'STRINGN': 0xd9, # character string (n byte per character)
'SHORT_STRING': 0xda, # character string (1 byte per character, 1 byte length indicator)
'TIME': 0xdb, # Duration in milliseconds
'EPATH': 0xdc, # CIP Path segment
'ENGUNIT': 0xdd, # Engineering Units
'STRINGI': 0xde # International character string
}
I_DATA_TYPE = {
0xc1: 'BOOL',
0xc2: 'SINT', # Signed 8-bit integer
0xc3: 'INT', # Signed 16-bit integer
0xc4: 'DINT', # Signed 32-bit integer
0xc5: 'LINT', # Signed 64-bit integer
0xc6: 'USINT', # Unsigned 8-bit integer
0xc7: 'UINT', # Unsigned 16-bit integer
0xc8: 'UDINT', # Unsigned 32-bit integer
0xc9: 'ULINT', # Unsigned 64-bit integer
0xca: 'REAL', # 32-bit floating point
0xcb: 'LREAL', # 64-bit floating point
0xcc: 'STIME', # Synchronous time
0xcd: 'DATE',
0xce: 'TIME_OF_DAY',
0xcf: 'DATE_AND_TIME',
0xd0: 'STRING', # character string (1 byte per character)
0xd1: 'BYTE', # byte string 8-bits
0xd2: 'WORD', # byte string 16-bits
0xd3: 'DWORD', # byte string 32-bits
0xd4: 'LWORD', # byte string 64-bits
0xd5: 'STRING2', # character string (2 byte per character)
0xd6: 'FTIME', # Duration high resolution
0xd7: 'LTIME', # Duration long
0xd8: 'ITIME', # Duration short
0xd9: 'STRINGN', # character string (n byte per character)
0xda: 'SHORT_STRING', # character string (1 byte per character, 1 byte length indicator)
0xdb: 'TIME', # Duration in milliseconds
0xdc: 'EPATH', # CIP Path segment
0xdd: 'ENGUNIT', # Engineering Units
0xde: 'STRINGI' # International character string
}
REPLAY_INFO = {
0x4e: 'FORWARD_CLOSE (4E,00)',
0x52: 'UNCONNECTED_SEND (52,00)',
0x54: 'FORWARD_OPEN (54,00)',
0x6f: 'send_rr_data (6F,00)',
0x70: 'send_unit_data (70,00)',
0x00: 'nop',
0x01: 'list_targets',
0x04: 'list_services',
0x63: 'list_identity',
0x64: 'list_interfaces',
0x65: 'register_session',
0x66: 'unregister_session',
}
PCCC_DATA_TYPE = {
'N': '\x89',
'B': '\x85',
'T': '\x86',
'C': '\x87',
'S': '\x84',
'F': '\x8a',
'ST': '\x8d',
'A': '\x8e',
'R': '\x88',
'O': '\x8b',
'I': '\x8c'
}
PCCC_DATA_SIZE = {
'N': 2,
'B': 2,
'T': 6,
'C': 6,
'S': 2,
'F': 4,
'ST': 84,
'A': 2,
'R': 6,
'O': 2,
'I': 2
}
PCCC_CT = {
'PRE': 1,
'ACC': 2,
'EN': 15,
'TT': 14,
'DN': 13,
'CU': 15,
'CD': 14,
'OV': 12,
'UN': 11,
'UA': 10
}
PCCC_ERROR_CODE = {
-2: "Not Acknowledged (NAK)",
-3: "No Reponse, Check COM Settings",
-4: "Unknown Message from DataLink Layer",
-5: "Invalid Address",
-6: "Could Not Open Com Port",
-7: "No data specified to data link layer",
-8: "No data returned from PLC",
-20: "No Data Returned",
16: "Illegal Command or Format, Address may not exist or not enough elements in data file",
32: "PLC Has a Problem and Will Not Communicate",
48: "Remote Node Host is Missing, Disconnected, or Shut Down",
64: "Host Could Not Complete Function Due To Hardware Fault",
80: "Addressing problem or Memory Protect Rungs",
96: "Function not allows due to command protection selection",
112: "Processor is in Program mode",
128: "Compatibility mode file missing or communication zone problem",
144: "Remote node cannot buffer command",
240: "Error code in EXT STS Byte"
}

View File

@@ -1,32 +0,0 @@
__author__ = 'Agostino Ruscito'
__version__ = "1.0.7"
__date__ = "08 03 2015"
import logging
logging.basicConfig(
filename="pycomm.log",
filemode='w',
level=logging.INFO,
format="%(name)-13s %(levelname)-10s %(asctime)s %(message)s",
# propagate=0,
)
LOGGER = logging.getLogger('pycomm')
class PycommError(Exception):
pass
def setup_logger(name, level, filename=None):
log = logging.getLogger('pycomm.'+name)
log.setLevel(level)
if filename:
fh = logging.FileHandler(filename, mode='w')
fh.setFormatter(logging.Formatter("%(levelname)-10s %(asctime)s %(message)s"))
log.addHandler(fh)
log.propagate = False
return log

View File

@@ -1,16 +0,0 @@
[MODIF]
[RESULT]
ON_LINE=N
TBL_CONF=Y
CRC_ORG=0x0
CRC_OLD=
CRC_NEW=0xA984E7E
DAT_ORG=0
DAT_OLD=0
DAT_NEW=1464970528
VER_ORG=0
VER_OLD=0
VER_NEW=74
CRC_ALL_OLD=
CRC_ALL_NEW=0xF554CD74