Skip to content
18 changes: 18 additions & 0 deletions ThinkingHome.NooLite.Console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ static void Main(string[] args)
app.Command("ports", PortsCommand);

app.Command("bind", BindCommand);
app.Command("bindstart", BindStartCommand);
app.Command("bindstop", BindStopCommand);
app.Command("unbind", UnbindCommand);
app.Command("on", OnCommand);
app.Command("off", OffCommand);
Expand Down Expand Up @@ -109,6 +111,22 @@ private static void BindCommand(CommandLineApplication cmd)
cmd.OnExecute(() => Invoke(args, (a, c) => a.Bind(c), (a, c) => a.BindF(c)));
}

private static void BindStartCommand(CommandLineApplication cmd)
{
var args = AddCommonArgs(cmd);

cmd.Description = "Start binding the specified adapter channel to the nooLite sensor.";
cmd.OnExecute(() => Invoke(args, (a, c) => a.BindStart(c), (a, c) => a.BindStart(c)));
}

private static void BindStopCommand(CommandLineApplication cmd)
{
var args = AddCommonArgs(cmd);

cmd.Description = "Stop binding the specified adapter channel from the nooLite sensor.";
cmd.OnExecute(() => Invoke(args, (a, c) => a.BindStop(), (a, c) => a.BindStop()));
}

private static void UnbindCommand(CommandLineApplication cmd)
{
var args = AddCommonArgs(cmd);
Expand Down
12 changes: 12 additions & 0 deletions ThinkingHome.NooLite.Tests/F/CommandTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Xunit;

namespace ThinkingHome.NooLite.Tests.MicroclimateData
{
using H = TestHelpers;

public class CommandTest
{


}
}
96 changes: 96 additions & 0 deletions ThinkingHome.NooLite.Tests/SendData/ParseTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using System;
using ThinkingHome.NooLite.Internal;
using Xunit;

namespace ThinkingHome.NooLite.Tests.SendData
{
using H = TestHelpers;

public class ParseTests
{
[Fact]
public void Parse_Mode_IsCorrect()
{
const byte RXF_CODE = 3;
byte[] bytes = H.GetBytes().Set(1, RXF_CODE);

var data = new NooLite.ReceivedData(bytes);

Assert.Equal(MTRFXXMode.RXF, data.Mode);
}

[Fact]
public void Parse_ResultCode_IsCorrect()
{
const byte NO_RESPONSE_CODE = 1;
byte[] bytes = H.GetBytes().Set(2, NO_RESPONSE_CODE);

var data = new NooLite.ReceivedData(bytes);

Assert.Equal(ResultCode.NoResponse, data.Result);
}

[Fact]
public void Parse_Remains_IsCorrect()
{
const byte REMAINS_TEST_VALUE = 133;
byte[] bytes = H.GetBytes().Set(3, REMAINS_TEST_VALUE);

var data = new NooLite.ReceivedData(bytes);

Assert.Equal(REMAINS_TEST_VALUE, data.Remains);
}

[Fact]
public void Parse_Channel_IsCorrect()
{
const byte CHANNEL_TEST_VALUE = 8;
byte[] bytes = H.GetBytes().Set(4, CHANNEL_TEST_VALUE);

var data = new NooLite.ReceivedData(bytes);

Assert.Equal(CHANNEL_TEST_VALUE, data.Channel);
}

[Fact]
public void Parse_Command_IsCorrect()
{
const byte COMMAND_SEND_STATE_CODE = 130;
byte[] bytes = H.GetBytes().Set(5, COMMAND_SEND_STATE_CODE);

var data = new NooLite.ReceivedData(bytes);

Assert.Equal(MTRFXXCommand.SendState, data.Command);
}

[Fact]
public void Parse_Data_IsCorrect()
{
const byte FMT_TEST_VALUE = 2;
byte[] TEST_DATA = {22, 33, 44, 55};

byte[] bytes = H.GetBytes()
.Set(6, FMT_TEST_VALUE)
.Set(7, TEST_DATA);

var data = new NooLite.ReceivedData(bytes);

Assert.Equal(FMT_TEST_VALUE, data.DataFormat);
Assert.Equal(22, data.Data1);
Assert.Equal(33, data.Data2);
Assert.Equal(44, data.Data3);
Assert.Equal(55, data.Data4);
}

[Fact]
public void Parse_DeviceId_IsCorrect()
{
byte[] bytesOfId = {0, 21, 5, 13};
byte[] bytes = H.GetBytes().Set(11, bytesOfId);

var data = new NooLite.ReceivedData(bytes);

Assert.Equal((UInt32) 1377549, data.DeviceId);
}
}
}
54 changes: 54 additions & 0 deletions ThinkingHome.NooLite.Tests/SendData/ValidationTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System;
using Xunit;

namespace ThinkingHome.NooLite.Tests.ReceivedData
{
public class ValidationTests
{
public const int VALID_DATA_SIZE = 17;

[Fact]
public void Constructor_ForNull_ThrowsException()
{
byte[] nullReceivedData = null;

Exception ex = Assert.ThrowsAny<Exception>(() => new NooLite.ReceivedData(nullReceivedData));

Assert.Contains("null", ex.Message);
}

[Fact]
public void Constructor_ForInvalidDataSize_ThrowsException()
{
byte[] invalidSizeData = new byte[3];

Exception ex = Assert.ThrowsAny<Exception>(() => new NooLite.ReceivedData(invalidSizeData));

Assert.Contains("length", ex.Message);
}


[Fact]
public void Constructor_ForInvalidFirstByte_ThrowsException()
{
byte[] testData = new byte[VALID_DATA_SIZE];
testData[0] = 124;

Exception ex = Assert.ThrowsAny<Exception>(() => new NooLite.ReceivedData(testData));

Assert.Contains("start", ex.Message);
}

[Fact]
public void Constructor_ForInvalidLastByte_ThrowsException()
{
byte[] testData = new byte[VALID_DATA_SIZE];
testData[0] = 173; // valid start marker
testData[VALID_DATA_SIZE - 1] = 124;

Exception ex = Assert.ThrowsAny<Exception>(() => new NooLite.ReceivedData(testData));

Assert.Contains("stop", ex.Message);
}
}
}
15 changes: 15 additions & 0 deletions ThinkingHome.NooLite/Internal/MTRFXXAction.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
namespace ThinkingHome.NooLite.Internal
{
/*
Бит 5…0 – Команда адаптеру(0…63)
Значение=0 – Передать команду
Значение=1 – Передать широковещательную команду
(одновременно всем устройствам на канале CH)
Значение=2 – Считать ответ(состояние приѐмного буфера)
Значение=3 – Включить привязку
Значение=4 – Выключить привязку
Значение=5 – Очистить ячейку(канал)
Значение=6 – Очистить память(все каналы)
Значение=7 – Отвязать адрес от канала
Значение=8 – Передать команду по указанному адресу
nooLite-F
Бит 6…7 – Nrep, количество дополнительных повторовкоманды(0...3). Количество передач команд = 2+Nrep
*/
public enum MTRFXXAction : byte
{
SendCommand = 0,
Expand Down
21 changes: 21 additions & 0 deletions ThinkingHome.NooLite/MTRFXXAdapterExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,21 @@ private static void SendData(MTRFXXAdapter adapter, MTRFXXCommand command, bool
}



#endregion

#region read state

public static void ReadState(this MTRFXXAdapter adapter, byte channel)
{
throw new NotSupportedException("Not supported in basic mode.");
}

public static void ReadStateF(this MTRFXXAdapter adapter, byte channel, UInt32? deviceId = null)
{
SendReadState(adapter, channel);
}

#endregion

#region brightness
Expand Down Expand Up @@ -262,6 +277,11 @@ public static void UnbindF(this MTRFXXAdapter adapter, byte channel)

#region RX mode

private static void SendReadState(this MTRFXXAdapter adapter, byte channel)
{
adapter.SendCommand(MTRFXXMode.TXF, MTRFXXAction.SendCommand, channel, MTRFXXCommand.ReadState);
}

public static void BindStart(this MTRFXXAdapter adapter, byte channel)
{
adapter.SendCommand(MTRFXXMode.RX, MTRFXXAction.StartBinding, channel, MTRFXXCommand.None);
Expand All @@ -288,6 +308,7 @@ public static void ExitServiceMode(this MTRFXXAdapter adapter)
adapter.SendCommand(MTRFXXMode.Service, MTRFXXAction.SendCommand, 0, MTRFXXCommand.None);
}


#endregion
}
}
2 changes: 2 additions & 0 deletions ThinkingHome.NooLite/ReceivedData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ namespace ThinkingHome.NooLite
{
public class ReceivedData
{
//https://www.noo.by/wiki/index.php?title=API_%D1%88%D0%BB%D1%8E%D0%B7%D0%B0/%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B5%D1%80%D0%B0_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_nooLite(-F)&mobileaction=toggle_view_mobile

#region static

public const byte START_MARKER = 173;
Expand Down