-
Notifications
You must be signed in to change notification settings - Fork 204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactoring - ASI CCD driver #359
Conversation
Thank you! This is the first time for hotplug implementation. I also see the worker thread implementation which could be used by other drivers as well! I will give this a go tonight. |
@pawel-soja Looks like there is some issue with the hotplug. One driver crashed, when I restarted (I have ASI120 and ASI178) and I get this: 2021-03-20T22:08:24: [ERROR] Error connecting to the CCD (ASI_ERROR_CAMERA_REMOVED). I recycled the power and cannot use the camera anymore. Can you please check? |
@knro Can you describe exactly in what order you run indi_asi_ccd, connect / disconnect cameras? |
I restarted the PI and it appears to be working now, will try to test more and see what happens. |
@knro Maybe as you saw I disabled the updateProperties function call. indi-3rdparty/indi-asi/asi_ccd.cpp Lines 386 to 395 in 99ec370
I disabled it because it removes all controls from all cameras. It seems that KStars does not consider the device name. You can test it on a simple example. #include <libindi/defaultdevice.h>
#include <libindi/indipropertylight.h>
class SimpleDevice : public INDI::DefaultDevice
{
const char *name;
INDI::PropertyLight LightLP {1};
public:
SimpleDevice(const char *name)
: name(name)
{
setDeviceName(name);
LightLP[0].fill("LIGHT_NAME", "LIGHT_LABEL");
LightLP.fill(getDeviceName(), "LIGHT_NAME_LP", "LIGHT_LABEL_LP", MAIN_CONTROL_TAB, IPS_OK);
}
bool updateProperties() override
{
DefaultDevice::updateProperties();
if (isConnected())
{
//defineProperty(LightLP);
IDDefLight(&LightLP, nullptr);
}
else
{
//deleteProperty(LightLP.getName());
IDDelete(LightLP.getDeviceName(), LightLP.getName(), nullptr);
}
return true;
}
bool Connect() override { return true; }
bool Disconnect() override { return true; }
const char *getDefaultName() override { return name; }
};
static SimpleDevice simpleDevice1("Simple Device 1");
static SimpleDevice simpleDevice2("Simple Device 2");
Connect both devices, then click disconnect in one of them. |
KStars 3.5.3 works ;) |
Thanks for the confirmation! Let me know if you have anything else! |
I am testing how to remove the entire device from tabs. bool DefaultDevice::deleteProperty(const char *propertyName)
{
D_PTR(DefaultDevice);
char errmsg[MAXRBUF];
if (propertyName == nullptr)
{
//while(!pAll.empty()) delete bar.back(), bar.pop_back();
IDDelete(getDeviceName(), nullptr, nullptr);
return true;
}
// Keep dynamic properties in existing property list so they can be reused
if (d->deleteDynamicProperties == false)
{
INDI::Property *prop = getProperty(propertyName);
if (prop && prop->isDynamic())
{
IDDelete(getDeviceName(), propertyName, nullptr);
return true;
}
}
if (removeProperty(propertyName, errmsg) == 0)
{
IDDelete(getDeviceName(), propertyName, nullptr);
return true;
}
else
return false;
} Unfortunately, all devices disappear (the 'INDI Control Panel' window closes). #include <libindi/defaultdevice.h>
#include <libindi/indipropertylight.h>
class SimpleDevice : public INDI::DefaultDevice
{
const char *name;
INDI::PropertyLight LightLP {1};
public:
SimpleDevice(const char *name)
: name(name)
{
setDeviceName(name);
LightLP[0].fill("LIGHT_NAME", "LIGHT_LABEL");
LightLP.fill(getDeviceName(), "LIGHT_NAME_LP", "LIGHT_LABEL_LP", MAIN_CONTROL_TAB, IPS_OK);
}
bool updateProperties() override
{
DefaultDevice::updateProperties();
if (isConnected())
{
//defineProperty(LightLP);
IDDefLight(&LightLP, nullptr);
}
else
{
// try delete Simple Device X
//deleteProperty(nullptr);
IDDelete(getDeviceName(), nullptr, nullptr);
}
return true;
}
bool Connect() override { return true; }
bool Disconnect() override { return true; }
const char *getDefaultName() override { return name; }
};
static SimpleDevice simpleDevice1("Simple Device 1");
static SimpleDevice simpleDevice2("Simple Device 2"); |
I found kstars/ekos/manager.cpp void Manager::removeDevice(ISD::GDInterface * devInterface)
{
// switch (devInterface->getType())
// {
// case KSTARS_CCD:
// removeTabs();
// break;
// default:
// break;
// }
if (alignProcess)
alignProcess->removeDevice(devInterface);
if (captureProcess)
captureProcess->removeDevice(devInterface);
if (focusProcess)
focusProcess->removeDevice(devInterface);
if (mountProcess)
mountProcess->removeDevice(devInterface);
if (guideProcess)
guideProcess->removeDevice(devInterface);
if (domeProcess)
domeProcess->removeDevice(devInterface);
if (weatherProcess)
weatherProcess->removeDevice(devInterface);
if (dustCapProcess)
{
dustCapProcess->removeDevice(devInterface);
DarkLibrary::Instance()->removeDevice(devInterface);
}
appendLogText(i18n("%1 is offline.", devInterface->getDeviceName()));
// #1 Remove from Generic Devices
// Generic devices are ALL the devices we receive from INDI server
// Whether Ekos cares about them (i.e. selected equipment) or extra devices we
// do not care about
for (auto &device : genericDevices)
{
if (device->getDeviceName() == devInterface->getDeviceName())
{
genericDevices.removeOne(device);
}
}
// #2 Remove from Proxy device
// Proxy devices are ALL the devices we specifically create in Ekos Manager to handle specific interfaces
for (auto &device : proxyDevices)
{
if (device->getDeviceName() == devInterface->getDeviceName())
{
proxyDevices.removeOne(device);
device->deleteLater();
}
}
// #3 Remove from Ekos Managed Device
// Managed devices are devices selected by the user in the device profile
for (auto it = managedDevices.begin(); it != managedDevices.end();)
{
if (it.value()->getDeviceName() == devInterface->getDeviceName())
{
it = managedDevices.erase(it);
}
else
++it;
}
if (managedDevices.isEmpty()) // <====================================
{
cleanDevices();
removeTabs();
}
} @knro Is the implementation at the end of the function with intention? Maybe it should be something like: if (managedDevices.isEmpty() && genericDevices.isEmpty() && proxyDevices.isEmpty())
{
cleanDevices();
removeTabs();
} |
Nice detective work @pawel-soja. I will check why it was done in this way. There are lots of scenarios that requires testing (remote and local drivers, chained server...etc). |
Fantastic! I would like to add something like this (indilib): DefaultDevicePrivate::~DefaultDevicePrivate()
{
const std::unique_lock<std::recursive_mutex> lock(DefaultDevicePrivate::devicesLock);
devices.remove(this);
IDDelete(deviceName.c_str(), nullptr, nullptr); // <==== added
} |
Hi!
Improving the readability of the driver.
indilib/indi#1389 is required for this PR.
Changes: