decharge-scout 4.0.2 → 4.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +33 -2
- package/package.json +1 -1
- package/src/weather-data.js +84 -37
package/index.js
CHANGED
|
@@ -33,7 +33,7 @@ dotenv.config({ path: path.join(process.cwd(), '.env') });
|
|
|
33
33
|
// Import modules
|
|
34
34
|
import { startWalletServer, openWalletConnection, waitForWalletConnection, getConnectedWallet } from './src/wallet-server.js';
|
|
35
35
|
import { setConnectedWallet, getBalance, checkBalance, mockStake, refundStake } from './src/browser-wallet.js';
|
|
36
|
-
import { getWeatherForLocation } from './src/weather-data.js';
|
|
36
|
+
import { getWeatherForLocation, getFallbackCoordinates } from './src/weather-data.js';
|
|
37
37
|
import { generateSmartPricing, getPricingInsights, getRegionalPricing } from './src/smart-pricing.js';
|
|
38
38
|
import { findCheapestWindow, calculateSavings } from './src/optimizer.js';
|
|
39
39
|
import { submitToOracle } from './src/oracle.js';
|
|
@@ -288,7 +288,38 @@ async function runQueryCycle(wallet, agentName, location, options) {
|
|
|
288
288
|
|
|
289
289
|
} catch (error) {
|
|
290
290
|
weatherSpinner.fail(chalk.red('Failed to fetch weather data'));
|
|
291
|
-
|
|
291
|
+
|
|
292
|
+
// Check if we have fallback coordinates available
|
|
293
|
+
const fallbackCoords = getFallbackCoordinates(location);
|
|
294
|
+
|
|
295
|
+
console.log(chalk.yellow(`\n⚠️ Could not geocode location: "${location}"`));
|
|
296
|
+
console.log(chalk.yellow(` Error: ${error.message}`));
|
|
297
|
+
|
|
298
|
+
if (fallbackCoords) {
|
|
299
|
+
console.log(chalk.blue(`\n💡 We have fallback coordinates for: ${fallbackCoords.name}, ${fallbackCoords.country}`));
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
console.log(chalk.blue(`\nOptions:`));
|
|
303
|
+
console.log(chalk.gray(` 1. Try a different location (e.g., just "Hyderabad" or "Hyderabad, India")`));
|
|
304
|
+
if (fallbackCoords) {
|
|
305
|
+
console.log(chalk.gray(` 2. Use fallback coordinates for ${fallbackCoords.name}`));
|
|
306
|
+
}
|
|
307
|
+
console.log(chalk.gray(` 3. Exit and restart\n`));
|
|
308
|
+
|
|
309
|
+
const userChoice = await question(chalk.blue('Enter new location (or press Enter to exit): '));
|
|
310
|
+
|
|
311
|
+
if (!userChoice.trim()) {
|
|
312
|
+
console.log(chalk.yellow('Exiting...'));
|
|
313
|
+
throw new Error('User chose to exit');
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Update location and retry this cycle
|
|
317
|
+
location = userChoice.trim();
|
|
318
|
+
console.log(chalk.green(`✓ Updated location to: ${location}`));
|
|
319
|
+
console.log(chalk.gray('Retrying...\n'));
|
|
320
|
+
|
|
321
|
+
// Retry with new location - this will loop back and try again
|
|
322
|
+
continue;
|
|
292
323
|
}
|
|
293
324
|
|
|
294
325
|
// Run optimization
|
package/package.json
CHANGED
package/src/weather-data.js
CHANGED
|
@@ -12,34 +12,57 @@ import fetch from 'node-fetch';
|
|
|
12
12
|
/**
|
|
13
13
|
* Get coordinates from location string
|
|
14
14
|
* Simple geocoding using Open-Meteo's geocoding API (also free!)
|
|
15
|
+
* Tries multiple search strategies for better success rate
|
|
15
16
|
*/
|
|
16
17
|
export async function getCoordinatesFromLocation(location) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
// Try multiple search strategies
|
|
19
|
+
const searchTerms = [
|
|
20
|
+
location, // Original: "Hyderabad, TS, IN"
|
|
21
|
+
location.split(',')[0].trim(), // Just city: "Hyderabad"
|
|
22
|
+
location.replace(/,\s*[A-Z]{2}\s*,/, ','), // Remove state: "Hyderabad, IN"
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
// Remove duplicates
|
|
26
|
+
const uniqueSearchTerms = [...new Set(searchTerms)];
|
|
27
|
+
|
|
28
|
+
let lastError = null;
|
|
29
|
+
|
|
30
|
+
for (const searchTerm of uniqueSearchTerms) {
|
|
31
|
+
try {
|
|
32
|
+
const locationEncoded = encodeURIComponent(searchTerm);
|
|
33
|
+
const url = `https://geocoding-api.open-meteo.com/v1/search?name=${locationEncoded}&count=5&language=en&format=json`;
|
|
34
|
+
|
|
35
|
+
const response = await fetch(url);
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
lastError = new Error(`Geocoding failed: ${response.status}`);
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const data = await response.json();
|
|
42
|
+
|
|
43
|
+
if (!data.results || data.results.length === 0) {
|
|
44
|
+
lastError = new Error(`Location "${searchTerm}" not found`);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Use first result
|
|
49
|
+
const result = data.results[0];
|
|
50
|
+
console.log(`✓ Geocoded "${searchTerm}" → ${result.name}, ${result.country} (${result.latitude}, ${result.longitude})`);
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
latitude: result.latitude,
|
|
54
|
+
longitude: result.longitude,
|
|
55
|
+
name: result.name,
|
|
56
|
+
country: result.country,
|
|
57
|
+
timezone: result.timezone || 'auto'
|
|
58
|
+
};
|
|
59
|
+
} catch (error) {
|
|
60
|
+
lastError = error;
|
|
61
|
+
continue;
|
|
24
62
|
}
|
|
25
|
-
|
|
26
|
-
const data = await response.json();
|
|
27
|
-
|
|
28
|
-
if (!data.results || data.results.length === 0) {
|
|
29
|
-
throw new Error('Location not found');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const result = data.results[0];
|
|
33
|
-
return {
|
|
34
|
-
latitude: result.latitude,
|
|
35
|
-
longitude: result.longitude,
|
|
36
|
-
name: result.name,
|
|
37
|
-
country: result.country,
|
|
38
|
-
timezone: result.timezone || 'UTC'
|
|
39
|
-
};
|
|
40
|
-
} catch (error) {
|
|
41
|
-
throw new Error(`Failed to geocode location: ${error.message}`);
|
|
42
63
|
}
|
|
64
|
+
|
|
65
|
+
throw new Error(`Failed to geocode location after trying: ${uniqueSearchTerms.join(', ')}. Last error: ${lastError?.message}`);
|
|
43
66
|
}
|
|
44
67
|
|
|
45
68
|
/**
|
|
@@ -95,23 +118,47 @@ export async function fetchWeatherForecast(latitude, longitude, timezone = 'auto
|
|
|
95
118
|
}
|
|
96
119
|
}
|
|
97
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Known coordinates for common cities (fallback)
|
|
123
|
+
*/
|
|
124
|
+
const KNOWN_CITIES = {
|
|
125
|
+
'hyderabad': { latitude: 17.385, longitude: 78.487, name: 'Hyderabad', country: 'India', timezone: 'Asia/Kolkata' },
|
|
126
|
+
'mumbai': { latitude: 19.076, longitude: 72.877, name: 'Mumbai', country: 'India', timezone: 'Asia/Kolkata' },
|
|
127
|
+
'delhi': { latitude: 28.704, longitude: 77.102, name: 'Delhi', country: 'India', timezone: 'Asia/Kolkata' },
|
|
128
|
+
'bangalore': { latitude: 12.972, longitude: 77.594, name: 'Bangalore', country: 'India', timezone: 'Asia/Kolkata' },
|
|
129
|
+
'chennai': { latitude: 13.083, longitude: 80.270, name: 'Chennai', country: 'India', timezone: 'Asia/Kolkata' },
|
|
130
|
+
'lagos': { latitude: 6.524, longitude: 3.379, name: 'Lagos', country: 'Nigeria', timezone: 'Africa/Lagos' },
|
|
131
|
+
'london': { latitude: 51.509, longitude: -0.118, name: 'London', country: 'United Kingdom', timezone: 'Europe/London' },
|
|
132
|
+
'new york': { latitude: 40.713, longitude: -74.006, name: 'New York', country: 'United States', timezone: 'America/New_York' },
|
|
133
|
+
'los angeles': { latitude: 34.052, longitude: -118.244, name: 'Los Angeles', country: 'United States', timezone: 'America/Los_Angeles' },
|
|
134
|
+
'chicago': { latitude: 41.878, longitude: -87.630, name: 'Chicago', country: 'United States', timezone: 'America/Chicago' },
|
|
135
|
+
'houston': { latitude: 29.760, longitude: -95.369, name: 'Houston', country: 'United States', timezone: 'America/Chicago' },
|
|
136
|
+
'dallas': { latitude: 32.776, longitude: -96.797, name: 'Dallas', country: 'United States', timezone: 'America/Chicago' },
|
|
137
|
+
};
|
|
138
|
+
|
|
98
139
|
/**
|
|
99
140
|
* Get weather data for a location
|
|
141
|
+
* Throws error if geocoding fails - caller should handle user interaction
|
|
100
142
|
*/
|
|
101
143
|
export async function getWeatherForLocation(location) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
console.log(`📍 Location: ${coords.name}, ${coords.country} (${coords.latitude}, ${coords.longitude})`);
|
|
144
|
+
// Try geocoding - throw error if fails
|
|
145
|
+
const coords = await getCoordinatesFromLocation(location);
|
|
146
|
+
console.log(`📍 Location: ${coords.name}, ${coords.country} (${coords.latitude}, ${coords.longitude})`);
|
|
106
147
|
|
|
107
|
-
|
|
108
|
-
|
|
148
|
+
// Get weather forecast
|
|
149
|
+
const forecast = await fetchWeatherForecast(coords.latitude, coords.longitude, coords.timezone);
|
|
109
150
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
151
|
+
return {
|
|
152
|
+
location: coords,
|
|
153
|
+
forecast
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Get fallback coordinates for known cities
|
|
159
|
+
* Returns null if city not in database
|
|
160
|
+
*/
|
|
161
|
+
export function getFallbackCoordinates(location) {
|
|
162
|
+
const cityKey = location.split(',')[0].trim().toLowerCase();
|
|
163
|
+
return KNOWN_CITIES[cityKey] || null;
|
|
117
164
|
}
|