Instrument Neutral Distributed Interface INDI 2.2.5
operation_confirmation.h
Go to the documentation of this file.
1/*
2 Gemini Power Box Hub Advanced v3 INDI Driver
3
4 Copyright (C) 2026 Dieter R Kedrowitsch <[email protected]>
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 General Public License along with
17 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 The full GNU General Public License is included in this distribution in the
21 file called LICENSE.
22*/
23
24#pragma once
25
26#include <cstddef>
27#include <type_traits>
28#include <utility>
29#include <variant>
30
33
34namespace geminipbh
35{
36
45
54
56{
57 public:
64
65 std::size_t channel() const
66 {
67 return channel_;
68 }
69 bool enabled() const
70 {
71 return enabled_;
72 }
73
74 private:
75 DcOutputTarget(std::size_t channel, bool enabled) : channel_(channel), enabled_(enabled) {}
76
77 std::size_t channel_ = 0;
78 bool enabled_ = false;
79};
80
82{
83 public:
90
91 std::size_t channel() const
92 {
93 return channel_;
94 }
95 bool enabled() const
96 {
97 return enabled_;
98 }
99
100 private:
101 UsbOutputTarget(std::size_t channel, bool enabled) : channel_(channel), enabled_(enabled) {}
102
103 std::size_t channel_ = 0;
104 bool enabled_ = false;
105};
106
108{
109 public:
116
117 std::size_t channel() const
118 {
119 return channel_;
120 }
121 bool enabled() const
122 {
123 return enabled_;
124 }
125
126 private:
127 HeaterEnabledTarget(std::size_t channel, bool enabled) : channel_(channel), enabled_(enabled) {}
128
129 std::size_t channel_ = 0;
130 bool enabled_ = false;
131};
132
134{
135 public:
144
145 std::size_t channel() const
146 {
147 return channel_;
148 }
150 {
151 return mode_;
152 }
153
154 private:
155 HeaterModeTarget(std::size_t channel, HeaterMode mode) : channel_(channel), mode_(mode) {}
156
157 std::size_t channel_ = 0;
159};
160
162{
163 public:
172
173 std::size_t channel() const
174 {
175 return channel_;
176 }
177 unsigned percent() const
178 {
179 return percent_;
180 }
181
182 private:
183 HeaterManualPowerTarget(std::size_t channel, unsigned percent) : channel_(channel), percent_(percent) {}
184
185 std::size_t channel_ = 0;
186 unsigned percent_ = 0;
187};
188
190{
191 public:
192 static ValueResult<OperationTarget> dcOutput(std::size_t channel, bool enabled)
193 {
194 auto target = DcOutputTarget::create(channel, enabled);
195 if (!target) return ValueResult<OperationTarget>::failure(target.error());
196 return ValueResult<OperationTarget>(OperationTarget(target.value()));
197 }
198
199 static ValueResult<OperationTarget> usbOutput(std::size_t channel, bool enabled)
200 {
201 auto target = UsbOutputTarget::create(channel, enabled);
202 if (!target) return ValueResult<OperationTarget>::failure(target.error());
203 return ValueResult<OperationTarget>(OperationTarget(target.value()));
204 }
205
206 static ValueResult<OperationTarget> heaterEnabled(std::size_t channel, bool enabled)
207 {
208 auto target = HeaterEnabledTarget::create(channel, enabled);
209 if (!target) return ValueResult<OperationTarget>::failure(target.error());
210 return ValueResult<OperationTarget>(OperationTarget(target.value()));
211 }
212
213 static ValueResult<OperationTarget> heaterMode(std::size_t channel, HeaterMode mode)
214 {
215 auto target = HeaterModeTarget::create(channel, mode);
216 if (!target) return ValueResult<OperationTarget>::failure(target.error());
217 return ValueResult<OperationTarget>(OperationTarget(target.value()));
218 }
219
220 static ValueResult<OperationTarget> heaterManualPower(std::size_t channel, unsigned percent)
221 {
222 auto target = HeaterManualPowerTarget::create(channel, percent);
223 if (!target) return ValueResult<OperationTarget>::failure(target.error());
224 return ValueResult<OperationTarget>(OperationTarget(target.value()));
225 }
226
228 {
229 return std::visit([](const auto & target) -> OperationKind
230 {
231 using Target = std::decay_t<decltype(target)>;
232 if constexpr (std::is_same_v<Target, DcOutputTarget>) return OperationKind::DcOutput;
233 if constexpr (std::is_same_v<Target, UsbOutputTarget>) return OperationKind::UsbOutput;
234 if constexpr (std::is_same_v<Target, HeaterEnabledTarget>) return OperationKind::HeaterEnabled;
235 if constexpr (std::is_same_v<Target, HeaterModeTarget>) return OperationKind::HeaterMode;
237 }, target_);
238 }
239
240 private:
241 using Variant =
242 std::variant<DcOutputTarget, UsbOutputTarget, HeaterEnabledTarget, HeaterModeTarget, HeaterManualPowerTarget>;
243
244 explicit OperationTarget(Variant target) : target_(std::move(target)) {}
245
246 Variant target_;
247
248 friend Confirmation confirmOperation(const OperationTarget &, const TelemetrySnapshot *);
249};
250
251inline Confirmation confirmOperation(const DcOutputTarget &target, const TelemetrySnapshot *snapshot)
252{
253 if (!snapshot) return Confirmation::ValueUnavailable;
254 if (target.channel() >= snapshot->dcOutputs.size()) return Confirmation::InvalidTarget;
255 return snapshot->dcOutputs[target.channel()] == target.enabled() ? Confirmation::Confirmed : Confirmation::NotConfirmed;
256}
257
259{
260 if (!snapshot) return Confirmation::ValueUnavailable;
261 if (target.channel() >= snapshot->usbOutputs.size()) return Confirmation::InvalidTarget;
262 return snapshot->usbOutputs[target.channel()] == target.enabled() ? Confirmation::Confirmed : Confirmation::NotConfirmed;
263}
264
266{
267 if (!snapshot) return Confirmation::ValueUnavailable;
268 if (target.channel() >= snapshot->heaterEnabled.size()) return Confirmation::InvalidTarget;
269 return snapshot->heaterEnabled[target.channel()] == target.enabled() ? Confirmation::Confirmed : Confirmation::NotConfirmed;
270}
271
273{
274 if (!snapshot) return Confirmation::ValueUnavailable;
275 if (target.channel() >= snapshot->heaterModes.size()) return Confirmation::InvalidTarget;
276 return snapshot->heaterModes[target.channel()] == target.mode() ? Confirmation::Confirmed : Confirmation::NotConfirmed;
277}
278
283
285{
286 return std::visit([snapshot](const auto & typedTarget)
287 {
288 return confirmOperation(typedTarget, snapshot);
289 }, target.target_);
290}
291
293{
294 return confirmOperation(target, &snapshot);
295}
296
297} // namespace geminipbh
static ValueResult< DcOutputTarget > create(std::size_t channel, bool enabled)
static ValueResult< HeaterEnabledTarget > create(std::size_t channel, bool enabled)
static ValueResult< HeaterManualPowerTarget > create(std::size_t channel, unsigned percent)
static ValueResult< HeaterModeTarget > create(std::size_t channel, HeaterMode mode)
static ValueResult< OperationTarget > usbOutput(std::size_t channel, bool enabled)
static ValueResult< OperationTarget > heaterManualPower(std::size_t channel, unsigned percent)
static ValueResult< OperationTarget > heaterEnabled(std::size_t channel, bool enabled)
friend Confirmation confirmOperation(const OperationTarget &, const TelemetrySnapshot *)
static ValueResult< OperationTarget > dcOutput(std::size_t channel, bool enabled)
static ValueResult< OperationTarget > heaterMode(std::size_t channel, HeaterMode mode)
static ValueResult< UsbOutputTarget > create(std::size_t channel, bool enabled)
static ValueResult failure(Error error)
Definition result.h:86
Confirmation confirmOperation(const DcOutputTarget &target, const TelemetrySnapshot *snapshot)
const std::array< HeaterMode, HeaterCount > heaterModes
static constexpr std::size_t DcOutputCount
static constexpr std::size_t UsbOutputCount
const std::array< bool, UsbOutputCount > usbOutputs
const std::array< bool, DcOutputCount > dcOutputs
const std::array< bool, HeaterCount > heaterEnabled
static constexpr std::size_t HeaterCount