Hardware/Heatmaster/HeatmasterGroup.cs
author moel.mich
Sat, 02 Oct 2010 18:15:46 +0000
changeset 206 1fa8eddc24a7
parent 195 0ee888c485d5
child 256 6dc6410489f4
permissions -rw-r--r--
Replaced HttpUtility.UrlEncode with Uri.EscapeDataString and deleted the reference to the System.Web assembly. The System.Web assembly seems to be missing on some .NET 4.0 installations (and the overhead of using it is a bit large, just for the UrlEncode method).
moel@171
     1
/*
moel@171
     2
  
moel@171
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@171
     4
moel@171
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@171
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@171
     7
  the License. You may obtain a copy of the License at
moel@171
     8
 
moel@171
     9
  http://www.mozilla.org/MPL/
moel@171
    10
moel@171
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@171
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@171
    13
  for the specific language governing rights and limitations under the License.
moel@171
    14
moel@171
    15
  The Original Code is the Open Hardware Monitor code.
moel@171
    16
moel@171
    17
  The Initial Developer of the Original Code is 
moel@171
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@171
    19
  Portions created by the Initial Developer are Copyright (C) 2010
moel@171
    20
  the Initial Developer. All Rights Reserved.
moel@171
    21
moel@171
    22
  Contributor(s):
moel@171
    23
moel@171
    24
  Alternatively, the contents of this file may be used under the terms of
moel@171
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@171
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@171
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@171
    28
  of those above. If you wish to allow use of your version of this file only
moel@171
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@171
    30
  use your version of this file under the terms of the MPL, indicate your
moel@171
    31
  decision by deleting the provisions above and replace them with the notice
moel@171
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@171
    33
  the provisions above, a recipient may use your version of this file under
moel@171
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@171
    35
 
moel@171
    36
*/
moel@171
    37
moel@171
    38
using System;
moel@171
    39
using System.Collections.Generic;
moel@182
    40
using System.Globalization;
moel@171
    41
using System.IO.Ports;
moel@172
    42
using System.Security;
moel@171
    43
using System.Text;
moel@171
    44
using System.Threading;
moel@172
    45
using Microsoft.Win32;
moel@171
    46
moel@171
    47
namespace OpenHardwareMonitor.Hardware.Heatmaster {
moel@171
    48
  internal class HeatmasterGroup : IGroup {
moel@171
    49
moel@195
    50
    private readonly List<Heatmaster> hardware = new List<Heatmaster>();
moel@195
    51
    private readonly StringBuilder report = new StringBuilder();
moel@171
    52
moel@171
    53
    private static string ReadLine(SerialPort port, int timeout) {
moel@171
    54
      int i = 0;
moel@171
    55
      StringBuilder builder = new StringBuilder();
moel@171
    56
      while (i < timeout) {
moel@171
    57
        while (port.BytesToRead > 0) {
moel@171
    58
          byte b = (byte)port.ReadByte();
moel@171
    59
          switch (b) {
moel@171
    60
            case 0xAA: return ((char)b).ToString();
moel@171
    61
            case 0x0D: return builder.ToString();
moel@171
    62
            default: builder.Append((char)b); break;
moel@171
    63
          }
moel@171
    64
        }
moel@171
    65
        i++;
moel@171
    66
        Thread.Sleep(1);
moel@171
    67
      }
moel@171
    68
      throw new TimeoutException();
moel@172
    69
    }
moel@172
    70
moel@172
    71
    private static string[] GetRegistryPortNames() {
moel@172
    72
      List<string> result = new List<string>();
moel@175
    73
      string[] paths = { "", "&MI_00" };
moel@172
    74
      try {
moel@175
    75
        foreach (string path in paths) {
moel@175
    76
          RegistryKey key = Registry.LocalMachine.OpenSubKey(
moel@175
    77
            @"SYSTEM\CurrentControlSet\Enum\USB\VID_10C4&PID_EA60" + path);
moel@175
    78
          if (key != null) {
moel@175
    79
            foreach (string subKeyName in key.GetSubKeyNames()) {
moel@175
    80
              RegistryKey subKey =
moel@175
    81
                key.OpenSubKey(subKeyName + "\\" + "Device Parameters");
moel@175
    82
              if (subKey != null) {
moel@175
    83
                string name = subKey.GetValue("PortName") as string;
moel@175
    84
                if (name != null && !result.Contains(name))
moel@195
    85
                  result.Add(name);
moel@175
    86
              }
moel@172
    87
            }
moel@172
    88
          }
moel@172
    89
        }
moel@172
    90
      } catch (SecurityException) { }
moel@172
    91
      return result.ToArray();
moel@172
    92
    }
moel@171
    93
moel@171
    94
    public HeatmasterGroup(ISettings settings) {
moel@172
    95
      
moel@172
    96
      // No implementation for Heatmaster on Unix systems
moel@195
    97
      int p = (int)Environment.OSVersion.Platform;
moel@172
    98
      if ((p == 4) || (p == 128))
moel@172
    99
        return;
moel@171
   100
moel@172
   101
      string[] portNames = GetRegistryPortNames();      
moel@199
   102
      for (int i = 0; i < portNames.Length; i++) {
moel@182
   103
        bool isValid = false;
moel@182
   104
        try {        
moel@182
   105
          using (SerialPort serialPort =
moel@182
   106
            new SerialPort(portNames[i], 38400, Parity.None, 8, StopBits.One)) {
moel@182
   107
            serialPort.NewLine = ((char)0x0D).ToString();            
moel@182
   108
            report.Append("Port Name: "); report.AppendLine(portNames[i]);
moel@171
   109
moel@182
   110
            try {
moel@182
   111
              serialPort.Open();
moel@182
   112
            } catch (UnauthorizedAccessException) {
moel@182
   113
              report.AppendLine("Exception: Access Denied");
moel@182
   114
            }
moel@171
   115
moel@182
   116
            if (serialPort.IsOpen) {
moel@182
   117
              serialPort.DiscardInBuffer();
moel@182
   118
              serialPort.DiscardOutBuffer();
moel@182
   119
              serialPort.Write(new byte[] { 0xAA }, 0, 1);
moel@171
   120
moel@182
   121
              int j = 0;
moel@182
   122
              while (serialPort.BytesToRead == 0 && j < 10) {
moel@182
   123
                Thread.Sleep(20);
moel@182
   124
                j++;
moel@171
   125
              }
moel@182
   126
              if (serialPort.BytesToRead > 0) {
moel@182
   127
                bool flag = false;
moel@182
   128
                while (serialPort.BytesToRead > 0 && !flag) {
moel@182
   129
                  flag |= (serialPort.ReadByte() == 0xAA);
moel@182
   130
                }
moel@182
   131
                if (flag) {
moel@182
   132
                  serialPort.WriteLine("[0:0]RH");
moel@182
   133
                  try {
moel@182
   134
                    int k = 0;
moel@182
   135
                    int revision = 0;
moel@182
   136
                    while (k < 5) {
moel@182
   137
                      string line = ReadLine(serialPort, 100);
moel@182
   138
                      if (line.StartsWith("-[0:0]RH:",
moel@182
   139
                        StringComparison.Ordinal)) {
moel@182
   140
                        revision = int.Parse(line.Substring(9), 
moel@182
   141
                          CultureInfo.InvariantCulture);
moel@182
   142
                        break;
moel@182
   143
                      }
moel@182
   144
                      k++;
moel@171
   145
                    }
moel@182
   146
                    isValid = (revision == 770);
moel@182
   147
                    if (!isValid) {
moel@182
   148
                      report.Append("Status: Wrong Hardware Revision " +
moel@182
   149
                        revision.ToString(CultureInfo.InvariantCulture));
moel@182
   150
                    }
moel@182
   151
                  } catch (TimeoutException) {
moel@182
   152
                    report.AppendLine("Status: Timeout Reading Revision");
moel@171
   153
                  }
moel@182
   154
                } else {
moel@182
   155
                  report.AppendLine("Status: Wrong Startflag");
moel@171
   156
                }
moel@171
   157
              } else {
moel@182
   158
                report.AppendLine("Status: No Response");
moel@171
   159
              }
moel@182
   160
              serialPort.DiscardInBuffer();
moel@171
   161
            } else {
moel@182
   162
              report.AppendLine("Status: Port not Open");
moel@182
   163
            }            
moel@171
   164
          }
moel@171
   165
        } catch (Exception e) {
moel@171
   166
          report.AppendLine(e.ToString());
moel@182
   167
        }
moel@182
   168
moel@182
   169
        if (isValid) {
moel@182
   170
          report.AppendLine("Status: OK");
moel@182
   171
          hardware.Add(new Heatmaster(portNames[i], settings));
moel@182
   172
        }
moel@171
   173
        report.AppendLine();
moel@171
   174
      }
moel@171
   175
    }
moel@171
   176
moel@171
   177
    public IHardware[] Hardware {
moel@171
   178
      get {
moel@171
   179
        return hardware.ToArray();
moel@171
   180
      }
moel@171
   181
    }
moel@171
   182
moel@171
   183
    public string GetReport() {
moel@171
   184
      if (report.Length > 0) {
moel@171
   185
        report.Insert(0, "Serial Port Heatmaster" + Environment.NewLine +
moel@171
   186
          Environment.NewLine);
moel@171
   187
        report.AppendLine();
moel@171
   188
        return report.ToString();
moel@171
   189
      } else
moel@171
   190
        return null;
moel@171
   191
    }
moel@171
   192
moel@171
   193
    public void Close() {
moel@171
   194
      foreach (Heatmaster heatmaster in hardware)
moel@171
   195
        heatmaster.Close();
moel@171
   196
    }
moel@171
   197
  }
moel@171
   198
}