Subversion Repositories HomeAutomation

Rev

Rev 2237 | Rev 2257 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1.  
  2. Sensor_ModuleNames    = [ "DS18x20", "FOST02", "BusVoltage", "SimpleDTMF", "DHT11", "VoltageCurrent", "ultrasonic" ];
  3. SensorRf_ModuleNames    = [ "rfTransceive" ];
  4. Sensor_Intervals      = function() { return [ 1, 5, 10, 15, 20 ]; };
  5. Sensor_Aliases        = function() { return Module_GetAliasNames(Sensor_ModuleNames); };
  6. Sensor_AvailableIds   = function() { return Module_GetAvailableIds(Sensor_ModuleNames); };
  7.  
  8. function Sensor_SetReportInterval(alias_name, interval)
  9. {
  10.     if (arguments.length < 2)
  11.     {
  12.         Log("\033[31mNot enough parameters given.\033[0m\n");
  13.         return false;
  14.     }
  15.  
  16.     var aliases_data = Module_ResolveAlias(alias_name, Sensor_ModuleNames);
  17.     var found = false;
  18.  
  19.     for (var name in aliases_data)
  20.     {
  21.         var variables = {"Time"     : interval };
  22.         if (Module_SendMessage(aliases_data[name]["module_name"], aliases_data[name]["module_id"], "Report_Interval", variables))
  23.         {
  24.             Log("\033[32mCommand sent successfully to " + name + ".\033[0m\n");
  25.         }
  26.         else
  27.         {
  28.             Log("\033[31mFailed to send command to " + name + ".\033[0m\n");
  29.         }
  30.  
  31.         found = true;
  32.     }
  33.  
  34.     if (!found)
  35.     {
  36.         Log("\033[31mNo aliases by the name " + alias_name + " were applicable for this command.\033[0m\n");
  37.         return false;
  38.     }
  39.  
  40.     return true;
  41. }
  42. Console_RegisterCommand(Sensor_SetReportInterval, function(arg_index, args) { return Console_StandardAutocomplete(arg_index, args, Sensor_Aliases(), Sensor_Intervals()); });
  43.  
  44. Sensor_OnNewPhonenumberFunctions = [];
  45.  
  46. function Sensor_RegisterToNewPhonenumber(alias_name, callback)
  47. {
  48.   if (!Sensor_OnNewPhonenumberFunctions[alias_name])
  49.   {
  50.     Sensor_OnNewPhonenumberFunctions[alias_name] = [];
  51.   }
  52.  
  53.   Sensor_OnNewPhonenumberFunctions[alias_name].push(callback);
  54. }
  55.  
  56. Sensor_OnDeviceStateChangeFunctions = [];
  57.  
  58. function Sensor_RegisterToDeviceStateChange(alias_name, callback)
  59. {
  60.   if (!Sensor_OnDeviceStateChangeFunctions[alias_name])
  61.   {
  62.     Sensor_OnDeviceStateChangeFunctions[alias_name] = [];
  63.   }
  64.  
  65.   Sensor_OnDeviceStateChangeFunctions[alias_name].push(callback);
  66. }
  67.  
  68.  
  69. function Sensor_OnMessage(module_name, module_id, command, variables)
  70. {
  71.   if (in_array(Sensor_ModuleNames, module_name))
  72.   {
  73.     var aliases_data = Module_LookupAliases({
  74.       "module_name" : module_name,
  75.       "module_id"   : module_id,
  76.       "group"       : false
  77.     });
  78.  
  79.     switch (command)
  80.     {
  81.       case "Phonenumber":
  82.       {
  83.         for (var alias_name in aliases_data)
  84.         {
  85.           var number = variables["Number"];
  86.           var incommingCall = true;
  87.           var checkName = true;
  88.  
  89.           Log("received from DTMF:\"" + number + "\"");
  90.  
  91.           if (variables["Number"].length >= 6)
  92.           {
  93.             /* A seems to mean it is an incomming call! */
  94.             if (number.charAt(0) === 'A' || number.charAt(0) === 'D')
  95.             {
  96.               incommingCall = true;
  97.  
  98.               /* Remove leading A */
  99.               number = number.substring(1);
  100.             }
  101.             else /* Outgoing call */
  102.             {
  103.               incommingCall = false;
  104.             }
  105.  
  106.             /* A number can have a trailing C */
  107.             var endIndex = number.indexOf('C');
  108.  
  109.             if (endIndex !== -1)
  110.             {
  111.               /* Remove trailing C */
  112.               number = number.substring(0, endIndex);
  113.             }
  114.           }
  115.           else if (number == "B00C")
  116.           {
  117.             /* Unknown number */
  118.             number = "Unknown";
  119.             incommingCall = true;
  120.             checkName = false;
  121.           }
  122.           else if (number == "B10C")
  123.           {
  124.             /* Secret/protected number */
  125.             number = "Protected";
  126.             incommingCall = true;
  127.             checkName = false;
  128.           }
  129.           else
  130.           {
  131.             Log("DTMF decoded number is to short, number: \"" + number + "\", length: " + number.length);
  132.             return;
  133.           }
  134.          
  135.           /* Adding area code prefix if needed */
  136.           if (number.charAt(0) != '0' && checkName)
  137.           {
  138.             if (typeof sensorDefaultPhoneAreaCode === 'undefined')
  139.             {
  140.               Log("\033[31mOnlinePhonebook: please add sensorDefaultPhoneAreaCode = yourAreaCode to autostart.js, defaulting to 031\033[0m\n");
  141.               number = "031" + number;
  142.             }
  143.             else
  144.             {
  145.                 number = sensorDefaultPhoneAreaCode + number;
  146.             }
  147.           }
  148.  
  149.           /* Store number and direction in last values */
  150.           var lastValue = {};
  151.           var lastValueString = Storage_GetParameter("LastValues", alias_name);
  152.  
  153.           if (lastValueString)
  154.           {
  155.             lastValue = JSON.parse(lastValueString);
  156.           }
  157.  
  158.           var timestamp = get_time();
  159.  
  160.           lastValue["Phonenumber"] = { "value" : number, "timestamp" : timestamp };
  161.           lastValue["Direction"] = { "value" : incommingCall ? "in" : "out", "timestamp" : timestamp };
  162.  
  163.           Storage_SetParameter("LastValues", alias_name, JSON.stringify(lastValue));
  164.  
  165.  
  166.           /* Store number in phone call history */
  167.           var newValue = { "number" : number, "direction" : incommingCall ? "in" : "out", "module" : alias_name, "names" : [], "timestamp" : timestamp };
  168.  
  169.           Storage_SetParameter("PhoneCalls", timestamp, JSON.stringify(newValue));
  170.  
  171.  
  172.           /* Log the number */
  173.           Log("New number: " + number + ", direction: " + (incommingCall ? "in" : "out"));
  174.          
  175.           /* Lookup name */
  176.           if (checkName)
  177.           {
  178.             Sensor_StoreNumberInPhonebook(number, timestamp);
  179.           }
  180.  
  181.           var phonebookNumbers = Storage_GetJsonParamter("PhoneBook", number);
  182.           if (!phonebookNumbers)
  183.           {
  184.             phonebookNumbers = [];
  185.           }
  186.          
  187.           /* Call any potential subscribers */
  188.           if (Sensor_OnNewPhonenumberFunctions[alias_name])
  189.           {
  190.             for (var n in Sensor_OnNewPhonenumberFunctions[alias_name])
  191.             {
  192.               /* Call callback with arguments alias, number, direction */
  193.               Sensor_OnNewPhonenumberFunctions[alias_name][n](alias_name, number, incommingCall ? "in" : "out", phonebookNumbers);
  194.             }
  195.           }
  196.         }
  197.         break;
  198.       }
  199.       case "Voltage":
  200.       case "Temperature_Celsius":
  201.       {
  202.         if ((module_name == "DS18x20") && (variables["Value"] == 85))
  203.         {
  204.           Log("\033[31mDS18x20: Temperature conversion error: " + module_name + ":" + module_id + ", SensorId=" + variables["SensorId"] + "\033[0m");
  205.           break;
  206.         }
  207.       }
  208.       case "Humidity_Percent":
  209.       case "Percent":
  210.       case "Distance":
  211.       {
  212.         for (var alias_name in aliases_data)
  213.         {
  214.           if (aliases_data[alias_name]["specific"]["SensorId"] != variables["SensorId"])
  215.           {
  216.             continue;
  217.           }
  218.  
  219.           var last_value = {};
  220.           var last_value_string = Storage_GetParameter("LastValues", alias_name);
  221.  
  222.           if (last_value_string)
  223.           {
  224.             last_value = eval("(" + last_value_string + ")");
  225.           }
  226.  
  227.           last_value[command] = { "value" : variables["Value"], "timestamp" : get_time() };
  228.  
  229.           Storage_SetParameter("LastValues", alias_name, JSON.stringify(last_value));
  230.         }
  231.  
  232.         break;
  233.       }
  234.     }
  235.   }
  236. }
  237. Module_RegisterToOnMessage("all", Sensor_OnMessage);
  238.  
  239. function SensorRf_OnMessage(module_name, module_id, command, variables)
  240. {
  241.     if (in_array(SensorRf_ModuleNames, module_name))
  242.     {
  243.         var aliases_data = Module_LookupAliases({
  244.         "module_name" : module_name,
  245.         "module_id"   : module_id,
  246.         "group"       : false   });
  247.        
  248.         /* Must check sensor here in case no alias is stored the adress needs to be printed */
  249.         var RubicsonSuccess = "NoRubicsonSensor";
  250.         var VikingSuccess = "NoVikingSensor";
  251.         var VikingSteakSuccess = "NoVikingSteakSensor";
  252.         if (variables["Protocol"] == "Rubicson")
  253.         {
  254.             /*
  255.                       ??? aaaaaaaa sttttttttttt hhhhhhhh cccccccc
  256.             341731651126    0b100 11111001 000011001011 00101110 00110110   20.3 46%
  257.             a = address, s = sign, t = temperature, h = humidity, c = crc
  258.             */
  259.             var data = variables["IRdata"];
  260.             var unknown = rshift(data,26)&0x3FF;
  261.             //var crc = data&0xFF;
  262.             //var humidity = (data>>>8)&0xFF;
  263.             var temp = (data>>>12)&0xFFF;
  264.             var addr = rshift(data,24)&0x3;
  265.             //var calccrc=crc8(rshift(data,8), 32);
  266.                    
  267.             var sign = (temp>>>11)&1;
  268.             if (sign > 0)
  269.             {
  270.                 temp = temp^0xFFF;
  271.                 temp += 1;
  272.                 temp = -temp;
  273.             }
  274.             temp = temp/10;
  275.  
  276.             RubicsonSuccess = "RubicsonNotFound";
  277.            
  278.         } else if (variables["Protocol"] == "Viking")
  279.         {
  280.             /*
  281.                               ??? aaaaaaaa sttttttttttt hhhhhhhh cccccccc
  282.             341731651126    0b100 11111001 000011001011 00101110 00110110   20.3 46%
  283.             a = address, s = sign, t = temperature, h = humidity, c = crc
  284.             */
  285.             var data = variables["IRdata"];
  286.             var crc = data&0xFF;
  287.             var humidity = (data>>>8)&0xFF;
  288.             var temp = (data>>>16)&0xFFF;
  289.             var addr = rshift(data,28)&0xFF;
  290.             var unknown = rshift(data,36)&0xF;
  291.             var calccrc=crc8(rshift(data,8), 32);
  292.  
  293.             var sign = (temp>>>11)&1;
  294.             temp = temp&0x7FF;
  295.             if (sign > 0)
  296.             {
  297.                 temp = -temp;
  298.             }
  299.             temp = temp/10;
  300.  
  301.             VikingSuccess = "VikingNotFound";
  302.            
  303.             if (unknown != 4)
  304.             {
  305.                 Log("\033[33mWarning: VikingSensor, unknown part="+unknown+", data="+data+"\033[0m");
  306.             }
  307.         } else if (variables["Protocol"] == "VikingSteak")
  308.         {
  309.             var data = variables["IRdata"];
  310.             var addr = (data>>>4)&0xFF;
  311.             var byte0 = rshift(data,32)&0xF;
  312.             var byte1 = rshift(data,28)&0xF;
  313.             var byte2 = rshift(data,24)&0xF;
  314.             var temp = Math.round((((((byte1^byte2)<<8)+((byte0^byte1)<<4)+byte0^10)-122)*5)/9);
  315.             VikingSteakSuccess = "VikingNotFound";
  316.         }
  317.                
  318.         loopAliases:    /* Label to break nested */
  319.         for (var alias_name in aliases_data)
  320.         {
  321.             if (aliases_data[alias_name]["specific"]["Channel"] == variables["Channel"] &&
  322.                 aliases_data[alias_name]["specific"]["Proto"] == variables["Protocol"])
  323.             {
  324.                 switch (variables["Protocol"])
  325.                 {
  326.                     case "Viking":
  327.                     {   /* Add alias with these specifics: Channel=0,Proto=Viking,Address=<address of sensor> */
  328.                         if (crc != calccrc)
  329.                         {
  330.                             Log("\033[31mError: VikingSensor, incorrect CRC, data="+data+", CRC="+crc+", calcCRC="+calccrc+"\033[0m");
  331.                             break loopAliases;
  332.                         }
  333.                         if (addr == aliases_data[alias_name]["specific"]["Address"])
  334.                         {
  335.                             VikingSuccess = "VikingFound";
  336.  
  337.                             var last_value = {};
  338.                             var last_value_string = Storage_GetParameter("LastValues", alias_name);
  339.  
  340.                             if (last_value_string)
  341.                             {
  342.                                 last_value = eval("(" + last_value_string + ")");
  343.                             }
  344.  
  345.                             var timestamp = get_time();
  346.                             last_value["Temperature_Celsius"] = { "value" : temp.toString(), "timestamp" : timestamp };
  347.                             if (humidity<101)
  348.                             {
  349.                                 last_value["Humidity_Percent"] = { "value" : humidity.toString(), "timestamp" : timestamp };
  350.                             }
  351.  
  352.                             Storage_SetParameter("LastValues", alias_name, JSON.stringify(last_value));
  353.                            
  354.                             break loopAliases;
  355.                         }
  356.                         break;
  357.                     }
  358.                     case "Viking":
  359.                     {   /* Add alias with these specifics: Channel=0,Proto=Viking,Address=<address of sensor> */
  360.                         /*if (crc != calccrc)
  361.                         {
  362.                             Log("\033[31mError: VikingSensor, incorrect CRC, data="+data+", CRC="+crc+", calcCRC="+calccrc+"\033[0m");
  363.                             break loopAliases;
  364.                         }*/
  365.                         if (addr == aliases_data[alias_name]["specific"]["Address"])
  366.                         {
  367.                             RubicsonSuccess = "RubicsonFound";
  368.  
  369.                             var last_value = {};
  370.                             var last_value_string = Storage_GetParameter("LastValues", alias_name);
  371.  
  372.                             if (last_value_string)
  373.                             {
  374.                                 last_value = eval("(" + last_value_string + ")");
  375.                             }
  376.  
  377.                             var timestamp = get_time();
  378.                             last_value["Temperature_Celsius"] = { "value" : temp.toString(), "timestamp" : timestamp };
  379.                             /*if (humidity<101)
  380.                             {
  381.                                 last_value["Humidity_Percent"] = { "value" : humidity.toString(), "timestamp" : timestamp };
  382.                             }
  383.                             */
  384.                             Storage_SetParameter("LastValues", alias_name, JSON.stringify(last_value));
  385.                            
  386.                             break loopAliases;
  387.                         }
  388.                         break;
  389.                     }
  390.                     case "VikingSteak":
  391.                     {   /* Add alias with these specifics: Channel=0,Proto=VikingSteak,Address=<address of sensor> */
  392.                         /* if no Address is added to the alias, all vikingSteaksensors will match*/
  393.                         if (aliases_data[alias_name]["specific"]["Address"] == undefined)
  394.                         {
  395.                             VikingSteakSuccess = "VikingFound";
  396.                             var last_value = {};
  397.                             var last_value_string = Storage_GetParameter("LastValues", alias_name);
  398.  
  399.                             if (last_value_string)
  400.                             {
  401.                                 last_value = eval("(" + last_value_string + ")");
  402.                             }
  403.  
  404.                             var timestamp = get_time();
  405.                             last_value["Temperature_Celsius"] = { "value" : temp.toString(), "timestamp" : timestamp };
  406.                             last_value["Address"] = { "value" : addr, "timestamp" : timestamp };
  407.                             Storage_SetParameter("LastValues", alias_name, JSON.stringify(last_value));
  408.                             break loopAliases;
  409.                         }
  410.                         else if (addr == aliases_data[alias_name]["specific"]["Address"])
  411.                         {
  412.                             VikingSteakSuccess = "VikingFound";
  413.                             var last_value = {};
  414.                             var last_value_string = Storage_GetParameter("LastValues", alias_name);
  415.  
  416.                             if (last_value_string)
  417.                             {
  418.                                 last_value = eval("(" + last_value_string + ")");
  419.                             }
  420.  
  421.                             var timestamp = get_time();
  422.                             last_value["Temperature_Celsius"] = { "value" : temp.toString(), "timestamp" : timestamp };
  423.                             last_value["Address"] = { "value" : addr, "timestamp" : timestamp };
  424.                             Storage_SetParameter("LastValues", alias_name, JSON.stringify(last_value));
  425.                            
  426.                             break loopAliases;
  427.                         }
  428.                         break;
  429.                     }
  430.                     case "Rubicson":
  431.                     {   /* Add alias with these specifics: Channel=0,Proto=Viking,Address=<address of sensor> */
  432.                         if (crc != calccrc)
  433.                         {
  434.                             Log("\033[31mError: Rubicson, incorrect CRC, data="+data+", CRC="+crc+", calcCRC="+calccrc+"\033[0m");
  435.                             break loopAliases;
  436.                         }
  437.                         if (addr == aliases_data[alias_name]["specific"]["Address"])
  438.                         {
  439.                             VikingSuccess = "VikingFound";
  440.  
  441.                             var last_value = {};
  442.                             var last_value_string = Storage_GetParameter("LastValues", alias_name);
  443.  
  444.                             if (last_value_string)
  445.                             {
  446.                                 last_value = eval("(" + last_value_string + ")");
  447.                             }
  448.  
  449.                             var timestamp = get_time();
  450.                             last_value["Temperature_Celsius"] = { "value" : temp.toString(), "timestamp" : timestamp };
  451.                             if (humidity<101)
  452.                             {
  453.                                 last_value["Humidity_Percent"] = { "value" : humidity.toString(), "timestamp" : timestamp };
  454.                             }
  455.  
  456.                             Storage_SetParameter("LastValues", alias_name, JSON.stringify(last_value));
  457.                            
  458.                             break loopAliases;
  459.                         }
  460.                         break;
  461.                     }
  462.                     case "Nexa2":
  463.                     {   /* Add alias with these specifics: Channel=0,Proto=Nexa2,OnData=<data for on>,OffData=<data for off> */
  464.                         var deviceStateCommand = "";
  465.                         if (variables["IRdata"] == aliases_data[alias_name]["specific"]["OnData"] && variables["Status"] == "Pressed")
  466.                         {
  467.                             deviceStateCommand = "On";
  468.                         }
  469.                         else if (variables["IRdata"] == aliases_data[alias_name]["specific"]["OffData"] && variables["Status"] == "Pressed")
  470.                         {
  471.                             deviceStateCommand = "Off";
  472.                         }
  473.                         else
  474.                         {
  475.                             break;
  476.                         }
  477.                        
  478.                         var last_value = {};
  479.                         var last_value_string = Storage_GetParameter("LastValues", alias_name);
  480.  
  481.                         if (last_value_string)
  482.                         {
  483.                             last_value = eval("(" + last_value_string + ")");
  484.                         }
  485.                        
  486.                         if (( typeof(last_value["State"]) == "undefined" ) ||
  487.                             ( deviceStateCommand == "Off" && last_value["State"]["value"] == "On" ) ||
  488.                             ( deviceStateCommand == "On" && last_value["State"]["value"] == "Off" ))
  489.                         {
  490.                             last_value["State"] = { "value" : deviceStateCommand, "timestamp" : get_time() };
  491.  
  492.                             Storage_SetParameter("LastValues", alias_name, JSON.stringify(last_value));
  493.  
  494.                             /* Call any potential subscribers */
  495.                             if (Sensor_OnDeviceStateChangeFunctions[alias_name])
  496.                             {
  497.                                 for (var n in Sensor_OnDeviceStateChangeFunctions[alias_name])
  498.                                 {
  499.                                     /* Call callback with arguments alias, state */
  500.                                     Sensor_OnDeviceStateChangeFunctions[alias_name][n](alias_name, deviceStateCommand);
  501.                                 }
  502.                             }
  503.                         }
  504.                         break;
  505.                     }
  506.                 }
  507.             }
  508.         }
  509.         if (VikingSuccess == "VikingNotFound")
  510.         {
  511.             Log("Found unknown vikingsensor address="+addr+" temperature="+temp+" humidity="+humidity+" unknown="+unknown);
  512.         }
  513.         if (VikingSteakSuccess == "VikingNotFound")
  514.         {
  515.             Log("Found unknown vikingSteaksensor address="+addr+" temperature="+temp);
  516.         }
  517.         if (RubicsonSuccess == "RubicsonNotFound")
  518.         {
  519.             Log("Found unknown Rubicson sensor address="+addr+" temperature="+temp);
  520.         }
  521.     }
  522. }
  523. Module_RegisterToOnMessage("all", SensorRf_OnMessage);
  524.  
  525. function Sensor_StoreNumberInPhonebook(number, timestamp)
  526. {
  527.   var phonebookNumbers = Storage_GetJsonParamter("PhoneBook", number);
  528.  
  529.   if (!phonebookNumbers)
  530.   {
  531.     phonebookNumbers = [];
  532.  
  533.     url = "wap.eniro.se/query?search_word=" + number + "&what=mobwp";
  534.     //Log("\033[31mURL: http://"+url+"\033[0m\n");
  535.  
  536.     Http_Request(url, function(socket_id, result, header, content_data)
  537.     {
  538.       //Log("\033[31mOnlinePhonebook-eniro: result was: " + result + "\033[0m\n");
  539.       //Log("\033[31mOnlinePhonebook-eniro: content was: " + content_data + "\033[0m\n");
  540.  
  541.       if (result.indexOf("200 OK") != -1)
  542.       {
  543.  
  544.         var lines = content_data.split("\n");
  545.  
  546.         var endString = "<anchor>Tillbaka<prev/></anchor>";
  547.         var nameStartString = "<td class=\"hTd2\">";
  548.         var nameEndString = "</table>";
  549.  
  550.         for (var n = 1; n < lines.length; n++)
  551.         {
  552.           var line = lines[n].trim("\n");
  553.  
  554.           if (line.indexOf(endString) != -1)
  555.           {
  556.             break;
  557.           }
  558.  
  559.           if (line.indexOf(nameStartString) != -1)
  560.           {
  561.             line = lines[n + 1].trim("\n");
  562.             splitted = line.split("b>");
  563.  
  564.             phonebookNumbers.push(splitted[1].substr(0, splitted[1].length - 2));
  565.             break;
  566.           }
  567.         }
  568.  
  569.         //Log("\033[31mOnlinePhonebook: Line: " + lines[1] + "\033[0m\n");
  570.         //Log("\033[31mOnlinePhonebook: Line: " + lines[2] + "\033[0m\n");
  571.         //Log("\033[31mOnlinePhonebook: Line: " + lines[3] + "\033[0m\n");
  572.         if (phonebookNumbers.length > 0)
  573.         {
  574.           Storage_SetJsonParameter("PhoneBook", number, phonebookNumbers);
  575.  
  576.           Sensor_UpdateNameInPhonecalls(timestamp, phonebookNumbers);
  577.  
  578.           Log("\033[31mOnlinePhonebook-eniro: Found: " + JSON.stringify(phonebookNumbers) + "\033[0m\n");
  579.         }
  580.       }
  581.       else
  582.       {
  583.         Log("\033[31mOnlinePhonebook-eniro: Failed to do name lookup, result was: " + result + "\033[0m\n");
  584.       }
  585.  
  586.       if (phonebookNumbers.length == 0)
  587.       {
  588.         if (typeof sensorRKSEEK_API !== 'undefined')
  589.         {
  590.           url = "rkseek.oblivioncreations.se/?client="+sensorRKSEEK_API+"&n=" + number + "&out=text";
  591.           Log("\033[31mURL: http://"+url+"\033[0m\n");
  592.  
  593.           Http_Request(url, function(socket_id, result, header, content_data)
  594.           {
  595.             phonebookNumbers = [];
  596.  
  597.             if (result.indexOf("200 OK") != -1)
  598.             {
  599.               //Log("\033[31mOnlinePhonebook: result was: " + content_data + "\033[0m\n");
  600.               var lines = content_data.split("\n");
  601.               //Log("\033[31mOnlinePhonebook: Line: " + lines[1] + "\033[0m\n");
  602.               //Log("\033[31mOnlinePhonebook: Line: " + lines[2] + "\033[0m\n");
  603.               //Log("\033[31mOnlinePhonebook: Line: " + lines[3] + "\033[0m\n");
  604.               if (lines[2].length > 0)
  605.               {
  606.                 phonebookNumbers = [ lines[2] ]; // TODO Is this really correct?!
  607.                 Storage_SetJsonParameter("PhoneBook", number, phonebookNumbers);
  608.                
  609.                 Sensor_UpdateNameInPhonecalls(timestamp, phonebookNumbers);
  610.  
  611.                 Log("\033[31mOnlinePhonebook-rseek: Found: " + JSON.stringify(phonebookNumbers) + "\033[0m\n");
  612.               }
  613.             }
  614.             else
  615.             {
  616.               Log("\033[31mOnlinePhonebook-rseek: Failed to do name lookup, result was: " + result + "\033[0m\n");
  617.             }
  618.           });
  619.         }
  620.       }
  621.     });
  622.         /*
  623.         Http_Request("wap.hitta.se/default.aspx?Who=" + number + "&Where=&PageAction=White",
  624.             function(socket_id, result, header, content_data) {
  625.                 var persons = new Array();
  626.                 if (result.indexOf("200 OK") != -1)
  627.                 {
  628.                     var endString = "<anchor>Tillbaka<prev/></anchor>";
  629.                     var nameStartString = " title=\"Link\">";
  630.                     var nameEndString = "</a>";
  631.  
  632.                     var lines = content_data.split("<br/>");
  633.  
  634.                     for (var n = 1; n < lines.length; n++)
  635.                     {
  636.                         var line = lines[n].trim(" \n");
  637.  
  638.                         if (line.indexOf(endString) != -1)
  639.                         {
  640.                             break;
  641.                         }
  642.                         var pos = line.indexOf(nameStartString + (persons.length+1) + ".");
  643.  
  644.                         if (pos != -1)
  645.                         {
  646.                             pos += nameStartString.length + 2
  647.                             persons[persons.length] = line.substr(pos, line.length-pos-nameEndString.length).html_entity_decode().replace("  ", " ");
  648.                         }
  649.                     }
  650.                     if (persons.length > 0) {
  651.                         Storage_SetJsonParameter("PhoneBook", number, persons);
  652.  
  653.                         //CAll all listeners!
  654.                         //....
  655.  
  656.                         Log("\033[31mOnlinePhonebook: Found: " + JSON.stringify(persons) + "\033[0m\n");
  657.                     }
  658.                 }
  659.                 else
  660.                 {
  661.                     Log("\033[31mOnlinePhonebook: Failed to do name lookup, result was: " + result + "\033[0m\n");
  662.                 }
  663.             }
  664.         );
  665.         */
  666.  
  667.   }
  668.   else
  669.   {
  670.     //Log("Number already stored\n");
  671.  
  672.     Sensor_UpdateNameInPhonecalls(timestamp, phonebookNumbers);
  673.   }
  674.  
  675.   return phonebookNumbers;
  676. }
  677. Console_RegisterCommand(Sensor_StoreNumberInPhonebook, function(arg_index, args) { return Console_StandardAutocomplete(arg_index, args); });
  678.  
  679. function Sensor_StoreNumberInPhonebookManual(number, name)
  680. {
  681.     if (arguments.length < 2)
  682.     {
  683.         Log("\033[31mNot enough parameters given.\033[0m\n");
  684.         return false;
  685.     }
  686.    
  687.     var completename = arguments[1];
  688.     for (var i=2; i<arguments.length; i++)
  689.     {
  690.         completename = completename+" "+arguments[i];
  691.     }
  692.    
  693.     phonebookNumbers = [];
  694.     phonebookNumbers.push(completename);
  695.     Storage_SetJsonParameter("PhoneBook", number, phonebookNumbers);
  696. }
  697. Console_RegisterCommand(Sensor_StoreNumberInPhonebookManual, function(arg_index, args) { return Console_StandardAutocomplete(arg_index, args); });
  698.  
  699. function Sensor_UpdateNameInPhonecalls(timestamp, numbers)
  700. {
  701.   if (numbers.length > 0)
  702.   {
  703.     var lastValueString = Storage_GetParameter("PhoneCalls", timestamp);
  704.  
  705.     if (lastValueString)
  706.     {
  707.       var lastValue = JSON.parse(lastValueString);
  708.  
  709.       lastValue.names = numbers;
  710.  
  711.       Storage_SetParameter("PhoneCalls", timestamp, JSON.stringify(lastValue));
  712.     }
  713.   }
  714. }
  715.  
  716. function Sensor_SetUltrasonicMode(alias_name, BottomLimit, TopLimit, mode)
  717. {
  718.     if (arguments.length < 4)
  719.     {
  720.         Log("\033[31mNot enough parameters given.\033[0m\n");
  721.         return false;
  722.     }
  723.  
  724.     var aliases_data = Module_ResolveAlias(alias_name, Sensor_ModuleNames);
  725.     var found = false;
  726.  
  727.     for (var name in aliases_data)
  728.     {
  729.         var variables = {   "0Percent"     : BottomLimit,
  730.                     "100Percent"   : TopLimit,
  731.                     "SensorMode"   : mode,
  732.                     "SensorId"  : aliases_data[name]["specific"]["Channel"],
  733.         };
  734.         if (Module_SendMessage(aliases_data[name]["module_name"], aliases_data[name]["module_id"], "UltrasonicConfig", variables))
  735.         {
  736.             Log("\033[32mCommand sent successfully to " + name + ".\033[0m\n");
  737.         }
  738.         else
  739.         {
  740.             Log("\033[31mFailed to send command to " + name + ".\033[0m\n");
  741.         }
  742.  
  743.         found = true;
  744.     }
  745.  
  746.     if (!found)
  747.     {
  748.         Log("\033[31mNo aliases by the name " + alias_name + " were applicable for this command.\033[0m\n");
  749.         return false;
  750.     }
  751.  
  752.     return true;
  753. }
  754. Console_RegisterCommand(Sensor_SetUltrasonicMode, function(arg_index, args) { return Console_StandardAutocomplete(arg_index, args, Sensor_Aliases()); });
  755.