×

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

Bi-monthly release with minor bug fixes and improvements

PyIndi without IndiClient class

  • Posts: 11
  • Thank you received: 0
I would like to know, whether it is possible to communicate with a CCD through PyIndi without having to construct a IndiClient class and only using functions.

E.g.

class IndiClient(PyIndi.BaseClient):
def __init__(self):
super(IndiClient, self).__init__()
self.logger = logging.getLogger('IndiClient')
self.logger.info('creating an instance of IndiClient')

....

indiclient=IndiClient()
indiclient.setServer("localhost",7624)


why can't I just ?

indiclient=PyIndi.BaseClient()
indiclient.setServer("localhost",7624)

Is there anyway to get around using classes?
3 years 7 months ago #57898

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

  • Posts: 12
  • Thank you received: 0
What difference does it make? I imagine they both work. The first one is more Pythonic and in the longer term you will find it easier to maintain.

If you write procedural code, like your second example eventually it will become more spaghetti-like and you split it into classes to maintain it. Much easier to start with classes.

Sorry to lecture you.

Regards,

Steve.
3 years 7 months ago #58038

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

  • Posts: 11
  • Thank you received: 0
Hi Steve, Thank you for the quick reply.
It makes a large difference for first time users of the module and for people that don't want to spend hours on writing a simple script just to take a picture.


No, the second one doesn't work

What do you mean with Pythonic? Isn't Pythonic the opposite ... like clear and efficient ?
- towardsdatascience.com/how-to-be-pythoni...ld-care-188d63a5037e
- stackoverflow.com/questions/25011078/what-does-pythonic-mean

Or do you mean bureaucratic?

Usually, one can use IPython or Jupyter notebooks to play around with python libraries. That way one can get around reading manuals and documentation, using the tab key to get all available functions and so on.

As far as I can tell, this is not really possible with PyIndi, since you first have to check with the documentation, which tells you to construct an unnecessary class like some bureaucrat at the DMV (I am a scientist, I don't respect bureaucrats) .

But thanks for the lecture.

Cheers,

Stefan
3 years 7 months ago #58047

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

  • Posts: 12
  • Thank you received: 0
Hi Stefan,

Sorry for the delay, my computer broke and I had to buy a new monitor.

I'm sure you saw this:
#!/usr/bin/env python
 
# for logging
import sys
import time
import logging
# import the PyIndi module
import PyIndi
 
# Fancy printing of INDI states
# Note that all INDI constants are accessible from the module as PyIndi.CONSTANTNAME
def strISState(s):
    if (s == PyIndi.ISS_OFF):
        return "Off"
    else:
        return "On"
def strIPState(s):
    if (s == PyIndi.IPS_IDLE):
        return "Idle"
    elif (s == PyIndi.IPS_OK):
        return "Ok"
    elif (s == PyIndi.IPS_BUSY):
        return "Busy"
    elif (s == PyIndi.IPS_ALERT):
        return "Alert"
 
# The IndiClient class which inherits from the module PyIndi.BaseClient class
# It should implement all the new* pure virtual functions.
class IndiClient(PyIndi.BaseClient):
    def __init__(self):
        super(IndiClient, self).__init__()
        self.logger = logging.getLogger('IndiClient')
        self.logger.info('creating an instance of IndiClient')
    def newDevice(self, d):
        self.logger.info("new device " + d.getDeviceName())
    def newProperty(self, p):
        self.logger.info("new property "+ p.getName() + " for device "+ p.getDeviceName())
    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.decode())
    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.decode() + " for device "+ nvp.device.decode())
    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):
        self.logger.info("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())+")")
 
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
 
# Create an instance of the IndiClient class and initialize its host/port members
indiclient=IndiClient()
indiclient.setServer("192.168.1.105",7624)
 
# Connect to server
print("Connecting and waiting 1 sec")
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)
 
# Print list of devices. The list is obtained from the wrapper function getDevices as indiclient is an instance
# of PyIndi.BaseClient and the original C++ array is mapped to a Python List. Each device in this list is an
# instance of PyIndi.BaseDevice, so we use getDeviceName to print its actual name.
print("List of devices")
dl=indiclient.getDevices()
for dev in dl:
    print(dev.getDeviceName())
 
# Print all properties and their associated values.
print("List of Device Properties")
devices={}
for d in dl:
    print("-- "+d.getDeviceName())
    devices[d.getDeviceName()]={}
    lp=d.getProperties()
    for p in lp:
        print("   > "+p.getName())
        devices[d.getDeviceName()][p.getName()]={}
        if p.getType()==PyIndi.INDI_TEXT:
            tpy=p.getText()
            for t in tpy:
                devices[d.getDeviceName()][p.getName()][t.name]=[t.label, p.getType(), t.text]
                print("T       "+t.name+"("+t.label+")= "+t.text)
        elif p.getType()==PyIndi.INDI_NUMBER:
            tpy=p.getNumber()
            for t in tpy:
                devices[d.getDeviceName()][p.getName()][t.name]=[t.label, p.getType(), str(t.value)]
                print("N       "+t.name+"("+t.label+")= "+str(t.value))
        elif p.getType()==PyIndi.INDI_SWITCH:
            tpy=p.getSwitch()
            for t in tpy:
                devices[d.getDeviceName()][p.getName()][t.name]=[t.label, p.getType(), strISState(t.s)]
                print("S       "+t.name+"("+t.label+")= "+strISState(t.s))
        elif p.getType()==PyIndi.INDI_LIGHT:
            tpy=p.getLight()
            for t in tpy:
                devices[d.getDeviceName()][p.getName()][t.name]=[t.label, p.getType(), strIPState(t.s)]
                print("L       "+t.name+"("+t.label+")= "+strIPState(t.s))
        elif p.getType()==PyIndi.INDI_BLOB:
            tpy=p.getBLOB()
            for t in tpy:
                devices[d.getDeviceName()][p.getName()][t.name]=[t.label, p.getType(), str(t.size)
                                                                 ]
                print("B       "+t.name+"("+t.label+")= <blob "+str(t.size)+" bytes>")
print(devices)
# Disconnect from the indiserver
print("Disconnecting")
indiclient.disconnectServer()

This is what I use and it works fine.

Regards

Steve.
3 years 7 months ago #58170

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

  • Posts: 180
  • Thank you received: 30
.

This is not exact. You can use ipython, for example (same it is expected from Jupyter), and you can use tab to get module objects or use other typical info tricks such as whatever_function? to get info on function parameters.

It is far from being the best/complete documentation possible (specially in a language that promotes inline documentation of modules, function and classes) but you cannot say it is not there.
3 years 7 months ago #58174

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

Time to create page: 0.706 seconds