class MqttSubscriber: def __init__(self, brokerIp=None, brokerPort=1883, topic=None): self.__brokerIp = brokerIp self.__brokerPort = brokerPort self.__topic = topic # mqtt의 Client 객체 생성 self.__client = mqtt.Client() # 콜백 함수 설정 self.__client.on_connect = self.__on_connect self.__client.on_disconnect = self.__on_disconnect # 메시지를 받았을때 자동을 호출되는 콜백함수 self.__client.on_message = self.__on_message # 센서 객체 생성 self.rgbLed = RgbLed(redpin=16, greenpin=18, bluepin=22) self.pca9685 = Pca9685() self.buzzer = ActiveBuzzer(35) self.laser = Laser(37) self.laser2 = Laser(29) self.sg90direction = Sg90(self.pca9685, channel=15) self.sg90sensor = Sg90(self.pca9685, channel=14) self.sg90camera_vertical = Sg90(self.pca9685, channel=13) self.sg90camera_horizontal = Sg90( self.pca9685, channel=8) #12번인데 지금 개박살나서 8번으로 비활성화 해놨어요 self.lcd1602 = Lcd1602(0x27) # 서보모터 각도 고정값 self.camera_angle_vertical = 10 self.camera_angle_horizontal = 70 self.direction_angle = 90 self.sensor_angle = 70 # mqtt 연결에 성공했을 경우 자동적으로 호출되는 콜백함수 def __on_connect(self, client, userdata, flags, rc): print('** connection **') self.__client.subscribe(self.__topic, qos=0) # mqtt 연결이 끊어졌을 경우 자동적으로 호출되는 콜백함수 def __on_disconnect(self, client, userdata, rc): print('** disconnection **') # message가 도착했을 때 자동으로 호출되는 콜백함수 def __on_message(self, client, userdata, message): # self.status = str(message.payload, encoding='UTF-8') # 각각의 토픽에 따라 메시지 내용 처리방식 # print(str(message.payload, encoding='UTF-8')) if message.topic == '/Control/RgbLed': if str(message.payload, encoding='UTF-8') == 'ledOn': self.rgbLed.red() elif str(message.payload, encoding='UTF-8') == 'ledOff': self.rgbLed.off() if message.topic == '/Control/Direction/Camera': if str(message.payload, encoding='UTF-8') == 'down': self.camera_angle_vertical -= 4 if self.camera_angle_vertical < 0: self.camera_angle_vertical = 0 self.sg90camera_vertical.angle(self.camera_angle_vertical) elif str(message.payload, encoding='UTF-8') == 'up': self.camera_angle_vertical += 4 if self.camera_angle_vertical > 120: self.camera_angle_vertical = 120 self.sg90camera_vertical.angle(self.camera_angle_vertical) elif str(message.payload, encoding='UTF-8') == 'right': self.camera_angle_horizontal -= 4 if self.camera_angle_horizontal < 10: self.camera_angle_horizontal = 10 self.sg90camera_horizontal.angle(self.camera_angle_horizontal) elif str(message.payload, encoding='UTF-8') == 'left': self.camera_angle_horizontal += 4 if self.camera_angle_horizontal > 170: self.camera_angle_horizontal = 170 self.sg90camera_horizontal.angle(self.camera_angle_horizontal) elif str(message.payload, encoding='UTF-8') == 'stop': self.sg90camera_vertical.angle(self.camera_angle_vertical) elif str(message.payload, encoding='UTF-8') == 'horizonstop': self.sg90camera_horizontal.angle(self.camera_angle_horizontal) if message.topic == '/Control/Laser': if str(message.payload, encoding='UTF-8') == 'on': self.laser.on() self.laser2.on() elif str(message.payload, encoding='UTF-8') == 'off': self.laser.off() self.laser2.off() if message.topic == '/Control/Direction/FrontWheel': if str(message.payload, encoding='UTF-8') == 'left': self.direction_angle -= 3 self.sensor_angle += 3 if self.direction_angle < 60: self.direction_angle = 60 if self.sensor_angle > 100: self.sensor_angle = 100 self.sg90direction.angle(self.direction_angle) self.sg90sensor.angle(self.sensor_angle) elif str(message.payload, encoding='UTF-8') == 'right': self.direction_angle += 3 self.sensor_angle -= 3 if self.direction_angle > 120: self.direction_angle = 120 if self.sensor_angle < 40: self.sensor_angle = 40 self.sg90direction.angle(self.direction_angle) self.sg90sensor.angle(self.sensor_angle) elif str(message.payload, encoding='UTF-8') == 'stop': self.sg90direction.angle(self.direction_angle) self.sg90sensor.angle(self.sensor_angle) if message.topic == '/Control/Buzzer': if str(message.payload, encoding='UTF-8') == 'buzzerOn': self.buzzer.on() elif str(message.payload, encoding='UTF-8') == 'buzzerOff': self.buzzer.off() if message.topic == '/Control/Lcd': received_message = str(message.payload, encoding='UTF-8') self.lcd1602.write(0, 0, 'Received Message') self.lcd1602.write(0, 1, '>' + received_message) if message.topic == '/Control/imagecapture': videoCapture = cv2.VideoCapture(0) if videoCapture.isOpened(): retval, frame = videoCapture.read() img = np.copy(frame) cv2.imwrite("C:/Temp" + str(datetime.now()) + ".jpg", img) # subscribe 메소드를 스레드방식으로 시작하는 메소드 def start(self): thread = threading.Thread(target=self.__subscribe) thread.start() # mqtt client에 구독자로서 연결 def __subscribe(self): self.__client.connect(self.__brokerIp, self.__brokerPort) self.__client.loop_forever() # 강제적으로 연결 종료 def stop(self): self.__client.unsubscribe(self.__topic) self.__client.disconnect()
class ControllerMqttSubscriber: def __init__(self, brokerIp=None, brokerPort=1883, topic=None): self.__brokerIp = brokerIp self.__brokerPort = brokerPort self.__topic = topic self.__client = mqtt.Client() self.__client.on_connect = self.__on_connect self.__client.on_disconnect = self.__on_disconnect self.__client.on_message = self.__on_message self.pca9685 = Pca9685() self.dcMotorL = DCMotor(IN1=11, IN2=12, pca9685=self.pca9685, pwm=5) self.dcMotorR = DCMotor(IN1=13, IN2=15, pca9685=self.pca9685, pwm=4) self.sg90direction = Sg90(self.pca9685, channel=15) self.sg90sensor = Sg90(self.pca9685, channel=14) self.sg90camera_vertical = Sg90(self.pca9685, channel=13) self.sg90camera_horizontal = Sg90(self.pca9685, channel=8) # 속도 정보가 저장되는 싱글톤 객체 생성 self.singletonSpeed = SingletonSpeed() # 모터의 기본 속도 정의 self.motorspeed = 0 self.camera_angle_vertical = 10 self.camera_angle_horizontal = 70 self.direction_angle = 90 self.sensor_angle = 70 self.laser1 = Laser(37) self.laser2 = Laser(29) self.buzzer = ActiveBuzzer(35) self.rgbLed = RgbLed(redpin=16, greenpin=18, bluepin=22) self.checkStatus = False # 연결 되었을 때 자동으로 호출되는 콜백함수 def __on_connect(self, client, userdata, flags, rc): print('** connection **') self.__client.subscribe(self.__topic, qos=0) # 연결이 끊겼을 때 자동으로 호출되는 콜백함수 def __on_disconnect(self, client, userdata, rc): print('** disconnection **') # 메시지가 도착했을 때 자동으로 호출되는 콜백함수 def __on_message(self, client, userdata, message): # self.status = str(message.payload, encoding='UTF-8') if message.topic == '/Controller/Move/Speed': # 모터 속도 설정 message = str(message.payload, encoding='UTF-8').split(':', -1) axesValue = float(message[1]) * -1 # 컨트롤러 9번 값 받아와서(-1 ~ 1) self.motorspeed = 2000 + int( 2000 * axesValue ) # 9번 값을 2000 곱한다음 2000에 더한다 = (-1 ~ 1) * 2000 + 2000 =(0 ~ 4000) 설정됨 if message.topic == '/Controller/Move/Forward': message = str(message.payload, encoding='UTF-8').split(':', -1) axesValue = abs(float(message[1])) axesCalValue = int(4000 * axesValue**2) if axesCalValue > self.motorspeed: self.motorspeed = self.motorspeed else: self.motorspeed = axesCalValue self.dcMotorR.setSpeed(self.motorspeed) self.dcMotorL.setSpeed(self.motorspeed) self.dcMotorR.forward() self.dcMotorL.forward() self.singletonSpeed.set_speed(self.motorspeed) if message.topic == '/Controller/Move/Backward': message = str(message.payload, encoding='UTF-8').split(':', -1) axesValue = abs(float(message[1])) axesCalValue = int(4000 * axesValue**2) if axesCalValue > self.motorspeed: self.motorspeed = self.motorspeed else: self.motorspeed = axesCalValue self.dcMotorR.setSpeed(self.motorspeed) self.dcMotorL.setSpeed(self.motorspeed) self.dcMotorR.backward() self.dcMotorL.backward() self.singletonSpeed.set_speed(self.motorspeed) if message.topic == '/Controller/Move/Stop': self.motorspeed = 0 self.dcMotorR.setSpeed(self.motorspeed) self.dcMotorL.setSpeed(self.motorspeed) self.singletonSpeed.set_speed(self.motorspeed) if message.topic == '/Controller/Move/Direction': message = str(message.payload, encoding='UTF-8').split(':', -1) axesValue = float(message[1]) direction_angle = int(30 * axesValue + 90) self.sg90direction.angle(direction_angle) #self.sg90sensor.angle(self.sensor_angle) if message.topic == '/Controller/Sensor/Direction': message = str(message.payload, encoding='UTF-8').split(':', -1) axesValue = float(message[1]) * (-1) sensor_angle = int(30 * axesValue + 70) self.sg90sensor.angle(sensor_angle) if message.topic == '/Controller/Camera/Direction': message = str(message.payload, encoding='UTF-8').split(':', -1) axesValue = round(float(message[1]), 1) if axesValue == 0.1 or axesValue == 0.4 or axesValue == -0.1: self.camera_angle_vertical -= 4 if self.camera_angle_vertical < 0: self.camera_angle_vertical = 0 self.sg90camera_vertical.angle(self.camera_angle_vertical) #아래 if axesValue == -1.0 or axesValue == 1.0 or axesValue == -0.7: self.camera_angle_vertical += 4 if self.camera_angle_vertical > 120: self.camera_angle_vertical = 120 self.sg90camera_vertical.angle(self.camera_angle_vertical) #위 if axesValue == -0.4 or axesValue == -0.1 or axesValue == -7.0: self.camera_angle_horizontal -= 4 if self.camera_angle_horizontal < 10: self.camera_angle_horizontal = 10 self.sg90camera_horizontal.angle( self.camera_angle_horizontal) #오른쪽 if axesValue == 0.7 or axesValue == 0.4 or axesValue == 1.0: self.camera_angle_horizontal += 4 if self.camera_angle_horizontal > 170: self.camera_angle_horizontal = 170 self.sg90camera_horizontal.angle( self.camera_angle_horizontal) #왼쪽 if message.topic == '/Controller/Laser': if str(message.payload, encoding='UTF-8') == 'on': self.laser1.on() self.laser2.on() elif str(message.payload, encoding='UTF-8') == 'off': self.laser1.off() self.laser2.off() if message.topic == '/Controller/Buzzer': if str(message.payload, encoding='UTF-8') == 'on': self.buzzer.on() elif str(message.payload, encoding='UTF-8') == 'off': self.buzzer.off() if message.topic == '/Controller/RGBLed': if str(message.payload, encoding='UTF-8') == 'redon': self.rgbLed.red() elif str(message.payload, encoding='UTF-8') == 'greenon': self.rgbLed.green() elif str(message.payload, encoding='UTF-8') == 'blueon': self.rgbLed.blue() elif str(message.payload, encoding='UTF-8') == 'off': self.rgbLed.off() # subscribe 메소드를 스레드방식으로 시작하는 메소드 def start(self): thread = threading.Thread(target=self.__subscribe) thread.start() # mqtt client에 구독자로서 연결 def __subscribe(self): self.__client.connect(self.__brokerIp, self.__brokerPort) self.__client.loop_forever() # 강제적으로 연결 종료 def stop(self): self.__client.unsubscribe(self.__topic) self.__client.disconnect()