Added a first implementation for the Heatmaster fan controller.
authormoel.mich
Sun, 22 Aug 2010 21:53:11 +0000
changeset 17181ab5e53122e
parent 170 31858ba46e9c
child 172 c9d8de472546
Added a first implementation for the Heatmaster fan controller.
GUI/HardwareNode.cs
Hardware/Computer.cs
Hardware/Heatmaster/Heatmaster.cs
Hardware/Heatmaster/HeatmasterGroup.cs
Hardware/IHardware.cs
OpenHardwareMonitorLib.csproj
Properties/AssemblyVersion.cs
     1.1 --- a/GUI/HardwareNode.cs	Tue Aug 17 21:44:02 2010 +0000
     1.2 +++ b/GUI/HardwareNode.cs	Sun Aug 22 21:53:11 2010 +0000
     1.3 @@ -68,6 +68,9 @@
     1.4          case HardwareType.HDD: 
     1.5            this.Image = Utilities.EmbeddedResources.GetImage("hdd.png");
     1.6            break;
     1.7 +        case HardwareType.Heatmaster:
     1.8 +          this.Image = Utilities.EmbeddedResources.GetImage("bigng.png");
     1.9 +          break;
    1.10          case HardwareType.Mainboard: 
    1.11            this.Image = Utilities.EmbeddedResources.GetImage("mainboard.png");
    1.12            break;
     2.1 --- a/Hardware/Computer.cs	Tue Aug 17 21:44:02 2010 +0000
     2.2 +++ b/Hardware/Computer.cs	Sun Aug 22 21:53:11 2010 +0000
     2.3 @@ -99,8 +99,9 @@
     2.4        Add(new Mainboard.MainboardGroup(settings));
     2.5        Add(new CPU.CPUGroup(settings));
     2.6        Add(new ATI.ATIGroup(settings));
     2.7 -      Add(new Nvidia.NvidiaGroup(settings));
     2.8 +      Add(new Nvidia.NvidiaGroup(settings));      
     2.9        Add(new TBalancer.TBalancerGroup(settings));
    2.10 +      Add(new Heatmaster.HeatmasterGroup(settings));
    2.11  
    2.12        if (hddEnabled)
    2.13          Add(new HDD.HDDGroup(settings));
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/Hardware/Heatmaster/Heatmaster.cs	Sun Aug 22 21:53:11 2010 +0000
     3.3 @@ -0,0 +1,287 @@
     3.4 +/*
     3.5 +  
     3.6 +  Version: MPL 1.1/GPL 2.0/LGPL 2.1
     3.7 +
     3.8 +  The contents of this file are subject to the Mozilla Public License Version
     3.9 +  1.1 (the "License"); you may not use this file except in compliance with
    3.10 +  the License. You may obtain a copy of the License at
    3.11 + 
    3.12 +  http://www.mozilla.org/MPL/
    3.13 +
    3.14 +  Software distributed under the License is distributed on an "AS IS" basis,
    3.15 +  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    3.16 +  for the specific language governing rights and limitations under the License.
    3.17 +
    3.18 +  The Original Code is the Open Hardware Monitor code.
    3.19 +
    3.20 +  The Initial Developer of the Original Code is 
    3.21 +  Michael Möller <m.moeller@gmx.ch>.
    3.22 +  Portions created by the Initial Developer are Copyright (C) 2010
    3.23 +  the Initial Developer. All Rights Reserved.
    3.24 +
    3.25 +  Contributor(s):
    3.26 +
    3.27 +  Alternatively, the contents of this file may be used under the terms of
    3.28 +  either the GNU General Public License Version 2 or later (the "GPL"), or
    3.29 +  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    3.30 +  in which case the provisions of the GPL or the LGPL are applicable instead
    3.31 +  of those above. If you wish to allow use of your version of this file only
    3.32 +  under the terms of either the GPL or the LGPL, and not to allow others to
    3.33 +  use your version of this file under the terms of the MPL, indicate your
    3.34 +  decision by deleting the provisions above and replace them with the notice
    3.35 +  and other provisions required by the GPL or the LGPL. If you do not delete
    3.36 +  the provisions above, a recipient may use your version of this file under
    3.37 +  the terms of any one of the MPL, the GPL or the LGPL.
    3.38 + 
    3.39 +*/
    3.40 +
    3.41 +using System;
    3.42 +using System.Collections.Generic;
    3.43 +using System.IO;
    3.44 +using System.IO.Ports;
    3.45 +using System.Text;
    3.46 +using System.Text.RegularExpressions;
    3.47 +using System.Threading;
    3.48 +
    3.49 +namespace OpenHardwareMonitor.Hardware.Heatmaster {
    3.50 +  internal class Heatmaster : Hardware {
    3.51 +
    3.52 +    private string portName;
    3.53 +    private SerialPort serialPort;
    3.54 +
    3.55 +    private int hardwareRevision;
    3.56 +    private int firmwareRevision;
    3.57 +    private int firmwareCRC;
    3.58 +
    3.59 +    private Sensor[] fans;
    3.60 +    private Sensor[] controls;
    3.61 +    private Sensor[] temperatures;
    3.62 +    private Sensor[] flows;
    3.63 +    private Sensor[] relays;
    3.64 +    
    3.65 +    private bool available = false;
    3.66 +
    3.67 +    private string ReadLine(int timeout) {
    3.68 +      int i = 0;
    3.69 +      StringBuilder builder = new StringBuilder();
    3.70 +      while (i <= timeout) {
    3.71 +        while (serialPort.BytesToRead > 0) {
    3.72 +          byte b = (byte)serialPort.ReadByte();
    3.73 +          switch (b) {
    3.74 +            case 0xAA: return ((char)b).ToString();
    3.75 +            case 0x0D: return builder.ToString();
    3.76 +            default: builder.Append((char)b); break;
    3.77 +          }
    3.78 +        }
    3.79 +        i++;
    3.80 +        Thread.Sleep(1);
    3.81 +      }
    3.82 +      throw new TimeoutException();
    3.83 +    }
    3.84 +
    3.85 +    private string ReadField(int device, char field) {
    3.86 +      serialPort.WriteLine("[0:" + device + "]R" + field);
    3.87 +      for (int i = 0; i < 5; i++) {
    3.88 +        string s = ReadLine(100);
    3.89 +        Match match = Regex.Match(s, @"-\[0:" + device.ToString() + @"\]R" +
    3.90 +          Regex.Escape(field.ToString()) + ":(.*)");
    3.91 +        if (match.Success) 
    3.92 +          return match.Groups[1].Value;
    3.93 +      }
    3.94 +      return null;
    3.95 +    }
    3.96 +
    3.97 +    private string ReadString(int device, char field) {
    3.98 +      string s = ReadField(device, field);
    3.99 +      if (s != null && s[0] == '"' && s[s.Length - 1] == '"')
   3.100 +        return s.Substring(1, s.Length - 2);
   3.101 +      else
   3.102 +        return null;
   3.103 +    }
   3.104 +
   3.105 +    private int ReadInteger(int device, char field) {
   3.106 +      string s = ReadField(device, field);      
   3.107 +      int i;
   3.108 +      if (int.TryParse(s, out i))
   3.109 +        return i;
   3.110 +      else
   3.111 +        return 0;
   3.112 +    }
   3.113 +
   3.114 +    private bool WriteField(int device, char field, string value) {
   3.115 +      serialPort.WriteLine("[0:" + device + "]W" + field + ":" + value);
   3.116 +      for (int i = 0; i < 5; i++) {
   3.117 +        string s = ReadLine(100);
   3.118 +        Match match = Regex.Match(s, @"-\[0:" + device.ToString() + @"\]W" + 
   3.119 +          Regex.Escape(field.ToString()) + ":" + value);
   3.120 +        if (match.Success)
   3.121 +          return true;
   3.122 +      }
   3.123 +      return false;
   3.124 +    }
   3.125 +
   3.126 +    private bool WriteInteger(int device, char field, int value) {
   3.127 +      return WriteField(device, field, value.ToString());
   3.128 +    }
   3.129 +
   3.130 +    private bool WriteString(int device, char field, string value) {
   3.131 +      return WriteField(device, field, '"' + value + '"');
   3.132 +    }
   3.133 +
   3.134 +    public Heatmaster(string portName, ISettings settings) {
   3.135 +
   3.136 +      this.portName = portName;
   3.137 +      try {
   3.138 +        serialPort = new SerialPort(portName, 38400, Parity.None, 8,
   3.139 +          StopBits.One);
   3.140 +        serialPort.Open();
   3.141 +        serialPort.NewLine = ((char)0x0D).ToString();
   3.142 +        
   3.143 +        hardwareRevision = ReadInteger(0, 'H');
   3.144 +        firmwareRevision = ReadInteger(0, 'V');
   3.145 +        firmwareCRC = ReadInteger(0, 'C');
   3.146 +
   3.147 +        int fanCount = ReadInteger(32, '?');
   3.148 +        int temperatureCount = ReadInteger(48, '?');
   3.149 +        int flowCount = ReadInteger(64, '?');
   3.150 +        int relayCount =  ReadInteger(80, '?');
   3.151 +
   3.152 +        fans = new Sensor[fanCount];
   3.153 +        controls = new Sensor[fanCount];
   3.154 +        for (int i = 0; i < fanCount; i++) {
   3.155 +          int device = 33 + i;
   3.156 +          string name = ReadString(device, 'C');
   3.157 +          fans[i] = new Sensor(name, device, SensorType.Fan, this, settings);          
   3.158 +          fans[i].Value = ReadInteger(device, 'R');
   3.159 +          ActivateSensor(fans[i]);
   3.160 +          controls[i] =
   3.161 +            new Sensor(name, device, SensorType.Control, this, settings);
   3.162 +          controls[i].Value = (100 / 255.0f) * ReadInteger(device, 'P');
   3.163 +          ActivateSensor(controls[i]);
   3.164 +        }
   3.165 +        
   3.166 +        for (int i = 0; i < fanCount; i++) {
   3.167 +          int device = 33 + i;
   3.168 +          string name = ReadString(device, 'C');
   3.169 +          
   3.170 +          fans[i].Value = ReadInteger(device, 'R');
   3.171 +          ActivateSensor(fans[i]);
   3.172 +        }
   3.173 +
   3.174 +        temperatures = new Sensor[temperatureCount];
   3.175 +        for (int i = 0; i < temperatureCount; i++) {
   3.176 +          int device = 49 + i;
   3.177 +          string name = ReadString(device, 'C');
   3.178 +          temperatures[i] =
   3.179 +            new Sensor(name, device, SensorType.Temperature, this, settings);
   3.180 +          int value = ReadInteger(device, 'T');
   3.181 +          temperatures[i].Value = 0.1f * value;
   3.182 +          if (value != -32768)
   3.183 +            ActivateSensor(temperatures[i]);
   3.184 +        }
   3.185 +
   3.186 +        flows = new Sensor[flowCount];
   3.187 +        for (int i = 0; i < flowCount; i++) {
   3.188 +          int device = 65 + i;
   3.189 +          string name = ReadString(device, 'C');
   3.190 +          flows[i] = new Sensor(name, device, SensorType.Flow, this, settings);
   3.191 +          flows[i].Value = 0.1f * ReadInteger(device, 'L');
   3.192 +          ActivateSensor(flows[i]);
   3.193 +        }
   3.194 +
   3.195 +        relays = new Sensor[relayCount];
   3.196 +        for (int i = 0; i < relayCount; i++) {
   3.197 +          int device = 81 + i;
   3.198 +          string name = ReadString(device, 'C');
   3.199 +          relays[i] = 
   3.200 +            new Sensor(name, device, SensorType.Control, this, settings);
   3.201 +          relays[i].Value = 100 * ReadInteger(device, 'S');
   3.202 +          ActivateSensor(relays[i]);
   3.203 +        }
   3.204 +
   3.205 +        // set the update rate to 2 Hz
   3.206 +        WriteInteger(0, 'L', 2);
   3.207 +        
   3.208 +        available = true;
   3.209 +
   3.210 +      } catch (IOException) { } catch (TimeoutException) { }      
   3.211 +    }
   3.212 +
   3.213 +    public override HardwareType HardwareType {
   3.214 +      get { return HardwareType.Heatmaster; }
   3.215 +    }
   3.216 +
   3.217 +    public override Identifier Identifier {
   3.218 +      get {
   3.219 +        return new Identifier("heatmaster",
   3.220 +          serialPort.PortName.TrimStart(new char[]{'/'}).ToLowerInvariant());
   3.221 +      }
   3.222 +    }
   3.223 +
   3.224 +    public override string Name {
   3.225 +      get { return "Heatmaster"; }
   3.226 +    }
   3.227 +
   3.228 +    public override void Update() {
   3.229 +      if (!available)
   3.230 +        return;
   3.231 +
   3.232 +      while (serialPort.BytesToRead > 0) {
   3.233 +        Match match = Regex.Match(ReadLine(0), @">\[0:(\d+)\]([0-9:\|-]+)");
   3.234 +        if (match.Success) {
   3.235 +          int device;
   3.236 +          if (int.TryParse(match.Groups[1].Value, out device)) {
   3.237 +            foreach (string s in match.Groups[2].Value.Split('|')) {
   3.238 +              string[] strings = s.Split(':');
   3.239 +              int[] ints = new int[strings.Length];
   3.240 +              for (int i = 0; i < ints.Length; i++)
   3.241 +                ints[i] = int.Parse(strings[i]);
   3.242 +              switch (device) {
   3.243 +                case 32:
   3.244 +                  if (ints.Length == 3 && ints[0] <= fans.Length) {
   3.245 +                    fans[ints[0] - 1].Value = ints[1];
   3.246 +                    controls[ints[0] - 1].Value = (100 / 255.0f) * ints[2];
   3.247 +                  }
   3.248 +                  break;
   3.249 +                case 48:
   3.250 +                  if (ints.Length == 2 && ints[0] <= temperatures.Length) 
   3.251 +                      temperatures[ints[0] - 1].Value = 0.1f * ints[1];
   3.252 +                  break;
   3.253 +                case 64:
   3.254 +                  if (ints.Length == 3 && ints[0] <= flows.Length)
   3.255 +                    flows[ints[0] - 1].Value = 0.1f * ints[1];
   3.256 +                  break;
   3.257 +                case 80:
   3.258 +                  if (ints.Length == 2 && ints[0] <= relays.Length)
   3.259 +                    relays[ints[0] - 1].Value = 100 * ints[1];
   3.260 +                  break;
   3.261 +              } 
   3.262 +            } 
   3.263 +          }
   3.264 +        }
   3.265 +      }
   3.266 +    }
   3.267 +
   3.268 +    public override string GetReport() {
   3.269 +      StringBuilder r = new StringBuilder();
   3.270 +
   3.271 +      r.AppendLine("Heatmaster");
   3.272 +      r.AppendLine();
   3.273 +      r.Append("Port: ");
   3.274 +      r.AppendLine(portName);
   3.275 +      r.Append("Hardware Revision: ");
   3.276 +      r.AppendLine(hardwareRevision.ToString());
   3.277 +      r.Append("Firmware Revision: ");
   3.278 +      r.AppendLine(firmwareRevision.ToString());
   3.279 +      r.Append("Firmware CRC: ");
   3.280 +      r.AppendLine(firmwareCRC.ToString());
   3.281 +      r.AppendLine();
   3.282 +
   3.283 +      return r.ToString();
   3.284 +    }
   3.285 +
   3.286 +    public void Close() {
   3.287 +      serialPort.Close();
   3.288 +    }
   3.289 +  }
   3.290 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/Hardware/Heatmaster/HeatmasterGroup.cs	Sun Aug 22 21:53:11 2010 +0000
     4.3 @@ -0,0 +1,172 @@
     4.4 +/*
     4.5 +  
     4.6 +  Version: MPL 1.1/GPL 2.0/LGPL 2.1
     4.7 +
     4.8 +  The contents of this file are subject to the Mozilla Public License Version
     4.9 +  1.1 (the "License"); you may not use this file except in compliance with
    4.10 +  the License. You may obtain a copy of the License at
    4.11 + 
    4.12 +  http://www.mozilla.org/MPL/
    4.13 +
    4.14 +  Software distributed under the License is distributed on an "AS IS" basis,
    4.15 +  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    4.16 +  for the specific language governing rights and limitations under the License.
    4.17 +
    4.18 +  The Original Code is the Open Hardware Monitor code.
    4.19 +
    4.20 +  The Initial Developer of the Original Code is 
    4.21 +  Michael Möller <m.moeller@gmx.ch>.
    4.22 +  Portions created by the Initial Developer are Copyright (C) 2010
    4.23 +  the Initial Developer. All Rights Reserved.
    4.24 +
    4.25 +  Contributor(s):
    4.26 +
    4.27 +  Alternatively, the contents of this file may be used under the terms of
    4.28 +  either the GNU General Public License Version 2 or later (the "GPL"), or
    4.29 +  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    4.30 +  in which case the provisions of the GPL or the LGPL are applicable instead
    4.31 +  of those above. If you wish to allow use of your version of this file only
    4.32 +  under the terms of either the GPL or the LGPL, and not to allow others to
    4.33 +  use your version of this file under the terms of the MPL, indicate your
    4.34 +  decision by deleting the provisions above and replace them with the notice
    4.35 +  and other provisions required by the GPL or the LGPL. If you do not delete
    4.36 +  the provisions above, a recipient may use your version of this file under
    4.37 +  the terms of any one of the MPL, the GPL or the LGPL.
    4.38 + 
    4.39 +*/
    4.40 +
    4.41 +using System;
    4.42 +using System.Collections.Generic;
    4.43 +using System.IO.Ports;
    4.44 +using System.Text;
    4.45 +using System.Threading;
    4.46 +
    4.47 +namespace OpenHardwareMonitor.Hardware.Heatmaster {
    4.48 +  internal class HeatmasterGroup : IGroup {
    4.49 +
    4.50 +    private List<Heatmaster> hardware = new List<Heatmaster>();
    4.51 +    private StringBuilder report = new StringBuilder();
    4.52 +
    4.53 +    private static string ReadLine(SerialPort port, int timeout) {
    4.54 +      int i = 0;
    4.55 +      StringBuilder builder = new StringBuilder();
    4.56 +      while (i < timeout) {
    4.57 +        while (port.BytesToRead > 0) {
    4.58 +          byte b = (byte)port.ReadByte();
    4.59 +          switch (b) {
    4.60 +            case 0xAA: return ((char)b).ToString();
    4.61 +            case 0x0D: return builder.ToString();
    4.62 +            default: builder.Append((char)b); break;
    4.63 +          }
    4.64 +        }
    4.65 +        i++;
    4.66 +        Thread.Sleep(1);
    4.67 +      }
    4.68 +      throw new TimeoutException();
    4.69 +    }   
    4.70 +
    4.71 +    public HeatmasterGroup(ISettings settings) {
    4.72 +
    4.73 +      string[] portNames = SerialPort.GetPortNames();      
    4.74 +      for (int i = portNames.Length - 1; i >= 0; i--) {
    4.75 +        try {
    4.76 +
    4.77 +          SerialPort serialPort =
    4.78 +            new SerialPort(portNames[i], 38400, Parity.None, 8, StopBits.One);
    4.79 +          serialPort.NewLine = ((char)0x0D).ToString();
    4.80 +
    4.81 +          bool isValid = false;
    4.82 +          report.Append("Port Name: "); report.AppendLine(portNames[i]);
    4.83 +
    4.84 +          try {
    4.85 +            serialPort.Open();
    4.86 +          } catch (UnauthorizedAccessException) {
    4.87 +            report.AppendLine("Exception: Access Denied");
    4.88 +          }
    4.89 +
    4.90 +          if (serialPort.IsOpen) {
    4.91 +            if (serialPort.CtsHolding) {
    4.92 +              serialPort.DiscardInBuffer();
    4.93 +              serialPort.DiscardOutBuffer(); 
    4.94 +              serialPort.Write(new byte[] { 0xAA }, 0, 1);
    4.95 +
    4.96 +              int j = 0;
    4.97 +              while (serialPort.BytesToRead == 0 && j < 10) {
    4.98 +                Thread.Sleep(20);
    4.99 +                j++;
   4.100 +              }
   4.101 +              if (serialPort.BytesToRead > 0) {
   4.102 +                bool flag = false;
   4.103 +                while (serialPort.BytesToRead > 0 && !flag) {
   4.104 +                  flag |= (serialPort.ReadByte() == 0xAA);
   4.105 +                }
   4.106 +                if (flag) {
   4.107 +                  serialPort.WriteLine("[0:0]RH");
   4.108 +                  try {
   4.109 +                    int k = 0;
   4.110 +                    int revision = 0;
   4.111 +                    while (k < 5) {
   4.112 +                      string line = ReadLine(serialPort, 100);
   4.113 +                      if (line.StartsWith("-[0:0]RH:")) {
   4.114 +                        int.TryParse(line.Substring(9), out revision);
   4.115 +                        break;
   4.116 +                      }
   4.117 +                      k++;
   4.118 +                    }
   4.119 +                    isValid = (revision == 770); 
   4.120 +                    if (!isValid) {
   4.121 +                      report.Append("Status: Wrong Hardware Revision " + 
   4.122 +                        revision.ToString());
   4.123 +                    }                 
   4.124 +                  } catch (TimeoutException) {
   4.125 +                    report.AppendLine("Status: Timeout Reading Revision");
   4.126 +                  }
   4.127 +                } else {
   4.128 +                  report.AppendLine("Status: Wrong Startflag");
   4.129 +                }
   4.130 +              } else {
   4.131 +                report.AppendLine("Status: No Response");
   4.132 +              }
   4.133 +            } else {
   4.134 +              report.AppendLine("Status: Not Clear to Send");
   4.135 +            }
   4.136 +            serialPort.DiscardInBuffer();
   4.137 +            serialPort.Close();
   4.138 +            serialPort.Dispose();
   4.139 +          } else {
   4.140 +            report.AppendLine("Status: Port not Open");
   4.141 +          }                          
   4.142 +          if (isValid) {
   4.143 +            report.AppendLine("Status: OK");
   4.144 +            hardware.Add(new Heatmaster(portNames[i], settings));
   4.145 +            return;
   4.146 +          }
   4.147 +        } catch (Exception e) {
   4.148 +          report.AppendLine(e.ToString());
   4.149 +        } 
   4.150 +        report.AppendLine();
   4.151 +      }
   4.152 +    }
   4.153 +
   4.154 +    public IHardware[] Hardware {
   4.155 +      get {
   4.156 +        return hardware.ToArray();
   4.157 +      }
   4.158 +    }
   4.159 +
   4.160 +    public string GetReport() {
   4.161 +      if (report.Length > 0) {
   4.162 +        report.Insert(0, "Serial Port Heatmaster" + Environment.NewLine +
   4.163 +          Environment.NewLine);
   4.164 +        report.AppendLine();
   4.165 +        return report.ToString();
   4.166 +      } else
   4.167 +        return null;
   4.168 +    }
   4.169 +
   4.170 +    public void Close() {
   4.171 +      foreach (Heatmaster heatmaster in hardware)
   4.172 +        heatmaster.Close();
   4.173 +    }
   4.174 +  }
   4.175 +}
     5.1 --- a/Hardware/IHardware.cs	Tue Aug 17 21:44:02 2010 +0000
     5.2 +++ b/Hardware/IHardware.cs	Sun Aug 22 21:53:11 2010 +0000
     5.3 @@ -46,6 +46,7 @@
     5.4      CPU,
     5.5      GPU,
     5.6      HDD,
     5.7 +    Heatmaster,
     5.8      Mainboard,
     5.9      SuperIO,
    5.10      TBalancer
     6.1 --- a/OpenHardwareMonitorLib.csproj	Tue Aug 17 21:44:02 2010 +0000
     6.2 +++ b/OpenHardwareMonitorLib.csproj	Sun Aug 22 21:53:11 2010 +0000
     6.3 @@ -71,6 +71,8 @@
     6.4      <Compile Include="Hardware\HDD\HDD.cs" />
     6.5      <Compile Include="Hardware\HDD\HDDGroup.cs" />
     6.6      <Compile Include="Hardware\HDD\SMART.cs" />
     6.7 +    <Compile Include="Hardware\Heatmaster\Heatmaster.cs" />
     6.8 +    <Compile Include="Hardware\Heatmaster\HeatmasterGroup.cs" />
     6.9      <Compile Include="Hardware\IComputer.cs" />
    6.10      <Compile Include="Hardware\Identifier.cs" />
    6.11      <Compile Include="Hardware\IElement.cs" />
    6.12 @@ -128,6 +130,7 @@
    6.13        <Install>true</Install>
    6.14      </BootstrapperPackage>
    6.15    </ItemGroup>
    6.16 +  <ItemGroup />
    6.17    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    6.18    <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
    6.19         Other similar extension points exist, see Microsoft.Common.targets.
     7.1 --- a/Properties/AssemblyVersion.cs	Tue Aug 17 21:44:02 2010 +0000
     7.2 +++ b/Properties/AssemblyVersion.cs	Sun Aug 22 21:53:11 2010 +0000
     7.3 @@ -38,5 +38,5 @@
     7.4  using System;
     7.5  using System.Reflection;
     7.6  
     7.7 -[assembly: AssemblyVersion("0.1.37.3")]
     7.8 -[assembly: AssemblyFileVersion("0.1.37.3")]
     7.9 +[assembly: AssemblyVersion("0.1.37.4")]
    7.10 +[assembly: AssemblyFileVersion("0.1.37.4")]