Anfänger Fragen zur Modulentwicklung - Unifi Network Api

Das mal raus.. weil Strings in PHP sind binary-safe und base64_encode erzeugt nur noch viel mehr overhead.

Und hier:

Reicht ein

return $snapshot;

Im Gerät kommt dann hier in $JSONString direkt der Bin-Payload an.

@paresy oder kann es sein, das der Rückgabewert eventuell nicht binär sicher ist?
Michael

Auf dem weg bekomm ich zwar kein Limit Fehler, aber das Bild ist nicht lesbar und auch im Debug sieht der $snapshot String dann im Device anders aus als im Gateway.

In der Symcon Doku habe ich noch Beispiele mit utf8_encode /utf8_decode gesehen, damit läufts dann wieder in den Limit Fehler…

Hab ich denn noch andere Möglichkeiten das Bild zu übergeben oder wäre es dann besser die ID des Medienobjekts zu übergeben und das schreiben direkt aus dem Gateway zu machen?

Eventuell ist irgendwo noch eine fehlende konvertierung?
IPS_SetMediaContent braucht ja wieder das base64…

Ich arbeite bei den Rückgabewerten gerne mit serialize und unserialize.
So kann ich auch ganze Arrays oder Objekte zurückgeben. Eventuell wäre das was für dich, wenn ich mir deinen Code bei ForwardData im Gateway anschaue.
Dann kannst du das wie folgt ändern und brauchst auch nirgendwo eine InstanzID im Datenaustausch.

	case "getDevices":
		$array = $this->getDevices($data->Param1);
		//$this->send($data->InstanceID,$data->Api,json_encode($array));
		//break;
		return serialize($array);

Und z.B. im Device:

	public function Send(string $api, string $param1)
	{
		if ($this->HasActiveParent()) {
			$value = $this->SendDataToParent(json_encode(['DataID' => '{BBE44630-5AEE-27A0-7D2E-E1D2D776B83B}',
			'Api' => $api,
			/*'InstanceID' => $this->InstanceID,*/
			'Param1' => $param1
			]));
			if ($value) {
				return unserialize($value)
			}
			return false;
		}			
	}

Das ist bestimmt für das JSON, welches auch die DataID benötigt (also für die Parameter bei den Funktionen und nicht bei dem Rückgabewert). Damit json_encode nicht über die Rohdaten stolpert.

Ne, das sieht ja vorher schon anders aus und das base64 hab ich dann im Device eingebaut. IPS_SetMediaContent($MedienID, base64_encode($snapshot));
Was das Gateway sendet (Snapshot:):
image

Was im Device ankommt (Send Data:):
image

Debug steht beides auf „Text“, sollte dann also gleich aussehen?

Ja, das muss ich ja noch komplett umbauen, da brauch ich ja auch die ID und Api nicht mehr zurückgeben, da ich ja den Kontext im Send habe, entsprechend dort ja dann passend reagieren kann…

Hab das snapshot anlegen jetzt mal in das Gateway geschoben, da muss ja dann nichts übergeben werden und es funktioniert…

public function getSnapshot(string $cameraID, int $idParent):bool {
			$ServerAddress = $this->ReadPropertyString( 'ServerAddress' );
			$APIKey = $this->ReadPropertyString( 'APIKey' );
			$ch = curl_init();
			curl_setopt( $ch, CURLOPT_URL, 'https://'.$ServerAddress.'/proxy/protect/integration/v1/cameras/' . $cameraID . '/snapshot?forceHighQuality=false' );
			curl_setopt( $ch, CURLOPT_HTTPGET, true );
			curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
			curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
			curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
			curl_setopt( $ch, CURLOPT_HTTPHEADER, array( 'X-API-KEY:'.$APIKey ) );
			curl_setopt( $ch, CURLOPT_SSLVERSION, 'CURL_SSLVERSION_TLSv1' );
			$RawData = curl_exec($ch);
			curl_close( $ch );			
			if ($RawData === false) {
				// Handle error
				$this->SendDebug("UnifiPGW", "Curl error: " . curl_error($ch), 0);
				$this->SetStatus( 201 ); // Set status to error
				return '';
			}			
			$MedienID = IPS_GetObjectIDByIdent('Snapshot', $idParent);
			if ($MedienID > 0) {
				if (isset($RawData) && !empty($RawData)) {
					IPS_SetMediaFile($MedienID, 'Snapshot_'.$idParent.'.jpeg', FALSE);
					IPS_SetMediaContent($MedienID, base64_encode($RawData));
				} else {
					return false;
				}
			} else {
				return false;
			}
			return true;
		}

Und direkt auch auf serialize/unserialize umgestellt, das scheint auch gut zu klappen.

Danke nochmal!

@bgersmann
Hallo,
hast du schon einen Zeitplan wann du das Protect Modul veröffentlichen möchtest?

LG
Stefan

So bitte nicht.
Dann lass das Gerät direkt das snapshot von der API laden.
Weil:
Eine Instanz darf nur unterhalb sich selbst und nie unter anderen Objekten Objekte erstellen oder ändern.
Siehe auch Punkt 5 und 6 hier bei review

Einfache Idee wäre:
Das Gerät sagt dem Parent: hey gibt mir mal die URL für meinen Snapshot und dann lädt das Gerät das Bild selber runter :slight_smile:
Michael

1 „Gefällt mir“

Theoretisch kommt ja der Aufruf von der Instanz, wo es angelegt wird… :smiley:

Hab es nun aber angepasst und schick die url + apikey, damit klappt es nun und es bleibt unter der Instanz.

1 „Gefällt mir“

Moin,

hab da noch mal eine kleine frage:

Ich habe eine Liste im Konfigurationsformular, da soll zu jedem Eintrag eine Variable angelegt werden. Das anlegen ist auch nicht das problem, das bekomm ich im ApplyChanges hin:

$webhooksArr= json_decode($this->ReadPropertyString('webhooks'), true);
        $vpos=1;
        foreach ($webhooksArr as $webhook) {
            $name = $webhook['Name'].str_replace("-","_",$webhook['WebhookID']);
            $this->MaintainVariable( $name, $webhook['Name'], 1, [ 'PRESENTATION' => VARIABLE_PRESENTATION_ENUMERATION,'LAYOUT'=> 2, 'OPTIONS'=>'[{"Caption":"Ausführen...","Color":65280,"IconActive":false,"IconValue":"","Value":1}]', 'ICON'=> 'bell-ring'], $vpos++, 1);
            $this->MaintainAction($name, true);
            $this->SetValue( $name, 1);
            $this->SendDebug(__FUNCTION__, 'Webhook: '.$name, 0);
        }

Aber wie bekomme ich nun Variablen gelöscht die nicht mehr in der Liste stehen?

muss ich mir die per IPS_GetChildrenIDs holen und prüfen ob sie noch teil der liste ist?

Oder komm ich irgendwo an die “alte” Liste um die zu vergleichen und dann zu löschen?

$children = IPS_GetChildrenIDs($this->InstanceID);

Kannst du machen.

Leider nein.
Aber… du kannst ja am Ende von Applychanges dir die neue/aktuelle Liste in einem Attribute speichern und dann hast du beim nächsten Applychanges die alte Liste (Attribut) und die neue (Property) zur Verfügung.
Michael

1 „Gefällt mir“