Это программа для контроллера:
namespace mdv
{
using System.IO.Ports;
using Timer = System.Timers.Timer;
using System.Text.Json;
using System.Net;
using uPLibrary.Networking.M2Mqtt.Messages;
using uPLibrary.Networking.M2Mqtt;
using System.Text;
using static System.Text.Encoding;
using System.Collections.Generic;
using System;
using System.Linq;
internal class Program
{
private static readonly Timer TimerWrite = new();
private static readonly Timer TimerNoData = new();
private static SerialPort port;
static int[] enter;
static int IDfan = 0;
static string[] Topics;
static Byte[] QOSMQTT;
static readonly Dictionary<int, Byte[]> FansGet = new();
static readonly Dictionary<int, Byte[]> FansSet = new();
static readonly Queue<int> SetNum = new(16);
static Byte[] indata;
static readonly MqttClient client = new(IPAddress.Parse("127.0.0.1")); // 127.0.0.1 192.168.42.1
static void Main(string[] args)
{
enter = JsonSerializer.Deserialize<int[]>(args[0]);
Topics = new string[enter.Length * 10];
QOSMQTT = new Byte[enter.Length * 10];
for (int i = 0; i < enter.Length; i++)
{
FansGet[enter[i]] = new Byte[16] { 170, 192, (Byte)enter[i], 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 63, (Byte)(129 - enter[i]), 85 };
FansSet[enter[i]] = new Byte[16] { 170, 195, (Byte)enter[i], 0, 128, 0, 8, 128, 21, 0, 0, 0, 0, 60, 0, 85 };
Topics[0 + i * 10] = $"/devices/Fan_{enter[i]}/controls/Power/on";
Topics[1 + i * 10] = $"/devices/Fan_{enter[i]}/controls/Mode/on";
Topics[2 + i * 10] = $"/devices/Fan_{enter[i]}/controls/Speed/on";
Topics[3 + i * 10] = $"/devices/Fan_{enter[i]}/controls/SetTemp/on";
Topics[4 + i * 10] = $"/devices/Fan_{enter[i]}/controls/Blinds/on";
Topics[5 + i * 10] = $"/devices/Fan_{enter[i]}/controls/Power";
Topics[6 + i * 10] = $"/devices/Fan_{enter[i]}/controls/Mode";
Topics[7 + i * 10] = $"/devices/Fan_{enter[i]}/controls/Speed";
Topics[8 + i * 10] = $"/devices/Fan_{enter[i]}/controls/SetTemp";
Topics[9 + i * 10] = $"/devices/Fan_{enter[i]}/controls/Blinds";
}
client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;
string clientId = Guid.NewGuid().ToString();
client.Connect(clientId);
client.Subscribe(Topics, QOSMQTT);
//string strValue = Convert.ToString(44); client.Unsubscribe(new string[]);
static void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
{
//Console.WriteLine($"{e.Topic}, - {Default.GetString(e.Message)}");
if (e.Topic.Split('/').Length == 6)
{
if (e.Topic.Split('/')[4] == "Power") // Включить выключить
{
if (Default.GetString(e.Message) == "1")
{
if (FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] < 128)
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] += 128;
}
}
else if (Default.GetString(e.Message) == "0")
{
if (FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] > 127)
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] -= 128;
}
}
}
else if (e.Topic.Split('/')[4] == "Mode") // Режим работы 0 - холод, 1 - тепло, 2 - вент, 3 - сушка, 4 - авто
{
if (Default.GetString(e.Message) == "0") // Режим охлаждение
{
if (FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] > 127)
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 136;
}
else
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 8;
}
}
else if (Default.GetString(e.Message) == "1") // Режим Обогрев
{
if (FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] > 127)
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 132;
}
else
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 4;
}
}
else if (Default.GetString(e.Message) == "2") // Режим Осушение
{
if (FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] > 127)
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 130;
}
else
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 2;
}
}
else if (Default.GetString(e.Message) == "3") // Режим вентилятора
{
if (FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] > 127)
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 129;
}
else
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 1;
}
}
else if (Default.GetString(e.Message) == "4") // Режим Авто
{
if (FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] > 127)
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 144;
}
else
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 16;
}
}
}
else if (e.Topic.Split('/')[4] == "Speed") // Скорость вентилятора 1, 2, 3, 4 - авто
{
if (Default.GetString(e.Message) == "1")
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][7] = 4;
}
else if (Default.GetString(e.Message) == "2")
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][7] = 2;
}
else if (Default.GetString(e.Message) == "3")
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][7] = 1;
}
else if (Default.GetString(e.Message) == "4")
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][7] = 128;
}
}
else if (e.Topic.Split('/')[4] == "Blinds") // Поворот жалюзи
{
if (Default.GetString(e.Message) == "1")
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][9] = 4;
}
else if (Default.GetString(e.Message) == "0")
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][9] = 0;
}
}
else if (e.Topic.Split('/')[4] == "SetTemp") // Уставка температуры 16-32
{
if (int.Parse(Default.GetString(e.Message)) > 15 & int.Parse(Default.GetString(e.Message)) < 32)
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][8] = Byte.Parse(Default.GetString(e.Message));
}
}
if (!SetNum.Contains(int.Parse(e.Topic.Split('/')[2].Split('_').Last()))) // Добавить в очередь
{
SetNum.Enqueue(int.Parse(e.Topic.Split('/')[2].Split('_').Last()));
}
}
else if (e.Topic.Split('/').Length == 5)
{
if (e.Topic.Split('/')[4] == "Power") // Включить выключить
{
if (Default.GetString(e.Message) == "1")
{
if (FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] < 128)
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] += 128;
}
}
else if (Default.GetString(e.Message) == "0")
{
if (FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] > 127)
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] -= 128;
}
}
}
else if (e.Topic.Split('/')[4] == "Mode") // Режим работы 0 - холод, 1 - тепло, 2 - вент, 3 - сушка, 4 - авто
{
if (Default.GetString(e.Message) == "0") // Режим охлаждение
{
if (FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] > 127)
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 136;
}
else
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 8;
}
}
else if (Default.GetString(e.Message) == "1") // Режим Обогрев
{
if (FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] > 127)
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 132;
}
else
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 4;
}
}
else if (Default.GetString(e.Message) == "2") // Режим Осушение
{
if (FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] > 127)
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 130;
}
else
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 2;
}
}
else if (Default.GetString(e.Message) == "3") // Режим вентилятора
{
if (FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] > 127)
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 129;
}
else
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 1;
}
}
else if (Default.GetString(e.Message) == "4") // Режим Авто
{
if (FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] > 127)
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 144;
}
else
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][6] = 16;
}
}
}
else if (e.Topic.Split('/')[4] == "Speed") // Скорость вентилятора 1, 2, 3, 4 - авто
{
if (Default.GetString(e.Message) == "1")
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][7] = 4;
}
else if (Default.GetString(e.Message) == "2")
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][7] = 2;
}
else if (Default.GetString(e.Message) == "3")
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][7] = 1;
}
else if (Default.GetString(e.Message) == "4")
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][7] = 128;
}
}
else if (e.Topic.Split('/')[4] == "Blinds") // Поворот жалюзи
{
if (Default.GetString(e.Message) == "1")
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][9] = 4;
}
else if (Default.GetString(e.Message) == "0")
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][9] = 0;
}
}
else if (e.Topic.Split('/')[4] == "SetTemp") // Уставка температуры 16-32
{
if (int.Parse(Default.GetString(e.Message)) > 15 & int.Parse(Default.GetString(e.Message)) < 32)
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][8] = Byte.Parse(Default.GetString(e.Message));
}
else if (Default.GetString(e.Message) == "0")
{
FansSet[int.Parse(e.Topic.Split('/')[2].Split('_').Last())][9] = 0;
}
}
client.Unsubscribe(new string[] { e.Topic });
}
}
port = new SerialPort
{
PortName = args[1],
BaudRate = 4800,
DataBits = 8,
Parity = System.IO.Ports.Parity.None,
StopBits = System.IO.Ports.StopBits.One,
ReadTimeout = 100,
WriteTimeout = 30,
ReadBufferSize = 32,
WriteBufferSize = 16
};
port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler2);
port.ErrorReceived += new SerialErrorReceivedEventHandler(Eror);
port.PinChanged += new SerialPinChangedEventHandler(Stopp);
try
{
port.Open();
client.Publish($"/devices/sist/controls/Serial", Encoding.UTF8.GetBytes("Порт открыт"), 0, false);
}
catch (Exception e)
{
//Console.WriteLine("ERROR: невозможно открыть порт:" + e.ToString());
client.Publish($"/devices/sist/controls/Serial", Encoding.UTF8.GetBytes("Невозможно открыть порт"), 0, false);
return;
}
TimerNoData.Interval = 200;
TimerNoData.Elapsed += NoConect;
TimerNoData.Elapsed += Writers;
TimerNoData.AutoReset = false;
TimerNoData.Enabled = false;
TimerWrite.Interval = 140;
TimerWrite.Elapsed += Writers;
TimerWrite.AutoReset = false;
TimerWrite.Enabled = true;
Console.ReadLine();
}
static void Eror(
object sender,
SerialErrorReceivedEventArgs e)
{
//Console.Write($"[eror]");
client.Publish($"/devices/sist/controls/Error", Encoding.UTF8.GetBytes($"Ошибка - {e.ToString}"), 0, false);
}
static void Stopp(
object sender,
SerialPinChangedEventArgs e)
{
//Console.Write($"[stopp]");
client.Publish($"/devices/sist/controls/Error", Encoding.UTF8.GetBytes("Неизвестное событие"), 0, false);
}
static bool keyRepeat = false;
static bool keySet = false;
static int RepeatCounter = 0;
static int t = 0;
static int s = 0;
static int n = 0;
static void Writers(Object? source, System.Timers.ElapsedEventArgs? e) // отправка данных
{
TimerNoData.Enabled = true;
if (keyRepeat & RepeatCounter < 2)
{
s = 0;
for (int i = 0; i < 14; i++)
{
s += FansSet[n][i];
}
s += 85;
FansSet[n][14] = (Byte)(255 - s % 256);
port.Write(FansSet[n], 0, 16);
//Console.WriteLine($"Повторная уставка {FansSet[n][2]}");
RepeatCounter += 1;
}
else if (SetNum.Count > 0)
{
if (RepeatCounter > 0)
{
RepeatCounter = 0;
}
if (!keySet)
{
keySet = true;
}
s = 85;
n = SetNum.Dequeue();
for (int i = 0; i < 14; i++)
{
s += FansSet[n][i];
}
FansSet[n][14] = (Byte)(255 - s % 256);
port.Write(FansSet[n], 0, 16);
//Console.WriteLine($"Уставка {FansSet[n][2]}, вент - {FansSet[n][7]}");
}
else
{
if (keySet)
{
keySet = false;
}
port.Write(FansGet[enter[t]], 0, 16);
//Console.WriteLine($"Отправка запроса {FansGet[enter[t]][2]}");
IDfan = enter[t];
client.Publish($"/devices/sist/controls/GanGetID", Encoding.UTF8.GetBytes($"{IDfan}"), 0, false);
if (enter.Length != 1)
{
if (t < enter.Length - 1)
{
t += 1;
}
else
{
t = 0;
}
}
}
}
static void NoConect(Object? source, System.Timers.ElapsedEventArgs? e) // нет связи
{
//Console.WriteLine("Нет ответа");
if (keySet)
{
keyRepeat = true;
}
else
{
client.Publish($"/devices/Fan_{IDfan}/controls/Alarm", Encoding.UTF8.GetBytes("2"), 0, false);
}
}
/// //////////////////////////////////////////////////////////////////////////////////////////////////
static int s2 = 0;
static void DataReceivedHandler2(
object sender,
SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
if (sp.BytesToRead > 30)
{
TimerNoData.Enabled = false;
if (TimerWrite.Enabled == false)
{
TimerWrite.Enabled = true;
}
indata = new Byte[32];
sp.Read(indata, 0, 32);
s2 = 85;
if (indata[0] == 254)
{
indata = indata.Skip(1).ToArray();
}
for (int i = 0; i < indata.Length - 2; i++)
{
s2 += indata[i];
//Console.WriteLine($"[{indata[i]}]");
}
if ((int)indata[30] == 255 - s2 % 256)
{
//Console.WriteLine($"ОК {indata[4]}");
DataPars(indata);
}
else
{
if (keySet)
{
keyRepeat = true;
}
client.Publish($"/devices/sist/controls/Error", Encoding.UTF8.GetBytes("Ошибка данных"), 0, false);
//Console.WriteLine("Не ОК");
}
sp.DiscardInBuffer();
}
else
{
sp.DiscardInBuffer();
}
}
static void DataPars(Byte[] data)
{
client.Publish($"/devices/Fan_{data[4]}/controls/Power", Encoding.UTF8.GetBytes($"{(data[8] & 128) >> 7}"), 0, false);
if ((data[8] & 16) == 16) // Режим авто
{
client.Publish($"/devices/Fan_{data[4]}/controls/Mode", Encoding.UTF8.GetBytes("4"), 0, false);
}
else if ((data[8] & 8) == 8) // Режим охлаждения
{
client.Publish($"/devices/Fan_{data[4]}/controls/Mode", Encoding.UTF8.GetBytes("0"), 0, false);
}
else if ((data[8] & 4) == 4) // Режим обогрева
{
client.Publish($"/devices/Fan_{data[4]}/controls/Mode", Encoding.UTF8.GetBytes("1"), 0, false);
}
else if ((data[8] & 2) == 2) // Режим осушения
{
client.Publish($"/devices/Fan_{data[4]}/controls/Mode", Encoding.UTF8.GetBytes("2"), 0, false);
}
else if ((data[8] & 1) == 1) // Режим вентилятора
{
client.Publish($"/devices/Fan_{data[4]}/controls/Mode", Encoding.UTF8.GetBytes("3"), 0, false);
}
if ((data[9] & 128) == 128) // Скорость 0 авто
{
client.Publish($"/devices/Fan_{data[4]}/controls/SpeedST", Encoding.UTF8.GetBytes("4"), 0, false);
}
else if ((data[9] & 4) == 4) // Скорость 1
{
client.Publish($"/devices/Fan_{data[4]}/controls/SpeedST", Encoding.UTF8.GetBytes("1"), 0, false);
}
else if ((data[9] & 2) == 2) // Скорость 2
{
client.Publish($"/devices/Fan_{data[4]}/controls/SpeedST", Encoding.UTF8.GetBytes("2"), 0, false);
}
else if ((data[9] & 1) == 1) // Скорость 3
{
client.Publish($"/devices/Fan_{data[4]}/controls/SpeedST", Encoding.UTF8.GetBytes("3"), 0, false);
}
else if (data[9] == 0) // Скорость 0
{
client.Publish($"/devices/Fan_{data[4]}/controls/SpeedST", Encoding.UTF8.GetBytes("0"), 0, false);
}
client.Publish($"/devices/Fan_{data[4]}/controls/SetTemp", Encoding.UTF8.GetBytes($"{data[10]}"), 0, false);
client.Publish($"/devices/Fan_{data[4]}/controls/Temp", Encoding.UTF8.GetBytes($"{(data[11] / 2) - 20}"), 0, false);
if ((data[8] & 4) == 4) // Жалюзи включены
{
client.Publish($"/devices/Fan_{data[4]}/controls/Blinds", Encoding.UTF8.GetBytes("1"), 0, false);
}
else if ((data[8] & 4) == 0) // Жалюзи выключены
{
client.Publish($"/devices/Fan_{data[4]}/controls/Blinds", Encoding.UTF8.GetBytes("0"), 0, false);
}
if (data[22] == 0 & data[23] == 0)
{
client.Publish($"/devices/Fan_{data[4]}/controls/Alarm", Encoding.UTF8.GetBytes("0"), 0, false);
client.Publish($"/devices/Fan_{data[4]}/controls/AlarmCode", Encoding.UTF8.GetBytes("0"), 0, false);
}
else
{
client.Publish($"/devices/Fan_{data[4]}/controls/Alarm", Encoding.UTF8.GetBytes("1"), 0, false);
if ((data[22] & 1) == 1)
{
client.Publish($"/devices/Fan_{data[4]}/controls/AlarmCode", Encoding.UTF8.GetBytes("1"), 0, false);
}
else if ((data[22] & 2) == 2)
{
client.Publish($"/devices/Fan_{data[4]}/controls/AlarmCode", Encoding.UTF8.GetBytes("2"), 0, false);
}
else if ((data[22] & 4) == 4)
{
client.Publish($"/devices/Fan_{data[4]}/controls/AlarmCode", Encoding.UTF8.GetBytes("3"), 0, false);
}
else if ((data[22] & 8) == 8)
{
client.Publish($"/devices/Fan_{data[4]}/controls/AlarmCode", Encoding.UTF8.GetBytes("4"), 0, false);
}
else if ((data[22] & 16) == 16)
{
client.Publish($"/devices/Fan_{data[4]}/controls/AlarmCode", Encoding.UTF8.GetBytes("5"), 0, false);
}
else if ((data[22] & 32) == 32)
{
client.Publish($"/devices/Fan_{data[4]}/controls/AlarmCode", Encoding.UTF8.GetBytes("6"), 0, false);
}
else if ((data[22] & 64) == 64)
{
client.Publish($"/devices/Fan_{data[4]}/controls/AlarmCode", Encoding.UTF8.GetBytes("7"), 0, false);
}
else if ((data[22] & 128) == 128)
{
client.Publish($"/devices/Fan_{data[4]}/controls/AlarmCode", Encoding.UTF8.GetBytes("8"), 0, false);
}
else if ((data[23] & 1) == 1)
{
client.Publish($"/devices/Fan_{data[4]}/controls/AlarmCode", Encoding.UTF8.GetBytes("9"), 0, false);
}
else if ((data[23] & 2) == 2)
{
client.Publish($"/devices/Fan_{data[4]}/controls/AlarmCode", Encoding.UTF8.GetBytes("10"), 0, false);
}
else if ((data[23] & 4) == 4)
{
client.Publish($"/devices/Fan_{data[4]}/controls/AlarmCode", Encoding.UTF8.GetBytes("11"), 0, false);
}
else if ((data[23] & 8) == 8)
{
client.Publish($"/devices/Fan_{data[4]}/controls/AlarmCode", Encoding.UTF8.GetBytes("12"), 0, false);
}
else if ((data[23] & 16) == 16)
{
client.Publish($"/devices/Fan_{data[4]}/controls/AlarmCode", Encoding.UTF8.GetBytes("13"), 0, false);
}
else if ((data[23] & 32) == 32)
{
client.Publish($"/devices/Fan_{data[4]}/controls/AlarmCode", Encoding.UTF8.GetBytes("14"), 0, false);
}
else if ((data[23] & 64) == 64)
{
client.Publish($"/devices/Fan_{data[4]}/controls/AlarmCode", Encoding.UTF8.GetBytes("15"), 0, false);
}
else if ((data[23] & 128) == 128)
{
client.Publish($"/devices/Fan_{data[4]}/controls/AlarmCode", Encoding.UTF8.GetBytes("16"), 0, false);
}
}
if (data[24] == 0 & data[25] == 0)
{
client.Publish($"/devices/Fan_{data[4]}/controls/Blok", Encoding.UTF8.GetBytes("0"), 0, false);
}
else
{
client.Publish($"/devices/Fan_{data[4]}/controls/Blok", Encoding.UTF8.GetBytes("1"), 0, false);
}
}
}
}