feat: add Agrarmonitor integration module
- New backend module (agrarmonitor) with status check and device registration - Frontend settings tab with connection status display and registration form - Environment variables for base URLs, credentials, cookie path and encryption key - Docker Compose env passthrough for agrarmonitor config Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import {
|
||||
createAgrarmonitorClient,
|
||||
FileCookieStore,
|
||||
AesGcmCookieEncryptor,
|
||||
type AgrarmonitorConnectorResult,
|
||||
} from 'agrarmonitor-connector';
|
||||
|
||||
export interface AgrarmonitorStatusDto {
|
||||
connected: boolean;
|
||||
registriert: boolean | null;
|
||||
freigeschaltet: boolean | null;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface AgrarmonitorRegisterResultDto {
|
||||
success: boolean;
|
||||
message: string;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class AgrarmonitorService {
|
||||
private readonly logger = new Logger(AgrarmonitorService.name);
|
||||
private client: AgrarmonitorConnectorResult | null = null;
|
||||
|
||||
constructor(private readonly configService: ConfigService) {}
|
||||
|
||||
async getClient(): Promise<AgrarmonitorConnectorResult> {
|
||||
if (this.client) return this.client;
|
||||
|
||||
const username = this.configService.get<string>('AGRARMONITOR_USERNAME', '');
|
||||
const password = this.configService.get<string>('AGRARMONITOR_PASSWORD', '');
|
||||
const baseUrl = this.configService.get<string>('AGRARMONITOR_BASE_URL', 'https://admin7.agrarmonitor.de');
|
||||
const apiBaseUrl = this.configService.get<string>('AGRARMONITOR_API_BASE_URL', 'https://api.agrarmonitor.de');
|
||||
const apiToken = this.configService.get<string>('AGRARMONITOR_API_TOKEN');
|
||||
const cookiePath = this.configService.get<string>('AGRARMONITOR_COOKIE_PATH', './data/agrarmonitor-cookies.json');
|
||||
const encryptionKey = this.configService.get<string>('AGRARMONITOR_ENCRYPTION_KEY');
|
||||
|
||||
const encryptor = encryptionKey ? new AesGcmCookieEncryptor(encryptionKey) : undefined;
|
||||
const cookieStore = new FileCookieStore(cookiePath, { encryptor, logger: this.logger });
|
||||
|
||||
this.client = await createAgrarmonitorClient({
|
||||
baseUrl,
|
||||
apiBaseUrl,
|
||||
apiToken,
|
||||
username,
|
||||
password,
|
||||
cookieStore,
|
||||
autoLogin: true,
|
||||
autoRetry: true,
|
||||
logger: this.logger,
|
||||
});
|
||||
|
||||
return this.client;
|
||||
}
|
||||
|
||||
async getStatus(): Promise<AgrarmonitorStatusDto> {
|
||||
try {
|
||||
const client = await this.getClient();
|
||||
const [registrierungStatus, freigeschaltetStatus] = await Promise.all([
|
||||
client.checkRegistriert(),
|
||||
client.checkFreigeschaltet(),
|
||||
]);
|
||||
return {
|
||||
connected: true,
|
||||
registriert: registrierungStatus.registriert,
|
||||
freigeschaltet: freigeschaltetStatus.freigeschaltet,
|
||||
};
|
||||
} catch (err: any) {
|
||||
this.client = null;
|
||||
return {
|
||||
connected: false,
|
||||
registriert: null,
|
||||
freigeschaltet: null,
|
||||
error: err?.message ?? 'Verbindung fehlgeschlagen',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async registerDevice(pcName: string, agrarmonitorId: string): Promise<AgrarmonitorRegisterResultDto> {
|
||||
const client = await this.getClient();
|
||||
const result = await client.registerDevice({ agrarmonitorId, pcName });
|
||||
return { success: result.success, message: result.message };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user