import minimalmodbus import time, json minimalmodbus.BAUDRATE = 9600 minimalmodbus.STOPBITS = 1 fmaddress = 110 daddress = 1 with open("/root/python_firmware/persist.json", "r") as f: temp = json.load(f) daddress = temp.get("drive", 1) fmaddress = temp.get("flowmeter", 247) def volume_units(vunit): units = { 0: "cm cubed/s", 1: "cm cubed/min", 2: "cm cubed/h", 3: "cm cubed/d", 4: "dm cubed/s", 5: "dm cubed/min", 6: "dm cubed/h", 7: "dm cubed/d", 8: "m cubed/s", 9: "m cubed/min", 10: "m cubed/h", 11: "m cubed/d", 12: "ml/s", 13: "ml/min", 14: "ml/h", 15: "ml/d", 16: "l/s", 17: "l/min", 18: "l/h (+)", 19: "l/d", 20: "hl/s", 21: "hl/min", 22: "hl/h", 23: "hl/d", 24: "Ml/s", 25: "Ml/min", 26: "Ml/h", 27: "Ml/d", 32: "af/s", 33: "af/min", 34: "af/h", 35: "af/d", 36: "ft cubed/s", 37: "ft cubed/min", 38: "ft cubed/h", 39: "ft cubed/d", 40: "fl oz/s (us)", 41: "fl oz/min (us)", 42: "fl oz/h (us)", 43: "fl oz/d (us)", 44: "gal/s (us)", 45: "gal/min (us)", 46: "gal/h (us)", 47: "gal/d (us)", 48: "Mgal/s (us)", 49: "Mgal/min (us)", 50: "Mgal/h (us)", 51: "Mgal/d (us)", 52: "bbl/s (us;liq.)", 53: "bbl/min (us;liq.)", 54: "bbl/h (us;liq.)", 55: "bbl/d (us;liq.)", 56: "bbl/s (us;beer)", 57: "bbl/min (us;beer)", 58: "bbl/h (us;beer)", 59: "bbl/d (us;beer)", 60: "bbl/s (us;oil)", 61: "bbl/min (us;oil)", 62: "bbl/h (us;oil)", 63: "bbl/d (us;oil)", 64: "bbl/s (us;tank)", 65: "bbl/min (us;tank)", 66: "bbl/h (us;tank)", 67: "bbl/d (us;tank)", 68: "gal/s (imp)", 69: "gal/min (imp)", 70: "gal/h (imp)", 71: "gal/d (imp)", 72: "Mgal/s (imp)", 73: "Mgal/min (imp)", 74: "Mgal/h (imp)", 75: "Mgal/d (imp)", 76: "bbl/s (imp;beer)", 77: "bbl/min (imp;beer)", 78: "bbl/h (imp;beer)", 79: "bbl/d (imp;beer)", 80: "bbl/s (imp;oil)", 81: "bbl/min (imp;oil)", 82: "bbl/h (imp;oil)", 83: "bbl/d (imp;oil)", 88: "kgal/s (us)", 89: "kgal/min (us)", 90: "kgal/h (us)", 91: "kgal/d (us)", 92: "MMft cubed/s", 93: "MMft cubed/min", 94: "MMft cubed/h", 96: "Mft cubed/d" } return units[vunit] def totalizer_units(tunit): units = { 0: "cm cubed", 1: "dm cubed", 2: "m cubed", 3: "ml", 4: "l", 5: "hl", 6: "Ml Mega", 8: "af", 9: "ft cubed", 10: "fl oz (us)", 11: "gal (us)", 12: "Mgal (us)", 13: "bbl (us;liq.)", 14: "bbl (us;beer)", 15: "bbl (us;oil)", 16: "bbl (us;tank)", 17: "gal (imp)", 18: "Mgal (imp)", 19: "bbl (imp;beer)", 20: "bbl (imp;oil)", 22: "kgal (us)", 23: "Mft cubed", 50: "g", 51: "kg", 52: "t", 53: "oz", 54: "lb", 55: "STon", 100: "Nl", 101: "Nm cubed", 102: "Sm cubed", 103: "Sft cubed", 104: "Sl", 105: "Sgal (us)", 106: "Sbbl (us;liq.)", 107: "Sgal (imp)", 108: "Sbbl (us;oil)", 109: "MMSft cubed", 110: "Nhl", 251: "None" } return units[tunit] def int_to_bits(n,x): return pad_to_x([int(digit) for digit in bin(n)[2:]],x) # [2:] to chop off the "0b" part def pad_to_x(n,x): while len(n) < x: n = [0] + n return n def status_codes(n): status_array = int_to_bits(n,16) status_low = { 0: "Stopped;", 1: "Operating in Forward;", 2: "Operating in Reverse;", 3: "DC operating;" } status_mid = { 0: "", 1: "Speed searching;", 2: "Accelerating;", 3: "At constant speed;", 4: "Decelerating;", 5: "Decelerating to stop;", 6: "H/W OCS;", 7: "S/W OCS;", 8: "Dwell operating;" } status_high = { 0: "Normal state", 4: "Warning occurred", 8: "Fault occurred" } values = { 0: 8, 1: 4, 2: 2, 3: 1 } stats_low = status_array[12:] stats_mid = status_array[8:12] stats_high = status_array[:4] low = 0 mid = 0 high = 0 for x in range(4): if stats_low[x] == 1: low = low + values[x] if stats_mid[x] == 1: mid = mid + values[x] if stats_high[x] == 1: high = high + values[x] return status_low[low] + " " + status_mid[mid] + ' ' + status_high[high] def fault_code_a(n): fault_code_array = int_to_bits(n,16) """ fault = { 0: "OCT", 1: "OVT", 2: "EXT-A", 3: "EST", 4: "COL", 5: "GFT", 6: "OHT", 7: "ETH", 8: "OLT", 9: "Reserved", 10: "EXT-B", 11: "EEP", 12: "FAN", 13: "POT", 14: "IOLT", 15: "LVT" } """ fault = { 0: "Overload Trip", 1: "Underload Trip", 2: "Inverter Overload Trip", 3: "E-Thermal Trip", 4: "Ground Fault Trip", 5: "Output Image Trip", 6: "Inmput Imaging Trip", 7: "Reserved", 8: "Reserved", 9: "NTC Trip", 10: "Overcurrent Trip", 11: "Overvoltage Trip", 12: "External Trip", 13: "Arm Short", 14: "Over Heat Trip", 15: "Fuse Open Trip" } faults = [] counter = 15 for x in range(16): if fault_code_array[x] == 1: faults = [fault[counter]] + faults counter = counter - 1 return ' '.join(faults) def fault_code_b(n): fault_code_array = int_to_bits(n,8) """ fault = { 0: "COM", 1: "Reserved", 2: "NTC", 3: "REEP", 4: "OC2", 5: "NBR", 6: "SAFA", 7: "SAFB" } """ fault = { 0: "Reserved", 1: "Reserved", 2: "Reserved", 3: "FAN Trip", 4: "Reserved", 5: "Reserved", 6: "Pre PID Fail", 7: "Bad contact at basic I/O board", 8: "External Brake Trip", 9: "No Motor Trip", 10: "Bad Option Card", 11: "Reserved", 12: "Reserved", 13: "Reserved", 14: "Pre Over Heat Trip", 15: "Reserved" } faults = [] counter = 7 for x in range(8): if fault_code_array[x] == 1: faults = [fault[counter]] + faults counter = counter - 1 return ' '.join(faults) registers = [ ('volume_flow', 3873, 'FLOAT', 10, 3600,2, fmaddress, None ), ('totalizer_1', 2609, 'FLOAT', 100, 3600,2, fmaddress, None ), ('totalizer_2', 2809, 'FLOAT', 100, 3600,2, fmaddress, None ), ('totalizer_3', 3009, 'FLOAT', 100, 3600,2, fmaddress, None ), ('volume_flow_units', 2102, 'INTEGER', 1,86400,1, fmaddress, volume_units), ('totalizer_1_units', 4603, 'INTEGER', 1,86400,1, fmaddress, totalizer_units), ('totalizer_2_units', 4604, 'INTEGER', 1,86400,1, fmaddress, totalizer_units), ('totalizer_3_units', 4605, 'INTEGER', 1,86400,1, fmaddress, totalizer_units), ('byte_order', 4914, 'INTEGER', 100, 3600,2, fmaddress, None), ('device_name', 7237, 'STRING', 100, 3600,5, fmaddress, None), ('serial_number', 7002, 'STRING', 100, 3600,6, fmaddress, None), ('run_status', 772, 'INTEGER', 0, 3600, 1, daddress, status_codes), ('frequency', 784, 'INTEGER', 2, 3600, 2, daddress, None), ('current', 783, 'INTEGER', 2, 3600, 2, daddress, None), ('fault_a', 815, 'INTEGER', 1, 3600, 1, daddress, fault_code_a), ('fault_b', 816, 'INTEGER', 1, 3600, 1, daddress, fault_code_b), ('pid_ref', 791, 'INTEGER', 5, 3600, 1, daddress, None), ('pid_feedback', 792, 'INTEGER', 5, 3600, 1, daddress, None), ('motor_rated_current', 4896, 'INTEGER', 300, 86400, 1, daddress, None), ('sleep_delay', 4924, 'INTEGER', 5, 86400, 1, daddress, None) ] for register in registers: instrument = minimalmodbus.Instrument('/dev/ttyS0', register[6]) #device, modbus slave address instrument.debug = False instrument.handle_local_echo = True if register[2] == "FLOAT": try: value = instrument.read_float(registeraddress=register[1], functioncode=4) #register -1 for float if register[7] != None: value = register[7](value) print("{} from {}: {}".format(register[0],register[6],value)) except Exception as e: print("Error: {}".format(e)) #time.sleep(1) elif register[2] == "INTEGER": try: value = instrument.read_register(registeraddress=register[1],functioncode=4) #register -1 for float if register[7] != None: value = register[7](value) print("{} from {}: {}".format(register[0],register[6],value)) except Exception as e: print("Error: {}".format(e)) #time.sleep(1) elif register[2] == "STRING": try: value = instrument.read_string(register[1], register[5], functioncode=4) value = ''.join([i if 0 < ord(i) < 128 else '' for i in value]) if register[7] != None: value = register[7](value) print("{} from {}: {}".format(register[0],register[6],value)) except Exception as e: print("Error: {}".format(e)) #time.sleep(1)