"ON AIR Schalter" soll auf Verbindungsabbruch reagieren

Bei der Gelegenheit kommt mir in den Sinn, mal wieder anzufragen, ob der dringende Wunsch nach einer procedure OnEncoderConnectionStateChange(…); noch in @Torben s Blickpunkt ist.

1 Like

Ja, ist es, aber Torben muss da an mehreren Stellen im Code ansetzen.
In Dortmund gibt es zwar keinen Wäldchestag, aber vielleicht, wer weiß… :upside_down_face:

1 Like

Ja ist denn schon Wäldchestag?
Nein, aber das Freitags-Update. :upside_down_face:

Bitte mal v6.3.11 Build 4433 testen:

Version 6.3.11 Build 4433 (2021-05-21)

(...)
[+] Background scripts: Added OnEncoderConnectionStateChange


(Testbericht folgt.)

2 Likes

Zwecks Ausprobieren: Welche Variablen werden der Prozedur denn mitgegeben?

Sorry, das ist leider nicht bekannt. Ich bin an der Stelle tatsächlich nur der Überbringer der guten Nachricht.

Na, dann müssen wir halt noch ein wenig herwarten. Klebe @Torben doch bitte einen gelben Zettel auf den Schreibtisch.

@Torben: Welche Variablen bringt denn diese Prozedur mit?

Die Antwort befindet sich - wie immer - im Background Script Template.mls im Programmverzeichnis:

// Called when the state of an encoder connection changes
procedure OnEncoderConnectionStateChange(Connection: IEncoderConnection; OldState, NewState: TEncoderConnectionState);
begin
end;
1 Like

Ups, die hatte ich natürlich übersehen, sorry. :face_with_hand_over_mouth:

Frage noch dazu: Wie packe ich die IEncoderConnection an? Also:

if Connection = … then

Wie hat die Abfrage auszusehen? Etwa

if Connection.GetCustomCaption = 'Encodername' then

?

Ja, über die CustomCaption zu gehen wäre eine Möglichkeit.

Oder du ermittelst den 0-basierten-Index in der Liste der Verbindungen:

idx := Encoder.GetConnections.IndexOf(Connection);
1 Like

Funktioniert:

const
  BUTTONNAME = 'SIGNAL.ENC';

var
  Count: integer;
  EncoderState: Array of integer;

procedure OnLoad; 
var
  i: integer;
begin
  Count := Encoder.GetConnections.GetCount;
  SetLength(EncoderState, Count);
  for i := 0 to Count - 1 do
  begin
    if Encoder.GetConnections.GetItem(i).GetState = ecsConnected then
      EncoderState[i] := 1
    else
      EncoderState[i] := 0;
  end;
end;

procedure OnEncoderConnectionStateChange(Connection: IEncoderConnection; 
  OldState, NewState: TEncoderConnectionState);
var
  i, c: integer;
begin
  i := Encoder.GetConnections.IndexOf(Connection);
  if NewState = ecsConnected then
    EncoderState[i] := 1
  else if (NewState = ecsDisconnected) AND (OldState = ecsConnected) then
    EncoderState[i] := 0;
  c := 0;
  Encoder.GetConnections.BeginRead;
  try
    for i := 0 to Count - 1 do
      c := c + EncoderState[i];
    if c = 0 then
      ExecuteCommand(BUTTONNAME + ' BACKGROUNDCOLOR #FF0000')
    else if c = Count then
      ExecuteCommand(BUTTONNAME + ' BACKGROUNDCOLOR #00FF00')
    else
      ExecuteCommand(BUTTONNAME + ' BACKGROUNDCOLOR #FFFF00');
  finally
    Encoder.GetConnections.EndRead;
  end;
end;

begin
end.

[Statischer Text namens SIGNAL.ENC ändert die Farbe:

  • Grün: Alle Encoder sind verbunden,

  • rot: Kein Encoder ist verbunden,

  • gelb: Mindestens ein Encoder (jedoch nicht alle) ist getrennt.]

Danke, @Torben!

5 Likes

Ich bin ja kein Freund von Polling Scripten und würde gerne das Script was wir hier gebastelt haben: Ansteuerung des OnAirScreen - #19 by shorty.xs Mit dieser neuen Funktion aufbereiten.

Kann ich da einfach die Zeile procedure OnTimer austauschen und das neue Procedure nutzen?
Gilt das setzen eines Hakens oder das entfernen eines Hakens, innerhalb der Einstellungen auch als State Change?

Ja, dafür ist es gemacht. Du mußt das Skript halt entsprechend anpassen. Ich hatte es mit Setzen und Entfernen von Haken ausprobiert und es klappt.

Hmm…

Ich hatte da so die schräge Idee, dieses Skript bzw. die Funktionalität mit dem hier zu ersetzen, aber: Das Skript wird erfolgreich geladen, die Anklick-Funktionen (s. u.) klappen, aber es ändert sich farbentechnisch nichts.

Mein Weg:
Ich habe einen statischen Text namens SIGNAL.ENC (als Anklick-Aktion wird der Encoder gestartet/getrennt) sowie das Skript als *.mls abgespeichert und natürlich dann als Background-Script laufen. Es ist nur ein Encoder eingerichtet bei mir. Hab ich etwas vergessen?

@UliNobbe : Kann wohl auch in die Skript-Ecke verschoben werden, denke ich… :wink:

Ich krieg dieses Script nicht richtig zum laufen. Leider auch keine Fehlermeldung, deshalb bin ich etwas ratlos.

Ich habe:

  • Einen Statischen Text mit der Fernsteuerungs-ID “SIGNAL.ENC”. Den kann ich auch per Kommando erreichen (über die Fernsteuerungskonsole kann ich den umfärben und so)
  • Das Script als Hintergrundscript gestartet
  • Bekomme beim Start einen grünen Button, weil der Encoder sich erfolgreich verbunden hat

Wenn ich jetzt aber meinen VPN Kanal zum Icecast-Server trenne um einen Ausfall zu simulieren, geht der Encoder-Status von Online (1/1) auf Verbinde… (0/1) aber meine SIGNAL.ENC Anzeige bleibt grün. Sollte sie nicht gelb werden?
Wenn ich den Encoder manuell trenne, wird die Anzeige rot.

Keine Fehlermeldung, weil alles so läuft wie vorgesehen:

Wie gesagt:

Du betreibst nur einen einzigen Encoder. Trennst Du ihn (indem Du das Häkchen entfernst), sind also alle getrennt, die Anzeige leuchtet rot.

Korrekt, denn die Anzeige reagiert auf vollständige Trennung („disconnected“). Klaust Du des Encoders Verbindung, so will er sich möglichst schnell wiederaufschalten, der Zustand ist also ein anderer („connecting“).

Ersetze die Zeile

else if (NewState = ecsDisconnected) AND (OldState = ecsConnected) then

durch

else if ((NewState = ecsDisconnected) OR (NewState = ecsConnecting)) 
  AND (OldState = ecsConnected)) then

Dann funktioniert es auch für Deine Anforderung. (Was in der Praxis ja auch sinnvoll ist. Das obige Skript war eher ein Beispiel für die Funktionalität der Prozedur.)

2 Likes

Moin!

Ich bekomme folgenden Fehler:

19.07.2021 09:45:47 Fehler       Fehler beim Laden des Hintergrund-Scripts D:\mAirList\scripts\Signal.mls: [Error] (32:32): 'THEN' expected

Das Skript sieht bei mir so aus:

const
  BUTTONNAME = 'SIGNAL.ENC';

var
  Count: integer;
  EncoderState: Array of integer;

procedure OnLoad; 
var
  i: integer;
begin
  Count := Encoder.GetConnections.GetCount;
  SetLength(EncoderState, Count);
  for i := 0 to Count - 1 do
  begin
    if Encoder.GetConnections.GetItem(i).GetState = ecsConnected then
      EncoderState[i] := 1
    else
      EncoderState[i] := 0;
  end;
end;

procedure OnEncoderConnectionStateChange(Connection: IEncoderConnection; 
  OldState, NewState: TEncoderConnectionState);
var
  i, c: integer;
begin
  i := Encoder.GetConnections.IndexOf(Connection);
  if NewState = ecsConnected then
    EncoderState[i] := 1
  else if ((NewState = ecsDisconnected) OR (NewState = ecsConnecting)) 
  AND (OldState = ecsConnected)) then
    EncoderState[i] := 0;
  c := 0;
  Encoder.GetConnections.BeginRead;
  try
    for i := 0 to Count - 1 do
      c := c + EncoderState[i];
    if c = 0 then
      ExecuteCommand(BUTTONNAME + ' BACKGROUNDCOLOR #FF0000')
    else if c = Count then
      ExecuteCommand(BUTTONNAME + ' BACKGROUNDCOLOR #00FF00')
    else
      ExecuteCommand(BUTTONNAME + ' BACKGROUNDCOLOR #FFFF00');
  finally
    Encoder.GetConnections.EndRead;
  end;
end;

begin
end.

Nebenbei noch eine Frage: Ich würde gerne auch den Button-Text dem Zustand entsprechend anpassen, im Moment erschliesst sich mir nämlich nicht, ob das Skript dieses tut…

Mit einem erweiterten Button vielleicht? Mal prüfen, ob und wie das ginge.