Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

migration from MAXDebug to hacs started

  • Loading branch information...
commit 3a54c17aedb882606cdbbee1b4f5a9bd808bf051 1 parent d7ecbec
@bietiekay authored
Showing with 2,157 additions and 93 deletions.
  1. +0 −7 Code/MAXDebug/MAXDebug.userprefs
  2. +12 −0 Code/xs1-data-logging/ELVMAX/DiffSet/BatteryStatus.cs
  3. +12 −0 Code/xs1-data-logging/ELVMAX/DiffSet/DeviceDiffSet.cs
  4. +107 −0 Code/xs1-data-logging/ELVMAX/DiffSet/DiffHouse.cs
  5. +92 −0 Code/xs1-data-logging/ELVMAX/DiffSet/HeatingThermostatDiff.cs
  6. +80 −0 Code/xs1-data-logging/ELVMAX/DiffSet/ShutterContactDiff.cs
  7. +20 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Base64.cs
  8. +13 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/MAXMessageTypes.cs
  9. +41 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/MAX_Exception.cs
  10. +69 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/C_Message.cs
  11. +192 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Devices/HeatingThermostat.cs
  12. +80 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Devices/HeatingThermostatPlus.cs
  13. +14 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Devices/IMAXDevice.cs
  14. +80 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Devices/PushButton.cs
  15. +169 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Devices/ShutterContact.cs
  16. +12 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Devices/ShutterContactModes.cs
  17. +14 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Devices/ThermostatModes.cs
  18. +80 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Devices/UnknownDevice.cs
  19. +80 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Devices/WallMountedThermostat.cs
  20. +88 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/H_Message.cs
  21. +10 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/IMAXMessage.cs
  22. +292 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/L_Message.cs
  23. +196 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/M_Message.cs
  24. +15 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Metadata/DeviceTypes.cs
  25. +52 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Metadata/House.cs
  26. +40 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Metadata/Room.cs
  27. +47 −0 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/TokenizeMessage.cs
  28. +34 −0 Code/xs1-data-logging/ELVMAX/MAXEncodeDecode.cs
  29. +145 −0 Code/xs1-data-logging/ELVMAX/MAXMonitoringThread.cs
  30. +38 −0 Code/xs1-data-logging/ELVMAX/Max_Threaded.cs
  31. +3 −3 Code/xs1-data-logging/LoggingThread.cs
  32. +0 −26 Code/xs1-data-logging/Max/MAXEncodeDecode.cs
  33. +0 −55 Code/xs1-data-logging/Max/MaxThread.cs
  34. +30 −2 Code/xs1-data-logging/xs1-data-logging.csproj
View
7 Code/MAXDebug/MAXDebug.userprefs
@@ -5,13 +5,6 @@
<Pad Id="ProjectPad">
<State expanded="True">
<Node name="MAXDebug" expanded="True">
- <Node name="ELVMAX_Data" expanded="True">
- <Node name="Messages" expanded="True">
- <Node name="Devices" expanded="True" />
- <Node name="Metadata" expanded="True" />
- </Node>
- </Node>
- <Node name="Notes" expanded="True" />
<Node name="MAXMonitoringThread.cs" selected="True" />
</Node>
</State>
View
12 Code/xs1-data-logging/ELVMAX/DiffSet/BatteryStatus.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace xs1_data_logging
+{
+ public enum BatteryStatus
+ {
+ unchanged,
+ ok,
+ lowbattery
+ }
+}
+
View
12 Code/xs1-data-logging/ELVMAX/DiffSet/DeviceDiffSet.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace xs1_data_logging
+{
+ public interface IDeviceDiffSet
+ {
+ DeviceTypes DeviceType { get;}
+ String DeviceName { get;}
+ Int32 RoomID { get;}
+ String RoomName { get;}
+ }
+}
View
107 Code/xs1-data-logging/ELVMAX/DiffSet/DiffHouse.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Collections.Generic;
+
+namespace xs1_data_logging
+{
+ public static class DiffHouse
+ {
+ /// <summary>
+ /// This method calculates the difference between house1 and house2 - whereas house1 is the old house2 the new one
+ /// </summary>
+ public static List<IDeviceDiffSet> CalculateDifferences(Dictionary<String,IMAXDevice> DevicesHouse1, Dictionary<String,IMAXDevice> DevicesHouse2)
+ {
+ List<IDeviceDiffSet> Differences = new List<IDeviceDiffSet>();
+
+ foreach(KeyValuePair<String,IMAXDevice> House1KVPair in DevicesHouse1)
+ {
+ // now we have a device from house 1 - we need to get that same device in house 2
+ if (DevicesHouse2.ContainsKey(House1KVPair.Key))
+ {
+ // we got it
+ IMAXDevice House2Device = DevicesHouse2[House1KVPair.Key];
+
+ if (House1KVPair.Value.Type == DeviceTypes.HeatingThermostat)
+ {
+ // HeatingThermostat
+ HeatingThermostatDiff Diff = null;
+
+ HeatingThermostat Device1 = (HeatingThermostat)House1KVPair.Value;
+ HeatingThermostat Device2 = (HeatingThermostat)House2Device;
+
+ if (Device1.LowBattery != Device2.LowBattery)
+ {
+ if (Diff == null)
+ Diff = new HeatingThermostatDiff(Device2.Name,Device2.AssociatedRoom.RoomID,Device2.AssociatedRoom.RoomName);
+
+ if (Device2.LowBattery)
+ Diff.LowBattery = BatteryStatus.lowbattery;
+ else
+ Diff.LowBattery = BatteryStatus.ok;
+ }
+
+ if (Device1.Mode != Device2.Mode)
+ {
+ if (Diff == null)
+ Diff = new HeatingThermostatDiff(Device2.Name,Device2.AssociatedRoom.RoomID,Device2.AssociatedRoom.RoomName);
+
+ Diff.Mode = Device2.Mode;
+ }
+
+ if (Device1.Temperature != Device2.Temperature)
+ {
+ if (Diff == null)
+ Diff = new HeatingThermostatDiff(Device2.Name,Device2.AssociatedRoom.RoomID,Device2.AssociatedRoom.RoomName);
+
+ Diff.Temperature = Device2.Temperature;
+ }
+
+ if (Diff != null)
+ {
+ Differences.Add(Diff);
+ }
+ }
+ else
+ if (House1KVPair.Value.Type == DeviceTypes.ShutterContact)
+ {
+ // ShutterContact
+ ShutterContactDiff Diff = null;
+
+ ShutterContact Device1 = (ShutterContact)House1KVPair.Value;
+ ShutterContact Device2 = (ShutterContact)House2Device;
+
+ if (Device1.LowBattery != Device2.LowBattery)
+ {
+ if (Diff == null)
+ Diff = new ShutterContactDiff(Device2.Name,Device2.AssociatedRoom.RoomID,Device2.AssociatedRoom.RoomName);
+
+ if (Device2.LowBattery)
+ Diff.LowBattery = BatteryStatus.lowbattery;
+ else
+ Diff.LowBattery = BatteryStatus.ok;
+
+ }
+
+ if (Device1.ShutterState != Device2.ShutterState)
+ {
+ if (Diff == null)
+ Diff = new ShutterContactDiff(Device2.Name,Device2.AssociatedRoom.RoomID,Device2.AssociatedRoom.RoomName);
+
+ Diff.ShutterState = Device2.ShutterState;
+ }
+
+ if (Diff != null)
+ {
+ Differences.Add(Diff);
+ }
+
+ }
+
+
+ }
+ }
+
+ return Differences;
+ }
+ }
+}
+
View
92 Code/xs1-data-logging/ELVMAX/DiffSet/HeatingThermostatDiff.cs
@@ -0,0 +1,92 @@
+using System;
+
+namespace xs1_data_logging
+{
+ public class HeatingThermostatDiff : IDeviceDiffSet
+ {
+ private DeviceTypes _DeviceType;
+ private String _DeviceName;
+ private Int32 _RoomID;
+ private String _RoomName;
+
+ #region device specific diff information
+ private ThermostatModes mode;
+ private Double temperature;
+ private BatteryStatus lowBattery;
+ #endregion
+
+ public HeatingThermostatDiff (String Name, Int32 Room_ID, String Room_Name)
+ {
+ _DeviceType = DeviceTypes.HeatingThermostat;
+ _DeviceName = Name;
+ _RoomID = Room_ID;
+ _RoomName = Room_Name;
+ lowBattery = BatteryStatus.unchanged;
+ temperature = Double.NaN;
+ mode = ThermostatModes.unchanged;
+ }
+
+ #region IDeviceDiffSet implementation
+ public DeviceTypes DeviceType {
+ get {
+ return _DeviceType;
+ }
+ }
+
+ public string DeviceName {
+ get {
+ return _DeviceName;
+ }
+ }
+
+ public int RoomID {
+ get {
+ return _RoomID;
+ }
+ }
+
+ public string RoomName {
+ get {
+ return _RoomName;
+ }
+ }
+ #endregion
+
+ #region device specific diff properties
+ public ThermostatModes Mode {
+ get {
+ return mode;
+ }
+ set {
+ mode = value;
+ }
+ }
+
+ public Double Temperature {
+ get {
+ return temperature;
+ }
+ set {
+ temperature = value;
+ }
+ }
+
+ public BatteryStatus LowBattery {
+ get {
+ return lowBattery;
+ }
+ set {
+ lowBattery = value;
+ }
+ }
+ #endregion
+
+ public override string ToString ()
+ {
+ return "\t"+lowBattery+"\t"+mode+"\t"+temperature;
+ //return string.Format ("[HeatingThermostatDiff: DeviceType={0}, DeviceName={1}, RoomID={2}, RoomName={3}, Mode={4}, Temperature={5}, LowBattery={6}]", DeviceType, DeviceName, RoomID, RoomName, Mode, Temperature, LowBattery);
+ }
+
+ }
+}
+
View
80 Code/xs1-data-logging/ELVMAX/DiffSet/ShutterContactDiff.cs
@@ -0,0 +1,80 @@
+using System;
+
+namespace xs1_data_logging
+{
+ public class ShutterContactDiff : IDeviceDiffSet
+ {
+ private DeviceTypes _DeviceType;
+ private String _DeviceName;
+ private Int32 _RoomID;
+ private String _RoomName;
+
+ #region device specific diff information
+ private ShutterContactModes state;
+ private BatteryStatus lowBattery;
+ #endregion
+
+ public ShutterContactDiff (String Name, Int32 Room_ID, String Room_Name)
+ {
+ _DeviceType = DeviceTypes.ShutterContact;
+ _DeviceName = Name;
+ _RoomID = Room_ID;
+ _RoomName = Room_Name;
+ lowBattery = BatteryStatus.unchanged;
+ state = ShutterContactModes.unchanged;
+ }
+
+ #region IDeviceDiffSet implementation
+ public DeviceTypes DeviceType {
+ get {
+ return _DeviceType;
+ }
+ }
+
+ public string DeviceName {
+ get {
+ return _DeviceName;
+ }
+ }
+
+ public int RoomID {
+ get {
+ return _RoomID;
+ }
+ }
+
+ public string RoomName {
+ get {
+ return _RoomName;
+ }
+ }
+ #endregion
+
+ #region device specific diff properties
+
+ public ShutterContactModes ShutterState {
+ get {
+ return state;
+ }
+ set {
+ state = value;
+ }
+ }
+
+ public BatteryStatus LowBattery {
+ get {
+ return lowBattery;
+ }
+ set {
+ lowBattery = value;
+ }
+ }
+ #endregion
+
+ public override string ToString ()
+ {
+ return "\t"+lowBattery+"\t"+state;
+ }
+ }
+}
+
View
20 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Base64.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace xs1_data_logging
+{
+ public static class Base64
+ {
+ #region Base64 encoding / decoding
+ public static string Encode(byte[] toEncode)
+ {
+ return Convert.ToBase64String(toEncode);
+ }
+
+ public static byte[] Decode(string encodedData)
+ {
+ return System.Convert.FromBase64String(encodedData);
+ }
+ #endregion
+ }
+}
+
View
13 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/MAXMessageTypes.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace xs1_data_logging
+{
+ public enum MAXMessageType
+ {
+ H,
+ M,
+ C,
+ L
+ }
+}
+
View
41 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/MAX_Exception.cs
@@ -0,0 +1,41 @@
+using System;
+
+namespace xs1_data_logging
+{
+ public abstract class AMAXException : Exception
+ {
+ protected AMAXException(Exception innerException = null) : base(String.Empty, innerException) { }
+
+ /// <summary>
+ /// The message which is associated to this Exception
+ /// </summary>
+ protected String _msg;
+
+ /// <summary>
+ /// The message property
+ /// </summary>
+ public override String Message
+ {
+ get { return _msg; }
+ }
+
+ /// <summary>
+ /// The error message
+ /// </summary>
+ /// <returns>The error message</returns>
+ public override string ToString()
+ {
+ return _msg;
+ }
+ }
+
+ public class MAXException: AMAXException
+ {
+ public MAXException(string Message)
+ {
+ _msg = Message;
+ }
+ }
+
+}
+
View
69 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/C_Message.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Text;
+
+namespace xs1_data_logging
+{
+ // The C response contains information about the configuration of a device.
+ public class C_Message : IMAXMessage
+ {
+ #region Message specific data
+ public String RFAdress;
+ public byte[] RawMessageDecoded;
+ #endregion
+
+ #region ToString override
+ public override string ToString ()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ //sb.AppendLine("C-Message:");
+
+ //sb.AppendLine("RF Address: "+RFAdress);
+
+ //System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
+ //sb.AppendLine("ASCII: "+enc.GetString(RawMessageDecoded));
+ //sb.Append("RAW: ");
+ /*
+ foreach(byte _b in RawMessageDecoded)
+ {
+ sb.Append(_b);
+ sb.Append(" ");
+ }
+ */
+ return sb.ToString();
+ }
+ #endregion
+
+ #region IMaxData implementation
+ public MAXMessageType MessageType
+ {
+ get
+ {
+ return MAXMessageType.C;
+ }
+ }
+ #endregion
+
+ // initializes this class and processes the given Input Message and fills the Message Fields
+ public C_Message (String RAW_Message, House _House)
+ {
+ if (RAW_Message.Length < 2)
+ throw new MAXException("Unable to process the RAW Message.");
+
+ if (!RAW_Message.StartsWith("C:"))
+ throw new MAXException("Unable to process the RAW Message. Not a C Message.");
+
+ String[] SplittedRAWMessage = RAW_Message.Remove(0,2).Split(new char[1] { ',' });
+
+ if (SplittedRAWMessage.Length >= 2)
+ {
+ RFAdress = SplittedRAWMessage[0];//Int32.Parse(SplittedRAWMessage[0],System.Globalization.NumberStyles.HexNumber);
+ RawMessageDecoded = Base64.Decode(SplittedRAWMessage[1]);
+ }
+ else
+ throw new MAXException("Unable to process C Message. Not enough content.");
+
+ }
+ }
+}
+
View
192 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Devices/HeatingThermostat.cs
@@ -0,0 +1,192 @@
+using System;
+using System.Text;
+
+namespace xs1_data_logging
+{
+ public class HeatingThermostat : IMAXDevice
+ {
+ private DeviceTypes _Type;
+ private String _RFAddress;
+ private String _SerialNumber;
+ private String _Name;
+ private Room _Room;
+
+ private double temperature;
+ private DateTime validUntil;
+ private bool lowBattery;
+ private bool panelLock;
+ private bool gatewayOK;
+ private bool error;
+ private bool valid;
+ private bool isAnswer;
+ private bool linkError;
+ private ThermostatModes mode;
+
+ public override string ToString ()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.AppendLine("\tDeviceType: "+Type.ToString());
+ sb.AppendLine("\tDeviceName: "+Name);
+ sb.AppendLine("\tSerialNumber: "+SerialNumber);
+ sb.AppendLine("\tRFAddress: "+RFAddress);
+ sb.AppendLine("\tTemperature: "+Temperature);
+ sb.AppendLine("\tLowBattery: "+LowBattery);
+ sb.AppendLine("\tisAnwer: "+IsAnswer);
+ sb.AppendLine("\tpanelLock: "+PanelLock);
+ sb.AppendLine("\tgatewayOK: "+GatewayOK);
+ sb.AppendLine("\terror: "+Error);
+ sb.AppendLine("\tvalid: "+Valid);
+ sb.AppendLine("\tLinkError: "+LinkError);
+ sb.AppendLine("\tMode: "+Mode);
+
+ return sb.ToString();
+ }
+
+ public HeatingThermostat()
+ {
+ _Type = DeviceTypes.HeatingThermostat;
+ }
+
+ #region IMAXDevice implementation
+ public DeviceTypes Type {
+ get {
+ return _Type;
+ }
+ }
+
+ public string RFAddress {
+ get {
+ return _RFAddress;
+ }
+ set {
+ _RFAddress = value;
+ }
+ }
+
+ public string SerialNumber {
+ get {
+ return _SerialNumber;
+ }
+ set {
+ _SerialNumber = value;
+ }
+ }
+
+ public string Name {
+ get {
+ return _Name;
+ }
+ set {
+ _Name = value;
+ }
+ }
+
+ public Room AssociatedRoom
+ {
+ get {
+ return _Room;
+ }
+ set {
+ _Room = value;
+ }
+ }
+
+ #endregion
+
+ #region HeatingThermostat specific properties
+ public ThermostatModes Mode {
+ get {
+ return mode;
+ }
+ set {
+ mode = value;
+ }
+ }
+
+ public bool LinkError {
+ get {
+ return linkError;
+ }
+ set {
+ linkError = value;
+ }
+ }
+
+ public bool IsAnswer {
+ get {
+ return isAnswer;
+ }
+ set {
+ isAnswer = value;
+ }
+ }
+
+ public bool Valid {
+ get {
+ return valid;
+ }
+ set {
+ valid = value;
+ }
+ }
+
+ public bool Error {
+ get {
+ return error;
+ }
+ set {
+ error = value;
+ }
+ }
+
+ public bool GatewayOK {
+ get {
+ return gatewayOK;
+ }
+ set {
+ gatewayOK = value;
+ }
+ }
+
+ public bool PanelLock {
+ get {
+ return panelLock;
+ }
+ set {
+ panelLock = value;
+ }
+ }
+ public double Temperature {
+ get {
+ return temperature;
+ }
+ set {
+ temperature = value;
+ }
+ }
+
+ public bool LowBattery {
+ get {
+ return lowBattery;
+ }
+ set {
+ lowBattery = value;
+ }
+ }
+ public DateTime ValidUntil {
+ get {
+ return validUntil;
+ }
+ set {
+ validUntil = value;
+ }
+ }
+ #endregion
+
+ #region GetDifferences
+ //public
+ #endregion
+ }
+}
+
View
80 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Devices/HeatingThermostatPlus.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Text;
+
+namespace xs1_data_logging
+{
+ public class HeatingThermostatPlus : IMAXDevice
+ {
+ private DeviceTypes _Type;
+ private String _RFAddress;
+ private String _SerialNumber;
+ private String _Name;
+ private Room _Room;
+
+ public override string ToString ()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.AppendLine("\tDeviceType: "+Type.ToString());
+ sb.AppendLine("\tDeviceName: "+Name);
+ sb.AppendLine("\tSerialNumber: "+SerialNumber);
+ sb.AppendLine("\tRFAddress: "+RFAddress);
+
+ return sb.ToString();
+ }
+
+ public HeatingThermostatPlus()
+ {
+ _Type = DeviceTypes.HeatingThermostatPlus;
+ }
+
+ #region IMAXDevice implementation
+ public DeviceTypes Type {
+ get {
+ return _Type;
+ }
+ }
+
+ public string RFAddress {
+ get {
+ return _RFAddress;
+ }
+ set {
+ _RFAddress = value;
+ }
+ }
+
+ public string SerialNumber {
+ get {
+ return _SerialNumber;
+ }
+ set {
+ _SerialNumber = value;
+ }
+ }
+
+ public string Name {
+ get {
+ return _Name;
+ }
+ set {
+ _Name = value;
+ }
+ }
+
+ public Room AssociatedRoom
+ {
+ get {
+ return _Room;
+ }
+ set {
+ _Room = value;
+ }
+ }
+
+ #endregion
+
+
+ }
+}
+
View
14 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Devices/IMAXDevice.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace xs1_data_logging
+{
+ public interface IMAXDevice
+ {
+ DeviceTypes Type { get;}
+ String RFAddress { get; set;}
+ String SerialNumber { get; set;}
+ String Name { get; set;}
+ Room AssociatedRoom { get; set;}
+ }
+}
+
View
80 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Devices/PushButton.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Text;
+
+namespace xs1_data_logging
+{
+ public class PushButton : IMAXDevice
+ {
+ private DeviceTypes _Type;
+ private String _RFAddress;
+ private String _SerialNumber;
+ private String _Name;
+ private Room _Room;
+
+ public override string ToString ()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.AppendLine("\tDeviceType: "+Type.ToString());
+ sb.AppendLine("\tDeviceName: "+Name);
+ sb.AppendLine("\tSerialNumber: "+SerialNumber);
+ sb.AppendLine("\tRFAddress: "+RFAddress);
+
+ return sb.ToString();
+ }
+
+ public PushButton()
+ {
+ _Type = DeviceTypes.PushButton;
+ }
+
+ #region IMAXDevice implementation
+ public DeviceTypes Type {
+ get {
+ return _Type;
+ }
+ }
+
+ public string RFAddress {
+ get {
+ return _RFAddress;
+ }
+ set {
+ _RFAddress = value;
+ }
+ }
+
+ public string SerialNumber {
+ get {
+ return _SerialNumber;
+ }
+ set {
+ _SerialNumber = value;
+ }
+ }
+
+ public string Name {
+ get {
+ return _Name;
+ }
+ set {
+ _Name = value;
+ }
+ }
+
+ public Room AssociatedRoom
+ {
+ get {
+ return _Room;
+ }
+ set {
+ _Room = value;
+ }
+ }
+
+ #endregion
+
+
+ }
+}
+
View
169 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Devices/ShutterContact.cs
@@ -0,0 +1,169 @@
+using System;
+using System.Text;
+
+namespace xs1_data_logging
+{
+ public class ShutterContact : IMAXDevice
+ {
+ private DeviceTypes _Type;
+ private String _RFAddress;
+ private String _SerialNumber;
+ private String _Name;
+ private Room _Room;
+
+ private bool lowBattery;
+ private bool panelLock;
+ private bool gatewayOK;
+ private bool error;
+ private bool valid;
+ private bool isAnswer;
+ private bool linkError;
+ private ShutterContactModes shutterState;
+
+ public override string ToString ()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.AppendLine("\tDeviceType: "+Type.ToString());
+ sb.AppendLine("\tDeviceName: "+Name);
+ sb.AppendLine("\tSerialNumber: "+SerialNumber);
+ sb.AppendLine("\tRFAddress: "+RFAddress);
+ sb.AppendLine("\tLowBattery: "+LowBattery);
+ sb.AppendLine("\tisAnwer: "+IsAnswer);
+ sb.AppendLine("\tpanelLock: "+PanelLock);
+ sb.AppendLine("\tgatewayOK: "+GatewayOK);
+ sb.AppendLine("\terror: "+Error);
+ sb.AppendLine("\tvalid: "+Valid);
+ sb.AppendLine("\tLinkError: "+LinkError);
+ sb.AppendLine("\tShutterState: "+ShutterState);
+
+ return sb.ToString();
+ }
+
+ public ShutterContact()
+ {
+ _Type = DeviceTypes.ShutterContact;
+ }
+
+ #region IMAXDevice implementation
+ public DeviceTypes Type {
+ get {
+ return _Type;
+ }
+ }
+
+ public string RFAddress {
+ get {
+ return _RFAddress;
+ }
+ set {
+ _RFAddress = value;
+ }
+ }
+
+ public string SerialNumber {
+ get {
+ return _SerialNumber;
+ }
+ set {
+ _SerialNumber = value;
+ }
+ }
+
+ public string Name {
+ get {
+ return _Name;
+ }
+ set {
+ _Name = value;
+ }
+ }
+
+ public Room AssociatedRoom
+ {
+ get {
+ return _Room;
+ }
+ set {
+ _Room = value;
+ }
+ }
+
+ #endregion
+
+ #region ShutterContact specific properties
+
+ public ShutterContactModes ShutterState {
+ get {
+ return shutterState;
+ }
+ set {
+ shutterState = value;
+ }
+ }
+ public bool LinkError {
+ get {
+ return linkError;
+ }
+ set {
+ linkError = value;
+ }
+ }
+
+ public bool IsAnswer {
+ get {
+ return isAnswer;
+ }
+ set {
+ isAnswer = value;
+ }
+ }
+
+ public bool Valid {
+ get {
+ return valid;
+ }
+ set {
+ valid = value;
+ }
+ }
+
+ public bool Error {
+ get {
+ return error;
+ }
+ set {
+ error = value;
+ }
+ }
+
+ public bool GatewayOK {
+ get {
+ return gatewayOK;
+ }
+ set {
+ gatewayOK = value;
+ }
+ }
+
+ public bool PanelLock {
+ get {
+ return panelLock;
+ }
+ set {
+ panelLock = value;
+ }
+ }
+ public bool LowBattery {
+ get {
+ return lowBattery;
+ }
+ set {
+ lowBattery = value;
+ }
+ }
+ #endregion
+
+ }
+}
+
View
12 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Devices/ShutterContactModes.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace xs1_data_logging
+{
+ public enum ShutterContactModes
+ {
+ closed,
+ open,
+ unchanged
+ }
+}
+
View
14 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Devices/ThermostatModes.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace xs1_data_logging
+{
+ public enum ThermostatModes
+ {
+ automatic,
+ manual,
+ vacation,
+ boost,
+ unchanged
+ }
+}
+
View
80 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Devices/UnknownDevice.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Text;
+
+namespace xs1_data_logging
+{
+ public class UnknownDevice : IMAXDevice
+ {
+ private DeviceTypes _Type;
+ private String _RFAddress;
+ private String _SerialNumber;
+ private String _Name;
+ private Room _Room;
+
+ public override string ToString ()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.AppendLine("\tDeviceType: "+Type.ToString());
+ sb.AppendLine("\tDeviceName: "+Name);
+ sb.AppendLine("\tSerialNumber: "+SerialNumber);
+ sb.AppendLine("\tRFAddress: "+RFAddress);
+
+ return sb.ToString();
+ }
+
+ public UnknownDevice()
+ {
+ _Type = DeviceTypes.Invalid;
+ }
+
+ #region IMAXDevice implementation
+ public DeviceTypes Type {
+ get {
+ return _Type;
+ }
+ }
+
+ public string RFAddress {
+ get {
+ return _RFAddress;
+ }
+ set {
+ _RFAddress = value;
+ }
+ }
+
+ public string SerialNumber {
+ get {
+ return _SerialNumber;
+ }
+ set {
+ _SerialNumber = value;
+ }
+ }
+
+ public string Name {
+ get {
+ return _Name;
+ }
+ set {
+ _Name = value;
+ }
+ }
+
+ public Room AssociatedRoom
+ {
+ get {
+ return _Room;
+ }
+ set {
+ _Room = value;
+ }
+ }
+
+ #endregion
+
+
+ }
+}
+
View
80 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Devices/WallMountedThermostat.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Text;
+
+namespace xs1_data_logging
+{
+ public class WallMountedThermostat : IMAXDevice
+ {
+ private DeviceTypes _Type;
+ private String _RFAddress;
+ private String _SerialNumber;
+ private String _Name;
+ private Room _Room;
+
+ public override string ToString ()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.AppendLine("\tDeviceType: "+Type.ToString());
+ sb.AppendLine("\tDeviceName: "+Name);
+ sb.AppendLine("\tSerialNumber: "+SerialNumber);
+ sb.AppendLine("\tRFAddress: "+RFAddress);
+
+ return sb.ToString();
+ }
+
+ public WallMountedThermostat()
+ {
+ _Type = DeviceTypes.WallMountedThermostat;
+ }
+
+ #region IMAXDevice implementation
+ public DeviceTypes Type {
+ get {
+ return _Type;
+ }
+ }
+
+ public string RFAddress {
+ get {
+ return _RFAddress;
+ }
+ set {
+ _RFAddress = value;
+ }
+ }
+
+ public string SerialNumber {
+ get {
+ return _SerialNumber;
+ }
+ set {
+ _SerialNumber = value;
+ }
+ }
+
+ public string Name {
+ get {
+ return _Name;
+ }
+ set {
+ _Name = value;
+ }
+ }
+
+ public Room AssociatedRoom
+ {
+ get {
+ return _Room;
+ }
+ set {
+ _Room = value;
+ }
+ }
+
+ #endregion
+
+
+ }
+}
+
View
88 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/H_Message.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Text;
+
+namespace xs1_data_logging
+{
+ // The H response contains information about the Cube.
+ public class H_Message : IMAXMessage
+ {
+ #region Message specific data
+ public String MAXserialNumber;
+ public String RFAddress;
+ public Int32 FirmwareVersion;
+ public String HTTPConnId;
+ public DateTime CubeDateTime;
+ #endregion
+
+ #region ToString override
+ public override string ToString ()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendLine("H-Message:");
+ sb.AppendLine("Serial Number: "+MAXserialNumber);
+ sb.AppendLine("RF Address: "+RFAddress);
+ sb.AppendLine("Firmware Version: "+FirmwareVersion);
+ sb.AppendLine("HTTPConnId: "+HTTPConnId);
+ sb.AppendLine("DateTime: "+CubeDateTime.ToLongDateString()+" "+CubeDateTime.ToLongTimeString());
+ return sb.ToString();
+ }
+ #endregion
+
+ #region IMaxData implementation
+ public MAXMessageType MessageType
+ {
+ get
+ {
+ return MAXMessageType.M;
+ }
+ }
+ #endregion
+
+ #region Decode Date and Time
+ public DateTime DecodeDateTime(String CubeDate, String CubeTime)
+ {
+ /// Example:
+ /// CubeDate: 0c0812
+ /// CubeTime: 1505
+
+ Int32 Day = Int32.Parse(CubeDate.Substring (4,2),System.Globalization.NumberStyles.HexNumber);
+ Int32 Month = Int32.Parse(CubeDate.Substring(2,2),System.Globalization.NumberStyles.HexNumber);
+ Int32 Year = Int32.Parse(CubeDate.Substring(0,2),System.Globalization.NumberStyles.HexNumber)+2000;
+
+ Int32 Hour = Int32.Parse(CubeTime.Substring(0,2),System.Globalization.NumberStyles.HexNumber);
+ Int32 Minute = Int32.Parse(CubeTime.Substring(2,2),System.Globalization.NumberStyles.HexNumber);
+
+ DateTime time = new DateTime(Year,Month,Day,Hour,Minute,0);
+
+ return time;
+ }
+ #endregion
+
+ // initializes this class and processdes the given Input Message and fills the Message Fields
+ public H_Message (String RAW_Message, House _House)
+ {
+ if (RAW_Message.Length < 2)
+ throw new MAXException("Unable to process the RAW Message.");
+
+ if (!RAW_Message.StartsWith("H:"))
+ throw new MAXException("Unable to process the RAW Message. Not a H Message.");
+
+ String[] SplittedRAWMessage = RAW_Message.Remove(0,2).Split(new char[1] { ',' });
+
+ if (SplittedRAWMessage.Length >= 3)
+ {
+ MAXserialNumber = SplittedRAWMessage[0];
+ RFAddress = SplittedRAWMessage[1];//Int32.Parse(SplittedRAWMessage[1],System.Globalization.NumberStyles.HexNumber);
+ FirmwareVersion = Int32.Parse(SplittedRAWMessage[2],System.Globalization.NumberStyles.HexNumber);
+ HTTPConnId = SplittedRAWMessage[4];
+ CubeDateTime = DecodeDateTime(SplittedRAWMessage[7],SplittedRAWMessage[8]);
+
+ _House.CubeInformation = this;
+ }
+ else
+ throw new MAXException("Unable to process H Message. Not enough content.");
+
+ }
+ }
+}
+
View
10 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/IMAXMessage.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace xs1_data_logging
+{
+ public interface IMAXMessage
+ {
+ MAXMessageType MessageType { get; }
+ }
+}
+
View
292 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/L_Message.cs
@@ -0,0 +1,292 @@
+using System;
+using System.Text;
+using System.Collections.Generic;
+
+namespace xs1_data_logging
+{
+ // This reponse contains real-time information about the devices.
+ public class L_Message : IMAXMessage
+ {
+ #region Message specific data
+ public List<IMAXDevice> DevicesInThisMessage;
+ public byte[] RawMessageDecoded;
+ #endregion
+
+ #region ToString override
+ public override string ToString ()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.AppendLine("L-Message:");
+
+// System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
+// sb.AppendLine("ASCII: "+enc.GetString(RawMessageDecoded));
+// sb.Append("RAW: ");
+//
+// foreach(byte _b in RawMessageDecoded)
+// {
+// sb.Append(_b);
+// sb.Append(" ");
+// }
+ foreach(IMAXDevice _device in DevicesInThisMessage)
+ {
+ switch(_device.Type)
+ {
+ case DeviceTypes.HeatingThermostat:
+ sb.Append(((HeatingThermostat)_device).ToString());
+ break;
+ case DeviceTypes.HeatingThermostatPlus:
+ sb.Append(((HeatingThermostatPlus)_device).ToString());
+ break;
+ case DeviceTypes.PushButton:
+ sb.Append(((PushButton)_device).ToString());
+ break;
+ case DeviceTypes.ShutterContact:
+ sb.Append(((ShutterContact)_device).ToString());
+ break;
+ case DeviceTypes.WallMountedThermostat:
+ sb.Append(((WallMountedThermostat)_device).ToString());
+ break;
+ default:
+ break;
+ }
+ sb.AppendLine();
+ }
+
+ return sb.ToString();
+ }
+ #endregion
+
+ #region IMaxData implementation
+ public MAXMessageType MessageType
+ {
+ get
+ {
+ return MAXMessageType.C;
+ }
+ }
+ #endregion
+
+ // initializes this class and processes the given Input Message and fills the Message Fields
+ public L_Message (String RAW_Message, House _House)
+ {
+ DevicesInThisMessage = new List<IMAXDevice>();
+
+ if (RAW_Message.Length < 2)
+ throw new MAXException("Unable to process the RAW Message.");
+
+ if (!RAW_Message.StartsWith("L:"))
+ throw new MAXException("Unable to process the RAW Message. Not a L Message.");
+
+ RawMessageDecoded = Base64.Decode(RAW_Message.Remove(0,2));
+
+ // Tokenize RAW Message
+ List<byte[]> Tokenized = TokenizeMessage.Tokenize(RawMessageDecoded);
+
+ foreach(byte[] array in Tokenized)
+ {
+ StringBuilder sb = new StringBuilder();
+
+ for(int i=0;i<=2;i++)
+ {
+ sb.Append(array[i]);
+ }
+ // get data 1 and data 2 out
+ // on position 5,6
+ byte Data1 = array[4];
+ byte Data2 = array[5];
+
+ String binValueData1 = Convert.ToString(Data1,2);
+ binValueData1 = binValueData1.PadLeft(8, '0');
+ String binValueData2 = Convert.ToString(Data2,2);
+ binValueData2 = binValueData2.PadLeft(8, '0');
+
+ Int32 Cursor = 7; // the current position, skipping ?1,
+
+ String RFAddress = sb.ToString();
+
+ #region look for this RF Adress in the House's device list
+ List<IMAXDevice> AllDevices = _House.GetAllDevices();
+ IMAXDevice foundDevice = null;
+ foreach(IMAXDevice _device in AllDevices)
+ {
+ if (_device.RFAddress == RFAddress)
+ {
+ foundDevice = _device;
+ break;
+ }
+ }
+ #endregion
+
+ if (foundDevice != null)
+ {
+ DevicesInThisMessage.Add(foundDevice);
+
+ #region HeatingThermostat
+ if (foundDevice.Type == DeviceTypes.HeatingThermostat)
+ {
+ HeatingThermostat KnownDevice = (HeatingThermostat)foundDevice;
+
+ #region get all those flags out of Data1 and Data2
+
+ #region Valid
+ if (binValueData1[3] == '1')
+ KnownDevice.Valid = true;
+ else
+ KnownDevice.Valid = false;
+ #endregion
+
+ #region Error
+ if (binValueData1[4] == '1')
+ KnownDevice.Error = true;
+ else
+ KnownDevice.Error = false;
+ #endregion
+
+ #region IsAnswer
+ if (binValueData1[5] == '1')
+ KnownDevice.IsAnswer = true;
+ else
+ KnownDevice.IsAnswer = false;
+ #endregion
+
+ #region LowBattery
+ if (binValueData2[0] == '1')
+ KnownDevice.LowBattery = true;
+ else
+ KnownDevice.LowBattery = false;
+ #endregion
+
+ #region LinkError
+ if (binValueData2[1] == '1')
+ KnownDevice.LinkError = true;
+ else
+ KnownDevice.LinkError = false;
+ #endregion
+
+ #region PanelLock
+ if (binValueData2[2] == '1')
+ KnownDevice.PanelLock = true;
+ else
+ KnownDevice.PanelLock = false;
+ #endregion
+
+ #region GatewayOK
+ if (binValueData2[3] == '1')
+ KnownDevice.GatewayOK = true;
+ else
+ KnownDevice.GatewayOK = false;
+ #endregion
+
+ #region Mode
+ String ModeValue = binValueData2[6]+""+binValueData2[7];
+
+ switch(ModeValue)
+ {
+ case "00":
+ KnownDevice.Mode = ThermostatModes.automatic;
+ break;
+ case "01":
+ KnownDevice.Mode = ThermostatModes.manual;
+ break;
+ case "10":
+ KnownDevice.Mode = ThermostatModes.vacation;
+ break;
+ case "11":
+ KnownDevice.Mode = ThermostatModes.boost;
+ break;
+ default:
+ break;
+ }
+ #endregion
+
+ #endregion
+
+ // hurray, we've got a device we know how to handle B-)
+ ((HeatingThermostat)foundDevice).Temperature = array[Cursor]/2;
+ Cursor++;
+ }
+ #endregion
+
+ #region ShutterContact
+ if (foundDevice.Type == DeviceTypes.ShutterContact)
+ {
+ ShutterContact KnownDevice = (ShutterContact)foundDevice;
+
+ #region get all those flags out of Data1 and Data2
+
+ #region Valid
+ if (binValueData1[3] == '1')
+ KnownDevice.Valid = true;
+ else
+ KnownDevice.Valid = false;
+ #endregion
+
+ #region Error
+ if (binValueData1[4] == '1')
+ KnownDevice.Error = true;
+ else
+ KnownDevice.Error = false;
+ #endregion
+
+ #region IsAnswer
+ if (binValueData1[5] == '1')
+ KnownDevice.IsAnswer = true;
+ else
+ KnownDevice.IsAnswer = false;
+ #endregion
+
+ #region LowBattery
+ if (binValueData2[0] == '1')
+ KnownDevice.LowBattery = true;
+ else
+ KnownDevice.LowBattery = false;
+ #endregion
+
+ #region LinkError
+ if (binValueData2[1] == '1')
+ KnownDevice.LinkError = true;
+ else
+ KnownDevice.LinkError = false;
+ #endregion
+
+ #region PanelLock
+ if (binValueData2[2] == '1')
+ KnownDevice.PanelLock = true;
+ else
+ KnownDevice.PanelLock = false;
+ #endregion
+
+ #region GatewayOK
+ if (binValueData2[3] == '1')
+ KnownDevice.GatewayOK = true;
+ else
+ KnownDevice.GatewayOK = false;
+ #endregion
+
+ #region Mode
+ String ModeValue = binValueData2[6]+""+binValueData2[7];
+
+ switch(ModeValue)
+ {
+ case "00":
+ KnownDevice.ShutterState = ShutterContactModes.closed;
+ break;
+ case "10":
+ KnownDevice.ShutterState = ShutterContactModes.open;
+ break;
+ default:
+ break;
+ }
+ #endregion
+
+ #endregion
+
+ }
+ #endregion
+ }
+ }
+ }
+ }
+}
+
View
196 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/M_Message.cs
@@ -0,0 +1,196 @@
+using System;
+using System.Text;
+using System.Collections.Generic;
+
+namespace xs1_data_logging
+{
+ // The M response contains information about additional data, like the Rooms that are defined,
+ // the Devices and the names they were given, and how the rooms and Devices are linked to each other.
+ public class M_Message : IMAXMessage
+ {
+ #region Message specific data
+ public Int32 Index;
+ public Int32 Count;
+ public byte[] RawMessageDecoded;
+ private House thisHouse;
+ #endregion
+
+ #region ToString override
+ public override string ToString ()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ foreach(Room _room in thisHouse.Rooms)
+ {
+ sb.Append(_room.ToString());
+ }
+
+ return sb.ToString();
+ }
+ #endregion
+
+ #region IMaxData implementation
+ public MAXMessageType MessageType
+ {
+ get
+ {
+ return MAXMessageType.M;
+ }
+ }
+ #endregion
+
+ // initializes this class and processes the given Input Message and fills the Message Fields
+ public M_Message (String RAW_Message, House _House)
+ {
+ thisHouse = _House;
+ if (RAW_Message.Length < 2)
+ throw new MAXException("Unable to process the RAW Message.");
+
+ if (!RAW_Message.StartsWith("M:"))
+ throw new MAXException("Unable to process the RAW Message. Not a M Message.");
+
+ String[] SplittedRAWMessage = RAW_Message.Remove(0,2).Split(new char[1] { ',' });
+
+ if (SplittedRAWMessage.Length >= 3)
+ {
+ Index = Int32.Parse(SplittedRAWMessage[0],System.Globalization.NumberStyles.HexNumber);
+ Count = Int32.Parse(SplittedRAWMessage[1],System.Globalization.NumberStyles.HexNumber);
+ RawMessageDecoded = Base64.Decode(SplittedRAWMessage[2]);
+
+// System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
+// Console.WriteLine(enc.GetString (RawMessageDecoded));
+// StringBuilder hexlist = new StringBuilder();
+//
+// foreach(Byte _byte in RawMessageDecoded)
+// {
+// hexlist.Append(_byte.ToString()+" ");
+// }
+
+ Int32 Cursor = 2;
+
+ // now go deeper
+ Byte RoomCount = RawMessageDecoded[Cursor];
+ Cursor++;
+
+ #region Rooms
+ // go through every room
+ for(byte roomnumber=1;roomnumber<=RoomCount;roomnumber++)
+ {
+ Room newRoom = new Room(thisHouse);
+
+ newRoom.RoomID = RawMessageDecoded[Cursor];
+ Cursor++;
+
+ Byte RoomNameLength = RawMessageDecoded[Cursor];
+ Cursor++;
+
+ byte[] RoomName = new byte[RoomNameLength];
+
+ for(Byte j=0;j<=RoomNameLength-1;j++)
+ {
+ //RoomName.Append((char)RawMessageDecoded[Cursor]);
+ RoomName[j] = RawMessageDecoded[Cursor];
+ Cursor++;
+ }
+ newRoom.RoomName = System.Text.Encoding.UTF8.GetString(RoomName);
+
+ StringBuilder RFAddress_Buffer = new StringBuilder();
+ for(Byte j=0;j<=3-1;j++)
+ {
+ RFAddress_Buffer.Append(RawMessageDecoded[Cursor]);
+ Cursor++;
+ }
+ newRoom.RFAddress = RFAddress_Buffer.ToString();//Int32.Parse(RFAddress_Buffer.ToString(),System.Globalization.NumberStyles.HexNumber);
+
+ _House.Rooms.Add(newRoom);
+ }
+
+ #region Devices
+ //newRoom.RFAddress = Int32.Parse(RFAddress.ToString(),System.Globalization.NumberStyles.HexNumber);
+ Byte DeviceCount = RawMessageDecoded[Cursor];
+ Cursor++;
+ // go through all the devices in here
+ for(byte devicenumber=1;devicenumber<=DeviceCount;devicenumber++)
+ {
+ // read in the device
+ IMAXDevice newDevice = new UnknownDevice();
+
+ #region Determine DeviceType
+ Byte DevType = RawMessageDecoded[Cursor];
+ Cursor++;
+
+ switch(DevType)
+ {
+ case 1:
+ newDevice = new HeatingThermostat();
+ break;
+ case 2:
+ newDevice = new HeatingThermostatPlus();
+ break;
+ case 3:
+ newDevice = new WallMountedThermostat();
+ break;
+ case 4:
+ newDevice = new ShutterContact();
+ break;
+ case 5:
+ newDevice = new PushButton();
+ break;
+ default:
+ break;
+ }
+ #endregion
+
+ StringBuilder DeviceRFAddress = new StringBuilder();
+ for(Byte j=0;j<=3-1;j++)
+ {
+ DeviceRFAddress.Append(RawMessageDecoded[Cursor]);
+ Cursor++;
+ }
+ newDevice.RFAddress = DeviceRFAddress.ToString();//Int32.Parse(DeviceRFAddress.ToString(),System.Globalization.NumberStyles.HexNumber);
+
+ StringBuilder DeviceSerialNumber = new StringBuilder();
+ for(Byte j=0;j<=10-1;j++)
+ {
+ DeviceSerialNumber.Append((char)RawMessageDecoded[Cursor]);
+ Cursor++;
+ }
+ newDevice.SerialNumber = DeviceSerialNumber.ToString();
+
+ Byte DeviceNameLength = RawMessageDecoded[Cursor];
+ Cursor++;
+
+ byte[] DeviceName = new byte[DeviceNameLength];
+
+ for(Byte j=0;j<=DeviceNameLength-1;j++)
+ {
+ DeviceName[j] = RawMessageDecoded[Cursor];
+ Cursor++;
+ }
+ newDevice.Name = System.Text.Encoding.UTF8.GetString(DeviceName);
+
+ Byte RoomID = RawMessageDecoded[Cursor];
+ Cursor++;
+
+ // add the device to the room
+ foreach(Room newRoom in _House.Rooms)
+ {
+ if (newRoom.RoomID == RoomID)
+ {
+ newDevice.AssociatedRoom = newRoom;
+ newRoom.Devices.Add(newDevice);
+ break;
+ }
+ }
+ }
+ #endregion
+ // add this Room to the M_Message-Structure
+ #endregion
+ }
+ else
+ throw new MAXException("Unable to process M Message. Not enough content.");
+
+ }
+ }
+}
+
View
15 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Metadata/DeviceTypes.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace xs1_data_logging
+{
+ public enum DeviceTypes
+ {
+ Invalid = 256,
+ HeatingThermostat = 1,
+ HeatingThermostatPlus = 2,
+ WallMountedThermostat = 3,
+ ShutterContact = 4,
+ PushButton = 5
+ }
+}
+
View
52 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Metadata/House.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+
+namespace xs1_data_logging
+{
+ public class House
+ {
+ public String Name;
+ public List<Room> Rooms;
+ public H_Message CubeInformation;
+
+ public House ()
+ {
+ Rooms = new List<Room>();
+ }
+
+ /// <summary>
+ /// Gets all devices.
+ /// </summary>
+ /// <returns>
+ /// The all devices.
+ /// </returns>
+ public List<IMAXDevice> GetAllDevices()
+ {
+ List<IMAXDevice> Devices = new List<IMAXDevice>();
+ foreach(Room _room in Rooms)
+ {
+ foreach(IMAXDevice _Device in _room.Devices)
+ {
+ Devices.Add(_Device);
+ }
+ }
+
+ return Devices;
+ }
+
+ public Dictionary<String,IMAXDevice> GetAllDevicesInADictionary()
+ {
+ Dictionary<String,IMAXDevice> Devices = new Dictionary<string, IMAXDevice>();
+ foreach(Room _room in Rooms)
+ {
+ foreach(IMAXDevice _Device in _room.Devices)
+ {
+ Devices.Add(_Device.SerialNumber,_Device);
+ }
+ }
+
+ return Devices;
+ }
+ }
+}
+
View
40 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/Messages/Metadata/Room.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace xs1_data_logging
+{
+ public class Room
+ {
+ public String RoomName;
+ public Byte RoomID;
+ public String RFAddress;
+ public List<IMAXDevice> Devices;
+ public House AssociatedHouse;
+
+ public override string ToString ()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.AppendLine("RoomName: "+RoomName);
+ sb.AppendLine("RoomID: "+RoomID);
+ sb.AppendLine("RFAddress: "+RFAddress);
+ sb.AppendLine("Devices:");
+
+ foreach(IMAXDevice _device in Devices)
+ {
+ sb.Append(_device.ToString());
+ sb.AppendLine();
+ }
+
+ return sb.ToString();
+ }
+
+ public Room (House _House)
+ {
+ AssociatedHouse = _House;
+ Devices = new List<IMAXDevice>();
+ }
+ }
+}
+
View
47 Code/xs1-data-logging/ELVMAX/ELVMAX_Data/TokenizeMessage.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+
+namespace xs1_data_logging
+{
+ public static class TokenizeMessage
+ {
+ #region TokenizeLMessage
+ /// this method extracts all the tokens out of one L message. This is a
+ /// fairly simple process: get the first byte, out of that we get the number
+ /// of bytes that belong to that token, read those bytes. If there are bytes
+ /// left in the L message do it all over again.
+ /// Example:
+ ///
+ /// 6 0 37 41 9 18 16 11 2 115 104 71 18 24 100 42 0 0 0
+ ///
+ /// Tokenized:
+ ///
+ /// Token 1 (Length 6): 0 37 41 9 18 16
+ /// Token 2 (Length 11): 2 115 104 71 18 24 100 42 0 0 0
+ public static List<byte[]> Tokenize(byte[] DecodedRAWMessage)
+ {
+ Int32 Cursor = 0; // this is the cursor that wanders through the message
+ List<byte[]> ReturnValues = new List<byte[]>();
+
+ while(Cursor != DecodedRAWMessage.Length)
+ {
+ // get first byte
+ Byte NumberOfBytes = DecodedRAWMessage[Cursor];
+ Cursor++;
+ byte[] Token = new byte[NumberOfBytes];
+
+ // now read exactly NumberOfBytes from DecodedRAWMessage
+ for(Byte i=0;i<=NumberOfBytes-1;i++)
+ {
+ Token[i] = DecodedRAWMessage[Cursor];
+ Cursor++;
+ }
+ ReturnValues.Add(Token);
+ }
+
+ return ReturnValues;
+ }
+ #endregion
+ }
+}
+
View
34 Code/xs1-data-logging/ELVMAX/MAXEncodeDecode.cs
@@ -0,0 +1,34 @@
+using System;
+
+namespace xs1_data_logging
+{
+ /// <summary>
+ /// this encodes/decodes messages from/to the ELV MAX! Cube. It's just base64.
+ /// </summary>
+ public class MAXEncodeDecode
+ {
+ public IMAXMessage ProcessMessage(String Message, House _House)
+ {
+ if (Message.Length < 2)
+ throw new MAXException("Unable to process message: "+Message);
+
+ // check what type of message we got and return the processed values
+
+ if (Message.StartsWith("M:"))
+ return new M_Message(Message, _House);
+
+ if (Message.StartsWith("H:"))
+ return new H_Message(Message, _House);
+
+ if (Message.StartsWith("C:"))
+ return new C_Message(Message, _House);
+
+ if (Message.StartsWith("L:"))
+ return new L_Message(Message, _House);
+
+ //throw new NotImplementedException();
+ return null;
+ }
+ }
+}
+
View
145 Code/xs1-data-logging/ELVMAX/MAXMonitoringThread.cs
@@ -0,0 +1,145 @@
+using System;
+using System.Net.Sockets; // TCP-streaming
+using System.Threading; // the sleeping part...
+using System.Text;
+using System.Collections.Generic;
+
+namespace xs1_data_logging
+{
+ public class MAXMonitoringThread
+ {
+ private String Hostname;
+ private Int32 Port;
+ public House theHouse;
+ private Dictionary<String,IMAXDevice> previousHouse;
+ private static bool keepRunning = true;
+ public bool running = true;
+ private Int32 MAXUpdateTime;
+
+ public MAXMonitoringThread(String _Hostname, Int32 _Port, Int32 UpdateTime = 10000)
+ {
+ Hostname = _Hostname;
+ Port = _Port;
+ MAXUpdateTime = UpdateTime;
+ }
+
+ // this is the ELV MAX! Cube monitoring script
+ public void Run()
+ {
+ while(running)
+ {
+ #region Update House
+ try
+ {
+ if (theHouse != null)
+ {
+ previousHouse = theHouse.GetAllDevicesInADictionary();
+ }
+
+ theHouse = new House();
+
+ // we obviously have enough paramteres, go on and try to connect
+ TcpClient client = new TcpClient();
+ client.Connect(Hostname,Port);
+ NetworkStream stream = client.GetStream();
+
+ // the read buffer (chosen quite big)
+ byte[] myReadBuffer = new byte[4096*8];
+ List<String> Messages = new List<string>();
+
+ // to build the complete message
+ StringBuilder myCompleteMessage = new StringBuilder();
+ int numberOfBytesRead = 0;
+
+ MAXEncodeDecode DecoderEncoder = new MAXEncodeDecode();
+ keepRunning = true;
+ // Incoming message may be larger than the buffer size.
+ do
+ {
+ myCompleteMessage = new StringBuilder();
+ stream.ReadTimeout = 1000;
+ try
+ {
+ numberOfBytesRead = stream.Read(myReadBuffer, 0, myReadBuffer.Length);
+ myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));
+
+ Messages.Add(myCompleteMessage.ToString());
+ }
+ catch(Exception)
+ {
+ keepRunning = false;
+ }
+ }
+ while(keepRunning);
+
+ List<String> PreProcessedMessages = new List<string>();
+ // preprocess
+ foreach(String _Message in Messages)
+ {
+ if (_Message.Remove(_Message.Length-2).Contains("\r\n"))
+ {
+ String[] PMessages = _Message.Remove(_Message.Length-2).Split(new char[1] { '\n' },StringSplitOptions.RemoveEmptyEntries);
+ foreach(String pmessage in PMessages)
+ {
+ PreProcessedMessages.Add(pmessage.Replace("\r","")+"\r\n");
+ }
+ }
+ else
+ PreProcessedMessages.Add(_Message);
+ }
+ // Analyze and Output Messages
+ foreach(String _Message in PreProcessedMessages)
+ {
+ IMAXMessage Message = DecoderEncoder.ProcessMessage(_Message.ToString(), theHouse);
+ /* if (Message != null)
+ {
+ ConsoleOutputLogger.WriteLine(_Message.ToString());
+ ConsoleOutputLogger.WriteLine(Message.ToString());
+ ConsoleOutputLogger.WriteLine("");
+ }*/
+ }
+ stream.Close();
+ client.Close();
+ }
+ catch(Exception)
+ {
+ }
+ #endregion
+
+ #region Diff the house
+ if (previousHouse != null)
+ {
+ // only if we already got two houses in here...
+ List<IDeviceDiffSet> differences = DiffHouse.CalculateDifferences(previousHouse,theHouse.GetAllDevicesInADictionary());
+ if (differences.Count != 0)
+ {
+ foreach(IDeviceDiffSet _difference in differences)
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.Append("S\t"+_difference.DeviceName+"\t"+_difference.DeviceType);
+
+ if (_difference.DeviceType == DeviceTypes.HeatingThermostat)
+ {
+ HeatingThermostatDiff _heating = (HeatingThermostatDiff)_difference;
+
+ ConsoleOutputLogger.WriteLine(_heating.ToString());
+ }
+
+ if (_difference.DeviceType == DeviceTypes.ShutterContact)
+ {
+ ShutterContactDiff _shutter = (ShutterContactDiff)_difference;
+
+ ConsoleOutputLogger.WriteLine(_shutter.ToString());
+ }
+ }
+ }
+ }
+ #endregion
+ Thread.Sleep (MAXUpdateTime);
+ }
+ }
+
+ }
+}
+
View
38 Code/xs1-data-logging/ELVMAX/Max_Threaded.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Threading;
+
+namespace xs1_data_logging
+{
+ class MainClass
+ {
+// public static void Main (string[] args)
+// {
+// ConsoleOutputLogger.verbose = true;
+// ConsoleOutputLogger.writeLogfile = true;
+//
+// Console.WriteLine ("ELV MAX! Debug Tool version 1 (C) Daniel Kirstenpfad 2012");
+// Console.WriteLine();
+//
+// // not enough paramteres given, display help
+// if (args.Length < 2)
+// {
+// Console.WriteLine("Syntax:");
+// Console.WriteLine();
+// Console.WriteLine("\tmaxdebug <hostname/ip> <port (e.g. 62910)> [commands]");
+// Console.WriteLine();
+// return;
+// }
+// ConsoleOutputLogger.LogToFile("--------------------------------------");
+//
+// MAXMonitoringThread _Thread = new MAXMonitoringThread(args[0], Convert.ToInt32 (args[1]),5000);
+// Thread MAXMonitoring = new Thread(new ThreadStart(_Thread.Run));
+//
+// MAXMonitoring.Start();
+//
+// while(_Thread.running)
+// {
+// Thread.Sleep(100);
+// }
+// }
+ }
+}
View
6 Code/xs1-data-logging/LoggingThread.cs
@@ -65,9 +65,9 @@ public void Run()
// Start the ELVMax Thread
// Todo: Add configurability of this startup
- MaxThread ELVMax = new MaxThread(ConsoleOutputLogger);
- Thread ELVMaxThread = new Thread(new ThreadStart(ELVMax.Run));
- ELVMaxThread.Start();
+ //MaxThread ELVMax = new MaxThread(ConsoleOutputLogger);
+ //Thread ELVMaxThread = new Thread(new ThreadStart(ELVMax.Run));
+ //ELVMaxThread.Start();
while (!Shutdown)
{
View
26 Code/xs1-data-logging/Max/MAXEncodeDecode.cs
@@ -1,26 +0,0 @@
-using System;
-
-namespace xs1_data_logging
-{
- /// <summary>
- /// this encodes/decodes messages from/to the ELV MAX! Cube. It's just base64.
- /// </summary>
- public static class MAXEncodeDecode
- {
- static public string Encode(string toEncode)
- {
- byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
- string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
- return returnValue;
- }
-
- static public string Decode(string encodedData)
- {
- byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);
- string returnValue = System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes);
- return returnValue;
- }
-
- }
-}
-
View
55 Code/xs1-data-logging/Max/MaxThread.cs
@@ -1,55 +0,0 @@
-/*
- * This is the thread that handles the connection to (at least one) ELV MAX! Cube base controller for ELV Max! home automation
- * hardware.
- *
- * more information here: http://www.elv.de/max-funk-heizungsregler-system.html
- *
- * At the moment this is a whitespace file which will hold the implementation of the MAX! Cube interface in the future - at
- * least when I got my sample :-) *
- *
- * */
-
-using System;
-using System.Collections.Generic;
-using System.Threading;
-
-namespace xs1_data_logging
-{
- public class MaxThread
- {
- private bool _Shutdown = false;
- private ConsoleOutputLogger ConsoleOutputLogger;
-
- public MaxThread (ConsoleOutputLogger Logger)
- {
- ConsoleOutputLogger = Logger;
- }
-
- public void Shutdown()
- {
- _Shutdown = true;
- }
-
- /// <summary>
- /// Run this instance.
- /// </summary>
- public void Run()
- {
- ConsoleOutputLogger.WriteLine("Starting MAX! handling thread.");
- TimeSpan temp = new TimeSpan();
- while (!_Shutdown)
- {
- try
- {
- // do something
- }
- catch(Exception)
- {
- }
-
- Thread.Sleep(1000); // just check every 1 seconds...
- }
- }
- }
-}
-
View
32 Code/xs1-data-logging/xs1-data-logging.csproj
@@ -73,10 +73,37 @@
<Compile Include="ActorStatusOutputTypes.cs" />
<Compile Include="SensorCheck.cs" />
<Compile Include="JSONHandlers\DataCache.cs" />
- <Compile Include="Max\MaxThread.cs" />
<Compile Include="HTTPProxy\HTTPProxy.cs" />
<Compile Include="HTTPProxy\HTTPProxyConfiguration.cs" />
- <Compile Include="Max\MAXEncodeDecode.cs" />
+ <Compile Include="ELVMAX\MAXEncodeDecode.cs" />
+ <Compile Include="ELVMAX\MAXMonitoringThread.cs" />
+ <Compile Include="ELVMAX\Max_Threaded.cs" />
+ <Compile Include="ELVMAX\DiffSet\BatteryStatus.cs" />
+ <Compile Include="ELVMAX\DiffSet\DeviceDiffSet.cs" />
+ <Compile Include="ELVMAX\DiffSet\DiffHouse.cs" />
+ <Compile Include="ELVMAX\DiffSet\HeatingThermostatDiff.cs" />
+ <Compile Include="ELVMAX\DiffSet\ShutterContactDiff.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\Base64.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\MAXMessageTypes.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\MAX_Exception.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\TokenizeMessage.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\Messages\C_Message.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\Messages\H_Message.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\Messages\IMAXMessage.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\Messages\L_Message.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\Messages\M_Message.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\Messages\Devices\HeatingThermostat.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\Messages\Devices\HeatingThermostatPlus.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\Messages\Devices\IMAXDevice.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\Messages\Devices\PushButton.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\Messages\Devices\ShutterContact.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\Messages\Devices\ShutterContactModes.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\Messages\Devices\ThermostatModes.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\Messages\Devices\UnknownDevice.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\Messages\Devices\WallMountedThermostat.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\Messages\Metadata\DeviceTypes.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\Messages\Metadata\House.cs" />
+ <Compile Include="ELVMAX\ELVMAX_Data\Messages\Metadata\Room.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
@@ -141,5 +168,6 @@
<ItemGroup>
<Folder Include="Max\" />
<Folder Include="HTTPProxy\" />
+ <Folder Include="ELVMAX\" />
</ItemGroup>
</Project>
Please sign in to comment.
Something went wrong with that request. Please try again.