Torc  0.1
torc1wirebus.cpp
Go to the documentation of this file.
1 /* Class Torc1WireBus
2 *
3 * This file is part of the Torc project.
4 *
5 * Copyright (C) Mark Kendall 2014-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 // Qt
24 #include <QDir>
25 
26 // Torc
27 #include "torclogging.h"
28 #include "torcadminthread.h"
29 #include "torcinputs.h"
30 #include "torc1wirebus.h"
31 #include "torc1wireds18b20.h"
32 
34 
70  m_inputs()
71 {
72 }
73 
74 void Torc1WireBus::Create(const QVariantMap &Details)
75 {
76  QWriteLocker locker(&m_handlerLock);
77 
78  // check for the correct directory
79  QDir dir(ONE_WIRE_DIRECTORY);
80  bool wire1found = dir.exists();
81 
82  QVariantMap::const_iterator i = Details.constBegin();
83  for ( ; i != Details.constEnd(); ++i)
84  {
85  // we look for 1Wire devices in <inputs>
86  if (i.key() != INPUTS_DIRECTORY)
87  continue;
88 
89  QVariantMap wire1 = i.value().toMap();
90  QVariantMap::iterator it = wire1.begin();
91  for ( ; it != wire1.end(); ++it)
92  {
93  // now we're looking for <wire1>
94  // N.B. XML doesn't allow element names to begin with numeric characters - hence wire1
95 
96  if (it.key() == ONE_WIRE_NAME)
97  {
98  // we have found a 1wire device config - make sure 1wire is available
99  if (!wire1found)
100  {
101  LOG(VB_GENERAL, LOG_ERR, QStringLiteral("1Wire device configured but cannot find 1Wire directory (%1)").arg(ONE_WIRE_DIRECTORY));
102  return;
103  }
104 
105  QVariantMap devices = it.value().toMap();
106  QVariantMap::iterator it2 = devices.begin();
107  for ( ; it2 != devices.end(); ++it2)
108  {
109  QString devicetype = it2.key();
110  QVariantMap details = it2.value().toMap();
111 
112  // a 1Wire device must have the <id> field
113  if (!details.contains(QStringLiteral("wire1serial")))
114  {
115  LOG(VB_GENERAL, LOG_ERR, QStringLiteral("Cannot create 1Wire device without unique 1Wire ID ('%1' '%2')")
116  .arg(devicetype, details.value(QStringLiteral("name")).toString()));
117  }
118  else
119  {
120  TorcInput* device = nullptr;
122  for ( ; factory; factory = factory->NextFactory())
123  {
124  device = factory->Create(devicetype, details);
125  if (device)
126  break;
127  }
128 
129  if (device)
130  {
131  QString deviceid = details.value(QStringLiteral("wire1serial")).toString();
132  LOG(VB_GENERAL, LOG_INFO, QStringLiteral("New 1Wire device: %1").arg(deviceid));
133  m_inputs.insert(deviceid, device);
134  }
135  else
136  {
137  LOG(VB_GENERAL, LOG_WARNING, QStringLiteral("Unable to find handler for 1Wire device type '%1'").arg(devicetype));
138  }
139  }
140 
141  }
142  }
143  }
144  }
145 }
146 
148 {
149  QWriteLocker locker(&m_handlerLock);
150 
151  // delete any extant inputs
152  QHash<QString,TorcInput*>::const_iterator it = m_inputs.constBegin();
153  for ( ; it != m_inputs.constEnd(); ++it)
154  {
155  TorcInputs::gInputs->RemoveInput(it.value());
156  it.value()->DownRef();
157  }
158  m_inputs.clear();
159 }
160 
162 
164  : nextTorc1WireDeviceFactory(gTorc1WireDeviceFactory)
165 {
167 }
168 
170 {
172 }
173 
175 {
177 }
178 
179 static const QString wire1InputTypes =
180 QStringLiteral("<xs:simpleType name='ds18b20SerialType'>\r\n"
181 " <xs:restriction base='xs:string'>\r\n"
182 " <xs:pattern value='28-[0-9a-fA-F]{12}'/>\r\n"
183 " </xs:restriction>\r\n"
184 "</xs:simpleType>\r\n"
185 "<xs:complexType name='ds18b20Type'>\r\n"
186 " <xs:all>\r\n"
187 " <xs:element name='name' type='deviceNameType'/>\r\n"
188 " <xs:element name='username' type='userNameType' minOccurs='0' maxOccurs='1'/>\r\n"
189 " <xs:element name='userdescription' type='userDescriptionType' minOccurs='0' maxOccurs='1'/>\r\n"
190 " <xs:element name='wire1serial' type='ds18b20SerialType'/>\r\n"
191 " </xs:all>\r\n"
192 "</xs:complexType>\r\n\r\n"
193 "<xs:complexType name='wire1Type'>\r\n"
194 " <xs:choice minOccurs='1' maxOccurs='unbounded'>\r\n"
195 " <xs:element name='ds18b20' type='ds18b20Type'/>\r\n"
196 " </xs:choice>\r\n"
197 "</xs:complexType>\r\n");
198 
199 static const QString wire1Inputs =
200 QStringLiteral(" <xs:element minOccurs='0' maxOccurs='1' name='wire1' type='wire1Type'/>\r\n");
201 
202 static const QString wire1Unique =
203 QStringLiteral("<!-- enforce unique 1Wire serial numbers -->\r\n"
204 "<xs:unique name='uniqueWire1Serial'>\r\n"
205 "<xs:selector xpath='.//wire1serial' />\r\n"
206 " <xs:field xpath='.' />\r\n"
207 "</xs:unique>\r\n");
208 
210 {
211  public:
212  void GetXSD(QMultiMap<QString,QString> &XSD) {
213  XSD.insert(XSD_INPUTTYPES, wire1InputTypes);
214  XSD.insert(XSD_INPUTS, wire1Inputs);
215  XSD.insert(XSD_UNIQUE, wire1Unique);
216  }
217 
#define XSD_UNIQUE
Definition: torccentral.h:64
A class to handle the one wire files system (OWFS) for 1Wire devices.
Definition: torc1wirebus.h:15
static const QString wire1InputTypes
static Torc1WireDeviceFactory * gTorc1WireDeviceFactory
Definition: torc1wirebus.h:40
void GetXSD(QMultiMap< QString, QString > &XSD)
#define ONE_WIRE_NAME
Definition: torc1wirebus.h:13
void Create(const QVariantMap &Details)
#define XSD_INPUTS
Definition: torccentral.h:55
static Torc1WireBus * gTorc1WireBus
Definition: torc1wirebus.h:20
static Torc1WireDeviceFactory * GetTorc1WireDeviceFactory(void)
Torc1WireDeviceFactory * NextFactory(void) const
static const QString wire1Inputs
double value
Definition: torcdevice.h:60
void Destroy(void)
virtual TorcInput * Create(const QString &DeviceType, const QVariantMap &Details)=0
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: torclogging.h:20
QReadWriteLock m_handlerLock
#define INPUTS_DIRECTORY
Definition: torcinput.h:12
#define XSD_INPUTTYPES
Definition: torccentral.h:54
Torc1WireDeviceFactory * nextTorc1WireDeviceFactory
Definition: torc1wirebus.h:41
#define ONE_WIRE_DIRECTORY
Definition: torc1wirebus.h:12
Torc1WireXSDFactory Torc1WireXSDFactory
static const QString wire1Unique