-
Notifications
You must be signed in to change notification settings - Fork 396
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
308 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
/* | ||
Relay Interface | ||
Copyright (C) 2024 Jasem Mutlaq ([email protected]) | ||
This library is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU Lesser General Public | ||
License as published by the Free Software Foundation; either | ||
version 2.1 of the License, or (at your option) any later version. | ||
This library is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
Lesser General Public License for more details. | ||
You should have received a copy of the GNU Lesser General Public | ||
License along with this library; if not, write to the Free Software | ||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
*/ | ||
|
||
#include "indirelayinterface.h" | ||
#include <cstring> | ||
#include "indilogger.h" | ||
|
||
namespace INDI | ||
{ | ||
|
||
///////////////////////////////////////////////////////////////////////////////////////////// | ||
/// | ||
///////////////////////////////////////////////////////////////////////////////////////////// | ||
RelayInterface::RelayInterface(DefaultDevice *defaultDevice) : m_defaultDevice(defaultDevice) | ||
{ | ||
} | ||
|
||
///////////////////////////////////////////////////////////////////////////////////////////// | ||
/// | ||
///////////////////////////////////////////////////////////////////////////////////////////// | ||
RelayInterface::~RelayInterface() | ||
{ | ||
} | ||
|
||
///////////////////////////////////////////////////////////////////////////////////////////// | ||
/// | ||
///////////////////////////////////////////////////////////////////////////////////////////// | ||
void RelayInterface::initProperties(const char *groupName, uint8_t relays) | ||
{ | ||
RelayLabelsTP.reserve(relays); | ||
|
||
// Initialize labels | ||
for (auto i = 0; i < relays; i++) | ||
{ | ||
auto name = "RELAY_" + std::to_string(i); | ||
auto label = "Relay #" + std::to_string(i); | ||
|
||
INDI::WidgetText oneLabel; | ||
oneLabel.fill(name, label, label); | ||
RelayLabelsTP.push(std::move(oneLabel)); | ||
} | ||
|
||
RelayLabelsTP.fill(m_defaultDevice->getDeviceName(), "RELAY_LABELS", "Labels", groupName, IP_RW, 60, IPS_IDLE); | ||
RelayLabelsTP.shrink_to_fit(); | ||
RelayLabelsTP.load(); | ||
|
||
RelaysSP.reserve(relays); | ||
// Initialize switches, use labels if loaded. | ||
for (auto i = 0; i < relays; i++) | ||
{ | ||
auto name = "RELAY_" + std::to_string(i); | ||
auto label = "Relay #" + std::to_string(i); | ||
|
||
INDI::PropertySwitch oneRelay {3}; | ||
oneRelay[Open].fill("OPEN", "Open", ISS_OFF); | ||
oneRelay[Close].fill("CLOSE", "Close", ISS_OFF); | ||
oneRelay[Flip].fill("FLIP", "Flip", ISS_OFF); | ||
|
||
if (i < RelayLabelsTP.count()) | ||
label = RelayLabelsTP[i].getText(); | ||
oneRelay.fill(m_defaultDevice->getDeviceName(), name.c_str(), label.c_str(), groupName, IP_RW, ISR_ATMOST1, 60, IPS_IDLE); | ||
RelaysSP.push_back(std::move(oneRelay)); | ||
} | ||
} | ||
|
||
///////////////////////////////////////////////////////////////////////////////////////////// | ||
/// | ||
///////////////////////////////////////////////////////////////////////////////////////////// | ||
bool RelayInterface::updateProperties() | ||
{ | ||
if (m_defaultDevice->isConnected()) | ||
{ | ||
for (auto &oneRelay : RelaysSP) | ||
m_defaultDevice->defineProperty(oneRelay); | ||
m_defaultDevice->defineProperty(RelayLabelsTP); | ||
} | ||
else | ||
{ | ||
for (auto &oneRelay : RelaysSP) | ||
m_defaultDevice->deleteProperty(oneRelay); | ||
m_defaultDevice->deleteProperty(RelayLabelsTP); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
///////////////////////////////////////////////////////////////////////////////////////////// | ||
/// | ||
///////////////////////////////////////////////////////////////////////////////////////////// | ||
bool RelayInterface::processSwitch(const char *dev, const char *name, ISState states[], char *names[], int n) | ||
{ | ||
if (dev && !strcmp(dev, m_defaultDevice->getDeviceName())) | ||
{ | ||
for (auto i = 0; i < RelaysSP.size(); i++) | ||
{ | ||
if (RelaysSP[i].isNameMatch(name)) | ||
{ | ||
auto oldState = RelaysSP[i].findOnSwitchIndex(); | ||
RelaysSP[i].update(states, names, n); | ||
auto newState = RelaysSP[i].findOnSwitchIndex(); | ||
if (oldState != newState) | ||
{ | ||
// Cast to Command and send | ||
if (CommandRelay(i, static_cast<Command>(newState))) | ||
{ | ||
RelaysSP[i].setState(IPS_OK); | ||
} | ||
else | ||
{ | ||
RelaysSP[i].setState(IPS_ALERT); | ||
RelaysSP[i].reset(); | ||
RelaysSP[i][oldState].setState(ISS_ON); | ||
} | ||
|
||
// Apply and return | ||
RelaysSP[i].apply(); | ||
return true; | ||
} | ||
// No state change | ||
else | ||
{ | ||
RelaysSP[i].setState(IPS_OK); | ||
RelaysSP[i].apply(); | ||
return true; | ||
} | ||
} | ||
|
||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
///////////////////////////////////////////////////////////////////////////////////////////// | ||
/// | ||
///////////////////////////////////////////////////////////////////////////////////////////// | ||
bool RelayInterface::processText(const char *dev, const char *name, char *texts[], char *names[], int n) | ||
{ | ||
if (dev && !strcmp(dev, m_defaultDevice->getDeviceName())) | ||
{ | ||
// If this call due to config loading, let's delete existing dummy property and define the full one | ||
if (RelayLabelsTP.isNameMatch(name)) | ||
{ | ||
RelayLabelsTP.update(texts, names, n); | ||
RelayLabelsTP.setState(IPS_OK); | ||
RelayLabelsTP.apply(); | ||
m_defaultDevice->saveConfig(RelayLabelsTP); | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
///////////////////////////////////////////////////////////////////////////////////////////// | ||
/// | ||
///////////////////////////////////////////////////////////////////////////////////////////// | ||
bool RelayInterface::saveConfigItems(FILE *fp) | ||
{ | ||
RelayLabelsTP.save(fp); | ||
return true; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/* | ||
Relay Interface | ||
Copyright (C) 2024 Jasem Mutlaq ([email protected]) | ||
This library is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU Lesser General Public | ||
License as published by the Free Software Foundation; either | ||
version 2.1 of the License, or (at your option) any later version. | ||
This library is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
Lesser General Public License for more details. | ||
You should have received a copy of the GNU Lesser General Public | ||
License along with this library; if not, write to the Free Software | ||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "indibase.h" | ||
#include <vector> | ||
#include <stdint.h> | ||
#include "indipropertyswitch.h" | ||
#include "indipropertytext.h" | ||
|
||
/** | ||
* \class RelayInterface | ||
\brief Provides interface to implement Remote Relay functionality. | ||
A web controlled relay is a simple device that can open, close, or flip a relay switch. | ||
\e IMPORTANT: initFilterProperties() must be called before any other function to initialize the filter properties. | ||
\author Jasem Mutlaq | ||
*/ | ||
namespace INDI | ||
{ | ||
|
||
class RelayInterface | ||
{ | ||
public: | ||
/*! Relay switch status. This is regardless on whether switch is normally closed or normally opened. */ | ||
typedef enum | ||
{ | ||
Opened, /*!< Switch is open circuit. */ | ||
Closed, /*!< Switch is close circuit. */ | ||
Unknown /*!< Could not determined switch status. */ | ||
} Status; | ||
|
||
/*! Relay switch Command. */ | ||
typedef enum | ||
{ | ||
Open, | ||
Close, | ||
Flip | ||
} Command; | ||
|
||
/** | ||
* \brief Query single relay status | ||
* \param index Relay index | ||
* \param status Store relay status in this variable. | ||
* \return True if operation is successful, false otherwise | ||
*/ | ||
virtual bool QueryRelay(uint32_t index, Status &status) = 0; | ||
|
||
/** | ||
* \brief Send command to relay | ||
* \return True if operation is successful, false otherwise | ||
*/ | ||
virtual bool CommandRelay(uint32_t index, Command command) = 0; | ||
|
||
protected: | ||
/** | ||
* @brief RelayInterface Initiailize Relay Interface | ||
* @param defaultDevice default device that owns the interface | ||
*/ | ||
explicit RelayInterface(DefaultDevice *defaultDevice); | ||
~RelayInterface(); | ||
|
||
/** | ||
* \brief Initialize filter wheel properties. It is recommended to call this function within | ||
* initProperties() of your primary device | ||
* \param groupName Group or tab name to be used to define filter wheel properties. | ||
* \param relays Number of relays | ||
*/ | ||
void initProperties(const char *groupName, uint8_t relays); | ||
|
||
/** | ||
* @brief updateProperties Defines or Delete properties based on default device connection status | ||
* @return True if all is OK, false otherwise. | ||
*/ | ||
bool updateProperties(); | ||
|
||
/** \brief Process switch properties */ | ||
bool processSwitch(const char *dev, const char *name, ISState states[], char *names[], int n); | ||
|
||
/** \brief Process text properties */ | ||
bool processText(const char *dev, const char *name, char *texts[], char *names[], int n); | ||
|
||
/** | ||
* @brief saveConfigItems save Filter Names in config file | ||
* @param fp pointer to config file | ||
* @return Always return true | ||
*/ | ||
bool saveConfigItems(FILE *fp); | ||
|
||
// Relay Toggle | ||
std::vector<INDI::PropertySwitch> RelaysSP; | ||
// Relay Labels | ||
INDI::PropertyText RelayLabelsTP {0}; | ||
|
||
DefaultDevice *m_defaultDevice { nullptr }; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters