Repository navigation
Expand file tree
/
Copy pathserver.js
More file actions
271 lines (229 loc) · 11.2 KB
/
Copy pathserver.js
File metadata and controls
271 lines (229 loc) · 11.2 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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
const express = require('express');
const cors = require('cors');
const path = require('path');
const OpenAI = require('openai');
require('dotenv').config();
const app = express();
const PORT = process.env.PORT || 3000;
// Initialize OpenAI
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
// Middleware
app.use(cors());
app.use(express.json());
app.use(express.static('.'));
// Weather data context for AI
const weatherContext = {
regions: [
{
name: "Jakarta",
areas: ["Jakarta Pusat", "Jakarta Utara", "Jakarta Selatan", "Jakarta Timur", "Jakarta Barat"],
description: "Ibu kota Indonesia dengan iklim tropis"
},
{
name: "Bogor",
areas: ["Bogor"],
description: "Kota hujan dengan suhu lebih sejuk"
},
{
name: "Bekasi",
areas: ["Bekasi"],
description: "Kota industri dengan cuaca hangat"
},
{
name: "Depok",
areas: ["Depok"],
description: "Kota satelit dengan kelembaban tinggi"
},
{
name: "Tangerang",
areas: ["Tangerang", "Tangerang Selatan"],
description: "Kota industri dengan cuaca bervariasi"
}
],
weatherTypes: {
"cerah": "Cuaca cerah dengan sinar matahari penuh",
"berawan": "Cuaca berawan dengan awan menutupi sebagian langit",
"hujan_ringan": "Hujan ringan dengan intensitas rendah",
"hujan_lebat": "Hujan lebat dengan intensitas tinggi"
}
};
// API endpoint for chat
app.post('/api/chat', async (req, res) => {
try {
const { message, weatherData } = req.body;
if (!message) {
return res.status(400).json({ error: 'Message is required' });
}
// Check if OpenAI API key is available and not exceeded quota
if (!process.env.OPENAI_API_KEY || process.env.OPENAI_API_KEY === 'your_openai_api_key_here') {
// Demo mode - provide intelligent responses based on weather data
const demoResponse = generateDemoResponse(message, weatherData);
return res.json({ response: demoResponse });
}
// Create weather context string
let weatherContextString = "Data cuaca terkini untuk wilayah Jakarta dan sekitarnya:\n\n";
if (weatherData && weatherData.features) {
weatherData.features.forEach(feature => {
const props = feature.properties;
weatherContextString += `${props.name} (${props.city}):\n`;
weatherContextString += `- Suhu: ${props.temperature}°C\n`;
weatherContextString += `- Kelembaban: ${props.humidity}%\n`;
weatherContextString += `- Cuaca: ${props.description}\n`;
weatherContextString += `- Kecepatan Angin: ${props.wind_speed} km/h\n`;
weatherContextString += `- Tekanan: ${props.pressure} hPa\n\n`;
});
}
// Create system prompt
const systemPrompt = `Anda adalah AI Weather Assistant yang ahli dalam memberikan informasi cuaca untuk wilayah Jakarta, Bogor, Bekasi, Depok, dan Tangerang.
Konteks wilayah:
${weatherContext.regions.map(region =>
`- ${region.name}: ${region.description}`
).join('\n')}
Jenis cuaca yang tersedia:
${Object.entries(weatherContext.weatherTypes).map(([key, value]) =>
`- ${key}: ${value}`
).join('\n')}
Gunakan data cuaca terkini yang disediakan untuk menjawab pertanyaan pengguna. Berikan jawaban yang informatif, akurat, dan mudah dipahami dalam bahasa Indonesia. Jika pengguna bertanya tentang prediksi cuaca, berikan saran berdasarkan pola cuaca saat ini.
Data cuaca terkini:
${weatherContextString}
Jawab pertanyaan pengguna dengan ramah dan informatif.`;
// Get response from OpenAI
const completion = await openai.chat.completions.create({
model: "gpt-3.5-turbo",
messages: [
{
role: "system",
content: systemPrompt
},
{
role: "user",
content: message
}
],
max_tokens: 500,
temperature: 0.7,
});
const aiResponse = completion.choices[0].message.content;
res.json({ response: aiResponse });
} catch (error) {
console.error('Error in chat API:', error);
// Fallback to demo mode if OpenAI API fails
const { message, weatherData } = req.body;
const demoResponse = generateDemoResponse(message, weatherData);
res.json({ response: demoResponse });
}
});
// Demo response generator for when OpenAI API is not available
function generateDemoResponse(message, weatherData) {
const lowerMessage = message.toLowerCase();
// Extract city names from message
const cities = ['jakarta', 'bogor', 'bekasi', 'depok', 'tangerang'];
const mentionedCity = cities.find(city => lowerMessage.includes(city));
// Find weather data for mentioned city
let cityWeather = null;
if (mentionedCity && weatherData && weatherData.features) {
cityWeather = weatherData.features.find(feature =>
feature.properties.city.toLowerCase() === mentionedCity
);
}
// Generate responses based on message content
if (lowerMessage.includes('cuaca') && lowerMessage.includes('jakarta')) {
if (cityWeather) {
return `Berdasarkan data terkini, cuaca di ${cityWeather.properties.name} saat ini adalah ${cityWeather.properties.description} dengan suhu ${cityWeather.properties.temperature}°C. Kelembaban mencapai ${cityWeather.properties.humidity}% dan kecepatan angin ${cityWeather.properties.wind_speed} km/h.`;
}
return "Cuaca di Jakarta saat ini bervariasi di setiap wilayah. Jakarta Timur cenderung cerah dengan suhu tinggi, sementara Jakarta Utara dan Selatan mengalami hujan ringan. Silakan klik area di peta untuk melihat detail cuaca di wilayah tertentu.";
}
if (lowerMessage.includes('hujan') && lowerMessage.includes('bogor')) {
return "Bogor memang dikenal sebagai 'Kota Hujan' dan saat ini sedang mengalami hujan ringan dengan suhu yang lebih sejuk (28°C) dibandingkan Jakarta. Kelembaban di Bogor cukup tinggi mencapai 85%.";
}
if (lowerMessage.includes('suhu') && lowerMessage.includes('bekasi')) {
if (cityWeather) {
return `Suhu di Bekasi saat ini adalah ${cityWeather.properties.temperature}°C dengan kondisi cuaca ${cityWeather.properties.description}. Kelembaban ${cityWeather.properties.humidity}% dan tekanan udara ${cityWeather.properties.pressure} hPa.`;
}
return "Suhu di Bekasi saat ini sekitar 32°C dengan kondisi berawan. Bekasi memiliki cuaca yang hangat karena merupakan kota industri.";
}
if (lowerMessage.includes('prediksi') || lowerMessage.includes('besok')) {
return "Berdasarkan pola cuaca saat ini, prediksi untuk besok kemungkinan akan tetap bervariasi. Jakarta Timur mungkin tetap cerah, sementara wilayah lain berpotensi mengalami hujan ringan hingga sedang. Bogor dan Depok cenderung lebih lembab dengan kemungkinan hujan.";
}
if (lowerMessage.includes('mana') && lowerMessage.includes('panas')) {
return "Berdasarkan data saat ini, Jakarta Timur memiliki suhu tertinggi (33°C) dengan kondisi cerah. Diikuti oleh Bekasi (32°C) dan Jakarta Pusat (32°C). Bogor memiliki suhu terendah (28°C) karena lokasinya yang lebih tinggi dan sering hujan.";
}
if (lowerMessage.includes('kelembaban')) {
return "Tingkat kelembaban di wilayah Jakarta dan sekitarnya saat ini berkisar antara 70-85%. Bogor memiliki kelembaban tertinggi (85%) karena sering hujan, sementara Jakarta Timur memiliki kelembaban terendah (70%) karena cuaca cerah.";
}
if (lowerMessage.includes('angin')) {
return "Kecepatan angin di wilayah Jakarta dan sekitarnya saat ini berkisar antara 7-15 km/h. Jakarta Utara memiliki angin terkuat (15 km/h), sementara Depok memiliki angin paling lemah (7 km/h).";
}
// Default response
return "Saya dapat membantu Anda dengan informasi cuaca untuk wilayah Jakarta, Bogor, Bekasi, Depok, dan Tangerang. Silakan tanyakan tentang suhu, kelembaban, kondisi cuaca, atau prediksi cuaca untuk wilayah tertentu. Anda juga dapat melihat peta cuaca interaktif di sebelah kiri untuk informasi visual.";
}
// API endpoint to get weather data for specific city
app.get('/api/weather/:city', (req, res) => {
try {
const fs = require('fs');
const city = req.params.city;
const weatherData = JSON.parse(fs.readFileSync(`data/${city}.geojson`, 'utf8'));
res.json(weatherData);
} catch (error) {
console.error(`Error loading weather data for ${req.params.city}:`, error);
res.status(500).json({ error: 'Failed to load weather data' });
}
});
// API endpoint to get all weather data
app.get('/api/weather', (req, res) => {
try {
const fs = require('fs');
const cities = ['jakarta', 'bogor', 'bekasi', 'depok', 'tangerang'];
const allFeatures = [];
cities.forEach(city => {
try {
const cityData = JSON.parse(fs.readFileSync(`data/${city}.geojson`, 'utf8'));
allFeatures.push(...cityData.features);
} catch (error) {
console.error(`Error loading ${city}.geojson:`, error);
}
});
const combinedData = {
type: "FeatureCollection",
features: allFeatures
};
res.json(combinedData);
} catch (error) {
console.error('Error loading weather data:', error);
res.status(500).json({ error: 'Failed to load weather data' });
}
});
// Health check endpoint
app.get('/api/health', (req, res) => {
res.json({
status: 'OK',
timestamp: new Date().toISOString(),
service: 'AI Weather Agent'
});
});
// Serve the main page
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'index.html'));
});
// Error handling middleware
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Something went wrong!' });
});
// Start server
app.listen(PORT, () => {
console.log(`AI Weather Agent server running on port ${PORT}`);
console.log(`Open http://localhost:${PORT} to view the application`);
// Check if OpenAI API key is configured
if (!process.env.OPENAI_API_KEY || process.env.OPENAI_API_KEY === 'your_openai_api_key_here') {
console.log('🔧 Running in DEMO MODE - No OpenAI API key required');
console.log(' The chatbot will provide intelligent responses based on weather data');
console.log(' To use OpenAI API, create a .env file with:');
console.log(' OPENAI_API_KEY=your_actual_api_key_here');
} else {
console.log('✅ OpenAI API key configured');
}
});
module.exports = app;