Instrument Neutral Distributed Interface INDI 2.2.5
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.
31std::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 ActiveDeviceTP[ACTIVE_WEATHER_1].fill("ACTIVE_WEATHER_1", "Station #1", nullptr);
61 ActiveDeviceTP[ACTIVE_WEATHER_2].fill( "ACTIVE_WEATHER_2", "Station #2", nullptr);
62 ActiveDeviceTP[ACTIVE_WEATHER_3].fill( "ACTIVE_WEATHER_3", "Station #3", nullptr);
63 ActiveDeviceTP[ACTIVE_WEATHER_4].fill("ACTIVE_WEATHER_4", "Station #4", nullptr);
64 ActiveDeviceTP.fill(getDeviceName(), "ACTIVE_DEVICES", "Stations", OPTIONS_TAB,
65 IP_RW, 60, IPS_IDLE);
66
67 // Station Status
68 StationLP[STATION_STATUS_1].fill("STATION_STATUS_1", "Station #1", IPS_IDLE);
69 StationLP[STATION_STATUS_2].fill("STATION_STATUS_2", "Station #2", IPS_IDLE);
70 StationLP[STATION_STATUS_3].fill("STATION_STATUS_3", "Station #3", IPS_IDLE);
71 StationLP[STATION_STATUS_4].fill("STATION_STATUS_4", "Station #4", IPS_IDLE);
72 StationLP.fill(getDeviceName(), "WEATHER_STATUS", "Status", MAIN_CONTROL_TAB, IPS_IDLE);
73
74 // Update Period
75 UpdatePeriodNP[0].fill("PERIOD", "Period (secs)", "%4.2f", 0, 3600, 60, 60);
76 UpdatePeriodNP.fill(getDeviceName(), "WEATHER_UPDATE", "Update", MAIN_CONTROL_TAB,
77 IP_RO, 60, IPS_IDLE);
78
80
82
83 return true;
84}
85
86void 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 (ActiveDeviceTP[i].getText() != nullptr && ActiveDeviceTP[i].getText()[0] != 0)
105 StationLP[i].setLabel(ActiveDeviceTP[i].getText());
106 }
107
108 defineProperty(StationLP);
109 defineProperty(UpdatePeriodNP);
110 }
111 else
112 {
113 deleteProperty(StationLP);
114 deleteProperty(UpdatePeriodNP);
115 }
116 return true;
117}
118
119bool 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 (ActiveDeviceTP.isNameMatch(name))
124 {
125 ActiveDeviceTP.setState(IPS_OK);
126 ActiveDeviceTP.update(texts, names, n);
127 // Update client display
128 ActiveDeviceTP.apply();
129
130 if (ActiveDeviceTP[ACTIVE_WEATHER_1].getText() != nullptr)
131 {
132 IDSnoopDevice(ActiveDeviceTP[ACTIVE_WEATHER_1].getText(), "WEATHER_STATUS");
133 IDSnoopDevice(ActiveDeviceTP[ACTIVE_WEATHER_1].getText(), "WEATHER_UPDATE");
134 }
135 if (ActiveDeviceTP[ACTIVE_WEATHER_1].text != nullptr)
136 {
137 IDSnoopDevice(ActiveDeviceTP[ACTIVE_WEATHER_1].getText(), "WEATHER_STATUS");
138 IDSnoopDevice(ActiveDeviceTP[ACTIVE_WEATHER_1].getText(), "WEATHER_UPDATE");
139 }
140 if (ActiveDeviceTP[ACTIVE_WEATHER_3].getText() != nullptr)
141 {
142 IDSnoopDevice(ActiveDeviceTP[ACTIVE_WEATHER_3].getText(), "WEATHER_STATUS");
143 IDSnoopDevice(ActiveDeviceTP[ACTIVE_WEATHER_3].getText(), "WEATHER_UPDATE");
144 }
145 if (ActiveDeviceTP[ACTIVE_WEATHER_4].getText() != nullptr)
146 {
147 IDSnoopDevice(ActiveDeviceTP[ACTIVE_WEATHER_4].getText(), "WEATHER_STATUS");
148 IDSnoopDevice(ActiveDeviceTP[ACTIVE_WEATHER_4].getText(), "WEATHER_UPDATE");
149 }
150
151 saveConfig(ActiveDeviceTP);
152
153 return true;
154 }
155 }
156
157 return INDI::DefaultDevice::ISNewText(dev, name, texts, names, n);
158}
159
161{
163
164 ActiveDeviceTP.save(fp);
165 UpdatePeriodNP.save(fp);
166
167 return true;
168}
169
171{
172 const char *propName = findXMLAttValu(root, "name");
173 const char *deviceName = findXMLAttValu(root, "device");
174
175 if (isConnected())
176 {
177 if (strcmp(propName, "WEATHER_STATUS") == 0)
178 {
179 for (int i = 0; i < 4; i++)
180 {
181 if (ActiveDeviceTP[i].getText() != nullptr && strcmp(ActiveDeviceTP[i].getText(), deviceName) == 0)
182 {
183 IPState stationState;
184
185 if (crackIPState(findXMLAttValu(root, "state"), &stationState) < 0)
186 break;
187
188 StationLP[i].setState(stationState);
189
190 updateOverallState();
191
192 break;
193 }
194 }
195
196 return true;
197 }
198
199 if (strcmp(propName, "WEATHER_UPDATE") == 0)
200 {
201 XMLEle *ep = nextXMLEle(root, 1);
202
203 for (int i = 0; i < 4; i++)
204 {
205 if (ActiveDeviceTP[i].getText() != nullptr && strcmp(ActiveDeviceTP[i].getText(), deviceName) == 0)
206 {
207 updatePeriods[i] = atof(pcdataXMLEle(ep));
208
209 updateUpdatePeriod();
210 break;
211 }
212 }
213 }
214 }
215
217}
218
219void WeatherMeta::updateOverallState()
220{
221 StationLP.setState(IPS_IDLE);
222
223 for (int i = 0; i < 4; i++)
224 {
225 if (StationLP[i].getState() > StationLP.getState())
226 StationLP.setState(StationLP[i].getState());
227 }
228
229 StationLP.apply();
230}
231
232void WeatherMeta::updateUpdatePeriod()
233{
234 double minPeriod = UpdatePeriodNP[0].getMin();
235
236 for (int i = 0; i < 4; i++)
237 {
238 if (updatePeriods[i] > 0 && updatePeriods[i] < minPeriod)
239 minPeriod = updatePeriods[i];
240 }
241
242 if (minPeriod != UpdatePeriodNP[0].getMax())
243 {
244 UpdatePeriodNP[0].setValue(minPeriod);
245 UpdatePeriodNP.apply();
246 }
247}
bool isConnected() const
const char * getDeviceName() const
INDI::PropertyText getText(const char *name) const
virtual bool updateProperties()
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool saveConfig(bool silent=false, const char *property=nullptr)
Save the current properties in a configuration file.
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 setDriverInterface(uint32_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
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()
Initialize properties initial state and value. The child class must implement this function.
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.
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
void save(FILE *f) const
save Save property to configuration file.
void setLabel(const char *label)
bool isNameMatch(const char *otherName) const
void fill(const char *device, const char *name, const char *label, const char *group, IPState state)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
bool update(const char *const texts[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
const char * getDefaultName() override
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
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...
bool Disconnect() override
Disconnect from device.
bool Connect() override
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
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,...
@ IP_RW
Definition indiapi.h:184
@ IP_RO
Definition indiapi.h:182
IPState
Property state.
Definition indiapi.h:158
@ IPS_IDLE
Definition indiapi.h:159
@ IPS_OK
Definition indiapi.h:160
int crackIPState(const char *str, IPState *ip)
Extract property state (Idle, OK, Busy, Alert) from the supplied string.
Definition indidevapi.c:793
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
const char * findXMLAttValu(XMLEle *ep, const char *name)
Find an XML element's attribute value.
Definition lilxml.cpp:644
XMLEle * nextXMLEle(XMLEle *ep, int init)
Iterate an XML element for a list of nesetd XML elements.
Definition lilxml.cpp:555
char * pcdataXMLEle(XMLEle *ep)
Return the pcdata of an XML element.
Definition lilxml.cpp:606
std::unique_ptr< WeatherMeta > weatherMeta(new WeatherMeta())