[Kstars-devel] [kstars] kstars: Introducing Ekos, a new tool for KStars that will empower amateur astronomers to utilize INDI based devices to perform essential functions in astrophotography:

Jasem Mutlaq mutlaqja at ikarustech.com
Wed Jan 25 21:57:13 UTC 2012


Git commit 18227de7bc08503da826f930c93720c8d1cc29e4 by Jasem Mutlaq.
Committed on 25/01/2012 at 22:51.
Pushed by mutlaqja into branch 'master'.

Introducing Ekos, a new tool for KStars that will empower amateur astronomers to utilize INDI based devices to perform essential functions in astrophotography:

+ Alignment: Facilitates polar alignment procedure.
+ Focus: Manual and Auto Focusing algorithms.
+ Guide: Guide the mount for accurate tracking for extended periods of time.
+ Capture: Capture CCDs images individually or in batch along with filter selection support.

This is a very early release and only basic functionality is provided. The above features will be added with time.

CCMAIL:kstars-devel at kde.org

M  +15   -2    kstars/CMakeLists.txt
M  +1    -1    kstars/dialogs/detaildialog.cpp
A  +12   -0    kstars/ekos/ccd.cpp     [License: UNKNOWN]  *
A  +21   -0    kstars/ekos/ccd.h     [License: UNKNOWN]  *
A  +290  -0    kstars/ekos/ekos.cpp     [License: GPL (v2+)]
A  +66   -0    kstars/ekos/ekos.h     [License: GPL (v2+)]
A  +366  -0    kstars/ekos/ekos.ui
A  +12   -0    kstars/ekos/filter.cpp     [License: UNKNOWN]  *
A  +19   -0    kstars/ekos/filter.h     [License: UNKNOWN]  *
A  +12   -0    kstars/ekos/focuser.cpp     [License: UNKNOWN]  *
A  +19   -0    kstars/ekos/focuser.h     [License: UNKNOWN]  *
A  +116  -0    kstars/ekos/genericdevice.cpp     [License: UNKNOWN]  *
A  +67   -0    kstars/ekos/genericdevice.h     [License: UNKNOWN]  *
A  +12   -0    kstars/ekos/telescope.cpp     [License: UNKNOWN]  *
A  +19   -0    kstars/ekos/telescope.h     [License: UNKNOWN]  *
M  +13   -5    kstars/indi/devicemanager.cpp
M  +1    -0    kstars/indi/devicemanager.h
M  +13   -13   kstars/indi/imagesequence.cpp
M  +53   -45   kstars/indi/indidevice.cpp
M  +15   -4    kstars/indi/indidevice.h
M  +3    -4    kstars/indi/indidriver.cpp
M  +2    -2    kstars/indi/indidriver.h
M  +15   -15   kstars/indi/indielement.cpp
M  +3    -9    kstars/indi/indielement.h
M  +31   -30   kstars/indi/indiproperty.cpp
M  +3    -3    kstars/indi/indiproperty.h
M  +21   -15   kstars/indi/indistd.cpp
M  +1    -1    kstars/indi/telescopewizardprocess.cpp
M  +1    -1    kstars/kspopupmenu.cpp
M  +2    -2    kstars/kstars.cpp
M  +5    -0    kstars/kstars.h
M  +13   -0    kstars/kstarsactions.cpp
M  +9    -0    kstars/kstarsinit.cpp
M  +1    -0    kstars/kstarsui-indi.rc
M  +33   -17   kstars/oal/equipmentwriter.ui
M  +2    -2    kstars/skymapdrawabstract.cpp
M  +1    -1    kstars/tools/observinglist.cpp

The files marked with a * at the end have a non valid license. Please read: http://techbase.kde.org/Policies/Licensing_Policy and use the headers which are listed at that page.


http://commits.kde.org/kstars/18227de7bc08503da826f930c93720c8d1cc29e4

diff --git a/kstars/CMakeLists.txt b/kstars/CMakeLists.txt
index 6f7ed20..80acbf2 100644
--- a/kstars/CMakeLists.txt
+++ b/kstars/CMakeLists.txt
@@ -43,6 +43,19 @@ if (INDI_FOUND)
     indi/streamform.ui
     indi/telescopewizard.ui
     )
+
+   set(ekosui_SRCS
+      ekos/ekos.ui
+   )
+
+   set(ekos_SRCS
+      ekos/ekos.cpp
+      ekos/genericdevice.cpp
+      ekos/telescope.cpp
+      ekos/ccd.cpp
+      ekos/filter.cpp
+      ekos/focuser.cpp
+   )
   
   include_directories(${INDI_INCLUDE_DIR})
 endif(INDI_FOUND)
@@ -385,7 +398,7 @@ set(printingui_SRCS
     printing/pwizwelcome.ui
 )
 
-set(kstars_SRCS ${indi_SRCS} ${fits_SRCS} 
+set(kstars_SRCS ${indi_SRCS} ${ekos_SRCS} ${fits_SRCS}
 	${libkstarswidgets_SRCS} ${libkstarscomponents_SRCS} ${libkstarstools_SRCS} 
 	${kstars_extra_SRCS}  ${kstars_gl_SRCS} ${kstars_projection_SRCS} ${xplanet_SRCS}
 	${kstars_options_SRCS} ${kstars_skyobjects_SRCS} ${kstars_dialogs_SRCS} ${oal_SRCS}
@@ -401,7 +414,7 @@ kde4_add_kcfg_files(kstars_SRCS ${kstars_KCFG_SRCS})
 #kde4_add_dcop_skels(kstars_SRCS kstarsinterface.h simclockinterface.h )
 
 kde4_add_ui_files(kstars_SRCS
-       ${indiui_SRCS} ${fitsui_SRCS} ${xplanetui_SRCS} ${kstars_optionsui_SRCS} ${kstars_dialogsui_SRCS}
+       ${indiui_SRCS} ${ekosui_SRCS} ${fitsui_SRCS} ${xplanetui_SRCS} ${kstars_optionsui_SRCS} ${kstars_dialogsui_SRCS}
        ${printingui_SRCS}
          thumbnailpicker.ui thumbnaileditor.ui oal/observeradd.ui oal/equipmentwriter.ui oal/execute.ui
 )
diff --git a/kstars/dialogs/detaildialog.cpp b/kstars/dialogs/detaildialog.cpp
index a6407d5..5d643c6 100644
--- a/kstars/dialogs/detaildialog.cpp
+++ b/kstars/dialogs/detaildialog.cpp
@@ -1015,7 +1015,7 @@ void DetailDialog::centerTelescope()
             ConnectEle = indidev->findElem("CONNECT");
             if (!ConnectEle) continue;
 
-            if (ConnectEle->state == PS_OFF)
+            if (ConnectEle->switch_state == ISS_OFF)
             {
                 KMessageBox::error(0, i18n("Telescope %1 is offline. Please connect and retry again.", indidev->label));
                 return;
diff --git a/kstars/ekos/ccd.cpp b/kstars/ekos/ccd.cpp
new file mode 100644
index 0000000..0e1d9a4
--- /dev/null
+++ b/kstars/ekos/ccd.cpp
@@ -0,0 +1,12 @@
+#include "ccd.h"
+
+namespace EkoDevice
+{
+
+CCD::CCD(INDI_D *idp) : GenericDevice(idp)
+{
+}
+
+} // namespace EkoDevice
+
+#include "ccd.moc"
diff --git a/kstars/ekos/ccd.h b/kstars/ekos/ccd.h
new file mode 100644
index 0000000..390661f
--- /dev/null
+++ b/kstars/ekos/ccd.h
@@ -0,0 +1,21 @@
+#ifndef EKODEVICE_CCD_H
+#define EKODEVICE_CCD_H
+
+#include "ekos/genericdevice.h"
+
+class INDI_D;
+
+namespace EkoDevice
+{
+
+class CCD : public GenericDevice
+{
+    Q_OBJECT
+
+public:
+    CCD(INDI_D *dp);
+};
+
+} // namespace EkoDevice
+
+#endif // EKODEVICE_CCD_H
diff --git a/kstars/ekos/ekos.cpp b/kstars/ekos/ekos.cpp
new file mode 100644
index 0000000..4aa2cde
--- /dev/null
+++ b/kstars/ekos/ekos.cpp
@@ -0,0 +1,290 @@
+/*  Ekos
+    Copyright (C) 2012 Jasem Mutlaq <mutlaqja at ikarustech.com>
+
+    This application is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+ */
+
+#include "ekos.h"
+
+#include "kstars.h"
+
+#include <KMessageBox>
+
+#include <config-kstars.h>
+
+
+#include "indi/devicemanager.h"
+#include "indi/indimenu.h"
+#include "indi/indielement.h"
+#include "indi/indidriver.h"
+#include "indi/indiproperty.h"
+#include "indi/indidevice.h"
+#include "indi/indistd.h"
+
+#include "ekos/telescope.h"
+#include "ekos/ccd.h"
+#include "ekos/filter.h"
+#include "ekos/focuser.h"
+
+Ekos::Ekos( KStars *_ks )
+        : QDialog( _ks )
+{
+    setupUi(this);
+
+    deviceManager = NULL;
+    nDevices=0;
+    useGuiderFromCCD=false;
+    useFilterFromCCD=false;
+
+    scope   =  NULL;
+    ccd     =  NULL;
+    guider  =  NULL;
+    focuser =  NULL;
+    filter  =  NULL;
+
+    telescopeCombo->addItem("--");
+    ccdCombo->addItem("--");
+    guiderCombo->addItem("--");
+    focuserCombo->addItem("--");
+    filterCombo->addItem("--");
+
+    foreach(IDevice *dv, KStars::Instance()->indiDriver()->devices)
+    {
+        switch (dv->type)
+        {
+        case KSTARS_TELESCOPE:
+             telescopeCombo->addItem(dv->tree_label);
+             break;
+
+        case KSTARS_CCD:
+            ccdCombo->addItem(dv->tree_label);
+            guiderCombo->addItem(dv->tree_label);
+            break;
+
+        case KSTARS_FOCUSER:
+            focuserCombo->addItem(dv->tree_label);
+            break;
+
+        case KSTARS_FILTER:
+            filterCombo->addItem(dv->tree_label);
+            break;
+
+        }
+    }
+
+    toolsWidget->setTabEnabled(1, false);
+    toolsWidget->setTabEnabled(2, false);
+    toolsWidget->setTabEnabled(3, false);
+    toolsWidget->setTabEnabled(4, false);
+
+    connect(processINDIB, SIGNAL(clicked()), this, SLOT(processINDI()));
+
+    connect(connectB, SIGNAL(clicked()), this, SLOT(connectDevices()));
+
+    connect(disconnectB, SIGNAL(clicked()), this, SLOT(disconnectDevices()));
+
+    connect(controlPanelB, SIGNAL(clicked()), KStars::Instance()->indiMenu(), SLOT(show()));
+
+}
+
+Ekos::~Ekos() {}
+
+void Ekos::processINDI()
+{
+    int port=0;
+
+    if (processINDIB->text() == i18n("Stop INDI"))
+    {
+        cleanDevices();
+        return;
+    }
+
+    IDevice *scope_dv=NULL, *ccd_dv=NULL, *guider_dv=NULL, *filter_dv=NULL, *focuser_dv=NULL;
+
+    // Don't start INDI if it's already started
+    if (deviceManager != NULL)
+        return;
+
+    // Let's clear cache
+    nDevices=0;
+    processed_devices.clear();
+
+    scope_dv   = KStars::Instance()->indiDriver()->findDeviceByLabel(telescopeCombo->currentText());
+    ccd_dv     = KStars::Instance()->indiDriver()->findDeviceByLabel(ccdCombo->currentText());
+    guider_dv  = KStars::Instance()->indiDriver()->findDeviceByLabel(guiderCombo->currentText());
+    filter_dv  = KStars::Instance()->indiDriver()->findDeviceByLabel(filterCombo->currentText());
+    focuser_dv = KStars::Instance()->indiDriver()->findDeviceByLabel(focuserCombo->currentText());
+
+    if (guider_dv == ccd_dv)
+        useGuiderFromCCD = true;
+
+    if (filter_dv == ccd_dv)
+        useFilterFromCCD = true;
+
+    if (scope_dv != NULL)
+        processed_devices.append(scope_dv);
+    if (ccd_dv != NULL)
+        processed_devices.append(ccd_dv);
+    if (guider_dv != NULL && useGuiderFromCCD == false)
+        processed_devices.append(guider_dv);
+    if (filter_dv != NULL && useFilterFromCCD == false)
+        processed_devices.append(filter_dv);
+
+    if (focuser_dv != NULL)
+        processed_devices.append(focuser_dv);
+
+
+    if (processed_devices.empty()) return;
+
+    nDevices = processed_devices.size();
+
+    // Select random port within range is none specified.
+     port = KStars::Instance()->indiDriver()->getINDIPort(port);
+
+     if (port <= 0)
+     {
+           KMessageBox::error(0, i18n("Cannot start INDI server: port error."));
+          return;
+     }
+
+         deviceManager = KStars::Instance()->indiMenu()->initDeviceManager("localhost", ((uint) port), localR->isChecked() ? DeviceManager::M_LOCAL : DeviceManager::M_SERVER);
+
+         if (deviceManager == NULL)
+         {
+                 kWarning() << "Warning: device manager has not been established properly";
+                 return;
+         }
+
+         deviceManager->appendManagedDevices(processed_devices);
+         deviceManager->startServer();
+         //connect(deviceManager, SIGNAL(deviceManagerError(DeviceManager *)), this, SLOT(disconnectDevices()));
+
+         connect(deviceManager, SIGNAL(deviceManagerError(DeviceManager *)), this, SLOT(cleanDevices()));
+
+         connect(deviceManager, SIGNAL(newDevice(INDI_D*)), this, SLOT(processNewDevice(INDI_D*)));
+
+         connectB->setEnabled(false);
+         disconnectB->setEnabled(false);
+         controlPanelB->setEnabled(false);
+
+         processINDIB->setText(i18n("Stop INDI"));
+
+}
+
+void Ekos::connectDevices()
+{
+    if (scope != NULL)
+        scope->Connect();
+
+    if (ccd != NULL)
+        ccd->Connect();
+
+    if (guider != NULL)
+        guider->Connect();
+
+    if (focuser != NULL)
+        focuser->Connect();
+
+    if (filter != NULL)
+        filter->Connect();
+}
+
+void Ekos::disconnectDevices()
+{
+
+    if (scope != NULL)
+        scope->Disconnect();
+
+    if (ccd != NULL)
+        ccd->Disconnect();
+
+    if (guider != NULL)
+        guider->Disconnect();
+
+    if (focuser != NULL)
+        focuser->Disconnect();
+
+    if (filter != NULL)
+        filter->Disconnect();
+
+}
+
+void Ekos::cleanDevices()
+{
+    KStars::Instance()->indiMenu()->stopDeviceManager(processed_devices);
+
+    processINDIB->setText(i18n("Start INDI"));
+    processINDIB->setEnabled(true);
+    connectB->setEnabled(false);
+    disconnectB->setEnabled(false);
+    controlPanelB->setEnabled(false);
+}
+
+void Ekos::processNewDevice(INDI_D *dp)
+{
+    // Let's wait until we get a CONNECTION property from the device
+
+    //connect(dp, SIGNAL(newProperty(INDI_P*)), this, SLOT(NewProperty(INDI_P*)));
+
+    foreach (IDevice *dv, processed_devices)
+    {
+        if (dv->name == dp->name)
+        {
+            switch (dv->type)
+            {
+               case KSTARS_TELESCOPE:
+                if (scope == NULL && dp->name == telescopeCombo->currentText())
+                {
+                    scope = new EkoDevice::Telescope(dp);
+                    connect(dp, SIGNAL(newProperty(INDI_P*)), scope, SLOT(processNewProperty(INDI_P*)));
+                }
+                break;
+
+            case KSTARS_CCD:
+                if (ccd == NULL && dp->name == ccdCombo->currentText())
+                {
+                     ccd = new EkoDevice::CCD(dp);
+                     connect(dp, SIGNAL(newProperty(INDI_P*)), ccd, SLOT(processNewProperty(INDI_P*)));
+                }
+               else if (guider == NULL && useGuiderFromCCD == false && dp->name == guiderCombo->currentText())
+               {
+                     guider = new EkoDevice::CCD(dp);
+                     connect(dp, SIGNAL(newProperty(INDI_P*)), guider, SLOT(processNewProperty(INDI_P*)));
+               }
+               break;
+
+            case KSTARS_FILTER:
+                if (filter == NULL && useFilterFromCCD == false && dp->name == filterCombo->currentText())
+                {
+                     filter = new EkoDevice::Filter(dp);
+                     connect(dp, SIGNAL(newProperty(INDI_P*)), filter, SLOT(processNewProperty(INDI_P*)));
+                 }
+                 break;
+
+            case KSTARS_FOCUSER:
+                if (focuser == NULL && dp->name == focuserCombo->currentText())
+                {
+                     focuser = new EkoDevice::Focuser(dp);
+                     connect(dp, SIGNAL(newProperty(INDI_P*)), focuser, SLOT(processNewProperty(INDI_P*)));
+                }
+                break;
+
+            }
+        }
+    }
+
+    nDevices--;
+
+    if (nDevices == 0)
+    {
+        connectB->setEnabled(true);
+        disconnectB->setEnabled(false);
+        controlPanelB->setEnabled(true);
+    }
+
+}
+
+#include "ekos.moc"
diff --git a/kstars/ekos/ekos.h b/kstars/ekos/ekos.h
new file mode 100644
index 0000000..71f1d7b
--- /dev/null
+++ b/kstars/ekos/ekos.h
@@ -0,0 +1,66 @@
+#ifndef EKOS_H
+#define EKOS_H
+
+/*  Ekos
+    Copyright (C) 2012 Jasem Mutlaq <mutlaqja at ikarustech.com>
+
+    This application is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+ */
+
+
+#include "ui_ekos.h"
+
+#include <QDialog>
+
+class DeviceManager;
+class KStars;
+class INDI_D;
+class INDI_P;
+class IDevice;
+
+namespace EkoDevice
+{
+   class GenericDevice;
+   class Telescope;
+   class CCD;
+   class Focuser;
+   class Filter;
+}
+
+class Ekos : public QDialog, public Ui::Ekos
+{
+    Q_OBJECT
+
+public:
+    Ekos( KStars *_ks );
+    ~Ekos();
+
+public slots:
+    void processINDI();
+    void connectDevices();
+    void disconnectDevices();
+    void cleanDevices();
+    void processNewDevice(INDI_D *dp);
+
+
+ private:
+    DeviceManager *deviceManager;
+    bool useGuiderFromCCD;
+    bool useFilterFromCCD;
+
+    EkoDevice::Telescope *scope;
+    EkoDevice::CCD *ccd;
+    EkoDevice::CCD *guider;
+    EkoDevice::Focuser *focuser;
+    EkoDevice::Filter *filter;
+
+    unsigned short nDevices;
+    QList<IDevice *> processed_devices;
+
+};
+
+
+#endif // EKOS_H
diff --git a/kstars/ekos/ekos.ui b/kstars/ekos/ekos.ui
new file mode 100644
index 0000000..5ac7fd3
--- /dev/null
+++ b/kstars/ekos/ekos.ui
@@ -0,0 +1,366 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Ekos</class>
+ <widget class="QWidget" name="Ekos">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>1014</width>
+    <height>195</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Ekos</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QTabWidget" name="toolsWidget">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>150</height>
+      </size>
+     </property>
+     <property name="currentIndex">
+      <number>0</number>
+     </property>
+     <widget class="QWidget" name="setupTab">
+      <attribute name="title">
+       <string>Setup</string>
+      </attribute>
+      <layout class="QHBoxLayout" name="horizontalLayout_4">
+       <item>
+        <layout class="QVBoxLayout" name="verticalLayout_4">
+         <item>
+          <layout class="QHBoxLayout" name="horizontalLayout">
+           <item>
+            <layout class="QVBoxLayout" name="verticalLayout_2">
+             <item>
+              <widget class="QLabel" name="label_6">
+               <property name="text">
+                <string>Telescope:</string>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="QLabel" name="label_7">
+               <property name="text">
+                <string>CCD:</string>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="QLabel" name="label_8">
+               <property name="text">
+                <string>Guider:</string>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </item>
+           <item>
+            <layout class="QVBoxLayout" name="verticalLayout_3">
+             <item>
+              <widget class="QComboBox" name="telescopeCombo">
+               <property name="sizePolicy">
+                <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                 <horstretch>0</horstretch>
+                 <verstretch>0</verstretch>
+                </sizepolicy>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="QComboBox" name="ccdCombo">
+               <property name="sizePolicy">
+                <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                 <horstretch>0</horstretch>
+                 <verstretch>0</verstretch>
+                </sizepolicy>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="QComboBox" name="guiderCombo">
+               <property name="sizePolicy">
+                <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                 <horstretch>0</horstretch>
+                 <verstretch>0</verstretch>
+                </sizepolicy>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </item>
+          </layout>
+         </item>
+         <item>
+          <spacer name="verticalSpacer_3">
+           <property name="orientation">
+            <enum>Qt::Vertical</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>20</width>
+             <height>40</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QVBoxLayout" name="verticalLayout_7">
+         <item>
+          <layout class="QHBoxLayout" name="horizontalLayout_2">
+           <item>
+            <layout class="QVBoxLayout" name="verticalLayout_5">
+             <item>
+              <widget class="QLabel" name="label_9">
+               <property name="text">
+                <string>Filter Wheel:</string>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="QLabel" name="label_10">
+               <property name="text">
+                <string>Focuser:</string>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </item>
+           <item>
+            <layout class="QVBoxLayout" name="verticalLayout_6">
+             <item>
+              <widget class="QComboBox" name="filterCombo">
+               <property name="sizePolicy">
+                <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                 <horstretch>0</horstretch>
+                 <verstretch>0</verstretch>
+                </sizepolicy>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="QComboBox" name="focuserCombo">
+               <property name="sizePolicy">
+                <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                 <horstretch>0</horstretch>
+                 <verstretch>0</verstretch>
+                </sizepolicy>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </item>
+          </layout>
+         </item>
+         <item>
+          <spacer name="verticalSpacer_4">
+           <property name="orientation">
+            <enum>Qt::Vertical</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>20</width>
+             <height>40</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer_4">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>18</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <layout class="QVBoxLayout" name="verticalLayout_8">
+         <item>
+          <widget class="QGroupBox" name="groupBox_2">
+           <property name="title">
+            <string>Mode</string>
+           </property>
+           <property name="flat">
+            <bool>false</bool>
+           </property>
+           <layout class="QVBoxLayout" name="verticalLayout_9">
+            <item>
+             <layout class="QHBoxLayout" name="horizontalLayout_16">
+              <item>
+               <widget class="QRadioButton" name="localR">
+                <property name="text">
+                 <string>Local</string>
+                </property>
+                <property name="checked">
+                 <bool>true</bool>
+                </property>
+               </widget>
+              </item>
+              <item>
+               <widget class="QRadioButton" name="remoteR">
+                <property name="text">
+                 <string>Remote</string>
+                </property>
+               </widget>
+              </item>
+             </layout>
+            </item>
+            <item>
+             <layout class="QHBoxLayout" name="horizontalLayout_17">
+              <item>
+               <spacer name="horizontalSpacer_5">
+                <property name="orientation">
+                 <enum>Qt::Horizontal</enum>
+                </property>
+                <property name="sizeHint" stdset="0">
+                 <size>
+                  <width>40</width>
+                  <height>20</height>
+                 </size>
+                </property>
+               </spacer>
+              </item>
+              <item>
+               <widget class="KPushButton" name="configureB">
+                <property name="enabled">
+                 <bool>false</bool>
+                </property>
+                <property name="text">
+                 <string>Configure...</string>
+                </property>
+               </widget>
+              </item>
+             </layout>
+            </item>
+           </layout>
+          </widget>
+         </item>
+         <item>
+          <layout class="QHBoxLayout" name="horizontalLayout_3">
+           <item>
+            <widget class="KPushButton" name="processINDIB">
+             <property name="enabled">
+              <bool>true</bool>
+             </property>
+             <property name="text">
+              <string>Start INDI</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="KPushButton" name="controlPanelB">
+             <property name="enabled">
+              <bool>false</bool>
+             </property>
+             <property name="text">
+              <string>Control Panel...</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <spacer name="horizontalSpacer_6">
+             <property name="orientation">
+              <enum>Qt::Horizontal</enum>
+             </property>
+             <property name="sizeType">
+              <enum>QSizePolicy::Maximum</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>40</width>
+               <height>20</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+           <item>
+            <widget class="KPushButton" name="connectB">
+             <property name="enabled">
+              <bool>false</bool>
+             </property>
+             <property name="text">
+              <string>Connect</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="KPushButton" name="disconnectB">
+             <property name="enabled">
+              <bool>false</bool>
+             </property>
+             <property name="text">
+              <string>Disconnect</string>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="alignTab">
+      <property name="enabled">
+       <bool>false</bool>
+      </property>
+      <attribute name="title">
+       <string>Align</string>
+      </attribute>
+     </widget>
+     <widget class="QWidget" name="focusTab">
+      <property name="enabled">
+       <bool>false</bool>
+      </property>
+      <attribute name="title">
+       <string>Focus</string>
+      </attribute>
+     </widget>
+     <widget class="QWidget" name="guideTab">
+      <property name="enabled">
+       <bool>false</bool>
+      </property>
+      <attribute name="title">
+       <string>Guide</string>
+      </attribute>
+     </widget>
+     <widget class="QWidget" name="captureTab">
+      <property name="enabled">
+       <bool>false</bool>
+      </property>
+      <attribute name="title">
+       <string>Capture</string>
+      </attribute>
+     </widget>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>KPushButton</class>
+   <extends>QPushButton</extends>
+   <header>kpushbutton.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/kstars/ekos/filter.cpp b/kstars/ekos/filter.cpp
new file mode 100644
index 0000000..11a404a
--- /dev/null
+++ b/kstars/ekos/filter.cpp
@@ -0,0 +1,12 @@
+#include "filter.h"
+
+namespace EkoDevice
+{
+
+Filter::Filter(INDI_D *idp) : GenericDevice(idp)
+{
+}
+
+} // namespace EkoDevice
+
+#include "filter.moc"
diff --git a/kstars/ekos/filter.h b/kstars/ekos/filter.h
new file mode 100644
index 0000000..fe49ed2
--- /dev/null
+++ b/kstars/ekos/filter.h
@@ -0,0 +1,19 @@
+#ifndef EKODEVICE_FILTER_H
+#define EKODEVICE_FILTER_H
+
+#include "ekos/genericdevice.h"
+
+class INDI_D;
+
+namespace EkoDevice
+{
+
+class Filter : public GenericDevice
+{
+public:
+    Filter(INDI_D *dp);
+};
+
+} // namespace EkoDevice
+
+#endif // EKODEVICE_FILTER_H
diff --git a/kstars/ekos/focuser.cpp b/kstars/ekos/focuser.cpp
new file mode 100644
index 0000000..e106a8e
--- /dev/null
+++ b/kstars/ekos/focuser.cpp
@@ -0,0 +1,12 @@
+#include "focuser.h"
+
+namespace EkoDevice
+{
+
+Focuser::Focuser(INDI_D *idp)  : GenericDevice(idp)
+{
+}
+
+} // namespace EkoDevice
+
+#include "focuser.moc"
diff --git a/kstars/ekos/focuser.h b/kstars/ekos/focuser.h
new file mode 100644
index 0000000..9c9f2c6
--- /dev/null
+++ b/kstars/ekos/focuser.h
@@ -0,0 +1,19 @@
+#ifndef EKODEVICE_FOCUSER_H
+#define EKODEVICE_FOCUSER_H
+
+#include "ekos/genericdevice.h"
+
+class INDI_D;
+
+namespace EkoDevice
+{
+
+class Focuser : public GenericDevice
+{
+public:
+    Focuser(INDI_D *);
+};
+
+} // namespace EkoDevice
+
+#endif // EKODEVICE_FOCUSER_H
diff --git a/kstars/ekos/genericdevice.cpp b/kstars/ekos/genericdevice.cpp
new file mode 100644
index 0000000..3d4d132
--- /dev/null
+++ b/kstars/ekos/genericdevice.cpp
@@ -0,0 +1,116 @@
+#include "genericdevice.h"
+
+#include "indi/indielement.h"
+#include "indi/indiproperty.h"
+namespace EkoDevice
+{
+
+GenericDevice::GenericDevice(INDI_D *idp) : QObject()
+{
+  dp = idp;
+}
+
+
+ bool GenericDevice::Connect()
+ {
+     INDI_P * pp = dp->findProp("CONNECTION");
+
+     if (pp == NULL)
+         return false;
+
+     INDI_E * el = pp->findElement(("CONNECT"));
+
+     if (el == NULL)
+         return false;
+
+     pp->newSwitch(el);
+
+     return true;
+ }
+
+ bool GenericDevice::Disconnect()
+ {
+     INDI_P * pp = dp->findProp("CONNECTION");
+
+     if (pp == NULL)
+         return false;
+
+     INDI_E * el = pp->findElement(("DISCONNECT"));
+
+     if (el == NULL)
+         return false;
+
+     pp->newSwitch(el);
+
+
+     return true;
+ }
+
+ INDI_P * GenericDevice::getProperty(const QString &pp)
+ {
+     return dp->findProp(pp);
+ }
+
+ INDI_E * GenericDevice::getElement(const QString &el)
+ {
+     return dp->findElem(el);
+ }
+
+ bool GenericDevice::setSwitch(const QString &sw, ISState value)
+ {
+     return true;
+ }
+
+ bool GenericDevice::setNumber(const QString &nm, double value)
+ {
+     return true;
+ }
+
+ bool GenericDevice::setText(const QString &tx, QString value)
+ {
+     return true;
+ }
+
+ bool GenericDevice::setLight(const QString &lg, IPState value)
+ {
+     return true;
+ }
+
+ bool GenericDevice::setBLOB(const QString &bb, char *buf, unsigned int size)
+ {
+     return true;
+ }
+
+ bool GenericDevice::processSwitch(const QString &sw, ISState value)
+ {
+     return true;
+ }
+
+ bool GenericDevice::processNumber(const QString &nm, double value)
+ {
+     return true;
+ }
+
+ bool GenericDevice::processText(const QString &tx, QString value)
+ {
+     return true;
+ }
+
+ bool GenericDevice::processLight(const QString &lg, IPState value)
+ {
+     return true;
+ }
+
+ bool GenericDevice::processBLOB(const QString &bb, unsigned char *buffer, int bufferSize, const QString &dataFormat, INDI_D::DTypes dataType)
+ {
+     return true;
+ }
+
+ bool GenericDevice::processNewProperty(INDI_P * pp)
+ {
+     return true;
+ }
+
+} // namespace EkoDevice
+
+#include "genericdevice.moc"
diff --git a/kstars/ekos/genericdevice.h b/kstars/ekos/genericdevice.h
new file mode 100644
index 0000000..289b4a4
--- /dev/null
+++ b/kstars/ekos/genericdevice.h
@@ -0,0 +1,67 @@
+#ifndef EKODEVICE_GENERICDEVICE_H
+#define EKODEVICE_GENERICDEVICE_H
+
+#include <indiapi.h>
+#include <QObject>
+
+#include "indi/indidevice.h"
+
+class QString;
+
+class INDI_P;
+class INDI_E;
+
+namespace EkoDevice
+{
+
+class GenericDevice : public QObject
+{
+    Q_OBJECT
+
+public:
+    GenericDevice(INDI_D *idp);
+
+    virtual bool Connect();
+    virtual bool Disconnect();
+
+    virtual bool setSwitch(const QString &sw, ISState value);
+    virtual bool setNumber(const QString &nm, double value);
+    virtual bool setText(const QString &tx, QString value);
+    virtual bool setLight(const QString &lg, IPState value);
+    virtual bool setBLOB(const QString &bb, char *buf, unsigned int size);
+
+    INDI_D * getDevice() { return dp; }
+    INDI_P * getProperty(const QString &pp);
+    INDI_E * getElement(const QString &el);
+
+    INDI_D *getDP() { return dp; }
+
+public slots:
+    virtual bool processSwitch(const QString &sw, ISState value);
+    virtual bool processNumber(const QString &nm, double value);
+    virtual bool processText(const QString &tx, QString value);
+    virtual bool processLight(const QString &lg, IPState value);
+    virtual bool processBLOB(const  QString &bb, unsigned char *buffer, int bufferSize, const QString &dataFormat, INDI_D::DTypes dataType);
+    virtual bool processNewProperty(INDI_P *p);
+
+signals:
+    void deviceConnected();
+    void deviceDisconnected();
+
+    // We don't emit those directly, they are emitted by INDI_D
+    void newSwitch(const QString &sw, ISState value);
+    void newNumber(const QString &nm, double value);
+    void newText(const QString &tx, QString value);
+    void newLight(const QString &lg, IPState value);
+    void newBLOB(const QString &bb, unsigned char *buffer, int bufferSize, const QString &dataFormat, INDI_D::DTypes dataType);
+    void newProperty(INDI_P *p);
+
+private:
+
+    INDI_D *dp;
+
+};
+
+} // namespace EkoDevice
+
+#endif // EKODEVICE_GENERICDEVICE_H
diff --git a/kstars/ekos/telescope.cpp b/kstars/ekos/telescope.cpp
new file mode 100644
index 0000000..abadf36
--- /dev/null
+++ b/kstars/ekos/telescope.cpp
@@ -0,0 +1,12 @@
+#include "telescope.h"
+
+namespace EkoDevice
+{
+
+Telescope::Telescope(INDI_D *idp) : GenericDevice(idp)
+{
+}
+
+} // namespace EkoDevice
+
+#include "telescope.moc"
diff --git a/kstars/ekos/telescope.h b/kstars/ekos/telescope.h
new file mode 100644
index 0000000..34cb535
--- /dev/null
+++ b/kstars/ekos/telescope.h
@@ -0,0 +1,19 @@
+#ifndef EKODEVICE_TELESCOPE_H
+#define EKODEVICE_TELESCOPE_H
+
+#include "ekos/genericdevice.h"
+
+class INDI_D;
+
+namespace EkoDevice
+{
+
+class Telescope : public GenericDevice
+{
+public:
+    Telescope(INDI_D *idp);
+};
+
+} // namespace EkoDevice
+
+#endif // EKODEVICE_TELESCOPE_H
diff --git a/kstars/indi/devicemanager.cpp b/kstars/indi/devicemanager.cpp
index 68631a5..038fda1 100644
--- a/kstars/indi/devicemanager.cpp
+++ b/kstars/indi/devicemanager.cpp
@@ -93,7 +93,7 @@ void DeviceManager::startServer()
     foreach(IDevice *device, managed_devices)
     {
         // JM: Temporary workaround for indiserver limit of client BLOBs for CCDs.
-        if (device->deviceType == KSTARS_CCD)
+        if (device->type == KSTARS_CCD)
         {
                 *serverProcess << "-m" << "100";
                 break;
@@ -118,6 +118,11 @@ void DeviceManager::startServer()
     if (mode == DeviceManager::M_LOCAL)
     	connectToServer();
 }
+
+void DeviceManager::stopServer()
+{
+    serverProcess->terminate();
+}
   
 void DeviceManager::connectToServer()
 {
@@ -229,7 +234,8 @@ void DeviceManager::dataReceived()
 		     // Silenty ignore property duplication errors
 		     if (err_code != INDI_PROPERTY_DUPLICATED)
 		     {
-	                    kDebug() << "Dispatch command error: " << err_cmd << endl;
+                            //kDebug() << "Dispatch command error: " << err_cmd << endl;
+                            fprintf(stderr, "Dispatch command error: %d for command %s\n", err_code, err_cmd.toStdString().c_str());
 	       	            prXMLEle (stderr, root, 0);
                      }
                 }
@@ -362,6 +368,7 @@ INDI_D * DeviceManager::addDevice (XMLEle *dep, QString & errmsg)
     INDI_D *dp;
     XMLAtt *ap;
     QString device_name, unique_label;
+    IDevice *targetDevice=NULL;
 
     /* allocate new INDI_D on indi_dev */
     ap = findAtt (dep, "device", errmsg);
@@ -382,10 +389,11 @@ INDI_D * DeviceManager::addDevice (XMLEle *dep, QString & errmsg)
 			// of IDevice because IDevice can have several names. It can have the tree_label which is the name it has in the local tree widget. Finally, the name that shows
 			// up in the INDI control panel is the unique name of the driver, which is for most cases tree_label, but if that exists already then we get tree_label_1..etc
 
-			if (device->driver_class == device_name && device->state == IDevice::DEV_TERMINATE)
+                        if (device->name == device_name && device->state == IDevice::DEV_TERMINATE)
 			{
 	 			device->state = IDevice::DEV_START;
 			        unique_label = device->unique_label = parent->getUniqueDeviceLabel(device->tree_label);
+                                targetDevice = device;
 				break;
 			}
 		}
@@ -394,7 +402,7 @@ INDI_D * DeviceManager::addDevice (XMLEle *dep, QString & errmsg)
 	if (unique_label.isEmpty())
 	  unique_label = parent->getUniqueDeviceLabel(device_name);
 
-    	dp = new INDI_D(parent, this, device_name, unique_label);
+        dp = new INDI_D(parent, this, device_name, unique_label, targetDevice);
 	indi_dev.append(dp);
 	emit newDevice(dp);
 
@@ -553,7 +561,7 @@ void DeviceManager::sendNewSwitch (INDI_P *pp, INDI_E *lp)
     serverFP << QString("  name='%1'>\n").arg(qPrintable( pp->name));
     serverFP << QString("  <oneSwitch\n");
     serverFP << QString("    name='%1'>\n").arg(qPrintable( lp->name));
-    serverFP << QString("      %1\n").arg(lp->state == PS_ON ? "On" : "Off");
+    serverFP << QString("      %1\n").arg(lp->switch_state == ISS_ON ? "On" : "Off");
     serverFP << QString("  </oneSwitch>\n");
 
     serverFP <<  QString("</newSwitchVector>\n");
diff --git a/kstars/indi/devicemanager.h b/kstars/indi/devicemanager.h
index 2ff6e31..79e2144 100644
--- a/kstars/indi/devicemanager.h
+++ b/kstars/indi/devicemanager.h
@@ -76,6 +76,7 @@ public:
 
     void appendManagedDevices(QList<IDevice *> & processed_devices);
     void startServer();
+    void stopServer();
     void connectToServer();
     void enableBLOB(bool enable, QString device = QString(), QString property = QString());
 
diff --git a/kstars/indi/imagesequence.cpp b/kstars/indi/imagesequence.cpp
index 46609b3..29d04fd 100644
--- a/kstars/indi/imagesequence.cpp
+++ b/kstars/indi/imagesequence.cpp
@@ -36,15 +36,15 @@
 imagesequence::imagesequence(QWidget* parent): QDialog(parent)
 {
     ksw = (KStars *) parent;
-    INDIMenu *devMenu = ksw->indiMenu();
+    //INDIMenu *devMenu = ksw->indiMenu();
 
     setupUi(this);
 
-    if (devMenu)
+    /*if (devMenu)
     {
         connect (devMenu, SIGNAL(newDevice()), this, SLOT(newCCD()));
         connect (devMenu, SIGNAL(newDevice()), this, SLOT(newFilter()));
-    }
+    }*/
 
     seqTimer = new QTimer(this);
 
@@ -113,7 +113,7 @@ bool imagesequence::setupCCDs()
     {
         for (int j=0; j < devMenu->managers.at(i)->indi_dev.size(); j++)
         {
-            imgProp = devMenu->managers.at(i)->indi_dev.at(j)->findProp("CCD_EXPOSURE");
+            imgProp = devMenu->managers.at(i)->indi_dev.at(j)->findProp("CCD_EXPOSURE_REQUEST");
             if (!imgProp)
                 continue;
 
@@ -147,17 +147,17 @@ bool imagesequence::setupCCDs()
         INDI_P *exposeProp;
         INDI_E *exposeElem;
 
-        exposeProp = stdDevCCD->dp->findProp("CCD_EXPOSURE");
+        exposeProp = stdDevCCD->dp->findProp("CCD_EXPOSURE_REQUEST");
         if (!exposeProp)
         {
-            KMessageBox::error(this, i18n("Device does not support CCD_EXPOSURE property."));
+            KMessageBox::error(this, i18n("Device does not support CCD_EXPOSURE_REQUEST property."));
             return false;
         }
 
         exposeElem = exposeProp->findElement("CCD_EXPOSURE_VALUE");
         if (!exposeElem)
         {
-            KMessageBox::error(this, i18n("CCD_EXPOSURE property is missing CCD_EXPOSURE_VALUE element."));
+            KMessageBox::error(this, i18n("CCD_EXPOSURE_REQUEST property is missing CCD_EXPOSURE_VALUE element."));
             return false;
         }
 
@@ -393,17 +393,17 @@ bool imagesequence::verifyCCDIntegrity()
     }
 
     stdDevCCD = idevice->stdDev;
-    exposeProp = stdDevCCD->dp->findProp("CCD_EXPOSURE");
+    exposeProp = stdDevCCD->dp->findProp("CCD_EXPOSURE_REQUEST");
     if (!exposeProp)
     {
-        KMessageBox::error(this, i18n("Device does not support CCD_EXPOSURE property."));
+        KMessageBox::error(this, i18n("Device does not support CCD_EXPOSURE_REQUEST property."));
         return false;
     }
 
     exposeElem = exposeProp->findElement("CCD_EXPOSURE_VALUE");
     if (!exposeElem)
     {
-        KMessageBox::error(this, i18n("CCD_EXPOSURE property is missing CCD_EXPOSURE_VALUE element."));
+        KMessageBox::error(this, i18n("CCD_EXPOSURE_REQUEST property is missing CCD_EXPOSURE_VALUE element."));
         return false;
     }
 
@@ -533,7 +533,7 @@ void imagesequence::captureImage()
     seqTimer->stop();
 
     // Make sure it's not busy, if it is then schedual.
-    if (exposeProp->state == PS_BUSY)
+    if (exposeProp->state == IPS_BUSY)
     {
         retries++;
 
@@ -550,7 +550,7 @@ void imagesequence::captureImage()
     }
 
     // Set duration if applicable. We check the property permission, min, and max values
-    if (exposeProp->perm == PP_RW || exposeProp->perm == PP_WO)
+    if (exposeProp->perm == IP_RW || exposeProp->perm == IP_WO)
     {
         if (seqExpose < exposeElem->min || seqExpose > exposeElem->max)
         {
@@ -646,7 +646,7 @@ void imagesequence::selectFilter()
         return;
     }
 
-    if (filterProp && (filterProp->perm == PP_RW || filterProp->perm == PP_WO))
+    if (filterProp && (filterProp->perm == IP_RW || filterProp->perm == IP_WO))
     {
         filterElem->targetValue = filterPosCombo->currentIndex();
         if (filterElem->spin_w)
diff --git a/kstars/indi/indidevice.cpp b/kstars/indi/indidevice.cpp
index 60c6437..5bc5e83 100644
--- a/kstars/indi/indidevice.cpp
+++ b/kstars/indi/indidevice.cpp
@@ -85,12 +85,13 @@ const char * indi_std[NINDI_STD] =
 ** INDI Device: The work-horse. Responsible for handling its
 ** child properties and managing signal and changes.
 *******************************************************************/
-INDI_D::INDI_D(INDIMenu *menuParent, DeviceManager *InParentManager, const QString &inName, const QString &inLabel) : KDialog( 0 )
+INDI_D::INDI_D(INDIMenu *menuParent, DeviceManager *InParentManager, const QString &inName, const QString &inLabel, IDevice *dv) : KDialog( 0 )
   {
     name      		= inName;
     label     		= inLabel;
     parent		= menuParent;
     deviceManager 	= InParentManager;
+    deviceDriver        = dv;
   
     deviceVBox     	= new QSplitter();
     deviceVBox->setOrientation(Qt::Vertical);
@@ -130,9 +131,12 @@ void INDI_D::registerProperty(INDI_P *pp)
 {
 
     if (isINDIStd(pp))
+    {
         pp->pg->dp->INDIStdSupport = true;
+        stdDev->registerProperty(pp);
+    }
 
-    stdDev->registerProperty(pp);
+    newProperty(pp);
 
 }
 
@@ -289,12 +293,14 @@ int INDI_D::setTextValue (INDI_P *pp, XMLEle *root, QString & errmsg)
         //fprintf(stderr, "tag okay, getting perm\n");
         switch (pp->perm)
         {
-        case PP_RW:	// FALLTHRU
-        case PP_RO:
+        case IP_RW:	// FALLTHRU
+        case IP_RO:
             if (pp->guitype == PG_TEXT)
             {
                 lp->text = QString(pcdataXMLEle(ep));
                 lp->read_w->setText(lp->text);
+
+                newText(lp->name, lp->text);
             }
             else if (pp->guitype == PG_NUMERIC)
             {
@@ -315,24 +321,14 @@ int INDI_D::setTextValue (INDI_P *pp, XMLEle *root, QString & errmsg)
                 lp->spinChanged(lp->value);
                 }*/
 
+                newNumber(lp->name, lp->value);
+
             }
             break;
 
-        case PP_WO:
-            // FIXME for WO properties, only min/max needs to be updated
-            /* if (pp->guitype == PG_TEXT)
-               lp->write_w->setText(QString(pcdataXMLEle(ep)));
-             else*/ if (pp->guitype == PG_NUMERIC)
+        case IP_WO:
+            if (pp->guitype == PG_NUMERIC)
             {
-                /*lp->value = atof(pcdataXMLEle(ep));
-                numberFormat(iNumber, lp->format.toAscii(), lp->value);
-                lp->text = iNumber;
-
-                if (lp->spin_w)
-                         lp->spin_w->setValue(lp->value);
-                else
-                   lp->write_w->setText(lp->text);*/
-
                 ap = findXMLAtt (ep, "min");
                 if (ap) { min = (int) atof(valuXMLAtt(ap)); lp->setMin(min); }
                 ap = findXMLAtt (ep, "max");
@@ -366,7 +362,8 @@ int INDI_D::setLabelState (INDI_P *pp, XMLEle *root, QString & errmsg)
     XMLAtt *ap;
     INDI_E *lp = NULL;
     int islight;
-    PState state;
+    IPState light_state;
+    ISState switch_state;
 
     /* for each child element */
     for (ep = nextXMLEle (root, 1), i=0; ep != NULL; ep = nextXMLEle (root, 0), i++)
@@ -385,8 +382,8 @@ int INDI_D::setLabelState (INDI_P *pp, XMLEle *root, QString & errmsg)
             return (-1);
         }
 
-        if ((islight && crackLightState (pcdataXMLEle(ep), &state) < 0)
-                || (!islight && crackSwitchState (pcdataXMLEle(ep), &state) < 0))
+        if ((islight && crackLightState (pcdataXMLEle(ep), &light_state) < 0)
+                || (!islight && crackSwitchState (pcdataXMLEle(ep), &switch_state) < 0))
         {
             errmsg = QString("INDI: <%1> unknown state %2 for %3 %4 %5").arg(tagXMLEle(root)).arg(pcdataXMLEle(ep)).arg(name).arg(pp->name).arg(tagXMLEle(ep));
             return (-1);
@@ -404,7 +401,10 @@ int INDI_D::setLabelState (INDI_P *pp, XMLEle *root, QString & errmsg)
 
         QFont buttonFont;
         /* engage new state */
-        lp->state = state;
+        if (islight)
+            lp->light_state = light_state;
+        else
+            lp->switch_state = switch_state;
 
         switch (pp->guitype)
         {
@@ -412,18 +412,22 @@ int INDI_D::setLabelState (INDI_P *pp, XMLEle *root, QString & errmsg)
             if (islight)
                 break;
 
-            lp->push_w->setDown(state == PS_ON ? true : false);
+            lp->push_w->setDown(switch_state == ISS_ON ? true : false);
             buttonFont = lp->push_w->font();
-            buttonFont.setBold(state == PS_ON ? true : false);
+            buttonFont.setBold(switch_state == ISS_ON ? true : false);
             lp->push_w->setFont(buttonFont);
 
+            newSwitch(lp->name, switch_state);
+
             break;
 
         case PG_RADIO:
-            lp->check_w->setChecked(state == PS_ON ? true : false);
+            lp->check_w->setChecked(switch_state == ISS_ON ? true : false);
+            newSwitch(lp->name, switch_state);
             break;
+
         case PG_MENU:
-            if (state == PS_ON)
+            if (switch_state == ISS_ON)
             {
                 if (menuChoice)
                 {
@@ -433,10 +437,12 @@ int INDI_D::setLabelState (INDI_P *pp, XMLEle *root, QString & errmsg)
                 menuChoice = 1;
                 pp->om_w->setCurrentIndex(i);
             }
+            newSwitch(lp->name, switch_state);
             break;
 
         case PG_LIGHTS:
             lp->drawLt();
+            newLight(lp->name, light_state);
             break;
 
         default:
@@ -579,17 +585,19 @@ int INDI_D::processBlob(INDI_E *blobEL, XMLEle *ep, QString & errmsg)
         memcpy(dataBuffer, blobBuffer, dataSize);
     }
 
-    if (dataType == ASCII_DATA_STREAM && blobEL->pp->state != PS_BUSY)
+    if (dataType == ASCII_DATA_STREAM && blobEL->pp->state != IPS_BUSY)
     {
         stdDev->asciiFileDirty = true;
 
-        if (blobEL->pp->state == PS_IDLE)
+        if (blobEL->pp->state == IPS_IDLE)
         {
             free (blobBuffer);
             return(0);
         }
     }
 
+    newBLOB(blobEL->name, dataBuffer, dataSize, dataFormat, dataType);
+
     stdDev->handleBLOB(dataBuffer, dataSize, dataFormat, dataType);
 
     free (blobBuffer);
@@ -721,7 +729,7 @@ INDI_G *  INDI_D::findGroup (const QString &grouptag,
  * return 0 if ok else -1 with excuse in errmsg[]
  */
 
-int INDI_D::findPerm (INDI_P *pp, XMLEle *root, PPerm *permp, QString & errmsg)
+int INDI_D::findPerm (INDI_P *pp, XMLEle *root, IPerm *permp, QString & errmsg)
 {
     XMLAtt *ap;
 
@@ -732,11 +740,11 @@ int INDI_D::findPerm (INDI_P *pp, XMLEle *root, PPerm *permp, QString & errmsg)
         return (-1);
     }
     if (!strcmp(valuXMLAtt(ap), "ro") || !strcmp(valuXMLAtt(ap), "r"))
-        *permp = PP_RO;
+        *permp = IP_RO;
     else if (!strcmp(valuXMLAtt(ap), "wo"))
-        *permp = PP_WO;
+        *permp = IP_WO;
     else if (!strcmp(valuXMLAtt(ap), "rw") || !strcmp(valuXMLAtt(ap), "w"))
-        *permp = PP_RW;
+        *permp = IP_RW;
     else {
         errmsg = QString("INDI: <%1> unknown perm %2 for %3 %4").arg(tagXMLEle(root)).arg(valuXMLAtt(ap)).arg(pp->pg->dp->name).arg(pp->name);
         return (-1);
@@ -748,20 +756,20 @@ int INDI_D::findPerm (INDI_P *pp, XMLEle *root, PPerm *permp, QString & errmsg)
 /* convert the given light/property state string to the PState at psp.
  * return 0 if successful, else -1 and leave *psp unchanged.
  */
-int INDI_D::crackLightState (char *name, PState *psp)
+int INDI_D::crackLightState (char *name, IPState *psp)
 {
     typedef struct
     {
-        PState s;
+        IPState s;
         const char *name;
     } PSMap;
 
     PSMap psmap[] =
         {
-            {PS_IDLE,  "Idle"},
-            {PS_OK,    "Ok"},
-            {PS_BUSY,  "Busy"},
-            {PS_ALERT, "Alert"},
+            {IPS_IDLE,  "Idle"},
+            {IPS_OK,    "Ok"},
+            {IPS_BUSY,  "Busy"},
+            {IPS_ALERT, "Alert"},
         };
 
     for (int i = 0; i < 4; i++)
@@ -776,18 +784,18 @@ int INDI_D::crackLightState (char *name, PState *psp)
 /* convert the given switch state string to the PState at psp.
  * return 0 if successful, else -1 and leave *psp unchanged.
  */
-int INDI_D::crackSwitchState (char *name, PState *psp)
+int INDI_D::crackSwitchState (char *name, ISState *psp)
 {
     typedef struct
     {
-        PState s;
+        ISState s;
         const char *name;
     } PSMap;
 
     PSMap psmap[] =
         {
-            {PS_ON,  "On"},
-            {PS_OFF, "Off"},
+            {ISS_ON,  "On"},
+            {ISS_OFF, "Off"},
         };
 
 
@@ -805,7 +813,7 @@ int INDI_D::buildTextGUI(XMLEle *root, QString & errmsg)
 {
     INDI_P *pp = NULL;
     int err_code=0;
-    PPerm p;
+    IPerm p;
     bool isGroupVisible=false;
 
     /* build a new property */
@@ -852,7 +860,7 @@ int INDI_D::buildNumberGUI (XMLEle *root, QString & errmsg)
 {
     INDI_P *pp = NULL;
     int err_code=0;
-    PPerm p;
+    IPerm p;
     bool isGroupVisible=false;
 
     /* build a new property */
@@ -1040,7 +1048,7 @@ int INDI_D::buildBLOBGUI  (XMLEle *root, QString & errmsg)
 {
     INDI_P *pp;
     int err_code=0;
-    PPerm p;
+    IPerm p;
     bool isGroupVisible=false;
 
     // build a new property
diff --git a/kstars/indi/indidevice.h b/kstars/indi/indidevice.h
index 009a69d..2b434e7 100644
--- a/kstars/indi/indidevice.h
+++ b/kstars/indi/indidevice.h
@@ -28,6 +28,7 @@ class INDI_G;
 class INDI_E;
 class INDIMenu;
 class INDIStdDevice;
+class IDevice;
 
 
 class QLabel;
@@ -54,13 +55,14 @@ class QSplitter;
                                           Device Manager  INDI Menu
 **************************************************************************/
 
+#include <indiapi.h>
 
 /* INDI device */
 class INDI_D : public KDialog
 {
     Q_OBJECT
 public:
-    INDI_D(INDIMenu *parentMenu, DeviceManager *InParentManager, const QString &inName, const QString &inLabel);
+    INDI_D(INDIMenu *parentMenu, DeviceManager *InParentManager, const QString &inName, const QString &inLabel, IDevice *dv);
     ~INDI_D();
 
     QString 	name;			/* device name */
@@ -80,6 +82,7 @@ public:
 
     INDIMenu      *parent;
     DeviceManager *deviceManager;
+    IDevice       *deviceDriver;
 
     enum DTypes { DATA_FITS, ASCII_DATA_STREAM, VIDEO_STREAM, DATA_OTHER, DATA_CCDPREVIEW };
 
@@ -104,7 +107,7 @@ public:
     INDI_P *   findProp    (const QString &name);
     INDI_E *   findElem    (const QString &name);
     INDI_G *   findGroup   (const QString &grouptag, int create, QString & errmsg);
-    int        findPerm    (INDI_P *pp  , XMLEle *root, PPerm *permp, QString & errmsg);
+    int        findPerm    (INDI_P *pp  , XMLEle *root, IPerm *permp, QString & errmsg);
 
     /*****************************************************************
     * Set/New
@@ -125,8 +128,8 @@ public:
     /*****************************************************************
     * Crack
     ******************************************************************/
-    int crackLightState  (char *name, PState *psp);
-    int crackSwitchState (char *name, PState *psp);
+    int crackLightState  (char *name, IPState *psp);
+    int crackSwitchState (char *name, ISState *psp);
 
     /*****************************************************************
     * Data processing
@@ -143,6 +146,14 @@ public:
 public slots:
     void engageTracking();
 
+signals:
+    void newSwitch(const QString &sw, ISState value);
+    void newNumber(const QString &nm, double value);
+    void newText(const QString &tx, QString value);
+    void newLight(const QString &lg, IPState value);
+    void newBLOB(const QString &bb, unsigned char *buffer, int bufferSize, const QString &dataFormat, INDI_D::DTypes dataType);
+    void newProperty(INDI_P *p);
+
 };
 
 #endif
diff --git a/kstars/indi/indidriver.cpp b/kstars/indi/indidriver.cpp
index 6982812..f972774 100644
--- a/kstars/indi/indidriver.cpp
+++ b/kstars/indi/indidriver.cpp
@@ -393,7 +393,6 @@ void INDIDriver::newCCDDiscovered()
 {
 
     emit newCCD();
-
 }
 
 void INDIDriver::resizeDeviceColumn()
@@ -710,7 +709,7 @@ bool INDIDriver::buildDriverElement(XMLEle *root, QTreeWidgetItem *DGroup, int g
         driversList.insert(driver, name);
 
     dv = new IDevice(name, label, driver, version);
-    dv->deviceType = groupType;
+    dv->type = groupType;
     dv->xmlSource = xmlSource;
     //connect(dv, SIGNAL(newServerInput()), this, SLOT(updateLocalTab()));
     if (focal_length > 0)
@@ -768,7 +767,7 @@ void INDIDriver::updateCustomDrivers()
             lastDevice = device;
 
             dv = new IDevice(name, label, driver, version);
-            dv->deviceType = KSTARS_TELESCOPE;
+            dv->type = KSTARS_TELESCOPE;
             dv->xmlSource = IDevice::EM_XML;
             dv->focal_length = focal_length;
             dv->aperture = aperture;
@@ -982,7 +981,7 @@ IDevice::IDevice(const QString &inName, const QString &inLabel, const QString &i
 {
     tree_label	 = inLabel;
     unique_label.clear();
-    driver_class = inName;
+    name = inName;
     driver	 = inDriver;
     version	 = inVersion;
 
diff --git a/kstars/indi/indidriver.h b/kstars/indi/indidriver.h
index ce3211b..ea517ab 100644
--- a/kstars/indi/indidriver.h
+++ b/kstars/indi/indidriver.h
@@ -56,7 +56,7 @@ public:
 
     QString tree_label;
     QString unique_label;
-    QString driver_class;
+    QString name;
     QString driver;
     QString version;
     QString id;
@@ -65,7 +65,7 @@ public:
     XMLSource xmlSource;
 
     DeviceManager *deviceManager;
-    int deviceType;
+    int type;
   
       /* Telescope specific attributes */
       double focal_length;
diff --git a/kstars/indi/indielement.cpp b/kstars/indi/indielement.cpp
index f28f2be..330f4e0 100644
--- a/kstars/indi/indielement.cpp
+++ b/kstars/indi/indielement.cpp
@@ -140,17 +140,17 @@ int INDI_E::buildTextGUI(const QString &initText)
 
     switch (pp->perm)
     {
-    case PP_RW:
+    case IP_RW:
         setupElementRead(ELEMENT_READ_WIDTH);
         setupElementWrite(ELEMENT_WRITE_WIDTH);
 
         break;
 
-    case PP_RO:
+    case IP_RO:
         setupElementRead(ELEMENT_FULL_WIDTH);
         break;
 
-    case PP_WO:
+    case IP_WO:
         setupElementWrite(ELEMENT_FULL_WIDTH);
         break;
     }
@@ -169,18 +169,18 @@ int INDI_E::buildBLOBGUI()
 
     switch (pp->perm)
     {
-    case PP_RW:
+    case IP_RW:
         setupElementRead(ELEMENT_READ_WIDTH);
         setupElementWrite(ELEMENT_WRITE_WIDTH);
         setupBrowseButton();
 
         break;
 
-    case PP_RO:
+    case IP_RO:
         setupElementRead(ELEMENT_FULL_WIDTH);
         break;
 
-    case PP_WO:
+    case IP_WO:
         setupElementWrite(ELEMENT_FULL_WIDTH);
         setupBrowseButton();
         break;
@@ -207,7 +207,7 @@ int INDI_E::buildNumberGUI  (double initValue)
 
     switch (pp->perm)
     {
-    case PP_RW:
+    case IP_RW:
         setupElementRead(ELEMENT_READ_WIDTH);
         if (scale)
             setupElementScale(ELEMENT_WRITE_WIDTH);
@@ -217,12 +217,12 @@ int INDI_E::buildNumberGUI  (double initValue)
         pp->PVBox->addLayout(EHBox);
         break;
 
-    case PP_RO:
+    case IP_RO:
         setupElementRead(ELEMENT_READ_WIDTH);
         pp->PVBox->addLayout(EHBox);
         break;
 
-    case PP_WO:
+    case IP_WO:
         if (scale)
             setupElementScale(ELEMENT_FULL_WIDTH);
         else
@@ -257,21 +257,21 @@ int INDI_E::buildLightGUI()
 void INDI_E::drawLt()
 {
     /* set state light */
-    switch (state)
+    switch (light_state)
     {
-    case PS_IDLE:
+    case IPS_IDLE:
         led_w->setColor(Qt::gray);
         break;
 
-    case PS_OK:
+    case IPS_OK:
         led_w->setColor(Qt::green);
         break;
 
-    case PS_BUSY:
+    case IPS_BUSY:
         led_w->setColor(Qt::yellow);
         break;
 
-    case PS_ALERT:
+    case IPS_ALERT:
         led_w->setColor(Qt::red);
         break;
 
@@ -465,7 +465,7 @@ void INDI_E::actionTriggered()
         // Just issue a new generic switch.
         if (pp->indistd->actionTriggered(this))
             return;
-        else if (state == PS_OFF)
+        else if (switch_state == ISS_OFF)
             pp->newSwitch(this);
         break;
 
diff --git a/kstars/indi/indielement.h b/kstars/indi/indielement.h
index 2d7e81c..cd05717 100644
--- a/kstars/indi/indielement.h
+++ b/kstars/indi/indielement.h
@@ -13,7 +13,7 @@
 #define INDIELEMENT_H_
 
 #include <lilxml.h>
-
+#include <indiapi.h>
 
 #include <kdialog.h>
 #include <unistd.h>
@@ -40,13 +40,6 @@
 // Pulse tracking
 #define INDI_PULSE_TRACKING   15000
 
-/* decoded elements.
- * lights use PState, TB's use the alternate binary names.
- */
-typedef enum {PS_IDLE = 0, PS_OK, PS_BUSY, PS_ALERT, PS_N} PState;
-#define	PS_OFF	PS_IDLE		/* alternate name */
-#define	PS_ON	PS_OK		/* alternate name */
-typedef enum {PP_RW = 0, PP_WO, PP_RO} PPerm;
 typedef enum {PG_NONE = 0, PG_TEXT, PG_NUMERIC, PG_BUTTONS,
               PG_RADIO, PG_MENU, PG_LIGHTS, PG_BLOB} PGui;
 
@@ -97,7 +90,8 @@ public:
     ~INDI_E();
     QString name;			/* name */
     QString label;			/* label is the name by default, unless specified */
-    PState state;			/* control on/off t/f etc */
+    IPState light_state;		/* control light state */
+    ISState switch_state;		/* control switch state */
     INDI_P *pp;				/* parent property */
 
     QHBoxLayout    *EHBox;   		/* Horizontal layout */
diff --git a/kstars/indi/indiproperty.cpp b/kstars/indi/indiproperty.cpp
index f9acf40..8c59aca 100644
--- a/kstars/indi/indiproperty.cpp
+++ b/kstars/indi/indiproperty.cpp
@@ -102,7 +102,7 @@ bool INDI_P::isOn(const QString &component)
     if (lp->check_w && lp->check_w->isChecked())
         return true;
 
-    if (lp->push_w && lp->state == PS_ON)
+    if (lp->push_w && lp->switch_state == ISS_ON)
         return true;
 
     return false;
@@ -117,28 +117,28 @@ INDI_E * INDI_P::findElement(const QString &elementName)
     return NULL;
 }
 
-void INDI_P::drawLt(PState lstate)
+void INDI_P::drawLt(IPState lstate)
 {
 
 
     /* set state light */
     switch (lstate)
     {
-    case PS_IDLE:
+    case IPS_IDLE:
         light->setColor(Qt::gray);
         break;
 
-    case PS_OK:
+    case IPS_OK:
         light->setColor(Qt::green);
         emit okState();
         disconnect( this, SIGNAL(okState()), 0, 0 );
         break;
 
-    case PS_BUSY:
+    case IPS_BUSY:
         light->setColor(Qt::yellow);
         break;
 
-    case PS_ALERT:
+    case IPS_ALERT:
         light->setColor(Qt::red);
         break;
 
@@ -162,7 +162,7 @@ void INDI_P::newText()
         {
             switch (perm)
             {
-            case PP_RW:
+            case IP_RW:
                 // FIXME is this problematic??
                 if (lp->write_w->text().isEmpty())
                     lp->text = lp->read_w->text();
@@ -170,10 +170,10 @@ void INDI_P::newText()
                     lp->text = lp->write_w->text();
                 break;
 
-            case PP_RO:
+            case IP_RO:
                 break;
 
-            case PP_WO:
+            case IP_WO:
                 // Ignore if it's empty
                 if (lp->write_w->text().isEmpty())
                     return;
@@ -194,7 +194,7 @@ void INDI_P::newText()
         }
     }
 
-    state = PS_BUSY;
+    state = IPS_BUSY;
 
     drawLt(state);
 
@@ -236,18 +236,19 @@ void INDI_P::newSwitch(INDI_E *lp)
 {
     QFont buttonFont;
 
-    assert(lp != NULL);
+    if (lp == NULL)
+        return;
 
     switch (guitype)
     {
     case PG_MENU:
-        if (lp->state == PS_ON)
+        if (lp->switch_state == ISS_ON)
             return;
 
         foreach( INDI_E *elm, el)
-        elm->state = PS_OFF;
+            elm->switch_state = ISS_OFF;
 
-        lp->state = PS_ON;
+        lp->switch_state = ISS_ON;
         break;
 
     case PG_BUTTONS:
@@ -261,27 +262,27 @@ void INDI_P::newSwitch(INDI_E *lp)
             buttonFont = elm->push_w->font();
             buttonFont.setBold(false);
             elm->push_w->setFont(buttonFont);
-            elm->state = PS_OFF;
+            elm->switch_state = ISS_OFF;
         }
 
         lp->push_w->setDown(true);
         buttonFont = lp->push_w->font();
         buttonFont.setBold(true);
         lp->push_w->setFont(buttonFont);
-        lp->state = PS_ON;
+        lp->switch_state = ISS_ON;
 
         break;
 
     case PG_RADIO:
-        lp->state = lp->state == PS_ON ? PS_OFF : PS_ON;
-        lp->check_w->setChecked(lp->state == PS_ON);
+        lp->switch_state = (lp->switch_state == ISS_ON ? ISS_OFF : ISS_ON);
+        lp->check_w->setChecked(lp->switch_state == ISS_ON);
         break;
 
     default:
         break;
 
     }
-    state = PS_BUSY;
+    state = IPS_BUSY;
 
     drawLt(state);
 
@@ -372,9 +373,9 @@ void INDI_P::newBlob()
         pg->dp->deviceManager->finishBlob();
 
     if (valid)
-        state = PS_BUSY;
+        state = IPS_BUSY;
     else
-        state = PS_ALERT;
+        state = IPS_ALERT;
 
     drawLt(state);
 }
@@ -476,7 +477,7 @@ int INDI_P::buildTextGUI(XMLEle *root, QString & errmsg)
 
     }
 
-    if (perm == PP_RO)
+    if (perm == IP_RO)
         return 0;
 
     // INDI STD, but we use our own controls
@@ -562,7 +563,7 @@ int INDI_P::buildNumberGUI  (XMLEle *root, QString & errmsg)
 
     setlocale(LC_NUMERIC,"");
 
-    if (perm == PP_RO)
+    if (perm == IP_RO)
         return 0;
 
 
@@ -638,7 +639,7 @@ int INDI_P::buildMenuGUI(XMLEle *root, QString & errmsg)
 
         lp = new INDI_E(this, switchName, switchLabel);
 
-        if (pg->dp->crackSwitchState (pcdataXMLEle(sep), &(lp->state)) < 0)
+        if (pg->dp->crackSwitchState (pcdataXMLEle(sep), &(lp->switch_state)) < 0)
         {
             errmsg = QString("INDI: <%1> unknown state %2 for %3 %4 %5").arg(tagXMLEle(root)).arg(valuXMLAtt(ap)).arg(name).arg(lp->name).arg(name);
             return DeviceManager::INDI_PROPERTY_INVALID;
@@ -646,7 +647,7 @@ int INDI_P::buildMenuGUI(XMLEle *root, QString & errmsg)
 
         menuOptions.append(switchLabel);
 
-        if (lp->state == PS_ON)
+        if (lp->switch_state == ISS_ON)
         {
             if (onItem != -1)
             {
@@ -720,7 +721,7 @@ int INDI_P::buildSwitchesGUI(XMLEle *root, QString & errmsg)
 
         lp = new INDI_E(this, switchName, switchLabel);
 
-        if (pg->dp->crackSwitchState (pcdataXMLEle(sep), &(lp->state)) < 0)
+        if (pg->dp->crackSwitchState (pcdataXMLEle(sep), &(lp->switch_state)) < 0)
         {
             errmsg = QString("INDI: <%1> unknown state %2 for %3 %4 %5").arg(tagXMLEle(root)).arg(valuXMLAtt(ap)).arg(name).arg(name).arg(lp->name);
             return DeviceManager::INDI_PROPERTY_INVALID;
@@ -737,7 +738,7 @@ int INDI_P::buildSwitchesGUI(XMLEle *root, QString & errmsg)
             //groupB->insert(button, j);
             groupB->addButton(button);
 
-            if (lp->state == PS_ON)
+            if (lp->switch_state == ISS_ON)
             {
                 button->setDown(true);
                 buttonFont = button->font();
@@ -758,7 +759,7 @@ int INDI_P::buildSwitchesGUI(XMLEle *root, QString & errmsg)
             //groupB->insert(checkbox, j);
             groupB->addButton(button);
 
-            if (lp->state == PS_ON)
+            if (lp->switch_state == ISS_ON)
                 checkbox->setChecked(true);
 
             lp->check_w = checkbox;
@@ -818,7 +819,7 @@ int INDI_P::buildLightsGUI(XMLEle *root, QString & errmsg)
 
         lp = new INDI_E(this, sname, slabel);
 
-        if (pg->dp->crackLightState (pcdataXMLEle(lep), &lp->state) < 0)
+        if (pg->dp->crackLightState (pcdataXMLEle(lep), &lp->light_state) < 0)
         {
             errmsg = QString("INDI: <%1> unknown state %2 for %3 %4 %5").arg(tagXMLEle(root)).arg(valuXMLAtt(ap)).arg(pg->dp->name).arg(name).arg(sname);
             return DeviceManager::INDI_PROPERTY_INVALID;
@@ -891,7 +892,7 @@ int INDI_P::buildBLOBGUI(XMLEle *root, QString & errmsg)
 
     connect(enableBLOBC, SIGNAL(stateChanged(int)), this, SLOT(setBLOBOption(int)));
 
-    if (perm != PP_RO)
+    if (perm != IP_RO)
     {
         setupSetButton(i18n("Upload"));
         QObject::connect(set_w, SIGNAL(clicked()), this, SLOT(newBlob()));
diff --git a/kstars/indi/indiproperty.h b/kstars/indi/indiproperty.h
index 7f951c0..b2974f1 100644
--- a/kstars/indi/indiproperty.h
+++ b/kstars/indi/indiproperty.h
@@ -47,9 +47,9 @@ public:
     INDI_G	*pg;			/* parent group */
     INDIStdProperty *indistd;		/* Associated std routines class */
     double	timeout;		/* timeout, seconds */
-    PState	state;			/* state light code */
+    IPState	state;			/* state light code */
     KLed	*light;			/* state LED */
-    PPerm       perm;		        /* permissions wrt client */
+    IPerm       perm;		        /* permissions wrt client */
     PGui        guitype;		/* type of GUI, if any */
     QCheckBox    *enableBLOBC;
 
@@ -69,7 +69,7 @@ public:
     QList<INDI_E*> el;		/* list of elements */
 
     /* Draw state LED */
-    void drawLt(PState lstate);
+    void drawLt(IPState lstate);
 
     /* First step in adding a new GUI element */
     void addGUI(XMLEle *root);
diff --git a/kstars/indi/indistd.cpp b/kstars/indi/indistd.cpp
index 1faaa48..8b4122c 100644
--- a/kstars/indi/indistd.cpp
+++ b/kstars/indi/indistd.cpp
@@ -306,8 +306,9 @@ void INDIStdDevice::setTextValue(INDI_P *pp)
         break;
 
     case CCD_EXPOSURE_REQUEST:
-        if (pp->state == PS_IDLE || pp->state == PS_OK)
+        if (pp->state == IPS_IDLE || pp->state == IPS_OK)
             pp->set_w->setText(i18n("Capture"));
+
         break;
 
     case CCD_FRAME:
@@ -380,7 +381,7 @@ void INDIStdDevice::setLabelState(INDI_P *pp)
         lp = pp->findElement("CONNECT");
         if (!lp) return;
 
-        if (lp->state == PS_ON)
+        if (lp->switch_state == ISS_ON)
         {
             createDeviceInit();
             emit linkAccepted();
@@ -418,7 +419,7 @@ void INDIStdDevice::setLabelState(INDI_P *pp)
     case VIDEO_STREAM:
         lp = pp->findElement("ON");
         if (!lp) return;
-        if (lp->state == PS_ON)
+        if (lp->switch_state == ISS_ON)
             streamWindow->enableStream(true);
         else
             streamWindow->enableStream(false);
@@ -444,7 +445,7 @@ void INDIStdDevice::streamDisabled()
     el = pp->findElement("OFF");
     if (!el) return;
 
-    if (el->state == PS_ON)
+    if (el->switch_state == ISS_ON)
         return;
 
     // Turn stream off
@@ -636,14 +637,14 @@ void INDIStdDevice::registerProperty(INDI_P *pp)
             {
                 if (device->deviceManager == dp->deviceManager)
                 {
-                    if (device->deviceType == KSTARS_TELESCOPE)
+                    if (device->type == KSTARS_TELESCOPE)
                     {
                         portEle->read_w->setText( Options::telescopePort() );
                         portEle->write_w->setText( Options::telescopePort() );
                         portEle->text = Options::telescopePort();
                         break;
                     }
-                    else if (device->deviceType == KSTARS_VIDEO)
+                    else if (device->type == KSTARS_VIDEO)
                     {
                         portEle->read_w->setText( Options::videoPort() );
                         portEle->write_w->setText( Options::videoPort() );
@@ -661,9 +662,14 @@ void INDIStdDevice::registerProperty(INDI_P *pp)
         emit newTelescope();
         break;
 
-        // Update Device menu actions
+    case CCD_EXPOSURE_REQUEST:
         drivers->updateMenuActions();
+        break;
+
+
     }
+
+
 }
 
 /*********************************************************************************/
@@ -752,7 +758,7 @@ bool INDIStdDevice::handleNonSidereal()
 
                 /* Send object name if available */
                 nameEle = dp->findElem("OBJECT_NAME");
-                if (nameEle && nameEle->pp->perm != PP_RO)
+                if (nameEle && nameEle->pp->perm != IP_RO)
                 {
                     nameEle->write_w->setText(currentObject->name());
                     nameEle->pp->newText();
@@ -811,7 +817,7 @@ void INDIStdDevice::timerDone()
     el   = prop->findElement("TRACK");
     if (!el) return;
 
-    if (el->state != PS_ON)
+    if (el->switch_state != ISS_ON)
     {
         devTimer->stop();
         return;
@@ -833,7 +839,7 @@ void INDIStdDevice::timerDone()
         return;
 
     // wait until slew is done
-    if (prop->state == PS_BUSY)
+    if (prop->state == IPS_BUSY)
         return;
 
     kDebug() << "Timer called, starting processing";
@@ -900,11 +906,11 @@ void INDIStdProperty::newText()
             {
                 if (device->deviceManager == stdDev->dp->deviceManager)
                 {
-                    if (device->deviceType == KSTARS_TELESCOPE)
+                    if (device->type == KSTARS_TELESCOPE)
                     {
                         Options::setTelescopePort( lp->text );
                     }
-                    else if (device->deviceType == KSTARS_VIDEO)
+                    else if (device->type == KSTARS_VIDEO)
                     {
                         Options::setVideoPort( lp->text );
                     }
@@ -995,10 +1001,10 @@ bool INDIStdDevice::slew_scope(SkyPoint *scope_target, INDI_E *lp)
 
     HorProp = dp->findProp("HORIZONTAL_COORD_REQUEST");
 
-    if (EqProp && EqProp->perm == PP_RO)
+    if (EqProp && EqProp->perm == IP_RO)
 		EqProp = NULL;
 
-    if (HorProp && HorProp->perm == PP_RO)
+    if (HorProp && HorProp->perm == IP_RO)
           	HorProp = NULL;
 
     //kDebug() << "Skymap click - RA: " << scope_target->ra().toHMSString() << " DEC: " << scope_target->dec().toDMSString();
@@ -1081,7 +1087,7 @@ bool INDIStdProperty::actionTriggered(INDI_E *lp)
                 return true;
 
            nameEle = stdDev->dp->findElem("OBJECT_NAME");
-       	   if (nameEle && nameEle->pp->perm != PP_RO)
+           if (nameEle && nameEle->pp->perm != IP_RO)
            {
                if (stdDev->currentObject == NULL)
 			nameEle->write_w->setText("--");
diff --git a/kstars/indi/telescopewizardprocess.cpp b/kstars/indi/telescopewizardprocess.cpp
index 5b4aac9..9ce1cc4 100644
--- a/kstars/indi/telescopewizardprocess.cpp
+++ b/kstars/indi/telescopewizardprocess.cpp
@@ -78,7 +78,7 @@ telescopeWizardProcess::telescopeWizardProcess( QWidget* parent, const char* /*n
 
 
     foreach (IDevice *device, indidriver->devices)
-    if (device->deviceType == KSTARS_TELESCOPE)
+    if (device->type == KSTARS_TELESCOPE)
         ui->telescopeCombo->addItem(device->tree_label);
 
     //if ( !Options::telescopePort().isEmpty())
diff --git a/kstars/kspopupmenu.cpp b/kstars/kspopupmenu.cpp
index ce70573..8350258 100644
--- a/kstars/kspopupmenu.cpp
+++ b/kstars/kspopupmenu.cpp
@@ -495,7 +495,7 @@ void KSPopupMenu::addINDI()
                         if (prop->stdID == ON_COORD_SET)
                             continue;
 
-                        a->setChecked( element->state == PS_ON );
+                        a->setChecked( element->switch_state == ISS_ON );
                     }
                 } // end property
             } // end group
diff --git a/kstars/kstars.cpp b/kstars/kstars.cpp
index ed757a3..bd84e28 100644
--- a/kstars/kstars.cpp
+++ b/kstars/kstars.cpp
@@ -57,8 +57,8 @@ KStars::KStars( bool doSplash, bool clockrun, const QString &startdate ) :
         AAVSODialog(0), findDialog(0), imgExportDialog(0), obsList(0),
         execute(0),
         avt(0), wut(0), skycal(0),
-        sb(0), pv(0), jmt(0), fm(0), astrocalc(0), printingWizard(0), indimenu(0), indidriver(0),
-        indiseq(0), DialogIsObsolete(false), StartClockRunning( clockrun ),
+    sb(0), pv(0), jmt(0), fm(0), astrocalc(0), printingWizard(0), indimenu(0), indidriver(0),
+        indiseq(0), ekosmenu(0), DialogIsObsolete(false), StartClockRunning( clockrun ),
         StartDateString( startdate )
 {
     new KstarsAdaptor(this);
diff --git a/kstars/kstars.h b/kstars/kstars.h
index aa76633..8ac71f5 100644
--- a/kstars/kstars.h
+++ b/kstars/kstars.h
@@ -64,6 +64,7 @@ class OpsSatellites;
 class OpsColors;
 class OpsAdvanced;
 class OpsINDI;
+class Ekos;
 #ifdef HAVE_XPLANET
 class OpsXplanet;
 #endif
@@ -533,6 +534,9 @@ private slots:
     /** action slot: open INDI control panel */
     void slotINDIPanel();
 
+    /** action slot: open Ekos panel */
+    void slotEkos();
+
     /** action slot: open dialog for setting the view options */
     void slotViewOps();
 
@@ -659,6 +663,7 @@ private:
     INDIMenu *indimenu;
     INDIDriver *indidriver;
     imagesequence *indiseq;  /* We need imgsequence here because it runs in batch mode */
+    Ekos *ekosmenu;
 
     QActionGroup *projectionGroup, *cschemeGroup;
 
diff --git a/kstars/kstarsactions.cpp b/kstars/kstarsactions.cpp
index 15d2552..d20f9b6 100644
--- a/kstars/kstarsactions.cpp
+++ b/kstars/kstarsactions.cpp
@@ -97,6 +97,9 @@
 
 #ifdef HAVE_CFITSIO_H
 #include "fitsviewer/fitsviewer.h"
+#ifdef HAVE_INDI_H
+#include "ekos/ekos.h"
+#endif
 #endif
 
 #ifdef HAVE_XPLANET
@@ -343,6 +346,16 @@ void KStars::slotINDIDriver()
 #endif
 }
 
+void KStars::slotEkos()
+{
+#ifdef HAVE_INDI_H
+    if (ekosmenu == NULL)
+        ekosmenu = new Ekos(this);
+
+    ekosmenu->show();
+#endif
+}
+
 void KStars::slotGeoLocator() {
     QPointer<LocationDialog> locationdialog = new LocationDialog(this);
     if ( locationdialog->exec() == QDialog::Accepted ) {
diff --git a/kstars/kstarsinit.cpp b/kstars/kstarsinit.cpp
index 1ed0a9b..fa0e4b4 100644
--- a/kstars/kstarsinit.cpp
+++ b/kstars/kstarsinit.cpp
@@ -378,6 +378,13 @@ void KStars::initActions() {
     actionCollection()->addAction("skycalendar", this, SLOT( slotCalendar() ) )
         << i18n("Sky Calendar...");
 
+#ifdef HAVE_INDI_H
+#ifndef Q_WS_WIN
+    actionCollection()->addAction("ekos", this, SLOT( slotEkos() ) )
+        << i18n("Ekos...");
+#endif
+#endif
+
 //FIXME: implement glossary
 //     ka = actionCollection()->addAction("glossary");
 //     ka->setText( i18n("Glossary...") );
@@ -427,6 +434,8 @@ void KStars::initActions() {
         << i18n("INDI Control Panel...");
     ka->setEnabled(false);
 
+
+
 #endif
 #endif
 
diff --git a/kstars/kstarsui-indi.rc b/kstars/kstarsui-indi.rc
index b8a2a09..6903a36 100644
--- a/kstars/kstarsui-indi.rc
+++ b/kstars/kstarsui-indi.rc
@@ -72,6 +72,7 @@
 		<Action name="lightcurvegenerator" />
 		<Action name="altitude_vs_time" />
 		<Action name="whats_up_tonight" />
+                <Action name="ekos" />
 		<Action name="glossary" />
 		<Action name="scriptbuilder" />
 		<Action name="solarsystem" />
diff --git a/kstars/oal/equipmentwriter.ui b/kstars/oal/equipmentwriter.ui
index b5693d1..4b3a23f 100644
--- a/kstars/oal/equipmentwriter.ui
+++ b/kstars/oal/equipmentwriter.ui
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>411</width>
-    <height>324</height>
+    <height>344</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="_2">
@@ -20,7 +20,7 @@
       </size>
      </property>
      <property name="currentIndex">
-      <number>3</number>
+      <number>0</number>
      </property>
      <property name="documentMode">
       <bool>false</bool>
@@ -86,6 +86,9 @@
            </item>
            <item row="5" column="1">
             <widget class="KComboBox" name="Type">
+             <property name="focusPolicy">
+              <enum>Qt::TabFocus</enum>
+             </property>
              <item>
               <property name="text">
                <string>Refractor</string>
@@ -128,9 +131,18 @@
            <item row="6" column="1">
             <layout class="QHBoxLayout" name="horizontalLayout_5">
              <item>
-              <widget class="KDoubleNumInput" name="Aperture" native="true">
+              <widget class="KDoubleNumInput" name="Aperture">
                <property name="focusPolicy">
-                <enum>Qt::TabFocus</enum>
+                <enum>Qt::ClickFocus</enum>
+               </property>
+               <property name="label">
+                <string/>
+               </property>
+               <property name="singleStep">
+                <double>0.100000000000000</double>
+               </property>
+               <property name="sliderEnabled">
+                <bool>false</bool>
                </property>
               </widget>
              </item>
@@ -153,9 +165,9 @@
            <item row="7" column="1">
             <layout class="QHBoxLayout" name="horizontalLayout_4">
              <item>
-              <widget class="KDoubleNumInput" name="FocalLength" native="true">
+              <widget class="KDoubleNumInput" name="FocalLength">
                <property name="focusPolicy">
-                <enum>Qt::TabFocus</enum>
+                <enum>Qt::ClickFocus</enum>
                </property>
               </widget>
              </item>
@@ -177,6 +189,9 @@
            </item>
            <item row="4" column="1">
             <widget class="QComboBox" name="driverComboBox">
+             <property name="focusPolicy">
+              <enum>Qt::TabFocus</enum>
+             </property>
              <item>
               <property name="text">
                <string>None</string>
@@ -273,7 +288,7 @@
            <item row="4" column="1">
             <layout class="QHBoxLayout" name="horizontalLayout_6">
              <item>
-              <widget class="KDoubleNumInput" name="e_focalLength" native="true">
+              <widget class="KDoubleNumInput" name="e_focalLength">
                <property name="focusPolicy">
                 <enum>Qt::TabFocus</enum>
                </property>
@@ -317,7 +332,7 @@
             </widget>
            </item>
            <item>
-            <widget class="KDoubleNumInput" name="Fov" native="true">
+            <widget class="KDoubleNumInput" name="Fov">
              <property name="focusPolicy">
               <enum>Qt::TabFocus</enum>
              </property>
@@ -467,7 +482,7 @@
             </widget>
            </item>
            <item row="4" column="1">
-            <widget class="KDoubleNumInput" name="l_Factor" native="true">
+            <widget class="KDoubleNumInput" name="l_Factor">
              <property name="focusPolicy">
               <enum>Qt::TabFocus</enum>
              </property>
@@ -649,9 +664,9 @@
  </widget>
  <customwidgets>
   <customwidget>
-   <class>KLineEdit</class>
-   <extends>QLineEdit</extends>
-   <header>klineedit.h</header>
+   <class>KDoubleNumInput</class>
+   <extends>QWidget</extends>
+   <header>knuminput.h</header>
   </customwidget>
   <customwidget>
    <class>KComboBox</class>
@@ -659,9 +674,10 @@
    <header>kcombobox.h</header>
   </customwidget>
   <customwidget>
-   <class>KDoubleNumInput</class>
-   <extends>QWidget</extends>
-   <header>knuminput.h</header>
+   <class>KLineEdit</class>
+   <extends>QLineEdit</extends>
+   <header>klineedit.h</header>
+   <container>1</container>
   </customwidget>
   <customwidget>
    <class>KListWidget</class>
@@ -681,13 +697,13 @@
   <tabstop>NewScope</tabstop>
   <tabstop>AddScope</tabstop>
   <tabstop>RemoveScope</tabstop>
-  <tabstop>EyepieceList</tabstop>
   <tabstop>e_Vendor</tabstop>
-  <tabstop>e_Model</tabstop>
+  <tabstop>EyepieceList</tabstop>
   <tabstop>e_focalLength</tabstop>
   <tabstop>Fov</tabstop>
   <tabstop>FovUnit</tabstop>
   <tabstop>NewEyepiece</tabstop>
+  <tabstop>e_Model</tabstop>
   <tabstop>AddEyepiece</tabstop>
   <tabstop>RemoveEyepiece</tabstop>
   <tabstop>LensList</tabstop>
diff --git a/kstars/skymapdrawabstract.cpp b/kstars/skymapdrawabstract.cpp
index 82db1ae..c724bff 100644
--- a/kstars/skymapdrawabstract.cpp
+++ b/kstars/skymapdrawabstract.cpp
@@ -201,7 +201,7 @@ void SkyMapDrawAbstract::drawTelescopeSymbols(QPainter &psky)
             // make sure the dev is on first
             if (devMenu->managers.at(i)->indi_dev.at(j)->isOn()) {
                 portConnect = devMenu->managers.at(i)->indi_dev.at(j)->findProp("CONNECTION");
-                if( !portConnect || portConnect->state == PS_BUSY )
+                if( !portConnect || portConnect->state == IPS_BUSY )
                     return;
 
                 eqNum = devMenu->managers.at(i)->indi_dev.at(j)->findProp("EQUATORIAL_EOD_COORD");
@@ -342,7 +342,7 @@ void SkyMapDrawAbstract::exportSkyImage(SkyQPainter *painter, bool scale)
 void SkyMapDrawAbstract::calculateFPS()
 {
     if(m_framecount == 25) {
-        float sec = m_fpstime.elapsed()/1000.;
+        //float sec = m_fpstime.elapsed()/1000.;
         // kDebug() << "FPS " << m_framecount/sec;
         m_framecount = 0;
         m_fpstime.restart();
diff --git a/kstars/tools/observinglist.cpp b/kstars/tools/observinglist.cpp
index 6f1b6fa..3d4ac99 100644
--- a/kstars/tools/observinglist.cpp
+++ b/kstars/tools/observinglist.cpp
@@ -603,7 +603,7 @@ void ObservingList::slotSlewToObject()
             ConnectEle = indidev->findElem("CONNECT");
             if (!ConnectEle) continue;
 
-            if (ConnectEle->state == PS_OFF)
+            if (ConnectEle->switch_state == ISS_OFF)
             {
                 KMessageBox::error(0, i18n("Telescope %1 is offline. Please connect and retry again.", indidev->label));
                 return;


More information about the Kstars-devel mailing list