def set_frame(self, minx, miny, width, height): # passed in pixels are the "size" of the current binning # # # INDI expects us to set frame in 1x1 pixels # ccd_frame = indihelper.getNumber(self.cam, 'CCD_FRAME') if ccd_frame is None: return False binx, biny = self.get_binning() if None in [binx, biny]: logging.error('set_frame: unable to determine binning!') return False logging.debug(f'set_frame: binning = {binx} {biny}') ccd_x = indihelper.findNumber(ccd_frame, 'X') ccd_y = indihelper.findNumber(ccd_frame, 'Y') ccd_w = indihelper.findNumber(ccd_frame, 'WIDTH') ccd_h = indihelper.findNumber(ccd_frame, 'HEIGHT') # logging.debug(f'set_frame: {minx} {miny} {width} {height} {ccd_x.value} ' # f'{ccd_y.value} {ccd_w.value} {ccd_h.value}') if None in [ccd_x, ccd_y, ccd_w, ccd_h]: return False ccd_x.value = minx * binx ccd_y.value = miny * biny ccd_w.value = width * binx ccd_h.value = height * biny self.backend.indiclient.sendNewNumber(ccd_frame) return True
def get_info(self): ccd_info = indihelper.getNumber(self.cam, 'CCD_INFO') if ccd_info is None: return None maxx = indihelper.findNumber(ccd_info, 'CCD_MAX_X') maxy = indihelper.findNumber(ccd_info, 'CCD_MAX_Y') pix_size = indihelper.findNumber(ccd_info, 'CCD_PIXEL_SIZE') pix_size_x = indihelper.findNumber(ccd_info, 'CCD_PIXEL_SIZE_X') pix_size_y = indihelper.findNumber(ccd_info, 'CCD_PIXEL_SIZE_Y') bpp = indihelper.findNumber(ccd_info, 'CCD_BITSPERPIXEL') # if maxx is None or maxy is None is pix_size is None \ # or pix_size_x is None or pix_size_y is None or bpp is None: if None in [maxx, maxy, pix_size, pix_size_x, pix_size_y, bpp]: return None obj = self.CCD_INFO() obj.CCD_MAX_X = maxx.value obj.CCD_MAX_Y = maxy.value obj.CCD_PIXEL_SIZE = pix_size.value obj.CCD_PIXEL_SIZE_X = pix_size_x.value obj.CCD_PIXEL_SIZE_Y = pix_size_y.value obj.CCD_BITSPERPIXEL = bpp.value return obj
def get_frame(self): ccd_frame = indihelper.getNumber(self.cam, 'CCD_FRAME') if ccd_frame is None: return None ccd_x = indihelper.findNumber(ccd_frame, 'X') ccd_y = indihelper.findNumber(ccd_frame, 'Y') ccd_w = indihelper.findNumber(ccd_frame, 'WIDTH') ccd_h = indihelper.findNumber(ccd_frame, 'HEIGHT') if None in [ccd_x, ccd_y, ccd_w, ccd_h]: return (None, None, None, None) # called expects pixels are the "size" of the current binning # # # INDI returns frame in 1x1 pixels # binx, biny = self.get_binning() if None in [binx, biny]: logging.error('get_frame: unable to determine binning!') return False # logging.debug(f'get_frame: binning = {binx} {biny}') return (ccd_x.value // binx, ccd_y.value // biny, ccd_w.value // binx, ccd_h.value // biny)
def get_binning(self): ccd_bin = indihelper.getNumber(self.cam, 'CCD_BINNING') binx = indihelper.findNumber(ccd_bin, 'HOR_BIN') biny = indihelper.findNumber(ccd_bin, 'VER_BIN') if binx is None or biny is None: return None, None return (binx.value, biny.value)
def start_exposure(self, expos): logging.debug(f'Exposing image for {expos} seconds') # FIXME currently always requesting a light frame # FIXME need to check return codes of all steps if self.cam: ccd_exposure = indihelper.getNumber(self.cam, 'CCD_EXPOSURE') if ccd_exposure is None: return False # we should inform the indi server that we want to receive the # 'CCD1' blob from this device # FIXME not good to reference global 'config' here - we already pass # a device object should combine? self.backend.indiclient.setBLOBMode(PyIndi.B_ALSO, self.name, 'CCD1') ccd_ccd1 = self.cam.getBLOB('CCD1') while not ccd_ccd1: time.sleep(0.25) ccd_ccd1 = self.device.getBLOB('CCD1') self.backend.indiclient.clearBlobEvent() ccd_expnum = indihelper.findNumber(ccd_exposure, 'CCD_EXPOSURE_VALUE') if ccd_expnum is None: return False ccd_expnum.value = expos self.backend.indiclient.sendNewNumber(ccd_exposure) return True else: return False
def sync(self, ra, dec): """Sync to ra/dec with ra in decimal hours and dec in degrees""" logging.debug(f'sync to {ra} {dec}') #logging.debug('finding) ON_COORD_SET switch') indihelper.setfindSwitchState(self.backend.indiclient, self.mount, 'ON_COORD_SET', 'SYNC', True) indihelper.setfindSwitchState(self.backend.indiclient, self.mount, 'ON_COORD_SET', 'SLEW', False) indihelper.setfindSwitchState(self.backend.indiclient, self.mount, 'ON_COORD_SET', 'TRACK', False) #logging.debug('getNumber EQUATORIAL_EOD_COORD') eq_coord = indihelper.getNumber(self.mount, 'EQUATORIAL_EOD_COORD') if eq_coord is None: return False #logging.debug('findNumber "RA"') ra_coord = indihelper.findNumber(eq_coord, 'RA') if ra_coord is None: return False #logging.debug('findNumber "DEC"') dec_coord = indihelper.findNumber(eq_coord, 'DEC') if dec_coord is None: return False #logging.debug(f'{ra_coord.value} {dec_coord.value}') ra_coord.value = ra dec_coord.value = dec #logging.debug(f'{ra_coord.value} {dec_coord.value}') #logging.debug('sending Number') self.backend.indiclient.sendNewNumber(eq_coord) return True
def set_binning(self, binx, biny): ccd_bin = indihelper.getNumber(self.cam, 'CCD_BINNING') if ccd_bin is None: return False num_binx = indihelper.findNumber(ccd_bin, 'HOR_BIN') num_biny = indihelper.findNumber(ccd_bin, 'VER_BIN') if num_binx is None or num_biny is None: return False num_binx.value = binx num_biny.value = biny self.backend.indiclient.sendNewNumber(ccd_bin) return True
def get_cooler_power(self): if self.camera_has_cooler_power is False: return None cool_power = indihelper.getNumber(self.cam, 'CCD_COOLER_POWER') if cool_power is None: self.camera_has_cooler_power = False return None num = indihelper.findNumber(cool_power, 'CCD_COOLER_VALUE') if num is None: self.camera_has_cooler_power = False return None return num.value
def get_min_max_exposure(self): if self.cam: ccd_exposure = indihelper.getNumber(self.cam, 'CCD_EXPOSURE') if ccd_exposure is None: return None ccd_expnum = indihelper.findNumber(ccd_exposure, 'CCD_EXPOSURE_VALUE') if ccd_expnum is None: return None return (ccd_expnum.min, ccd_expnum.max) else: return None
def get_camera_usbbandwidth(self): """ Looks for camera specific usb traffic - only works for ASI afaik""" if self.cam: ccd_controls = indihelper.getNumber(self.cam, 'CCD_CONTROLS') if ccd_controls is None: return None ccd_usb = indihelper.findNumber(ccd_controls, 'BandWidth') if ccd_usb is None: return None return ccd_usb.value else: return None
def get_camera_offset(self): """ Looks for camera specific offset - only works for ASI afaik""" if self.cam: ccd_controls = indihelper.getNumber(self.cam, 'CCD_CONTROLS') if ccd_controls is None: return None ccd_offset = indihelper.findNumber(ccd_controls, 'Offset') if ccd_offset is None: return None return ccd_offset.value else: return None
def get_camera_gain(self): """ Looks for camera specific gain - only works for ASI afaik""" if self.cam: ccd_controls = indihelper.getNumber(self.cam, 'CCD_CONTROLS') if ccd_controls is None: return None ccd_gain = indihelper.findNumber(ccd_controls, 'Gain') if ccd_gain is None: return None return ccd_gain.value else: return None
def get_max_binning(self): if self.cam: ccd_bin = indihelper.getNumber(self.cam, 'CCD_BINNING') #logging.info(f'ccd_bin={ccd_bin}') if ccd_bin is None: return None ccd_hbin = indihelper.findNumber(ccd_bin, 'HOR_BIN') #logging.info(f'ccd_hbin={indihelper.dump_Number(ccd_hbin)}') if ccd_hbin is None: return None return ccd_hbin.max else: return None
def slew(self, ra, dec): """Slew to ra/dec with ra in decimal hours and dec in degrees""" indihelper.setfindSwitchState(self.backend.indiclient, self.mount, 'ON_COORD_SET', 'SLEW', False) indihelper.setfindSwitchState(self.backend.indiclient, self.mount, 'ON_COORD_SET', 'TRACK', True) indihelper.setfindSwitchState(self.backend.indiclient, self.mount, 'ON_COORD_SET', 'SYNC', False) eq_coord = indihelper.getNumber(self.mount, 'EQUATORIAL_EOD_COORD') if eq_coord is None: return False self.slew_eqcoord = eq_coord ra_coord = indihelper.findNumber(eq_coord, 'RA') if ra_coord is None: return False dec_coord = indihelper.findNumber(eq_coord, 'DEC') if dec_coord is None: return False ra_coord.value = ra dec_coord.value = dec self.backend.indiclient.sendNewNumber(eq_coord) return True