1#[cfg(feature = "python")]
2use pyo3::prelude::*;
3use std::fmt::Display;
4use std::str::FromStr;
5
6use serde::{Deserialize, Serialize};
7use strum::Display;
8
9pub mod models;
10pub use models::MinerModel;
11
12#[cfg_attr(feature = "python", pyclass(str, module = "asic_rs"))]
13#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Serialize, Deserialize, Display)]
14pub enum MinerFirmware {
15 #[serde(rename = "Stock")]
16 Stock,
17 #[serde(rename = "BraiinsOS")]
18 BraiinsOS,
19 #[serde(rename = "VNish")]
20 VNish,
21 #[serde(rename = "ePIC")]
22 EPic,
23 #[serde(rename = "HiveOS")]
24 HiveOS,
25 #[serde(rename = "LuxOS")]
26 LuxOS,
27 #[serde(rename = "Marathon")]
28 Marathon,
29}
30
31#[cfg_attr(feature = "python", pyclass(str, module = "asic_rs"))]
32#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Serialize, Deserialize, Display)]
33pub enum MinerMake {
34 #[serde(rename = "AntMiner")]
35 AntMiner,
36 #[serde(rename = "WhatsMiner")]
37 WhatsMiner,
38 #[serde(rename = "AvalonMiner")]
39 AvalonMiner,
40 #[serde(rename = "ePIC")]
41 EPic,
42 #[serde(rename = "Braiins")]
43 Braiins,
44 #[serde(rename = "Bitaxe")]
45 Bitaxe,
46}
47
48#[cfg_attr(feature = "python", pyclass(str, module = "asic_rs"))]
49#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Serialize, Deserialize, Display)]
50pub enum HashAlgorithm {
51 #[serde(rename = "SHA256")]
52 SHA256,
53 #[serde(rename = "Scrypt")]
54 Scrypt,
55 #[serde(rename = "X11")]
56 X11,
57 #[serde(rename = "Blake2S256")]
58 Blake2S256,
59 #[serde(rename = "Kadena")]
60 Kadena,
61}
62
63#[cfg_attr(feature = "python", pyclass(get_all, module = "asic_rs"))]
64#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Serialize, Deserialize)]
65pub struct DeviceInfo {
66 pub make: MinerMake,
67 pub model: MinerModel,
68 pub hardware: MinerHardware,
69 pub firmware: MinerFirmware,
70 pub algo: HashAlgorithm,
71}
72
73impl DeviceInfo {
74 pub(crate) fn new(
75 make: MinerMake,
76 model: MinerModel,
77 firmware: MinerFirmware,
78 algo: HashAlgorithm,
79 ) -> Self {
80 Self {
81 make,
82 hardware: MinerHardware::from(&model),
83 model,
84 firmware,
85 algo,
86 }
87 }
88}
89
90#[cfg_attr(feature = "python", pyclass(get_all, module = "asic_rs"))]
91#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Serialize, Deserialize)]
92pub struct MinerHardware {
93 pub chips: Option<u16>,
94 pub fans: Option<u8>,
95 pub boards: Option<u8>,
96}
97
98impl From<&MinerModel> for MinerHardware {
99 fn from(model: &MinerModel) -> Self {
100 match model {
101 MinerModel::AntMiner(model_name) => Self::from(model_name),
102 MinerModel::WhatsMiner(model_name) => Self::from(model_name),
103 MinerModel::Braiins(model_name) => Self::from(model_name),
104 MinerModel::Bitaxe(model_name) => Self::from(model_name),
105 MinerModel::EPic(model_name) => Self::from(model_name),
106 MinerModel::AvalonMiner(model_name) => Self::from(model_name),
107 }
108 }
109}
110
111#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize, Display)]
112pub enum MinerControlBoard {
113 #[serde(rename = "Xilinx")]
115 Xilinx,
116 #[serde(rename = "BeagleBoneBlack")]
117 BeagleBoneBlack,
118 #[serde(rename = "AMLogic")]
119 AMLogic,
120 #[serde(rename = "CVITek")]
121 CVITek,
122 #[serde(rename = "H3")]
124 H3,
125 #[serde(rename = "H6")]
126 H6,
127 #[serde(rename = "H6OS")]
128 H6OS,
129 #[serde(rename = "H616")]
130 H616,
131 #[serde(rename = "MM3v2X3")]
133 MM3v2X3,
134 #[serde(rename = "MM3v1X3")]
135 MM3v1X3,
136 #[serde(rename = "MM3v1")]
137 MM3v1,
138 #[serde(rename = "B102")]
140 B102,
141 #[serde(rename = "B201")]
142 B201,
143 #[serde(rename = "B202")]
144 B202,
145 #[serde(rename = "B203")]
146 B203,
147 #[serde(rename = "B204")]
148 B204,
149 #[serde(rename = "B205")]
150 B205,
151 #[serde(rename = "B207")]
152 B207,
153 #[serde(rename = "B401")]
154 B401,
155 #[serde(rename = "B402")]
156 B402,
157 #[serde(rename = "B403")]
158 B403,
159 #[serde(rename = "B601")]
160 B601,
161 #[serde(rename = "B602")]
162 B602,
163 #[serde(rename = "B800")]
164 B800,
165 #[serde(rename = "BraiinsCB")]
167 BraiinsCB,
168 #[serde(rename = "ePIC UMC")]
169 EPicUMC,
170 #[serde(rename = "MaraCB")]
171 MaraCB,
172 Unknown(String),
174}
175
176#[derive(Debug, Clone)]
177pub struct ControlBoardParseError;
178
179impl Display for ControlBoardParseError {
180 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
181 write!(f, "Failed to parse control board type")
182 }
183}
184
185impl FromStr for MinerControlBoard {
186 type Err = String;
187
188 fn from_str(s: &str) -> Result<Self, Self::Err> {
189 let cb_model = s.trim().replace(" ", "").to_uppercase();
190 match cb_model.as_ref() {
191 "XILINX" => Ok(Self::Xilinx),
192 "BBB" => Ok(Self::BeagleBoneBlack),
193 "BB" => Ok(Self::BeagleBoneBlack),
194 "BEAGLEBONE" => Ok(Self::BeagleBoneBlack),
195 "BEAGLEBONEBLACK" => Ok(Self::BeagleBoneBlack),
196 "CVITEK" => Ok(Self::CVITek),
197 "CVCTRL" => Ok(Self::CVITek),
198 "AMLOGIC" => Ok(Self::AMLogic),
199 "AML" => Ok(Self::AMLogic),
200 "H3" => Ok(Self::H3),
201 "H6" => Ok(Self::H6),
202 "H6OS" => Ok(Self::H6OS),
203 "H616" => Ok(Self::H616),
204 "MM3V2_X3" => Ok(Self::MM3v2X3),
205 "MM3V1_X3" => Ok(Self::MM3v1X3),
206 "MM3V1" => Ok(Self::MM3v1),
207 "102" => Ok(Self::B102),
208 "201" => Ok(Self::B201),
209 "202" => Ok(Self::B202),
210 "203" => Ok(Self::B203),
211 "204" => Ok(Self::B204),
212 "205" => Ok(Self::B205),
213 "207" => Ok(Self::B207),
214 "401" => Ok(Self::B401),
215 "402" => Ok(Self::B402),
216 "403" => Ok(Self::B403),
217 "601" => Ok(Self::B601),
218 "602" => Ok(Self::B602),
219 "800" => Ok(Self::B800),
220 "BraiinsCB" => Ok(Self::BraiinsCB),
221 "ePIC UMC" => Ok(Self::EPicUMC),
222 _ => Ok(Self::Unknown(s.to_string())),
223 }
224 }
225}