aquarium_control/sensors/
atlas_scientific_error.rs

1/* Copyright 2025 Uwe Martin
2
3Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
5The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
7THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8*/
9use crate::launch::channels::AquaChannelError;
10use crate::sensors::i2c_error::I2cError;
11use crate::utilities::channel_content::AquariumSignal;
12use std::num::ParseFloatError;
13use std::str::Utf8Error;
14use thiserror::Error;
15
16/// error codes for evaluation of sensor unit response
17#[allow(dead_code)]
18#[derive(Debug, Error)]
19pub enum AtlasScientificError {
20    /// The first character in the message sent from the sensor does not match the required magic number.
21    #[error("[{0}] The first character in the message sent from the sensor ({2}) does not match the required magic number ({1}).")]
22    FirstCharacterNotMagic(String, u8, u8),
23
24    /// The last character in the message sent from the sensor does not match the required magic number.
25    #[error("[{0}] The last character in the message sent from the sensor ({2}) does not match the required magic number ({1})")]
26    LastCharacterNotMagic(String, u8, u8),
27
28    /// The message sent from the sensor unit contains non-numeric characters in the data section
29    #[error("[{0}] The message sent from the sensor unit contains non-numeric character with ASCII value ('{1}') in the data section.")]
30    ContainsInvalidCharacter(String, u8),
31
32    /// The error is masked by other checks. Still, the signature of the function to convert from u8 array slice to String throws an error.
33    #[error("[{location}] An invalid UTF8 sequence occurred.")]
34    InvalidUtf8Sequence {
35        location: String,
36
37        #[source]
38        source: Utf8Error,
39    },
40
41    /// Conversion from String to f32 failed.
42    #[error("[{location}] Conversion from String to f32 failed.")]
43    ConversionFailure {
44        location: String,
45
46        #[source]
47        source: ParseFloatError,
48    },
49
50    /// Incorrect buffer length
51    #[error("[{0}] The response from {1} has incorrect length ({2}).")]
52    IncorrectBufferLength(String, AquariumSignal, usize),
53
54    /// Mutex poisoned
55    #[error("[{location}] Could not lock mutex for {signal}")]
56    CouldNotLockMutex {
57        location: String,
58        signal: AquariumSignal,
59    },
60
61    /// Error in sensor unit response for a specific signal.
62    #[error("[{location}] Error in sensor unit response for {signal}.")]
63    ResponseCheckFailed {
64        location: String,
65        signal: AquariumSignal,
66        #[source]
67        source: Box<AtlasScientificError>,
68    },
69
70    /// Initial value, is overwritten
71    #[error("Initialization value - result has not been set yet")]
72    Initial,
73
74    /// Error in I2C communication for a specific signal.
75    #[error("[{location}] Error in I2C communication for {signal}.")]
76    I2cCommunicationFailure {
77        location: String,
78        signal: AquariumSignal,
79
80        #[source]
81        source: I2cError,
82    },
83
84    /// Error is used to communicate to caller that receiving needs to be repeated.
85    #[error("[{0}] Channel for receiving from I2CInterface thread is empty.")]
86    ChannelIsEmpty(String),
87
88    /// The channel is disconnected.
89    #[error("[{location}] Channel for receiving from I2CInterface is disconnected.")]
90    ChannelIsDisconnected {
91        location: String,
92        #[source]
93        source: AquaChannelError,
94    },
95
96    /// Logic error: Signal is unknown
97    #[error("[{0}] Ignoring invalid signal request ({1})")]
98    InvalidSignal(String, AquariumSignal),
99
100    /// Signal request could not be created.
101    #[error("[{location}] Signal request creation failed.")]
102    SignalRequestCreationFailure {
103        location: String,
104
105        #[source]
106        source: I2cError,
107    },
108
109    /// Sending request to I2cInterface thread failed.
110    #[error("[{location}] Sending request to I2cInterface thread failed.")]
111    SendingRequestToI2cInterfaceFailed {
112        location: String,
113
114        #[source]
115        source: AquaChannelError,
116    },
117
118    /// Enum value covering unreachable branch in match
119    #[error("Internal error - this should never happen.")]
120    UnknownError(String),
121}