Instrument Neutral Distributed Interface INDI  2.0.2
weathermeta.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright(c) 2015 Jasem Mutlaq. All rights reserved.
3 
4  INDI Weather Underground (TM) Weather Driver
5 
6  This program is free software; you can redistribute it and/or modify it
7  under the terms of the GNU General Public License as published by the Free
8  Software Foundation; either version 2 of the License, or (at your option)
9  any later version.
10 
11  This program is distributed in the hope that it will be useful, but WITHOUT
12  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 
21  The full GNU General Public License is included in this distribution in the
22  file called LICENSE.
23 *******************************************************************************/
24 
25 #include "weathermeta.h"
26 
27 #include <cstring>
28 #include <memory>
29 
30 // We declare an auto pointer to WeatherMeta.
31 std::unique_ptr<WeatherMeta> weatherMeta(new WeatherMeta());
32 
34 {
35  setVersion(1, 0);
36 
37  updatePeriods[0] = updatePeriods[1] = updatePeriods[2] = updatePeriods[3] = -1;
38 }
39 
41 {
42  return (const char *)"Weather Meta";
43 }
44 
46 {
47  return true;
48 }
49 
51 {
52  return true;
53 }
54 
56 {
58 
59  // Active Devices
60  IUFillText(&ActiveDeviceT[0], "ACTIVE_WEATHER_1", "Station #1", nullptr);
61  IUFillText(&ActiveDeviceT[1], "ACTIVE_WEATHER_2", "Station #2", nullptr);
62  IUFillText(&ActiveDeviceT[2], "ACTIVE_WEATHER_3", "Station #3", nullptr);
63  IUFillText(&ActiveDeviceT[3], "ACTIVE_WEATHER_4", "Station #4", nullptr);
64  IUFillTextVector(&ActiveDeviceTP, ActiveDeviceT, 4, getDeviceName(), "ACTIVE_DEVICES", "Stations", OPTIONS_TAB,
65  IP_RW, 60, IPS_IDLE);
66 
67  // Station Status
68  IUFillLight(&StationL[0], "STATION_STATUS_1", "Station #1", IPS_IDLE);
69  IUFillLight(&StationL[1], "STATION_STATUS_2", "Station #2", IPS_IDLE);
70  IUFillLight(&StationL[2], "STATION_STATUS_3", "Station #3", IPS_IDLE);
71  IUFillLight(&StationL[3], "STATION_STATUS_4", "Station #4", IPS_IDLE);
72  IUFillLightVector(&StationLP, StationL, 4, getDeviceName(), "WEATHER_STATUS", "Status", MAIN_CONTROL_TAB, IPS_IDLE);
73 
74  // Update Period
75  IUFillNumber(&UpdatePeriodN[0], "PERIOD", "Period (secs)", "%4.2f", 0, 3600, 60, 60);
76  IUFillNumberVector(&UpdatePeriodNP, UpdatePeriodN, 1, getDeviceName(), "WEATHER_UPDATE", "Update", MAIN_CONTROL_TAB,
77  IP_RO, 60, IPS_IDLE);
78 
80 
82 
83  return true;
84 }
85 
86 void WeatherMeta::ISGetProperties(const char *dev)
87 {
89 
90  defineProperty(&ActiveDeviceTP);
91 
92  loadConfig(true, "ACTIVE_DEVICES");
93 }
94 
96 {
98 
99  if (isConnected())
100  {
101  // If Active devices are already defined, let's set the active devices as labels
102  for (int i = 0; i < 4; i++)
103  {
104  if (ActiveDeviceT[i].text != nullptr && ActiveDeviceT[i].text[0] != 0)
105  strncpy(StationL[i].label, ActiveDeviceT[i].text, MAXINDILABEL);
106  }
107 
108  defineProperty(&StationLP);
109  defineProperty(&UpdatePeriodNP);
110  }
111  else
112  {
113  deleteProperty(StationLP.name);
114  deleteProperty(UpdatePeriodNP.name);
115  }
116  return true;
117 }
118 
119 bool WeatherMeta::ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
120 {
121  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
122  {
123  if (strcmp(name, ActiveDeviceTP.name) == 0)
124  {
125  ActiveDeviceTP.s = IPS_OK;
126  IUUpdateText(&ActiveDeviceTP, texts, names, n);
127  // Update client display
128  IDSetText(&ActiveDeviceTP, nullptr);
129 
130  if (ActiveDeviceT[0].text != nullptr)
131  {
132  IDSnoopDevice(ActiveDeviceT[0].text, "WEATHER_STATUS");
133  IDSnoopDevice(ActiveDeviceT[0].text, "WEATHER_UPDATE");
134  }
135  if (ActiveDeviceT[1].text != nullptr)
136  {
137  IDSnoopDevice(ActiveDeviceT[1].text, "WEATHER_STATUS");
138  IDSnoopDevice(ActiveDeviceT[1].text, "WEATHER_UPDATE");
139  }
140  if (ActiveDeviceT[2].text != nullptr)
141  {
142  IDSnoopDevice(ActiveDeviceT[2].text, "WEATHER_STATUS");
143  IDSnoopDevice(ActiveDeviceT[2].text, "WEATHER_UPDATE");
144  }
145  if (ActiveDeviceT[3].text != nullptr)
146  {
147  IDSnoopDevice(ActiveDeviceT[3].text, "WEATHER_STATUS");
148  IDSnoopDevice(ActiveDeviceT[3].text, "WEATHER_UPDATE");
149  }
150 
151  return true;
152  }
153  }
154 
155  return INDI::DefaultDevice::ISNewText(dev, name, texts, names, n);
156 }
157 
159 {
161 
162  IUSaveConfigText(fp, &ActiveDeviceTP);
163  IUSaveConfigNumber(fp, &UpdatePeriodNP);
164 
165  return true;
166 }
167 
169 {
170  const char *propName = findXMLAttValu(root, "name");
171  const char *deviceName = findXMLAttValu(root, "device");
172 
173  if (isConnected())
174  {
175  if (strcmp(propName, "WEATHER_STATUS") == 0)
176  {
177  for (int i = 0; i < 4; i++)
178  {
179  if (ActiveDeviceT[i].text != nullptr && strcmp(ActiveDeviceT[i].text, deviceName) == 0)
180  {
181  IPState stationState;
182 
183  if (crackIPState(findXMLAttValu(root, "state"), &stationState) < 0)
184  break;
185 
186  StationL[i].s = stationState;
187 
188  updateOverallState();
189 
190  break;
191  }
192  }
193 
194  return true;
195  }
196 
197  if (strcmp(propName, "WEATHER_UPDATE") == 0)
198  {
199  XMLEle *ep = nextXMLEle(root, 1);
200 
201  for (int i = 0; i < 4; i++)
202  {
203  if (ActiveDeviceT[i].text != nullptr && strcmp(ActiveDeviceT[i].text, deviceName) == 0)
204  {
205  updatePeriods[i] = atof(pcdataXMLEle(ep));
206 
207  updateUpdatePeriod();
208  break;
209  }
210  }
211  }
212  }
213 
215 }
216 
217 void WeatherMeta::updateOverallState()
218 {
219  StationLP.s = IPS_IDLE;
220 
221  for (int i = 0; i < 4; i++)
222  {
223  if (StationL[i].s > StationLP.s)
224  StationLP.s = StationL[i].s;
225  }
226 
227  IDSetLight(&StationLP, nullptr);
228 }
229 
230 void WeatherMeta::updateUpdatePeriod()
231 {
232  double minPeriod = UpdatePeriodN[0].max;
233 
234  for (int i = 0; i < 4; i++)
235  {
236  if (updatePeriods[i] > 0 && updatePeriods[i] < minPeriod)
237  minPeriod = updatePeriods[i];
238  }
239 
240  if (minPeriod != UpdatePeriodN[0].max)
241  {
242  UpdatePeriodN[0].value = minPeriod;
243  IDSetNumber(&UpdatePeriodNP, nullptr);
244  }
245 }
bool isConnected() const
Definition: basedevice.cpp:520
const char * getDeviceName() const
Definition: basedevice.cpp:821
virtual bool updateProperties()
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual void ISGetProperties(const char *dev)
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
virtual bool ISSnoopDevice(XMLEle *root)
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
virtual bool loadConfig(bool silent=false, const char *property=nullptr)
Load the last saved configuration file.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
virtual bool saveConfigItems(FILE *fp)
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual bool initProperties()
Initilize properties initial state and value. The child class must implement this function.
void setDriverInterface(uint16_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
void addDebugControl()
Add Debug control to the driver.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process the client newSwitch command.
const char * getDefaultName() override
Definition: weathermeta.cpp:40
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
Definition: weathermeta.cpp:55
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
virtual void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
Definition: weathermeta.cpp:86
bool Disconnect() override
Disconnect from device.
Definition: weathermeta.cpp:50
bool Connect() override
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
Definition: weathermeta.cpp:45
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition: weathermeta.cpp:95
virtual bool ISSnoopDevice(XMLEle *root) override
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
const char * OPTIONS_TAB
OPTIONS_TAB Where all the driver's options are located. Those may include auxiliary controls,...
double max(void)
@ IP_RW
Definition: indiapi.h:186
@ IP_RO
Definition: indiapi.h:184
IPState
Property state.
Definition: indiapi.h:160
@ IPS_IDLE
Definition: indiapi.h:161
@ IPS_OK
Definition: indiapi.h:162
#define MAXINDILABEL
Definition: indiapi.h:192
void IUFillLight(ILight *lp, const char *name, const char *label, IPState s)
Assign attributes for a light property. The light's auxiliary elements will be set to NULL.
Definition: indidevapi.c:169
void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a number vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidevapi.c:272
void IUFillLightVector(ILightVectorProperty *lvp, ILight *lp, int nlp, const char *dev, const char *name, const char *label, const char *group, IPState s)
Assign attributes for a light vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidevapi.c:255
void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a text vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidevapi.c:291
void IUSaveConfigNumber(FILE *fp, const INumberVectorProperty *nvp)
Add a number vector property value to the configuration file.
Definition: indidevapi.c:15
void IUFillText(IText *tp, const char *name, const char *label, const char *initialText)
Assign attributes for a text property. The text's auxiliary elements will be set to NULL.
Definition: indidevapi.c:198
void IUFillNumber(INumber *np, const char *name, const char *label, const char *format, double min, double max, double step, double value)
Assign attributes for a number property. The number's auxiliary elements will be set to NULL.
Definition: indidevapi.c:180
void IUSaveConfigText(FILE *fp, const ITextVectorProperty *tvp)
Add a text vector property value to the configuration file.
Definition: indidevapi.c:20
int crackIPState(const char *str, IPState *ip)
Extract property state (Idle, OK, Busy, Alert) from the supplied string.
Definition: indidevapi.c:576
void IDSetLight(const ILightVectorProperty *lvp, const char *fmt,...)
Definition: indidriver.c:1251
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
Definition: indidriver.c:1211
int IUUpdateText(ITextVectorProperty *tvp, char *texts[], char *names[], int n)
Update all text members in a text vector property.
Definition: indidriver.c:1396
void IDSnoopDevice(const char *snooped_device, const char *snooped_property)
Function a Driver calls to snoop on another Device. Snooped messages will then arrive via ISSnoopDevi...
Definition: indidriver.c:143
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
Definition: indidriver.c:1191
const char * findXMLAttValu(XMLEle *ep, const char *name)
Find an XML element's attribute value.
Definition: lilxml.cpp:644
char * pcdataXMLEle(XMLEle *ep)
Return the pcdata of an XML element.
Definition: lilxml.cpp:606
XMLEle * nextXMLEle(XMLEle *ep, int init)
Iterate an XML element for a list of nesetd XML elements.
Definition: lilxml.cpp:555
char name[MAXINDINAME]
Definition: indiapi.h:421
char name[MAXINDINAME]
Definition: indiapi.h:323
char name[MAXINDINAME]
Definition: indiapi.h:250
std::unique_ptr< WeatherMeta > weatherMeta(new WeatherMeta())