Instrument Neutral Distributed Interface INDI 2.2.5
cheapodc.h
Go to the documentation of this file.
1/*
2 CheapoDC - Dew Controller
3 https://github.com/hcomet/CheapoDC
4
5 Copyright (C) 2024 Stephen Hillier
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library 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 GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
21*/
22
23#pragma once
24
25#include <defaultdevice.h>
26#include "indipropertytext.h"
27#include <indipowerinterface.h>
28
29#include <time.h> // for nsleep()
30#include <errno.h> // for nsleep()
31
32/*
33 Version Change Information
34 V1.0
35 - Initial release supports CheapoDC firmware 1.X features
36 V1.1
37 - release to add support for CheapoDC firmware 2.x features
38 - bug fix for Longitude range checking
39 - adds support for Weather Device snoop for local temperature/humidity instead of using CheapoDC weather query
40 - move Latitude/Longitude settings to more common Site Management Tab with Location settings
41 - Location Snoop enabled by default for Telescope Simulator
42 - move to ActiveDevicesTP model for setting snoop devices
43 V1.2
44 - Add support for addtional Controller Pins supported in CheapoDC firmware 2.2.0.
45 - Fix GET command processing to not throw a JSON error when an error response is received from device
46 V2.0
47 - Major refactor to move to INDI Power Interface
48 - Support for new CheapoDC firmware 2.3.0 internal Humidity sensor capability
49*/
50#define CHEAPODC_VERSION_MAJOR 2
51#define CHEAPODC_VERSION_MINOR 0
52
53// CheapoDC Commands used
54#define CDC_CMD_ATPQ "ATPQ" // ambient temperature - float %3.2f
55#define CDC_CMD_HU "HU" // humidity - float %3.2f
56#define CDC_CMD_DP "DP" // Dew point - float %3.2f
57#define CDC_CMD_SP "SP" // set point - float %3.2f
58#define CDC_CMD_TPO "TPO" // Track Point offset - float %2.2f (-5.0 to 5.0)
59#define CDC_CMD_TKR "TKR" // Tracking range - float %2.2f (4.0 to 10.0)
60#define CDC_CMD_DCO "DCO" // Dew Controller Output- int (0 to 100)
61#define CDC_CMD_WS "WS" // Weather source - string
62#define CDC_CMD_QN "QN" // Query Weather Now (Set only command)
63#define CDC_CMD_FW "FW" // firmware version - string
64#define CDC_CMD_DCM "DCM" // dew controller mode
65#define CDC_CMD_DCTM "DCTM" // dew controller temperature mode
66#define CDC_CMD_SPM "SPM" // dew controller set point mode
67#define CDC_CMD_WQE "WQE" // Weather query every
68#define CDC_CMD_UOE "UOE" // update outputs every
69#define CDC_CMD_WAPI "WAPI" // Weather API URL
70#define CDC_CMD_WKEY "WKEY" // Weather API Key
71#define CDC_CMD_LAT "LAT" // Location latitude
72#define CDC_CMD_LON "LON" // Location longitude
73#define CDC_CMD_CDT "CDT" // Location current date time
74#define CDC_CMD_TMZ "TMZ" // Location time zone offset in seconds
75#define CDC_CMD_DST "DST" // DST offset
76#define CDC_CMD_OMIN "OMIN" // DC Min output
77#define CDC_CMD_OMAX "OMAX" // DC Max output
78#define CDC_CMD_ATPX "ATPX" // Local Temperature input by external app
79#define CDC_CMD_CTP "CTP" // Current Track Point Temperature
80#define CDC_CMD_WUL "WUL" // Get Weather Query Station name
81#define CDC_CMD_LWUD "LWUD" // date of last weather update (in Weather Staion time zone)
82#define CDC_CMD_LWUT "LWUT" // time of last weather update (in Weather Staion time zone)
83#define CDC_CMD_WQEN "WQEN" // Weather Query Enabled (false=0, true=1)
84// the following commands are stubs for the addtional controller output pins 2, 3, 4, 5. Inserting the
85// pin number in the stub command string will form the correct CheapoDC command string.
86#define CDC_CMD_CPM "CPM%d" // Controller Pin Mode for pin x (0=Disabled, 1=Controller, 2=PWM, 3=Boolean)
87#define CDC_CMD_CPO "CPO%d" // Controller Pin Output for pin x (0 to 100)
88#define CDC_CMD_SDAP "SDAP" // Internal Humidity sensor SDA Pin
89
90#define CDC_GET_COMMAND "{\"GET\":\"%s\"}"
91#define CDC_SET_COMMAND "{\"SET\":{\"%s\":\"%s\"}}"
92#define CDC_RESPONSE_LENGTH 512
93#define CDC_COMMAND_LENGTH 512
94#define CDC_SET_VALUE_LENGTH 256
95#define CDC_INT_VALUE "%d"
96#define CDC_FLOAT_VALUE "%3.2f"
97#define CDC_TEXT_VALUE "%s"
98#define CDC_DEFAULT_POLLING_PERIOD 30000 // in msec, 30 seconds is often enough for Dew Control
99#define CDC_DEFAULT_HOST "cheapodc.local" // default host for connection tab
100#define CDC_DEFAULT_PORT 58000 // default TCP port for connection tab
101#define CDC_MIN_ADDITIONAL_OUTPUT 2 // Addtional outputs start at 2
102#define CDC_TOTAL_ADDITIONAL_OUTPUTS 4 // 4 addtional outputs - 2, 3, 4 and 5
103
104
105// Snoop Device information
106#define CDC_SNOOP_LOCATION_PROPERTY "GEOGRAPHIC_COORD"
107#define CDC_SNOOP_LOCATION_LATITUDE "LAT"
108#define CDC_SNOOP_LOCATION_LONGITUDE "LONG"
109#define CDC_SNOOP_TIME_PROPERTY "TIME_UTC"
110#define CDC_SNOOP_TIME_OFFSET "OFFSET"
111#define CDC_SNOOP_FOCUSER_PROPERTY "FOCUS_TEMPERATURE"
112#define CDC_SNOOP_FOCUSER_TEMPERATURE "TEMPERATURE"
113#define CDC_SNOOP_WEATHER_PROPERTY "WEATHER_PARAMETERS"
114#define CDC_SNOOP_WEATHER_TEMPERATURE "WEATHER_TEMPERATURE"
115#define CDC_SNOOP_WEATHER_HUMIDITY "WEATHER_HUMIDITY"
116
117/******************************************************************************/
118
120{
121 public:
122 CheapoDC();
123 virtual ~CheapoDC() = default;
124
125 virtual const char *getDefaultName() override;
126 virtual bool initProperties() override;
127 virtual bool updateProperties() override;
128 virtual bool saveConfigItems(FILE *fp) override;
129 virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override;
130 virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override;
131 virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override;
132 virtual bool ISSnoopDevice(XMLEle *root) override;
133 virtual void TimerHit() override;
134
135 protected:
136 virtual bool SetPowerPort(size_t port, bool enabled) override;
137 virtual bool SetDewPort(size_t port, bool enabled, double dutyCycle) override;
138 virtual bool SetVariablePort(size_t port, bool enabled, double voltage) override;
139 virtual bool SetLEDEnabled(bool enabled) override;
140 virtual bool SetAutoDewEnabled(size_t port, bool enabled) override;
141 virtual bool CyclePower() override;
142 virtual bool SetUSBPort(size_t port, bool enabled) override;
143
148 typedef enum
149 {
152 CONNECTION_TCP = 1 << 2
154
155 private:
156 enum controllerMode
157 {
158 AUTOMATIC = 0,
159 MANUAL,
160 OFF,
161 };
162
163 enum temperatureMode
164 {
165 WEATHER_QUERY = 0,
166 EXTERNAL_INPUT
167 };
168
169 enum setPointMode
170 {
171 DEWPOINT = 0,
172 TEMPERATURE,
173 MIDPOINT
174 };
175
176 enum weatherSource
177 {
178 OPENMETEO = 0,
179 OPENWEATHER,
180 EXTERNALSOURCE,
181 INTERNALSOURCE // Supported in CheapoDC firmware 2.3.0 and later
182 };
183
184 enum CheapoDCLocation
185 {
186 LOCATION_LATITUDE = 0,
187 LOCATION_LONGITUDE
188 };
189
190 enum deviceTime
191 {
192 LOCAL_TIME = 0,
193 UTC_OFFSET
194 };
195
196 enum activeDevice
197 {
198 ACTIVE_TELESCOPE = 0,
199 ACTIVE_FOCUSER,
200 ACTIVE_WEATHER
201 };
202
203 enum controllerPinModes
204 {
205 CONTROLLER_PIN_MODE_DISABLED = 0,
206 CONTROLLER_PIN_MODE_CONTROLLER,
207 CONTROLLER_PIN_MODE_PWM,
208 CONTROLLER_PIN_MODE_BOOLEAN,
209 MAX_PIN_MODES
210 };
211
212 const char* pinModeText[MAX_PIN_MODES] = {"Disabled", "Controller", "PWM", "Boolean"};
213 const char* channelLabels[MAX_PIN_MODES] = {"Output %d (Disabled)", "Output %d (Controller)",
214 "Output %d (PWM)", "Output %d (On/Off)"};
215 int powerChannelToOutput[CDC_TOTAL_ADDITIONAL_OUTPUTS+CDC_MIN_ADDITIONAL_OUTPUT] = { -1, -1, -1, -1, -1, -1 };
216 int dewChannelToOutput[CDC_TOTAL_ADDITIONAL_OUTPUTS+CDC_MIN_ADDITIONAL_OUTPUT] = { -1, -1, -1, -1, -1, -1 };
217 int outputToChannel[CDC_TOTAL_ADDITIONAL_OUTPUTS] = { -1, -1, -1, -1 };
218 int lastControllerPinMode[CDC_TOTAL_ADDITIONAL_OUTPUTS] = { CONTROLLER_PIN_MODE_DISABLED, CONTROLLER_PIN_MODE_DISABLED,
219 CONTROLLER_PIN_MODE_DISABLED, CONTROLLER_PIN_MODE_DISABLED };
220
221 bool fwVOneDetected = false;
222 bool internalHumiditySensorSupported = false;
223 bool additionalOutputsSupported = false;
224 int fwMajorVersion = 0;
225 int fwMinorVersion = 0;
226 int fwPatchVersion = 0;
227 int timerIndex = -1;
228 unsigned int previousControllerMode = MANUAL;
229 unsigned int prevMinOutput = 0;
230 unsigned int prevMaxOutput = 100;
231 unsigned int previousTemperatureMode = WEATHER_QUERY;
232 char activeTelescopeDevice[MAXINDINAME] = {"Telescope Simulator"};
233 char activeFocuserDevice[MAXINDINAME] = {"Focuser Simulator"};
234 char activeWeatherDevice[MAXINDINAME] = {"Weather Simulator"};
235 bool usingExternalWeatherSource = false;
236 bool previuoslyUsingExternalWeatherSource = usingExternalWeatherSource;
237
238 int msleep(long duration);
239 bool sendCommand(const char *cmd, char *response);
240 bool sendGetCommand(const char *cmd, char *resp);
241 bool sendSetCommand(const char *cmd, char *value);
242 bool Handshake();
243 bool Ack();
244 bool readSettings();
245 void refreshSettings(bool delayRefresh = false);
246 void getWeatherSource();
247 bool setWeatherSource(int value);
248 bool setControllerMode(int value);
249 bool setTemperatureMode(int value);
250 bool setSetPointMode(int value);
251 bool setSetPoint(float value);
252 bool setTrackPointOffset(float value);
253 bool setTrackingRange(float value);
254 bool setOutput(int value);
255 bool setMinimumOutput(int value);
256 bool setMaximumOutput(int value);
257 bool setUpdateOutputEvery(int value);
258 bool setWeatherQueryEvery(int value);
259 bool setWeatherQueryAPIKey(const char *key);
260 bool setWeatherQueryEnabled(bool enabled);
261 bool setUTCOffset(int offset);
262 bool setLatitude(float value);
263 bool setLongitude(float value);
264 bool setLocation(float latitude, float longitude);
265 bool setExternalTemperature(float value);
266 bool setWeatherTemperature(float value);
267 bool setWeatherHumidity(float value);
268 bool setSnoopLocationDevice(const char *device, const char *property, const char *latAttribute, const char *lonAttribute);
269 bool setSnoopTemperatureDevice(const char *device, const char *property, const char *attribute);
270 bool setSnoopWeatherDevice(const char *device, const char *property, const char *temperatureAttribute,
271 const char *humidityAttribute);
272 void setActiveDevice(const char *telescopeDevice, const char *focuserDevice, const char *weatherDevice);
273 bool setAdditionalOutput( int outputPin, int output );
274 bool checkOutputConfiguration();
275
276 // Connection::Serial *serialConnection { nullptr };
277 Connection::TCP *tcpConnection{nullptr};
278
279 int PortFD{-1};
280
281 uint8_t cdcConnection{CONNECTION_TCP};
282
283 // CheapoDC Timeouts
284 static const uint8_t CDC_READ_TIMEOUT{10}; // 10 seconds
285 static const long CDC_SMALL_DELAY{50}; // 50ms delay from send command to read response
286
287 INDI::PropertyNumber OutputPowerNP{1};
288 INDI::PropertyNumber MinimumOutputNP{1};
289 INDI::PropertyNumber MaximumOutputNP{1};
290 INDI::PropertySwitch TemperatureModeSP{2};
291 INDI::PropertySwitch SetPointModeSP{3};
292 INDI::PropertyNumber XtrnTemperatureNP{2};
293 INDI::PropertyNumber HumidityNP{1};
294 INDI::PropertyNumber DewpointNP{1};
295 INDI::PropertyNumber SetPointTemperatureNP{1};
296 INDI::PropertyNumber TrackPointOffsetNP{1};
297 INDI::PropertyNumber TrackingRangeNP{1};
298 INDI::PropertyNumber UpdateOutputEveryNP{1};
299 INDI::PropertyNumber QueryWeatherEveryNP{1};
300 INDI::PropertySwitch WeatherSourceSP{4};
301 INDI::PropertyText WeatherQueryAPIKeyTP{1};
302 INDI::PropertyText WeatherUpdatedTP{1};
303 INDI::PropertyNumber LocationNP{2};
304 INDI::PropertyText FWversionTP{1};
305 INDI::PropertySwitch RefreshSP{1};
306 INDI::PropertyText DeviceTimeTP{2};
307 INDI::PropertyText ActiveDeviceTP{3};
308};
hid_device * device
#define CDC_MIN_ADDITIONAL_OUTPUT
Definition cheapodc.h:101
#define CDC_TOTAL_ADDITIONAL_OUTPUTS
Definition cheapodc.h:102
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual bool SetPowerPort(size_t port, bool enabled) override
SetPowerPort Set power port on/off.
Definition cheapodc.cpp:829
virtual ~CheapoDC()=default
virtual bool SetDewPort(size_t port, bool enabled, double dutyCycle) override
SetDewPort Set DEW/Dew port duty cycle.
Definition cheapodc.cpp:880
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
@ CONNECTION_NONE
Definition cheapodc.h:150
@ CONNECTION_SERIAL
Definition cheapodc.h:151
@ CONNECTION_TCP
Definition cheapodc.h:152
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition cheapodc.cpp:171
virtual bool CyclePower() override
CyclePower Cycle power to all ports.
Definition cheapodc.cpp:964
virtual bool SetAutoDewEnabled(size_t port, bool enabled) override
SetAutoDewEnabled Enable/disable automatic dew control.
Definition cheapodc.cpp:862
virtual const char * getDefaultName() override
Definition cheapodc.cpp:271
virtual bool SetUSBPort(size_t port, bool enabled) override
SetUSBPort Set USB port on/off.
Definition cheapodc.cpp:970
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
virtual bool SetLEDEnabled(bool enabled) override
SetLEDEnabled Enable/disable power LEDs.
Definition cheapodc.cpp:957
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool SetVariablePort(size_t port, bool enabled, double voltage) override
SetVariablePort Set variable voltage port.
Definition cheapodc.cpp:948
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
Definition cheapodc.cpp:978
virtual bool ISSnoopDevice(XMLEle *root) override
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
Definition cheapodc.cpp:49
The TCP class manages connection with devices over the network via TCP/IP. Upon successful connection...
Class to provide extended functionality for devices in addition to the functionality provided by INDI...
ISState
Switch state.
Definition indiapi.h:148
#define MAXINDINAME
Definition indiapi.h:189
uint8_t cmd[4]
Definition pwc-ioctl.h:2