Torc  0.1
torcoutputs.cpp
Go to the documentation of this file.
1 /* Class TorcOutput
2 *
3 * This file is part of the Torc project.
4 *
5 * Copyright (C) Mark Kendall 2015-18
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 * USA.
21 */
22 
23 // Torc
24 #include "torclogging.h"
25 #include "torccoreutils.h"
26 #include "torccentral.h"
27 #include "torcnetworkpwmoutput.h"
30 #include "torcnetworkphoutput.h"
32 #include "torcoutputs.h"
33 
34 #define BLACKLIST QStringLiteral("")
35 
36 TorcOutputs* TorcOutputs::gOutputs = new TorcOutputs();
37 
76  : QObject(),
77  TorcHTTPService(this, OUTPUTS_DIRECTORY, QStringLiteral("outputs"), TorcOutputs::staticMetaObject, BLACKLIST),
79  outputList(),
80  outputTypes(),
81  m_createdOutputs()
82 {
83 }
84 
86 {
87  return tr("Outputs");
88 }
89 
90 void TorcOutputs::Graph(QByteArray* Data)
91 {
92  if (!Data)
93  return;
94 
95  QString start =
96  QStringLiteral(" subgraph cluster_2 {\r\n"
97  " label = \"%1\";\r\n"
98  " style=filled;\r\n"
99  " fillcolor=\"grey95\";\r\n").arg(tr("Outputs"));
100  Data->append(start);
101  foreach(TorcOutput* output, outputList)
102  output->Graph(Data);
103  Data->append(" }\r\n\r\n");
104 }
105 
106 void TorcOutputs::SubscriberDeleted(QObject *Subscriber)
107 {
109 }
110 
113 QVariantMap TorcOutputs::GetOutputList(void)
114 {
115  QVariantMap result;
116  QReadLocker locker(&m_httpServiceLock);
117 
118  // iterate over our list for each output type
119  for (int type = TorcOutput::Unknown; type < TorcOutput::MaxType; type++)
120  {
121  QStringList outputsfortype;
122  foreach (TorcOutput *output, outputList)
123  if (output->GetType() == type)
124  outputsfortype.append(output->GetUniqueId());
125 
126  if (!outputsfortype.isEmpty())
127  result.insert(TorcCoreUtils::EnumToLowerString<TorcOutput::Type>(static_cast<TorcOutput::Type>(type)), outputsfortype);
128  }
129  return result;
130 }
131 
133 {
134  return TorcCoreUtils::EnumList<TorcOutput::Type>();
135 }
136 
138 {
139  QWriteLocker locker(&m_httpServiceLock);
140  if (!Output)
141  return;
142 
143  if (Output->GetUniqueId().isEmpty())
144  return;
145 
146  if (outputList.contains(Output))
147  {
148  LOG(VB_GENERAL, LOG_WARNING, QStringLiteral("Already have output named %1 - ignoring").arg(Output->GetUniqueId()));
149  return;
150  }
151 
152  Output->UpRef();
153  outputList.append(Output);
154  LOG(VB_GENERAL, LOG_INFO, QStringLiteral("Registered output %1").arg(Output->GetUniqueId()));
155  emit OutputsChanged();
156 }
157 
159 {
160  QWriteLocker locker(&m_httpServiceLock);
161  if (!Output)
162  return;
163 
164  if (Output->GetUniqueId().isEmpty())
165  return;
166 
167  if (!outputList.contains(Output))
168  {
169  LOG(VB_GENERAL, LOG_WARNING, QStringLiteral("Output %1 not recognised - cannot remove").arg(Output->GetUniqueId()));
170  return;
171  }
172 
173  LOG(VB_GENERAL, LOG_INFO, QStringLiteral("Output %1 deregistered").arg(Output->GetUniqueId()));
174  Output->DownRef();
175  outputList.removeOne(Output);
176  emit OutputsChanged();
177 }
178 
179 void TorcOutputs::Create(const QVariantMap &Details)
180 {
181  QWriteLocker locker(&m_handlerLock);
182 
183  QVariantMap::const_iterator i = Details.constBegin();
184  for ( ; i != Details.constEnd(); ++i)
185  {
186  // network devices can be <inputs> or <outputs>
187  if (i.key() != OUTPUTS_DIRECTORY)
188  continue;
189 
190  QVariantMap devices = i.value().toMap();
191  QVariantMap::const_iterator j = devices.constBegin();
192  for ( ; j != devices.constEnd(); ++j)
193  {
194  // look for <network> or <constant>
195  QString group = j.key();
196  bool network = group == NETWORK_DEVICE_STRING;
197  bool constant = group == CONSTANT_DEVICE_STRING;
198 
199  if (!network && !constant)
200  continue;
201 
202  QVariantMap details = j.value().toMap();
203  QVariantMap::const_iterator it = details.constBegin();
204  for ( ; it != details.constEnd(); ++it)
205  {
206  for (int type = TorcOutput::Unknown; type != TorcOutput::MaxType; type++)
207  {
208  if (it.key() == TorcCoreUtils::EnumToLowerString<TorcOutput::Type>(static_cast<TorcOutput::Type>(type)))
209  {
210  QVariantMap input = it.value().toMap();
211  QString defaultvalue = network ? input.value(QStringLiteral("default")).toString() : input.value(QStringLiteral("value")).toString();
212  QString uniqueid = input.value(QStringLiteral("name"), QStringLiteral("Error")).toString();
213 
214  bool ok = false;
215  double defaultdouble = defaultvalue.toDouble(&ok);
216  if (!ok)
217  defaultdouble = 0.0;
218 
219  TorcOutput* newoutput = nullptr;
220  switch (type)
221  {
222  case TorcOutput::PWM:
223  newoutput = network ? new TorcNetworkPWMOutput(defaultdouble, input) : new TorcPWMOutput(defaultdouble, DEVICE_CONSTANT + TorcCoreUtils::EnumToLowerString<TorcOutput::Type>(TorcOutput::PWM), input);
224  break;
225  case TorcOutput::Switch:
226  newoutput = network ? new TorcNetworkSwitchOutput(defaultdouble, input) : new TorcSwitchOutput(defaultdouble, DEVICE_CONSTANT + TorcCoreUtils::EnumToLowerString<TorcOutput::Type>(TorcOutput::Switch), input);
227  break;
229  newoutput = network ? new TorcNetworkTemperatureOutput(defaultdouble, input) : new TorcTemperatureOutput(defaultdouble, DEVICE_CONSTANT + TorcCoreUtils::EnumToLowerString<TorcOutput::Type>(TorcOutput::Temperature), input);
230  break;
231  case TorcOutput::pH:
232  newoutput = network ? new TorcNetworkpHOutput(defaultdouble, input) : new TorcpHOutput(defaultdouble, DEVICE_CONSTANT + TorcCoreUtils::EnumToLowerString<TorcOutput::Type>(TorcOutput::pH), input);
233  break;
234  /*
235  case TorcOutput::Integer:
236  newoutput = network ? new TorcNetworkIntegerOutput(defaultdouble, input) : new TorcIntegerOutput(defaultdouble, DEVICE_CONSTANT + TorcCoreUtils::EnumToLowerString<TorcOutput::Type>(TorcOutput::Integer), input);
237  break;
238  */
239  case TorcOutput::Button:
240  if (constant)
241  LOG(VB_GENERAL, LOG_ERR, QStringLiteral("Cannot create constant button input"));
242  else
243  newoutput = new TorcNetworkButtonOutput(defaultdouble, input);
244  default: break;
245  }
246 
247  if (newoutput)
248  m_createdOutputs.insert(uniqueid, newoutput);
249  }
250  }
251  }
252  }
253  }
254 }
255 
257 {
258  QWriteLocker locker(&m_handlerLock);
259  QMap<QString,TorcOutput*>::const_iterator it2 = m_createdOutputs.constBegin();
260  for ( ; it2 != m_createdOutputs.constEnd(); ++it2)
261  {
262  it2.value()->DownRef();
263  TorcOutputs::gOutputs->RemoveOutput(it2.value());
264  }
265  m_createdOutputs.clear();
266 }
virtual void Graph(QByteArray *Data)
Definition: torcoutput.cpp:92
virtual TorcOutput::Type GetType(void)=0
#define BLACKLIST
Definition: torcoutputs.cpp:34
A network output that mimics the behaviour of a mechanical push button.
void Graph(QByteArray *Data)
Definition: torcoutputs.cpp:90
#define NETWORK_DEVICE_STRING
Definition: torcdevice.h:14
virtual bool DownRef(void)
#define DEVICE_CONSTANT
Definition: torcdevice.h:17
QVariantMap GetOutputList(void)
Return a map of known outputs.
#define OUTPUTS_DIRECTORY
Definition: torcoutput.h:13
QStringList GetOutputTypes(void)
void HandleSubscriberDeleted(QObject *Subscriber)
QReadWriteLock m_httpServiceLock
QString GetUIName(void) override
Definition: torcoutputs.cpp:85
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: torclogging.h:20
void OutputsChanged(void)
void SubscriberDeleted(QObject *Subscriber)
QReadWriteLock m_handlerLock
QVariantMap outputList
Definition: torcoutputs.h:18
void Destroy(void) override
void RemoveOutput(TorcOutput *Output)
void Create(const QVariantMap &Details) override
#define CONSTANT_DEVICE_STRING
Definition: torcdevice.h:15
TorcOutputs()
TorcOutputs contains the master record of known outputs.
Definition: torcoutputs.cpp:75
void AddOutput(TorcOutput *Output)
QString GetUniqueId(void)
Definition: torcdevice.cpp:162