Zum Inhalt

🏠 Real Estate CRM - Umfassendes Integrationskonzept

Deep Research Ergebnis | Stand: 30. Dezember 2025


πŸ“‹ Executive Summary

Dieses Dokument beschreibt ein modulares Real Estate CRM-System mit intelligenten Bridges zu verschiedenen Drittanbieter-Diensten fΓΌr Buchhaltung, Marketing, IdentitΓ€tsprΓΌfung, Finanzierung, IoT und Smart Building Management.


πŸ—οΈ Systemarchitektur

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         REAL ESTATE CRM CORE                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚  β”‚  Objekte    β”‚ β”‚  Kontakte   β”‚ β”‚  Termine    β”‚ β”‚  Dokumente          β”‚β”‚
β”‚  β”‚  Management β”‚ β”‚  & Leads    β”‚ β”‚  & Events   β”‚ β”‚  & ExposΓ©s          β”‚β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚                          β”‚                          β”‚
         β–Ό                          β–Ό                          β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   BRIDGE LAYER  β”‚    β”‚   BRIDGE LAYER      β”‚    β”‚   BRIDGE LAYER      β”‚
β”‚   Buchhaltung   β”‚    β”‚   Marketing         β”‚    β”‚   Kommunikation     β”‚
β”‚   ─────────────│    β”‚   ─────────────────│    β”‚   ─────────────────│
β”‚   β€’ sevdesk    β”‚    β”‚   β€’ Adobe Express   β”‚    β”‚   β€’ MS Graph        β”‚
β”‚   β€’ Fintech    β”‚    β”‚   β€’ Adobe Lightroom β”‚    β”‚   β€’ Apple Invites   β”‚
β”‚                 β”‚    β”‚   β€’ plano.so        β”‚    β”‚   β€’ E-Mail/Kalender β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                          β”‚                          β”‚
         β–Ό                          β–Ό                          β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   BRIDGE LAYER  β”‚    β”‚   BRIDGE LAYER      β”‚    β”‚   BRIDGE LAYER      β”‚
β”‚   Finanzierung  β”‚    β”‚   IdentitΓ€t         β”‚    β”‚   IoT & Smart       β”‚
β”‚   ─────────────│    β”‚   ─────────────────│    β”‚   Building          β”‚
β”‚   β€’ Open Bankingβ”‚    β”‚   β€’ WebID Solutions β”‚    β”‚   ─────────────────│
β”‚   β€’ finAPI      β”‚    β”‚   β€’ SCHUFA B2B      β”‚    β”‚   β€’ ESP32 Sensoren  β”‚
β”‚   β€’ Targobank   β”‚    β”‚   β€’ KYC/AML         β”‚    β”‚   β€’ ista            β”‚
β”‚                 β”‚    β”‚                     β”‚    β”‚   β€’ Smart Meter     β”‚
β”‚                 β”‚    β”‚                     β”‚    β”‚   β€’ evcc (E-Mob)    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

1️⃣ sevdesk Integration (Buchhaltung)

API-Übersicht

Basis-URL: https://api.sevdesk.de/

VerfΓΌgbare Endpunkte

Endpunkt Beschreibung
/Contact Kontakte/Kunden verwalten
/Invoice Rechnungen erstellen/verwalten
/Voucher Belege erfassen
/AccountingType Buchungskategorien
/Document Dokumente hochladen

Use Cases fΓΌr Real Estate

interface SevdeskBridge {
  // Mieter als Kontakt anlegen
  createTenantContact(tenant: Tenant): Promise<SevdeskContact>;

  // Nebenkostenabrechnung erstellen
  createUtilityBillInvoice(property: Property, period: DateRange): Promise<Invoice>;

  // Mieteinnahmen buchen
  bookRentalIncome(payment: RentalPayment): Promise<Voucher>;

  // Maklerprovision abrechnen
  createCommissionInvoice(deal: PropertyDeal): Promise<Invoice>;

  // Dokumente synchronisieren
  syncDocuments(propertyId: string): Promise<Document[]>;
}

Authentifizierung

  • API-Token basiert
  • OAuth 2.0 fΓΌr erweiterte Integrationen
  • Rate Limiting beachten

Datenfluss

CRM Mietvertrag β†’ sevdesk Kontakt
CRM Zahlung β†’ sevdesk Buchung
CRM Nebenkosten β†’ sevdesk Rechnung
sevdesk Mahnwesen ← CRM Zahlungsstatus

2️⃣ Adobe Creative Cloud Integration

2.1 Adobe Express (Werbung & ExposΓ©)

Developer Portal: https://developer.adobe.com/express/

Features fΓΌr Real Estate

Feature Anwendung
Templates Vordefinierte ExposΓ©-Vorlagen
Brand Kit Makler-Branding konsistent
Quick Actions Bildbearbeitung automatisieren
Embed SDK Express im CRM einbetten

SDK Integration

// Adobe Express Embed SDK
import { CCEverywhere } from '@anthropic/cc-everywhere-sdk';

const ccEverywhere = await CCEverywhere.initialize({
  clientId: 'YOUR_CLIENT_ID',
  appName: 'RealEstate CRM',
  appVersion: '1.0.0',
  platformCategory: 'web'
});

// ExposΓ© erstellen
async function createPropertyExpose(property: Property) {
  const editor = await ccEverywhere.createDesign({
    templateType: 'flyer',
    templateId: 'real-estate-expose',
    outputType: 'PDF',
    callbacks: {
      onPublish: (result) => saveToPropertyDocs(property.id, result),
      onError: (error) => handleError(error)
    }
  });
}

ExposΓ©-Workflow

1. Objektdaten aus CRM laden
2. Bilder aus Lightroom abrufen
3. Express Template befΓΌllen
4. Automatische Layouts generieren
5. PDF/Web-Version exportieren
6. An Interessenten versenden

2.2 Adobe Lightroom (Media Assets)

API Dokumentation: https://developer.adobe.com/lightroom/lightroom-api-docs/

REST API Endpunkte

Endpunkt Funktion
GET /v2/catalogs Kataloge auflisten
GET /v2/catalogs/{id}/assets Assets abrufen
GET /v2/catalogs/{id}/albums Alben verwalten
POST /v2/catalogs/{id}/assets Assets hochladen

Integration Konzept

interface LightroomBridge {
  // Album pro Immobilie
  createPropertyAlbum(propertyId: string): Promise<Album>;

  // Bilder hochladen
  uploadPropertyImages(propertyId: string, images: File[]): Promise<Asset[]>;

  // Optimierte Renditions abrufen
  getOptimizedImages(propertyId: string, size: 'thumb' | 'web' | 'print'): Promise<string[]>;

  // Auto-Tagging fΓΌr Suche
  getAssetKeywords(assetId: string): Promise<string[]>;
}

Bildverwaltung Workflow

Fotograf β†’ Lightroom Upload β†’ Auto-Enhance
                    ↓
            AI-basierte Tags
                    ↓
          CRM Objektzuordnung
                    ↓
      ExposΓ© Generation (Express)

3️⃣ plano.so Integration (Grundrisse & Visualisierung)

Hinweis

plano.so scheint ein Grundriss/Floorplan-Tool zu sein. Genaue API-Dokumentation war nicht verfΓΌgbar.

Angenommene Integration

interface PlanoBridge {
  // Grundriss erstellen
  createFloorPlan(property: Property, measurements: Measurements): Promise<FloorPlan>;

  // 3D Visualisierung
  generate3DModel(floorPlanId: string): Promise<Model3D>;

  // Interaktive Tour
  createVirtualTour(propertyId: string): Promise<VirtualTourUrl>;

  // Export fΓΌr ExposΓ©
  exportFloorPlan(planId: string, format: 'svg' | 'pdf' | 'png'): Promise<Blob>;
}

Alternative Tools mit APIs

Tool API Funktion
Matterport REST API 3D-Scans, Virtual Tours
Floorplanner SDK Interaktive Grundrisse
RoomSketcher Export API 2D/3D Grundrisse
Cedreo Embed Home Design

4️⃣ Microsoft Graph Integration

API-Übersicht

Basis-URL: https://graph.microsoft.com/v1.0/

Relevante Endpunkte fΓΌr CRM

Endpunkt Funktion Real Estate Use Case
/me/calendar/events Kalender Besichtigungstermine
/me/messages E-Mail Kundenkommunikation
/me/contacts Kontakte Interessenten sync
/me/drive OneDrive Dokumentenablage
/users User Management Team-Koordination
/groups Teams/Gruppen Projektteams

Authentication Flow

import { Client } from '@microsoft/microsoft-graph-client';
import { TokenCredentialAuthenticationProvider } from '@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials';

// Azure AD App Registration erforderlich
const graphClient = Client.initWithMiddleware({
  authProvider: new TokenCredentialAuthenticationProvider(credential, {
    scopes: [
      'Calendars.ReadWrite',
      'Mail.Send',
      'Contacts.ReadWrite',
      'Files.ReadWrite.All'
    ]
  })
});

CRM Integration Beispiele

interface MSGraphBridge {
  // Besichtigungstermin erstellen
  async createViewingAppointment(viewing: PropertyViewing): Promise<Event> {
    return await graphClient.api('/me/calendar/events').post({
      subject: `Besichtigung: ${viewing.property.address}`,
      start: { dateTime: viewing.startTime, timeZone: 'Europe/Berlin' },
      end: { dateTime: viewing.endTime, timeZone: 'Europe/Berlin' },
      location: { displayName: viewing.property.address },
      attendees: viewing.attendees.map(a => ({
        emailAddress: { address: a.email, name: a.name },
        type: 'required'
      })),
      body: {
        contentType: 'HTML',
        content: generateViewingEmailBody(viewing)
      }
    });
  }

  // ExposΓ© per Mail versenden
  async sendExpose(recipient: Contact, expose: Document): Promise<void> {
    await graphClient.api('/me/sendMail').post({
      message: {
        subject: `ExposΓ©: ${expose.propertyTitle}`,
        body: { contentType: 'HTML', content: expose.emailBody },
        toRecipients: [{ emailAddress: { address: recipient.email } }],
        attachments: [{
          '@odata.type': '#microsoft.graph.fileAttachment',
          name: `${expose.propertyTitle}.pdf`,
          contentBytes: expose.pdfBase64
        }]
      }
    });
  }

  // Kontakte synchronisieren
  async syncContacts(crmContacts: CRMContact[]): Promise<void> {
    for (const contact of crmContacts) {
      await graphClient.api('/me/contacts').post({
        givenName: contact.firstName,
        surname: contact.lastName,
        emailAddresses: [{ address: contact.email }],
        businessPhones: [contact.phone],
        categories: ['CRM', contact.type] // 'Interessent', 'Mieter', etc.
      });
    }
  }
}

5️⃣ Apple Invites (Open House Veranstaltungen)

iOS EventKit Framework

Dokumentation: https://developer.apple.com/documentation/eventkit

Limitierungen

⚠️ Wichtig: Apple Invites ist primÀr eine iOS-native App ohne âffentliche REST API. Integration erfolgt über:

  1. EventKit (iOS/macOS native) - Lokale Kalender-Events
  2. CalDAV Protocol - iCloud Kalender-Sync
  3. iCal (.ics) Files - Universelle Einladungen

Empfohlene LΓΆsung: Hybrid-Ansatz

// Serverseitig: iCal Generation
import ical from 'ical-generator';

function createOpenHouseInvite(event: OpenHouseEvent): string {
  const cal = ical({
    prodId: '//RealEstate CRM//Open House//DE',
    name: 'Open House Einladung'
  });

  cal.createEvent({
    start: event.startTime,
    end: event.endTime,
    summary: `Open House: ${event.property.address}`,
    description: event.description,
    location: event.property.fullAddress,
    url: event.registrationUrl,
    organizer: {
      name: event.agent.name,
      email: event.agent.email
    },
    alarms: [
      { type: 'display', trigger: 3600 }, // 1h vorher
      { type: 'display', trigger: 86400 } // 1 Tag vorher
    ]
  });

  return cal.toString();
}

Mobile App Integration

// iOS App Component
import EventKit

class OpenHouseManager {
    let eventStore = EKEventStore()

    func createOpenHouseEvent(property: Property, date: Date) async throws -> EKEvent {
        // Berechtigung anfordern
        try await eventStore.requestAccess(to: .event)

        let event = EKEvent(eventStore: eventStore)
        event.title = "Open House: \(property.address)"
        event.startDate = date
        event.endDate = date.addingTimeInterval(7200) // 2 Stunden
        event.location = property.fullAddress
        event.notes = property.description
        event.calendar = eventStore.defaultCalendarForNewEvents

        // Teilnehmer hinzufΓΌgen
        event.attendees = property.interestedContacts.map { contact in
            EKParticipant() // Simplified
        }

        try eventStore.save(event, span: .thisEvent)
        return event
    }
}

6️⃣ BonitΓ€tsprΓΌfung & Vorfinanzierung (FinTech)

6.1 finAPI (Open Banking)

Portal: https://www.finapi.io/

Produkte

Produkt Funktion Real Estate Anwendung
Open Banking API Kontozugriff (PSD2) Einkommensnachweis
Data Intelligence Finanzanalyse BonitΓ€tsbewertung
Payment API ZahlungsauslΓΆsung Mietkautionszahlung
GiroIdent (KYC) IdentitΓ€tsprΓΌfung GwG-konforme Verifizierung

Integration

interface FinAPIBridge {
  // BonitΓ€tsprΓΌfung starten
  async initiateCreditCheck(tenant: TenantApplication): Promise<CreditCheckSession> {
    // 1. Bank-Login Widget anzeigen
    const bankConnection = await finapi.connectBank({
      bankId: tenant.selectedBankId,
      callbackUrl: `${API_URL}/finapi/callback`
    });

    // 2. Transaktionsanalyse
    const analysis = await finapi.analyzeTransactions({
      connectionId: bankConnection.id,
      period: '6_MONTHS',
      categories: ['SALARY', 'RENT', 'RECURRING']
    });

    // 3. BonitΓ€tsscore berechnen
    return {
      score: analysis.creditScore,
      monthlyIncome: analysis.averageIncome,
      rentAffordability: analysis.averageIncome * 0.35, // 35% Regel
      riskLevel: analysis.riskAssessment
    };
  }

  // Mietkaution via Überweisung
  async processDeposit(deposit: DepositPayment): Promise<PaymentResult> {
    return await finapi.initiatePayment({
      amount: deposit.amount,
      purpose: `Mietkaution ${deposit.propertyId}`,
      recipientIban: deposit.landlordIban,
      recipientName: deposit.landlordName
    });
  }
}

6.2 Open Banking (PSD2/Berlin Group)

Standard: Berlin Group NextGenPSD2

API Aggregatoren fΓΌr Targobank

Aggregator Abdeckung Features
Plaid EU-weit Transaktionsanalyse
TrueLayer UK/EU Payment Initiation
Salt Edge 50+ LΓ€nder Account Information
Nordigen (GoCardless) EU Kostenlos fΓΌr AIS
YAXI DACH Lokale Banken

Targobank-spezifisch

// Via Aggregator (z.B. Plaid)
const bankAccess = await plaid.createLinkToken({
  user: { client_user_id: tenant.id },
  products: ['transactions', 'identity'],
  country_codes: ['DE'],
  language: 'de',
  institution_ids: ['ins_targobank'] // Targobank ID
});

7️⃣ WebID Solutions (IdentitΓ€tsprΓΌfung)

VerfΓΌgbare Produkte

Produkt Methode GwG-konform Use Case
VideoID (Live) Video-Chat mit Agent βœ… Premium-Verifizierung
VideoID (Review) KI + Agent Review βœ… Skalierbare LΓΆsung
AutoID KI-basiert (Selfie+ID) βœ…* Self-Service
AccountID Online-Banking Transaktion βœ… Schnelle Verifizierung
eID Personalausweis NFC-Chip βœ… Deutsche Ausweise
TrueID Wiederverwendbare IdentitΓ€t βœ… Stammkunden
SignID QES Qualifizierte Signatur βœ… Vertragsunterzeichnung
CorporateID Unternehmensidentifikation βœ… Gewerbliche Mieter

*je nach Konfiguration

Integration Workflow

interface WebIDBridge {
  // IdentitΓ€tsprΓΌfung initiieren
  async startIdentification(person: Person, method: WebIDMethod): Promise<IdentSession> {
    const session = await webid.createSession({
      method: method, // 'VideoID' | 'AutoID' | 'AccountID' | 'eID'
      person: {
        firstName: person.firstName,
        lastName: person.lastName,
        dateOfBirth: person.dob,
        nationality: person.nationality
      },
      callbackUrl: `${API_URL}/webid/callback/${person.id}`,
      redirectUrl: `${APP_URL}/verification/complete`
    });

    return {
      sessionId: session.id,
      widgetUrl: session.identificationUrl,
      expiresAt: session.expiresAt
    };
  }

  // Ergebnis verarbeiten
  async handleCallback(sessionId: string): Promise<IdentificationResult> {
    const result = await webid.getResult(sessionId);

    return {
      verified: result.status === 'SUCCESS',
      identData: {
        fullName: result.person.fullName,
        dateOfBirth: result.person.dateOfBirth,
        address: result.person.address,
        documentNumber: result.document.number,
        documentExpiry: result.document.expiryDate
      },
      riskIndicators: result.riskAssessment
    };
  }

  // Digitale Signatur fΓΌr Mietvertrag
  async signContract(contract: LeaseContract, signers: Signer[]): Promise<SignedContract> {
    const signSession = await webid.createSignSession({
      documentUrl: contract.pdfUrl,
      signers: signers.map(s => ({
        email: s.email,
        signaturePositions: s.signatureFields
      })),
      signatureLevel: 'QES' // Qualifizierte elektronische Signatur
    });

    return signSession;
  }
}

Real Estate Workflow

1. Interessent meldet sich fΓΌr Wohnung
           ↓
2. WebID Session starten (AutoID/VideoID)
           ↓
3. Dokument-Scan & Selfie
           ↓
4. Biometrische Verifizierung
           ↓
5. Ergebnis an CRM β†’ BonitΓ€tsprΓΌfung freigeben
           ↓
6. Bei Zusage: SignID fΓΌr Mietvertrag

8️⃣ ESP32 IoT Integration (TΓΌrschilder & Sensoren)

Hardware-Übersicht

Chips: ESP32-WROOM-32E, ESP32-S3, ESP32-C6

AnwendungsfΓ€lle

Anwendung Hardware Protokoll Daten
E-Ink TΓΌrschild ESP32 + E-Paper MQTT/HTTP Mietername, QR-Code
WΓ€rmemengenzΓ€hler ESP32 + M-Bus MQTT Heizverbrauch
WasserzΓ€hler ESP32 + ImpulszΓ€hler MQTT mΒ³ Verbrauch
StromzΓ€hler ESP32 + S0-Interface MQTT kWh Verbrauch
Raumklima ESP32 + BME280 MQTT Temp, Feuchte, Druck
Bewegungsmelder ESP32 + PIR MQTT Anwesenheit
TΓΌrkontakt ESP32 + Reed MQTT Γ–ffnungsstatus

ESP-IDF Firmware Beispiel

// ESP32 Sensor Node
#include "esp_wifi.h"
#include "mqtt_client.h"
#include "driver/i2c.h"

#define MQTT_BROKER "mqtt://iot.realestate-crm.local"
#define PROPERTY_ID "prop_12345"
#define UNIT_ID "unit_001"

typedef struct {
    float temperature;
    float humidity;
    float heat_energy_kwh;
    float water_m3;
    float electricity_kwh;
} sensor_data_t;

void publish_sensor_data(esp_mqtt_client_handle_t client, sensor_data_t *data) {
    char topic[64];
    char payload[256];

    snprintf(topic, sizeof(topic), "properties/%s/units/%s/sensors", PROPERTY_ID, UNIT_ID);
    snprintf(payload, sizeof(payload),
        "{"
        "\"temperature\":%.2f,"
        "\"humidity\":%.2f,"
        "\"heat_kwh\":%.2f,"
        "\"water_m3\":%.3f,"
        "\"electricity_kwh\":%.2f,"
        "\"timestamp\":%lld"
        "}",
        data->temperature, data->humidity,
        data->heat_energy_kwh, data->water_m3,
        data->electricity_kwh, (long long)time(NULL)
    );

    esp_mqtt_client_publish(client, topic, payload, 0, 1, 0);
}

CRM Backend Integration

// MQTT Subscriber im CRM Backend
import mqtt from 'mqtt';

const client = mqtt.connect('mqtt://iot.realestate-crm.local');

client.subscribe('properties/+/units/+/sensors');

client.on('message', async (topic, message) => {
  const [, propertyId, , unitId] = topic.split('/');
  const data = JSON.parse(message.toString());

  // Daten speichern
  await db.sensorReadings.create({
    propertyId,
    unitId,
    timestamp: new Date(data.timestamp * 1000),
    data
  });

  // FΓΌr Nebenkostenabrechnung aggregieren
  await updateUtilityCosts(propertyId, unitId, data);
});

E-Ink TΓΌrschild

// ESP32 + Waveshare E-Paper Display
#include "epd_driver.h"
#include "esp_http_client.h"

void update_door_sign(const char* tenant_name, const char* qr_data) {
    epd_clear();

    // Mietername anzeigen
    epd_draw_string(10, 20, tenant_name, &Font24);

    // QR-Code fΓΌr Paketdienst
    uint8_t qr_code[QR_SIZE];
    generate_qr(qr_data, qr_code);
    epd_draw_bitmap(10, 60, qr_code, QR_SIZE, QR_SIZE);

    // Hausnummer
    epd_draw_string(150, 20, "12a", &Font48);

    epd_update();
}

// Update via HTTP von CRM
void http_event_handler(esp_http_client_event_t *evt) {
    if (evt->event_id == HTTP_EVENT_ON_DATA) {
        door_sign_data_t *data = parse_json(evt->data);
        update_door_sign(data->tenant_name, data->qr_code);
    }
}

9️⃣ evcc Integration (E-Mobility & Solar-Laden)

Übersicht

evcc ist eine Open-Source-Software fΓΌr Solaroptimiertes Laden von Elektrofahrzeugen.

  • GitHub: https://github.com/evcc-io/evcc
  • Dokumentation: https://docs.evcc.io/
  • Lizenz: MIT

⚠️ Wichtig: Die evcc-Installation und -Wartung ist NICHT unsere Aufgabe. Wir greifen lediglich auf bereits vorhandene evcc-Installationen zu, um Daten für das Real Estate CRM zu nutzen.

Warum evcc fΓΌr Real Estate?

Use Case Beschreibung
Nebenkostenabrechnung Ladestrom-Verbrauch pro Mieter erfassen
Energiemonitoring PV-Ertrag, Batteriespeicher, Netzverbrauch
Ladeinfrastruktur Verwaltung von Wallboxen in MehrfamilienhΓ€usern
Smart Building Integration in GebΓ€ude-Energiemanagement
Billing Abrechnung von LadevorgΓ€ngen fΓΌr Mieter/EigentΓΌmer

evcc REST API

Basis-URL: http://<evcc-host>:7070/api/

Haupt-Endpunkte

Endpunkt Methode Beschreibung
/api/state GET Kompletter Systemstatus (Grid, PV, Battery, Loadpoints)
/api/health GET Systemgesundheit prΓΌfen
/api/sessions GET Alle Ladesessions abrufen
/api/tariff/{type} GET Stromtarif-Informationen
/api/loadpoints/{id} GET Ladepunkt-Konfiguration
/api/loadpoints/{id}/mode/{value} POST Lademodus setzen (off/now/minpv/pv)
/api/loadpoints/{id}/limitsoc/{value} POST SoC-Limit setzen
/api/loadpoints/{id}/limitenergy/{value} POST Energie-Limit setzen (kWh)

State Response Struktur

interface EvccState {
  // Site-Level Daten
  gridPower: number;        // Netzleistung (W) - positiv=Bezug, negativ=Einspeisung
  pvPower: number;          // PV-Leistung (W)
  batteryPower: number;     // Batterie (W) - positiv=Entladen, negativ=Laden
  batterySoc: number;       // Batterie-SoC (%)
  homePower: number;        // Hausverbrauch (W)

  // PV-Meter Arrays
  pv: Array<{
    power: number;
    energy: number;
  }>;

  // Batterie-Meter Arrays
  battery: Array<{
    power: number;
    soc: number;
    capacity: number;
  }>;

  // Grid-Daten
  grid: {
    power: number;
    currents: [number, number, number];  // PhasenstrΓΆme
  };

  // Ladepunkte
  loadpoints: EvccLoadpoint[];

  // Tarife
  tariffGrid: number;       // Aktueller Strompreis (ct/kWh)
  tariffFeedIn: number;     // EinspeisevergΓΌtung (ct/kWh)
  tariffCo2: number;        // CO2-IntensitΓ€t (g/kWh)
}

interface EvccLoadpoint {
  title: string;
  mode: 'off' | 'now' | 'minpv' | 'pv';
  charging: boolean;
  connected: boolean;
  enabled: boolean;

  // Leistung & Energie
  chargePower: number;           // Aktuelle Ladeleistung (W)
  chargedEnergy: number;         // Geladene Energie Session (kWh)
  chargeTotalImport: number;     // Gesamt-Energie (kWh)

  // Fahrzeug (wenn erkannt)
  vehicleTitle?: string;
  vehicleSoc?: number;
  vehicleRange?: number;

  // Limits
  limitSoc?: number;
  limitEnergy?: number;

  // Session
  sessionEnergy: number;
  sessionSolarPercentage: number;
  sessionPrice: number;
  sessionPricePerKWh: number;
  sessionCo2PerKWh: number;
}

MQTT API

evcc unterstΓΌtzt auch MQTT fΓΌr Echtzeit-Updates:

evcc/site/gridPower          β†’ Netzleistung
evcc/site/pvPower            β†’ PV-Leistung
evcc/site/batteryPower       β†’ Batterieleistung
evcc/site/batterySoc         β†’ Batterie-SoC
evcc/loadpoints/1/chargePower β†’ Ladeleistung LP1
evcc/loadpoints/1/chargedEnergy β†’ Session-Energie LP1
evcc/loadpoints/1/mode       β†’ Lademodus LP1

CRM Integration

interface EvccBridge {
  private baseUrl: string;
  private mqttClient?: MqttClient;

  constructor(evccHost: string) {
    this.baseUrl = `http://${evccHost}:7070/api`;
  }

  // Aktuellen Systemstatus abrufen
  async getState(): Promise<EvccState> {
    const response = await fetch(`${this.baseUrl}/state`);
    return response.json();
  }

  // Alle Ladesessions fΓΌr Abrechnung
  async getSessions(year?: number, month?: number): Promise<ChargingSession[]> {
    const params = new URLSearchParams();
    if (year) params.set('year', year.toString());
    if (month) params.set('month', month.toString());

    const response = await fetch(`${this.baseUrl}/sessions?${params}`);
    return response.json();
  }

  // Gesundheitscheck
  async isHealthy(): Promise<boolean> {
    try {
      const response = await fetch(`${this.baseUrl}/health`);
      return response.ok;
    } catch {
      return false;
    }
  }

  // Energiedaten fΓΌr Nebenkostenabrechnung aggregieren
  async getEnergyData(
    propertyId: string,
    startDate: Date,
    endDate: Date
  ): Promise<PropertyEnergyData> {
    const sessions = await this.getSessions();

    // Sessions nach Zeitraum filtern
    const relevantSessions = sessions.filter(s => 
      new Date(s.created) >= startDate && 
      new Date(s.finished) <= endDate
    );

    // Nach Fahrzeug/Mieter gruppieren
    const byVehicle = groupBy(relevantSessions, 'vehicle');

    return {
      propertyId,
      period: { start: startDate, end: endDate },
      totalEnergy: sum(relevantSessions.map(s => s.chargedEnergy)),
      solarPercentage: avg(relevantSessions.map(s => s.solarPercentage)),
      totalCost: sum(relevantSessions.map(s => s.price)),
      byTenant: mapToTenants(byVehicle)
    };
  }

  // Echtzeit-Monitoring via MQTT
  subscribeToUpdates(callback: (data: EvccUpdate) => void): void {
    this.mqttClient = mqtt.connect('mqtt://evcc-host:1883');

    this.mqttClient.subscribe('evcc/#');

    this.mqttClient.on('message', (topic, message) => {
      const [, category, ...rest] = topic.split('/');
      callback({
        category,
        key: rest.join('/'),
        value: parseFloat(message.toString()) || message.toString()
      });
    });
  }
}

UnterstΓΌtzte Hardware (Auswahl)

Wallboxen/Charger

Hersteller Modelle
go-e go-eCharger Home, Gemini
Easee Home, Charge
OpenWB OpenWB 1.x, 2.0
KEBA KeContact P30
ABL eMH1, eMH2
Heidelberg Energy Control
Wallbe Eco, Pro
WARP Charger Smart, Pro
SMA EV Charger
Mennekes Amtron
OCPP Alle OCPP 1.6J kompatiblen

Wechselrichter & Speicher

Hersteller Protokoll
SMA Sunny Home Manager, Modbus
Fronius Solar API
Huawei FusionSolar API
Kostal Modbus
SolarEdge Modbus
Enphase Enlighten API
Tesla Powerwall API
BYD HVS/HVM via Wechselrichter

Smart Meter

Typ Protokoll
SMA Energy Meter Multicast
Discovergy REST API
Tibber Pulse GraphQL
Shelly HTTP API
Tasmota MQTT
Modbus TCP/RTU

Datenfluss fΓΌr Abrechnung

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        evcc Installation                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ Wallbox 1 β”‚ β”‚ Wallbox 2 β”‚ β”‚ PV-Anlage β”‚ β”‚ Batteriespeicherβ”‚  β”‚
β”‚  β”‚ (Mieter A)β”‚ β”‚ (Mieter B)β”‚ β”‚           β”‚ β”‚                 β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚        β”‚             β”‚             β”‚               β”‚             β”‚
β”‚        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚
β”‚                            β”‚                                      β”‚
β”‚                     evcc Core Engine                              β”‚
β”‚                            β”‚                                      β”‚
β”‚              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                       β”‚
β”‚              β”‚                           β”‚                       β”‚
β”‚         REST API                    MQTT Broker                  β”‚
β”‚         :7070/api                    :1883                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚                           β”‚
               β–Ό                           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     Real Estate CRM                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚ evcc Bridge    β”‚  β”‚ Session Storage β”‚  β”‚ Billing Engine   β”‚   β”‚
β”‚  β”‚ (Polling/MQTT) │─▢│ (PostgreSQL)    │─▢│ (sevdesk Export) β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Beispiel: Nebenkostenabrechnung mit Ladestrom

async function generateChargingBill(
  propertyId: string,
  tenantId: string,
  period: BillingPeriod
): Promise<ChargingBill> {
  const evcc = new EvccBridge('192.168.1.100');

  // Sessions vom evcc abrufen
  const sessions = await evcc.getSessions(period.year, period.month);

  // Nach Fahrzeug/Mieter filtern (Vehicle-ID = Tenant-Mapping)
  const tenant = await db.tenants.findById(tenantId);
  const tenantSessions = sessions.filter(s => 
    s.vehicle === tenant.evccVehicleId
  );

  // Kosten berechnen
  const totalEnergy = tenantSessions.reduce((sum, s) => sum + s.chargedEnergy, 0);
  const solarEnergy = tenantSessions.reduce((sum, s) => 
    sum + (s.chargedEnergy * s.solarPercentage / 100), 0);
  const gridEnergy = totalEnergy - solarEnergy;

  // Staffelpreise: Solar gΓΌnstiger als Netz
  const solarPrice = 0.08; // €/kWh (Eigenverbrauch)
  const gridPrice = 0.35;  // €/kWh (Netzbezug)

  const totalCost = (solarEnergy * solarPrice) + (gridEnergy * gridPrice);

  return {
    tenantId,
    propertyId,
    period,
    sessions: tenantSessions.length,
    totalEnergy,
    solarEnergy,
    gridEnergy,
    solarPercentage: (solarEnergy / totalEnergy) * 100,
    totalCost,
    avgPricePerKWh: totalCost / totalEnergy,
    co2Saved: solarEnergy * 0.4 // kg CO2 pro kWh eingespart
  };
}

Mehrfamilienhaus-Setup

# Beispiel: evcc Konfiguration fΓΌr MFH mit 4 Ladepunkten
loadpoints:
  - name: "Stellplatz 1 - Wohnung 1A"
    charger: wallbox_1a
    vehicle: mieter_mueller  # Fahrzeug-Zuordnung fΓΌr Abrechnung
    mode: pv

  - name: "Stellplatz 2 - Wohnung 2B"
    charger: wallbox_2b
    vehicle: mieter_schmidt
    mode: pv

  - name: "Stellplatz 3 - Wohnung 3C"
    charger: wallbox_3c
    vehicle: mieter_weber
    mode: pv

  - name: "Besucherparkplatz"
    charger: wallbox_visitor
    mode: now  # Sofort-Laden fΓΌr Besucher

πŸ”Ÿ ista Integration (Heizkosten & Energieverbrauch)

Übersicht

ista SE ist MarktfΓΌhrer fΓΌr Nebenkostenabrechnung in Deutschland mit: - 45 Mio. funkende MessgerΓ€te - 14 Mio. Wohnungen/Nutzeinheiten - EcoTrend Verbrauchsinformationen

Digitale LΓΆsungen

Produkt Funktion
ista einfachSmart Komplett-LΓΆsung Heizkostenabrechnung
EcoTrend Monatliche Verbrauchsinformation (HKVO-konform)
Webportal Liegenschaftsverwaltung
Digital-Pakt Prozessdigitalisierung

Integration Strategie

⚠️ Hinweis: ista bietet keine âffentliche API. Integration erfolgt über:

  1. Webportal Datenexport (CSV/Excel)
  2. Datenaustausch via B2B-Schnittstelle (nach Vereinbarung)
  3. EcoTrend Push-Nachrichten an Mieter
// Konzept: ista Daten-Import
interface IstaDataBridge {
  // Manueller CSV-Import
  async importBillingData(file: File): Promise<BillingData[]> {
    const csv = await parseCSV(file);
    return csv.map(row => ({
      propertyId: this.mapPropertyId(row.liegenschaft),
      unitId: this.mapUnitId(row.nutzeinheit),
      period: row.abrechnungszeitraum,
      heatingCosts: parseFloat(row.heizkosten),
      waterCosts: parseFloat(row.warmwasser),
      totalCosts: parseFloat(row.gesamt)
    }));
  }

  // B2B API (falls verfΓΌgbar)
  async fetchConsumptionData(propertyId: string): Promise<ConsumptionData> {
    // Erfordert ista Partnervertrag
    return await istaB2B.getConsumption(propertyId);
  }
}

Alternative Smart Meter APIs

Anbieter API Daten
Discovergy REST API Strom-Echtzeit
Tibber GraphQL Stromverbrauch
Enphase Enlighten API Solar + Speicher
emonPi Open Source DIY Monitoring

πŸ” Sicherheitskonzept

Authentifizierung

// Multi-Provider Auth
const authProviders = {
  msgraph: new MicrosoftAuthProvider(azureConfig),
  adobe: new AdobeIMSProvider(adobeConfig),
  finapi: new FinAPIAuthProvider(finapiConfig),
  webid: new WebIDAuthProvider(webidConfig)
};

// Token-Speicherung (verschlΓΌsselt)
const tokenVault = new SecureTokenVault({
  encryption: 'AES-256-GCM',
  storage: 'encrypted-db',
  autoRefresh: true
});

Datenschutz (DSGVO)

Aspekt Maßnahme
Einwilligung Granulare Consent-Verwaltung
Datensparsamkeit Nur notwendige Daten speichern
VerschlΓΌsselung TLS 1.3, At-rest AES-256
LΓΆschkonzept Automatische LΓΆschung nach Frist
Auskunft Self-Service Datenexport
Auftragsverarbeitung AVV mit allen Anbietern

πŸ“Š Datenmodell

// Core Entities
interface Property {
  id: string;
  type: 'residential' | 'commercial' | 'mixed';
  address: Address;
  units: Unit[];
  documents: Document[];
  sensors: IoTDevice[];
  financials: PropertyFinancials;
}

interface Unit {
  id: string;
  propertyId: string;
  type: 'apartment' | 'office' | 'retail' | 'parking';
  size: number; // mΒ²
  rooms: number;
  currentLease?: Lease;
  utilities: UtilityMeters;
}

interface Contact {
  id: string;
  type: 'prospect' | 'tenant' | 'owner' | 'vendor';
  person: PersonData;
  identityVerification?: IdentityVerification;
  creditCheck?: CreditCheck;
  communications: Communication[];
}

interface Lease {
  id: string;
  unitId: string;
  tenantId: string;
  startDate: Date;
  endDate?: Date;
  monthlyRent: number;
  deposit: number;
  documents: LeaseDocument[];
  payments: Payment[];
}

// Integration Links
interface ExternalLinks {
  sevdeskContactId?: string;
  msgraphContactId?: string;
  lightroomAlbumId?: string;
  webidSessionId?: string;
  finapiConnectionId?: string;
}

πŸš€ Implementierungs-Roadmap

Phase 1: Core CRM (Monat 1-2)

  • [ ] Objektverwaltung
  • [ ] Kontaktmanagement
  • [ ] Dokumentenablage
  • [ ] Basis-UI

Phase 2: MS Graph & Kommunikation (Monat 3)

  • [ ] Kalender-Synchronisation
  • [ ] E-Mail-Integration
  • [ ] Kontakt-Sync

Phase 3: Buchhaltung (Monat 4)

  • [ ] sevdesk-Bridge
  • [ ] Rechnungserstellung
  • [ ] ZahlungsΓΌberwachung

Phase 4: Marketing (Monat 5-6)

  • [ ] Adobe Express Integration
  • [ ] Lightroom Asset Management
  • [ ] ExposΓ©-Generator

Phase 5: Fintech & IdentitΓ€t (Monat 7-8)

  • [ ] WebID Verifizierung
  • [ ] finAPI BonitΓ€tsprΓΌfung
  • [ ] Digitale Unterschriften

Phase 6: IoT & Smart Building (Monat 9-10)

  • [ ] ESP32 Firmware
  • [ ] MQTT Backend
  • [ ] Verbrauchsdashboard
  • [ ] evcc Integration (E-Mobility)
  • [ ] Ladesession-Abrechnung

Phase 7: Optimierung (Monat 11-12)

  • [ ] Performance-Tuning
  • [ ] Mobile App
  • [ ] Reporting & Analytics

API Dokumentationen

Standards

Rechtliche Grundlagen

  • DSGVO / GDPR
  • GwG (GeldwΓ€schegesetz)
  • HKVO (Heizkostenverordnung)
  • CO2KostAufG

Erstellt: 30.12.2025 | Real Estate CRM Deep Research