Working on POC-108. Reading holding registers confirmed working
This commit is contained in:
BIN
Modbus Map.xlsx
Normal file
BIN
Modbus Map.xlsx
Normal file
Binary file not shown.
6
README.md
Normal file
6
README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Modbus Register Map
|
||||
|
||||
## Coils
|
||||
|
||||
Reg. # | Description | Access |
|
||||
1 |
|
||||
149
analog.json
Normal file
149
analog.json
Normal file
@@ -0,0 +1,149 @@
|
||||
[
|
||||
{"tag_name": "_Firmware_Rev", "register_type": "ir", "register_number": 1, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "_Program_Firmware", "register_type": "ir", "register_number": 6, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[1].Card_Type", "register_type": "ir", "register_number": 11, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[1].Downhole_AdjustedGrossStroke", "register_type": "ir", "register_number": 16, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[1].Downhole_FluidLoad", "register_type": "ir", "register_number": 21, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[1].Downhole_GrossStroke", "register_type": "ir", "register_number": 26, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[1].Downhole_Max_Load.Load", "register_type": "ir", "register_number": 31, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[1].Downhole_Max_Position.Position", "register_type": "ir", "register_number": 36, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[1].Downhole_Min_Load.Load", "register_type": "ir", "register_number": 41, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[1].Downhole_Min_Position.Position", "register_type": "ir", "register_number": 46, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[1].Downhole_NetStroke", "register_type": "ir", "register_number": 51, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[1].Fillage_Percent", "register_type": "ir", "register_number": 56, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[1].Fluid_Above_Pump", "register_type": "ir", "register_number": 61, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[1].Fluid_Moved", "register_type": "ir", "register_number": 66, "scale_type": 0, "scale_multiplier": 10000},
|
||||
{"tag_name": "Card_Past[1].ID", "register_type": "ir", "register_number": 71, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[1].Num_Points", "register_type": "ir", "register_number": 76, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[1].Polished_Rod_HP", "register_type": "ir", "register_number": 81, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[1].Pump_HP", "register_type": "ir", "register_number": 86, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[1].Pump_Intake_Pressure", "register_type": "ir", "register_number": 91, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[1].SPM", "register_type": "ir", "register_number": 96, "scale_type": 0, "scale_multiplier": 1000},
|
||||
{"tag_name": "Card_Past[1].Surface_Max.Load", "register_type": "ir", "register_number": 101, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[1].Surface_Max.Position", "register_type": "ir", "register_number": 106, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[1].Surface_Min.Load", "register_type": "ir", "register_number": 111, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[1].Surface_Min.Position", "register_type": "ir", "register_number": 116, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[1].Surface_StrokeLength", "register_type": "ir", "register_number": 121, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[1].Tubing_Movement", "register_type": "ir", "register_number": 126, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[2].Card_Type", "register_type": "ir", "register_number": 131, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[2].Downhole_AdjustedGrossStroke", "register_type": "ir", "register_number": 136, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[2].Downhole_FluidLoad", "register_type": "ir", "register_number": 141, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[2].Downhole_GrossStroke", "register_type": "ir", "register_number": 146, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[2].Downhole_Max_Load.Load", "register_type": "ir", "register_number": 151, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[2].Downhole_Max_Position.Position", "register_type": "ir", "register_number": 156, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[2].Downhole_Min_Load.Load", "register_type": "ir", "register_number": 161, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[2].Downhole_Min_Position.Position", "register_type": "ir", "register_number": 166, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[2].Downhole_NetStroke", "register_type": "ir", "register_number": 171, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[2].Fillage_Percent", "register_type": "ir", "register_number": 176, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[2].Fluid_Above_Pump", "register_type": "ir", "register_number": 181, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[2].Fluid_Moved", "register_type": "ir", "register_number": 186, "scale_type": 0, "scale_multiplier": 10000},
|
||||
{"tag_name": "Card_Past[2].ID", "register_type": "ir", "register_number": 191, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[2].Num_Points", "register_type": "ir", "register_number": 196, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[2].Polished_Rod_HP", "register_type": "ir", "register_number": 201, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[2].Pump_HP", "register_type": "ir", "register_number": 206, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[2].Pump_Intake_Pressure", "register_type": "ir", "register_number": 211, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[2].SPM", "register_type": "ir", "register_number": 216, "scale_type": 0, "scale_multiplier": 1000},
|
||||
{"tag_name": "Card_Past[2].Surface_Max.Load", "register_type": "ir", "register_number": 221, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[2].Surface_Max.Position", "register_type": "ir", "register_number": 226, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[2].Surface_Min.Load", "register_type": "ir", "register_number": 231, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[2].Surface_Min.Position", "register_type": "ir", "register_number": 236, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[2].Surface_StrokeLength", "register_type": "ir", "register_number": 241, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[2].Tubing_Movement", "register_type": "ir", "register_number": 246, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[3].Card_Type", "register_type": "ir", "register_number": 251, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[3].Downhole_AdjustedGrossStroke", "register_type": "ir", "register_number": 256, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[3].Downhole_FluidLoad", "register_type": "ir", "register_number": 261, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[3].Downhole_GrossStroke", "register_type": "ir", "register_number": 266, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[3].Downhole_Max_Load.Load", "register_type": "ir", "register_number": 271, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[3].Downhole_Max_Position.Position", "register_type": "ir", "register_number": 276, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[3].Downhole_Min_Load.Load", "register_type": "ir", "register_number": 281, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[3].Downhole_Min_Position.Position", "register_type": "ir", "register_number": 286, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[3].Downhole_NetStroke", "register_type": "ir", "register_number": 291, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[3].Fillage_Percent", "register_type": "ir", "register_number": 296, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[3].Fluid_Above_Pump", "register_type": "ir", "register_number": 301, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[3].Fluid_Moved", "register_type": "ir", "register_number": 306, "scale_type": 0, "scale_multiplier": 10000},
|
||||
{"tag_name": "Card_Past[3].ID", "register_type": "ir", "register_number": 311, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[3].Num_Points", "register_type": "ir", "register_number": 316, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[3].Polished_Rod_HP", "register_type": "ir", "register_number": 321, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[3].Pump_HP", "register_type": "ir", "register_number": 326, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[3].Pump_Intake_Pressure", "register_type": "ir", "register_number": 331, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[3].SPM", "register_type": "ir", "register_number": 336, "scale_type": 0, "scale_multiplier": 1000},
|
||||
{"tag_name": "Card_Past[3].Surface_Max.Load", "register_type": "ir", "register_number": 341, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[3].Surface_Max.Position", "register_type": "ir", "register_number": 346, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[3].Surface_Min.Load", "register_type": "ir", "register_number": 351, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[3].Surface_Min.Position", "register_type": "ir", "register_number": 356, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[3].Surface_StrokeLength", "register_type": "ir", "register_number": 361, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[3].Tubing_Movement", "register_type": "ir", "register_number": 366, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[4].Card_Type", "register_type": "ir", "register_number": 371, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[4].Downhole_AdjustedGrossStroke", "register_type": "ir", "register_number": 376, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[4].Downhole_FluidLoad", "register_type": "ir", "register_number": 381, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[4].Downhole_GrossStroke", "register_type": "ir", "register_number": 386, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[4].Downhole_Max_Load.Load", "register_type": "ir", "register_number": 391, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[4].Downhole_Max_Position.Position", "register_type": "ir", "register_number": 396, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[4].Downhole_Min_Load.Load", "register_type": "ir", "register_number": 401, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[4].Downhole_Min_Position.Position", "register_type": "ir", "register_number": 406, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[4].Downhole_NetStroke", "register_type": "ir", "register_number": 411, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[4].Fillage_Percent", "register_type": "ir", "register_number": 416, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[4].Fluid_Above_Pump", "register_type": "ir", "register_number": 421, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[4].Fluid_Moved", "register_type": "ir", "register_number": 426, "scale_type": 0, "scale_multiplier": 10000},
|
||||
{"tag_name": "Card_Past[4].ID", "register_type": "ir", "register_number": 431, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[4].Num_Points", "register_type": "ir", "register_number": 436, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[4].Polished_Rod_HP", "register_type": "ir", "register_number": 441, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[4].Pump_HP", "register_type": "ir", "register_number": 446, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[4].Pump_Intake_Pressure", "register_type": "ir", "register_number": 451, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[4].SPM", "register_type": "ir", "register_number": 456, "scale_type": 0, "scale_multiplier": 1000},
|
||||
{"tag_name": "Card_Past[4].Surface_Max.Load", "register_type": "ir", "register_number": 461, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[4].Surface_Max.Position", "register_type": "ir", "register_number": 466, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[4].Surface_Min.Load", "register_type": "ir", "register_number": 471, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Card_Past[4].Surface_Min.Position", "register_type": "ir", "register_number": 476, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[4].Surface_StrokeLength", "register_type": "ir", "register_number": 481, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Card_Past[4].Tubing_Movement", "register_type": "ir", "register_number": 486, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Drive_Speed_Reference_SP", "register_type": "ir", "register_number": 491, "scale_type": 0, "scale_multiplier": 10},
|
||||
{"tag_name": "Drive_Torque_Percent", "register_type": "ir", "register_number": 496, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "GAUGEOFF_Average_SPM", "register_type": "ir", "register_number": 501, "scale_type": 0, "scale_multiplier": 1000},
|
||||
{"tag_name": "GAUGEOFF_Downhole_GrossStroke", "register_type": "ir", "register_number": 506, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "GAUGEOFF_Downhole_NetStroke", "register_type": "ir", "register_number": 511, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "GAUGEOFF_Electricity_Cost", "register_type": "ir", "register_number": 516, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "GAUGEOFF_Fluid_Above_Pump", "register_type": "ir", "register_number": 521, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "GAUGEOFF_Inflow_Rate", "register_type": "ir", "register_number": 526, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "GAUGEOFF_kWh", "register_type": "ir", "register_number": 531, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "GAUGEOFF_kWh_Regen", "register_type": "ir", "register_number": 536, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "GAUGEOFF_Lifting_Cost", "register_type": "ir", "register_number": 541, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "GAUGEOFF_Max_Load", "register_type": "ir", "register_number": 546, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "GAUGEOFF_Min_Load", "register_type": "ir", "register_number": 551, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "GAUGEOFF_Percent_Run", "register_type": "ir", "register_number": 556, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "GAUGEOFF_Polished_Rod_HP", "register_type": "ir", "register_number": 561, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "GAUGEOFF_Pump_Intake_Pressure", "register_type": "ir", "register_number": 566, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "GAUGEOFF_Surface_StrokeLength", "register_type": "ir", "register_number": 571, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "GAUGEOFF_Tubing_Movement", "register_type": "ir", "register_number": 576, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Gearbox_Loading", "register_type": "ir", "register_number": 581, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Gearbox_Torque", "register_type": "ir", "register_number": 586, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Input_Analog_1_AIN.Val", "register_type": "ir", "register_number": 591, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Input_Analog_2_AIN.Val", "register_type": "ir", "register_number": 596, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Input_Analog_3_AIN.Val", "register_type": "ir", "register_number": 601, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Instantaneous_SPM", "register_type": "ir", "register_number": 606, "scale_type": 0, "scale_multiplier": 10},
|
||||
{"tag_name": "kWh_Today", "register_type": "ir", "register_number": 611, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Max_Theoretical_Fluid_Load", "register_type": "ir", "register_number": 616, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Motor_Torque", "register_type": "ir", "register_number": 621, "scale_type": 0, "scale_multiplier": 100},
|
||||
|
||||
{"tag_name": "_dt", "register_type": "hr", "register_number": 1, "scale_type": 0, "scale_multiplier": 1000},
|
||||
{"tag_name": "Casing_ID", "register_type": "hr", "register_number": 6, "scale_type": 0, "scale_multiplier": 1000},
|
||||
{"tag_name": "Drive_Start_Speed", "register_type": "hr", "register_number": 11, "scale_type": 0, "scale_multiplier": 10},
|
||||
{"tag_name": "Electricity_Cost", "register_type": "hr", "register_number": 16, "scale_type": 0, "scale_multiplier": 1000},
|
||||
{"tag_name": "Estimated_Tubing_Movement", "register_type": "hr", "register_number": 21, "scale_type": 0, "scale_multiplier": 100},
|
||||
{"tag_name": "Fluid_Gradient", "register_type": "hr", "register_number": 26, "scale_type": 0, "scale_multiplier": 1000},
|
||||
{"tag_name": "Friction", "register_type": "hr", "register_number": 31, "scale_type": 0, "scale_multiplier": 10},
|
||||
{"tag_name": "Gauge_Off_Time.Hour", "register_type": "hr", "register_number": 36, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Gauge_Off_Time.Min", "register_type": "hr", "register_number": 41, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Input_Analog_1_AIN.Cfg_PVEUMax", "register_type": "hr", "register_number": 46, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Input_Analog_1_AIN.Cfg_PVEUMin", "register_type": "hr", "register_number": 51, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Input_Analog_2_AIN.Cfg_PVEUMax", "register_type": "hr", "register_number": 56, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Input_Analog_2_AIN.Cfg_PVEUMin", "register_type": "hr", "register_number": 61, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Input_Analog_3_AIN.Cfg_PVEUMax", "register_type": "hr", "register_number": 66, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Input_Analog_3_AIN.Cfg_PVEUMin", "register_type": "hr", "register_number": 71, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Input_Inclinometer_AIN.Cfg_PVEUMax", "register_type": "hr", "register_number": 76, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Input_Inclinometer_AIN.Cfg_PVEUMin", "register_type": "hr", "register_number": 81, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Input_LoadCell_AIN.Cfg_PVEUMax", "register_type": "hr", "register_number": 86, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "Input_LoadCell_AIN.Cfg_PVEUMin", "register_type": "hr", "register_number": 91, "scale_type": 0, "scale_multiplier": 1},
|
||||
{"tag_name": "K_Factor", "register_type": "hr", "register_number": 96, "scale_type": 0, "scale_multiplier": 1000},
|
||||
{"tag_name": "Min_Fluid_Load_Shutdown_Setpoint", "register_type": "hr", "register_number": 101, "scale_type": 0, "scale_multiplier": 1}
|
||||
]
|
||||
4
arraylist.json
Normal file
4
arraylist.json
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
[
|
||||
|
||||
]
|
||||
31
digital.json
Normal file
31
digital.json
Normal file
@@ -0,0 +1,31 @@
|
||||
[
|
||||
{"tag_name": "_TOC_ACCEPTED", "register_type": "co", "register_number": 1},
|
||||
{"tag_name": "Autotune_Next_Start", "register_type": "co", "register_number": 2},
|
||||
{"tag_name": "Gas_Interference_Override_Enabled", "register_type": "co", "register_number": 3},
|
||||
{"tag_name": "Gauge_Off_Manual", "register_type": "co", "register_number": 4},
|
||||
{"tag_name": "Initialize", "register_type": "co", "register_number": 5},
|
||||
{"tag_name": "Input_Analog_1.Channel", "register_type": "co", "register_number": 6},
|
||||
{"tag_name": "Input_Analog_1.Enabled", "register_type": "co", "register_number": 7},
|
||||
{"tag_name": "Input_Analog_1.Type", "register_type": "co", "register_number": 8},
|
||||
{"tag_name": "Input_Analog_2.Channel", "register_type": "co", "register_number": 9},
|
||||
{"tag_name": "Input_Analog_2.Enabled", "register_type": "co", "register_number": 10},
|
||||
{"tag_name": "Input_Analog_2.Type", "register_type": "co", "register_number": 11},
|
||||
{"tag_name": "Input_Analog_3.Channel", "register_type": "co", "register_number": 12},
|
||||
{"tag_name": "Input_Analog_3.Enabled", "register_type": "co", "register_number": 13},
|
||||
{"tag_name": "Input_Analog_3.Type", "register_type": "co", "register_number": 14},
|
||||
{"tag_name": "Input_Inclinometer_Calibrate", "register_type": "co", "register_number": 15},
|
||||
{"tag_name": "Input_Inclinometer.Channel", "register_type": "co", "register_number": 16},
|
||||
{"tag_name": "Input_Inclinometer.Enabled", "register_type": "co", "register_number": 17},
|
||||
{"tag_name": "Input_Inclinometer.Type", "register_type": "co", "register_number": 18},
|
||||
{"tag_name": "Input_LoadCell.Channel", "register_type": "co", "register_number": 19},
|
||||
{"tag_name": "Input_LoadCell.Enabled", "register_type": "co", "register_number": 20},
|
||||
{"tag_name": "Input_LoadCell.Type", "register_type": "co", "register_number": 21},
|
||||
{"tag_name": "Min_Fluid_Load_Shutdown_Enabled", "register_type": "co", "register_number": 22},
|
||||
{"tag_name": "Restart_After_Fault_Allowed", "register_type": "co", "register_number": 23},
|
||||
{"tag_name": "Update_Tapers", "register_type": "co", "register_number": 24},
|
||||
{"tag_name": "USE_WIRELESS_LOADCELL", "register_type": "co", "register_number": 25},
|
||||
{"tag_name": "Write_Mode_Data", "register_type": "co", "register_number": 26},
|
||||
{"tag_name": "Write_Setup_Data", "register_type": "co", "register_number": 27},
|
||||
{"tag_name": "Inclinometer_Calibrating", "register_type": "di", "register_number": 1},
|
||||
{"tag_name": "Inclinometer_Stale", "register_type": "di", "register_number": 2}
|
||||
]
|
||||
90
plc_to_mongo.py
Normal file
90
plc_to_mongo.py
Normal file
@@ -0,0 +1,90 @@
|
||||
import pymongo
|
||||
import json
|
||||
from time import sleep
|
||||
from time import time as now
|
||||
from pymongo import MongoClient
|
||||
import pycomm_helper.utils as plc
|
||||
|
||||
PLC_IP_ADDRESS = '10.20.4.7'
|
||||
|
||||
|
||||
def main():
|
||||
client = MongoClient()
|
||||
db = client.tag_data
|
||||
|
||||
tag_vals = db.tag_vals
|
||||
print("THERE ARE ALREADY {} VALUES IN tag_vals".format(tag_vals.count()))
|
||||
with open('analog.json', 'rb') as analogfile:
|
||||
analog_list = json.loads(analogfile.read())
|
||||
|
||||
with open('digital.json', 'rb') as digitalfile:
|
||||
digital_list = json.loads(digitalfile.read())
|
||||
|
||||
with open('arraylist.json', 'rb') as arrayfile:
|
||||
arr_list = [] # json.loads(arrayfile.read())
|
||||
|
||||
for entry in analog_list + digital_list + arr_list:
|
||||
if tag_vals.find({'tag_name': entry['tag_name']}).count() < 1:
|
||||
tag_vals.insert(entry)
|
||||
print("NOW THERE ARE {} VALUES IN tag_vals".format(tag_vals.count()))
|
||||
|
||||
while True:
|
||||
for t in analog_list:
|
||||
try:
|
||||
plc_val = plc.readTag(PLC_IP_ADDRESS, t['tag_name'])
|
||||
if plc_val:
|
||||
t['tag_type'] = plc_val[1]
|
||||
t['val_actual'] = plc_val[0]
|
||||
t['timestamp'] = now()
|
||||
if int(t['scale_type']) == 0:
|
||||
t['val'] = int(plc_val[0] * t['scale_multiplier'])
|
||||
else:
|
||||
t['val'] = int(plc_val[0] / t['scale_multiplier'])
|
||||
tag_vals.update({'tag_name': t['tag_name']}, t)
|
||||
print("Updated: {}".format(tag_vals.find({'tag_name': t['tag_name']})[0]))
|
||||
except Exception as e:
|
||||
print("[ERROR] {} - {}".format(t['tag_name'], e))
|
||||
|
||||
for t in digital_list:
|
||||
try:
|
||||
plc_val = plc.readTag(PLC_IP_ADDRESS, t['tag_name'])
|
||||
if plc_val:
|
||||
t['tag_type'] = plc_val[1]
|
||||
t['val'] = plc_val[0]
|
||||
t['timestamp'] = now()
|
||||
tag_vals.update({'tag_name': t['tag_name']}, t)
|
||||
print("Updated: {}".format(tag_vals.find({'tag_name': t['tag_name']})[0]))
|
||||
except Exception as e:
|
||||
print("[ERROR] {} - {}".format(t['tag_name'], e))
|
||||
|
||||
for a in arr_list:
|
||||
try:
|
||||
plc_val = plc.readArray(PLC_IP_ADDRESS, str(a['tag_name']), int(a['length']))
|
||||
if plc_val:
|
||||
a['val'] = plc_val
|
||||
a['tag_type'] = 'ARRAY'
|
||||
t['timestamp'] = now()
|
||||
tag_vals.update({'tag_name': a['tag_name']}, a)
|
||||
print("Updated: {}".format(tag_vals.find({'tag_name': a['tag_name']})[0]))
|
||||
except Exception as e:
|
||||
print("[ERROR] {} - {}".format(a['tag_name'], e))
|
||||
|
||||
sleep(5)
|
||||
|
||||
|
||||
def purge():
|
||||
client = MongoClient()
|
||||
db = client.tag_data
|
||||
|
||||
tag_vals = db.tag_vals
|
||||
tag_vals.delete_many({})
|
||||
print("THERE ARE {} VALUES IN tag_vals".format(tag_vals.count()))
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
if len(sys.argv) > 1:
|
||||
if sys.argv[1] == 'purge':
|
||||
print("Purging...")
|
||||
purge()
|
||||
else:
|
||||
main()
|
||||
@@ -1,85 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
'''
|
||||
Pymodbus Server With Updating Thread
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
This is an example of having a background thread updating the
|
||||
context while the server is operating. This can also be done with
|
||||
a python thread::
|
||||
|
||||
from threading import Thread
|
||||
|
||||
thread = Thread(target=updating_writer, args=(context,))
|
||||
thread.start()
|
||||
'''
|
||||
# ---------------------------------------------------------------------------#
|
||||
# import the modbus libraries we need
|
||||
# ---------------------------------------------------------------------------#
|
||||
from pymodbus.server.async import StartTcpServer
|
||||
from pymodbus.device import ModbusDeviceIdentification
|
||||
from pymodbus.datastore import ModbusSequentialDataBlock
|
||||
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
|
||||
# from pymodbus.transaction import ModbusRtuFramer, ModbusAsciiFramer
|
||||
|
||||
# ---------------------------------------------------------------------------#
|
||||
# import the twisted libraries we need
|
||||
# ---------------------------------------------------------------------------#
|
||||
from twisted.internet.task import LoopingCall
|
||||
|
||||
# ---------------------------------------------------------------------------#
|
||||
# configure the service logging
|
||||
# ---------------------------------------------------------------------------#
|
||||
import logging
|
||||
logging.basicConfig()
|
||||
log = logging.getLogger()
|
||||
log.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------#
|
||||
# define your callback process
|
||||
# ---------------------------------------------------------------------------#
|
||||
def updating_writer(a):
|
||||
''' A worker process that runs every so often and
|
||||
updates live values of the context. It should be noted
|
||||
that there is a race condition for the update.
|
||||
|
||||
:param arguments: The input arguments to the call
|
||||
'''
|
||||
log.debug("updating the context")
|
||||
context = a[0]
|
||||
register = 3
|
||||
slave_id = 0x00
|
||||
address = 0x10
|
||||
values = context[slave_id].getValues(register, address, count=5)
|
||||
values = [v + 1 for v in values]
|
||||
log.debug("new values: " + str(values))
|
||||
context[slave_id].setValues(register, address, values)
|
||||
|
||||
# ---------------------------------------------------------------------------#
|
||||
# initialize your data store
|
||||
# ---------------------------------------------------------------------------#
|
||||
store = ModbusSlaveContext(
|
||||
di=ModbusSequentialDataBlock(0, [17]*100),
|
||||
co=ModbusSequentialDataBlock(0, [17]*100),
|
||||
hr=ModbusSequentialDataBlock(0, [17]*100),
|
||||
ir=ModbusSequentialDataBlock(0, [17]*100))
|
||||
context = ModbusServerContext(slaves=store, single=True)
|
||||
|
||||
# ---------------------------------------------------------------------------#
|
||||
# initialize the server information
|
||||
# ---------------------------------------------------------------------------#
|
||||
identity = ModbusDeviceIdentification()
|
||||
identity.VendorName = 'pymodbus'
|
||||
identity.ProductCode = 'PM'
|
||||
identity.VendorUrl = 'http://github.com/bashwork/pymodbus/'
|
||||
identity.ProductName = 'pymodbus Server'
|
||||
identity.ModelName = 'pymodbus Server'
|
||||
identity.MajorMinorRevision = '1.0'
|
||||
|
||||
# ---------------------------------------------------------------------------#
|
||||
# run the server you want
|
||||
# ---------------------------------------------------------------------------#
|
||||
time = 5 # 5 seconds delay
|
||||
loop = LoopingCall(f=updating_writer, a=(context,))
|
||||
loop.start(time, now=False) # initially delay by time
|
||||
StartTcpServer(context, identity=identity, address=("localhost", 5020))
|
||||
209
poc_to_modbus.py
Normal file
209
poc_to_modbus.py
Normal file
@@ -0,0 +1,209 @@
|
||||
#!/usr/bin/env python
|
||||
'''
|
||||
Pymodbus Server With Callbacks
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
This is an example of adding callbacks to a running modbus server
|
||||
when a value is written to it. In order for this to work, it needs
|
||||
a device-mapping file.
|
||||
'''
|
||||
# ---------------------------------------------------------------------------#
|
||||
# import the modbus libraries we need
|
||||
# ---------------------------------------------------------------------------#
|
||||
from pymodbus.server.async import StartTcpServer
|
||||
from pymodbus.device import ModbusDeviceIdentification
|
||||
from pymodbus.datastore import ModbusSparseDataBlock
|
||||
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
|
||||
from pymodbus.transaction import ModbusRtuFramer, ModbusAsciiFramer
|
||||
|
||||
# ---------------------------------------------------------------------------#
|
||||
# import the python libraries we need
|
||||
# ---------------------------------------------------------------------------#
|
||||
import pymongo
|
||||
from pymongo import MongoClient
|
||||
from pycomm_helper import utils as plc
|
||||
from time import time as now
|
||||
# ---------------------------------------------------------------------------#
|
||||
# configure the service logging
|
||||
# ---------------------------------------------------------------------------#
|
||||
import logging
|
||||
logging.basicConfig()
|
||||
log = logging.getLogger()
|
||||
log.setLevel(logging.DEBUG)
|
||||
|
||||
PLC_IP_ADDRESS = '10.20.4.7'
|
||||
|
||||
|
||||
def getTagsFromDB():
|
||||
client = MongoClient()
|
||||
db = client.tag_data
|
||||
tags = db.tag_vals
|
||||
print("Found {} tags in the database".format(tags.count()))
|
||||
di_tags_cur = tags.find({'register_type': 'di'})
|
||||
di_tags = list(di_tags_cur)
|
||||
di_tags_num = di_tags_cur.count()
|
||||
print("{} Digital Inputs".format(di_tags_num))
|
||||
|
||||
co_tags_cur = tags.find({'register_type': 'co'})
|
||||
co_tags = list(co_tags_cur)
|
||||
co_tags_num = co_tags_cur.count()
|
||||
print("{} Coils".format(co_tags_num))
|
||||
|
||||
ir_tags_cur = tags.find({'register_type': 'ir'})
|
||||
ir_tags = list(ir_tags_cur)
|
||||
ir_tags_num = ir_tags_cur.count()
|
||||
print("{} Input Registers".format(ir_tags_num))
|
||||
|
||||
hr_tags_cur = tags.find({'register_type': 'hr'})
|
||||
hr_tags = list(hr_tags_cur)
|
||||
hr_tags_num = hr_tags_cur.count()
|
||||
print("{} Holding Registers".format(hr_tags_num))
|
||||
|
||||
return {'di': di_tags, 'co': co_tags, 'ir': ir_tags, 'hr': hr_tags}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------#
|
||||
# create your custom data block with callbacks
|
||||
# ---------------------------------------------------------------------------#
|
||||
class DigitalTagDataBlock(ModbusSparseDataBlock):
|
||||
''' A datablock that stores the new value in memory
|
||||
and passes the operation to a message queue for further
|
||||
processing.
|
||||
'''
|
||||
|
||||
def __init__(self, register_type, tag_list):
|
||||
'''
|
||||
'''
|
||||
values = {}
|
||||
self.register_type = register_type
|
||||
|
||||
for t in tag_list:
|
||||
try:
|
||||
values[t['register_number']] = t['val']
|
||||
except KeyError:
|
||||
values[t['register_number']] = 911
|
||||
# print("Initialized DigitalTagDataBlock for {} with values {}".format(self.register_type, values))
|
||||
super(DigitalTagDataBlock, self).__init__(values)
|
||||
|
||||
def getValues(self, address, count=1):
|
||||
client = MongoClient()
|
||||
db = client.tag_data
|
||||
tags = db.tag_vals
|
||||
|
||||
if count > 1:
|
||||
for i in range(address, address + count):
|
||||
tag_found = tags.find_one({'register_number': i, 'register_type': self.register_type})
|
||||
print("{} = {}".format(tag_found['tag_name'], tag_found['val']))
|
||||
super(DigitalTagDataBlock, self).setValues(address, tag_found['val'])
|
||||
else:
|
||||
tag_found = tags.find_one({'register_number': address, 'register_type': self.register_type})
|
||||
print("{} = {}".format(tag_found['tag_name'], tag_found['val']))
|
||||
super(DigitalTagDataBlock, self).setValues(address, tag_found['val'])
|
||||
|
||||
return super(DigitalTagDataBlock, self).getValues(address, count=count)
|
||||
|
||||
def setValues(self, address, value):
|
||||
''' Sets the requested values of the datastore
|
||||
|
||||
:param address: The starting address
|
||||
:param values: The new values to be set
|
||||
'''
|
||||
client = MongoClient()
|
||||
db = client.tag_data
|
||||
tags = db.tag_vals
|
||||
tag_name = tags.find_one({'register_number': address, 'register_type': self.register_type})['tag_name']
|
||||
plc.writeTag(PLC_IP_ADDRESS, tag_name, value)
|
||||
|
||||
|
||||
class AnalogTagDataBlock(ModbusSparseDataBlock):
|
||||
''' A datablock that stores the new value in memory
|
||||
and passes the operation to a message queue for further
|
||||
processing.
|
||||
'''
|
||||
|
||||
def __init__(self, register_type, tag_list):
|
||||
'''
|
||||
'''
|
||||
values = {}
|
||||
self.register_type = register_type
|
||||
|
||||
for t in tag_list:
|
||||
try:
|
||||
values[t['register_number']] = t['val']
|
||||
values[t['register_number'] + 1] = t['scale_type']
|
||||
values[t['register_number'] + 2] = t['scale_multiplier']
|
||||
values[t['register_number'] + 3] = 0
|
||||
except KeyError:
|
||||
values[t['register_number']] = 911
|
||||
values[t['register_number'] + 1] = 2
|
||||
values[t['register_number'] + 2] = 0
|
||||
values[t['register_number'] + 3] = 0
|
||||
values[t['register_number'] + 4] = 123
|
||||
|
||||
# print("Initialized AnalogTagDataBlock for {} with values {}".format(self.register_type, values))
|
||||
super(AnalogTagDataBlock, self).__init__(values)
|
||||
|
||||
def getValues(self, address, count=1):
|
||||
client = MongoClient()
|
||||
db = client.tag_data
|
||||
tags = db.tag_vals
|
||||
|
||||
if count > 1:
|
||||
for i in range(address, address + count):
|
||||
tag_found = tags.find_one({'register_number': i, 'register_type': self.register_type})
|
||||
if tag_found:
|
||||
print("{} = {}".format(tag_found['tag_name'], tag_found['val']))
|
||||
super(AnalogTagDataBlock, self).setValues(address, tag_found['val'])
|
||||
super(AnalogTagDataBlock, self).setValues(address + 3, 0)
|
||||
else:
|
||||
tag_found = tags.find_one({'register_number': address, 'register_type': self.register_type})
|
||||
if tag_found:
|
||||
print("{} = {}".format(tag_found['tag_name'], tag_found['val']))
|
||||
super(AnalogTagDataBlock, self).setValues(address, tag_found['val'])
|
||||
super(AnalogTagDataBlock, self).setValues(address + 3, 0)
|
||||
|
||||
return super(AnalogTagDataBlock, self).getValues(address, count=count)
|
||||
|
||||
def setValues(self, address, value):
|
||||
''' Sets the requested values of the datastore
|
||||
|
||||
:param address: The starting address
|
||||
:param values: The new values to be set
|
||||
'''
|
||||
client = MongoClient()
|
||||
db = client.tag_data
|
||||
tags = db.tag_vals
|
||||
tag_name = tags.find_one({'register_number': address, 'register_type': self.register_type})['tag_name']
|
||||
plc.writeTag(PLC_IP_ADDRESS, tag_name, value)
|
||||
|
||||
|
||||
def main():
|
||||
# ---------------------------------------------------------------------------#
|
||||
# initialize your data store
|
||||
# ---------------------------------------------------------------------------#
|
||||
tags_in_db = getTagsFromDB()
|
||||
di_block = DigitalTagDataBlock('di', tags_in_db['di'])
|
||||
co_block = DigitalTagDataBlock('co', tags_in_db['co'])
|
||||
hr_block = AnalogTagDataBlock('hr', tags_in_db['hr'])
|
||||
ir_block = AnalogTagDataBlock('ir', tags_in_db['ir'])
|
||||
store = ModbusSlaveContext(di=di_block, co=co_block, hr=hr_block, ir=ir_block)
|
||||
context = ModbusServerContext(slaves=store, single=True)
|
||||
|
||||
# ---------------------------------------------------------------------------#
|
||||
# initialize the server information
|
||||
# ---------------------------------------------------------------------------#
|
||||
identity = ModbusDeviceIdentification()
|
||||
identity.VendorName = 'pymodbus'
|
||||
identity.ProductCode = 'PM'
|
||||
identity.VendorUrl = 'http://github.com/bashwork/pymodbus/'
|
||||
identity.ProductName = 'pymodbus Server'
|
||||
identity.ModelName = 'pymodbus Server'
|
||||
identity.MajorMinorRevision = '1.0'
|
||||
|
||||
# ---------------------------------------------------------------------------#
|
||||
# run the server you want
|
||||
# ---------------------------------------------------------------------------#
|
||||
StartTcpServer(context, identity=identity, address=("localhost", 5020))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
79
test.py
Normal file
79
test.py
Normal file
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env python
|
||||
'''
|
||||
Pymodbus Synchronous Client Examples
|
||||
--------------------------------------------------------------------------
|
||||
The following is an example of how to use the synchronous modbus client
|
||||
implementation from pymodbus.
|
||||
It should be noted that the client can also be used with
|
||||
the guard construct that is available in python 2.5 and up::
|
||||
with ModbusClient('127.0.0.1') as client:
|
||||
result = client.read_coils(1,10)
|
||||
print result
|
||||
'''
|
||||
# ---------------------------------------------------------------------------#
|
||||
# import the various server implementations
|
||||
# ---------------------------------------------------------------------------#
|
||||
from pymodbus.client.sync import ModbusTcpClient as ModbusClient
|
||||
# from pymodbus.client.sync import ModbusUdpClient as ModbusClient
|
||||
# from pymodbus.client.sync import ModbusSerialClient as ModbusClient
|
||||
|
||||
# ---------------------------------------------------------------------------#
|
||||
# configure the client logging
|
||||
# ---------------------------------------------------------------------------#
|
||||
import logging
|
||||
logging.basicConfig()
|
||||
log = logging.getLogger()
|
||||
log.setLevel(logging.INFO)
|
||||
# ---------------------------------------------------------------------------#
|
||||
# choose the client you want
|
||||
# ---------------------------------------------------------------------------#
|
||||
# make sure to start an implementation to hit against. For this
|
||||
# you can use an existing device, the reference implementation in the tools
|
||||
# directory, or start a pymodbus server.
|
||||
#
|
||||
# If you use the UDP or TCP clients, you can override the framer being used
|
||||
# to use a custom implementation (say RTU over TCP). By default they use the
|
||||
# socket framer::
|
||||
#
|
||||
# client = ModbusClient('localhost', port=5020, framer=ModbusRtuFramer)
|
||||
#
|
||||
# It should be noted that you can supply an ipv4 or an ipv6 host address for
|
||||
# both the UDP and TCP clients.
|
||||
#
|
||||
# There are also other options that can be set on the client that controls
|
||||
# how transactions are performed. The current ones are:
|
||||
#
|
||||
# * retries - Specify how many retries to allow per transaction (default = 3)
|
||||
# * retry_on_empty - Is an empty response a retry (default = False)
|
||||
# * source_address - Specifies the TCP source address to bind to
|
||||
#
|
||||
# Here is an example of using these options::
|
||||
#
|
||||
# client = ModbusClient('localhost', retries=3, retry_on_empty=True)
|
||||
# ---------------------------------------------------------------------------#
|
||||
client = ModbusClient('localhost', port=5020)
|
||||
# client = ModbusClient(method='ascii', port='/dev/pts/2', timeout=1)
|
||||
# client = ModbusClient(method='rtu', port='/dev/pts/2', timeout=1)
|
||||
client.connect()
|
||||
|
||||
# ---------------------------------------------------------------------------#
|
||||
# specify slave to query
|
||||
# ---------------------------------------------------------------------------#
|
||||
# The slave to query is specified in an optional parameter for each
|
||||
# individual request. This can be done by specifying the `unit` parameter
|
||||
# which defaults to `0x00`
|
||||
# ---------------------------------------------------------------------------#
|
||||
print("HOLDING REGISTERS")
|
||||
for i in range(0, 21):
|
||||
rd = client.read_holding_registers(i * 5, 5)
|
||||
print rd.registers
|
||||
|
||||
print("INPUT REGISTERS")
|
||||
for i in range(2, 125):
|
||||
rd = client.read_input_registers(i * 5, 5)
|
||||
print rd.registers
|
||||
|
||||
# ---------------------------------------------------------------------------#
|
||||
# close the client
|
||||
# ---------------------------------------------------------------------------#
|
||||
client.close()
|
||||
Reference in New Issue
Block a user