67 cap &= ~CCD_HAS_COOLER;
85 cap &= ~CCD_HAS_COOLER;
127 std::string form_data;
130 for (
auto& [key, value] : request.
items())
132 if (!form_data.empty()) form_data +=
"&";
134 if (value.is_string())
136 form_data += key +
"=" + value.get<std::string>();
138 else if (value.is_number_integer())
140 form_data += key +
"=" + std::to_string(value.get<
int>());
142 else if (value.is_number_float())
144 form_data += key +
"=" + std::to_string(value.get<
double>());
146 else if (value.is_boolean())
148 form_data += key +
"=" + (value.get<
bool>() ?
"true" :
"false");
153 if (!form_data.empty()) form_data +=
"&";
154 form_data +=
"ClientID=" + std::to_string(getpid());
179 LOGF_INFO(
"Seestar raw metadata: Rank=%d, Dim1=%d, Dim2=%d, Dim3=%d, TransType=%d, DataStart=%d",
189 int32_t actual_rank = metadata->
Rank;
194 if (actual_rank < 2 || actual_rank > 3)
196 LOGF_ERROR(
"Invalid corrected rank: %d (must be 2 or 3)", actual_rank);
200 if (actual_width <= 0 || actual_height <= 0)
202 LOGF_ERROR(
"Invalid corrected dimensions: %dx%d", actual_width, actual_height);
213 int32_t actual_data_start = metadata->
DataStart;
216 size_t bytes_per_element = 2;
217 uint32_t planes = (actual_rank == 3) ? 1 : 1;
218 size_t expected_data_size = actual_width * actual_height * planes * bytes_per_element;
219 size_t actual_data_size = body_size - actual_data_start;
221 LOGF_DEBUG(
"Seestar ImageBytes corrected: %dx%dx%d, rank=%d, type=Int16, data_size=%zu (expected=%zu)",
222 actual_width, actual_height, planes, actual_rank, actual_data_size, expected_data_size);
225 size_t tolerance = std::max(expected_data_size / 100, (
size_t)1024);
226 if (actual_data_size < expected_data_size - tolerance || actual_data_size > expected_data_size + tolerance)
228 LOGF_WARN(
"Data size mismatch: expected %zu bytes, got %zu bytes (tolerance: %zu)",
229 expected_data_size, actual_data_size, tolerance);
234 metadata->
Rank = actual_rank;
237 metadata->
Dimension3 = (actual_rank == 3) ? planes : 0;
241 LOGF_INFO(
"Seestar ImageBytes: %dx%d, rank=%d, type=Int16, %zu bytes",
242 actual_width, actual_height, actual_rank, actual_data_size);
uint32_t getTransactionId()
void setDefaultServerAddress(const char *host, const char *port, bool force=false)
bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
bool Connect() override
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
uint32_t GetCCDCapability() const
GetCCDCapability returns the CCD capabilities.
void SetCCDCapability(uint32_t cap)
SetCCDCapability Set the CCD capabilities. All fields must be initialized.
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
The SeestarCCD class provides Seestar specific workarounds for the ASCOM Alpaca CCD driver.
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual std::string buildAlpacaFormData(const nlohmann::json &request) override
Build Alpaca form data with Seestar-specific parameter ordering.
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
virtual const char * getDefaultName() override
virtual int SetTemperature(double temperature) override
Set CCD temperature.
virtual bool Connect() override
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
virtual bool parseImageBytesMetadata(ImageBytesMetadata *metadata, size_t body_size) override
Parse ImageBytes metadata with Seestar-specific workarounds.
SeestarCCD()
Main entry point - INDI handles this through the unique_ptr.
a class to store JSON values
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
std::unique_ptr< SeestarCCD > seestar_ccd(new SeestarCCD())
Implementations for common driver routines.
#define LOGF_INFO(fmt,...)
#define LOGF_WARN(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOGF_ERROR(fmt,...)