Changes in / [20:30]


Ignore:
Location:
/trunk
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • /trunk/J_CurrentCostEnviR1.js

    r20 r30  
    22function getChildApplianceName(deviceId, a) 
    33{ 
    4     var matches = jsonp.ud.devices.findAll(function(d) { 
     4    var matches = jQuery.grep(jsonp.ud.devices, function(d) { 
    55        return d.altid == "Appliance" + a && d.id_parent == deviceId 
    66    } ); 
     
    99} 
    1010 
     11function getFormula(deviceId) 
     12{ 
     13    var formula = get_device_state(deviceId, "urn:futzle-com:serviceId:CurrentCostEnviR1", "Formula", 0); 
     14    if (formula == undefined) formula = ""; 
     15    if (/^[0-9]/.test(formula)) formula = "+" + formula; 
     16    return formula; 
     17} 
     18 
     19function setFormula(deviceId, a, operation) 
     20{ 
     21    var formula = getFormula(deviceId); 
     22    formula = formula.replace("-" + a, "").replace("+" + a, ""); 
     23    if (operation == "add") 
     24    { 
     25        formula += "+" + a; 
     26    } 
     27    else if (operation == "subtract") 
     28    { 
     29        formula += "-" + a; 
     30    } 
     31    set_device_state(deviceId, "urn:futzle-com:serviceId:CurrentCostEnviR1", "Formula", formula, 0); 
     32} 
     33 
     34var entityMap = { 
     35  "&": "&", 
     36  "<": "&lt;", 
     37  ">": "&gt;", 
     38  '"': '&quot;', 
     39  "'": '&#39;', 
     40  "/": '&#x2F;' 
     41}; 
     42 
     43function escapeHtml(string) { 
     44  return String(string).replace(/[&<>"'\/]/g, function (s) { 
     45    return entityMap[s]; 
     46  }); 
     47} 
     48 
    1149/* Entry point for "Configuration" tab. 
    1250   Provide GUI for editing global and per-appliance settings. */ 
    1351function setup(deviceId) 
    1452{ 
     53    var applianceTypes = [ "Unknown", "Electricity (Power)", "Electricity (Pulse)" ]; 
     54 
    1555    var htmlResult = ""; 
    1656    htmlResult += "<div>"; 
     
    2262    var childTemperature = get_device_state(deviceId, "urn:futzle-com:serviceId:CurrentCostEnviR1", "ChildTemperature", 0); 
    2363    if (childTemperature == undefined) childTemperature = 0; 
    24     htmlResult += "<td><input type='checkbox' id='childTemperature' " + (childTemperature == "1" ? "checked='checked' " : "") + "onclick='set_device_state(" + deviceId + ", \"urn:futzle-com:serviceId:CurrentCostEnviR1\", \"ChildTemperature\", $F(\"childTemperature\") ? 1 : 0, 0)'/></td>"; 
     64    htmlResult += "<td><input type='checkbox' id='childTemperature' " + (childTemperature == "1" ?  "checked='checked' " : "") + "onclick='set_device_state(" + deviceId + ", \"urn:futzle-com:serviceId:CurrentCostEnviR1\", \"ChildTemperature\", jQuery(this).is(\":checked\") ? 1 : 0, 0)'/></td>"; 
    2565 
    2666    htmlResult += "</tr><tr>"; 
     
    3070    var applianceDetect = get_device_state(deviceId, "urn:futzle-com:serviceId:CurrentCostEnviR1", "ApplianceAutoDetect", 0); 
    3171    if (applianceDetect == undefined) applianceDetect = 1; 
    32     htmlResult += "<td><input type='checkbox' id='applianceDetect' " + (applianceDetect == "1" ? "checked='checked' " : "") + "onclick='set_device_state(" + deviceId + ", \"urn:futzle-com:serviceId:CurrentCostEnviR1\", \"ApplianceAutoDetect\", $F(\"applianceDetect\") ? 1 : 0, 0)'/></td>"; 
     72    htmlResult += "<td><input type='checkbox' id='applianceDetect' " + (applianceDetect == "1" ? "checked='checked' " : "") + "onclick='set_device_state(" + deviceId + ", \"urn:futzle-com:serviceId:CurrentCostEnviR1\", \"ApplianceAutoDetect\", jQuery(this).is(\":checked\") ? 1 : 0, 0)'/></td>"; 
    3373 
    3474    htmlResult += "</tr>"; 
     
    3878    htmlResult += "<table border='0' padding='0' width='100%'>"; 
    3979    htmlResult += "<tr>"; 
    40     htmlResult += "<th>Appliance</th><th>ID</th><th>Name</th><th>Separate Phases</th><th>Main power</th>"; 
     80    htmlResult += "<th>Appliance</th><th>Type</th><th>ID</th><th>Name</th><th>Separate Phases</th><th>Main power</th>"; 
    4181    htmlResult += "</tr>"; 
    4282 
    43     var formula = get_device_state(deviceId, "urn:futzle-com:serviceId:CurrentCostEnviR1", "Formula", 0); 
    44     if (formula == undefined) formula = ""; 
    45     if (/^[0-9]/.test(formula)) formula = "+" + formula; 
     83    var formula = getFormula(deviceId); 
    4684    var a; 
    4785    for (a = 0; a < 10; a++) 
     
    4987        var applianceId = get_device_state(deviceId, "urn:futzle-com:serviceId:CurrentCostEnviR1", "Appliance" + a, 0); 
    5088        if (applianceId == undefined || applianceId == "" || applianceId == "0") continue; 
     89        var applianceType = get_device_state(deviceId, "urn:futzle-com:serviceId:CurrentCostEnviR1", "Appliance" + a + "Type", 0); 
     90        if (applianceType == undefined) { applianceType = 1; } 
     91        applianceType = applianceType - 0; 
    5192        htmlResult += "<tr>"; 
    5293        // Appliance number 
    5394        htmlResult += "<td>" + a + (a == 0 ? " (whole house)" : "") + "</td>"; 
     95        // Appliance type 
     96        htmlResult += "<td>" + applianceTypes[applianceType] + "</td>"; 
    5497        // Appliance unique identifier 
    55         htmlResult += "<td>" + applianceId.escapeHTML() + "</td>"; 
     98        htmlResult += "<td>" + escapeHtml(applianceId) + "</td>"; 
    5699        // Appliance name as set by the user 
    57100        var applianceName = getChildApplianceName(deviceId, a); 
    58101        htmlResult += "<td>" + applianceName + "</td>"; 
    59         // Create additional child devices for each phase? 
    60         var applianceThreePhase = get_device_state(deviceId, "urn:futzle-com:serviceId:CurrentCostEnviR1", "Appliance" + a + "ThreePhase", 0); 
    61         if (applianceThreePhase == undefined) applianceThreePhase = 0; 
    62         htmlResult += "<td><input type='checkbox' " + (applianceThreePhase == "1" ? "checked='checked' " : "") + "/></td>"; 
    63         // How does the child's energy contribute to the main device's energy (+ or -)? 
    64         htmlResult += "<td>" 
    65         htmlResult += "<select>"; 
    66         htmlResult += "<option value='none' " + (formula.indexOf("+" + a) == -1 && formula.indexOf("-" + a) == -1 ? "selected='selected' " : "")  + ">None</option>"; 
    67         htmlResult += "<option value='add' " + (formula.indexOf("+" + a) != -1 ? "selected='selected' " : "")  + ">Add</option>"; 
    68         htmlResult += "<option value='subtract' " + (formula.indexOf("-" + a) != -1 ? "selected='selected' " : "")  + ">Subtract</option>"; 
    69         htmlResult += "</select>"; 
    70         htmlResult += "</td>"; 
    71         htmlResult += "</tr>"; 
     102        if (applianceType == 1) 
     103        { 
     104            // Create additional child devices for each phase? 
     105            var applianceThreePhase = get_device_state(deviceId, "urn:futzle-com:serviceId:CurrentCostEnviR1", "Appliance" + a + "ThreePhase", 0); 
     106            if (applianceThreePhase == undefined) applianceThreePhase = 0; 
     107            htmlResult += "<td><input type='checkbox' id='appliance" + a + "ThreePhase' " + (applianceThreePhase == "1" ? "checked='checked' " : "") + "onclick='set_device_state(" + deviceId + ", \"urn:futzle-com:serviceId:CurrentCostEnviR1\", \"Appliance" + a + "ThreePhase\", jQuery(\"#appliance" + a + "ThreePhase\").is(\":checked\") ? 1 : 0, 0)'/></td>"; 
     108            // How does the child's energy contribute to the main device's energy (+ or -)? 
     109            htmlResult += "<td>" 
     110            htmlResult += "<select id='formula" + a + "' onchange='setFormula(" + deviceId + "," + a + ", jQuery(\"#formula" + a + "\").val())'>"; 
     111            htmlResult += "<option value='none' " + (formula.indexOf("+" + a) == -1 && formula.indexOf("-" + a) == -1 ? "selected='selected' " : "") + ">None</option>"; 
     112            htmlResult += "<option value='add' " + (formula.indexOf("+" + a) != -1 ? "selected='selected' " : "") + ">Add</option>"; 
     113            htmlResult += "<option value='subtract' " + (formula.indexOf("-" + a) != -1 ? "selected='selected' " : "") + ">Subtract</option>"; 
     114            htmlResult += "</select>"; 
     115            htmlResult += "</td>"; 
     116            htmlResult += "</tr>"; 
     117        } 
     118        else 
     119        { 
     120            // No phase or arithmetic for pulse meters. 
     121            htmlResult += "<td /><td />"; 
     122        }    
    72123    } 
    73124 
  • /trunk/J_SerialConnection.js

    r20 r30  
    2727 *      If set and of the form "1.1.1.1", this means that the TCP port is a "default" 
    2828 *      value, which may mean something useful or not, depending on the plugin. 
    29  *      Use luup.io.open() or signal an error. 
     29 *      If your plugin's implementation uses <ioPort> then Luup may open a 
     30 *      connection for you anyway.  Use luup.io.open(), do nothing, or signal an error. 
    3031 *      Other forms are reserved (for IPv6 or named hosts). 
    3132 *    - If neither is set, return false from the startup to signal an error. 
     
    4344  + numberPattern65535 + ")$"); 
    4445 
     46var entityMap = { 
     47  "&": "&amp;", 
     48  "<": "&lt;", 
     49  ">": "&gt;", 
     50  '"': '&quot;', 
     51  "'": '&#39;', 
     52  "/": '&#x2F;' 
     53}; 
     54 
     55function escapeHtml(string) { 
     56  return String(string).replace(/[&<>"'\/]/g, function (s) { 
     57    return entityMap[s]; 
     58  }); 
     59} 
     60 
    4561function getConnectionType(deviceId) 
    4662{ 
    4763  var ioDevice = get_device_state(deviceId, "urn:micasaverde-com:serviceId:HaDevice1", "IODevice", 0); 
    48   var ipDevice = jsonp.get_device_by_id(deviceId); 
     64  var ipDevice = jQuery.grep(jsonp.ud.devices, function(o, i) { return o.id == deviceId; })[0]; 
    4965  if (ioDevice != undefined && ioDevice != "") { return "ioDevice"; } 
    5066  if (ipDevice != undefined) 
     
    6177function getSerialDevices(deviceId) 
    6278{ 
    63   return jsonp.ud.devices.findAll(function(d) { 
     79  return jQuery.grep(jsonp.ud.devices, function(d) { 
    6480    return d.device_type == "urn:micasaverde-org:device:SerialPort:1"; 
    6581  } ); 
     
    7187function getDeviceOfSerialDevice(serialDeviceId) 
    7288{ 
    73   var matches = jsonp.ud.devices.findAll(function(d) { 
    74     return d.states.findAll(function(state) { 
     89  var matches = jQuery.grep(jsonp.ud.devices, function(d) { 
     90    return jQuery.grep(d.states, function(state) { 
    7591      return state.service == "urn:micasaverde-com:serviceId:HaDevice1" && 
    7692        state.variable == "IODevice" && 
     
    85101function getIpAddress(deviceId) 
    86102{ 
    87   var ipDevice = jsonp.get_device_by_id(deviceId); 
     103  var ipDevice = jQuery.grep(jsonp.ud.devices, function(o, i) { return o.id == deviceId; })[0]; 
     104  if (ipDevice == undefined) { return undefined; } 
    88105  var ip = ipDevice.ip; 
    89   if (ip == undefined) { return undefined; } 
    90106  if (ip == "") { return undefined; } 
    91107  if (ipv4Pattern.test(ip)) { return ip; } 
     
    98114function getTcpPort(deviceId) 
    99115{ 
    100   var ipDevice = jsonp.get_device_by_id(deviceId); 
     116  var ipDevice = jQuery.grep(jsonp.ud.devices, function(o, i) { return o.id == deviceId; })[0]; 
     117  if (ipDevice == undefined) { return undefined; } 
    101118  var ip = ipDevice.ip; 
    102   if (ip == undefined) { return undefined; } 
    103119  if (ip == "") { return undefined; } 
    104120  if (ipv4Pattern.test(ip)) { return undefined; } 
     
    109125 
    110126/* Mess with the DOM to disable parts of the UI. */ 
    111 function enableSelectedOption(deviceId, currentConnectionType) 
    112 { 
    113   $('serialDevice').disable(); 
    114   $('ipaddress').disable(); 
    115   $('tcpport').disable(); 
     127function enableSelectedOption(deviceId, currentConnectionType, ownedSerialDeviceId) 
     128{ 
     129  jQuery('#serialDevice').get(0).disabled = true; 
     130  jQuery('#serialSpeed').get(0).disabled = true; 
     131  jQuery('#serialData').get(0).disabled = true; 
     132  jQuery('#serialParity').get(0).disabled = true; 
     133  jQuery('#serialStop').get(0).disabled = true; 
     134  jQuery('#ipaddress').get(0).disabled = true; 
     135  jQuery('#tcpport').get(0).disabled = true; 
    116136 
    117137  if (currentConnectionType == "ioDevice") 
    118138  { 
    119     $('serialDevice').enable(); 
     139    jQuery('#serialDevice').get(0).disabled = false; 
     140    if (ownedSerialDeviceId != undefined && ownedSerialDeviceId != "") 
     141    { 
     142      var serialSpeed = jsonp.get_lu_device_variable_value(ownedSerialDeviceId, "urn:micasaverde-org:serviceId:SerialPort1", "baud", 0); 
     143      if (serialSpeed == undefined || serialSpeed == "") serialSpeed = "9600";  // Default 
     144      jQuery('#serialSpeed').val(serialSpeed).get(0).disabled = false; 
     145      var serialData = jsonp.get_lu_device_variable_value(ownedSerialDeviceId, "urn:micasaverde-org:serviceId:SerialPort1", "databits", 0); 
     146      if (serialData == undefined || serialData == "") serialData = "8";  // Default 
     147      jQuery('#serialData').val(serialData).get(0).disabled = false; 
     148      var serialParity = jsonp.get_lu_device_variable_value(ownedSerialDeviceId, "urn:micasaverde-org:serviceId:SerialPort1", "parity", 0); 
     149      if (serialParity == undefined || serialParity == "") serialParity = "none";  // Default 
     150      jQuery('#serialParity').val(serialParity).get(0).disabled = false; 
     151      var serialStop = jsonp.get_lu_device_variable_value(ownedSerialDeviceId, "urn:micasaverde-org:serviceId:SerialPort1", "stopbits", 0); 
     152      if (serialStop == undefined || serialStop == "") serialStop = "1";  // Default 
     153      jQuery('#serialStop').val(serialStop).get(0).disabled = false; 
     154    } 
    120155  } 
    121156  if (currentConnectionType == "ip") 
    122157  { 
    123     $('ipaddress').enable(); 
    124     $('tcpport').enable(); 
     158    jQuery('#ipaddress').get(0).disabled = false; 
     159    jQuery('#tcpport').get(0).disabled = false; 
    125160  } 
    126161} 
     
    131166function setSerialDevice(deviceId, serialDeviceId) 
    132167{ 
    133   enableSelectedOption(deviceId,"ioDevice"); 
    134168  set_device_state(deviceId, "urn:micasaverde-com:serviceId:HaDevice1", "IODevice", serialDeviceId, 0); 
    135   jsonp.get_device_by_id(deviceId).ip = ""; 
     169  var ipDevice = jQuery.grep(jsonp.ud.devices, function(o, i) { return o.id == deviceId; })[0]; 
     170  ipDevice.ip = ""; 
     171  enableSelectedOption(deviceId, "ioDevice", serialDeviceId); 
     172} 
     173 
     174/* Set the IODevice serial properties (speed, parity, etc.). */ 
     175function setSerialProperties(deviceId, serialDeviceId) 
     176{ 
     177  set_device_state(serialDeviceId, "urn:micasaverde-org:serviceId:SerialPort1", "baud", jQuery('#serialSpeed').val(), 0); 
     178  set_device_state(serialDeviceId, "urn:micasaverde-org:serviceId:SerialPort1", "databits", jQuery('#serialData').val(), 0); 
     179  set_device_state(serialDeviceId, "urn:micasaverde-org:serviceId:SerialPort1", "parity", jQuery('#serialParity').val(), 0); 
     180  set_device_state(serialDeviceId, "urn:micasaverde-org:serviceId:SerialPort1", "stopbits", jQuery('#serialStop').val(), 0); 
    136181} 
    137182 
     
    141186function setIPDevice(deviceId, ipAddress, tcpPort) 
    142187{ 
    143   enableSelectedOption(deviceId,"ip"); 
    144   if (tcpPort == undefined || tcpPort == "") 
    145   { 
    146     jsonp.get_device_by_id(deviceId).ip = ipAddress; 
     188  if (jQuery('#tcpport').get(0).disabled || tcpPort == undefined || tcpPort == "") 
     189  { 
     190    var ipDevice = jQuery.grep(jsonp.ud.devices, function(o, i) { return o.id == deviceId; })[0]; 
     191    ipDevice.ip = ""; 
    147192  } 
    148193  else 
    149194  { 
    150     jsonp.get_device_by_id(deviceId).ip = ipAddress + ":" + tcpPort; 
     195    var ipDevice = jQuery.grep(jsonp.ud.devices, function(o, i) { return o.id == deviceId; })[0]; 
     196    ipDevice.ip = ipAddress + ":" + tcpPort; 
    151197  } 
    152198  set_device_state(deviceId, "urn:micasaverde-com:serviceId:HaDevice1", "IODevice", "", 0); 
     199  enableSelectedOption(deviceId, "ip", undefined); 
     200} 
     201 
     202/* Fetch the named file over Ajax and execute function 
     203   f() on the resulting XML. */ 
     204function withUpnpFileName(deviceId, filename, f) 
     205{ 
     206  new Ajax.Request("../port_3480/" + filename, { 
     207    onSuccess : function(response) { 
     208        return f(response.responseXML); 
     209      } 
     210    } 
     211  ); 
     212} 
     213 
     214/* Fetch the Implementation file (I_*.xml) and 
     215   execute the function f() on the resulting XML. */ 
     216function withImplementationFile(deviceId, f) 
     217{ 
     218  var device = jQuery.grep(jsonp.ud.devices, function(o, i) { return o.id == deviceId; })[0]; 
     219  if (device.impl_file != "") 
     220  { 
     221    return withUpnpFileName(deviceId, device.impl_file, f); 
     222  } 
     223  else 
     224  { 
     225    return withUpnpFileName(deviceId, device.device_file, function(doc) { 
     226      var implementationElement = doc.querySelector("root > device > implementationList > implementationFile"); 
     227      if (implementationElement != undefined) 
     228      { 
     229        var implementationFile = implementationElement.textContent.trim(); 
     230        return withUpnpFileName(deviceId, implementationFile, f); 
     231      } 
     232    }); 
     233  } 
    153234} 
    154235 
     
    165246  htmlResult += "<p><input type='radio' name='connectionType' value='serial' "; 
    166247  if (currentConnectionType == "ioDevice") htmlResult += "checked='checked' "; 
    167   htmlResult += "onclick='setSerialDevice(" + deviceId + ",$F(serialDevice))'/>Serial port or IPSerial device "; 
    168   htmlResult += "<select id='serialDevice' onchange='setSerialDevice(" + deviceId + ",$F(serialDevice))'>"; 
     248  htmlResult += "onclick='setSerialDevice(" + deviceId + ",jQuery(\"#serialDevice\").val())'/>Serial port or IPSerial device "; 
     249  htmlResult += "<select id='serialDevice' onchange='setSerialDevice(" + deviceId + ",jQuery(\"#serialDevice\").val())'>"; 
    169250  htmlResult += "<option value=''>None</option>"; 
    170251  var serialDevices = getSerialDevices(deviceId); 
    171   htmlResult += serialDevices.inject("", function(htmlResult, d) { 
     252  var ownedSerialDeviceId; 
     253  jQuery.each(serialDevices, function(i, d) { 
    172254    htmlResult += "<option value='" + d.id + "'"; 
    173255    var deviceOwner = getDeviceOfSerialDevice(d.id); 
     
    178260        // This is my serial device. 
    179261        htmlResult += " selected='selected'"; 
     262        ownedSerialDeviceId = d.id; 
    180263      } 
    181264      else 
     
    185268      } 
    186269    } 
    187     htmlResult += ">" + d.name.escapeHTML(); 
     270    htmlResult += ">" + escapeHtml(d.name); 
    188271    // Tell user who owns this device (if it's not us). 
    189272    if (deviceOwner != undefined && deviceOwner.id != deviceId) 
    190273    { 
    191       htmlResult += " [" + deviceOwner.name.escapeHTML() + "]"; 
     274      htmlResult += " [" + escapeHtml(deviceOwner.name) + "]"; 
    192275    } 
    193276    htmlResult += "</option>"; 
    194     return htmlResult; 
    195277  }); 
    196278  htmlResult += "</select>"; 
    197279  htmlResult += "</p>"; 
     280  htmlResult += "<p style='margin-left: 4em;'>"; 
     281  htmlResult += "Speed <select id='serialSpeed' onchange='setSerialProperties(" + deviceId + ",jQuery(\"#serialDevice\").val())'><option value='300'>300</option><option value='1200'>1200</option><option value='2400'>2400</option><option value='4800'>4800</option><option value='9600'>9600</option><option value='19200'>19200</option><option value='38400'>38400</option><option value='57600'>57600</option><option value='115200'>115200</option><option value='230400'>230400</option></select>"; 
     282  htmlResult += " Data bits <select id='serialData' onchange='setSerialProperties(" + deviceId + ",jQuery(\"#serialDevice\").val())'><option value='7'>7</option><option value='8'>8</option></select>"; 
     283  htmlResult += " Parity <select id='serialParity' onchange='setSerialProperties(" + deviceId + ",jQuery(\"#serialDevice\").val())'><option value='none'>None</option><option value='even'>Even</option><option value='odd'>Odd</option></select>"; 
     284  htmlResult += " Stop bits <select id='serialStop' onchange='setSerialProperties(" + deviceId + ",jQuery(\"#serialDevice\").val())'><option value='0'>0</option><option value='1'>1</option><option value='2'>2</option></select>"; 
     285  htmlResult += "</p>"; 
    198286 
    199287  /* Serial proxy over Ethernet. */ 
    200288  htmlResult += "<p><input type='radio' name='connectionType' value='ip' "; 
    201289  if (currentConnectionType == "ip") htmlResult += "checked='checked' "; 
    202   htmlResult += "onclick='setIPDevice(" + deviceId + ",$F(ipaddress),$F(tcpport))'/>Serial proxy on another machine "; 
     290  htmlResult += "onclick='setIPDevice(" + deviceId + ",jQuery(\"#ipaddress\").val(),jQuery(\"#tcpport\").val())'/>Serial proxy on another machine "; 
    203291  var ipAddress = getIpAddress(deviceId); 
    204292  if (ipAddress == undefined) { ipAddress = ""; } 
    205   htmlResult += "<p style='margin-left: 4em;'>IP address <input id='ipaddress' type='text' size='16' value='" + ipAddress.escapeHTML() + "' onchange='setIPDevice(" + deviceId + ",$F(ipaddress),$F(tcpport))' />"; 
     293  htmlResult += "<p style='margin-left: 4em;'>IP address <input id='ipaddress' type='text' size='16' value='" + escapeHtml(ipAddress) + "' onchange='setIPDevice(" + deviceId + ",jQuery(\"#ipaddress\").val(),jQuery(\"#tcpport\").val())' />"; 
    206294  var tcpPort = getTcpPort(deviceId); 
    207295  if (tcpPort == undefined) { tcpPort = ""; } 
    208   htmlResult += " TCP port <input id='tcpport' type='text' size='6' value='" + tcpPort.escapeHTML() + "' onchange='setIPDevice(" + deviceId + ",$F(ipaddress),$F(tcpport))' /></p> "; 
     296  htmlResult += " TCP port <input id='tcpport' type='text' size='6' value='" + escapeHtml(tcpPort) + "' onchange='setIPDevice(" + deviceId + ",jQuery(\"#ipaddress\").val(),jQuery(\"#tcpport\").val())' /></p> "; 
    209297  htmlResult += "</p>"; 
    210298 
     
    213301  set_panel_html(htmlResult); 
    214302 
    215   enableSelectedOption(deviceId, currentConnectionType); 
    216 } 
     303  enableSelectedOption(deviceId, currentConnectionType, ownedSerialDeviceId); 
     304 
     305  /* See if this device has an <ioPort> element. 
     306     If so, don't let user edit the TCP port. */ 
     307  withImplementationFile(deviceId, function(doc) { 
     308    var ioPortElement = doc.querySelector("implementation > settings > ioPort"); 
     309    if (ioPortElement != undefined) 
     310    { 
     311      var ioPortHardcoded = ioPortElement.textContent.trim(); 
     312      jQuery('#tcpport').val(ioPortHardcoded).get(0).disabled = true; 
     313    } 
     314  }); 
     315} 
  • /trunk/L_CurrentCostEnviR1.lua

    r20 r30  
    99-- Cache of child devices, maps appliance number to MiOS device ID. 
    1010CHILD_DEVICE = { } 
     11CHILD_DEVICE_TYPE = { } 
    1112CHILD_DEVICE_THREEPHASE = { ["0"] = { }, ["1"] = { }, ["2"] = { }, ["3"] = { }, ["4"] = { }, ["5"] = { }, ["6"] = { }, ["7"] = { }, ["8"] = { }, ["9"] = { } } 
    1213-- Child device for temperature, if configured. 
     
    6061        if ((luup.variable_get(SERVICE_ID, "Appliance" .. tostring(child), lul_device) or "0") ~= "0") then 
    6162            CHILD_DEVICE_COUNT = CHILD_DEVICE_COUNT + 1 
    62             luup.chdev.append(lul_device, childDevices, "Appliance" .. tostring(child), 
    63                 "Appliance " .. child, "urn:schemas-futzle-com:device:CurrentCostEnvirAppliance:1", 
    64                 "D_CurrentCostEnviRAppliance1.xml", "", "", false) 
     63            -- What type of device is it? 
     64            local deviceType = luup.variable_get(SERVICE_ID, "Appliance" .. tostring(child) .. "Type", lul_device) or "1" 
     65            if (deviceType == "1") then 
     66                -- Electricity power (clamp, individual monitor). 
     67                luup.chdev.append(lul_device, childDevices, "Appliance" .. tostring(child), 
     68                    "Appliance " .. child, "urn:schemas-futzle-com:device:CurrentCostEnviRAppliance:1", 
     69                    "D_CurrentCostEnviRAppliance1.xml", "", "", false) 
     70            elseif (deviceType == "2") then 
     71                -- Impulse meter (OptiSmart). 
     72                luup.chdev.append(lul_device, childDevices, "Appliance" .. tostring(child), 
     73                    "Appliance " .. child .. " (pulse)", "urn:schemas-futzle-com:device:CurrentCostEnviRAppliancePulse:1", 
     74                    "D_CurrentCostEnviRAppliancePulse1.xml", "", "", false) 
     75            end 
    6576        end 
    6677        if ((luup.variable_get(SERVICE_ID, "Appliance" .. tostring(child) .. "ThreePhase", lul_device) or "0") ~= "0") then 
    6778            for phase = 1, 3 do 
    6879                luup.chdev.append(lul_device, childDevices, "Appliance" .. tostring(child) .. "Phase" .. tostring(phase), 
    69                     "Appliance " .. child .. " phase " .. phase, "urn:schemas-futzle-com:device:CurrentCostEnvirAppliancePhase:1", 
     80                    "Appliance " .. child .. " phase " .. phase, "urn:schemas-futzle-com:device:CurrentCostEnviRAppliancePhase:1", 
    7081                    "D_CurrentCostEnviRAppliancePhase1.xml", "", "", false) 
    7182            end 
     
    106117    AUTO_DETECT = luup.variable_get(SERVICE_ID, "ApplianceAutoDetect", lul_device) 
    107118    if (AUTO_DETECT == nil) then 
     119        AUTO_DETECT = "1" 
    108120        luup.variable_set(SERVICE_ID, "ApplianceAutoDetect", "1", lul_device) 
    109121    end 
     122 
     123    -- Set the device category. 21 is "power meter". 
     124    luup.attr_set("category_num", 21, lul_device) 
    110125 
    111126    -- Cache the child device ids, and populate the history variables. 
     
    114129            if (v.device_num_parent == lul_device and v.id == "Appliance" .. sensor) then 
    115130                if (DEBUG) then luup.log("Child deviceId for Appliance " .. sensor .. " is " .. k) end 
    116                 CHILD_DEVICE[tostring(sensor)] = k 
    117                 TWOHOURLY_HISTORY[tostring(sensor)] = deserializeHistory(luup.variable_get(SERVICE_ID, "TwoHourlyHistory", k) or "") 
    118                 DAILY_HISTORY[tostring(sensor)] = deserializeHistory(luup.variable_get(SERVICE_ID, "DailyHistory", k) or "") 
    119                 MONTHLY_HISTORY[tostring(sensor)] = deserializeHistory(luup.variable_get(SERVICE_ID, "MonthlyHistory", k) or "") 
     131                -- What type of device is it? 
     132                local deviceType = luup.variable_get(SERVICE_ID, "Appliance" .. tostring(child) .. "Type", lul_device) or "1" 
     133                if (deviceType == "1") then 
     134                    -- Electricity power (clamp, individual monitor). 
     135                    -- Set the device category. 21 is "power meter". 
     136                    luup.attr_set("category_num", 21, k) 
     137                    CHILD_DEVICE[tostring(sensor)] = k 
     138                    CHILD_DEVICE_TYPE[tostring(sensor)] = "1" 
     139                    TWOHOURLY_HISTORY[tostring(sensor)] = deserializeHistory(luup.variable_get(SERVICE_ID, "TwoHourlyHistory", k) or "") 
     140                    DAILY_HISTORY[tostring(sensor)] = deserializeHistory(luup.variable_get(SERVICE_ID, "DailyHistory", k) or "") 
     141                    MONTHLY_HISTORY[tostring(sensor)] = deserializeHistory(luup.variable_get(SERVICE_ID, "MonthlyHistory", k) or "") 
     142                elseif (deviceType == "2") then 
     143                    -- Impulse meter (OptiSmart). 
     144                    -- Set the device category. 21 is "power meter". 
     145                    luup.attr_set("category_num", 21, k) 
     146                    CHILD_DEVICE[tostring(sensor)] = k 
     147                    CHILD_DEVICE_TYPE[tostring(sensor)] = "2" 
     148                end 
    120149            end 
    121150            for phase = 1, 3 do 
    122151                if (v.device_num_parent == lul_device and v.id == "Appliance" .. sensor .. "Phase" .. phase) then 
    123152                    if (DEBUG) then luup.log("Child deviceId for Appliance " .. sensor .. " Phase " .. phase .. " is " .. k) end 
     153                    -- Set the device category. 21 is "power meter". 
     154                    luup.attr_set("category_num", 21, k) 
    124155                    CHILD_DEVICE_THREEPHASE[tostring(sensor)][tostring(phase)] = k 
    125156                end 
     
    127158        end 
    128159        if (v.device_num_parent == lul_device and v.id == "Temperature") then 
     160            -- Set the device category. 17 is "temperature". 
     161            luup.attr_set("category_num", 17, k) 
    129162            CHILD_TEMPERATURE_DEVICE = k 
    130163        end 
     
    174207end  
    175208 
     209-- Set a variable only if it is different. 
     210function set_if_different(serviceId, variable, value, deviceId) 
     211    if (luup.variable_get(serviceId, variable, deviceId) ~= tostring(value)) then 
     212        luup.variable_set(serviceId, variable, value, deviceId) 
     213    end 
     214end 
     215 
    176216--  
    177217-- Process elements in the <msg> part of a packet. 
     
    181221function processMsgSrc(context, lul_device, source) 
    182222    context.version = source 
    183     luup.variable_set(SERVICE_ID, "Version", source, lul_device) 
     223    set_if_different(SERVICE_ID, "Version", source, lul_device) 
    184224    return context 
    185225end 
     
    188228function processMsgUid(context, lul_device, uid) 
    189229    context.uid = uid 
    190     luup.variable_set(SERVICE_ID, "UID", uid, lul_device) 
     230    set_if_different(SERVICE_ID, "UID", uid, lul_device) 
    191231    return context 
    192232end 
     
    195235function processMsgDsb(context, lul_device, dsb) 
    196236    context.dsb = dsb 
    197     luup.variable_set(SERVICE_ID, "DaysSinceBirth", tonumber(dsb), lul_device) 
     237    set_if_different(SERVICE_ID, "DaysSinceBirth", tonumber(dsb), lul_device) 
    198238    return context 
    199239end 
     
    202242function processMsgTime(context, lul_device, time) 
    203243    context.time = time 
    204     luup.variable_set(SERVICE_ID, "Time", time, lul_device) 
     244    set_if_different(SERVICE_ID, "Time", time, lul_device) 
    205245    return context 
    206246end 
     
    329369        local childDevice = CHILD_DEVICE[context.sensor] 
    330370        if (childDevice ~= nil) then 
    331             luup.variable_set(ENERGY_SERVICE_ID, "Watts", context.watts, childDevice) 
    332             luup.variable_set(SERVICE_ID, "DaysSinceBirth", context.dsb, childDevice) 
    333             luup.variable_set(SERVICE_ID, "Time", context.time, childDevice) 
    334             luup.variable_set(TEMPERATURE_SERVICE_ID, "CurrentTemperature", context.tmpr, childDevice) 
    335             if (context.version) then luup.variable_set(SERVICE_ID, "Version", context.version, childDevice) end 
    336             if (context.uid) then luup.variable_set(SERVICE_ID, "UID", context.uid, childDevice) end 
     371            set_if_different(ENERGY_SERVICE_ID, "Watts", context.watts, childDevice) 
     372            set_if_different(SERVICE_ID, "DaysSinceBirth", context.dsb, childDevice) 
     373            set_if_different(SERVICE_ID, "Time", context.time, childDevice) 
     374            set_if_different(TEMPERATURE_SERVICE_ID, "CurrentTemperature", context.tmpr, childDevice) 
     375            if (context.version) then set_if_different(SERVICE_ID, "Version", context.version, childDevice) end 
     376            if (context.uid) then set_if_different(SERVICE_ID, "UID", context.uid, childDevice) end 
    337377        end 
    338378 
     
    341381            local childDevicePhase = CHILD_DEVICE_THREEPHASE[context.sensor][tostring(phase)] 
    342382            if (childDevicePhase ~= nil) then 
    343                 luup.variable_set(ENERGY_SERVICE_ID, "Watts", context.phase[tostring(phase)], childDevicePhase) 
    344                 luup.variable_set(SERVICE_ID, "DaysSinceBirth", context.dsb, childDevicePhase) 
    345                 luup.variable_set(SERVICE_ID, "Time", context.time, childDevicePhase) 
    346                 luup.variable_set(TEMPERATURE_SERVICE_ID, "CurrentTemperature", context.tmpr, childDevicePhase) 
    347                 if (context.version) then luup.variable_set(SERVICE_ID, "Version", context.version, childDevicePhase) end 
    348                 if (context.uid) then luup.variable_set(SERVICE_ID, "UID", context.uid, childDevicePhase) end 
    349             end 
    350         end 
    351  
    352         -- Note this appliance number, if permitted. 
    353         if (AUTO_DETECT or "0" ~= "0") then 
    354             local previousId = luup.variable_get(SERVICE_ID, "Appliance" .. context.sensor, lul_device) 
    355             if (previousId == nil or context.id ~= previousId) then 
    356                 luup.variable_set(SERVICE_ID, "Appliance" .. context.sensor, context.id, lul_device) 
    357                 CHILD_DEVICE_COUNT = CHILD_DEVICE_COUNT + 1 
    358                 -- Did we start with zero appliances?  Tell user we found another. 
    359                 if (CHILD_DEVICE_DISCOVERY_HANDLE ~= nil) then 
    360                     luup.task("Discovered " .. CHILD_DEVICE_COUNT .. (CHILD_DEVICE_COUNT == 1 and " appliance" or " appliances") .. ". Reload when all appliances are discovered", 1, string.format("%s[%d]", luup.devices[lul_device].description, lul_device), CHILD_DEVICE_DISCOVERY_HANDLE) 
    361                 end 
     383                set_if_different(ENERGY_SERVICE_ID, "Watts", context.phase[tostring(phase)], childDevicePhase) 
     384                set_if_different(SERVICE_ID, "DaysSinceBirth", context.dsb, childDevicePhase) 
     385                set_if_different(SERVICE_ID, "Time", context.time, childDevicePhase) 
     386                set_if_different(TEMPERATURE_SERVICE_ID, "CurrentTemperature", context.tmpr, childDevicePhase) 
     387                if (context.version) then set_if_different(SERVICE_ID, "Version", context.version, childDevicePhase) end 
     388                if (context.uid) then set_if_different(SERVICE_ID, "UID", context.uid, childDevicePhase) end 
    362389            end 
    363390        end 
     
    365392        -- Compute parent device's reading, using its custom formula. 
    366393        APPLIANCE_POWER[context.sensor] = context.watts 
    367         luup.variable_set(ENERGY_SERVICE_ID, "Watts", calculateFormula(APPLIANCE_POWER), lul_device) 
     394        set_if_different(ENERGY_SERVICE_ID, "Watts", calculateFormula(APPLIANCE_POWER), lul_device) 
     395    elseif (context.packetType == "realtime" and context.type == "2") then 
     396        -- Impulse (OptiSmart) meter data. 
     397 
     398        -- Log the child device's impulse (if there is a child device). 
     399        local childDevice = CHILD_DEVICE[context.sensor] 
     400        if (childDevice ~= nil) then 
     401            set_if_different(ENERGY_SERVICE_ID, "Pulse", context.imp, childDevice) 
     402            local zero = luup.variable_get(SERVICE_ID, "PulseZero", childDevice) or "0" 
     403            set_if_different(SERVICE_ID, "ImpulsePerUnit", context.ipu, childDevice) 
     404            set_if_different(ENERGY_SERVICE_ID, "KWH", (tonumber(context.imp) - tonumber(zero))/tonumber(context.ipu), childDevice) 
     405            set_if_different(SERVICE_ID, "DaysSinceBirth", context.dsb, childDevice) 
     406            set_if_different(SERVICE_ID, "Time", context.time, childDevice) 
     407            set_if_different(TEMPERATURE_SERVICE_ID, "CurrentTemperature", context.tmpr, childDevice) 
     408            if (context.version) then set_if_different(SERVICE_ID, "Version", context.version, childDevice) end 
     409            if (context.uid) then set_if_different(SERVICE_ID, "UID", context.uid, childDevice) end 
     410        end 
     411    end 
     412 
     413    -- Note this appliance number, if permitted. 
     414    if (AUTO_DETECT ~= "0") then 
     415        local previousId = luup.variable_get(SERVICE_ID, "Appliance" .. context.sensor, lul_device) 
     416        if (previousId == nil or context.id ~= previousId) then 
     417            set_if_different(SERVICE_ID, "Appliance" .. context.sensor, context.id, lul_device) 
     418            set_if_different(SERVICE_ID, "Appliance" .. context.sensor .. "Type", context.type, lul_device) 
     419            CHILD_DEVICE_COUNT = CHILD_DEVICE_COUNT + 1 
     420            -- Did we start with zero appliances?  Tell user we found another. 
     421            if (CHILD_DEVICE_DISCOVERY_HANDLE ~= nil) then 
     422                luup.task("Discovered " .. CHILD_DEVICE_COUNT .. (CHILD_DEVICE_COUNT == 1 and " appliance" or " appliances") .. ". Reload when all appliances are discovered", 1, string.format("%s[%d]", luup.devices[lul_device].description, lul_device), CHILD_DEVICE_DISCOVERY_HANDLE) 
     423            end 
     424        end 
    368425    end 
    369426 
    370427    if (context.tmpr) then 
    371         luup.variable_set(TEMPERATURE_SERVICE_ID, "CurrentTemperature", context.tmpr, lul_device) 
     428        set_if_different(TEMPERATURE_SERVICE_ID, "CurrentTemperature", context.tmpr, lul_device) 
    372429        -- Set temperature on the child temperature device (if there is one). 
    373430        if (CHILD_TEMPERATURE_DEVICE) then 
    374             luup.variable_set(TEMPERATURE_SERVICE_ID, "CurrentTemperature", context.tmpr, CHILD_TEMPERATURE_DEVICE) 
     431            set_if_different(TEMPERATURE_SERVICE_ID, "CurrentTemperature", context.tmpr, CHILD_TEMPERATURE_DEVICE) 
    375432        end 
    376433    end 
     
    399456    for sensor = 0, 9 do 
    400457        local childDevice = CHILD_DEVICE[tostring(sensor)] 
    401         if (childDevice ~= nil) then 
     458        local childDeviceType = CHILD_DEVICE_TYPE[tostring(sensor)] 
     459        if (childDevice ~= nil and childDeviceType == "1") then 
    402460            luup.variable_set(SERVICE_ID, "TwoHourlyHistory", serializeHistory(TWOHOURLY_HISTORY[tostring(sensor)]), childDevice) 
    403461            luup.variable_set(SERVICE_ID, "DailyHistory", serializeHistory(DAILY_HISTORY[tostring(sensor)]), childDevice) 
Note: See TracChangeset for help on using the changeset viewer.