×

INDI Library v2.0.6 is Released (02 Feb 2024)

Bi-monthly release with minor bug fixes and improvements

Trying to debug a PyIndi-client script

  • Posts: 102
  • Thank you received: 13
Dear all,
I would like to setup a simple script to acquire multiple images from my DSLR (Cannon EOS 350D). To do so, I tried to follow the nice tutorial here:
indilib.org/develop/tutorials/151-time-l...ith-indi-python.html

Unfortunately, I got the following error:
    self.logger.info("new Message "+ d.messageQueue(m).decode())
AttributeError: 'SwigPyObject' object has no attribute 'decode'

Related to the following line:
def newMessage(self, d, m):
        self.logger.info("new Message "+ d.messageQueue(m).decode())

It should be noticed that I use the indi server along with the CCD Simulator driver:
indiserver indi_simulator_ccd

What is wrong with this code ?

Thank you very much for your help
6 years 8 months ago #17674

Please Log in or Create an account to join the conversation.

  • Posts: 226
  • Thank you received: 88
Hi,
The code in this tutorial is for Python2 (and it works, I just tested), I got the following error using Python3:
Traceback (most recent call last):
  File "timelapse.py", line 48, in newText
    self.logger.info("new Text "+ tvp.name.decode() + " for device "+ tvp.device.decode())
AttributeError: 'str' object has no attribute 'decode'
Which is not the same error as yours...
So I wonder how did you install the Pyindi client wrapper: you have to use pip now, the repo given in the tutorial is no longer maintained.
pip install pyindi-client
or pip3 if you use python3.
See here for more info.
Now I've got no newMessage from the driver when running the script in Python2, so not sure what's going on in your case...
6 years 8 months ago #17691

Please Log in or Create an account to join the conversation.

  • Posts: 102
  • Thank you received: 13
Thank you Gaheel,

While the initial post was being reviewed by admin, I solved the peoblem, I'll post my python3 version of the tutorial:
import sys, time, logging
import PyIndi
import io
 
class IndiClient(PyIndi.BaseClient):
  device=None
  imgIdx=0
  def __init__(self):
   super(IndiClient, self).__init__()
   self.logger = logging.getLogger('PyQtIndi.IndiClient')
   self.logger.info('creating an instance of PyQtIndi.IndiClient')
  def newDevice(self, d):
    self.logger.info("new device " + d.getDeviceName())
    if d.getDeviceName() == "CCD Simulator":
      self.logger.info("Set new device CCD Simulator!")
      # save reference to the device in member variable
      self.device = d
  def newProperty(self, p):
    self.logger.info("new property "+ p.getName() +
      " for device "+ p.getDeviceName())
    if (self.device is not None 
        and p.getName() == "CONNECTION" 
        and p.getDeviceName() == self.device.getDeviceName()):
      self.logger.info("Got property CONNECTION for CCD Simulator!")
      # connect to device
      self.connectDevice(self.device.getDeviceName())
      # set BLOB mode to BLOB_ALSO
      self.setBLOBMode(1, self.device.getDeviceName(), None)
    if p.getName() == "CCD_EXPOSURE":
      # take first exposure
      self.takeExposure()
  def removeProperty(self, p):
   self.logger.info("remove property "+ p.getName() +
     " for device "+ p.getDeviceName())
  def newBLOB(self, bp):
    self.logger.info("new BLOB "+ bp.name)
    # get image data
    img = bp.getblobdata()
    # write image data to StringIO buffer
    blobfile = io.BytesIO(img)
    # open a file and save buffer to disk
    with open("frame"+str(self.imgIdx)+".fit", "wb") as f:
      f.write(blobfile.getvalue())
    self.imgIdx+=1
    # start new exposure for timelapse images!
    self.takeExposure()
  def newSwitch(self, svp):
    self.logger.info ("new Switch "+ svp.name.decode() +
      " for device "+ svp.device.decode())
  def newNumber(self, nvp):
    self.logger.info("new Number "+ nvp.name +
      " for device "+ nvp.device)
  def newText(self, tvp):
    self.logger.info("new Text "+ tvp.name.decode() +
      " for device "+ tvp.device.decode())
  def newLight(self, lvp):
    self.logger.info("new Light "+ lvp.name.decode() +
      " for device "+ lvp.device.decode())
  def newMessage(self, d, m):
    self.logger.info("new Message "+ d.messageQueue(m).decode())
  def serverConnected(self):
    print("Server connected ("+self.getHost()+":"+str(self.getPort())+")")
  def serverDisconnected(self, code):
    self.logger.info("Server disconnected (exit code = "+str(code)
      +","+str(self.getHost())+":"+str(self.getPort())+")")
  """ 
    Now application related methods
  """
  def takeExposure(self):
    self.logger.info("<<<<<<<< Exposure >>>>>>>>>")
    # get current exposure time
    exp = self.device.getNumber("CCD_EXPOSURE")
    # set exposure time to 5 seconds
    exp[0].value = 5
    # send new exposure time to server/device
    self.sendNewNumber(exp)
 
 
 
#Configure logger
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
 
# instantiate the client
indiclient=IndiClient()
# set indi server localhost and port 7624
#indiclient.setServer("192.168.0.73",7624)
indiclient.setServer("localhost",7624)
# connect to indi server
print("Connecting and waiting 2secs")
if (not(indiclient.connectServer())):
  print("No indiserver running on "+indiclient.getHost()+":"+
    str(indiclient.getPort())+" - Try to run")
  print("  indiserver indi_simulator_telescope indi_simulator_ccd")
  sys.exit(1)
 
time.sleep(1)
 
# start endless loop, client works asynchron in background
while True:
    time.sleep(1)
 
 
#One can now open images:
#from astropy.io import fits
#hdulist = fits.open('input.fits')
#hdulist.info()
#plt.imshow(hdulist[0].data)
#plt.show()
#del hdul[0].data
#hdulist.close
6 years 8 months ago #17693

Please Log in or Create an account to join the conversation.

  • Posts: 102
  • Thank you received: 13
PS: any comment on how to add cooling periods for the ccd between exposure, or simply writing better python code (avoid polling) would be much appreciated :)
6 years 8 months ago #17696

Please Log in or Create an account to join the conversation.

  • Posts: 49
  • Thank you received: 20
Hi,

I just updated the tutorial. No it should work with Python2 and 3: indilib.org/develop/tutorials/151-time-l...ith-indi-python.html
Tested with OrangePi zero and Armbian.

If you want to add a cooling period, just add a
time.sleep(cooling_period)
before
self.takeExposure()
in
newBLOB(self, bp)
so it waits some seconds before it resets the exposure timer.

Where does the code poll? At the moment the member functions of the IndiBaseClient are called asynchronous. You just could add a signal handler to terminate the program/endless loop properly.
The following user(s) said Thank You: Jasem Mutlaq, dolguldur
6 years 8 months ago #17802

Please Log in or Create an account to join the conversation.

Time to create page: 0.469 seconds