def do_status(self, arg): 'Get the status of an RTU' if len(self.__rtu_comms) > 0: if arg and arg not in self.__rtu_data.keys(): print('RTU %s not found' % arg) return False elif arg: addr = arg else: addr = runprompt(listq(message='Get the status of which RTU?', choices=self.__rtu_comms.keys())) data = self.__rtu_data[addr]['ioas'] print('\r\nCurrent status of RTU %s:' % addr) print('='*40) for k, v in data.items(): print('IOA %d:' % k) print('-'*15) print('Type: %s' % IOAS[k][0]) value = v if IOAS[k][0] is not 'Breaker': print('Value: {0:5.12f} {1:s}'.format(value, IOAS[k][1])) else: value = 'CLOSED' if value == 0 else 'OPEN' print('Value: %s' % value) print('='*40 + '\r\n') else: print('''Not connected to any RTUs''') return False
def do_disconnect(self, arg: str): 'Disconnect from an RTU' if len(self.__rtu_comms) > 0: rtuaddr = runprompt( listq(message='Disconnect from which RTU?', choices=self.__rtu_comms.keys())) self.__keepalive_kill[rtuaddr] = True # Stop keepalive t = self.__keepalive[rtuaddr] t.join() self.__rtu_u_state[rtuaddr] = 0x08 # Expect STOPDT con pkt = APDU() / APCI(ApduLen=4, Type=0x03, UType=0x04) # STOPDT act self.__rtu_comms[rtuaddr].send(pkt.build()) while self.__rtu_u_state[ rtuaddr] is not None and self.__rtu_u_state[rtuaddr] > 0: print(f'\rTerminating connection with {rtuaddr:s} ... ', end='') sleep(0.33) print('') self.__killsignals[rtuaddr] = True t = self.__threads.pop(rtuaddr) t.join() s = self.__rtu_comms.pop(rtuaddr) d = self.__rtu_data.pop(rtuaddr) k = self.__killsignals.pop(rtuaddr) self.__rtu_asdu.pop(rtuaddr) s.close() else: print('Not connected to any RTUs')
def do_send(self, arg): 'Send a command to an RTU' if len(self.__rtu_comms) > 0: rtuaddr = runprompt(listq(message='Send a command to which RTU?', choices=self.__rtu_comms.keys())) breakers = [] for i in self.__rtu_data[rtuaddr]['ioas'].keys(): if IOAS[i][0] == 'Breaker': breakers.append(str(i)) if len(breakers) > 0: ioa = int(runprompt(listq(message='Send command to which IOA?', choices=breakers))) status = int(self.__rtu_data[rtuaddr]['ioas'][ioa]) >> 1 print(f"{self.__rtu_data[rtuaddr]['ioas']} {status}") if status == 0: print('The last known state is CLOSED') ans = runprompt(listq(message='Would you like to OPEN this IOA?', choices=['Yes', 'No'])) else: print('The last known state is OPEN') ans = runprompt(listq(message='Would you like to CLOSE this IOA?', choices=['Yes', 'No'])) if ans == 'Yes': status = 1 if status > 0 else 2 self.__rtu_data[rtuaddr]['tx'] += 1 self.__rtu_i_state[rtuaddr] = (0x07 << 8) | 0x80 | status pkt = build_104_asdu_packet(45, self.__rtu_asdu[rtuaddr], ioa, self.__rtu_data[rtuaddr]['tx'], self.__rtu_data[rtuaddr]['rx'], 6, SE=1, QU=1, SCS=status) self.__rtu_comms[rtuaddr].send(pkt) while self.__rtu_i_state[rtuaddr] is not None and self.__rtu_i_state[rtuaddr] > 0: print(f'\rSending single command (SELECT) to {rtuaddr:s} ... ', end='') sleep(0.25) print('') if self.__rtu_i_state[rtuaddr] is None: print(f'Error sending command to {rtuaddr:s}') else: self.__rtu_i_state[rtuaddr] = (0x07 << 8) | status pkt = build_104_asdu_packet(45, self.__rtu_asdu[rtuaddr], ioa, self.__rtu_data[rtuaddr]['tx'], self.__rtu_data[rtuaddr]['rx'], 6, SE=0, QU=1, SCS=status) self.__rtu_comms[rtuaddr].send(pkt) while self.__rtu_i_state[rtuaddr] is not None and self.__rtu_i_state[rtuaddr] > 0: print(f'\rSending single command (EXECUTE) to {rtuaddr:s} ... ') sleep(0.25) print('') else: print('This RTU cannot receive any commands') else: print('''Not connected to any RTUs''') return False