class TestClientServer(unittest.TestCase): def setUp(self): # modbus server self.server = ModbusServer(port=5020, no_block=True) self.server.start() # modbus client self.client = ModbusClient(port=5020) self.client.open() def tearDown(self): self.client.close() def test_read_and_write(self): # word space self.assertEqual(self.client.read_holding_registers(0), [0], 'Default value is 0 when server start') self.assertEqual(self.client.read_input_registers(0), [0], 'Default value is 0 when server start') # single read/write self.assertEqual(self.client.write_single_register(0, 0xffff), True) self.assertEqual(self.client.read_input_registers(0), [0xffff]) # multi-write at max size words_l = [randint(0, 0xffff)] * 0x7b self.assertEqual(self.client.write_multiple_registers(0, words_l), True) self.assertEqual(self.client.read_holding_registers(0, len(words_l)), words_l) self.assertEqual(self.client.read_input_registers(0, len(words_l)), words_l) # write over sized words_l = [randint(0, 0xffff)] * 0x7c self.assertEqual(self.client.write_multiple_registers(0, words_l), None) # bit space self.assertEqual(self.client.read_coils(0), [False], 'Default value is False when server start') self.assertEqual(self.client.read_discrete_inputs(0), [False], 'Default value is False when server start') # single read/write self.assertEqual(self.client.write_single_coil(0, True), True) self.assertEqual(self.client.read_coils(0), [True]) self.assertEqual(self.client.read_discrete_inputs(0), [True]) # multi-write at min size bits_l = [getrandbits(1)] * 0x1 self.assertEqual(self.client.write_multiple_coils(0, bits_l), True) self.assertEqual(self.client.read_coils(0, len(bits_l)), bits_l) self.assertEqual(self.client.read_discrete_inputs(0, len(bits_l)), bits_l) # multi-write at max size bits_l = [getrandbits(1)] * 0x7b0 self.assertEqual(self.client.write_multiple_coils(0, bits_l), True) self.assertEqual(self.client.read_coils(0, len(bits_l)), bits_l) self.assertEqual(self.client.read_discrete_inputs(0, len(bits_l)), bits_l) # multi-write over sized bits_l = [getrandbits(1)] * 0x7b1 self.assertEqual(self.client.write_multiple_coils(0, bits_l), None)
def run_modbus_server(host, port): print('starting modbus server at %s:%d' % (host, port)) server = ModbusServer(host=host, port=port, no_block=True) server.start() DataBank.set_words(0, [0] * 100) while True: DataBank.set_words(0x39, [random.randint(1, 10), 0]) DataBank.set_words(0x41, [random.randint(1, 10), 0]) DataBank.set_words(0x4b, [random.randint(1, 10), 0]) DataBank.set_words(0x50, [random.randint(1, 10), 0]) time.sleep(1)
def server_start(host, port): # parse args #parser = argparse.ArgumentParser() #parser.add_argument('-H', '--host', type=str, default='localhost', help='Host') #parser.add_argument('-p', '--port', type=int, default=502, help='TCP port') #args = parser.parse_args() #print("humo") # start modbus server server = ModbusServer(host, int(port), no_block=True) server.start()
def main(): ip, port = load_serve_config('server_info.json') server = ModbusServer(ip, port) print('PAI TA ÔN') print(f'IP: {ip} port {port}') try: server.start() except Exception as e: print(f'shutdown server with exception: {e}') server.stop() print('server is offline')
def run_server(): server = ModbusServer(host="", port=502, no_block=True) try: server.start() logging.info("Modbus server started") #Initialize 500 registers from address 0 DataBank.set_words(0, [0x0000] * 500) while True: continue #Stop server if interrupted except: server.close()
class ModbusInstance: def __init__(self, host: str = '0.0.0.0', port: int = 502): self.port = port self.host = host self.server = None def run(self, run_async: bool = True): self.server = ModbusServer(host=self.host, port=self.port, no_block=run_async) self.server.start() @staticmethod def write_str(index: int, string: str): parsed_text = [ord(c) for c in string] ModbusInstance.write(index, parsed_text) @staticmethod def write_int(index: int, value: int): value = int(round(value)) ModbusInstance.write(index, [value]) @staticmethod def write_float(index: int, value: float): val = str(value).split('.') prefix = val[0] suffix = val[1] suffix = suffix + '0' if len(suffix) == 1 else suffix ModbusInstance.write(index, [int('%s%s' % (prefix, suffix))]) @staticmethod def write_bit(index: int, value: int): DataBank.set_bits(index, [value]) log('Wrote %s to index %s' % (value, index + 10001)) @staticmethod def write(index: int, value: any): index = index - 40001 if index > 40000 else index DataBank.set_words(index, value) value = value[0] if isinstance(value, list) else value index += 40001 log('Wrote %s to index %s' % (value, index))
def main(): """ Main method to run the pyModbusTCP server for the test modbus endpoint. """ try: print('modbus main start') # Set holding register data to their address. # Set coils to address % 3 == 0. for i in range(0x4000): print('Setting word {} to {}'.format(i, i)) print('Setting bits {} to {}'.format(i, i % 3 == 0)) DataBank.set_words(i, [i]) DataBank.set_bits(i, [i % 3 == 0]) server = ModbusServer(host='', port=1502, no_block=True) server.start() print('started modbus server') global STOP_SERVER while not STOP_SERVER: time.sleep(.01) server.stop() print('stopped modbus server') except Exception: traceback.print_exc()
#!/bin/python from pyModbusTCP.server import ModbusServer, DataBank from time import sleep from random import uniform # Create an instance of ModbusServer server = ModbusServer("127.0.0.1", 502, no_block=True) try: print("Start server...") server.start() print("Server is online") state = [0] while True: DataBank.set_words(0, [int(uniform(0, 100))]) if state != DataBank.get_words(1): state = DataBank.get_words(1) print("Value of Register 1 has changed to " + str(state)) sleep(0.5) except: print("Shutdown server ...") server.stop() print("Server is offline")
class Thread(QThread): changePixmap = pyqtSignal(QImage) changePixmap2 = pyqtSignal(QImage) contTotal = pyqtSignal(str) width = 150 height = 400 #eggCount = 0 exitCounter = 0 #OffsetRefLines = 100 # Adjust ths value according to your usage ReferenceFrame = None distance_tresh = 400 #radius_min = 0 #radius_max = 0 #area_min = 750 #area_max = 1100 def __init__(self, modbusHab, areaMAx, areaMin, contorno, radiusMin, radiusMax, of7Linhas, portaTCP, porcEsc, contagemParou, diaAtual): super(Thread, self).__init__() self.area_max = areaMAx self.area_min = areaMin self.contornoValue = contorno self.radiusMin = radiusMin self.radiusMax = radiusMax self.of7Linhas = of7Linhas self.eggCount = int(contagemParou) self.portaTCP = portaTCP self.modbusHab = modbusHab self.cont = 0 self.porcEsc = porcEsc self.diaAtual = diaAtual #self.modbus=TCP def stop(self): self.coreActive = False self.quit() def lerModbus(self): zera = DataBank.get_words(1) if int(zera[0]) == 1: self.eggCount = 0 zera[0] = 0 DataBank.set_words(1, [0]) def escreveModbus(self, contador): self.server = ModbusServer("127.0.0.1", int(self.portaTCP), no_block=True) self.server.start() DataBank.set_words(0, [int(contador)]) def run(self): self.coreActive = True cap = cv2.VideoCapture('13.mp4') #cap = cv2.VideoCapture(0) fgbg = cv2.createBackgroundSubtractorMOG2() # for mask tempoini = time.time() while (self.coreActive): data = time.localtime() dia = data.tm_mday if (int(dia) != int(self.diaAtual)): self.eggCount = 0 (grabbed, frame) = cap.read() frame = cv2.rotate(frame, cv2.ROTATE_90_COUNTERCLOCKWISE) if not grabbed: print('Egg count: ' + str(self.eggCount)) print('\n End of the video file...') break # get Settings radius/area values #radius_min=10 #radius_max = 20 #area_min=500 #area_max = 1000 borderSize = self.contornoValue if self.radiusMin == '': self.radiusMin = 0 if self.radiusMax == '': self.radiusMax = 0 if self.area_min == '': self.area_min = 0 if self.area_max == '': self.area_max = 0 percent = int(self.porcEsc) width = int(frame.shape[1] * percent // 100) height = int(frame.shape[0] * percent // 100) dim = (width, height) frame40 = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA) height = np.size(frame40, 0) width = np.size(frame40, 1) fgmask = fgbg.apply(frame40) hsv = cv2.cvtColor(frame40, cv2.COLOR_BGR2HSV) th, bw = cv2.threshold(hsv[:, :, 2], 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)) morph = cv2.morphologyEx(bw, cv2.MORPH_CLOSE, kernel) dist = cv2.distanceTransform(morph, cv2.DIST_L2, cv2.DIST_MASK_PRECISE) distborder = cv2.copyMakeBorder( dist, borderSize, borderSize, borderSize, borderSize, cv2.BORDER_CONSTANT | cv2.BORDER_ISOLATED, 0) gap = 10 kernel2 = cv2.getStructuringElement( cv2.MORPH_ELLIPSE, (2 * (borderSize - gap) + 1, 2 * (borderSize - gap) + 1)) kernel2 = cv2.copyMakeBorder( kernel2, gap, gap, gap, gap, cv2.BORDER_CONSTANT | cv2.BORDER_ISOLATED, 0) distTempl = cv2.distanceTransform(kernel2, cv2.DIST_L2, cv2.DIST_MASK_PRECISE) nxcor = cv2.matchTemplate(distborder, distTempl, cv2.TM_CCOEFF_NORMED) mn, mx, _, _ = cv2.minMaxLoc(nxcor) th, peaks = cv2.threshold(nxcor, mx * 0.5, 255, cv2.THRESH_BINARY) peaks8u = cv2.convertScaleAbs(peaks) # fgmask = self.fgbg.apply(peaks8u) #_, contours, hierarchy = cv2.findContours(peaks8u, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE) contours, hierarchy = cv2.findContours(peaks8u, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE) peaks8u = cv2.convertScaleAbs(peaks) # to use as mask # plot reference lines (entrance and exit lines) coordYEntranceLine = (height // 2) + int(self.of7Linhas) coordYMiddleLine = (height // 2) coordYExitLine = (height // 2) - int(self.of7Linhas) cv2.line(frame40, (0, coordYEntranceLine), (width, coordYEntranceLine), (255, 0, 0), 2) cv2.line(frame40, (0, coordYMiddleLine), (width, coordYMiddleLine), (0, 255, 0), 6) cv2.line(frame40, (0, coordYExitLine), (width, coordYExitLine), (255, 0, 0), 2) flag = False egg_list = [] egg_index = 0 for i in range(len(contours)): contour = contours[i] (x, y), radius = cv2.minEnclosingCircle(contour) radius = int(radius) (x, y, w, h) = cv2.boundingRect(contour) egg_index = i egg_list.append([x, y, flag]) if len(contour) >= 5: if (radius <= int(self.radiusMax) and radius >= int(self.radiusMin)): # print("radius: ", radius) # pprint.pprint(hierarchy) ellipse = cv2.fitEllipse(contour) # (x, y, w, h) = cv2.boundingRect(contour) (center, axis, angle) = ellipse try: coordXContour, coordYContour = int(center[0]), int( center[1]) except: coordXContour, coordYContour = 0, 0 coordXCentroid = (2 * coordXContour + w) // 2 coordYCentroid = (2 * coordYContour + h) // 2 try: ax1, ax2 = int(axis[0]) - 2, int(axis[1]) - 2 except: ax1, ax2 = 2, 2 orientation = float(angle) area = cv2.contourArea(contour) if area >= float(self.area_min) and area <= float( self.area_max): #print('egg list: ' + str(egg_list) + ' index: ' + str(egg_index)) if ((coordYContour <= coordYEntranceLine) and (coordYContour >= coordYExitLine)): cv2.ellipse(frame40, (coordXContour, coordYContour), (ax1, ax2), orientation, 0, 360, (255, 0, 0), 2) # blue cv2.circle(frame40, (coordXContour, coordYContour), 1, (0, 255, 0), 15) # green cv2.putText(frame40, str(int(area)), (coordXContour, coordYContour), cv2.FONT_HERSHEY_SIMPLEX, 0.5, 0, 1, cv2.LINE_AA) for k in range(len(egg_list)): egg_new_X = x egg_new_Y = y dist = abs(egg_new_Y - egg_list[k][1]) if dist > self.distance_tresh: # distance_tresh = 200 egg_list.append([egg_new_X, egg_new_Y, flag]) absDistance = abs(coordYContour - coordYEntranceLine) if ((coordYContour >= coordYEntranceLine) and (absDistance <= 3)): self.eggCount += 1 egg_list.remove([egg_new_X, egg_new_Y, flag]) #salva imagem a cada 2 segundos tempofinal = time.time() if (tempofinal - tempoini > 2): cv2.imwrite('frame.jpg', frame40) tempoini = time.time() #escreve e ler modbus a cada 2 segundos if (self.modbusHab == 1): self.escreveModbus(self.eggCount) self.lerModbus() self.rgbImage = cv2.cvtColor(frame40, cv2.COLOR_BGR2RGB) h, w, ch = self.rgbImage.shape bytesPerLine = ch * w convertToQtFormat = QImage(self.rgbImage.data, w, h, bytesPerLine, QImage.Format_RGB888) p = convertToQtFormat.scaled(640, 480, Qt.KeepAspectRatio) self.changePixmap.emit(p) rgbImage2 = cv2.cvtColor(peaks8u, cv2.COLOR_BGR2RGB) h, w, ch = rgbImage2.shape bytesPerLine = ch * w convertToQtFormat = QImage(rgbImage2.data, w, h, bytesPerLine, QImage.Format_RGB888) p = convertToQtFormat.scaled(640, 480, Qt.KeepAspectRatio) self.changePixmap2.emit(p) self.contTotal.emit(str(self.eggCount)) # cleanup the camera and close any open windows cap.release()
import time from pyModbusTCP.server import ModbusServer, DataBank # need https://github.com/dbader/schedule import schedule # word @0 = second since 00:00 divide by 10 to avoid 16 bits overflow def alive_word_job(): DataBank.set_words(0, [int(time.time()) % (24*3600) // 10]) if __name__ == "__main__": # parse args parser = argparse.ArgumentParser() parser.add_argument("-H", "--host", type=str, default="localhost", help="Host") parser.add_argument("-p", "--port", type=int, default=502, help="TCP port") args = parser.parse_args() # init modbus server and start it server = ModbusServer(host=args.host, port=args.port, no_block=True) server.start() # init scheduler # schedule a daily downtime (from 18:00 to 06:00) schedule.every().day.at("18:00").do(server.stop) schedule.every().day.at("06:00").do(server.start) # update life word at @0 schedule.every(10).seconds.do(alive_word_job) # main loop while True: schedule.run_pending() time.sleep(1)
words.append(random.randrange(0, 10000)) words.append(random.randrange(220, 240)) words.append(random.randrange(0, 800)) print(words) DataBank.set_words(0, [words[0]]) # power DataBank.set_words(1, [words[1]]) # ac voltage DataBank.set_words(2, [words[2]]) # dc voltage if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("-H", "--host", type=str, default="0.0.0.0", help="host") parser.add_argument("-p", "--port", type=int, default=502, help="port") args = parser.parse_args() modbus_server = ModbusServer(host=args.host, port=args.port, no_block=True) modbus_server.start() scheduler = BackgroundScheduler() scheduler.add_job(set_databank_words, trigger="cron", second="*/20") scheduler.start() print('server started on {0}:{1}!'.format(args.host, args.port)) while True: time.sleep(1)
class AsyncModbusServer(object): """Asynchronous Modbus TCP Server.""" def __init__( self, *, host='127.0.0.1', bit_adr=0, bit_num=1, word_adr=0, word_num=1, timeout=1, name='Modbus Server', ): """Init server.""" self.port = mdb.PORT self.host = host self.bit_adr = bit_adr self.bit_num = bit_num self.word_adr = word_adr self.word_num = word_num self.timeout = timeout self.name = name self.connection = None try: self.connection = ModbusServer( host=self.host, port=self.port, no_block=True, ) self.connection.start() except Exception as err: raise ServerError('Error with server', err) async def run_task(self): """Run asyncio server.""" executor = concurrent.futures.ThreadPoolExecutor(max_workers=3, ) task = asyncio.create_task(self._awaitable(executor)) await task def stop(self): """Stop server.""" self.connection.stop() def _setup(self): cryptogen = SystemRandom() while True: bits_value = [ bool(cryptogen.randrange(2)) for indx in range(self.bit_num) ] words_value = [ cryptogen.randrange(10) for _ in range(self.word_num) ] try: DataBank.set_bits(self.bit_adr, bits_value) DataBank.set_words(self.word_adr, words_value) except Exception as err: raise ServerError('Error with writing', err) async def _awaitable(self, executor): loop = asyncio.get_event_loop() while True: await loop.run_in_executor( executor, self._setup(), ) await asyncio.sleep(self.timeout)
class TestClientServer(unittest.TestCase): port = 5020 def setUp(self): # modbus server self.server = ModbusServer(port=TestClientServer.port, no_block=True) self.server.start() # modbus client self.client = ModbusClient(port=TestClientServer.port) self.client.open() # to prevent address taken errors TestClientServer.port += 1 def tearDown(self): self.client.close() @repeat def test_word_init(self): # word space self.assertEqual(self.client.read_holding_registers(0), [0], 'Default value is 0 when server start') self.assertEqual(self.client.read_input_registers(0), [0], 'Default value is 0 when server start') @repeat def test_word_single(self): # single read/write self.assertEqual(self.client.write_single_register(0, 0xffff), True) self.assertEqual(self.client.read_input_registers(0), [0xffff]) @repeat def test_word_multi(self): # multi-write at max size words_l = [randint(0, 0xffff)] * 0x7b self.assertEqual(self.client.write_multiple_registers(0, words_l), True) self.assertEqual(self.client.read_holding_registers(0, len(words_l)), words_l) self.assertEqual(self.client.read_input_registers(0, len(words_l)), words_l) @repeat def test_word_oversize(self): # write over sized words_l = [randint(0, 0xffff)] * 0x7c self.assertEqual(self.client.write_multiple_registers(0, words_l), None) @repeat def test_bit_init(self): # bit space self.assertEqual(self.client.read_coils(0), [False], 'Default value is False when server start') self.assertEqual(self.client.read_discrete_inputs(0), [False], 'Default value is False when server start') @repeat def test_bit_single(self): # single read/write self.assertEqual(self.client.write_single_coil(0, True), True) self.assertEqual(self.client.read_coils(0), [True]) self.assertEqual(self.client.read_discrete_inputs(0), [True]) @repeat def test_bit_multi_min(self): # multi-write at min size bits_l = [getrandbits(1)] * 0x1 self.assertEqual(self.client.write_multiple_coils(0, bits_l), True) self.assertEqual(self.client.read_coils(0, len(bits_l)), bits_l) self.assertEqual(self.client.read_discrete_inputs(0, len(bits_l)), bits_l) @repeat def test_bit_multi_max(self): # multi-write at max size bits_l = [getrandbits(1)] * 0x7b0 self.assertEqual(self.client.write_multiple_coils(0, bits_l), True) self.assertEqual(self.client.read_coils(0, len(bits_l)), bits_l) self.assertEqual(self.client.read_discrete_inputs(0, len(bits_l)), bits_l) @repeat def test_bit_multi_oversize(self): # multi-write over sized bits_l = [getrandbits(1)] * 0x7b1 self.assertEqual(self.client.write_multiple_coils(0, bits_l), None)