Ankündigung

Einklappen
Keine Ankündigung bisher.

AVM Plugin

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    AVM Plugin

    Wiki-Seite bei smarthomeNG: https://github.com/smarthomeNG/smarthome/wiki/AVM
    Aktuelle Version: 0.914

    ----
    Hallo zusammen,

    auch wenn meine Feature-Ideen noch grenzenlos sind, habe ich gerade meinen Arbeitsstand des AVM Plugins zum Ausprobieren in den DEV Bereich des smarthomeNG Github Projekts geschoben.

    Alles ist nun auf TR-064 Basis, Ziel war es, die Features des FritzBox Plugins im Wesentlichen neu abzubilden und zu erweitern - mir hatte einiges gefehlt. Auch war mir wichtig, beliebig viele AVM Geräte parallel ansprechen zu können.

    Die Anbindung des CallMonitor-Service der FB habe ich zudem ziemlich aufgebohrt. Aktuell tracked er den letzten (bzw. aktuell aktiven) Anruf - incoming oder outgoing -, dessen Dauer (Counter in sep. Thread) usw. Das Ganze erweitere ich demnächst noch für eine getrennte "Buchhaltung" von incoming, outgoing und dem letzten verpassten Anruf (Eventübergang RING -> DISCONNECT).

    Wichtig wäre mir zu allem Anfang, dass ihr testet und bei Fehlern debugged. Ich bin nicht sicher, ob die TRY-CATCH Blöcke schon vernünftig funktionieren und ich denke auch, dass man Performanceoptimierungen machen kann. Wichtig: das Ding ist noch Alpha und ich committe es deswegen auch noch nicht ins SmartHomeNG GITHub Repo. Meine Programmiererfahrung in Python ist zudem noch relativ gering, komme aus der Java-Welt. Habe trotzdem versucht, einige Tipps von https://wiki.python.org/moin/PythonS...erformanceTips zu berücksichtigen. Ein Loop dauert bei mir mit allen in der readme.md angegeben Items ca 15 Sek.

    Getestet habe ich mit den drei AVM Geräten FritzBox 7490 (FRITZ!OS 06.51), einem FRITZ! WLAN Repeater 1750E (FRITZ!OS 06.32) und einem
    WLAN Repeater 300E (FRITZ!OS 06.30), die ich parallel durch Mehrfachinstantiierung des Plugins eingebunden habe. Das Plugin sollte zudem parallel zu den alten Plugins betreibbar sein, auch wenn es sein kann, dass die FB dann überlastet wird..

    Jetzt bin ich erstmal über Feedback, Debugging, Featurerequests etc. dankbar.

    PS: Ich habe alles unter Python 3.4 laufen, daher kann unter 3.2 durchaus noch ein Problem sein...
    Zuletzt geändert von psilo; 20.04.2016, 18:06.

    #2
    Link nun oben ergänzt...

    Kommentar


      #3
      Coole Sache - vielen Dank.

      Frage: Kann man damit auch anrufe an IP Telefone (z.B. **620) auslösen? Das ging mit dem alten Plugin nicht.

      Kommentar


        #4
        Meine DECT Telefone gehen, reine IP Telefone weiß ich nicht, da ich keine habe ;-) Ich nutze die Standard API, ich würde behaupten mehr als das was geht geht nicht
        Ich verwende - wie meines Wissens auch das alte Plugin - die X_AVM-DE_DialNumber aus der http://avm.de/fileadmin/user_upload/...x_voipSCPD.pdf. Wenn hier mehr eingebunden werden muss für VOIP und mir das jemand sagen kann, baue ichs gerne. Wie gesagt, kann aber leider nur mit DECT testen..

        Ein IP Telefon müsste ja auch nie interne Nummer haben, oder? Ich mache das bei mir bspw. so:

        sh.fritzbox_7490.set_call_origin("**610")
        sh.fritzbox_7490.start_call('**9')

        **610 ist die interne Nummer meines Mobilteils 1. **9 Rundruf.

        Am besten einfach mal testen und schauen was rauskommt.. Wie gesagt: es kann auch noch Fehler geben. Drum ist testen und autonomes Analysieren für mich gerade wichtig.. Für mich pers. läuft alles, aber es muss halt noch robust werden..
        Zuletzt geändert von psilo; 04.04.2016, 17:39.

        Kommentar


          #5
          Im Develop wäre es jetzt auch: https://github.com/smarthomeNG/smarthome

          Und irgendwie bin ich immer noch zu doof für Pull-Requests...

          Kommentar


            #6
            Okay, ich teste es mal bei Zeiten. Die Ip Telefone haben die internen NUmmer **620 und folgende, früher ging es mit
            sh.fritzbox.call('**610', '**620') nicht

            Kommentar


              #7
              Der App an meinem Handy hat er die **620 gegeben, ist das dann äquivalent? dann kann ich morgen mal testen.. Wenn das so funktioniert und ich testen kann, schaue ich gerne auch nochmal die ganze VOIP API durch.. jetzt bin ich noch warm mit dem Zeug.. Gibt aber wohl auch Limitierungen, der CallMonitor von der FB gibt wohl bei internen Calls keine Info-Zeilen aus... Hab den Output schon genauer analysiert. Das stört mich auch, weil die Sprechanlage dranhängt..

              Kommentar


                #8
                Noch jemand eine Idee wie ich einen verpassten Anruf ermitteln könnte? Dachte erst mit Eventreihenfolge RING -> DISCONNECT geht das vernünftig, wenn der AB aber annimmt, kriege ich ein RING -> CONNECT. Ich kann jetzt über die Nebenstelle rausfinden, ob der AB drangegangen ist.

                Frage wäre aber, ob man irgendwie abheben kann, so lange der interne AB noch aktiv ist?! Das könnte meine Auswertung dann wieder aushebeln..

                Kommentar


                  #9
                  Hi,

                  ich kann Dir bei Deiner eigentlichen Frage nicht helfen, aber bei der Nebenfrage: Mit den Fritz-Telefonen kann man, solange der AB noch läuft, das Gespräch übernehmen. Die blenden einen passenden Menüpunkt ein. Also: Ja, mann kann abheben. Wie die Eventreihenfolge hierbei aussieht weiß ich leider nicht.

                  Gruß, Waldemar

                  Kommentar


                    #10
                    Hmmm mein FritzFon hat zwar etwas mit AB gesagt, ich habe aber nicht gerafft, wie ich abheben kann, war aber ein interner Testanruf.. Dann analysiere ich mal via Handy auf Festnetz weiter, ob es was bringt, den "last missed call" zu bestimmen oder ob einfach der letzte eingehende (mit "duration" Angabe) nicht ausreicht..

                    Ok Analyseergebnis.. AB hebt mit Angabe Nebenstelle 40 ab (CONNECT). Wenn ich dann vom Telefon abhebe gibt es kein weiteres Event. Heißt: es lässt sich nicht eindeutig bestimmen, ob ein Anruf wirklich "verpasst" wurde.. Dementsprechend lasse ich den weiterentwickelten CM jetzt mal auf "letzter / laufender eingehender" und "letzter / laufender ausgehender" Anruf inkl. "live" Update der laufenden Dauer.
                    Zuletzt geändert von psilo; 05.04.2016, 11:24.

                    Kommentar


                      #11
                      @Marcov: bei mir geht aktuell ein

                      Code:
                      [COLOR=#94558d]self[/COLOR].set_call_origin([COLOR=#008080][B]"**610"[/B][/COLOR])
                      [COLOR=#94558d]self[/COLOR].start_call([COLOR=#008080][B]'**620'[/B][/COLOR])
                      Die App am Handy klingelt - bin nur nicht sicher, ob das exakt das Verhalten von VOIP ist?!

                      Kommentar


                        #12
                        Anbei mal ein kleiner Screenshot mit modifiziertem Widget aus dem Widget-Repo. Je nach Event verändert sich natürlich auch das Icon, so wie im Standardwidget auch:

                        Code:
                        {{ basic.symbol(id~'ring', gad_event, '', icon1~'phone_ring.png', 'ring') }}
                        {{ basic.symbol(id~'call', gad_event, '', icon1~'phone_call_out.png', 'call') }}
                        {{ basic.symbol(id~'connect', gad_event, '', icon1~'phone_call.png', 'connect') }}
                        {{ basic.symbol(id~'disconnect', gad_event, '', 'icons/ws/phone_call_end.svg', 'disconnect') }}

                        widget.png

                        Kommentar


                          #13
                          sehr schöne Arbeit

                          Grüße Ronny

                          Kommentar


                            #14
                            Zitat von psilo Beitrag anzeigen
                            Noch jemand eine Idee wie ich einen verpassten Anruf ermitteln könnte?
                            Wie meinst du das? Hab ich noch nicht verstanden.
                            Du bekommst aus der Fritzbox den Status des Anrufs:
                            1 = ankommende Verbindung, die entgegengenommen wurde
                            2 = ankommende Verbindung, die niemand entgegengenommen hat (sog. verpasster Anruf)
                            3 = abgehende Verbindung

                            Laut tr064, von TAM den Eintrag wenn der Anrufbeantworter zugeschlagen hat, auch die URL zum download des Voice Files, Zeitpunkt etc.
                            Oder meinst du etwas anderes?
                            Ich stecke da jetzt aber nicht so tief in der tr064 wie du nach der ganzen Arbeit am Plugin.

                            Übrigens sehr gute Arbeit! Danke dafür.
                            Freue mich schon drauf das neue Plugin anzubinden.

                            Kommentar


                              #15
                              @cmalo: ja nur nimmt der AB den Anruf entgegen und der CallMonitor Service quittiert das mit einem CONNECTED. Normal hätte ich "verpassten Anruf" mit RING und DISCONNECTED ermittelt.. Ich halte immer das letzte Event. Wenn jetzt der AB drangeht, kriege ich den zwar über die Nebenstellen-ID heraus (40-44), ABER wenn ich wärend der Anrufer auf den AB spricht noch abhebe, kriege ich genau das nicht mehr mit. Daher ist aus meiner Sicht nicht wirklich 100%ig ermittelbar, ob ein Anruf "wirklich" verpasst wurde. Wie im Widget zu sehen ist es sinnvoller, den letzten eingehenden und ausgehenden anzuzeigen. Man selber kann ja dann "interpolieren" ob der letzte eingehende angenommen wurde oder nicht..

                              Das alte Plugin war da deutlich grobgranularer und hat nichtmal Zustandsübergänge berücksichtigt. Im übrigen checke ich auch explizit auf die CallId. Bitte nicht erschrecken - und noch keine Gewähr auf Fehler. In ersten Tests läuft es bei mir aber gut durch ;-):

                              Code:
                              def _trigger(self, call_from, call_to, time, callid, branch):
                                      """
                                      Triggers the event: sets item values and looks up numbers in the phone book.
                                      """
                                      event = self._event[callid]
                              
                                      if event == 'RING':
                                          self._call_incoming_cid = callid # set call id for incoming call
                                          self._duration_item['call_duration_incoming'](0) # reset duration for incoming calls
                                          for item in self._items_incoming:  # update items for incoming calls
                                              if item.conf['avm_data_type'] in ['is_call_incoming']:
                                                  item(1)
                                              if item.conf['avm_data_type'] in ['is_call_outgoing']:
                                                  item(0)
                                              elif item.conf['avm_data_type'] in ['last_caller_incoming']:
                                                  item(self._callback(call_from))
                                              elif item.conf['avm_data_type'] in ['last_call_date_incoming']:
                                                  item(time)
                                              elif item.conf['avm_data_type'] in ['call_event_incoming']:
                                                  item(event.lower())
                                          for item in self._items: # update generic items
                                              if item.conf['avm_data_type'] in ['call_event']:
                                                  item(event.lower())
                                              elif item.conf['avm_data_type'] in ['call_direction']:
                                                  item("incoming")
                                      elif event == 'CALL':
                                          self._call_outgoing_cid = callid # set call id for outgoing call
                                          self._duration_item['call_duration_outgoing'](0) # reset duration for outgoing calls
                                          for item in self._items_outgoing:  # update items for outgoing calls
                                              if item.conf['avm_data_type'] in ['is_call_incoming']:
                                                  item(0)
                                              elif item.conf['avm_data_type'] in ['is_call_outgoing']:
                                                  item(1)
                                              elif item.conf['avm_data_type'] in ['last_caller_outgoing']:
                                                  item(self._callback(call_to))
                                              elif item.conf['avm_data_type'] in ['last_call_date_outgoing']:
                                                  item(time)
                                              elif item.conf['avm_data_type'] in ['call_event_outgoing']:
                                                  item(event.lower())
                                          for item in self._items:  # update generic items
                                              if item.conf['avm_data_type'] in ['call_event']:
                                                  item(event.lower())
                                              elif item.conf['avm_data_type'] in ['call_direction']:
                                                  item("outgoing")
                                      else: #connect und disconnect
                                          if event == 'CONNECT':
                                              # start counter thread
                                              if self._old_event[callid] == "CALL":  # start counter thread only if duration item set and call is outgoing
                                                  if self._duration_item['call_duration_outgoing'] != None:
                                                      self._start_counter(time, 'outgoing', callid)
                                              elif self._old_event[callid] == "RING":  # start counter thread only if duration item set and call is incoming
                                                  if self._duration_item['call_duration_incoming'] != None:
                                                      self._start_counter(time, 'incoming', callid)
                                              # set item attributes
                                              if self._old_event[callid] == "CALL":
                                                  for item in self._items_outgoing:
                                                      if item.conf['avm_data_type'] in ['call_event_outgoing']:
                                                          item(event.lower())
                                              elif self._old_event[callid] == "RING":
                                                  for item in self._items_incoming:
                                                      if item.conf['avm_data_type'] in ['call_event_incoming']:
                                                          item(event.lower())
                                          elif event == 'DISCONNECT':
                                              # stop counter threads
                                              if callid == self._call_incoming_cid:
                                                  for item in self._items_incoming:
                                                      if item.conf['avm_data_type'] in ['call_event_incoming']:
                                                          item(event.lower())
                                                      elif item.conf['avm_data_type'] in['is_call_incoming']:
                                                          item(0)
                                                  if self._duration_item['call_duration_incoming'] != None:
                                                      self._stop_counter('incoming')
                                                      self._call_incoming_cid = None
                                              elif callid == self._call_outgoing_cid:
                                                  for item in self._items_outgoing:
                                                      if item.conf['avm_data_type'] in ['call_event_outgoing']:
                                                          item(event.lower())
                                                      elif item.conf['avm_data_type'] in ['is_call_outgoing']:
                                                          item(0)
                                                  if self._duration_item['call_duration_outgoing'] != None:
                                                      self._stop_counter('outgoing')
                                                      self._call_outgoing_cid = None
                              
                                              # set item attributes
                                              if self._old_event[callid] == "CALL":
                                                  for item in self._items_outgoing:
                                                      if item.conf['avm_data_type'] in ['call_event_outgoing']:
                                                          item(event.lower())
                                              elif self._old_event[callid] == "RING":
                                                  for item in self._items_incoming:
                                                      if item.conf['avm_data_type'] in ['call_event_incoming']:
                                                          item(event.lower())
                                          for item in self._items:
                                              if item.conf['avm_data_type'] in ['call_event']:
                                                  item(event.lower())

                              Kommentar

                              Lädt...
                              X