-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_hashboard_simple.py
More file actions
241 lines (203 loc) · 8.6 KB
/
Copy pathtest_hashboard_simple.py
File metadata and controls
241 lines (203 loc) · 8.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#!/usr/bin/env python3
"""
Simple synchronous hashboard control test using only standard library.
This bypasses Home Assistant to help diagnose hashboard switching issues.
"""
import socket
import json
import time
def send_luxos_command(host, command, parameter=""):
"""Send a command to LuxOS miner via TCP port 4028."""
try:
# Create the command JSON
cmd = {"command": command}
if parameter:
cmd["parameter"] = parameter
message = json.dumps(cmd)
# Connect to miner
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)
sock.connect((host, 4028))
# Send command
sock.sendall(message.encode('utf-8'))
# Receive response
response = b""
while True:
chunk = sock.recv(4096)
if not chunk:
break
response += chunk
# LuxOS responses end with \x00
if b'\x00' in response:
break
sock.close()
# Parse response (remove null byte and parse JSON)
response_str = response.decode('utf-8').rstrip('\x00')
return json.loads(response_str)
except Exception as e:
return {"error": str(e)}
def get_session_id(host, username, password):
"""Get LuxOS session ID for authenticated commands."""
# Try newer 'session' command first
result = send_luxos_command(host, "session", f"{username},{password}")
if "SESSION" in result and result["SESSION"]:
session_info = result["SESSION"][0]
# Try both "SessionID" and "Session ID" for compatibility
session_id = session_info.get("SessionID") or session_info.get("Session ID")
if session_id:
print(f"✓ Login successful (session command), session ID: {session_id}")
return session_id
# Try older 'logon' command
result = send_luxos_command(host, "logon", f"{username},{password}")
if "SESSION" in result and result["SESSION"]:
session_info = result["SESSION"][0]
session_id = session_info.get("SessionID") or session_info.get("Session ID")
if session_id:
print(f"✓ Login successful (logon command), session ID: {session_id}")
return session_id
print(f"✗ Login failed: {result}")
print(f" Trying to continue without session ID (some commands may work)")
return "0" # Return dummy session ID to allow testing
def display_devs(devs_result):
"""Display device (hashboard) information."""
if "DEVS" in devs_result:
print(f"\nFound {len(devs_result['DEVS'])} hashboards:")
for i, board in enumerate(devs_result['DEVS']):
status = board.get('Status', 'Unknown')
enabled = board.get('Enabled', 'Unknown')
temp = board.get('Temperature', 'Unknown')
hashrate = board.get('MHS 5s', 0) / 1000000 # Convert to TH/s
print(f" Board {i}: Status={status}, Enabled={enabled}, Temp={temp}°C, Hashrate={hashrate:.2f} TH/s")
else:
print(f"No device info: {devs_result}")
def main():
"""Main diagnostic function."""
print("=== LuxOS Hashboard Control Diagnostic Tool (Simple) ===\n")
MINER_HOST = "192.168.1.210"
MINER_USERNAME = "root"
MINER_PASSWORD = "root"
print(f"Testing hashboard control on {MINER_HOST}")
print(f"{'='*60}\n")
# Test 1: Basic connection
print("1. Testing basic connection...")
version = send_luxos_command(MINER_HOST, "version")
if "error" in version:
print(f" ✗ Connection failed: {version['error']}\n")
return
else:
print(f" ✓ Connection successful")
if "VERSION" in version and version["VERSION"]:
ver_info = version["VERSION"][0]
print(f" Miner: {ver_info.get('Type', 'Unknown')}")
print(f" LuxOS: {ver_info.get('LUXminer', 'Unknown')}\n")
# Test 2: Get session ID
print("2. Getting session ID...")
session_id = get_session_id(MINER_HOST, MINER_USERNAME, MINER_PASSWORD)
if not session_id:
print(" ✗ Failed to get session ID\n")
return
print()
# Test 3: Get current status
print("3. Getting miner status...")
devs = send_luxos_command(MINER_HOST, "devs")
display_devs(devs)
print()
# Test 4: Check miner state
print("4. Checking miner state...")
stats = send_luxos_command(MINER_HOST, "stats")
if "STATS" in stats and len(stats["STATS"]) > 1:
hashrate = stats["STATS"][1].get("GHS 5s", 0)
print(f" Current total hashrate: {hashrate/1000:.2f} TH/s")
if hashrate < 1000:
print(" ⚠ Miner appears to be in sleep/idle mode")
else:
print(" ✓ Miner is active")
print()
# Test 5: Check ATM status
print("5. Checking ATM (Automatic Tuning Mode) status...")
atm_status = send_luxos_command(MINER_HOST, "atm")
if "ATM" in atm_status and atm_status["ATM"]:
atm_info = atm_status["ATM"][0]
enabled = atm_info.get("Enabled", "Unknown")
print(f" ATM Enabled: {enabled}")
if enabled:
print(" ℹ ATM must be disabled temporarily to control hashboards")
print()
# Test 6: Interactive hashboard control
print("6. Hashboard Control Test")
print(f"{'='*60}")
while True:
print("\nOptions:")
print(" 1 - Enable hashboard 0")
print(" 2 - Disable hashboard 0")
print(" 3 - Enable hashboard 1")
print(" 4 - Disable hashboard 1")
print(" 5 - Enable hashboard 2")
print(" 6 - Disable hashboard 2")
print(" 7 - Get current status")
print(" 8 - Test resume/wakeup")
print(" q - Quit")
choice = input("\nEnter choice: ").strip().lower()
if choice == 'q':
break
elif choice == '7':
devs = send_luxos_command(MINER_HOST, "devs")
display_devs(devs)
elif choice == '8':
print("\nTesting curtail wakeup command...")
result = send_luxos_command(MINER_HOST, "curtail", f"{session_id},wakeup")
print(f"Response: {result}")
elif choice in ['1', '2', '3', '4', '5', '6']:
# Parse board number and action
if choice in ['1', '3', '5']:
board_num = (int(choice) - 1) // 2
action = 'enable'
command = 'enableboard'
else:
board_num = (int(choice) - 2) // 2
action = 'disable'
command = 'disableboard'
print(f"\n{'='*60}")
print(f"Attempting to {action} hashboard {board_num}...")
print(f"{'='*60}")
# Step 1: Disable ATM
print("\nStep 1: Disabling ATM...")
atm_disable = send_luxos_command(MINER_HOST, "atmset", f"{session_id},enabled=false")
print(f"Response: {atm_disable}")
if "STATUS" in atm_disable and atm_disable["STATUS"]:
status = atm_disable["STATUS"][0]
if status.get("STATUS") == "S":
print("✓ ATM disabled successfully")
else:
print(f"⚠ ATM disable warning: {status.get('Msg')}")
time.sleep(0.5)
# Step 2: Execute hashboard command
print(f"\nStep 2: Executing {command} for board {board_num}...")
board_result = send_luxos_command(MINER_HOST, command, f"{session_id},{board_num}")
print(f"Response: {board_result}")
if "STATUS" in board_result and board_result["STATUS"]:
status = board_result["STATUS"][0]
if status.get("STATUS") == "S":
print(f"✓ {command} successful!")
else:
print(f"✗ {command} failed: {status.get('Msg')}")
time.sleep(0.5)
# Step 3: Re-enable ATM
print("\nStep 3: Re-enabling ATM...")
atm_enable = send_luxos_command(MINER_HOST, "atmset", f"{session_id},enabled=true")
print(f"Response: {atm_enable}")
if "STATUS" in atm_enable and atm_enable["STATUS"]:
status = atm_enable["STATUS"][0]
if status.get("STATUS") == "S":
print("✓ ATM re-enabled successfully")
else:
print(f"⚠ ATM re-enable warning: {status.get('Msg')}")
# Step 4: Check new status
print("\nStep 4: Checking new status...")
time.sleep(1)
devs = send_luxos_command(MINER_HOST, "devs")
display_devs(devs)
else:
print("Invalid choice")
if __name__ == "__main__":
main()