Welcome to Tesla Motors Club
Discuss Tesla's Model S, Model 3, Model X, Model Y, Cybertruck, Roadster and More.
Register

Domotica (DSMR, IOT, MQTT, etc.)

This site may earn commission on affiliate links.
Ik ga er ook aan beginnen:
  • TWC Gen2 ophangen en 3-fase ernaartoe trekken, dan kan ik iig sneller laden dan nu (1x16A met de UMC schiet echt niet op)
  • DSMR Reader (die mijn P1 poort al uitleest) laten publiceren naar MQTT en die dan uitlezen met TWCManager zodat ik 's nachts de volledige capaciteit kan gebruiken
  • Scheduler inbouwen zodat ik kan laten laden op de laagste uren (dankzij Tibber)
Heb verschillende RPi's liggen, een RS-485 serial USB stick en DSMR reader draait al in de meterkast. Ben de taal Python nog niet machtig maar een paar aanpassingen moet toch lukken. To be continued.
 
  • Like
Reactions: RichieB and Phil V
Ik ga er ook aan beginnen:
  • TWC Gen2 ophangen en 3-fase ernaartoe trekken, dan kan ik iig sneller laden dan nu (1x16A met de UMC schiet echt niet op)
  • DSMR Reader (die mijn P1 poort al uitleest) laten publiceren naar MQTT en die dan uitlezen met TWCManager zodat ik 's nachts de volledige capaciteit kan gebruiken
  • Scheduler inbouwen zodat ik kan laten laden op de laagste uren (dankzij Tibber)

De TWC hangt (met 3 fases laden is zoveel beter dan met 1 fase), zit nu te puzzelen om TWC Manager in te zetten als load balancer. Die lijkt geen rekening te houden met 3 fases, er wordt gekeken naar het geconsumeerde aantal watts en de rest zou dan beschikbaar moeten zijn voor de TWC. Ik zou dus het verbruik van alledrie de fases uit moeten lezen en daar de hoogste waarde van doorgeven aan TWC Manager. @wooter @RichieB Klopt dat?
 
@cousin_IT TWCManager is echt een beroerde load balancer voor 3 fasen. Zie ook mijn opmerkingen hier: New feature that allows to limit the max power from the Grid by juanjoqg · Pull Request #220 · ngardiner/TWCManager

Nu je DSMR-Reader hebt draaien kan je een oplossing gebruiken die daar speciaal voor gemaakt is: GitHub - RichieB2B/tesla-loadbalancer: Loadbalancer for charging Tesla vehicles at home

Het was ooit mijn bedoeling om TWCManager slimmer te maken, maar wellicht moet ik mijn eigen script juist uitbreiden met een web interface en ondersteuning voor het RS-485 protocol ipv de Tesla API.
 
Last edited:
@cousin_IT TWCManager is echt een beroerde load balancer voor 3 fasen. Zie ook mijn opmerkingen hier: New feature that allows to limit the max power from the Grid by juanjoqg · Pull Request #220 · ngardiner/TWCManager

Nu je DSMR-Reader hebt draaien kan je een oplossing gebruiken die daar speciaal voor gemaakt is: GitHub - RichieB2B/tesla-loadbalancer: Loadbalancer for charging Tesla vehicles at home

Het was ooit mijn bedoeling om TWCManager slimmer te maken, maar wellicht moet ik mijn eigen script juist uitbreiden met een web interface en ondersteuning voor het RS-485 protocol ipv de Tesla API.

Dank voor de link, ik vind het ook geen ideale oplossing :( Ik heb ook naar jouw oplossing gekeken. Die zou veel beter aansluiten bij wat ik wil maar ik huiver voor de latency van P1 -> DSMR (5 sec) -> MQTT (5 sec) -> Tesla API -> (?) -> Tesla.

Er zit een plug-in in DSMR die automatisch alle P1 telegrammen in JSON naar een API stuurt (link). Idealiter luister je daarnaar en pas je per telegram de waarde aan via RS-485 (vergelijk 3 fases, pak hoogste waarde, haal die van de vaste waarde van de installatieautomaat af), dan haal je alle latency ertussenuit.

Ik heb zelf geen ervaring met Python maar het lijkt me wel een interessant project om op te pakken. De code van TWC Manager voor de communicatie is opnieuw te gebruiken lijkt me.
 
@cousin_IT De reactietijd van mijn script is zo'n 30 seconden. Dat is voor de C-curve van je hoofdzekering echt helemaal geen probleem. Die kan een overschrijding van 100% (dus 50A bij een 3x25A aansluiting) prima een paar minuten aan zonder af te slaan. De optimalisatie die je voorstelt (MQTT overslaan) is dus niet nodig. De vertraging die MQTT introduceert is wellicht een seconde, zeker geen 5. RS-485 gebruiken ipv de Tesla API zal wel significant sneller zijn.

Ik heb trouwens een P1 meter die elke 1 seconde een datagram en dus ook een MQTT bericht geeft. Maar ook met een oudere slimme meter die elke 10 seconden een datagram afgeeft moet dit gewoon werken.
 
Last edited:
  • Like
Reactions: adjego
@cousin_IT De reactietijd van mijn script is zo'n 30 seconden. Dat is voor de C-curve van je hoofdzekering echt helemaal geen probleem. Die kan een overschrijding van 100% (dus 50A bij een 3x25A aansluiting) prima een paar minuten aan zonder af te slaan. De optimalisatie die je voorstelt (MQTT overslaan) is dus niet nodig. De vertraging die MQTT introduceert is wellicht een seconde, zeker geen 5. RS-485 gebruiken ipv de Tesla API zal wel significant sneller zijn.

Ik heb trouwens een P1 meter die elke 1 seconde een datagram en dus ook een MQTT bericht geeft. Maar ook met een oudere slimme meter die elke 10 seconden een datagram afgeeft moet dit gewoon werken.
Dank voor je uitleg. Ik heb ook een DSMR5 meter maar ik zie dat DSMR reader slechts iedere 5 seconden een nieuw MQTT bericht plaatst (zie bijlage) en dat ik dat zo nergens kon aanpassen, vandaar dat ik me afvroeg of dit wel de beste oplossing was. Je opmerking over de C-curve van de hoofdzekering is terecht dus MQTT kan blijven. Ik heb nog wel steeds een voorkeur voor het aansluren van de TWC middels RS-485 ipv via de API.

1673364335349.png
 
@cousin_IT Ik heb nog een keer gekeken en ik krijg elke 2 seconden een MQTT bericht van DSMR-Reader. Ik vermoed dat de frequentie instelbaar is door de netbeheerder en dat DSMR-Reader ze gewoon doorzet zodra ze binnen komen.

Mijn geplande aanpassingen van het script zijn als volgt:
  1. Web interface voor keuze van 3 modes:
    1. Normaal laden (snelheid instelbaar, bijv. 16A), dit is inclusief bewaking van de hoofdzekering
    2. Maximaal laden (zo snel mogelijk), dit is inclusief bewaking van de hoofdzekering
    3. Zo min mogelijk terugleveren (zo snel laden dat teruglevering / afname rond de 0W blijft)
  2. RS-485 aansturing ipv Tesla API
  3. Ondersteuning voor 2 of meer Tesla's in een account
Ik heb alleen geed idee waneer ik er tijd voor heb..
 
@cousin_IT TWCManager is echt een beroerde load balancer voor 3 fasen. Zie ook mijn opmerkingen hier: New feature that allows to limit the max power from the Grid by juanjoqg · Pull Request #220 · ngardiner/TWCManager

Nu je DSMR-Reader hebt draaien kan je een oplossing gebruiken die daar speciaal voor gemaakt is: GitHub - RichieB2B/tesla-loadbalancer: Loadbalancer for charging Tesla vehicles at home

Het was ooit mijn bedoeling om TWCManager slimmer te maken, maar wellicht moet ik mijn eigen script juist uitbreiden met een web interface en ondersteuning voor het RS-485 protocol ipv de Tesla API.
Ik gebruik TWCManager enkel om het aantal Amperes door te geven. De berekening doe ik in nodered en baseer ik op het voltage x wattage van de 3 fasen omdat je vrije wattages afhangen van hoeveel volt en ampere er al getrokken wordt. In de zomer 250V en 10kW trekt minder ampere dan in de winter aan 220V.

Diepere integratie waarbij de berekening binnen TWCManager gedaan wordt ben ik nog niet aan.
 
@cousin_IT Ik heb nog een keer gekeken en ik krijg elke 2 seconden een MQTT bericht van DSMR-Reader. Ik vermoed dat de frequentie instelbaar is door de netbeheerder en dat DSMR-Reader ze gewoon doorzet zodra ze binnen komen.

Mijn geplande aanpassingen van het script zijn als volgt:
  1. Web interface voor keuze van 3 modes:
    1. Normaal laden (snelheid instelbaar, bijv. 16A), dit is inclusief bewaking van de hoofdzekering
    2. Maximaal laden (zo snel mogelijk), dit is inclusief bewaking van de hoofdzekering
    3. Zo min mogelijk terugleveren (zo snel laden dat teruglevering / afname rond de 0W blijft)
  2. RS-485 aansturing ipv Tesla API
  3. Ondersteuning voor 2 of meer Tesla's in een account
Ik heb alleen geed idee waneer ik er tijd voor heb..
Enige wat voor mij nog zou missen is gepland laden, dus tussen 3 en 6 uur 's ochtends bijv. Kan ook met de API maar is omslachtiger. Ik zou je aanvullingen hoe dan ook verwelkomen, testsetup staat gereed (TWC, RPi)
 
@cousin_IT TWCManager is echt een beroerde load balancer voor 3 fasen. Zie ook mijn opmerkingen hier: New feature that allows to limit the max power from the Grid by juanjoqg · Pull Request #220 · ngardiner/TWCManager

Nu je DSMR-Reader hebt draaien kan je een oplossing gebruiken die daar speciaal voor gemaakt is: GitHub - RichieB2B/tesla-loadbalancer: Loadbalancer for charging Tesla vehicles at home

Het was ooit mijn bedoeling om TWCManager slimmer te maken, maar wellicht moet ik mijn eigen script juist uitbreiden met een web interface en ondersteuning voor het RS-485 protocol ipv de Tesla API.

geen idee of het al voorbij is gekomen maar hier is een goed script GitHub - RSP267/TWC: Domoticz plugin for the Tesla Wall Connector te vinden voor 3 fase load balancing. gebruik ik nu al ruim 3 jaar naar tevredenheid. het is weliswaar voor domoticz maar wellicht kan je de code hergebruiken.
 
Dit is mijn C# implementatie, ik doe niet eens iets met TWCManager. Gewoon de Tesla API en DSMR reader.

Ik heb het nooit echt netjes gemaakt maar het werkt wel :cool:


using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using MQTTnet;

class DsmrTeslaLoadBalancer
{
const string HomeZoneName = "Huize Smits";
static readonly TimeSpan HistoryDuration = TimeSpan.FromMinutes(1);
readonly HashSet<(DateTime, int)> History = new();

readonly ILogger Logger;
readonly TeslaOperations Ops;

const int NetMaximum = 25;
const int TeslaChargeCurrentMin = 5;

int L1, L2, L3, LMax;
bool IsConnected;
bool IsCharging;
bool IsHome = true;
int TeslaChargeCurrent;
int TeslaChargeCurrentMax = 24;

int Max(int a, int b, int c) => Math.Max(a, Math.Max(b, c));

public DsmrTeslaLoadBalancer(ILogger<DsmrTeslaLoadBalancer> logger, TeslaOperations ops)
{
Logger = logger;
Ops = ops;
}

public async Task Update()
{
var phaseAmpsMax = Max(L1, L2, L3);

History.Add((DateTime.UtcNow, phaseAmpsMax));

foreach (var x in History)
{
if (x.Item1 < DateTime.UtcNow - HistoryDuration)
{
History.Remove(x);
}
}

if (!IsConnected || !IsCharging || !IsHome)
{
Logger.LogTrace("Not connected to home charger or not charging ({isConnected}, {isCharging}, {isHome})", IsConnected, IsCharging, IsHome);
return;
}

var diff = NetMaximum - phaseAmpsMax;

if (LMax == phaseAmpsMax && diff == 0)
{
Logger.LogTrace("No change in LMax and diff");
return;
}

LMax = phaseAmpsMax;

Logger.LogDebug("Phase power current max phases: ({netMax}A) {phaseAmpsMax}A delta {diff}A", NetMaximum, phaseAmpsMax, diff);

var currentValue = TeslaChargeCurrent;

if (diff > 0) // Omhoog
{
if (currentValue < TeslaChargeCurrentMax)
{
// Mag enkel omhoog als de afgelopen minuut geen spike is geweest
var max = History.Max(x => x.Item2);

if (max > NetMaximum)
{
Logger.LogDebug("Not increasing as history has values that exceed NetMaximum");
return;
}
var newValue = currentValue + 1;
Logger.LogDebug("Increasing amps to {NewValue}", newValue);
await SetChargingAmps(newValue); // Could use diff, but favor small 1 amp increments every DSMR interval of 5 seconds
}
else
{
Logger.LogTrace("Already at max");
}
}
else if (diff < 0) // Omlaag
{
var newValue = currentValue + diff;

if (newValue < TeslaChargeCurrentMin) // Failsafe!
{
await ChargeStop();
}
else
{
Logger.LogDebug("DecreasingAmps to {NewValue}", newValue);
await SetChargingAmps(newValue);
}
}
}

async Task SetChargingAmps(int current)
{
if (current > TeslaChargeCurrentMax || current < TeslaChargeCurrentMin) throw new ArgumentOutOfRangeException(nameof(current), current, $"Value must be between {TeslaChargeCurrentMin} and {TeslaChargeCurrentMax}.");
TeslaChargeCurrent = current; // Temp set until receiving next update
await Ops.SetChargingAmps(current);
}

async Task ChargeStop()
{
Logger.LogInformation("Stop charging");
await Ops.ChargeStop();
}

[Subscribe("dsmr/reading/phase_power_current_l1")]
public async Task HandleDsmrL1(MqttApplicationMessage msg, CancellationToken cancellationToken)
{
var value = int.Parse(msg.ConvertPayloadToString(), CultureInfo.InvariantCulture);
if (L1 == value) return;

L1 = value;
Logger.LogDebug("Phase {phase}: {amps}A", nameof(L1), L1);
await Update();
}

[Subscribe("dsmr/reading/phase_power_current_l2")]
public async Task HandleDsmrL2(MqttApplicationMessage msg, CancellationToken cancellationToken)
{
var value = int.Parse(msg.ConvertPayloadToString(), CultureInfo.InvariantCulture);
if (L2 == value) return;

L2 = value;
Logger.LogDebug("Phase {phase}: {amps}A", nameof(L2), L2);
await Update();
}

[Subscribe("dsmr/reading/phase_power_current_l3")]
public async Task HandleDsmrL3(MqttApplicationMessage msg, CancellationToken cancellationToken)
{
var value = int.Parse(msg.ConvertPayloadToString(), CultureInfo.InvariantCulture);
if (L3 == value) return;

L3 = value;
Logger.LogDebug("Phase {phase}: {amps}A", nameof(L3), L3);
await Update();
}

[Subscribe("teslamate/cars/+/plugged_in")]
public Task HandlePluggedIn(MqttApplicationMessage msg, CancellationToken cancellationToken)
{
IsConnected = msg.ConvertPayloadToString() == "true";
Logger.LogInformation("IsConnected = {IsConnected}", IsConnected);
return Update();
}

[Subscribe("teslamate/cars/+/geofence")]
public async Task HandleCarGeofence(MqttApplicationMessage msg, CancellationToken cancellationToken)
{
var zoneName = msg.ConvertPayloadToString();
IsHome = !string.IsNullOrEmpty(zoneName) && zoneName.Contains("🏠") || zoneName == HomeZoneName;
Logger.LogInformation("IsHome = {IsHome} ({zoneName})", IsHome, zoneName);
await Update();
}

[Subscribe("teslamate/cars/+/state")]
public async Task HandleState(MqttApplicationMessage msg, CancellationToken cancellationToken)
{
IsCharging = msg.ConvertPayloadToString() == "charging";
Logger.LogInformation("IsCharging = {IsCharging}", IsCharging);
await Update();
}

[Subscribe("teslamate/cars/+/charge_current_request")]
public Task HandleChargerActualCurrent(MqttApplicationMessage msg, CancellationToken cancellationToken)
{
TeslaChargeCurrent = int.Parse(msg.ConvertPayloadToString(), CultureInfo.InvariantCulture);
if (!IsCharging)
{
Logger.LogInformation("Not charging, set TeslaChargeCurrentMax = {charger_actual_current}A", TeslaChargeCurrent);
TeslaChargeCurrentMax = TeslaChargeCurrent;
}
Logger.LogInformation("charger_actual_current = {charger_actual_current}A", TeslaChargeCurrent);
return Task.CompletedTask;
}

[Subscribe("teslamate/cars/+/time_to_full_charge")]
public Task HandleTimeToFullCharge(MqttApplicationMessage msg, CancellationToken cancellationToken)
{
var value = msg.ConvertPayloadToString();
var hours = double.Parse(value, CultureInfo.InvariantCulture);
var at = DateTimeOffset.Now.AddHours(hours);
at = at.Round(TimeSpan.FromSeconds(15));
Logger.LogInformation("time_to_full_charge = {at} ({value})", at, value);
return Task.CompletedTask;
}
}
 
Met de prijzen feeds van https://enever.nl/ ( https://enever.nl/feed/stroomprijs_morgen.php ) ben ik nu bezig met de volgens logica:

Als ingeplugged en in de thuis zone. Check hoeveel kWh tot de chargelimit er bij moet. Bereken de dip tot morgenochtend 8 uur en bereken wanneer het laden moet starten. Rekening houdende met de maximale laadsnelheid (17kW)


Bv:

01-02: 15ct
02-03: 10ct
03-04: 08ct
04-05: 12ct

Stel:

Er moet minder dan 17kWh in, start dan om 03:00.
Er moet 17-34kWh in, start dan om 02:00.
Er moet 34-15kWh in, start dan ook om 02:00

Deze "start laden op het goedkoopste moment trigger" ga ik ergens dit weekend maken.

Versie 2 zal zijn, enkel laden in uren onder een bepaald niveau (gemiddelde of 25% van de delta tussen min/max) ondanks dat dit betekend dat de laad limiet misschien niet behaald zal worden. Dit in combinatie met "laad enkel in het goedkoopste uur".
 
  • Like
Reactions: wooter
Met de prijzen feeds van https://enever.nl/ ( https://enever.nl/feed/stroomprijs_morgen.php ) ben ik nu bezig met de volgens logica:

Als ingeplugged en in de thuis zone. Check hoeveel kWh tot de chargelimit er bij moet. Bereken de dip tot morgenochtend 8 uur en bereken wanneer het laden moet starten.

Sinds deze maand dynamisch, en wilde ook al zoiets gaan maken. Loop er alleen nog tegenaan dat de auto eigenlijk of meteen, of uitgesteld wil gaan laden. Kan nu de tijd om 03:00/06:00 scheduled charging zetten (had voorheen 0:30, maar dat is met dynamisch niet meer het beste moment), maar kan je ook op andere manier voorkomen dat de auto automatisch gaat laden?