def trackModeChanged(self): if self.ui.trackMode.isChecked(): self.track = RepeatTimer(5.0, self.tracking) self.track.start() logging.debug("Track mode ON") else: self.track.cancel() logging.debug("Track mode Off")
def __init__(self): """ Initialize sensor readings and led animations """ #initialize ping sensor and register callback self.sensor = PingSensor(self.setDistance) #initialize neopixel object self.strip = Adafruit_NeoPixel(LEDShow.LED_COUNT, LEDShow.LED_PIN, LEDShow.LED_FREQ_HZ, LEDShow.LED_DMA, LEDShow.LED_INVERT, LEDShow.LED_BRIGHTNESS) self.strip.begin() #grid conversion self.grid = utils.stripToGrid(LEDShow.LED_COUNT, 8) ###SHUFFLE THESE!!! #list of animations to cycle through self.animations = [ AnimationWipe(self), AnimationPulse(self), AnimationLeap(self), AnimationMirror(self), AnimationDuel(self), AnimationWave(self), AnimationSquares(self) ] #initialized animation index self.animationIndex = -1 #animation duration timer if len(self.animations) > 1: self.timer = RepeatTimer() self.timer.start(LEDShow.ANIMATION_DURATION, self.nextAnimation) #initialize animations self.currentAnimation = None self.nextAnimation() self.startPingInterval = time.time() #ping loop try: GPIO.setmode(GPIO.BOARD) self.sensor.ping() #emit ping every interval defined by the animation while (True): self.endPingInterval = time.time() - self.startPingInterval if (self.endPingInterval >= self.pingInterval): self.sensor.ping() #cleanup finally: GPIO.cleanup() self.clearPixels()
class LaserControlMain(QtGui.QMainWindow): act_stell_pos = QtCore.pyqtSignal(str, str) def __init__(self, parent=None): super(LaserControlMain, self).__init__(parent) self.confMode = False self.nRef = 0 self.device = None (self._ra, self._dec) = ("0h0m0s", "0º0'0''") self.ui = Ui_LaserControl() self.ui.setupUi(self) self.ui.Reconfigure.setVisible(False) regex = QtCore.QRegExp( "%s" % (_fromUtf8("^-?[0-9]{1,3}(º|ᵒ)[0-9]{1,3}'[0-9]{1,3}([']{2}|\")$"))) self.Valid = QtGui.QRegExpValidator(regex, self) self.ui.posHorizontal.setValidator(self.Valid) self.ui.posVertical.setValidator(self.Valid) self.ui.posHorizontal.setText("%s" % (_fromUtf8("0º0'0''"))) self.ui.posVertical.setText("%s" % (_fromUtf8("0º0'0''"))) self.ui.tabWidget.setCurrentIndex(1) self.ui.tabWidget.setTabEnabled(1, False) self.pos = ('0.0000', '0.0000') self._prev_pos = ("0º0'0''", "0º0'0''") #Starts server self.Server = Telescope_Server(pos_signal=self.act_stell_pos) self.Server.daemon = True self.Server.start() self.setSignals() self.setShortcuts() #At the beginning, configuration mode is On self.ui.confMode.setChecked(True) ## Connects the UI signals # def setSignals(self): #Movements QtCore.QObject.connect(self.ui.upButton, QtCore.SIGNAL("pressed()"), self.upPressed) QtCore.QObject.connect(self.ui.downButton, QtCore.SIGNAL("pressed()"), self.downPressed) QtCore.QObject.connect(self.ui.rightButton, QtCore.SIGNAL("pressed()"), self.rightPressed) QtCore.QObject.connect(self.ui.leftButton, QtCore.SIGNAL("pressed()"), self.leftPressed) QtCore.QObject.connect(self.ui.upButton, QtCore.SIGNAL("released()"), self.arrow_released) QtCore.QObject.connect(self.ui.downButton, QtCore.SIGNAL("released()"), self.arrow_released) QtCore.QObject.connect(self.ui.rightButton, QtCore.SIGNAL("released()"), self.arrow_released) QtCore.QObject.connect(self.ui.leftButton, QtCore.SIGNAL("released()"), self.arrow_released) #Position QtCore.QObject.connect(self.ui.posVertical, QtCore.SIGNAL("editingFinished()"), self.posChanged) QtCore.QObject.connect(self.ui.posHorizontal, QtCore.SIGNAL("editingFinished()"), self.posChanged) #Laser QtCore.QObject.connect(self.ui.laserOn, QtCore.SIGNAL("toggled(bool)"), self.laserToggled) #Options QtCore.QObject.connect(self.ui.confMode, QtCore.SIGNAL("toggled(bool)"), self.confModeChanged) QtCore.QObject.connect(self.ui.trackMode, QtCore.SIGNAL("toggled(bool)"), self.trackModeChanged) #Device connection self.refreshSerialPorts() QtCore.QObject.connect(self.ui.action_Refresh, QtCore.SIGNAL("triggered(bool)"), self.refreshSerialPorts) QtCore.QObject.connect(self.ui.action_Desconectar, QtCore.SIGNAL("triggered(bool)"), self.closeDevice) #El dispositivo debe recalcular el número de pasos por vuelta en cada eje QtCore.QObject.connect(self.ui.action_Recalibrar, QtCore.SIGNAL("triggered(bool)"), self.initDevice) #Stellarium.. self.Server.stell_pos_recv.connect(self.stellariumRecv) ## Show available serial ports and set connection signals # def refreshSerialPorts(self): # Clear menu.. self.ui.menu_Connect.clear() self.ui.menu_Connect.addAction(self.ui.action_Refresh) self.ui.menu_Connect.addSeparator() port_list = get_avalilable_ports() for device_path in port_list: act = QtGui.QAction(device_path, self) act.triggered.connect( functools.partial(self.connectDevice, device_path)) self.ui.menu_Connect.addAction(act) ## Shortcuts for the device movements # def setShortcuts(self): self.ui.leftB_shortCut = QtGui.QShortcut( QtGui.QKeySequence("Shift+Left"), self, self.ui.leftButton.animateClick) self.ui.rightB_shortCut = QtGui.QShortcut( QtGui.QKeySequence("Shift+Right"), self, self.ui.rightButton.animateClick) self.ui.upB_shortCut = QtGui.QShortcut(QtGui.QKeySequence("Shift+Up"), self, self.ui.upButton.animateClick) self.ui.downB_shortCut = QtGui.QShortcut( QtGui.QKeySequence("Shift+Down"), self, self.ui.downButton.animateClick) ## Handles the coordinate reception from Stellarium # # Receives the coordinates from Stellarium by the Telescope_Server instance. # If the device is connected, sends the coordinates to it, as either the configuration or movement values. # # Also manages the UI status along the configuration process. # # \param ra Right ascension # \param dec Declination # \param mtime Timestamp def stellariumRecv(self, ra, dec, mtime): ra = float(ra) dec = float(dec) mtime = float(mtime) mtime = 1.46037891509e+15 logging.debug("%s" % mtime) logging.debug("%s" % coords.toJ2000(ra, dec, mtime)) (sra, sdec, stime) = coords.eCoords2str(ra, dec, mtime) # print stime (self._ra, self._dec) = (sra, sdec) if self.device != None: logging.debug("Sending to the device: '%s','%s','%s'" % (sra, sdec, stime)) try: if self.ui.Reconfigure.isChecked(): if self.ui.redef_1: self.ui.redef_1.setChecked(False) redef = 1 elif self.ui.redef_2: self.ui.redef_2.setChecked(False) redef = 2 else: self.ui.redef_3.setChecked(False) redef = 3 self.ui.Reconfigure.setChecked(False) self.device.setRef(redef, sra, sdec, stime) elif not self.confMode: self.device.goto(sra, sdec, stime) else: self.nRef = self.nRef + 1 self.ui.text_status.setText("References: %d/2" % self.nRef) self.device.setRef(self.nRef, sra, sdec, stime) if self.nRef == 2: self.setConfigDone() self.nRef = 0 except: logging.debug("Device not found..") e = sys.exc_info()[1] print("Error: %s" % e) ## Up key pushed # # Starts the upward movement of the device def upPressed(self): if self.device != None: self.device.movy('1') ## Down key pushed # # Starts the downward movement def downPressed(self): if self.device != None: self.device.movy('0') ## Right key pushed # # Starts the clockwise movement def rightPressed(self): if self.device != None: self.device.movx('1') ## Left key pushed # # Starts the counter clockwise movement def leftPressed(self): if self.device != None: self.device.movx('0') ## Up/Down/Right/Left key released.. # # Stops any movement def arrow_released(self): if self.device != None: self.device.stop() ## Handles the changes on the coordinates text boxes # # If the device is configured, sends the new coordinates to it def posChanged(self): logging.debug( "(%s, %s)" % (self.ui.posHorizontal.text(), self.ui.posVertical.text())) x = _toUtf8(self.ui.posHorizontal.text()) y = _toUtf8(self.ui.posVertical.text()) if self.device != None and (self._prev_pos[0] != x or self._prev_pos[1] != y): logging.debug("Sending (%s, %s) to device" % (x, y)) self.device.move(x, y) self._prev_pos = (x, y) ## Handles the changes on "configuration mode" check box # def confModeChanged(self): if self.ui.confMode.isChecked(): self.confMode = True self.nRef = 0 logging.debug("Conf mode ON") else: self.setConfigDone() self.confMode = False logging.debug("Conf mode Off") ## Handles the end of the device configuration process # def setConfigDone(self): self.ui.confMode.setChecked(False) self.ui.tabWidget.setTabEnabled(1, True) self.ui.tabWidget.setCurrentIndex(1) self.ui.text_status.setText("References: 2/2") self.ui.confMode.setVisible(False) self.ui.textEdit.setVisible(False) self.ui.Reconfigure.setVisible(True) ## Handles changes on tracking check box # # If check is On, starts the tracking mode on the device def trackModeChanged(self): if self.ui.trackMode.isChecked(): self.track = RepeatTimer(5.0, self.tracking) self.track.start() logging.debug("Track mode ON") else: self.track.cancel() logging.debug("Track mode Off") ## Starts the device connection # # In case of error, shows the message on UI # \param device_path USB Serial Device path def connectDevice(self, device_path): self.ui.action_Desconectar.setEnabled(True) self.ui.action_Recalibrar.setEnabled(True) logging.info("Connecting to device via '%s'" % device_path) try: if self.device == None: self.device = LaserDev(usb_serial=device_path) self.device.init_received.connect(self.init_received) self.device.pos_received.connect(self.pos_received) self.device.pos_e_received.connect(self.pos_e_received) self.device.start() except: logging.info("Device not found") QtGui.QMessageBox.warning(self, 'Warning', "Device not found") self.ui.action_Desconectar.setEnabled(False) self.ui.action_Recalibrar.setEnabled(False) self.device = None ## Initialize device # # The device will calculate the steps per revolution def initDevice(self): logging.info("Initializing device..") try: if self.device != None: self.device.init() except: logging.info("Error initializing device.") ## Receives the end of initialization signal from the device # # That signal indicates that the device is successfully initialized def init_received(self): logging.debug("Init received") self.pos = ('0.0000', '0.0000') self.ui.posHorizontal.setText("%s" % _fromUtf8("0º0'0''")) self.ui.posVertical.setText("%s" % _fromUtf8("0º0'0''")) ## Receives the position updated signal from the device # # The parameters are the horizontal coordinates which the device points to def pos_received(self, x, y): logging.debug("%s,%s" % (x, y)) self.pos = (x, y) self.ui.posHorizontal.setText("%s" % _fromUtf8( coords.deg_2_degStr(360.0 - coords.radStr_2_deg(self.pos[0])))) self.ui.posVertical.setText( "%s" % _fromUtf8(coords.radStr_2_degStr(self.pos[1]))) ## Receives the position updated signal from the device # # The parameters are the equatorial coordinates which the device points to def pos_e_received(self, x, y): logging.debug("%s,%s" % (x, y)) self.act_stell_pos.emit(x, y) ## Tracking mode # # Updates periodically the device position by sending the equatorial coordinates and time def tracking(self): logging.debug( "('%s', '%s', '%s')" % (self._ra, self._dec, strftime("%Hh%Mm%Ss", localtime()))) if self.device != None and self._ra != '0h0m0s': self.device.goto(self._ra, self._dec, strftime("%Hh%Mm%Ss", localtime())) ## Laser toggle.. # def laserToggled(self): if self.ui.laserOn.isChecked(): if self.device != None: self.device.laserOn() logging.debug("Laser ON") else: if self.device != None: self.device.laserOff() logging.debug("Laser Off") ## Close the device connection # def closeDevice(self): self.ui.action_Conectar.setEnabled(True) self.ui.action_Desconectar.setEnabled(False) self.ui.action_Recalibrar.setEnabled(False) logging.info("Disconnecting device..") try: if self.device != None: self.device.close() self.device = None except: self.device = None ## Exit.. # def closeEvent(self, event): logging.debug("Bye!") try: self.Server.close_socket() self.track.cancel() event.accept() except: event.accept()
class LEDShow(object): """ LEDShow manages the ultrasonic sensor readings and the LED animation sequence. """ # LED strip configuration: LED_COUNT = 1536 # Number of LED pixels. LED_PIN = 18 # GPIO pin connected to the pixels (must support PWM!). LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz) LED_DMA = 5 # DMA channel to use for generating signal (try 5) LED_BRIGHTNESS = 100 # Set to 0 for darkest and 255 for brightest LED_INVERT = False # True to invert the signal (when using NPN transistor level shift) #Sensor configuration ANIMATION_DURATION = 300 # The collective inactive (non animating) time from animation start to finish(trigger next animation) MAX_DISTANCE = 210.0 # The maximum distance accepted from the ultrasonic sensor (cm) MIN_DISTANCE = 80.0 # The minimum distance accepted from the ultrasonic sensor (cm) RANDOMIZE = True # Next animation is selected randomly def __init__(self): """ Initialize sensor readings and led animations """ #initialize ping sensor and register callback self.sensor = PingSensor(self.setDistance) #initialize neopixel object self.strip = Adafruit_NeoPixel(LEDShow.LED_COUNT, LEDShow.LED_PIN, LEDShow.LED_FREQ_HZ, LEDShow.LED_DMA, LEDShow.LED_INVERT, LEDShow.LED_BRIGHTNESS) self.strip.begin() #grid conversion self.grid = utils.stripToGrid(LEDShow.LED_COUNT, 8) ###SHUFFLE THESE!!! #list of animations to cycle through self.animations = [ AnimationWipe(self), AnimationPulse(self), AnimationLeap(self), AnimationMirror(self), AnimationDuel(self), AnimationWave(self), AnimationSquares(self) ] #initialized animation index self.animationIndex = -1 #animation duration timer if len(self.animations) > 1: self.timer = RepeatTimer() self.timer.start(LEDShow.ANIMATION_DURATION, self.nextAnimation) #initialize animations self.currentAnimation = None self.nextAnimation() self.startPingInterval = time.time() #ping loop try: GPIO.setmode(GPIO.BOARD) self.sensor.ping() #emit ping every interval defined by the animation while (True): self.endPingInterval = time.time() - self.startPingInterval if (self.endPingInterval >= self.pingInterval): self.sensor.ping() #cleanup finally: GPIO.cleanup() self.clearPixels() def setDistance(self, d): """ The sensor callback evaluates the reported distance then sends it to the current animation when a change is detected. Also queues the next animation when the *ANIMATION_DURATION* has expired. """ #increment animation time self.startPingInterval = time.time() #only update animation when new distance is less than MAX_DISTANCE #and current animation is valid distance = int(d) if not self.currentAnimation == None: self.distance = distance self.currentAnimation.run() def nextAnimation(self): """ Queues the next animation in the list and updates the sensor interval. If the current animation is at the end of the list, the sequence starts over. """ #next index if LEDShow.RANDOMIZE: index = self.animationIndex while index == self.animationIndex: index = randint(0, len(self.animations) - 1) self.animationIndex = index else: self.animationIndex = 0 if (self.animationIndex == len(self.animations) - 1) else (self.animationIndex + 1) if not self.currentAnimation == None: self.currentAnimation.stop() self.currentAnimation = self.animations[self.animationIndex] print(self.currentAnimation) self.distance = 0 self.pingInterval = self.currentAnimation.pingInterval() def clearPixels(self): """ Clears all pixels in the strip """ for i in range(self.numPixels()): self.setPixelColor(i, 0, 0, 0) self.show() def setPixelColor(self, pixel, red, green, blue): """ Set specified LED to RGB value """ if pixel < LEDShow.LED_COUNT: red = utils.clamp(red, 0, 255) green = utils.clamp(green, 0, 255) blue = utils.clamp(blue, 0, 255) self.strip.setPixelColorRGB(pixel, green, red, blue) #GRB to RGB def getPixelColor(self, pixel): """ Return RGB value of specified pixel """ return utils.intToRGB(self.strip.getPixelColor(pixel)) def setPixelColorXY(self, x, y, red, green, blue): """ Set color of pixel at specified grid location """ if x < len(self.grid) and y < len(self.grid[0]): self.setPixelColor(self.grid[x][y], red, green, blue) def getPixelColorXY(self, x, y): return self.getPixelColor(self.grid[x][y]) def setRowColor(self, row, red, green, blue): """ Set entire a row to the provided color """ if row < len(self.grid[0]): for x in range(len(self.grid)): self.setPixelColorXY(x, row, red, green, blue) def getRowCount(self): return len(self.grid[0]) def getColumnCount(self): return len(self.grid) def setColumnColor(self, column, red, green, blue): """ Set entire column to the provided color """ if column < len(self.grid): for y in range(len(self.grid[0])): self.setPixelColorXY(column, y, red, green, blue) def setGridColor(self, red, green, blue): for i in range(self.numPixels()): self.setPixelColor(i, red, green, blue) def drawSquare(self, x, y, width, height, red, green, blue): for w in range(width): for h in range(height): self.setPixelColorXY(x + w, y - h, red, green, blue) def show(self): """ Refresh LEDs """ self.strip.show() def numPixels(self): """ The strips LED count """ return self.strip.numPixels() def setBrightness(self, brightness): LEDShow.LED_BRIGHTNESS = brightness self.strip.setBrightness(LEDShow.LED_BRIGHTNESS) def getBrightness(self): return LEDShow.LED_BRIGHTNESS def getMaxDistance(self): return LEDShow.MAX_DISTANCE def getMinDistance(self): return LEDShow.MIN_DISTANCE
class LaserControlMain(QtGui.QMainWindow): ## @var act_stell_pos # Signal to communications with the Telescope_Server instance # It emits when we want to send to Stellarium the equatorial coordinates act_stell_pos = QtCore.pyqtSignal(str, str) ## Class constructor # # Starts the UI and the Telescope_Server instance # # \param parent (optional) Parent object. By default is None def __init__(self, parent=None): super(LaserControlMain, self).__init__(parent) self.confMode = False self.nRef = 0 self.device = None (self._ra, self._dec) = ("0h0m0s", "0º0'0''") self.ui = Ui_LaserControl() self.ui.setupUi(self) self.ui.Reconfigure.setVisible(False) regex=QtCore.QRegExp("%s" % (_fromUtf8("^-?[0-9]{1,3}(º|ᵒ)[0-9]{1,3}'[0-9]{1,3}([']{2}|\")$"))) self.Valid=QtGui.QRegExpValidator(regex, self) self.ui.posHorizontal.setValidator(self.Valid) self.ui.posVertical.setValidator(self.Valid) self.ui.posHorizontal.setText("%s" % (_fromUtf8("0º0'0''"))) self.ui.posVertical.setText("%s" % (_fromUtf8("0º0'0''"))) self.ui.tabWidget.setCurrentIndex(1) self.ui.tabWidget.setTabEnabled(1, False) self.pos = ('0.0000', '0.0000') self._prev_pos = ("0º0'0''", "0º0'0''") #Starts server self.Server = Telescope_Server(pos_signal=self.act_stell_pos) self.Server.daemon = True self.Server.start() self.setSignals() self.setShortcuts() #At the beginning, configuration mode is On self.ui.confMode.setChecked(True) ## Connects the UI signals # def setSignals(self): #Movements QtCore.QObject.connect(self.ui.upButton, QtCore.SIGNAL("pressed()"), self.upPressed) QtCore.QObject.connect(self.ui.downButton, QtCore.SIGNAL("pressed()"), self.downPressed) QtCore.QObject.connect(self.ui.rightButton, QtCore.SIGNAL("pressed()"), self.rightPressed) QtCore.QObject.connect(self.ui.leftButton, QtCore.SIGNAL("pressed()"), self.leftPressed) QtCore.QObject.connect(self.ui.upButton, QtCore.SIGNAL("released()"), self.arrow_released) QtCore.QObject.connect(self.ui.downButton, QtCore.SIGNAL("released()"), self.arrow_released) QtCore.QObject.connect(self.ui.rightButton, QtCore.SIGNAL("released()"), self.arrow_released) QtCore.QObject.connect(self.ui.leftButton, QtCore.SIGNAL("released()"), self.arrow_released) #Position QtCore.QObject.connect(self.ui.posVertical, QtCore.SIGNAL("editingFinished()"), self.posChanged) QtCore.QObject.connect(self.ui.posHorizontal, QtCore.SIGNAL("editingFinished()"), self.posChanged) #Laser QtCore.QObject.connect(self.ui.laserOn, QtCore.SIGNAL("toggled(bool)"), self.laserToggled) #Options QtCore.QObject.connect(self.ui.confMode, QtCore.SIGNAL("toggled(bool)"), self.confModeChanged) QtCore.QObject.connect(self.ui.trackMode, QtCore.SIGNAL("toggled(bool)"), self.trackModeChanged) #Device connection QtCore.QObject.connect(self.ui.action_Conectar, QtCore.SIGNAL("triggered(bool)"), self.connectDevice) QtCore.QObject.connect(self.ui.action_Desconectar, QtCore.SIGNAL("triggered(bool)"), self.closeDevice) #El dispositivo debe recalcular el número de pasos por vuelta en cada eje QtCore.QObject.connect(self.ui.action_Recalibrar, QtCore.SIGNAL("triggered(bool)"), self.initDevice) #Stellarium.. self.Server.stell_pos_recv.connect(self.stellariumRecv) ## Shortcuts for the device movements # def setShortcuts(self): self.ui.leftB_shortCut = QtGui.QShortcut(QtGui.QKeySequence("Shift+Left"), self, self.ui.leftButton.animateClick) self.ui.rightB_shortCut = QtGui.QShortcut(QtGui.QKeySequence("Shift+Right"), self, self.ui.rightButton.animateClick) self.ui.upB_shortCut = QtGui.QShortcut(QtGui.QKeySequence("Shift+Up"), self, self.ui.upButton.animateClick) self.ui.downB_shortCut = QtGui.QShortcut(QtGui.QKeySequence("Shift+Down"), self, self.ui.downButton.animateClick) ## Handles the coordinate reception from Stellarium # # Receives the coordinates from Stellarium by the Telescope_Server instance. # If the device is connected, sends the coordinates to it, as either the configuration or movement values. # # Also manages the UI status along the configuration process. # # \param ra Right ascension # \param dec Declination # \param mtime Timestamp def stellariumRecv(self, ra, dec, mtime): ra = float(ra) dec = float(dec) mtime = float(mtime) logging.debug("%s" % coords.toJ2000(ra, dec, mtime)) (sra, sdec, stime) = coords.eCoords2str(ra, dec, mtime) (self._ra, self._dec) = (sra, sdec) if self.device != None: logging.debug("Sending to the device: '%s','%s','%s'" % (sra, sdec, stime)) try: if self.ui.Reconfigure.isChecked(): if self.ui.redef_1: self.ui.redef_1.setChecked(False) redef = 1 elif self.ui.redef_2: self.ui.redef_2.setChecked(False) redef = 2 else: self.ui.redef_3.setChecked(False) redef = 3 self.ui.Reconfigure.setChecked(False) self.device.setRef(redef, sra, sdec, stime) elif not self.confMode: self.device.goto(sra, sdec, stime) else: self.nRef = self.nRef + 1 self.ui.text_status.setText("References: %d/2" % self.nRef) self.device.setRef(self.nRef, sra, sdec, stime) if self.nRef == 2: self.setConfigDone() self.nRef = 0 except: logging.debug("Device not found..") e = sys.exc_info()[1] print("Error: %s" % e) ## Up key pushed # # Starts the upward movement of the device def upPressed(self): if self.device != None: self.device.movy('1') ## Down key pushed # # Starts the downward movement def downPressed(self): if self.device != None: self.device.movy('0') ## Right key pushed # # Starts the clockwise movement def rightPressed(self): if self.device != None: self.device.movx('1') ## Left key pushed # # Starts the counter clockwise movement def leftPressed(self): if self.device != None: self.device.movx('0') ## Up/Down/Right/Left key released.. # # Stops any movement def arrow_released(self): if self.device != None: self.device.stop() ## Handles the changes on the coordinates text boxes # # If the device is configured, sends the new coordinates to it def posChanged(self): logging.debug("(%s, %s)" % (self.ui.posHorizontal.text(), self.ui.posVertical.text())) x = _toUtf8(self.ui.posHorizontal.text()) y = _toUtf8(self.ui.posVertical.text()) if self.device != None and (self._prev_pos[0]!=x or self._prev_pos[1]!=y): logging.debug("Sending (%s, %s) to device" % (x, y)) self.device.move(x,y) self._prev_pos = (x, y) ## Handles the changes on "configuration mode" check box # def confModeChanged(self): if self.ui.confMode.isChecked(): self.confMode = True self.nRef = 0 logging.debug("Conf mode ON") else: self.setConfigDone() self.confMode = False logging.debug("Conf mode Off") ## Handles the end of the device configuration process # def setConfigDone(self): self.ui.confMode.setChecked(False) self.ui.tabWidget.setTabEnabled(1, True) self.ui.tabWidget.setCurrentIndex(1) self.ui.text_status.setText("References: 2/2") self.ui.confMode.setVisible(False) self.ui.textEdit.setVisible(False) self.ui.Reconfigure.setVisible(True) ## Handles changes on tracking check box # # If check is On, starts the tracking mode on the device def trackModeChanged(self): if self.ui.trackMode.isChecked(): self.track = RepeatTimer(5.0, self.tracking) self.track.start() logging.debug("Track mode ON") else: self.track.cancel() logging.debug("Track mode Off") ## Starts the device connection # # In case of error, shows the message on UI def connectDevice(self): self.ui.action_Conectar.setEnabled(False) self.ui.action_Desconectar.setEnabled(True) self.ui.action_Recalibrar.setEnabled(True) logging.info("Connecting device") try: if self.device == None: self.device = LaserDev(usb_serial='/dev/ttyUSB0')#TODO.. make this configurable.. self.device.init_received.connect(self.init_received) self.device.pos_received.connect(self.pos_received) self.device.pos_e_received.connect(self.pos_e_received) self.device.start() except: logging.info("Device not found") QtGui.QMessageBox.warning(self, 'Warning', "Device not found") self.ui.action_Conectar.setEnabled(True) self.ui.action_Desconectar.setEnabled(False) self.ui.action_Recalibrar.setEnabled(False) self.device = None ## Initialize device # # The device will calculate the steps per revolution def initDevice(self): logging.info("Initializing device..") try: if self.device != None: self.device.init() except: logging.info("Error initializing device.") ## Receives the end of initialization signal from the device # # That signal indicates that the device is successfully initialized def init_received(self): logging.debug("Init received") self.pos = ('0.0000', '0.0000') self.ui.posHorizontal.setText("%s" % _fromUtf8("0º0'0''")) self.ui.posVertical.setText("%s" % _fromUtf8("0º0'0''")) ## Receives the position updated signal from the device # # The parameters are the horizontal coordinates which the device points to def pos_received(self, x, y): logging.debug("%s,%s" % (x, y)) self.pos = (x, y) self.ui.posHorizontal.setText("%s" % _fromUtf8(coords.deg_2_degStr(360.0 - coords.radStr_2_deg(self.pos[0])))) self.ui.posVertical.setText("%s" % _fromUtf8(coords.radStr_2_degStr(self.pos[1]))) ## Receives the position updated signal from the device # # The parameters are the equatorial coordinates which the device points to def pos_e_received(self, x, y): logging.debug("%s,%s" % (x, y)) self.act_stell_pos.emit(x, y) ## Tracking mode # # Updates periodically the device position by sending the equatorial coordinates and time def tracking(self): logging.debug("('%s', '%s', '%s')" % (self._ra, self._dec, strftime("%Hh%Mm%Ss", localtime()))) if self.device != None and self._ra != '0h0m0s': self.device.goto( self._ra, self._dec, strftime("%Hh%Mm%Ss", localtime()) ) ## Laser toggle.. # def laserToggled(self): if self.ui.laserOn.isChecked(): if self.device != None: self.device.laserOn() logging.debug("Laser ON") else: if self.device != None: self.device.laserOff() logging.debug("Laser Off") ## Close the device connection # def closeDevice(self): self.ui.action_Conectar.setEnabled(True) self.ui.action_Desconectar.setEnabled(False) self.ui.action_Recalibrar.setEnabled(False) logging.info("Disconnecting device..") try: if self.device != None: self.device.close() self.device = None except: self.device = None ## Exit.. # def closeEvent(self, event): logging.debug("Bye!") try: self.Server.close_socket() self.track.cancel() event.accept() except: event.accept()
class Monitor(object): def __init__(self, server_list, monitor_config, mqtt_client): self.interval = monitor_config['interval'] self.recipients = monitor_config['recipients'] self.servers = self.getServers(server_list) self.heartbeatFile = monitor_config['heartbeatFile'] self.heartbeatHours = monitor_config['heartbeatHours'] self.init_sound = monitor_config['init_sound'] self.error_sound = monitor_config['error_sound'] self.success_sound = monitor_config['success_sound'] self.heartbeat_sound = monitor_config['heartbeat_sound'] self.notification_user = monitor_config['notification_user'] self.notification_token = monitor_config['notification_token'] self.notification_url = monitor_config['notification_url'] self.app_name = monitor_config['app_name'] self.hostname = socket.gethostname() self.repeat_timer = None self.mode = 0 self.client = mqtt_client self.learnIp() self.startChecks() self.notify(self.app_name + ' Started', self.init_sound) self.client.publish(self.app_name + ' Started|' + self.get_time() + "|" + self.get_date()) time.sleep(2) self.checkServers() def startChecks(self): """Initalise timer and heartbeat""" self.heartbeat() self.getTimer() def notify(self, mymessage, sound): """Sends a pushover notification""" mytitle = self.hostname + " > monitor." return create_request([self.notification_url], 'POST', { "token": self.notification_token, # Pushover app token "user": self.notification_user, # Pushover user token "html": "1", # 1 for HTML, 0 to disable "title": mytitle, # Title of message "message": mymessage, # Message (HTML if required) "sound": sound, # Sound played on receiving device }) def cancelTimer(self): self.repeat_timer.cancel() def getTimer(self): if self.repeat_timer is None: self.repeat_timer = RepeatTimer(self.interval, self.checkServers, *args, **kwargs) def get_date(self): now = datetime.now() return now.strftime("%d/%m/%Y") def get_time(self): now = datetime.now() return now.strftime("%H:%M") def learnIp(self): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("gmail.com",80)) ip = s.getsockname()[0] self.ip = ip s.close() self.client.publish(self.hostname + "|" + ip) time.sleep(3) logging.info(self.hostname + " IP " + ip) def run(self): logging.info("Run: " + self.app_name) self.repeat_timer.start() def checkServers(self, *args, **kwargs): self.heartbeat() for server in self.servers: _thread.start_new_thread(server.check_status, ()) time.sleep(0.1) time.sleep(1) down_servers = self.getDownServers() if len(down_servers) > 0: self.notifyDown(down_servers) else: mes = "UP @ " + self.get_time() + "|" + self.get_date() logging.info(mes) self.client.publish(mes) self.reset() def getDownServers(self): down_servers = [] for server in self.servers: # if server.status != 'OK' and server.fails >= server.max_fails and server.notified_fail == False: if server.status != 'OK' and server.fails >= server.max_fails: down_servers.append(server) return down_servers def notifyDown(self, down_servers): message = '' for server in down_servers: text = "%s %s %s - %s\n" % (server.name, server.last_checked, server.url, server.status) message += text server.notified_fail = True mes = "Down|" + server.name logging.info(mes) self.client.publish(mes) time.sleep(1) time.sleep(2) self.notify(message, self.error_sound) mes = "DOWN @ " + self.get_time() + "|" + self.get_date() logging.info(mes) self.client.publish(mes) def getServers(self, server_list): servers = [] # for row in records: # print("Id = ", row[0], ) # print("Name = ", row[1]) # print("URL = ", row[2]) # print("Max Fails = ", row[3]) # print("Assert String = ", row[4]) # print("Timeout = ", row[5], "\n") # for server in server_list: # servers.append(Server(name=server['name'], # url=server['url'], # timeout=server['timeout'], # max_fails=server['max_fails'], # assert_string=server['assert_string'])) for server in server_list: servers.append(Server(name=server[1], url=server[2], timeout=server[5], max_fails=server[3], assert_string=server[4])) return servers def reset(self): # logging.info("reset") for server in self.servers: server.notified_fail = False server.fails = 0 server.status = 'OK' server.assert_pass = True def heartbeat(self): # logging.info("heartbeat") filePath = self.heartbeatFile a_name = self.app_name if(os.path.isfile(filePath)): f = open(filePath,"r") last = f.readline() f.close() dt_last = datetime.strptime(last, '%b %d %Y %I:%M%p') hours = math.floor(((datetime.now() - dt_last).total_seconds()) / 3600) if(hours > self.heartbeatHours): self.notify(a_name + ' Heartbeat', self.heartbeat_sound) self.client.publish("Heartbeat @ " + self.get_time() + "|" + self.get_date()) # for recipient in self.recipients: self.writeHeartbeat() else: self.writeHeartbeat() def writeHeartbeat(self): # logging.info("writeHeartbeat") filePath = self.heartbeatFile f = open(filePath,"w") f.write(datetime.now().strftime('%b %d %Y %I:%M%p')) f.close() def update(self): # logging.info('update') self.reset() def setMode(self, mode): self.mode = mode modes = { 0: "Monitor", 1: "Backup", 2: "Configuration", 3: "Connect", 4: "Disconnect", 5: "Reboot", 6: "Shutdown" } mode_text = modes.get(mode, "Unknown") def getMode(self): return self.mode
def getTimer(self): if self.repeat_timer is None: self.repeat_timer = RepeatTimer(self.interval, self.checkServers, *args, **kwargs)
def do_main_program(self): self.running = True print("do_main_program(): Spoustim sluzbu...", flush=True) ntf.notify("READY=1") ntf.notify("STATUS=Inicializuji sluzbu HMP...") conn = self.get_DB() c = conn.cursor() self.sett = {} for r in c.execute("select param, sval from setting"): self.sett[r[0]] = r[1] self.tasks.queue.clear() self.resp.queue.clear() c.execute( "update inprogress set probiha = 0 where akce='NACTENI_STRUKTURY_ZAPOJENI'" ) c.execute( "update inprogress set probiha = 0, sval='Služba spuštěna' where akce='HMP_DAEMON'" ) conn.commit() self.check_serial_comm() #spust GSM modul pokud je potreba try: if int(self.sett["USE_GSM_MODULE"]) == 1: self.gsmth = GsmDaemonTask() self.gsmth.start( self.sett["GSM_USBINTERFACE"], self.sett["GSM_HW_ADDR"], self.sett["GSM_SIM_PIN"], self.sett["GSM_APN_NAME"], self.sett["GSM_APN_USER"], self.sett["GSM_APN_PASS"], int(self.sett["GSM_WATCHDOG_TIMEINTERVAL"]), self.sett["GSM_WATCHDOG_PING_SERVER"]) except: pass self.tlast = time.time() self.thKeepAlive = RepeatTimer(15, self.keep_alive) # kontrola co 15s if int(self.sett["CLOUD_SEND_14H_INTERVAL_SEC"]) > 0: self.thCloudExportHistory = RepeatTimer( int(self.sett["CLOUD_SEND_14H_INTERVAL_SEC"]), self.cloud_export_history) if int(self.sett["CLOUD_SEND_LIVE_INTERVAL_SEC"]) > 0: self.thCloudExportLive = RepeatTimer( int(self.sett["CLOUD_SEND_LIVE_INTERVAL_SEC"]), self.cloud_export_live) self.thHistoryDownload = RepeatTimer( int(self.sett["SERIAL_DOWNLOAD_HISTORY_INTERVAL_SEC"]), self.download_history) # kontrola co 900s self.thKonstantyRefresh = RepeatTimer(910, self.reload_konstanty) self.thClearHistory = RepeatTimer(86400, self.clean_history) self.clean_history() self.reload_konstanty() self.download_history() while self.running: try: #posbirej dotazy na hmp zarizeni a posli je do 485 pouze 5 zaznamu for q in c.execute( "select id, prikaz, typ_dotazu, isql, iscmd, iswrite from serial_prikaz where odpoved is null and islock=0 order by id asc limit 8" ).fetchall(): if q[4] == 1: #jedna se o prikaz pro sluzbu, provadi se ihned if q[1] == "FLUSH_QUEQUE": with self.tasks.mutex: self.tasks.queue.clear() elif q[1] == "RESTART": with self.tasks.mutex: self.tasks.queue.clear() self.running = False self.restart() elif q[3] == 1: #jedna se o sql prikaz ten se provadi FIFO self.tasks.put({ 'data': q[1], 'id': q[0], 'typ': q[2], 'sql': 1, 'wr': 0 }) else: bf = conv_str_hex_in_bytes(q[1]) self.tasks.put({ 'data': bf, 'id': q[0], 'typ': q[2], 'sql': 0, 'wr': q[5] }) c.execute("update serial_prikaz set islock=1 where id=?", (q[0], )) conn.commit() self.check_serial_comm() ntf.notify("WATCHDOG=1") while self.resp.qsize() > 0: # odpoved od HMP rs = self.resp.get() if rs['sql'] == 1: c.execute(rs['data']) c.execute( "update serial_prikaz set odpoved='sql_done', cas_odpoved=CURRENT_TIMESTAMP where id=?", (rs['id'], )) conn.commit() self.resp.task_done() continue #zaznamenej cas kdy naposledy odpovedel dfrom = telegram_get_from(rs['data']) try: if rs['id'] > 0: self.tlast = time.time() c.execute( "update serial_prikaz set odpoved=?, cas_odpoved=CURRENT_TIMESTAMP where id=?", ( conv_hex_to_str(rs['data']), rs['id'], )) conn.commit() fce = switcher_process(rs['typ']) fce(c, rs['data'], dfrom) else: #aktualni bezny datagram spotreba fce = switcher_process(-1) #vychozi fce(c, rs['data'], dfrom) except Exception as e: print( "do_main_program()[call]: Ex: {}, Typ: {}, Id: {}, Data: {}" .format(str(e), rs['typ'], rs['id'], conv_hex_to_str(rs['data'])), flush=True) pass conn.commit() self.resp.task_done() except sqlite3.OperationalError as ex: ntf.notify("ERRNO=1") except Exception as e: print( "do_main_program()[2]: Ex: {}, Typ: {}, Id: {}, Data: {}". format(str(e), rs['typ'], rs['id'], conv_hex_to_str(rs['data'])), flush=True) pass time.sleep(0.1) conn.close() #ukonci komunikaci sluzba nebezi self.sth.running = False print("do_main_program(): Konec sluzby...", flush=True) ntf.notify("STOPPING=1")