diff --git a/Modbus Map.xlsx b/Modbus Map.xlsx index 4818ce1..a50f72c 100644 Binary files a/Modbus Map.xlsx and b/Modbus Map.xlsx differ diff --git a/analog.json b/analog.json index 1864a69..15dd2f2 100644 --- a/analog.json +++ b/analog.json @@ -1,149 +1,159 @@ [ - {"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": "_Firmware_Rev", "register_type": "ir", "register_number": 1}, + {"tag_name": "_Program_Firmware", "register_type": "ir", "register_number": 2}, + {"tag_name": "Card_Past[1].Card_Type", "register_type": "ir", "register_number": 3}, + {"tag_name": "Card_Past[1].Downhole_AdjustedGrossStroke", "register_type": "ir", "register_number": 4}, + {"tag_name": "Card_Past[1].Downhole_FluidLoad", "register_type": "ir", "register_number": 6}, + {"tag_name": "Card_Past[1].Downhole_GrossStroke", "register_type": "ir", "register_number": 8}, + {"tag_name": "Card_Past[1].Downhole_Max_Load.Load", "register_type": "ir", "register_number": 10}, + {"tag_name": "Card_Past[1].Downhole_Max_Position.Position", "register_type": "ir", "register_number": 12}, + {"tag_name": "Card_Past[1].Downhole_Min_Load.Load", "register_type": "ir", "register_number": 14}, + {"tag_name": "Card_Past[1].Downhole_Min_Position.Position", "register_type": "ir", "register_number": 16}, + {"tag_name": "Card_Past[1].Downhole_NetStroke", "register_type": "ir", "register_number": 18}, + {"tag_name": "Card_Past[1].Fillage_Percent", "register_type": "ir", "register_number": 20}, + {"tag_name": "Card_Past[1].Fluid_Above_Pump", "register_type": "ir", "register_number": 22}, + {"tag_name": "Card_Past[1].Fluid_Moved", "register_type": "ir", "register_number": 24}, + {"tag_name": "Card_Past[1].ID", "register_type": "ir", "register_number": 26}, + {"tag_name": "Card_Past[1].Num_Points", "register_type": "ir", "register_number": 27}, + {"tag_name": "Card_Past[1].Polished_Rod_HP", "register_type": "ir", "register_number": 28}, + {"tag_name": "Card_Past[1].Pump_HP", "register_type": "ir", "register_number": 30}, + {"tag_name": "Card_Past[1].Pump_Intake_Pressure", "register_type": "ir", "register_number": 32}, + {"tag_name": "Card_Past[1].SPM", "register_type": "ir", "register_number": 34}, + {"tag_name": "Card_Past[1].Surface_Max.Load", "register_type": "ir", "register_number": 36}, + {"tag_name": "Card_Past[1].Surface_Max.Position", "register_type": "ir", "register_number": 38}, + {"tag_name": "Card_Past[1].Surface_Min.Load", "register_type": "ir", "register_number": 40}, + {"tag_name": "Card_Past[1].Surface_Min.Position", "register_type": "ir", "register_number": 42}, + {"tag_name": "Card_Past[1].Surface_StrokeLength", "register_type": "ir", "register_number": 44}, + {"tag_name": "Card_Past[1].Tubing_Movement", "register_type": "ir", "register_number": 46}, + {"tag_name": "Card_Past[2].Card_Type", "register_type": "ir", "register_number": 48}, + {"tag_name": "Card_Past[2].Downhole_AdjustedGrossStroke", "register_type": "ir", "register_number": 49}, + {"tag_name": "Card_Past[2].Downhole_FluidLoad", "register_type": "ir", "register_number": 51}, + {"tag_name": "Card_Past[2].Downhole_GrossStroke", "register_type": "ir", "register_number": 53}, + {"tag_name": "Card_Past[2].Downhole_Max_Load.Load", "register_type": "ir", "register_number": 55}, + {"tag_name": "Card_Past[2].Downhole_Max_Position.Position", "register_type": "ir", "register_number": 57}, + {"tag_name": "Card_Past[2].Downhole_Min_Load.Load", "register_type": "ir", "register_number": 59}, + {"tag_name": "Card_Past[2].Downhole_Min_Position.Position", "register_type": "ir", "register_number": 61}, + {"tag_name": "Card_Past[2].Downhole_NetStroke", "register_type": "ir", "register_number": 63}, + {"tag_name": "Card_Past[2].Fillage_Percent", "register_type": "ir", "register_number": 65}, + {"tag_name": "Card_Past[2].Fluid_Above_Pump", "register_type": "ir", "register_number": 67}, + {"tag_name": "Card_Past[2].Fluid_Moved", "register_type": "ir", "register_number": 69}, + {"tag_name": "Card_Past[2].ID", "register_type": "ir", "register_number": 71}, + {"tag_name": "Card_Past[2].Num_Points", "register_type": "ir", "register_number": 72}, + {"tag_name": "Card_Past[2].Polished_Rod_HP", "register_type": "ir", "register_number": 73}, + {"tag_name": "Card_Past[2].Pump_HP", "register_type": "ir", "register_number": 75}, + {"tag_name": "Card_Past[2].Pump_Intake_Pressure", "register_type": "ir", "register_number": 77}, + {"tag_name": "Card_Past[2].SPM", "register_type": "ir", "register_number": 79}, + {"tag_name": "Card_Past[2].Surface_Max.Load", "register_type": "ir", "register_number": 81}, + {"tag_name": "Card_Past[2].Surface_Max.Position", "register_type": "ir", "register_number": 83}, + {"tag_name": "Card_Past[2].Surface_Min.Load", "register_type": "ir", "register_number": 85}, + {"tag_name": "Card_Past[2].Surface_Min.Position", "register_type": "ir", "register_number": 87}, + {"tag_name": "Card_Past[2].Surface_StrokeLength", "register_type": "ir", "register_number": 89}, + {"tag_name": "Card_Past[2].Tubing_Movement", "register_type": "ir", "register_number": 91}, + {"tag_name": "Card_Past[3].Card_Type", "register_type": "ir", "register_number": 93}, + {"tag_name": "Card_Past[3].Downhole_AdjustedGrossStroke", "register_type": "ir", "register_number": 94}, + {"tag_name": "Card_Past[3].Downhole_FluidLoad", "register_type": "ir", "register_number": 96}, + {"tag_name": "Card_Past[3].Downhole_GrossStroke", "register_type": "ir", "register_number": 98}, + {"tag_name": "Card_Past[3].Downhole_Max_Load.Load", "register_type": "ir", "register_number": 100}, + {"tag_name": "Card_Past[3].Downhole_Max_Position.Position", "register_type": "ir", "register_number": 102}, + {"tag_name": "Card_Past[3].Downhole_Min_Load.Load", "register_type": "ir", "register_number": 104}, + {"tag_name": "Card_Past[3].Downhole_Min_Position.Position", "register_type": "ir", "register_number": 106}, + {"tag_name": "Card_Past[3].Downhole_NetStroke", "register_type": "ir", "register_number": 108}, + {"tag_name": "Card_Past[3].Fillage_Percent", "register_type": "ir", "register_number": 110}, + {"tag_name": "Card_Past[3].Fluid_Above_Pump", "register_type": "ir", "register_number": 112}, + {"tag_name": "Card_Past[3].Fluid_Moved", "register_type": "ir", "register_number": 114}, + {"tag_name": "Card_Past[3].ID", "register_type": "ir", "register_number": 116}, + {"tag_name": "Card_Past[3].Num_Points", "register_type": "ir", "register_number": 117}, + {"tag_name": "Card_Past[3].Polished_Rod_HP", "register_type": "ir", "register_number": 118}, + {"tag_name": "Card_Past[3].Pump_HP", "register_type": "ir", "register_number": 120}, + {"tag_name": "Card_Past[3].Pump_Intake_Pressure", "register_type": "ir", "register_number": 122}, + {"tag_name": "Card_Past[3].SPM", "register_type": "ir", "register_number": 124}, + {"tag_name": "Card_Past[3].Surface_Max.Load", "register_type": "ir", "register_number": 126}, + {"tag_name": "Card_Past[3].Surface_Max.Position", "register_type": "ir", "register_number": 128}, + {"tag_name": "Card_Past[3].Surface_Min.Load", "register_type": "ir", "register_number": 130}, + {"tag_name": "Card_Past[3].Surface_Min.Position", "register_type": "ir", "register_number": 132}, + {"tag_name": "Card_Past[3].Surface_StrokeLength", "register_type": "ir", "register_number": 134}, + {"tag_name": "Card_Past[3].Tubing_Movement", "register_type": "ir", "register_number": 136}, + {"tag_name": "Card_Past[4].Card_Type", "register_type": "ir", "register_number": 138}, + {"tag_name": "Card_Past[4].Downhole_AdjustedGrossStroke", "register_type": "ir", "register_number": 139}, + {"tag_name": "Card_Past[4].Downhole_FluidLoad", "register_type": "ir", "register_number": 141}, + {"tag_name": "Card_Past[4].Downhole_GrossStroke", "register_type": "ir", "register_number": 143}, + {"tag_name": "Card_Past[4].Downhole_Max_Load.Load", "register_type": "ir", "register_number": 145}, + {"tag_name": "Card_Past[4].Downhole_Max_Position.Position", "register_type": "ir", "register_number": 147}, + {"tag_name": "Card_Past[4].Downhole_Min_Load.Load", "register_type": "ir", "register_number": 149}, + {"tag_name": "Card_Past[4].Downhole_Min_Position.Position", "register_type": "ir", "register_number": 151}, + {"tag_name": "Card_Past[4].Downhole_NetStroke", "register_type": "ir", "register_number": 153}, + {"tag_name": "Card_Past[4].Fillage_Percent", "register_type": "ir", "register_number": 155}, + {"tag_name": "Card_Past[4].Fluid_Above_Pump", "register_type": "ir", "register_number": 157}, + {"tag_name": "Card_Past[4].Fluid_Moved", "register_type": "ir", "register_number": 159}, + {"tag_name": "Card_Past[4].ID", "register_type": "ir", "register_number": 161}, + {"tag_name": "Card_Past[4].Num_Points", "register_type": "ir", "register_number": 162}, + {"tag_name": "Card_Past[4].Polished_Rod_HP", "register_type": "ir", "register_number": 163}, + {"tag_name": "Card_Past[4].Pump_HP", "register_type": "ir", "register_number": 165}, + {"tag_name": "Card_Past[4].Pump_Intake_Pressure", "register_type": "ir", "register_number": 167}, + {"tag_name": "Card_Past[4].SPM", "register_type": "ir", "register_number": 169}, + {"tag_name": "Card_Past[4].Surface_Max.Load", "register_type": "ir", "register_number": 171}, + {"tag_name": "Card_Past[4].Surface_Max.Position", "register_type": "ir", "register_number": 173}, + {"tag_name": "Card_Past[4].Surface_Min.Load", "register_type": "ir", "register_number": 175}, + {"tag_name": "Card_Past[4].Surface_Min.Position", "register_type": "ir", "register_number": 177}, + {"tag_name": "Card_Past[4].Surface_StrokeLength", "register_type": "ir", "register_number": 179}, + {"tag_name": "Card_Past[4].Tubing_Movement", "register_type": "ir", "register_number": 181}, + {"tag_name": "Drive_Speed_Reference_SP", "register_type": "ir", "register_number": 183}, + {"tag_name": "Drive_Torque_Percent", "register_type": "ir", "register_number": 185}, + {"tag_name": "GAUGEOFF_Average_SPM", "register_type": "ir", "register_number": 187}, + {"tag_name": "GAUGEOFF_Downhole_GrossStroke", "register_type": "ir", "register_number": 189}, + {"tag_name": "GAUGEOFF_Downhole_NetStroke", "register_type": "ir", "register_number": 191}, + {"tag_name": "GAUGEOFF_Electricity_Cost", "register_type": "ir", "register_number": 193}, + {"tag_name": "GAUGEOFF_Fluid_Above_Pump", "register_type": "ir", "register_number": 195}, + {"tag_name": "GAUGEOFF_Inflow_Rate", "register_type": "ir", "register_number": 197}, + {"tag_name": "GAUGEOFF_kWh", "register_type": "ir", "register_number": 199}, + {"tag_name": "GAUGEOFF_kWh_Regen", "register_type": "ir", "register_number": 201}, + {"tag_name": "GAUGEOFF_Lifting_Cost", "register_type": "ir", "register_number": 203}, + {"tag_name": "GAUGEOFF_Max_Load", "register_type": "ir", "register_number": 205}, + {"tag_name": "GAUGEOFF_Min_Load", "register_type": "ir", "register_number": 207}, + {"tag_name": "GAUGEOFF_Percent_Run", "register_type": "ir", "register_number": 209}, + {"tag_name": "GAUGEOFF_Polished_Rod_HP", "register_type": "ir", "register_number": 211}, + {"tag_name": "GAUGEOFF_Pump_Intake_Pressure", "register_type": "ir", "register_number": 213}, + {"tag_name": "GAUGEOFF_Surface_StrokeLength", "register_type": "ir", "register_number": 215}, + {"tag_name": "GAUGEOFF_Tubing_Movement", "register_type": "ir", "register_number": 217}, + {"tag_name": "Gearbox_Loading", "register_type": "ir", "register_number": 219}, + {"tag_name": "Gearbox_Torque", "register_type": "ir", "register_number": 221}, + {"tag_name": "Input_Analog_1_AIN.Val", "register_type": "ir", "register_number": 223}, + {"tag_name": "Input_Analog_2_AIN.Val", "register_type": "ir", "register_number": 225}, + {"tag_name": "Input_Analog_3_AIN.Val", "register_type": "ir", "register_number": 227}, + {"tag_name": "Instantaneous_SPM", "register_type": "ir", "register_number": 229}, + {"tag_name": "kWh_Today", "register_type": "ir", "register_number": 231}, + {"tag_name": "Max_Theoretical_Fluid_Load", "register_type": "ir", "register_number": 233}, + {"tag_name": "Motor_Torque", "register_type": "ir", "register_number": 235}, - {"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} + {"tag_name": "_dt", "register_type": "hr", "register_number": 1}, + {"tag_name": "Casing_ID", "register_type": "hr", "register_number": 3}, + {"tag_name": "Drive_Start_Speed", "register_type": "hr", "register_number": 5}, + {"tag_name": "Electricity_Cost", "register_type": "hr", "register_number": 7}, + {"tag_name": "Estimated_Tubing_Movement", "register_type": "hr", "register_number": 9}, + {"tag_name": "Fluid_Gradient", "register_type": "hr", "register_number": 11}, + {"tag_name": "Friction", "register_type": "hr", "register_number": 13}, + {"tag_name": "Gauge_Off_Time.Hour", "register_type": "hr", "register_number": 15}, + {"tag_name": "Gauge_Off_Time.Min", "register_type": "hr", "register_number": 16}, + {"tag_name": "Input_Analog_1_AIN.Cfg_PVEUMax", "register_type": "hr", "register_number": 17}, + {"tag_name": "Input_Analog_1_AIN.Cfg_PVEUMin", "register_type": "hr", "register_number": 19}, + {"tag_name": "Input_Analog_2_AIN.Cfg_PVEUMax", "register_type": "hr", "register_number": 21}, + {"tag_name": "Input_Analog_2_AIN.Cfg_PVEUMin", "register_type": "hr", "register_number": 23}, + {"tag_name": "Input_Analog_3_AIN.Cfg_PVEUMax", "register_type": "hr", "register_number": 25}, + {"tag_name": "Input_Analog_3_AIN.Cfg_PVEUMin", "register_type": "hr", "register_number": 27}, + {"tag_name": "Input_Inclinometer_AIN.Cfg_PVEUMax", "register_type": "hr", "register_number": 29}, + {"tag_name": "Input_Inclinometer_AIN.Cfg_PVEUMin", "register_type": "hr", "register_number": 31}, + {"tag_name": "Input_LoadCell_AIN.Cfg_PVEUMax", "register_type": "hr", "register_number": 33}, + {"tag_name": "Input_LoadCell_AIN.Cfg_PVEUMin", "register_type": "hr", "register_number": 35}, + {"tag_name": "K_Factor", "register_type": "hr", "register_number": 37}, + {"tag_name": "Min_Fluid_Load_Shutdown_Setpoint", "register_type": "hr", "register_number": 39}, + {"tag_name": "Input_Analog_1.Channel", "register_type": "hr", "register_number": 41}, + {"tag_name": "Input_Analog_1.Type", "register_type": "hr", "register_number": 42}, + {"tag_name": "Input_Analog_2.Channel", "register_type": "hr", "register_number": 43}, + {"tag_name": "Input_Analog_2.Type", "register_type": "hr", "register_number": 44}, + {"tag_name": "Input_Analog_3.Channel", "register_type": "hr", "register_number": 45}, + {"tag_name": "Input_Analog_3.Type", "register_type": "hr", "register_number": 46}, + {"tag_name": "Input_Inclinometer.Channel", "register_type": "hr", "register_number": 47}, + {"tag_name": "Input_Inclinometer.Type", "register_type": "hr", "register_number": 48}, + {"tag_name": "Input_LoadCell.Channel", "register_type": "hr", "register_number": 49}, + {"tag_name": "Input_LoadCell.Type", "register_type": "hr", "register_number": 50} ] diff --git a/arraylist.json b/arraylist.json index 221a9a5..9151b5c 100644 --- a/arraylist.json +++ b/arraylist.json @@ -1,4 +1,19 @@ [ - + {"tag_name": "Card_Past[1].Surface_Position", "register_type": "ir", "register_number": 237, "arr_len": 750}, + {"tag_name": "Card_Past[2].Surface_Position", "register_type": "ir", "register_number": 1737, "arr_len": 750}, + {"tag_name": "Card_Past[3].Surface_Position", "register_type": "ir", "register_number": 3237, "arr_len": 750}, + {"tag_name": "Card_Past[4].Surface_Position", "register_type": "ir", "register_number": 4737, "arr_len": 750}, + {"tag_name": "Card_Past[1].Surface_Load", "register_type": "ir", "register_number": 6237, "arr_len": 750}, + {"tag_name": "Card_Past[2].Surface_Load", "register_type": "ir", "register_number": 7737, "arr_len": 750}, + {"tag_name": "Card_Past[3].Surface_Load", "register_type": "ir", "register_number": 9237, "arr_len": 750}, + {"tag_name": "Card_Past[4].Surface_Load", "register_type": "ir", "register_number": 10737, "arr_len": 750}, + {"tag_name": "Card_Past[1].Downhole_Position", "register_type": "ir", "register_number": 12237, "arr_len": 750}, + {"tag_name": "Card_Past[2].Downhole_Position", "register_type": "ir", "register_number": 13737, "arr_len": 750}, + {"tag_name": "Card_Past[3].Downhole_Position", "register_type": "ir", "register_number": 15237, "arr_len": 750}, + {"tag_name": "Card_Past[4].Downhole_Position", "register_type": "ir", "register_number": 16737, "arr_len": 750}, + {"tag_name": "Card_Past[1].Downhole_Load", "register_type": "ir", "register_number": 18237, "arr_len": 750}, + {"tag_name": "Card_Past[2].Downhole_Load", "register_type": "ir", "register_number": 19737, "arr_len": 750}, + {"tag_name": "Card_Past[3].Downhole_Load", "register_type": "ir", "register_number": 21237, "arr_len": 750}, + {"tag_name": "Card_Past[4].Downhole_Load", "register_type": "ir", "register_number": 22737, "arr_len": 750} ] diff --git a/digital.json b/digital.json index 3d1232d..2acee8e 100644 --- a/digital.json +++ b/digital.json @@ -4,28 +4,18 @@ {"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": "Input_Analog_1.Enabled", "register_type": "co", "register_number": 6}, + {"tag_name": "Input_Analog_2.Enabled", "register_type": "co", "register_number": 7}, + {"tag_name": "Input_Analog_3.Enabled", "register_type": "co", "register_number": 8}, + {"tag_name": "Input_Inclinometer_Calibrate", "register_type": "co", "register_number": 9}, + {"tag_name": "Input_Inclinometer.Enabled", "register_type": "co", "register_number": 10}, + {"tag_name": "Input_LoadCell.Enabled", "register_type": "co", "register_number": 11}, + {"tag_name": "Min_Fluid_Load_Shutdown_Enabled", "register_type": "co", "register_number": 12}, + {"tag_name": "Restart_After_Fault_Allowed", "register_type": "co", "register_number": 13}, + {"tag_name": "Update_Tapers", "register_type": "co", "register_number": 14}, + {"tag_name": "USE_WIRELESS_LOADCELL", "register_type": "co", "register_number": 15}, + {"tag_name": "Write_Mode_Data", "register_type": "co", "register_number": 16}, + {"tag_name": "Write_Setup_Data", "register_type": "co", "register_number": 17}, {"tag_name": "Inclinometer_Calibrating", "register_type": "di", "register_number": 1}, {"tag_name": "Inclinometer_Stale", "register_type": "di", "register_number": 2} ] diff --git a/plc_to_mongo.py b/plc_to_mongo.py index 8b5ad50..325dc74 100644 --- a/plc_to_mongo.py +++ b/plc_to_mongo.py @@ -21,7 +21,7 @@ def main(): digital_list = json.loads(digitalfile.read()) with open('arraylist.json', 'rb') as arrayfile: - arr_list = [] # json.loads(arrayfile.read()) + 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: @@ -34,14 +34,10 @@ def main(): 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['val'] = 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])) + print("Updated: {} - {}".format(t['tag_name'], t['val'])) except Exception as e: print("[ERROR] {} - {}".format(t['tag_name'], e)) @@ -53,19 +49,19 @@ def main(): 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])) + print("Updated: {} - {}".format(t['tag_name'], t['val'])) 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'])) + plc_val = plc.readArray(PLC_IP_ADDRESS, str(a['tag_name']), int(a['arr_len'])) 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])) + print("Updated: {} - {}".format(a['tag_name'], a['val'])) except Exception as e: print("[ERROR] {} - {}".format(a['tag_name'], e)) diff --git a/poc_to_modbus.py b/poc_to_modbus.py index 0b0b322..4fbd434 100644 --- a/poc_to_modbus.py +++ b/poc_to_modbus.py @@ -1,11 +1,9 @@ #!/usr/bin/env python ''' -Pymodbus Server With Callbacks +Pymodbus Server from MongoDB -------------------------------------------------------------------------- -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. +This program takes the values in a mongo database and exposes them over Modbus/TCP ''' # ---------------------------------------------------------------------------# # import the modbus libraries we need @@ -15,7 +13,6 @@ from pymodbus.device import ModbusDeviceIdentification from pymodbus.datastore import ModbusSparseDataBlock from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext from pymodbus.transaction import ModbusRtuFramer, ModbusAsciiFramer -from pymodbus.payload import BinaryPayloadBuilder from pymodbus.constants import Endian # ---------------------------------------------------------------------------# @@ -25,20 +22,34 @@ import pymongo from pymongo import MongoClient from pycomm_helper import utils as plc from time import time as now +import struct # ---------------------------------------------------------------------------# # configure the service logging # ---------------------------------------------------------------------------# import logging logging.basicConfig() log = logging.getLogger() -log.setLevel(logging.DEBUG) +log.setLevel(logging.INFO) PLC_IP_ADDRESS = '10.20.4.7' -# ---------------------------------------------------------------------------# -# Datatype Mapping -# ---------------------------------------------------------------------------# +def float_to_bytes(float_val): + ''' + Converts a float to little-endian bytes + ''' + packed_string = struct.pack('f', float_val) + unpacked_list = list(struct.unpack('HH', packed_string)) + return unpacked_list + + +def integer_to_byte(integer_val): + ''' + Converts an integer to its byte + ''' + packed_string = struct.pack('h', integer_val) + unpacked = list(struct.unpack('H', packed_string)) + return unpacked def getTagsFromDB(): @@ -93,19 +104,14 @@ class DigitalTagDataBlock(ModbusSparseDataBlock): 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']) + # client = MongoClient() + # db = client.tag_data + # tags = db.tag_vals + # + # 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']) return super(DigitalTagDataBlock, self).getValues(address, count=count) @@ -133,50 +139,56 @@ class AnalogTagDataBlock(ModbusSparseDataBlock): ''' values = {} self.register_type = register_type - register_values = {} + register_values = [] for t in tag_list: - builder = BinaryPayloadBuilder(endian=Endian.Little) try: - if t['tag_type'] == 'SINT': - builder.add_8bit_int(t['val_actual']) - elif t['tag_type'][:3] == 'INT': - builder.add_16bit_int(t['val_actual']) + if t['tag_type'][-3:] == 'INT': + register_values.append({"r_num": t['register_number'], "r_vals": integer_to_byte(t['val'])}) elif t['tag_type'] == 'REAL': - builder.add_32bit_float(t['val_actual']) - - register_values[t['register_number']] = builder.to_registers + register_values.append({"r_num": t['register_number'], "r_vals": float_to_bytes(t['val'])}) + elif t['tag_type'] == 'ARRAY': + arr_vals = [] + for i in range(0, len(t['val'])): + arr_vals = arr_vals + float_to_bytes(t['val'][i]) + register_values.append({"r_num": t['register_number'], "r_vals": arr_vals}) except KeyError: - register_values[t['register_number']] = [] print("No value for register #{} - {}".format(t['register_number'], t['tag_name'])) - + register_values.sort(key=lambda x: x['r_num']) + values = [0] + for x in register_values: + values = values + x['r_vals'] - # 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: + try: for i in range(address, address + count): tag_found = tags.find_one({'register_number': i, 'register_type': self.register_type}) + val_registers = [] if tag_found: + if tag_found['tag_type'][-3:] == 'INT': + val_registers = integer_to_byte(tag_found['val']) + elif tag_found['tag_type'] == 'REAL': + val_registers = float_to_bytes(tag_found['val']) + elif tag_found['tag_type'] == 'ARRAY': + val_registers = [] + for k in range(0, len(tag_found['val'])): + val_registers = val_registers + float_to_bytes(tag_found['val'][k]) + for j in range(0, len(val_registers)): + super(AnalogTagDataBlock, self).setValues(i + j, val_registers[j]) 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) + except Exception as e: + print(e) return super(AnalogTagDataBlock, self).getValues(address, count=count) def setValues(self, address, value): - ''' Sets the requested values of the datastore + ''' + Sets the requested values of the datastore :param address: The starting address :param values: The new values to be set diff --git a/test.py b/test.py index a412199..556e384 100644 --- a/test.py +++ b/test.py @@ -10,6 +10,7 @@ from pymodbus.client.sync import ModbusTcpClient as ModbusClient # ---------------------------------------------------------------------------# from pymongo import MongoClient import unittest +import struct # ---------------------------------------------------------------------------# # configure the client logging @@ -44,44 +45,65 @@ def close_enough(a, b): return False +def lebyte_to_float(word_list): + ''' + Converts list of little-endian bytes to float + ''' + packed_string = struct.pack("HH", *word_list) + unpacked_float = struct.unpack("f", packed_string)[0] + return unpacked_float + + +def lebyte_to_integer(word_list): + ''' + Converts list(size = 1) of little-endian bytes to Integer + ''' + try: + packed_string = struct.pack("H", *word_list) + unpacked_int = struct.unpack("h", packed_string)[0] + except Exception as e: + print("Unable to convert {} to integer".format(word_list)) + return False + return unpacked_int + + # ---------------------------------------------------------------------------# # specify slave to query # ---------------------------------------------------------------------------# -class TestStringMethods(unittest.TestCase): +class TestModbusDatabaseValues(unittest.TestCase): def test_holding_registers(self): modbus_client.connect() tag_in_db = mongo_tags.find({"register_type": 'hr'}) for db_tag in tag_in_db: try: - database_actual_value = float(db_tag['val_actual']) database_value = db_tag['val'] - if db_tag['scale_type'] == 0: - database_calc_value = float(db_tag['val']) / float(db_tag['scale_multiplier']) - else: - database_calc_value = float(db_tag['val']) * float(db_tag['scale_multiplier']) except KeyError: print("No value in DB for {}".format(db_tag['tag_name'])) - + reg = [] try: - reg = modbus_client.read_holding_registers(db_tag['register_number'] - 1, 5).registers + if db_tag['tag_type'][-3:] == 'INT': + reg = modbus_client.read_holding_registers(db_tag['register_number'] - 1, 1).registers + elif db_tag['tag_type'] == 'REAL': + reg = modbus_client.read_holding_registers(db_tag['register_number'] - 1, 2).registers # print(reg) except AttributeError: print("Could not get register {} for {}".format(db_tag['register_number'], db_tag['tag_name'])) - self.assertTrue(1 == 0) - next() + continue if reg: - modbus_value = reg[0] - if int(reg[1]) == 0: - modbus_actual_value = float(modbus_value) / float(reg[2]) - elif int(reg[1]) == 1: - modbus_actual_value = float(modbus_value) * float(reg[2]) + if len(reg) == 2: + # r = reg.reverse() + modbus_value = lebyte_to_float(reg) + else: + modbus_value = lebyte_to_integer(reg) # print("Modbus Actual: {}".format(modbus_actual_value)) # print("Database Actual: {}".format(database_actual_value)) # print("Database Calc: {}".format(database_calc_value)) - # print("Modbus Scaled: {}".format(modbus_value)) - # print("Database Scaled: {}".format(database_value)) - self.assertTrue(modbus_actual_value == database_calc_value) + if not modbus_value == database_value: + print("---- {}: {} ----".format(db_tag['tag_name'], db_tag['register_number'])) + print(reg) + print("Modbus Scaled: {}".format(modbus_value)) + print("Database Scaled: {}".format(database_value)) self.assertTrue(modbus_value == database_value) modbus_client.close() @@ -90,37 +112,118 @@ class TestStringMethods(unittest.TestCase): tag_in_db = mongo_tags.find({"register_type": 'ir'}) for db_tag in tag_in_db: try: - database_actual_value = float(db_tag['val_actual']) database_value = db_tag['val'] - if db_tag['scale_type'] == 0: - database_calc_value = float(db_tag['val']) / float(db_tag['scale_multiplier']) - else: - database_calc_value = float(db_tag['val']) * float(db_tag['scale_multiplier']) except KeyError: print("No value in DB for {}".format(db_tag['tag_name'])) - + reg = [] try: - reg = modbus_client.read_input_registers(db_tag['register_number'] - 1, 5).registers + if db_tag['tag_type'][-3:] == 'INT': + reg = modbus_client.read_input_registers(db_tag['register_number'] - 1, 1).registers + elif db_tag['tag_type'] == 'REAL': + reg = modbus_client.read_input_registers(db_tag['register_number'] - 1, 2).registers + elif db_tag['tag_type'] == 'ARRAY': + continue + # print(reg) except AttributeError: print("Could not get register {} for {}".format(db_tag['register_number'], db_tag['tag_name'])) continue if reg: - modbus_value = reg[0] - if int(reg[1]) == 0: - modbus_actual_value = float(modbus_value) / float(reg[2]) - elif int(reg[1]) == 1: - modbus_actual_value = float(modbus_value) * float(reg[2]) + if len(reg) > 0: + if len(reg) == 2: + # r = reg.reverse() + modbus_value = lebyte_to_float(reg) + elif len(reg) == 1: + modbus_value = lebyte_to_integer(reg) - # print("Modbus Actual: {}".format(modbus_actual_value)) - # print("Database Actual: {}".format(database_actual_value)) - # print("Database Calc: {}".format(database_calc_value)) - # print("Modbus Scaled: {}".format(modbus_value)) - # print("Database Scaled: {}".format(database_value)) - self.assertTrue(modbus_actual_value == database_calc_value) - self.assertTrue(modbus_value == database_value) + # print("Modbus Actual: {}".format(modbus_actual_value)) + # print("Database Actual: {}".format(database_actual_value)) + # print("Database Calc: {}".format(database_calc_value)) + if not modbus_value == database_value: + print("---- {}: {} ----".format(db_tag['tag_name'], db_tag['register_number'])) + print(reg) + print("Modbus Scaled: {}".format(modbus_value)) + print("Database Scaled: {}".format(database_value)) + self.assertTrue(modbus_value == database_value) modbus_client.close() + def test_arrays(self): + modbus_client.connect() + tag_in_db = mongo_tags.find({"register_type": 'ir'}) + for db_tag in tag_in_db: + try: + database_value = db_tag['val'] + except KeyError: + print("No value in DB for {}".format(db_tag['tag_name'])) + reg = [] + array_values = [] + try: + if db_tag['tag_type'] == 'ARRAY': + array_regs = [] + db_vals = db_tag['val'] + reg_len = db_tag['arr_len'] * 2 + get_len = 125 + num_gets = int(reg_len) / get_len + last_get = reg_len % get_len + for x in range(0, num_gets): + inp_register = (int(db_tag['register_number']) - 1) + (get_len * x) + read_registers = modbus_client.read_input_registers(inp_register, get_len).registers + array_regs = array_regs + read_registers + if last_get > 0: + array_regs = array_regs + modbus_client.read_input_registers((db_tag['register_number'] - 1) + (get_len * num_gets), last_get).registers + + for i in range(0, reg_len, 2): + array_values.append(lebyte_to_float([array_regs[i], array_regs[i + 1]])) + else: + continue + + except AttributeError: + print("Could not get register {} for {}".format(db_tag['register_number'], db_tag['tag_name'])) + continue + if not array_values == db_vals: + if len(array_values) > 0: + for i in range(0, len(array_values)): + print("{} = {} - {}".format(i, array_values[i], db_vals[i])) + self.assertTrue(array_values == db_vals) + modbus_client.close() + + def test_coils(self): + modbus_client.connect() + tag_in_db = mongo_tags.find({"register_type": 'co'}) + for db_tag in tag_in_db: + try: + database_value = db_tag['val'] + except KeyError: + print("No value in DB for {}".format(db_tag['tag_name'])) + + try: + reg = modbus_client.read_coils(db_tag['register_number'] - 1, 1).bits + if not database_value == reg[0]: + print("{} =/= {}".format(database_value, reg[0])) + self.assertTrue(database_value == reg[0]) + + except AttributeError: + print("Could not get register {} for {}".format(db_tag['register_number'], db_tag['tag_name'])) + continue + + def test_digital_inputs(self): + modbus_client.connect() + tag_in_db = mongo_tags.find({"register_type": 'di'}) + for db_tag in tag_in_db: + try: + database_value = db_tag['val'] + except KeyError: + print("No value in DB for {}".format(db_tag['tag_name'])) + + try: + reg = modbus_client.read_discrete_inputs(db_tag['register_number'] - 1, 1).bits + if not database_value == reg[0]: + print("{} =/= {}".format(database_value, reg[0])) + self.assertTrue(database_value == reg[0]) + + except AttributeError: + print("Could not get register {} for {}".format(db_tag['register_number'], db_tag['tag_name'])) + continue if __name__ == '__main__': unittest.main()