feat(control): connect physical feedback to bounded V4 command and fallback paths
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"scope": "corrected_feedback_trial_disabled",
|
||||
"managerId": 17004,
|
||||
"batteryInstanceId": 44234,
|
||||
"files": {
|
||||
"libs/BatterieNetzfahrplanV4RueckmeldungTrait.php": {
|
||||
"before": null,
|
||||
"after": "24cf0654f1a6bd545d64ce5f115f309b16d8ffca5172ec64fb37c390c6f001a7"
|
||||
},
|
||||
"libs/BatterieNetzfahrplanV4TestTrait.php": {
|
||||
"before": null,
|
||||
"after": "80474ff24cf9b2d32dfe481f0ce26bb94584c458b0fa3de232dec3897b64a4b2"
|
||||
},
|
||||
"libs/BatterieRegler.php": {
|
||||
"before": "035988c54d4d0cc3a59d234f1c08a8edbf5fcac42e09a6bcea61d3dd8270771b",
|
||||
"after": "beecc9c817b722336367e1c574c1a38afc8f3f5346442170d67c101b980adf7b"
|
||||
},
|
||||
"libs/ManagerNetzfahrplanV4EmpfangTrait.php": {
|
||||
"before": "d083cfa6ae8e8026c134d2b53f34bb6fbe342fb7332a3e7da1b881de33e13e97",
|
||||
"after": "936939a3e4a5a5d54fdff68f6fc689a9400e8406aecd5ac09ebc8a6b569c0b66"
|
||||
},
|
||||
"libs/ManagerNetzfahrplanV4TestTrait.php": {
|
||||
"before": null,
|
||||
"after": "c0d9b6336574dd8acf5f84adb12a32cad3b42ae91c5a31d513d0bc638a560f18"
|
||||
},
|
||||
"libs/NetzfahrplanV4Regeltest.php": {
|
||||
"before": null,
|
||||
"after": "bdac3e2e54c50a4c1541da8918ddf3ab2f665bb5cc6696848f546e7b05f5f249"
|
||||
},
|
||||
"libs/NetzfahrplanV4Rueckmeldung.php": {
|
||||
"before": null,
|
||||
"after": "a7459a208c4dd84ffe3a166d266dcd00216f3660fe60e5ee61d5042d0b840631"
|
||||
},
|
||||
"Batterie/module.php": {
|
||||
"before": "34503645f7e21dd1e5bf0a3f754f6592175dd67f9a263bf431f3801209555401",
|
||||
"after": "3d5fcd83e4e7d999d5ac949fe357b492d5661ffa76639d2ca57a3f3934eabdbe"
|
||||
},
|
||||
"Manager/module.php": {
|
||||
"before": "83e80883c8f9b817c0af5e239b20bcb019c7cf7f7943ee5bcc6493ac5a743532",
|
||||
"after": "cbbb33a8f71dda8cc80a4fc01cd3d6154da8153b5523306b2da723bb44f2dd79"
|
||||
}
|
||||
},
|
||||
"configurationSha256": "f66cfb9ebf5e02259b902f876a4c78756a51b3f2f2c240fd92c0f01161268c56",
|
||||
"dependencies": {
|
||||
"libs/NetzfahrplanV4Planpruefung.php": "24b935d80bad4ce2d9047b6777aaf74a18773236ca91a2844a0907012f4fadf4",
|
||||
"libs/Nachrichtenvertrag.php": "215ad7d4c5240b39b48cb7672f5057afa532aafdb34039862a1a22985a9ee839",
|
||||
"libs/VerbraucherBasisTrait.php": "10fd9f54283c378104bce11d623d5581558355d26fc2f85bf04b316542874507",
|
||||
"libs/VerbraucherSchnittstelle.php": "6329d423dca7b551f01fd884204be45be43f92cd6da6e4faedf2c3c9b4654a15",
|
||||
"libs/ManagerNetzfahrplanV4Trait.php": "e27a3595e4ed8cdb62e2561149ef6a50adb9194e0239eb25c1216aee2716fa88",
|
||||
"libs/ManagerNetzfahrplanV4DatenTrait.php": "59ae0ae283839ca82c58db9c071dcf28d0ab95e44f7a74c6473aca837ce416c4",
|
||||
"libs/NetzfahrplanV4Datenarchiv.php": "57ef7a60c273c5270b3e93ff5528d7d294e708725c9edfe81ac7ed819587f983",
|
||||
"libs/NetzfahrplanV4Messaufnahme.php": "ebe873bb714041e505a4f500b34c9bae3a5a0b93ac459161584ced758507a6e9",
|
||||
"libs/NetzfahrplanV4Bilanzierung.php": "ffda2a03dbb226a4405a2ad66704c080a9dc475ce64282ad3f0d7d60034ab199",
|
||||
"libs/NetzfahrplanV4Betriebsdaten.php": "6ff7d5710995778e7f941020a6f18555307ef51f16867f13efc204915e6dc9d9",
|
||||
"libs/NetzfahrplanV4Bezugszaehler.php": "7aa01ce83a343eb767a889575fa04cece7f1c65cda347723e24dd68da40cea9a",
|
||||
"libs/ManagerEnergieTrait.php": "2f89b0ad31ee6dd99180a7225173036eb6212b2ea7157e57fee23f0f8b441a51",
|
||||
"libs/EnergieMessung.php": "16c64e1cbefde81c25f913aaca6546f0d30cc8f2fddecea0768a3760a98e97d2",
|
||||
"libs/StoerungsSnapshot.php": "c871c1dd58d7fb1ef6c06985de066518688ef080f3cbdadda192d66cedcf49e1",
|
||||
"libs/Anlagentopologie.php": "1b7e95d103a3048ed38c464a424f2f12821a147b269e149fd6b89bca84878c47",
|
||||
"libs/Lizenzpruefung.php": "cb93cb49b93ed3ebb2060dba28b5b2dec2f29548d6ccff1afd9c7cb4624ad77e",
|
||||
"libs/EinspeiseRegler.php": "8b982be5b95275c6dd6611a2bf2b1f89b991ba53cf94e46df0eed3249add65e0",
|
||||
"libs/ManagerRegler.php": "608a4abebbe45da37a16316a530fa3f5ab21cb880bb341acbdcd3a9aaa93c6ee",
|
||||
"libs/ManagerSchnittstelle.php": "0aae8c8c85eb252c577fcb0b5a50a12f3247e4a0bb083579122854f6c35878b3"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
"""Recreate a reviewed Lihrenmoos package from this commit; never install in Symcon."""
|
||||
from pathlib import Path
|
||||
import hashlib,json,sys
|
||||
here=Path(__file__).resolve().parent;repo=here.parents[1]
|
||||
if len(sys.argv)!=2:raise SystemExit('Usage: python3 build_stage.py NEW_PRIVATE_STAGING_DIRECTORY')
|
||||
target=Path(sys.argv[1]).resolve()
|
||||
allowed=[Path('/srv/agent'),Path('/home/agent/services/qa')]
|
||||
if not any(target!=p and target.is_relative_to(p) for p in allowed):raise SystemExit('Use a private agent staging directory, not live module paths')
|
||||
if target.exists():raise SystemExit('Destination must not exist')
|
||||
m=json.loads((here/'MANIFEST.json').read_text());contents={}
|
||||
for n,v in m['files'].items():
|
||||
p=repo/n
|
||||
if p.is_symlink() or not p.resolve().is_relative_to(repo):raise SystemExit('Unsafe source')
|
||||
data=p.read_bytes()
|
||||
if hashlib.sha256(data).hexdigest()!=v['after']:raise SystemExit('Reviewed source changed: '+n)
|
||||
contents['source/'+n]=data
|
||||
for n,v in m['dependencies'].items():
|
||||
if hashlib.sha256((repo/n).read_bytes()).hexdigest()!=v:raise SystemExit('Dependency changed: '+n)
|
||||
for n in ['install.php','file_installer.php','MANIFEST.json','feedback-config.json']:contents[n]=(here/n).read_bytes()
|
||||
if hashlib.sha256(contents['feedback-config.json']).hexdigest()!=m['configurationSha256']:raise SystemExit('Configuration changed')
|
||||
target.mkdir(parents=True,mode=0o700)
|
||||
for n,data in contents.items():
|
||||
p=target/n;p.parent.mkdir(parents=True,exist_ok=True);p.write_bytes(data);p.chmod(0o640)
|
||||
(target/'PACKAGE_HASHES.json').write_text(json.dumps({n:hashlib.sha256(v).hexdigest() for n,v in contents.items()},indent=2)+'\n')
|
||||
print('Private staging package created:',target,'; no running module, settings or control changes.')
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"version": 1,
|
||||
"installationId": "e3a08f9e-af12-4695-99bd-8b51c0520021",
|
||||
"assetId": "anlage01-virtual-ev",
|
||||
"managerId": 17004,
|
||||
"batteryInstanceId": 44234,
|
||||
"mode": "virtual_split",
|
||||
"allowEstimatedForTrial": false,
|
||||
"maxSkewSeconds": 30,
|
||||
"maxAgeSeconds": 60,
|
||||
"idleToleranceW": 50.0,
|
||||
"trackingToleranceW": 200.0,
|
||||
"sources": [
|
||||
{
|
||||
"key": "grid",
|
||||
"variableId": 40348,
|
||||
"parentId": 11490,
|
||||
"ident": "Power_8",
|
||||
"factorToW": 1000,
|
||||
"role": "grid"
|
||||
},
|
||||
{
|
||||
"key": "physical_goodwe1",
|
||||
"variableId": 47725,
|
||||
"parentId": 19742,
|
||||
"ident": "A_6_3_35182",
|
||||
"factorToW": -1,
|
||||
"role": "physical"
|
||||
},
|
||||
{
|
||||
"key": "physical_goodwe2",
|
||||
"variableId": 35724,
|
||||
"parentId": 57658,
|
||||
"ident": "A_6_3_35182",
|
||||
"factorToW": -1,
|
||||
"role": "physical"
|
||||
},
|
||||
{
|
||||
"key": "physical_solaredge",
|
||||
"variableId": 21447,
|
||||
"parentId": 30789,
|
||||
"ident": "Value",
|
||||
"factorToW": 1,
|
||||
"role": "physical"
|
||||
},
|
||||
{
|
||||
"key": "ev_requested",
|
||||
"variableId": 19651,
|
||||
"parentId": 58448,
|
||||
"ident": "Nennleistung_Soll_EV",
|
||||
"factorToW": 1.0,
|
||||
"role": "ev_request"
|
||||
},
|
||||
{
|
||||
"key": "sdl_requested",
|
||||
"variableId": 38943,
|
||||
"parentId": 58448,
|
||||
"ident": "Nennleistung_Soll_SDL",
|
||||
"factorToW": 1.0,
|
||||
"role": "sdl_request"
|
||||
},
|
||||
{
|
||||
"key": "gateway_active",
|
||||
"role": "gateway_active",
|
||||
"variableId": 23483,
|
||||
"parentId": 58448,
|
||||
"ident": "State",
|
||||
"factorToW": 1.0
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/** File-only installation helpers. No module classes loaded from the staging tree. */
|
||||
function v4FeedbackWrite(string $path, string $content, int $mode=0644): void
|
||||
{
|
||||
if (is_link($path)) throw new RuntimeException('Symlink wird nicht ersetzt.');
|
||||
$temp=tempnam(dirname($path),'.v4-feedback-');
|
||||
if ($temp===false) throw new RuntimeException('Temporaere Datei nicht verfuegbar.');
|
||||
try {
|
||||
if (file_put_contents($temp,$content,LOCK_EX)!==strlen($content) || !chmod($temp,$mode) || !rename($temp,$path)) throw new RuntimeException('Atomarer Dateitausch fehlgeschlagen.');
|
||||
} finally { if(is_file($temp))unlink($temp); }
|
||||
}
|
||||
|
||||
function v4FeedbackFiles(string $stage,string $target): array
|
||||
{
|
||||
$allowed=['libs/NetzfahrplanV4Rueckmeldung.php','libs/BatterieNetzfahrplanV4RueckmeldungTrait.php','libs/NetzfahrplanV4Regeltest.php',
|
||||
'libs/BatterieNetzfahrplanV4TestTrait.php','libs/ManagerNetzfahrplanV4TestTrait.php','libs/ManagerNetzfahrplanV4EmpfangTrait.php','libs/BatterieRegler.php','Batterie/module.php','Manager/module.php'];
|
||||
$m=json_decode((string)file_get_contents($stage.'/MANIFEST.json'),true,32,JSON_THROW_ON_ERROR);
|
||||
if (($m['scope']??null)!=='corrected_feedback_trial_disabled' || count($m['files']??[])!==count($allowed) || array_diff(array_keys($m['files']),$allowed)) throw new RuntimeException('Unerwarteter Dateiumfang.');
|
||||
if (realpath($target)!==$target || is_link($target)) throw new RuntimeException('Modulpfad unerwartet.');
|
||||
foreach($m['dependencies'] as $name=>$hash) {
|
||||
if (!preg_match('~^libs/[A-Za-z0-9]+\.php$~D',$name) || is_link($target.'/'.$name) || hash_file('sha256',$target.'/'.$name)!==$hash) throw new RuntimeException('Abhaengigkeit wurde parallel geaendert: '.$name);
|
||||
}
|
||||
$before=[];$source=[];$already=true;
|
||||
// Explicit dependency order. Both top-level modules are replaced only after all dependencies.
|
||||
foreach($allowed as$name) {
|
||||
$path=$target.'/'.$name;$candidate=$stage.'/source/'.$name;
|
||||
if (is_link($path)||is_link($candidate)||realpath(dirname($path))!==$target.'/'.dirname($name)) throw new RuntimeException('Unerwarteter Dateipfad.');
|
||||
$source[$name]=(string)file_get_contents($candidate);
|
||||
if (hash('sha256',$source[$name])!==$m['files'][$name]['after']) throw new RuntimeException('Paketpruefsumme geaendert: '.$name);
|
||||
token_get_all($source[$name],TOKEN_PARSE);
|
||||
$before[$name]=is_file($path)?file_get_contents($path):null;
|
||||
$hash=$before[$name]===null?null:hash('sha256',$before[$name]);
|
||||
if (!in_array($hash,[$m['files'][$name]['before'],$m['files'][$name]['after']],true)) throw new RuntimeException('Paralleler Modulstand; nichts ueberschrieben: '.$name);
|
||||
if($hash!==$m['files'][$name]['after'])$already=false;
|
||||
}
|
||||
if($already)return ['status'=>'already_installed','backup'=>null];
|
||||
$backup=$stage.'/backups/'.gmdate('Ymd\THis\Z').'-'.bin2hex(random_bytes(4));
|
||||
if(!mkdir($backup,0700,true))throw new RuntimeException('Sicherung fehlgeschlagen.');
|
||||
foreach($allowed as$name) {
|
||||
if($before[$name]!==null) {
|
||||
$dest=$backup.'/'.$name;if(!is_dir(dirname($dest)))mkdir(dirname($dest),0700,true);
|
||||
v4FeedbackWrite($dest,$before[$name],0600);
|
||||
}
|
||||
}
|
||||
v4FeedbackWrite($backup.'/MANIFEST.json',json_encode($m,JSON_THROW_ON_ERROR|JSON_PRETTY_PRINT),0600);
|
||||
$written=[];
|
||||
try {
|
||||
foreach($allowed as$name) {
|
||||
if((is_file($target.'/'.$name)?file_get_contents($target.'/'.$name):null)!==$before[$name])throw new RuntimeException('Parallele Aenderung waehrend Installation.');
|
||||
if($before[$name]===$source[$name])continue;
|
||||
v4FeedbackWrite($target.'/'.$name,$source[$name]);$written[]=$name;
|
||||
}
|
||||
} catch(Throwable $e) {
|
||||
foreach(array_reverse($written)as$name) {
|
||||
$p=$target.'/'.$name;
|
||||
if(!is_link($p)&&is_file($p)&&hash_file('sha256',$p)===$m['files'][$name]['after']) {
|
||||
if($before[$name]===null)unlink($p);else v4FeedbackWrite($p,$before[$name]);
|
||||
}
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
return ['status'=>'installed','backup'=>$backup,'filesChanged'=>$written];
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
// Execute only in Lihrenmoos Symcon. Installs code and readonly feedback mapping; never starts a trial.
|
||||
if(!function_exists('IPS_GetKernelVersion'))throw new RuntimeException('Nur im IP-Symcon-Skripteditor ausfuehren.');
|
||||
require_once __DIR__.'/file_installer.php';
|
||||
$manager=17004;$battery=44234;$locked=false;$changedMapping=false;$oldMapping=null;
|
||||
$report=['scope'=>'corrected_feedback_trial_disabled','startedAt'=>gmdate('c'),'actuatorPermissionGranted'=>false,'serverUpdateRequired'=>false];
|
||||
try {
|
||||
$hashes=json_decode((string)file_get_contents(__DIR__.'/PACKAGE_HASHES.json'),true,32,JSON_THROW_ON_ERROR);
|
||||
foreach($hashes as$name=>$hash) {
|
||||
if(str_contains($name,'..')||str_starts_with($name,'/')||is_link(__DIR__.'/'.$name)||hash_file('sha256',__DIR__.'/'.$name)!==$hash)throw new RuntimeException('Vorbereitetes Paket veraendert.');
|
||||
}
|
||||
foreach([$manager=>'{6F771B18-59D4-4C8A-B951-3B2FE9F6A2C4}',$battery=>'{437FB683-517F-4FEC-8CCB-FE6B0A62B69E}']as$id=>$module) {
|
||||
if(!IPS_InstanceExists($id)||IPS_GetInstance($id)['ModuleInfo']['ModuleID']!==$module)throw new RuntimeException('Modulzuordnung ungueltig.');
|
||||
if(IPS_HasChanges($id))throw new RuntimeException('Offene Aenderungen zuerst speichern oder verwerfen.');
|
||||
}
|
||||
$beforeM=json_decode(IPS_GetConfiguration($manager),true,128,JSON_THROW_ON_ERROR);
|
||||
$beforeB=json_decode(IPS_GetConfiguration($battery),true,128,JSON_THROW_ON_ERROR);
|
||||
if(($beforeM['NetzfahrplanAktiv']??null)!==false || ($beforeM['NetzfahrplanV4RegeltestErlaubt']??false)!==false || ($beforeB['NetzfahrplanV4RegeltestErlaubt']??false)!==false)throw new RuntimeException('Alte Fahrplanausgabe und beide Regeltestfreigaben muessen AUS bleiben.');
|
||||
$c=json_decode((string)file_get_contents(__DIR__.'/feedback-config.json'),true,32,JSON_THROW_ON_ERROR);
|
||||
$manifest=json_decode((string)file_get_contents(__DIR__.'/MANIFEST.json'),true,32,JSON_THROW_ON_ERROR);
|
||||
if(($c['managerId']??null)!==$manager || ($c['batteryInstanceId']??null)!==$battery || ($c['allowEstimatedForTrial']??null)!==false
|
||||
|| hash_file('sha256',__DIR__.'/feedback-config.json')!==$manifest['configurationSha256'])throw new RuntimeException('Falsche Rueckmeldekonfiguration.');
|
||||
$desired=json_encode($c,JSON_THROW_ON_ERROR|JSON_PRESERVE_ZERO_FRACTION);
|
||||
$oldMapping=$beforeB['NetzfahrplanV4RueckmeldungKonfiguration']??'{}';
|
||||
if(!in_array($oldMapping,['','{}',$desired],true))throw new RuntimeException('Abweichende Rueckmeldekonfiguration nicht ueberschrieben.');
|
||||
$controls=[];foreach(IPS_GetModuleList()as$module)if((IPS_GetModule($module)['Prefix']??'')==='MC')$controls=array_merge($controls,IPS_GetInstanceListByModuleID($module));
|
||||
if(count($controls)!==1||!function_exists('MC_ReloadModule'))throw new RuntimeException('Module Control nicht eindeutig.');
|
||||
$locked=IPS_SemaphoreEnter('ENELIX.V4.FeedbackInstall',3000);if(!$locked)throw new RuntimeException('Installation bereits aktiv.');
|
||||
$report['files']=v4FeedbackFiles(__DIR__,'/var/lib/symcon/modules/Enelix-EMS');
|
||||
if(MC_ReloadModule($controls[0],'Enelix-EMS')===false)throw new RuntimeException('Bibliotheks-Reload fehlgeschlagen.');
|
||||
$afterM=json_decode(IPS_GetConfiguration($manager),true,128,JSON_THROW_ON_ERROR);
|
||||
$afterB=json_decode(IPS_GetConfiguration($battery),true,128,JSON_THROW_ON_ERROR);
|
||||
foreach([[$beforeM,$afterM],[$beforeB,$afterB]]as$pair)foreach($pair[0]as$key=>$value)if(!array_key_exists($key,$pair[1])||$pair[1][$key]!==$value)throw new RuntimeException('Bestehender Parameter beim Reload veraendert: '.$key);
|
||||
if(!array_key_exists('NetzfahrplanV4RueckmeldungKonfiguration',$afterB)||!array_key_exists('NetzfahrplanV4RegeltestErlaubt',$afterM)
|
||||
||!function_exists('ENELIX_GetV4BatterieRueckmeldung')||!function_exists('ENELIX_GetV4ManagerTestStatus')) {
|
||||
$report['status']='waiting_for_registration';
|
||||
echo "Dateien installiert. Modulregistrierung wird abgeschlossen; diesen Aufruf einmal wiederholen. Keine Stellfreigabe.\n";
|
||||
} else {
|
||||
if($afterM['NetzfahrplanV4RegeltestErlaubt']!==false||$afterB['NetzfahrplanV4RegeltestErlaubt']!==false)throw new RuntimeException('Unerwartete Testfreigabe.');
|
||||
if($afterB['NetzfahrplanV4RueckmeldungKonfiguration']!==$desired) {
|
||||
IPS_SetProperty($battery,'NetzfahrplanV4RueckmeldungKonfiguration',$desired);$changedMapping=true;IPS_ApplyChanges($battery);
|
||||
}
|
||||
$finalM=json_decode(IPS_GetConfiguration($manager),true,128,JSON_THROW_ON_ERROR);
|
||||
$finalB=json_decode(IPS_GetConfiguration($battery),true,128,JSON_THROW_ON_ERROR);
|
||||
foreach([[$beforeM,$finalM],[$beforeB,$finalB]]as$pair)foreach($pair[0]as$key=>$value)if($key!=='NetzfahrplanV4RueckmeldungKonfiguration'&&(!array_key_exists($key,$pair[1])||$pair[1][$key]!==$value))throw new RuntimeException('Bestehender Parameter unerwartet veraendert: '.$key);
|
||||
if(($finalM['NetzfahrplanAktiv']??null)!==false||($finalM['NetzfahrplanV4RegeltestErlaubt']??null)!==false||($finalB['NetzfahrplanV4RegeltestErlaubt']??null)!==false)throw new RuntimeException('Unerwartete Stellfreigabe nach Installation.');
|
||||
$f=json_decode(ENELIX_GetV4BatterieRueckmeldung($battery),true,32,JSON_THROW_ON_ERROR);
|
||||
$report['feedback']=array_intersect_key($f,array_flip(['status','kind','method','reason','reasons','estimated','batteryW','gridW','sourceOldestAt','checkedAt','configHash','usableForTrial','canDispatch']));
|
||||
$report['status']='corrected_feedback_installed_trial_disabled';$report['originalParametersPreserved']=true;
|
||||
echo "OK: Korrigierte physische Rueckmeldung mit Manager-Vorschau und Batterietreiber verbunden.\n";
|
||||
echo 'Rueckmeldung: '.($f['status']??'available').'; Modellanteil: '.(($f['estimated']??false)?'ja':'nein').".\n";
|
||||
if(isset($f['reason']))echo 'Aktueller Hinweis: '.$f['reason']."\n";
|
||||
echo "Beide Regeltestfreigaben AUS. Keine V4-Ausgabe aktiviert; vorhandene Regelung, Energiekonten und Datensender bleiben bestehen.\n";
|
||||
}
|
||||
} catch(Throwable $e) {
|
||||
$report['status']='needs_review';$report['reason']=substr($e->getMessage(),0,260);
|
||||
if($changedMapping && $oldMapping!==null) {
|
||||
try{IPS_SetProperty($battery,'NetzfahrplanV4RueckmeldungKonfiguration',$oldMapping);IPS_ApplyChanges($battery);$report['mappingRestored']=true;}catch(Throwable $ignored){$report['mappingRestored']=false;}
|
||||
}
|
||||
echo 'FEHLER: '.$report['reason']."\nKeine V4-Stellfreigabe erteilt.\n";
|
||||
} finally {
|
||||
$report['finishedAt']=gmdate('c');v4FeedbackWrite(__DIR__.'/INSTALL_RESULT.json',json_encode($report,JSON_THROW_ON_ERROR|JSON_PRETTY_PRINT),0644);
|
||||
if($locked)IPS_SemaphoreLeave('ENELIX.V4.FeedbackInstall');
|
||||
echo 'FEEDBACK INSTALL REPORT: '.__DIR__."/INSTALL_RESULT.json\n";
|
||||
}
|
||||
Reference in New Issue
Block a user