Files
Symcon_Belevo_Energiemanage…/VGT_Sub/module.php
2025-11-21 15:14:39 +01:00

215 lines
7.5 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
class VGT_Sub extends IPSModule
{
public function Create()
{
parent::Create();
$this->RegisterPropertyString('DeviceID', '');
/** -------------------------------------------
* STATUS Variablen (schreibbar)
* ------------------------------------------*/
$this->RegisterVariableInteger('PowerProduction', 'Power Production', '', 10);
$this->EnableAction('PowerProduction');
$this->RegisterVariableBoolean('IsReady', 'Is Ready', '', 11);
$this->EnableAction('IsReady');
$this->RegisterVariableBoolean('IsRunning', 'Is Running', '', 12);
$this->EnableAction('IsRunning');
$this->RegisterVariableInteger('StateOfCharge', 'State of Charge', '', 13);
$this->EnableAction('StateOfCharge');
$this->RegisterVariableInteger('MinSOC', 'Min SOC', '', 14);
$this->EnableAction('MinSOC');
$this->RegisterVariableInteger('MaxSOC', 'Max SOC', '', 15);
$this->EnableAction('MaxSOC');
/** -------------------------------------------
* REMOTE CONTROL (readonly)
* ------------------------------------------*/
$this->RegisterVariableInteger('PowerSetpoint', 'Power Setpoint', '', 20);
$this->RegisterVariableString('Strategy', 'Strategy', '', 21);
$this->RegisterVariableString('RemoteControlPayload', 'Remote Control Payload', '', 30);
/** -------------------------------------------
* FEEDBACK REQUEST (readonly)
* ------------------------------------------*/
$this->RegisterVariableString('FeedbackRequestPayload', 'Feedback Request Payload', '', 40);
}
public function ApplyChanges()
{
parent::ApplyChanges();
$this->ConnectParent('{DBDA3967-E416-4354-A5C9-2FB9E7E2F5B3}'); // MQTT Client Gateway
}
/** ----------------------------------------------------------
* REQUEST ACTION → Statusvariablen schreibbar machen
* ----------------------------------------------------------*/
public function RequestAction($Ident, $Value)
{
$this->SetValue($Ident, $Value);
$device = $this->ReadPropertyString('DeviceID');
if ($device === '') {
return;
}
switch ($Ident) {
case 'PowerProduction':
case 'IsReady':
case 'IsRunning':
case 'StateOfCharge':
case 'MinSOC':
case 'MaxSOC':
$payload = json_encode([
'power_production' => $this->GetValue('PowerProduction'),
'is_ready' => $this->GetValue('IsReady'),
'is_running' => $this->GetValue('IsRunning'),
'state_of_charge' => $this->GetValue('StateOfCharge'),
'min_soc' => $this->GetValue('MinSOC'),
'max_soc' => $this->GetValue('MaxSOC')
]);
$this->Publish("status/$device", $payload);
break;
}
}
/** ----------------------------------------------------------
* SUBSCRIBE (nur bei „MQTT_CONNECTED“)
* ----------------------------------------------------------*/
private function Subscribe(string $topic): void
{
if (!$this->HasActiveParent()) {
$this->SendDebug('MQTT', 'Subscribe ohne aktiven Parent: ' . $topic, 0);
return;
}
$this->SendDebug('MQTT', 'Subscribe → ' . $topic, 0);
$this->SendDataToParent(json_encode([
'DataID' => '{7F2A28E2-ABFA-4C77-B43F-042E1ED9F2D2}',
'PacketType' => 8, // SUBSCRIBE
'QualityOfService' => 0,
'Retain' => false,
'Topic' => $topic,
'Payload' => ''
]));
}
/** ----------------------------------------------------------
* PUBLISH
* ----------------------------------------------------------*/
private function Publish(string $topic, string $payload): void
{
if (!$this->HasActiveParent()) {
$this->SendDebug('MQTT', 'Publish ohne aktiven Parent: ' . $topic, 0);
return;
}
$this->SendDebug('MQTT', 'Publish → Topic=' . $topic . ' Payload=' . $payload, 0);
$this->SendDataToParent(json_encode([
'DataID' => '{7F2A28E2-ABFA-4C77-B43F-042E1ED9F2D2}',
'PacketType' => 3,
'QualityOfService' => 0,
'Retain' => false,
'Topic' => $topic,
'Payload' => $payload
]));
}
/** ----------------------------------------------------------
* RECEIVE DATA
* ----------------------------------------------------------*/
public function ReceiveData($JSONString)
{
$data = json_decode($JSONString, true);
if (!is_array($data)) {
return;
}
// --- MQTT CONNECTED EVENT ---
if (isset($data['Event']) && $data['Event'] === 'MQTT_CONNECTED') {
$this->SendDebug('MQTT', 'MQTT_CONNECTED → re-subscribing…', 0);
$device = $this->ReadPropertyString('DeviceID');
if ($device !== '') {
$this->Subscribe("feedback-request/$device");
$this->Subscribe("remote-control-request/$device");
}
return;
}
// --- Normale MQTT Messages ---
$topic = $data['Topic'] ?? '';
$payload = $data['Payload'] ?? '';
$this->SendDebug('MQTT', "Receive: Topic=$topic Payload=$payload", 0);
$device = $this->ReadPropertyString('DeviceID');
if ($device === '') {
return;
}
/** -------------------------------------------
* 1⃣ FEEDBACK REQUEST
* ------------------------------------------*/
if ($topic === "feedback-request/$device") {
$this->SetValue('FeedbackRequestPayload', $payload);
$json = json_decode($payload, true);
if (!is_array($json)) {
$json = [];
}
$response = array_merge($json, [
"power_production" => $this->GetValue('PowerProduction'),
"is_ready" => $this->GetValue('IsReady'),
"is_running" => $this->GetValue('IsRunning'),
"state_of_charge" => $this->GetValue('StateOfCharge'),
"min_soc" => $this->GetValue('MinSOC'),
"max_soc" => $this->GetValue('MaxSOC')
]);
$this->Publish("feedback-response/$device", json_encode($response));
return;
}
/** -------------------------------------------
* 2⃣ REMOTE CONTROL REQUEST
* ------------------------------------------*/
if ($topic === "remote-control-request/$device") {
$this->SetValue('RemoteControlPayload', $payload);
$json = json_decode($payload, true);
if (is_array($json)) {
if (array_key_exists('power_setpoint', $json)) {
$this->SetValue('PowerSetpoint', (int) $json['power_setpoint']);
}
if (array_key_exists('strategy', $json)) {
$this->SetValue('Strategy', (string) $json['strategy']);
}
}
// Antwort spiegeln
$this->Publish("remote-control-response/$device", $payload);
return;
}
}
}