Skip to content

Commit e7dfc40

Browse files
authored
lx200_10micron: add shutdown command, guard behind parked state (#2415)
Adds a Shutdown button on the Main Control tab that sends :shutdown# to power off the 10micron mount. The button is blocked (IPS_ALERT + warning) unless the mount is fully parked, preventing accidental power-off during active use. Property implemented with INDI::PropertySwitch using the modern .fill()/.reset()/.setState()/.apply()/.isNameMatch() API.
1 parent ab1ace2 commit e7dfc40

2 files changed

Lines changed: 55 additions & 0 deletions

File tree

drivers/telescope/lx200_10micron.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#define UNATTENDED_FLIP "UNATTENDED_FLIP"
6262
#define WAKE_ON_LAN_MAC "WAKE_ON_LAN_MAC"
6363
#define WAKE_ON_LAN_SEND "WAKE_ON_LAN_SEND"
64+
#define MOUNT_SHUTDOWN "MOUNT_SHUTDOWN"
6465

6566
LX200_10MICRON::LX200_10MICRON() : LX200Generic()
6667
{
@@ -197,6 +198,9 @@ bool LX200_10MICRON::initProperties()
197198

198199
IUFillSwitch(&WoLSendS[0], "SEND", "Wake Mount", ISS_OFF);
199200
IUFillSwitchVector(&WoLSendSP, WoLSendS, 1, getDeviceName(), WAKE_ON_LAN_SEND, "Wake on LAN", CONNECTION_TAB, IP_RW, ISR_ATMOST1, 60, IPS_IDLE);
201+
202+
MountShutdownSP[0].fill("SHUTDOWN", "Shutdown Mount", ISS_OFF);
203+
MountShutdownSP.fill(getDeviceName(), MOUNT_SHUTDOWN, "Shutdown", MAIN_CONTROL_TAB, IP_RW, ISR_ATMOST1, 60, IPS_IDLE);
200204
}
201205
return result;
202206
}
@@ -220,6 +224,11 @@ bool LX200_10MICRON::saveConfigItems(FILE *fp)
220224
// Called by INDI::Telescope when connected state changes to add/remove properties
221225
bool LX200_10MICRON::updateProperties()
222226
{
227+
// Define MountShutdownSP before the parent call so it appears immediately on connect,
228+
// not after the slow getBasicData() mount queries inside LX200Generic::updateProperties().
229+
if (isConnected())
230+
defineProperty(MountShutdownSP);
231+
223232
bool result = LX200Generic::updateProperties();
224233

225234
if (isConnected())
@@ -266,6 +275,7 @@ bool LX200_10MICRON::updateProperties()
266275
}
267276
else
268277
{
278+
deleteProperty(MountShutdownSP);
269279
deleteProperty(UnattendedFlipSP.name);
270280
deleteProperty(ProductTP.name);
271281
deleteProperty(RefractionModelTemperatureNP.name);
@@ -1335,6 +1345,32 @@ bool LX200_10MICRON::ISNewSwitch(const char *dev, const char *name, ISState *sta
13351345
IDSetSwitch(&WoLSendSP, nullptr);
13361346
return true;
13371347
}
1348+
if (MountShutdownSP.isNameMatch(name))
1349+
{
1350+
MountShutdownSP.reset();
1351+
if (!isParked())
1352+
{
1353+
MountShutdownSP.setState(IPS_ALERT);
1354+
LOG_WARN("Mount must be parked before shutdown.");
1355+
MountShutdownSP.apply();
1356+
return false;
1357+
}
1358+
// :shutdown# — returns '1' on success, '0' on failure; ~20 s until power-off
1359+
if (0 != setStandardProcedureAndExpectChar(fd, ":shutdown#", "1"))
1360+
{
1361+
MountShutdownSP.setState(IPS_ALERT);
1362+
LOG_ERROR("Mount shutdown command failed.");
1363+
MountShutdownSP.apply();
1364+
return false;
1365+
}
1366+
MountShutdownSP.setState(IPS_OK);
1367+
LOG_INFO("Mount shutdown initiated. Disconnecting before mount powers off.");
1368+
MountShutdownSP.apply();
1369+
// Defer disconnect so ISNewSwitch returns cleanly before we tear down the property list
1370+
m_ShutdownPending = true;
1371+
SetTimer(100);
1372+
return true;
1373+
}
13381374
}
13391375

13401376
return LX200Generic::ISNewSwitch(dev, name, states, names, n);
@@ -1500,6 +1536,20 @@ int LX200_10MICRON::setStandardProcedureAndReturnResponse(int fd, const char *da
15001536
return 0;
15011537
}
15021538

1539+
void LX200_10MICRON::TimerHit()
1540+
{
1541+
if (m_ShutdownPending)
1542+
{
1543+
m_ShutdownPending = false;
1544+
// Standard INDI disconnect sequence — same as clicking Disconnect in the UI
1545+
Disconnect();
1546+
setConnected(false, IPS_IDLE);
1547+
updateProperties();
1548+
return; // do not reschedule polling
1549+
}
1550+
LX200Generic::TimerHit();
1551+
}
1552+
15031553
bool LX200_10MICRON::sendWakeOnLanPacket()
15041554
{
15051555
const char *macStr = WoLMacT[0].text;

drivers/telescope/lx200_10micron.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,16 @@ class LX200_10MICRON : public LX200Generic
183183
ISwitch WoLSendS[1];
184184
ISwitchVectorProperty WoLSendSP;
185185

186+
// Shutdown
187+
INDI::PropertySwitch MountShutdownSP {1};
188+
186189
private:
187190
int fd = -1; // short notation for PortFD/sockfd
188191
bool getMountInfo();
189192
bool flip();
190193
bool sendWakeOnLanPacket();
194+
bool m_ShutdownPending { false };
195+
void TimerHit() override;
191196

192197
int OldGstat = GSTAT_UNSET;
193198
struct _Ginfo

0 commit comments

Comments
 (0)