[Debian-iot-packaging] [openzwave-controlpanel] 33/81: Capture query stage information. Add testing a single device as well as entire network. Support sending Basic class values. Make sure last access times are updated. Handle new notifications. Fix bug in empty association arrays. Track awake/sleeping/dead device status. Support request/response/unsolicited statistics.

Dara Adib daradib-guest at moszumanska.debian.org
Thu Dec 22 16:57:48 UTC 2016


This is an automated email from the git hooks/post-receive script.

daradib-guest pushed a commit to branch debian/master
in repository openzwave-controlpanel.

commit c48bcd91af21a91b1bee9a0c4b4d22098c728638
Author: glsatz <glsatz at gmail.com>
Date:   Sat Jan 5 03:02:16 2013 +0000

    Capture query stage information.
    Add testing a single device as well as entire network.
    Support sending Basic class values.
    Make sure last access times are updated.
    Handle new notifications.
    Fix bug in empty association arrays.
    Track awake/sleeping/dead device status.
    Support request/response/unsolicited statistics.
---
 cp.html       | 110 +++++++++++++++++++++++-----------------------------------
 cp.js         |  25 ++++++++-----
 ozwcp.cpp     |  39 +++++++++++++++++++--
 webserver.cpp |  65 +++++++++++++++++++++++++---------
 4 files changed, 145 insertions(+), 94 deletions(-)

diff --git a/cp.html b/cp.html
index f9cba08..8800fc4 100644
--- a/cp.html
+++ b/cp.html
@@ -307,11 +307,14 @@
 		    <th style="text-align: center;">Failed</th>
 		    <th style="text-align: center;">Retries</th>
 		    <th style="text-align: center;">Received</th>
+		    <th style="text-align: center;">Unsolicited</th>
 		    <th style="text-align: center;">Duplicates</th>
 		    <th style="text-align: center;">Last Sent</th>
 		    <th style="text-align: center;">Last Received</th>
-		    <th style="text-align: center;">Last RTT</th>
-		    <th style="text-align: center;">Average RTT</th>
+		    <th style="text-align: center;">Last Request RTT</th>
+		    <th style="text-align: center;">Average Request RTT</th>
+		    <th style="text-align: center;">Last Response RTT</th>
+		    <th style="text-align: center;">Average Response RTT</th>
 		    <th style="text-align: center;">Quality</th>
 		  </tr>
 		</thead>
@@ -358,6 +361,8 @@
 	  <div id="thcntl" name="thcntl" class="rsb" style="display: none; margin-right: 5px;">
 	    <div class="rsb" style="margin-left: 5px;">
 	      <button id="testbutton" name="testbutton" onclick="return TestHealLoad('test');" type="submit">Run</button>
+	      <label><span class="legend" style="font-size: 12px;">Node:</span></label>
+	      <input id="testnode" type="text" size="5" class="legend">
 	      <label><span class="legend" style="font-size: 12px;">Message count:</span></label>
 	      <input id="testmcnt" type="text" size="5" class="legend">
 	    </div>
@@ -444,79 +449,52 @@
 		<th>Location</th>
 		<th>Value</th>
 		<th>Last Heard</th>
+		<th>Status</th>
 	      </tr>
 	    </thead> <tbody id="tbody">
 	      <tr>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
 	      </tr>
 	      <tr>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
 	      </tr>
 	      <tr>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
 	      </tr>
 	      <tr>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
-		<td> <br>
-		</td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
+		<td> <br> </td>
 	      </tr>
 	    </tbody>
 	  </table>
diff --git a/cp.js b/cp.js
index dd4583f..cc42e86 100644
--- a/cp.js
+++ b/cp.js
@@ -214,7 +214,7 @@ function PollReply()
 		     name: elem[i].getAttribute('name'), location: elem[i].getAttribute('location'),
 		     listening: elem[i].getAttribute('listening') == 'true', frequent: elem[i].getAttribute('frequent') == 'true',
 		     beam: elem[i].getAttribute('beam') == 'true', routing: elem[i].getAttribute('routing') == 'true',
-		     security: elem[i].getAttribute('security') == 'true',
+		     security: elem[i].getAttribute('security') == 'true', status: elem[i].getAttribute('status'),
 		     values: null, groups: null};
 	var k = 0;
 	var values = elem[i].getElementsByTagName('value');
@@ -332,7 +332,7 @@ function PollReply()
 	  }
 	  if (exthelp.length > 0)
 	    exthelp = exthelp.substr(0, exthelp.length - 2);
-	  stuff=stuff+'<tr id="node'+i+'" onmouseover="this.className=\'highlight\';" onmouseout="if (this.id == curnode) this.className=\'click\'; else this.className=\'normal\';" onclick="return SaveNode(this.id);" ondblClick="ClearNode(); return DisplayNode();"><td onmouseover="ShowToolTip(\''+exthelp+'\',0);" onmouseout="HideToolTip();">'+nodes[i].id+ext+'</td><td>'+nodes[i].btype+'</td><td>'+nodes[i].gtype+'</td><td>'+nodes[i].manufacturer+' '+nodes[i].product+'</td><td>'+nodes[i].name+'</ [...]
+	  stuff=stuff+'<tr id="node'+i+'" onmouseover="this.className=\'highlight\';" onmouseout="if (this.id == curnode) this.className=\'click\'; else this.className=\'normal\';" onclick="return SaveNode(this.id);" ondblClick="ClearNode(); return DisplayNode();"><td onmouseover="ShowToolTip(\''+exthelp+'\',0);" onmouseout="HideToolTip();">'+nodes[i].id+ext+'</td><td>'+nodes[i].btype+'</td><td>'+nodes[i].gtype+'</td><td>'+nodes[i].manufacturer+' '+nodes[i].product+'</td><td>'+nodes[i].name+'</ [...]
 	  CreateDivs('user', divcur, i);
 	  CreateDivs('config', divcon, i);
 	  CreateDivs('system', divinfo, i);
@@ -1403,12 +1403,18 @@ function TestHealLoad(fun)
 {
   var params='fun='+fun;
   if (fun == 'test') {
+    var cnt = document.getElementById('testnode');
+    if (cnt.value.length == 0) {
+      params = params+'&num=0';
+    } else {
+      params = params+'&num='+cnt.value;
+    }
     var cnt = document.getElementById('testmcnt');
     if (cnt.value.length == 0) {
       alert('Missing count value');
       return false;
     }
-    params = params+'&num='+cnt.value;
+    params = params+'&cnt='+cnt.value;
   } else if (fun == 'heal') {
     var cnt = document.getElementById('healnode');
     if (cnt.value.length == 0) {
@@ -1559,17 +1565,18 @@ function CreateDivs(genre,divto,ind)
   if (nodes[ind].values != null) {
       var j = 0;
     for (var i = 0; i < nodes[ind].values.length; i++) {
-      if (nodes[ind].values[i].genre != genre)
+      var match;
+      if (genre == 'user')
+	match = (nodes[ind].values[i].genre == genre || nodes[ind].values[i].genre == 'basic');
+      else
+	match = (nodes[ind].values[i].genre == genre);
+      if (!match)
 	continue;
-      var lastclass='';
-      var vid=nodes[ind].id+'-'+nodes[ind].values[i].cclass+'-'+genre+'-'+nodes[ind].values[i].type+'-'+nodes[ind].values[i].instance+'-'+nodes[ind].values[i].index;
+      var vid=nodes[ind].id+'-'+nodes[ind].values[i].cclass+'-'+nodes[ind].values[i].genre+'-'+nodes[ind].values[i].type+'-'+nodes[ind].values[i].instance+'-'+nodes[ind].values[i].index;
       j++;
       if (nodes[ind].values[i].type == 'bool') {
 	divto[ind]=divto[ind]+CreateOnOff(ind,i,vid);
       } else if (nodes[ind].values[i].type == 'byte') {
-	if (lastclass == 'BASIC' && cls == 'SWITCH MULTILEVEL')
-	  divto[ind]='';
-	lastclass=nodes[ind].values[i].cclass;
 	divto[ind]=divto[ind]+CreateTextBox(ind,i,vid);
       } else if (nodes[ind].values[i].type == 'int') {
 	divto[ind]=divto[ind]+CreateTextBox(ind,i,vid);
diff --git a/ozwcp.cpp b/ozwcp.cpp
index e5004e2..4a57873 100644
--- a/ozwcp.cpp
+++ b/ozwcp.cpp
@@ -447,6 +447,8 @@ void OnNotification (Notification const* _notification, void* _context)
 	       id.GetIndex(), valueTypeStr(id.GetType()));
     pthread_mutex_lock(&nlock);
     nodes[_notification->GetNodeId()]->addValue(id);
+    nodes[_notification->GetNodeId()]->setTime(time(NULL));
+    nodes[_notification->GetNodeId()]->setChanged(true);
     pthread_mutex_unlock(&nlock);
     break;
   case Notification::Type_ValueRemoved:
@@ -456,6 +458,8 @@ void OnNotification (Notification const* _notification, void* _context)
 	       id.GetIndex(), valueTypeStr(id.GetType()));
     pthread_mutex_lock(&nlock);
     nodes[_notification->GetNodeId()]->removeValue(id);
+    nodes[_notification->GetNodeId()]->setTime(time(NULL));
+    nodes[_notification->GetNodeId()]->setChanged(true);
     pthread_mutex_unlock(&nlock);
     break;
   case Notification::Type_ValueChanged:
@@ -481,12 +485,13 @@ void OnNotification (Notification const* _notification, void* _context)
     {
       Log::Write(LogLevel_Info, "Notification: Group Home 0x%08x Node %d Group %d",
 		 _notification->GetHomeId(), _notification->GetNodeId(), _notification->GetGroupIdx());
-      uint8 *v;
+      uint8 *v = NULL;
       int8 n = Manager::Get()->GetAssociations(homeId, _notification->GetNodeId(), _notification->GetGroupIdx(), &v);
       pthread_mutex_lock(&nlock);
       nodes[_notification->GetNodeId()]->addGroup(_notification->GetNodeId(), _notification->GetGroupIdx(), n, v);
       pthread_mutex_unlock(&nlock);
-      delete [] v;
+      if (v != NULL)
+	delete [] v;
     }
     break;
   case Notification::Type_NodeNew:
@@ -530,6 +535,9 @@ void OnNotification (Notification const* _notification, void* _context)
     pthread_mutex_lock(&nlock);
     nodes[_notification->GetNodeId()]->saveValue(id);
     pthread_mutex_unlock(&nlock);
+    pthread_mutex_lock(&glock);
+    needsave = true;
+    pthread_mutex_unlock(&glock);
     break;
   case Notification::Type_NodeNaming:
     Log::Write(LogLevel_Info, "Notification: Node Naming Home %08x Node %d Genre %s Class %s Instance %d Index %d Type %s",
@@ -621,7 +629,7 @@ void OnNotification (Notification const* _notification, void* _context)
     Log::Write(LogLevel_Info, "Notification: Driver Reset, homeId %08x", _notification->GetHomeId());
     pthread_mutex_lock(&glock);
     done = false;
-    needsave = false;
+    needsave = true;
     homeId = _notification->GetHomeId();
     if (Manager::Get()->IsStaticUpdateController(homeId)) {
       cmode = "SUC";
@@ -638,12 +646,21 @@ void OnNotification (Notification const* _notification, void* _context)
     break;
   case Notification::Type_EssentialNodeQueriesComplete:
     Log::Write(LogLevel_Info, "Notification: Essential Node %d Queries Complete", _notification->GetNodeId());
+    pthread_mutex_lock(&nlock);
+    nodes[_notification->GetNodeId()]->setTime(time(NULL));
+    nodes[_notification->GetNodeId()]->setChanged(true);
+    pthread_mutex_unlock(&nlock);
     break;
   case Notification::Type_NodeQueriesComplete:
     Log::Write(LogLevel_Info, "Notification: Node %d Queries Complete", _notification->GetNodeId());
     pthread_mutex_lock(&nlock);
     nodes[_notification->GetNodeId()]->sortValues();
+    nodes[_notification->GetNodeId()]->setTime(time(NULL));
+    nodes[_notification->GetNodeId()]->setChanged(true);
     pthread_mutex_unlock(&nlock);
+    pthread_mutex_lock(&glock);
+    needsave = true;
+    pthread_mutex_unlock(&glock);
     break;
   case Notification::Type_AwakeNodesQueried:
     Log::Write(LogLevel_Info, "Notification: Awake Nodes Queried");
@@ -676,6 +693,22 @@ void OnNotification (Notification const* _notification, void* _context)
       nodes[_notification->GetNodeId()]->setChanged(true);
       pthread_mutex_unlock(&nlock);
       break;
+    case Notification::Code_Sleep:
+      Log::Write(LogLevel_Info, "Notification: Notification home %08x node %d Sleep",
+		 _notification->GetHomeId(), _notification->GetNodeId());
+      pthread_mutex_lock(&nlock);
+      nodes[_notification->GetNodeId()]->setTime(time(NULL));
+      nodes[_notification->GetNodeId()]->setChanged(true);
+      pthread_mutex_unlock(&nlock);
+      break;
+    case Notification::Code_Dead:
+      Log::Write(LogLevel_Info, "Notification: Notification home %08x node %d Dead",
+		 _notification->GetHomeId(), _notification->GetNodeId());
+      pthread_mutex_lock(&nlock);
+      nodes[_notification->GetNodeId()]->setTime(time(NULL));
+      nodes[_notification->GetNodeId()]->setChanged(true);
+      pthread_mutex_unlock(&nlock);
+      break;
     default:
       Log::Write(LogLevel_Info, "Notification: Notification home %08x node %d Unknown %d",
 		 _notification->GetHomeId(), _notification->GetNodeId(), _notification->GetNotification());
diff --git a/webserver.cpp b/webserver.cpp
index 49f1c7a..24b063f 100644
--- a/webserver.cpp
+++ b/webserver.cpp
@@ -219,7 +219,7 @@ void Webserver::web_get_groups (int n, TiXmlElement *ep)
 }
 
 /*
- * web_get_genre
+ * web_get_values
  * Retreive class values based on genres
  */
 void Webserver::web_get_values (int i, TiXmlElement *ep)
@@ -432,10 +432,13 @@ const char *Webserver::SendStatResponse (struct MHD_Connection *conn, const char
 	nodeElement->LinkEndChild(newstat("nstat", "Retried sent messages", ndata.m_retries));
 	nodeElement->LinkEndChild(newstat("nstat", "Received messages", ndata.m_receivedCnt));
 	nodeElement->LinkEndChild(newstat("nstat", "Received duplicates", ndata.m_receivedDups));
-	nodeElement->LinkEndChild(newstat("nstat", "Last sent message", ndata.m_sentTS.c_str()));
-	nodeElement->LinkEndChild(newstat("nstat", "Last received message", ndata.m_receivedTS.c_str()));
-	nodeElement->LinkEndChild(newstat("nstat", "Last RTT", ndata.m_averageRequestRTT));
-	nodeElement->LinkEndChild(newstat("nstat", "Average RTT", ndata.m_averageRequestRTT));
+	nodeElement->LinkEndChild(newstat("nstat", "Received unsolicited", ndata.m_receivedUnsolicited));
+	nodeElement->LinkEndChild(newstat("nstat", "Last sent message", ndata.m_sentTS.substr(5).c_str()));
+	nodeElement->LinkEndChild(newstat("nstat", "Last received message", ndata.m_receivedTS.substr(5).c_str()));
+	nodeElement->LinkEndChild(newstat("nstat", "Last Request RTT", ndata.m_averageRequestRTT));
+	nodeElement->LinkEndChild(newstat("nstat", "Average Request RTT", ndata.m_averageRequestRTT));
+	nodeElement->LinkEndChild(newstat("nstat", "Last Response RTT", ndata.m_averageResponseRTT));
+	nodeElement->LinkEndChild(newstat("nstat", "Average Response RTT", ndata.m_averageResponseRTT));
 	nodeElement->LinkEndChild(newstat("nstat", "Quality", ndata.m_quality));
 	while (!ndata.m_ccData.empty()) {
 	  Node::CommandClassData ccd = ndata.m_ccData.front();
@@ -474,7 +477,8 @@ const char *Webserver::SendTestHealResponse (struct MHD_Connection *conn, const
 					     const char *arg1, const char *arg2, const char *arg3)
 {
   TiXmlDocument doc;
-  int cnt;
+  int node;
+  int arg;
   bool healrrs = false;
   static char fntemp[32];
   char *fn;
@@ -485,20 +489,24 @@ const char *Webserver::SendTestHealResponse (struct MHD_Connection *conn, const
   doc.LinkEndChild(testElement);
 
   if (strcmp(fun, "test") == 0 && arg1 != NULL) {
-    cnt = atoi((char *)arg1);
-    Manager::Get()->TestNetwork(homeId, cnt);
+    node = atoi((char *)arg1);
+    arg = atoi((char *)arg2);
+    if (node == 0)
+      Manager::Get()->TestNetwork(homeId, arg);
+    else
+      Manager::Get()->TestNetworkNode(homeId, node, arg);
   } else if (strcmp(fun, "heal") == 0 && arg1 != NULL) {
     testElement = new TiXmlElement("heal");
-    cnt = atoi((char *)arg1);
+    node = atoi((char *)arg1);
     if (arg2 != NULL) {
-      int i = atoi((char *)arg2);
-      if (i != 0)
+      arg = atoi((char *)arg2);
+      if (arg != 0)
 	healrrs = true;
     }
-    if (cnt == 0)
+    if (node == 0)
       Manager::Get()->HealNetwork(homeId, healrrs);
     else
-      Manager::Get()->HealNetworkNode(homeId, cnt, healrrs);
+      Manager::Get()->HealNetworkNode(homeId, node, healrrs);
   }
 
   strncpy(fntemp, "/tmp/ozwcp.testheal.XXXXXX", sizeof(fntemp));
@@ -627,7 +635,7 @@ const char *Webserver::SendSceneResponse (struct MHD_Connection *conn, const cha
 }
 
 /*
- * SendPollRespose
+ * SendPollResponse
  * Process poll request from client and return
  * data as xml.
  */
@@ -721,6 +729,8 @@ int Webserver::SendPollResponse (struct MHD_Connection *conn)
     j = 1;
     while (j <= MyNode::getNodeCount() && i < MAX_NODES) {
       if (nodes[i] != NULL && nodes[i]->getChanged()) {
+	bool listening;
+	bool flirs;
 	TiXmlElement* nodeElement = new TiXmlElement("node");
 	pollElement->LinkEndChild(nodeElement);
 	nodeElement->SetAttribute("id", i);
@@ -730,12 +740,33 @@ int Webserver::SendPollResponse (struct MHD_Connection *conn)
 	nodeElement->SetAttribute("location", Manager::Get()->GetNodeLocation(homeId, i).c_str());
 	nodeElement->SetAttribute("manufacturer", Manager::Get()->GetNodeManufacturerName(homeId, i).c_str());
 	nodeElement->SetAttribute("product", Manager::Get()->GetNodeProductName(homeId, i).c_str());
-	nodeElement->SetAttribute("listening", Manager::Get()->IsNodeListeningDevice(homeId, i) ? "true" : "false");
-	nodeElement->SetAttribute("frequent", Manager::Get()->IsNodeFrequentListeningDevice(homeId, i) ? "true" : "false");
+	listening = Manager::Get()->IsNodeListeningDevice(homeId, i);
+	nodeElement->SetAttribute("listening", listening ? "true" : "false");
+	flirs = Manager::Get()->IsNodeFrequentListeningDevice(homeId, i);
+	nodeElement->SetAttribute("frequent", flirs ? "true" : "false");
 	nodeElement->SetAttribute("beam", Manager::Get()->IsNodeBeamingDevice(homeId, i) ? "true" : "false");
 	nodeElement->SetAttribute("routing", Manager::Get()->IsNodeRoutingDevice(homeId, i) ? "true" : "false");
 	nodeElement->SetAttribute("security", Manager::Get()->IsNodeSecurityDevice(homeId, i) ? "true" : "false");
 	nodeElement->SetAttribute("time", nodes[i]->getTime());
+	fprintf(stderr, "i=%d failed=%d\n", i, Manager::Get()->IsNodeFailed(homeId, i));
+	fprintf(stderr, "i=%d awake=%d\n", i, Manager::Get()->IsNodeAwake(homeId, i));
+	fprintf(stderr, "i=%d state=%s\n", i, Manager::Get()->GetNodeQueryStage(homeId, i).c_str());
+	fprintf(stderr, "i=%d listening=%d flirs=%d\n", i, listening, flirs);
+	if (Manager::Get()->IsNodeFailed(homeId, i))
+	  nodeElement->SetAttribute("status", "Dead");
+	else {
+	  string s = Manager::Get()->GetNodeQueryStage(homeId, i);
+	  if (s == "Complete") {
+	    if (i != nodeId && !listening && !flirs)
+	      nodeElement->SetAttribute("status", Manager::Get()->IsNodeAwake(homeId, i) ? "Awake" : "Sleeping" );
+	    else
+	      nodeElement->SetAttribute("status", "Ready");
+	  } else {
+	    if (i != nodeId && !listening && !flirs)
+	      s = s + (Manager::Get()->IsNodeAwake(homeId, i) ? " (awake)" : " (sleeping)");
+	    nodeElement->SetAttribute("status", s.c_str());
+	  }
+	}
 	web_get_groups(i, nodeElement);
 	// Don't think the UI needs these
 	//web_get_genre(ValueID::ValueGenre_Basic, i, nodeElement);
@@ -903,6 +934,8 @@ int web_config_post (void *cls, enum MHD_ValueKind kind, const char *key, const
       cp->conn_arg1 = (void *)strdup(data);
     if (strcmp(key, "num") == 0)
       cp->conn_arg2 = (void *)strdup(data);
+    if (strcmp(key, "cnt") == 0)
+      cp->conn_arg3 = (void *)strdup(data);
     if (strcmp(key, "healrrs") == 0)
       cp->conn_arg3 = (void *)strdup(data);
   } else if (strcmp(cp->conn_url, "/confparmpost.html") == 0) {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-iot/openzwave-controlpanel.git



More information about the Debian-iot-packaging mailing list