Skip to content

Commit 8ce21a1

Browse files
committed
Final Polish: Real UI/UX, Notifications, Weather, Subsidy, Room DB, License & Readme
1 parent 051a10d commit 8ce21a1

9 files changed

Lines changed: 383 additions & 176 deletions

File tree

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 B. JASWANTH REDDY
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 27 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -1,158 +1,37 @@
1-
# 🌾 NuKropAI — Autonomous Agriculture AI Operating System
1+
# 🌾 NuKropAI - The Ultimate AI Operating System for Agriculture
22

3-
[![Build Status](https://img.shields.io/badge/Build-Passing-brightgreen.svg)](https://github.com/JACK-AI7/NuKropAI)
4-
[![Version](https://img.shields.io/badge/Version-v1.0.0-blue.svg)](https://github.com/JACK-AI7/NuKropAI)
5-
[![Kotlin](https://img.shields.io/badge/Kotlin-2.0.21-purple.svg)](https://kotlinlang.org/)
6-
[![Android SDK](https://img.shields.io/badge/TargetSDK-34%2F36-green.svg)](https://developer.android.com/studio)
7-
[![Backend](https://img.shields.io/badge/Node.js-v20%2B-darkgreen.svg)](https://nodejs.org/)
8-
[![Database](https://img.shields.io/badge/Supabase-Auth%20%26%20DB-emerald.svg)](https://supabase.com/)
9-
[![AI Engine](https://img.shields.io/badge/Groq%20LLM-Llama%203.3%20%2F%203.2-orange.svg)](https://groq.com/)
3+
NuKropAI is an advanced, fully-functional, real-time Agriculture OS built specifically for farmers. It leverages the latest AI technology, live government APIs, and hyperlocal weather data to provide an unmatched, 100% functional full-stack solution directly on mobile devices.
104

11-
**NuKropAI** is an enterprise-grade, full-stack smart agriculture operating system designed to empower farmers, agronomists, and agricultural enterprises with AI-driven vision diagnostics, real-time market data, telemetry, and automated crop management tools.
5+
Designed and Developed by **B. JASWANTH REDDY**.
126

137
---
148

15-
## 🚀 Key Modules & Features
9+
## 🚀 Core Features (100% Real-World Functional)
1610

17-
### 🌿 1. AI Crop Disease Scanner & Soil Health Analysis
18-
* **Groq Vision LLM Integration**: Multi-model fallback (`llama-3.2-11b-vision-preview`, `llama-3.2-90b-vision-preview`) for instant visual disease diagnosis on crop leaves and stems.
19-
* **Treatment & Product Matching**: Returns exact disease names, severity levels, confidence scores, and real brand-name Indian agricultural products (pesticides, fungicides) with precise dosages and purchase links.
20-
* **Soil Composition & NPK Estimator**: Evaluates soil texture, pH range, organic matter content, and NPK deficiency recommendations.
11+
- **AI Crop Doctor & Disease Scanner**: Uses Gemini Vision AI to analyze photos of crops/soil and instantly provides diagnosis, remedies, and treatment plans in your local language (Voice Text-to-Speech included).
12+
- **Live Mandi Prices & Autopilot**: Connects directly to government `api.data.gov.in` to fetch the absolute latest Mandi prices based on your GPS location. Includes AI trend analysis and price crash predictions.
13+
- **Background Market & Weather Alerts**: Utilizes Android WorkManager to monitor target prices in the background. If a price hike or rain is detected, a high-priority system notification is instantly sent.
14+
- **Hyperlocal Open-Meteo Weather**: No mock data. Gives you exact temperature, rain, wind, and humidity forecasts based on your exact latitude and longitude.
15+
- **AI Subsidy & Scheme Matcher**: Uses LLM intelligence to match your farm profile (State, Size, Crop) to the latest 2024 active PM-KISAN, PMFBY, and state-specific agricultural schemes.
16+
- **Cloud & Local Memory**: Powered by Supabase for authentication and Room Database for seamless, offline-first local memory saving.
17+
- **True Multilingual Support**: Change the language on the fly. The entire OS instantly translates to Hindi, Telugu, Tamil, Marathi, and English.
2118

22-
### 🔐 2. Enterprise Authentication & User Management
23-
* **Supabase Integration**: Auth engine backed by Supabase Kotlin SDK (`auth-kt`). Supports email/password authentication, persistent user sessions, metadata synchronization, and guest modes.
24-
* **Secure Profile & Data Security**: Full user profile customization with fallback metadata extraction.
19+
## 🛠 Tech Stack
2520

26-
### 📊 3. Live Mandi Market Intelligence & Price Ticker
27-
* **Real-time Government API Ingestion**: Direct integration with `data.gov.in` Mandi APIs featuring key rotation and failover mechanisms.
28-
* **Multi-language Support**: Instant translation support (English, Hindi, Telugu, Tamil, Marathi).
29-
* **Price Drop & Surge Alerts**: Automated background notifications via Android `WorkManager` for critical price spikes and severe localized weather events.
21+
- **Frontend**: Kotlin, Jetpack Compose (100% Declarative UI)
22+
- **Backend / Auth**: Supabase Auth (Magic Links, OAuth)
23+
- **Local Database**: Android Room DB (SQLite)
24+
- **AI Vision / Intelligence**: OpenRouter / Google Gemini Vision APIs
25+
- **Background Processing**: Android WorkManager & Coroutines
26+
- **Real-Time Data**: Open-Meteo API, Indian Government Open Data (Agmarknet)
3027

31-
### 🚜 4. Smart Tractor Autopilot & Telemetry Controls
32-
* **Autonomous Guidance Controls**: A-B line navigation mode, speed throttling, compass heading calculations, and coverage tracking.
33-
* **Edge Watchdog & Circuit Breaker**: Resilience layer for IoT telemetry streaming across Wi-Fi, GSM, and LoRa networks.
28+
## 🎨 UI/UX Philosophy
29+
NuKropAI embraces modern, premium aesthetics:
30+
- Glassmorphism & Soft Gradients
31+
- Dark-mode first design
32+
- Vibrant color coding for clear user guidance
33+
- Haptic micro-animations
3434

35-
### 💰 5. Agricultural Loan & Financial Planner
36-
* **Kisan Credit Card (KCC) Eligibility Calculator**: Computes scale of finance based on land acreage, crop type, and subsidized interest rates.
37-
* **PM-KISAN Scheme Tracker**: Financial breakdown for agricultural subsidies and crop insurance (PMFBY).
38-
39-
---
40-
41-
## 🏗 System Architecture
42-
43-
```mermaid
44-
graph TD
45-
A[Mobile Farmer App - Android Jetpack Compose] -->|Auth & User Sync| B[Supabase Backend Service]
46-
A -->|Vision Analysis & LLM Queries| C[Groq AI Inference Cloud]
47-
A -->|Live Rates & Failover| D[Gov Mandi API / Local Node.js Gateway]
48-
E[Web Management Portal - React + Vite] -->|Enterprise Dashboard| B
49-
F[Edge IoT Gateway / Telemetry] -->|Mqtt / GSM| D
50-
```
51-
52-
---
53-
54-
## 🛠 Tech Stack & Versions
55-
56-
| Layer | Component | Technologies & Versions |
57-
| :--- | :--- | :--- |
58-
| **Mobile App** | UI Framework | Android Jetpack Compose, Material 3, Kotlin 2.0.21 |
59-
| **Mobile App** | Architecture | MVVM, Coroutines, StateFlow, Room DB v2.6.1, KSP |
60-
| **Mobile App** | Vision & Camera | CameraX (v1.4.1), TensorFlow Lite (v2.16.1), Coil |
61-
| **Network & Auth**| Authentication | Supabase Kotlin Auth (`io.github.jan-tennert.supabase:auth-kt:3.1.4`) |
62-
| **Network & Auth**| REST & Async | OkHttp 4.12.0, Ktor Client Android, Serialization |
63-
| **Backend API** | Server & Middleware | Node.js v20, TypeScript, Fastify / Express, Redis |
64-
| **Web Dashboard** | Frontend | React 18, Vite, TypeScript, TailwindCSS |
65-
66-
---
67-
68-
## 📦 Project Directory Structure
69-
70-
```
71-
agriculture-ai-os/
72-
├── app/ # Android Native Jetpack Compose Application
73-
│ ├── src/main/java/com/example/
74-
│ │ ├── AuthViewModel.kt # Supabase Session & Auth Management
75-
│ │ ├── GeminiVisionService.kt # Groq Vision LLM API Pipeline
76-
│ │ ├── DiseaseScannerScreen.kt # CameraX AI Scanning UI
77-
│ │ ├── HomeScreen.kt # Primary Farmer Operating Dashboard
78-
│ │ ├── MandiApiService.kt # Live Market Rates & Key Rotation
79-
│ │ ├── SupabaseClient.kt # Supabase Client Initializer
80-
│ │ └── ...
81-
│ └── build.gradle.kts
82-
├── backend/ # Node.js TypeScript API Gateway & Telemetry Service
83-
│ ├── src/
84-
│ ├── docker-compose.yml
85-
│ └── package.json
86-
├── web/ # React + Vite Enterprise Web Portal
87-
│ ├── src/
88-
│ └── package.json
89-
├── build.gradle.kts # Root Project Gradle Configuration
90-
├── settings.gradle.kts
91-
└── README.md
92-
```
93-
94-
---
95-
96-
## ⚙️ Setup & Building Instructions
97-
98-
### 📱 Android Application (Mobile)
99-
100-
#### Prerequisites:
101-
* **JDK**: OpenJDK 17 or Android Studio Bundled JBR
102-
* **Android Studio**: Ladybug / Koala or newer (SDK 34+)
103-
104-
#### Steps:
105-
1. **Clone the repository**:
106-
```bash
107-
git clone https://github.com/JACK-AI7/NuKropAI.git
108-
cd NuKropAI
109-
```
110-
2. **Build Release APK**:
111-
```bash
112-
./gradlew assembleRelease --no-daemon
113-
```
114-
3. The generated release APK will be located at:
115-
`app/build/outputs/apk/release/app-release.apk`
116-
117-
---
118-
119-
### 🖥️ Backend Service (Node.js)
120-
121-
1. **Navigate to the backend directory**:
122-
```bash
123-
cd backend
124-
```
125-
2. **Install dependencies**:
126-
```bash
127-
npm install
128-
```
129-
3. **Start Development Server**:
130-
```bash
131-
npm run dev
132-
```
133-
134-
---
135-
136-
### 🌐 Web Dashboard (React + Vite)
137-
138-
1. **Navigate to the web directory**:
139-
```bash
140-
cd web
141-
```
142-
2. **Install dependencies**:
143-
```bash
144-
npm install
145-
```
146-
3. **Launch Dev Server**:
147-
```bash
148-
npm run dev
149-
```
150-
151-
---
152-
153-
## 📄 License & Release Notes
154-
155-
* **Version**: `1.0.0`
156-
* **Release Date**: August 2026
157-
* **Maintainer**: NuKropAI Core Engineering Team
158-
* **License**: MIT License
35+
## 📜 License
36+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
37+
**Copyright (c) 2024 B. JASWANTH REDDY**

app/src/main/java/com/example/DiseaseScannerScreen.kt

Lines changed: 125 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ import dev.jeziellago.compose.markdowntext.MarkdownText
3737
import kotlinx.coroutines.launch
3838
import org.json.JSONObject
3939
import java.io.File
40+
import android.os.Environment
41+
import android.content.ContentValues
42+
import android.provider.MediaStore
43+
import android.widget.Toast
44+
import androidx.compose.material.icons.Icons
45+
import androidx.compose.material.icons.automirrored.filled.ArrowBack
46+
import androidx.compose.material.icons.filled.Download
4047

4148
enum class ScanMode { CROP, SOIL }
4249

@@ -300,19 +307,19 @@ fun CameraScanner(modifier: Modifier, scanMode: ScanMode, onBack: () -> Unit) {
300307
Modifier.fillMaxWidth().background(Color(0xDD0D1208)).statusBarsPadding().padding(4.dp),
301308
verticalAlignment = Alignment.CenterVertically
302309
) {
303-
IconButton(onBack) { Text("←", fontSize = 22.sp, color = NuKropText) }
310+
IconButton(onBack) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back", tint = NuKropText) }
304311
Column {
305312
Text(if (scanMode == ScanMode.CROP) "Crop Disease & Pest Scan" else "Soil Health Analysis",
306313
fontSize = 15.sp, fontWeight = FontWeight.Bold, color = NuKropText)
307-
Text("Powered by OpenRouter Vision AI", fontSize = 10.sp, color = accent)
314+
Text("Powered by NuKrop Vision AI", fontSize = 10.sp, color = accent)
308315
}
309316
}
310317

311318
// Center hint
312319
Box(Modifier.align(Alignment.BottomCenter).padding(bottom = 230.dp)) {
313320
Box(Modifier.clip(RoundedCornerShape(20.dp)).background(Color(0xBB0D1208)).padding(horizontal = 16.dp, vertical = 8.dp)) {
314321
Text(
315-
if (scanning) "🔬 Analyzing with OpenRouter AI..."
322+
if (scanning) "🔬 Analyzing with NuKrop AI..."
316323
else if (scanMode == ScanMode.CROP) "📍 Point at crop leaves / stem / fruit"
317324
else "📍 Point at soil sample clearly",
318325
fontSize = 13.sp, color = if (scanning) accent else NuKropTextMuted
@@ -412,10 +419,10 @@ fun ScanResultView(modifier: Modifier, raw: String, mode: ScanMode, accent: Colo
412419
Column(modifier.fillMaxSize().background(NuKropDark).verticalScroll(scroll)) {
413420
// Header
414421
Row(Modifier.fillMaxWidth().background(NuKropSurface).statusBarsPadding().padding(8.dp), verticalAlignment = Alignment.CenterVertically) {
415-
IconButton(onBack) { Text("←", fontSize = 22.sp, color = NuKropText) }
422+
IconButton(onBack) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back", tint = NuKropText) }
416423
Column {
417424
Text("AI Analysis Complete", fontSize = 16.sp, fontWeight = FontWeight.Bold, color = NuKropText)
418-
Text("Results powered by OpenRouter Vision", fontSize = 10.sp, color = NuKropTextMuted)
425+
Text("Results powered by NuKrop Vision AI", fontSize = 10.sp, color = NuKropTextMuted)
419426
}
420427
}
421428

@@ -433,15 +440,121 @@ fun ScanResultView(modifier: Modifier, raw: String, mode: ScanMode, accent: Colo
433440
else RawResultFallback(raw)
434441
}
435442

436-
Spacer(Modifier.height(16.dp))
437-
Row(Modifier.fillMaxWidth().padding(16.dp), Arrangement.spacedBy(12.dp)) {
438-
OutlinedButton(onBack, Modifier.weight(1f).height(50.dp), shape = RoundedCornerShape(25.dp),
439-
border = BorderStroke(1.dp, NuKropTextDim)) { Text("← Back", color = NuKropTextMuted) }
440-
Button(onRescan, Modifier.weight(1f).height(50.dp), shape = RoundedCornerShape(25.dp),
441-
colors = ButtonDefaults.buttonColors(containerColor = accent)) {
442-
Text("Scan Again", color = NuKropDark, fontWeight = FontWeight.Bold)
443+
Spacer(Modifier.height(8.dp))
444+
Column(Modifier.fillMaxWidth().padding(16.dp), verticalArrangement = Arrangement.spacedBy(12.dp)) {
445+
Button(
446+
onClick = { saveReportToDownloads(context, raw) },
447+
modifier = Modifier.fillMaxWidth().height(50.dp),
448+
shape = RoundedCornerShape(25.dp),
449+
colors = ButtonDefaults.buttonColors(containerColor = NuKropCard)
450+
) {
451+
Icon(Icons.Filled.Download, contentDescription = "Save", tint = accent, modifier = Modifier.size(20.dp))
452+
Spacer(Modifier.width(8.dp))
453+
Text("Save to Mobile", color = accent, fontWeight = FontWeight.Bold)
454+
}
455+
456+
Row(Modifier.fillMaxWidth(), Arrangement.spacedBy(12.dp)) {
457+
OutlinedButton(onBack, Modifier.weight(1f).height(50.dp), shape = RoundedCornerShape(25.dp),
458+
border = BorderStroke(1.dp, NuKropTextDim)) {
459+
Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back", tint = NuKropTextMuted, modifier = Modifier.size(18.dp))
460+
Spacer(Modifier.width(6.dp))
461+
Text("Back", color = NuKropTextMuted)
462+
}
463+
Button(onRescan, Modifier.weight(1f).height(50.dp), shape = RoundedCornerShape(25.dp),
464+
colors = ButtonDefaults.buttonColors(containerColor = accent)) {
465+
Text("Scan Again", color = NuKropDark, fontWeight = FontWeight.Bold)
466+
}
467+
}
468+
}
469+
}
470+
}
471+
472+
fun saveReportToDownloads(context: android.content.Context, content: String) {
473+
try {
474+
// Format the raw JSON into a readable text report
475+
val formattedContent = runCatching {
476+
val d = parseCropJson(content)
477+
if (d != null) {
478+
"""
479+
NuKropAI Scan Report
480+
====================
481+
Status: ${d.status}
482+
Diagnosis: ${d.name}
483+
Confidence: ${d.confidence}%
484+
Severity: ${d.severity}
485+
486+
SYMPTOMS
487+
--------
488+
${d.symptoms}
489+
490+
CAUSE
491+
-----
492+
${d.cause}
493+
494+
TREATMENT PLAN
495+
--------------
496+
${d.treatment}
497+
498+
PREVENTION
499+
----------
500+
${d.prevention}
501+
502+
PRODUCTS RECOMMENDED
503+
--------------------
504+
${d.products.joinToString("\n") { (info, stores) ->
505+
"- ${info.first} (Dose: ${info.second})\n Buy: ${stores.firstOrNull()?.url ?: "Search locally"}"
506+
}}
507+
""".trimIndent()
508+
} else {
509+
val s = parseSoilJson(content)
510+
if (s != null) {
511+
"""
512+
NuKropAI Soil Report
513+
====================
514+
Soil Type: ${s.soilType}
515+
Est. pH: ${s.estimatedPH}
516+
Texture: ${s.texture}
517+
Organic Matter: ${s.organicMatter}
518+
519+
DEFICIENCIES
520+
------------
521+
${s.deficiencies.joinToString(", ")}
522+
523+
IMPROVEMENTS
524+
------------
525+
${s.improvements}
526+
527+
SUITABLE CROPS
528+
--------------
529+
${s.suitableCrops.joinToString(", ")}
530+
531+
FERTILIZERS
532+
-----------
533+
${s.fertilizers.joinToString("\n") { (info, stores) ->
534+
"- ${info.first} (Dose: ${info.second})\n Buy: ${stores.firstOrNull()?.url ?: "Search locally"}"
535+
}}
536+
""".trimIndent()
537+
} else content
538+
}
539+
}.getOrDefault(content)
540+
541+
val resolver = context.contentResolver
542+
val contentValues = ContentValues().apply {
543+
put(MediaStore.MediaColumns.DISPLAY_NAME, "NuKropAI_Report_${System.currentTimeMillis()}.txt")
544+
put(MediaStore.MediaColumns.MIME_TYPE, "text/plain")
545+
put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS)
546+
}
547+
val uri = resolver.insert(MediaStore.Files.getContentUri("external"), contentValues)
548+
if (uri != null) {
549+
resolver.openOutputStream(uri)?.use { os ->
550+
os.write(formattedContent.toByteArray())
443551
}
552+
Toast.makeText(context, "Saved to Downloads!", Toast.LENGTH_SHORT).show()
553+
} else {
554+
Toast.makeText(context, "Failed to save file", Toast.LENGTH_SHORT).show()
444555
}
556+
} catch (e: Exception) {
557+
Toast.makeText(context, "Error: ${e.message}", Toast.LENGTH_SHORT).show()
445558
}
446559
}
447560

0 commit comments

Comments
 (0)