feat(workflow): publish verified forecast controls and consolidated docs
Tests / test (push) Successful in 1m1s
Tests / test (push) Successful in 1m1s
Approved by Daniel Haefliger for develop and beta. Author dh_Agent, authenticated account dh. Preserve published battery, charging and overall Energy Pie changes. No deployment or plant control authorization.
This commit is contained in:
@@ -29,16 +29,18 @@ trait ManagerNetzfahrplanV4DatenTrait
|
||||
private function konfiguriereNetzfahrplanV4Daten(): void
|
||||
{
|
||||
$this->SetTimerInterval('NetzfahrplanV4DatenErfassen', 0);
|
||||
if (!$this->ReadPropertyBoolean('NetzfahrplanV4MessdatenAktiv')) return;
|
||||
if (!$this->prognoseLernenAktiv() || $this->ReadAttributeString('PrognoseV4Einrichtungsfehler') !== '') return;
|
||||
try {
|
||||
$this->v4DatenKonfiguration();
|
||||
$config = $this->v4DatenKonfiguration();
|
||||
if ($this->ReadAttributeInteger('NetzfahrplanV4DatenVersion')<1) {
|
||||
// One retry after the data-only upgrade, never a cursor reset or a device write.
|
||||
$this->WriteAttributeInteger('NetzfahrplanV4DatenVersuch', 0);
|
||||
$this->WriteAttributeInteger('NetzfahrplanV4DatenFehlerzahl', 0);
|
||||
$this->WriteAttributeInteger('NetzfahrplanV4DatenVersion', 1);
|
||||
}
|
||||
$this->SetTimerInterval('NetzfahrplanV4DatenErfassen', 30000);
|
||||
$ages = array_column($config['accounting']['sources'], 'maxAgeSeconds');
|
||||
$seconds = max(1, min(30, (int) floor(min($ages) / 2)));
|
||||
$this->SetTimerInterval('NetzfahrplanV4DatenErfassen', $seconds * 1000);
|
||||
} catch (\Throwable $e) {
|
||||
$this->v4DatenStatus(['status'=>'configuration_error','errorType'=>get_class($e)]);
|
||||
}
|
||||
@@ -47,10 +49,10 @@ trait ManagerNetzfahrplanV4DatenTrait
|
||||
private function v4DatenKonfiguration(): array
|
||||
{
|
||||
$id=$this->ReadAttributeString('LizenzInstallationID');
|
||||
$dataset=$this->ReadPropertyString('NetzfahrplanV4Datensatz');
|
||||
$dataset=$this->prognoseV4Datensatz();
|
||||
if (!preg_match('/^[a-zA-Z0-9_-]{1,80}$/D',$dataset)
|
||||
|| !preg_match('/^[0-9a-f-]{36}$/D',$id)) throw new \RuntimeException('Dataset/installation not configured');
|
||||
$c=json_decode($this->ReadPropertyString('NetzfahrplanV4Messkonfiguration'),true,64,JSON_THROW_ON_ERROR);
|
||||
$c=json_decode($this->prognoseV4Messkonfiguration(),true,64,JSON_THROW_ON_ERROR);
|
||||
$c=NetzfahrplanV4Messaufnahme::configuration($c);
|
||||
if ($c['installationId']!==$id || ($c['managerId']??null)!==$this->InstanceID) throw new \RuntimeException('Measurement mapping belongs to another manager');
|
||||
return $c;
|
||||
@@ -74,12 +76,12 @@ trait ManagerNetzfahrplanV4DatenTrait
|
||||
$receipt=json_decode($this->ReadAttributeString('NetzfahrplanV4LetzteDatenquittung'),true,32,JSON_THROW_ON_ERROR);
|
||||
$data['lastAcknowledgement']=$receipt;
|
||||
$this->SetValue('NetzfahrplanV4Datenstatus',json_encode($data+['checkedAt'=>gmdate('c'),
|
||||
'datasetId'=>$this->ReadPropertyString('NetzfahrplanV4Datensatz'),'controlEnabled'=>false],JSON_THROW_ON_ERROR));
|
||||
'datasetId'=>$this->prognoseV4Datensatz(),'controlEnabled'=>false],JSON_THROW_ON_ERROR));
|
||||
}
|
||||
|
||||
public function ErfasseNetzfahrplanV4Daten(): void
|
||||
{
|
||||
if (!$this->ReadPropertyBoolean('NetzfahrplanV4MessdatenAktiv')) return;
|
||||
if (!$this->prognoseLernenAktiv() || $this->ReadAttributeString('PrognoseV4Einrichtungsfehler') !== '') return;
|
||||
$lock='ENELIX.V4.ApplicationData.'.$this->InstanceID;
|
||||
if (!IPS_SemaphoreEnter($lock,0)) return;
|
||||
try {
|
||||
@@ -185,7 +187,7 @@ trait ManagerNetzfahrplanV4DatenTrait
|
||||
if ($records===[]) return ['status'=>'up_to_date'];
|
||||
$id=$this->ReadAttributeString('LizenzInstallationID');$token=$this->ReadAttributeString('PrognoseInstallationsToken');
|
||||
if ($token==='') throw new \RuntimeException('Existing device token unavailable');
|
||||
$payload=json_encode(['version'=>1,'datasetId'=>$this->ReadPropertyString('NetzfahrplanV4Datensatz'),'records'=>$records],JSON_THROW_ON_ERROR);
|
||||
$payload=json_encode(['version'=>1,'datasetId'=>$this->prognoseV4Datensatz(),'records'=>$records],JSON_THROW_ON_ERROR);
|
||||
$h=curl_init('https://license.enelix.ch/api/v1/installations/'.rawurlencode($id).'/prognosis/planner-v4/measurements');
|
||||
if ($h===false) throw new \RuntimeException('Cannot prepare data transfer');
|
||||
try {
|
||||
@@ -197,11 +199,11 @@ trait ManagerNetzfahrplanV4DatenTrait
|
||||
if ($answer===false||$code!==200||strlen($answer)>65536) throw new \RuntimeException('Measurement delivery not acknowledged',$code);
|
||||
$ack=json_decode($answer,true,32,JSON_THROW_ON_ERROR);
|
||||
if (!in_array($ack['status']??null,['stored','duplicate'],true)
|
||||
||($ack['datasetId']??null)!==$this->ReadPropertyString('NetzfahrplanV4Datensatz')
|
||||
||($ack['datasetId']??null)!==$this->prognoseV4Datensatz()
|
||||
||($ack['acceptedThrough']??null)!==$lastTime) throw new \RuntimeException('Measurement acknowledgement does not match batch');
|
||||
$this->WriteAttributeString('NetzfahrplanV4DatenCursor',json_encode($candidate,JSON_THROW_ON_ERROR));
|
||||
return ['status'=>'acknowledged','records'=>count($records),'acceptedThrough'=>$lastTime,
|
||||
'datasetId'=>$this->ReadPropertyString('NetzfahrplanV4Datensatz'),
|
||||
'datasetId'=>$this->prognoseV4Datensatz(),
|
||||
'journalDuplicateTimestampsSkipped'=>$skippedDuplicateTimestamps,
|
||||
'journalAcknowledgedTimestampsSkipped'=>$skippedAcknowledgedTimestamps];
|
||||
} finally { curl_close($h); }
|
||||
|
||||
Reference in New Issue
Block a user