JavaScript Examples¶
JavaScript/TypeScript examples for browser and Node.js environments.
Browser (Fetch API)¶
/**
* Tessellate Renewables API Client
*/
class TessellateClient {
constructor(apiKey = null) {
this.baseUrl = 'https://api.tessellaterenewables.com';
this.headers = {
'Content-Type': 'application/json',
};
if (apiKey) {
this.headers['X-API-Key'] = apiKey;
}
}
async request(endpoint, method = 'GET', body = null) {
const options = {
method,
headers: this.headers,
};
if (body) {
options.body = JSON.stringify(body);
}
const response = await fetch(`${this.baseUrl}${endpoint}`, options);
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'API request failed');
}
return response.json();
}
async getSolarResource(latitude, longitude) {
return this.request('/solar/resource', 'POST', { latitude, longitude });
}
async quickOptimize(latitude, longitude, capacityKw, objective = 'energy') {
return this.request('/solar/optimization/quick', 'POST', {
site: { latitude, longitude, capacity_kw: capacityKw },
objective,
});
}
async fullOptimize(latitude, longitude, capacityKw, options = {}) {
const { objective = 'energy', maxIterations = 50, bounds = null } = options;
// Submit job
const job = await this.request('/solar/optimization/run', 'POST', {
site: { latitude, longitude, capacity_kw: capacityKw },
objective,
max_iterations: maxIterations,
bounds,
});
// Poll for results
return this.pollJob(job.job_id);
}
async pollJob(jobId, intervalMs = 2000) {
while (true) {
const result = await this.request(`/solar/optimization/${jobId}`);
if (result.status === 'completed') {
return result;
} else if (result.status === 'failed') {
throw new Error(result.error_message || 'Job failed');
}
await new Promise((resolve) => setTimeout(resolve, intervalMs));
}
}
async predict(latitude, longitude, capacityKw, params = {}) {
const {
tilt = 30,
azimuth = 180,
dcAcRatio = 1.2,
gcr = 0.4,
} = params;
return this.request('/solar/predict', 'POST', {
latitude,
longitude,
capacity_kw: capacityKw,
tilt,
azimuth,
dc_ac_ratio: dcAcRatio,
gcr,
});
}
}
// Usage
const client = new TessellateClient();
async function optimizeSite() {
try {
const result = await client.quickOptimize(35.0, -110.0, 1000, 'energy');
console.log('Optimal Parameters:');
console.log(` Tilt: ${result.optimal_parameters.tilt}°`);
console.log(` Azimuth: ${result.optimal_parameters.azimuth}°`);
console.log('Energy Performance:');
console.log(` Annual Energy: ${result.energy_metrics.annual_energy_mwh.toLocaleString()} MWh`);
console.log(` Capacity Factor: ${(result.energy_metrics.capacity_factor * 100).toFixed(1)}%`);
} catch (error) {
console.error('Error:', error.message);
}
}
optimizeSite();
Node.js with Axios¶
const axios = require('axios');
class TessellateClient {
constructor(apiKey = null) {
this.client = axios.create({
baseURL: 'https://api.tessellaterenewables.com',
headers: {
'Content-Type': 'application/json',
...(apiKey && { 'X-API-Key': apiKey }),
},
});
}
async quickOptimize(latitude, longitude, capacityKw, objective = 'energy') {
const { data } = await this.client.post('/solar/optimization/quick', {
site: { latitude, longitude, capacity_kw: capacityKw },
objective,
});
return data;
}
// ... other methods
}
module.exports = TessellateClient;
TypeScript¶
interface Site {
latitude: number;
longitude: number;
capacity_kw: number;
}
interface OptimalParameters {
tilt: number;
azimuth: number;
dc_ac_ratio: number;
gcr: number;
}
interface EnergyMetrics {
annual_energy_mwh: number;
capacity_factor: number;
specific_yield: number;
performance_ratio: number;
}
interface FinancialMetrics {
lcoe_cents_per_kwh: number;
npv_dollars: number;
irr_percent: number;
payback_years: number;
}
interface OptimizationResult {
optimal_parameters: OptimalParameters;
energy_metrics: EnergyMetrics;
financial_metrics: FinancialMetrics;
}
class TessellateClient {
private baseUrl: string;
private headers: Record<string, string>;
constructor(apiKey?: string) {
this.baseUrl = 'https://api.tessellaterenewables.com';
this.headers = {
'Content-Type': 'application/json',
};
if (apiKey) {
this.headers['X-API-Key'] = apiKey;
}
}
async quickOptimize(
latitude: number,
longitude: number,
capacityKw: number,
objective: 'energy' | 'lcoe' | 'npv' | 'irr' = 'energy'
): Promise<OptimizationResult> {
const response = await fetch(`${this.baseUrl}/solar/optimization/quick`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify({
site: { latitude, longitude, capacity_kw: capacityKw },
objective,
}),
});
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
return response.json();
}
}
// Usage
const client = new TessellateClient();
async function main() {
const result = await client.quickOptimize(35.0, -110.0, 1000, 'energy');
console.log(`Tilt: ${result.optimal_parameters.tilt}°`);
}
main();
React Hook Example¶
import { useState, useCallback } from 'react';
function useSolarOptimization() {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [result, setResult] = useState(null);
const optimize = useCallback(async (latitude, longitude, capacityKw, objective = 'energy') => {
setLoading(true);
setError(null);
try {
const response = await fetch(
'https://api.tessellaterenewables.com/solar/optimization/quick',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
site: { latitude, longitude, capacity_kw: capacityKw },
objective,
}),
}
);
if (!response.ok) {
throw new Error('Optimization failed');
}
const data = await response.json();
setResult(data);
return data;
} catch (err) {
setError(err.message);
throw err;
} finally {
setLoading(false);
}
}, []);
return { optimize, loading, error, result };
}
// Usage in component
function SolarOptimizer() {
const { optimize, loading, error, result } = useSolarOptimization();
const handleSubmit = async (e) => {
e.preventDefault();
await optimize(35.0, -110.0, 1000, 'energy');
};
return (
<div>
<button onClick={handleSubmit} disabled={loading}>
{loading ? 'Optimizing...' : 'Optimize'}
</button>
{error && <p className="error">{error}</p>}
{result && (
<div>
<p>Optimal Tilt: {result.optimal_parameters.tilt}°</p>
<p>Annual Energy: {result.energy_metrics.annual_energy_mwh.toLocaleString()} MWh</p>
</div>
)}
</div>
);
}
Error Handling¶
async function safeOptimize(client, latitude, longitude, capacityKw) {
try {
const result = await client.quickOptimize(latitude, longitude, capacityKw);
return { success: true, data: result };
} catch (error) {
if (error.response) {
// Server responded with error
return {
success: false,
error: error.response.data.message || 'Server error',
status: error.response.status,
};
} else if (error.request) {
// No response received
return {
success: false,
error: 'Network error - no response received',
};
} else {
// Request setup error
return {
success: false,
error: error.message,
};
}
}
}