IP-Symcon mit VoIP/SIP Support

Unfassbar, aber wahr. Zwar viel zu spät - aber wie man doch so schön sagt: Besser spät, als nie.

Wir haben endlich etwas, dass wir vorzeigen können. Ein Revival unseres Mega-Vote Events, welches mit dem ISDN Modul 2005 in Thema mit der Nummer 126 Premiere gefeiert hat! (Link). Wer war da schon mit dabei? :slight_smile:

Wir arbeiten daran, dass wir endlich VoIP/SIP Support zu IP-Symcon 5.1 5.2 anbieten können.
Einen ersten Vorgeschmack könnt ihr ausprobieren, indem ihr unter folgender Rufnummer anruft:

Vote-Hotline: 0451 / 30 500 511 8

Die Ergebnisse werden Live aktualisiert, nachdem ihr aufgelegt habt! (Und wir wollen nur beste Noten, bitte :D)

Auswertung: Mega-Vote Auswertung - Powered by IP-Symcon WebFront


Natürlich gibt es auch einen Gewinner!

Unter allen Teilnehmern verlosen wir eine der heiß begehrten IP-Symcon Tassen. Der Gewinner wird telefonisch oder per SMS benachrichtigt und kann den Gewinn auf dem Symcon Event 2019 feierlich entgegennehmen. Im Rahmen des Datenschutzes weise ich darauf hin, dass dazu beim Anruf eure Telefonnummer gespeichert wird. Nach Abschluss des Mega-Vote Events werden alle Daten gelöscht.

paresy

PS: Wenn unsere Vote-Hotline überlastet ist (=IP-Symcon is abgestürzt), versuche ich dies so schnell wie möglich zu korrigieren.

Anbei der Quellcode zum nachstöbern:


<?

$id_voip = 58519;
$id_tts = 34810; 
$id_text = 34742;
$id_blacklist = 36888;
$id_archive = 35323;
$id_calls = 26475;
$id_count = 22795;
$id_result = 54098;
$id_results = 56462;

if($_IPS['SENDER'] == "VoIP") {
    //We only want to handle incoming messages
    if(VOIP_GetConnection($id_voip, $_IPS["CONNECTION"])["Direction"] == 1 /* Outgoing */)
        return;

    switch($_IPS["EVENT"]) {
        case "Incoming":
            VOIP_SetData($id_voip, $_IPS["CONNECTION"], json_encode([
                "Number" => $_IPS["DATA"],
                "Vote" => 0
            ]));
            //WFC_SendNotification(31245, "Neuer Teilmehmer!", maskPhoneNumber($_IPS["DATA"]), "Telephone", 5);
            break;
        case "Connect":
            $data = json_decode(VOIP_GetData($id_voip, $_IPS["CONNECTION"]), true);
            $blacklist = json_decode(GetValue($id_blacklist), true);
            $found = false;
            foreach($blacklist as $number) {
                if($number == $data["Number"]) {
                    VOIP_PlayWave($id_voip, $_IPS["CONNECTION"], IPS_GetKernelDir() . "/media/abgelehnt.wav");
                    $data["Vote"] = -1;
                    VOIP_SetData($id_voip, $_IPS["CONNECTION"], json_encode($data));
                    $found = true;
                    break;                  
                }
            }
            if(!$found) {
                VOIP_PlayWave($id_voip, $_IPS["CONNECTION"], IPS_GetKernelDir() . "/media/willkommen.wav");
            }
            break;
        case "Disconnect":
            $data = json_decode(VOIP_GetData($id_voip, $_IPS["CONNECTION"]), true);
            SetValue($id_calls, $data["Number"] . " = " . $data["Vote"]);
            break;
        case "DTMF":
            $data = json_decode(VOIP_GetData($id_voip, $_IPS["CONNECTION"]), true);
            if($data["Vote"] != 0) {
                VOIP_PlayWave($id_voip, $_IPS["CONNECTION"], IPS_GetKernelDir() . "/media/fertig.wav");
            } else {
                switch($_IPS["DATA"]) {
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                        VOIP_PlayWave($id_voip, $_IPS["CONNECTION"], IPS_GetKernelDir() . "/media/danke_".$_IPS["DATA"].".wav");
                        $data["Vote"] = $_IPS["DATA"];
                        VOIP_SetData($id_voip, $_IPS["CONNECTION"], json_encode($data));

                        //Add to blacklist
                        if($data["Vote"] == 6) {
                            $blacklist = json_decode(GetValue($id_blacklist), true);
                            $blacklist[] = $data["Number"];
                            SetValue($id_blacklist, json_encode($blacklist));
                        }

                        break;        
                    case '#':
                        VOIP_PlayWave($id_voip, $_IPS["CONNECTION"], TTSAWSPOLLY_GenerateFile($id_tts, GetValue($id_text)));
                        break;
                    default:    
                        VOIP_PlayWave($id_voip, $_IPS["CONNECTION"], IPS_GetKernelDir() . "/media/ungueltig.wav");
                        break;                 
                }
            }
    }
}

//Source: https://medium.com/@yemiwebby/replace-some-characters-with-asterisks-in-php-using-str-repeat-2c78b3899bad
function maskPhoneNumber($number){   
    return str_repeat("*", strlen($number)-4) . substr($number, -4);
}

//Get all calls. This is not efficient, but does the job for our low volume hotline.
$calls = AC_GetLoggedValues($id_archive, $id_calls, 0, 0, 0);
$result = 0;
$count = 0;
foreach($calls as $call) {
    if(preg_match("/.*\ =\ (\d)/", $call["Value"], $matches)) {
        $result += intval($matches[1]);
        $count++;
    }
}

SetValue($id_count, $count);
SetValue($id_result, number_format($result / $count, 2));

//Render table only with latest calls...
$calls = array_splice($calls, 0, 10);

$html = "<table style='width: 100%; border-collapse: collapse;'>";
$html .= "<tr>";
$html .= "<td style='padding: 5px; font-weight: bold;'>Datum/Uhrzeit</td>";
$html .= "<td style='padding: 5px; font-weight: bold;'>Telefonnummer</td>";
$html .= "<td style='padding: 5px; font-weight: bold;'>Note</td>";
$html .= "</tr>";

foreach($calls as $call) {
    preg_match("/(.*) = (.*)/", $call["Value"], $result);

    if($result[2] == -1) {
        $result[2] = "Blockiert";
    } else if($result[2] == 0) {
        $result[2] = "Abgebrochen";
    }   

    $html .= "<tr style='border-top: 1px solid rgba(255,255,255,0.10);'>";
    $html .= "<td style='padding: 5px;'>".date("d.m.Y H:i", $call["TimeStamp"])."</td>";
    $html .= "<td style='padding: 5px;'>".maskPhoneNumber($result[1])."</td>";
    $html .= "<td style='padding: 5px;'>".$result[2]."</td>";
    $html .= "</tr>";
}

$html .= "</table>";

SetValue($id_results, $html);

?>

Beipspiel zum Anrufen und Nachricht hinterlassen. (Etwas simpel. Es geht auch schöner über Events ;))


 $id = VOIP_Connect(56175, "0451305005xx");

 for($i = 0; $i <= 10; $i++) {
     IPS_Sleep(1000);
     $c = VOIP_GetConnection(56175, $id);
     if($c['Connected']) {
        VOIP_PlayWave(56175, $id, IPS_GetKernelDir() . "/media/willkommen.wav");
        //VOIP_PlayWave(56175, $id, TTSAWSPOLLY_GenerateFile(34810, "Alarm! Es brennt im Keller!"));
        return;
     }
 }

 VOIP_Disconnect(56175, $id);

MegaVoteAudio.zip (996 KB)

Ich habe heute Mittag noch überlegt, als der Thread mit der Keynote kam, irgendetwas neues muss es geben. [emoji3]

Genial! [emoji4]

Edit: Funktioniert! [emoji4] richtig cool!

Grüße,
Kai

Gesendet von iPhone mit Tapatalk

Ich :).

Das war meine erste „Fernbedienung“ um im Garten Licht, Wasserspiel, etc. zu schalten.

Sehr cool! Habe gleich mal eine 1 mit Sternchen gegeben :slight_smile:

Hoffentlich funktioniert das auch unter Linux?

wer ist denn ***mous ??

Wahrscheinlich Anonymous

Freue mich schon auf die erste Beta :slight_smile:

ich auch :D:D;)

Oh ja, ich mich auch [emoji1360][emoji1360]

Gesendet von iPhone mit Tapatalk

ich würde mir einen VOIP Türklingel Support mit Video wünschen. Pop up in der App mit Video und Buttons für Verbindung mit sprechen und Türöffner…

Da schließe ich mich an ! Das wäre super !

Sehr schön, danke! Für mich liegt der Schwerpunkt auf ausgehenden Anrufen zur Sprachbenachrichtigung/Alarmierung.

Auch das wird möglich sein. :slight_smile:

paresy

Sehr gut. Die Anforderung habe ich auch im diversen Projekten.

wann gibt es denn die erste Beta Version zum testen ? :D:D:D

Gut, dass einer den Mut hatte die Frage zu stellen :smiley:

Ein bisschen Geduld müsst ihr noch haben. Ich habe zwischenzeitlich den Quellcode im ersten Beitrag hinzugefügt und ein simples Beispiel, wie man einen Anruf mit Alarmierung realisieren können.

Bisher läuft es super stabil auf meiner Entwickler SymBox (noch ein ganz alte mit CM1 ;))

paresy

Hi,

so, hab das gerade mal probiert:

vom Handy, lüppt sauber, erkennt die DTMF Signale und sagt sie an.

vorher:
per Groundwire (auf iPhone 7+) direkt zum SIP Account des Providers (Pepcom/PYUR).
erkennt die DTMF nicht !, daher erscheint dann im Protokoll abgebrochen.

nach dem erfolgreichen Handytest (in der Hoffnung Groundwire sei das Problem)

Siemens SL910 --> Siemens Analog Basis ! --> FB7390 --> Ubiquiti USG --> SIP PYUR
mag auch nicht !

In der Fritzbox ist unter

Telefonie --> eigene Rufnummern --> dierichtige --> weitere Einstellungen (DTMF)

A) das Teil gesetzt auf Automatisch, alternativ könnte man:
B) INFO, RTP oder Inband
C) RTP oder Inband
D) Inband ****************** hiermit schnurrt es wie eine Katze ******************

Fritzfon --> FB7390 --> Ubiquiti USG --> SIP PYUR
will ebenso nicht !

Vermute mal es liegt am Provider oder in der FB,
jemand ´nen Tip?

mfg

BerndJ

PS: selber hin bekommen, einfach inband eintragen statt automatisch und schon läuft es.

Eine Frage

Welche Schnittstelle muss ich den ansprechen?

Hi,

A) das Teil gesetzt auf Automatisch, alternativ könnte man:
B) INFO, RTP oder Inband
C) RTP oder Inband
D) Inband ****************** hiermit schnurrt es wie eine Katze ******************

Bei DTMF gibt es verschiedene Möglichkeiten DTM zu übertragen:

  1. Inband -> DTMF als Tonsignal, muß im Empfänger vom DSP ausgewertet werden
  2. INFO -> DTMF kommt als SIP-Kommando („notify“)
  3. RTP -> DTMF kommt als Steuerbefehl im Mediastream
    Alle verfahren müssen vom Empfänger ausgewertet werden können.
    Herausforderung ist jedoch die Übertragung über verschiedene Instanzen, wie bei Dir. Dazu kommen noch die Providerschnittstellen…

Am besten mal mit wireshark zwischen Telefon und Router gucken was 'rausgeht und bei IPS was ankommt.

Viele Grüße aus OBC

kea