ajustado firmware MVD e unificado PZM com WIT

This commit is contained in:
Diego Freitas 2024-06-14 16:23:18 -03:00
parent 5b0acda9f1
commit 2e35fc7efc
147 changed files with 963 additions and 7531 deletions

42
.vscode/settings.json vendored
View File

@ -6,6 +6,46 @@
"list": "cpp",
"xstring": "cpp",
"xutility": "cpp",
"string": "cpp"
"string": "cpp",
"algorithm": "cpp",
"atomic": "cpp",
"bit": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"compare": "cpp",
"concepts": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"exception": "cpp",
"ios": "cpp",
"iosfwd": "cpp",
"istream": "cpp",
"iterator": "cpp",
"limits": "cpp",
"memory": "cpp",
"new": "cpp",
"ostream": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"typeinfo": "cpp",
"utility": "cpp",
"xfacet": "cpp",
"xiosbase": "cpp",
"xlocale": "cpp",
"xlocinfo": "cpp",
"xlocnum": "cpp",
"xmemory": "cpp",
"xstddef": "cpp",
"xtr1common": "cpp"
}
}

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -368,71 +368,6 @@
<Compile Include="Models\Modules\MovimentacaoUnificadoModel.cs" />
<Compile Include="Models\Modules\PinoutModel.cs" />
<Compile Include="Models\Modules\SensoriamentoModel.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Connector\Entity\SerialPortConfig.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Connector\Entity\TcpClientConfig.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Connector\Entity\TcpServerConfig.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Connector\Entity\UdpConfig.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Connector\Interface\ConnectConfig.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Connector\Interface\IConnector.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Connector\Interface\IReceiveListener.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Connector\Interface\SendDataInterface.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Connector\Modular\Tcp\TcpServer.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Connector\Modular\Tcp\TcpServerPool.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Connector\Modular\Tcp\TcpServerProxy.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Connector\Modular\Udp\UdpServer.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Connector\Modular\Udp\UdpServerPool.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Connector\Modular\Udp\UdpServerProxy.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Connector\Role\SPConnector.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Connector\Role\TcpClientConnector.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Connector\Role\TcpServerConnector.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Connector\Role\UdpConnector.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\Constant\InnerKeys.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\Context\DeviceManager.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\Context\DeviceManagerEvents.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\Context\ReadDataSleepManager.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\DeviceDataSource.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\DeviceEvents.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\DeviceModel.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\DKey\ByteKey.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\DKey\DataKey.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\DKey\DoubleKey.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\DKey\FloatKey.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\DKey\IntKey.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\DKey\ShortKey.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\DKey\StringKey.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\Entity\DeviceOption.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\Enum\DataType.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\Interfaces\IDeviceComponent.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\Interfaces\Impls\RateCalculationCompo.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Device\Utils\DeviceModelFactory.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Processor\Interface\IDataProcessor.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Processor\Interface\Impls\EmptyProcessor.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Resolver\Enum\WitSensorProtocol.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Resolver\Interface\Impls\EmptyResolver.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Device\Resolver\Interface\IProtocolResolver.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Example\IAttitudeSenosrApi.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Tools\Byte\ByteArrayConvert.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Tools\Cmd\Entity\CmdBean.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Tools\Cmd\Utils\CmdUtils.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Tools\DateTime\DateTimeUtils.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Tools\Device\AutoDelayUtils.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Tools\Device\DataProcessorContext.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Tools\Device\RecordKeySwitch.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Tools\Device\Utils\AsciiProtocolUtils.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Tools\Device\Utils\ATCommandHelper.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Tools\Device\Utils\DipSensorMagHelper.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Tools\Device\Utils\Modbus16Utils.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Tools\Device\Utils\MWT925Helper.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Tools\Device\Utils\SerialPortUtils.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Tools\Device\Utils\WitCanProtocolUtils.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Tools\Device\Utils\WitProtocolUtils.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Tools\Device\Utils\WitSensorHelper.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Tools\Device\Utils\WT925Helper.cs" />
<Compile Include="Models\Modules\WT901C485\WitSdk\Tools\Gps\GpsUtils.cs" />
<Compile Include="Models\Modules\WT901C485\Wt901c\Components\Modbus16Resolver.cs" />
<Compile Include="Models\Modules\WT901C485\Wt901c\Components\WT901C485Processor.cs" />
<Compile Include="Models\Modules\WT901C485\Wt901c\Data\WitSensorKey.cs" />
<Compile Include="Models\Modules\WT901C485\Wt901c\WT901C485.cs" />
<Compile Include="Models\MotorComum.cs" />
<Compile Include="Models\Operacoes\OperacaoManualModel.cs" />
<Compile Include="Models\Operacoes\OperacaoMapaGPSModel.cs" />
@ -441,6 +376,7 @@
<Compile Include="Models\PZEMModel.cs" />
<Compile Include="Models\SonarModel.cs" />
<Compile Include="Models\Variaveis.cs" />
<Compile Include="Models\WT901CModel.cs" />
<Compile Include="Services\APIService.cs" />
<Compile Include="Services\BLD300RService.cs" />
<Compile Include="Services\CameraService.cs" />

View File

@ -222,7 +222,7 @@ namespace AgroBase.Forms.Sensoriamento
else
{
var Comando = PZEMService.ComandoGetParametro(PZEMService.Parametros[cmbBateriaParametro.Text]);
PZEMService.EnviarComando(PZEMService.PortaPZEM, Comando);
PZEMService.EnviarComando(ModbusService._PortaModbus, Comando);
}
}
@ -237,14 +237,14 @@ namespace AgroBase.Forms.Sensoriamento
else
{
var Comando = PZEMService.ComandoSetParametro(PZEMService.Parametros[cmbBateriaParametro.Text], Convert.ToInt32(nudBateriaValor.Value));
PZEMService.EnviarComando(PZEMService.PortaPZEM, Comando);
PZEMService.EnviarComando(ModbusService._PortaModbus, Comando);
}
}
private void btnBateriaCalibrar_Click(object sender, EventArgs e)
{
var Comando = PZEMService.ComandoCalibragem();
PZEMService.EnviarComando(PZEMService.PortaPZEM, Comando);
PZEMService.EnviarComando(ModbusService._PortaModbus, Comando);
}

View File

@ -30,6 +30,9 @@
{
this.btnMovimentação = new System.Windows.Forms.Button();
this.btnDirecional = new System.Windows.Forms.Button();
this.gpbSensoriamento = new System.Windows.Forms.GroupBox();
this.chbRequisitarDados = new System.Windows.Forms.CheckBox();
this.gpbSensoriamento.SuspendLayout();
this.SuspendLayout();
//
// btnMovimentação
@ -54,11 +57,34 @@
this.btnDirecional.UseVisualStyleBackColor = true;
this.btnDirecional.Click += new System.EventHandler(this.btnDirecional_Click);
//
// gpbSensoriamento
//
this.gpbSensoriamento.Controls.Add(this.chbRequisitarDados);
this.gpbSensoriamento.Location = new System.Drawing.Point(12, 63);
this.gpbSensoriamento.Name = "gpbSensoriamento";
this.gpbSensoriamento.Size = new System.Drawing.Size(306, 63);
this.gpbSensoriamento.TabIndex = 2;
this.gpbSensoriamento.TabStop = false;
this.gpbSensoriamento.Text = "Sensoriamento";
//
// chbRequisitarDados
//
this.chbRequisitarDados.AutoSize = true;
this.chbRequisitarDados.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.chbRequisitarDados.Location = new System.Drawing.Point(6, 26);
this.chbRequisitarDados.Name = "chbRequisitarDados";
this.chbRequisitarDados.Size = new System.Drawing.Size(236, 20);
this.chbRequisitarDados.TabIndex = 0;
this.chbRequisitarDados.Text = "Requisitar Dados Para os Módulos";
this.chbRequisitarDados.UseVisualStyleBackColor = true;
this.chbRequisitarDados.CheckedChanged += new System.EventHandler(this.chbRequisitarDados_CheckedChanged);
//
// frmMvdConfig
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(330, 68);
this.ClientSize = new System.Drawing.Size(330, 138);
this.Controls.Add(this.gpbSensoriamento);
this.Controls.Add(this.btnDirecional);
this.Controls.Add(this.btnMovimentação);
this.MaximizeBox = false;
@ -66,6 +92,8 @@
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Parametrização - Movimentação";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.frmMvdConfig_FormClosing);
this.gpbSensoriamento.ResumeLayout(false);
this.gpbSensoriamento.PerformLayout();
this.ResumeLayout(false);
}
@ -74,5 +102,7 @@
private System.Windows.Forms.Button btnMovimentação;
private System.Windows.Forms.Button btnDirecional;
private System.Windows.Forms.GroupBox gpbSensoriamento;
private System.Windows.Forms.CheckBox chbRequisitarDados;
}
}

View File

@ -1,5 +1,6 @@
using AgroBase.Forms.Direcional;
using AgroBase.Forms.Movimentacao;
using AgroBase.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@ -37,6 +38,12 @@ namespace AgroBase.Forms
frm.ShowDialog();
}
private void chbRequisitarDados_CheckedChanged(object sender, EventArgs e)
{
Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.ForEach(m =>
{
m.RequisitarDados = chbRequisitarDados.Checked;
});
}
}
}

View File

@ -22,8 +22,6 @@ using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Wit.SDK.Modular.Sensor.Modular.DataProcessor.Constant;
using Wit.SDK.Modular.WitSensorApi.Modular.WT901C485;
using static AgroBase.Models.Enuns;
namespace AgroBase

View File

@ -9,9 +9,6 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using Wit.SDK.Modular.Sensor.Modular.DataProcessor.Constant;
using Wit.SDK.Modular.WitSensorApi.Modular.WT901C485;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using System.Drawing.Drawing2D;
@ -28,7 +25,7 @@ namespace AgroBase.Forms
double AnguloZ = 0;
private GLControl glControl;
Timer tmrLeitura;
WT901C485 WT901C = Variaveis.WT901C;
//WT901C485 WT901C = Variaveis.WT901C;
public frmWT901C()
{
@ -222,45 +219,45 @@ namespace AgroBase.Forms
txtY.Text = AnguloY.ToString("0.00");
txtZ.Text = AnguloZ.ToString("0.00");
gridDados.Rows[0].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.VersionNumber);
gridDados.Rows[1].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.ChipTime).ToString().Split(' ')[0];
gridDados.Rows[2].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.ChipTime).ToString().Split(' ')[1];
gridDados.Rows[3].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.AccX);
gridDados.Rows[4].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.AccY);
gridDados.Rows[5].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.AccZ);
gridDados.Rows[6].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.AccM);
gridDados.Rows[7].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.AsX);
gridDados.Rows[8].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.AsY);
gridDados.Rows[9].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.AsZ);
gridDados.Rows[10].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.AsM);
gridDados.Rows[11].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.AngleX);
gridDados.Rows[12].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.AngleY);
gridDados.Rows[13].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.AngleZ);
gridDados.Rows[14].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.HX);
gridDados.Rows[15].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.HY);
gridDados.Rows[16].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.HZ);
gridDados.Rows[17].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.HM);
gridDados.Rows[18].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.T);
gridDados.Rows[19].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.P);
gridDados.Rows[20].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.H);
gridDados.Rows[0].Cells[1].Value = WT901CService.DadosLeitura.Versao;
gridDados.Rows[1].Cells[1].Value = WT901CService.DadosLeitura.DataHora.ToString("dd/MM/yyyy");
gridDados.Rows[2].Cells[1].Value = WT901CService.DadosLeitura.DataHora.ToString("HH:mm:ss");
gridDados.Rows[3].Cells[1].Value = WT901CService.DadosLeitura.AccX;
gridDados.Rows[4].Cells[1].Value = WT901CService.DadosLeitura.AccY;
gridDados.Rows[5].Cells[1].Value = WT901CService.DadosLeitura.AccZ;
gridDados.Rows[6].Cells[1].Value = WT901CService.DadosLeitura.AccM;
gridDados.Rows[7].Cells[1].Value = WT901CService.DadosLeitura.AsX;
gridDados.Rows[8].Cells[1].Value = WT901CService.DadosLeitura.AsY;
gridDados.Rows[9].Cells[1].Value = WT901CService.DadosLeitura.AsZ;
gridDados.Rows[10].Cells[1].Value = WT901CService.DadosLeitura.AsM;
gridDados.Rows[11].Cells[1].Value = WT901CService.DadosLeitura.AngleX;
gridDados.Rows[12].Cells[1].Value = WT901CService.DadosLeitura.AngleY;
gridDados.Rows[13].Cells[1].Value = WT901CService.DadosLeitura.AngleZ;
gridDados.Rows[14].Cells[1].Value = WT901CService.DadosLeitura.HX;
gridDados.Rows[15].Cells[1].Value = WT901CService.DadosLeitura.HY;
gridDados.Rows[16].Cells[1].Value = WT901CService.DadosLeitura.HZ;
gridDados.Rows[17].Cells[1].Value = WT901CService.DadosLeitura.HM;
gridDados.Rows[18].Cells[1].Value = WT901CService.DadosLeitura.Temperatura;
gridDados.Rows[19].Cells[1].Value = WT901CService.DadosLeitura.Pressao;
gridDados.Rows[20].Cells[1].Value = WT901CService.DadosLeitura.Altitude;
gridDados.Rows[21].Cells[1].Value = "";
gridDados.Rows[22].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.D0);
gridDados.Rows[23].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.D1);
gridDados.Rows[24].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.D2);
gridDados.Rows[25].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.D3);
gridDados.Rows[26].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.Q0);
gridDados.Rows[27].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.Q1);
gridDados.Rows[28].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.Q2);
gridDados.Rows[29].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.Q3);
gridDados.Rows[30].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.LonDeg);
gridDados.Rows[31].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.LatDeg);
gridDados.Rows[32].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.GPSHeight);
gridDados.Rows[33].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.GPSYaw);
gridDados.Rows[34].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.GPSV);
gridDados.Rows[35].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.SN.ToString());
gridDados.Rows[36].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.PDOP);
gridDados.Rows[37].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.HDOP);
gridDados.Rows[38].Cells[1].Value = WT901C.GetDeviceData(WitSensorKey.VDOP);
gridDados.Rows[22].Cells[1].Value = WT901CService.DadosLeitura.D0;
gridDados.Rows[23].Cells[1].Value = WT901CService.DadosLeitura.D1;
gridDados.Rows[24].Cells[1].Value = WT901CService.DadosLeitura.D2;
gridDados.Rows[25].Cells[1].Value = WT901CService.DadosLeitura.D3;
gridDados.Rows[26].Cells[1].Value = WT901CService.DadosLeitura.Q0;
gridDados.Rows[27].Cells[1].Value = WT901CService.DadosLeitura.Q1;
gridDados.Rows[28].Cells[1].Value = WT901CService.DadosLeitura.Q2;
gridDados.Rows[29].Cells[1].Value = WT901CService.DadosLeitura.Q3;
gridDados.Rows[30].Cells[1].Value = WT901CService.DadosLeitura.Longitude;
gridDados.Rows[31].Cells[1].Value = WT901CService.DadosLeitura.Latitude;
gridDados.Rows[32].Cells[1].Value = WT901CService.DadosLeitura.GPS_Altitude;
gridDados.Rows[33].Cells[1].Value = WT901CService.DadosLeitura.GPS_Orientacao;
gridDados.Rows[34].Cells[1].Value = WT901CService.DadosLeitura.GPS_Velcodiade;
gridDados.Rows[35].Cells[1].Value = WT901CService.DadosLeitura.GPS_NumeroSatelites;
gridDados.Rows[36].Cells[1].Value = WT901CService.DadosLeitura.PDOP;
gridDados.Rows[37].Cells[1].Value = WT901CService.DadosLeitura.HDOP;
gridDados.Rows[38].Cells[1].Value = WT901CService.DadosLeitura.VDOP;
}

View File

@ -58,6 +58,7 @@ namespace AgroBase.Models
Wit = 107,
Bld = 108,
Mvd = 109,
Mbs = 110,
}
public enum F_Code

View File

@ -304,14 +304,14 @@ namespace AgroBase.Models.Modules
public async Task LoopRegistrador()
{
await Task.Delay(1000);
await Task.Delay(_TaxaAmostragem);
if (Conectado)
{
if (UltimaDirecao != Direcao.Parado)
{
TempoEmAtividade++;
double VelocidadeMedia = Modulos.Where(x => x.Conectado).Average(x => x.MovMotor.VelocidadeInstantanea * 1000 / 3600);
double VelocidadeMedia = Modulos.Where(x => x.Conectado).Average(x => x.MovMotor.VelocidadeInstantanea * _TaxaAmostragem / 3600);
DistanciaPercorridaTotal += 1 * VelocidadeMedia;
DistanciaPercorridaParcial += (UltimaDirecao == Direcao.Frente ? 1 : UltimaDirecao == Direcao.Tras ? -1 : 0) * VelocidadeMedia;
DistanciaPercorridaOperacao += 1 * VelocidadeMedia;
@ -340,6 +340,12 @@ namespace AgroBase.Models.Modules
Variaveis.OperacaoEmAndamento.DispMvd.AdicionarMensagemFila(Modulo.Modulo_ID, Protocolo, true, false);
}
}*/
foreach (var Modulo in Modulos.Where(x => x.RequisitarDados && (x.MovMotor.Inicializado || x.DirMotor.Inicializado)))
{
string Protocolo = Modulo.ProtocoloAquisicaoDados();
Variaveis.OperacaoEmAndamento.DispMvd.AdicionarMensagemFila(Modulo.Modulo_ID, Protocolo, false, false);
}
}
await LoopRegistrador();
@ -351,7 +357,7 @@ namespace AgroBase.Models.Modules
{
public string Modulo_ID { get; set; }
public bool Disponivel { get; set; }
public bool RequisitarDados { get; set; } = false;
public bool Conectado
{
@ -392,6 +398,7 @@ namespace AgroBase.Models.Modules
Modulo_ID + SerialService.SplitParams +
(Conectar ? "1" : "0") + SerialService.SplitParams +
MovimentacaoUnificadaModel._TaxaAmostragem.ToString() + SerialService.SplitParams +
(RequisitarDados ? "1" : "0") + SerialService.SplitParams +
PinoutModel.PinoProtocolo(_pinout, Funcoes);
if (Conectar)
@ -442,6 +449,16 @@ namespace AgroBase.Models.Modules
}
}
public string ProtocoloAquisicaoDados()
{
string ProtocoloMotor =
((int)F_Code.Req).ToString() + SerialService.SplitMessage +
Modulo_ID + SerialService.SplitParams +
"";
return ProtocoloMotor;
}
}
public class MvdMotorBLDC

View File

@ -1,35 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Modular.Sensor.Modular.Connector.Entity
{
/// <summary>
/// 串口配置
/// </summary>
[Serializable]
public class SerialPortConfig : IConnectConfig
{
/// <summary>
/// 波特率
/// </summary>
public int BaudRate { get; set; } = 0;
/// <summary>
/// com口名称
/// </summary>
public string PortName { get; set; } = "";
/// <summary>
/// 是否启用rts
/// </summary>
public bool RtsEnable { get; set; } = false;
/// <summary>
/// 是否启用dtr
/// </summary>
public bool DTREnable { get; set; } = false;
}
}

View File

@ -1,26 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Modular.Sensor.Modular.Connector.Entity
{
/// <summary>
/// tcp客户端配置
/// </summary>
[Serializable]
public class TcpClientConfig : IConnectConfig
{
/// <summary>
/// 通信的远程服务端ip
/// </summary>
public string IP { get; set; }
/// <summary>
/// 通信的远程服务端端口
/// </summary>
public int Port { get; set; }
}
}

View File

@ -1,26 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Modular.Sensor.Modular.Connector.Entity
{
/// <summary>
/// tcp服务端配置
/// </summary>
[Serializable]
public class TcpServerConfig : IConnectConfig
{
/// <summary>
/// 监听的IP和端口号
/// </summary>
public IPEndPoint IPEndPoint = null;
/// <summary>
/// 远程网络地址
/// </summary>
public EndPoint RemoteEP = null;
}
}

View File

@ -1,27 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Modular.Sensor.Modular.Connector.Entity
{
/// <summary>
/// UDP配置
/// </summary>
[Serializable]
public class UdpConfig : IConnectConfig
{
/// <summary>
/// 本地ip和端口
/// </summary>
public IPEndPoint localIpPoint = null;
/// <summary>
/// 远程ip和端口
/// </summary>
public IPEndPoint remoteIpPoint = null;
}
}

View File

@ -1,18 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Net;
using System.Text;
namespace Wit.SDK.Modular.Sensor.Modular.Connector.Entity
{
/// <summary>
/// 连接配置
/// </summary>
public interface IConnectConfig
{
}
}

View File

@ -1,208 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using Wit;
using Wit.SDK;
using Wit.SDK.Modular;
using Wit.SDK.Modular.Sensor;
using Wit.SDK.Modular.Sensor.Device;
using Wit.SDK.Modular.Sensor.Modular;
using Wit.SDK.Modular.Sensor.Modular.Connector.Entity;
using Wit.SDK.Modular.Sensor.Modular.Connector.Interface;
namespace Wit.SDK.Modular.Sensor.Modular.Connector.Interface
{
/// <summary>
/// 核心通讯模块接口
/// </summary>
public abstract class IConnector
{
/// <summary>
/// 连接状态
/// </summary>
protected ConnectStatus ConnectStatus { get; set; } = ConnectStatus.Closed;
/// <summary>
/// 接收数据队列
/// </summary>
public ConcurrentQueue<byte[]> ReceiveQueue = new ConcurrentQueue<byte[]>();
/// 发送数据锁
/// </summary>
public object OnSendDataLockObj = new object();
/// <summary>
/// 接收数据队列
/// </summary>
public Thread ReceiveThread;
/// <summary>
/// 收数据的人
/// </summary>
private List<DataReceivedInterface> receiveListenerList = new List<DataReceivedInterface>();
/// <summary>
/// 监听发送数据的人
/// </summary>
private List<SendDataInterface> sendDataInterfaceList = new List<SendDataInterface>();
/// <summary>
/// 构造
/// </summary>
public IConnector() {
ReceiveThread = new Thread(HandleReceiveThread) { IsBackground = true };
ReceiveThread.Start();
}
/// <summary>
/// 对象销毁时
/// </summary>
~IConnector()
{
if (ReceiveThread != null) {
ReceiveThread.Abort();
}
}
/// <summary>
/// 检查配置
/// </summary>
public abstract void CheckConfig();
/// <summary>
/// 获得连接配置
/// </summary>
/// <returns></returns>
public abstract IConnectConfig GetConfig();
/// <summary>
/// 是否已经打开连接
/// </summary>
/// <returns></returns>
public bool IsOpen()
{
return ConnectStatus == ConnectStatus.Opened;
}
/// <summary>
/// 打开连接
/// </summary>
/// <returns></returns>
public abstract void Open();
/// <summary>
/// 关闭连接
/// </summary>
/// <returns></returns>
public abstract void Close();
/// <summary>
/// 发送数据
/// </summary>
/// <param name="data"></param>
public abstract void SendData(byte[] data);
/// <summary>
/// 移除接收数据的人
/// </summary>
/// <param name="listener"></param>
public void LogoutReceivedObj(DataReceivedInterface listener) {
receiveListenerList.Remove(listener);
}
/// <summary>
/// 添加接收数据的人
/// </summary>
/// <param name="listener"></param>
public void RegisterReceivedObj(DataReceivedInterface listener) {
receiveListenerList.Add(listener);
}
/// <summary>
/// 取消发送数据监听者
/// </summary>
/// <param name="listener"></param>
public void LogoutDataDisplayObj(SendDataInterface listener) {
sendDataInterfaceList.Remove(listener);
}
/// <summary>
/// 添加发送数据监听者
/// </summary>
/// <param name="listener"></param>
public void RegisterDataDisplayObj(SendDataInterface listener) {
sendDataInterfaceList.Add(listener);
}
/// <summary>
/// 接收数据
/// </summary>
/// <param name="data"></param>
public void onReceive(byte[] data)
{
ReceiveQueue.Enqueue(data);
}
/// <summary>
/// 处理接收数据线程
/// </summary>
private void HandleReceiveThread()
{
while (true) {
Thread.Sleep(1);
while (ReceiveQueue.Count > 0) {
byte[] data = null;
ReceiveQueue.TryDequeue(out data);
for (int i = 0; i < receiveListenerList.Count; i++)
{
DataReceivedInterface dataReceived = receiveListenerList[i];
dataReceived.OnDataReceived(data);
}
}
}
}
/// <summary>
/// 如果发送数据
/// </summary>
/// <param name="data"></param>
public void OnSendData(byte[] data)
{
for (int i = 0; i < sendDataInterfaceList.Count; i++)
{
var item = sendDataInterfaceList[i];
// 调用线程池完成操作
ThreadPool.QueueUserWorkItem(new WaitCallback((p) =>
{
lock (OnSendDataLockObj)
{
item.OnSendData(data);
}
}), null);
}
}
}
/// <summary>
/// 连接状态
/// </summary>
public enum ConnectStatus
{
/// <summary>
/// 打开的
/// </summary>
Opened = 0,
/// <summary>
/// 关闭的
/// </summary>
Closed = 1
}
}

View File

@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Modular.Sensor.Modular.Connector.Interface
{
/// <summary>
/// 接收数据监听者
/// </summary>
public interface DataReceivedInterface
{
void OnDataReceived(byte[] data);
}
}

View File

@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Modular.Sensor.Modular.Connector.Interface
{
/// <summary>
/// 发送数据接口
/// </summary>
public interface SendDataInterface
{
void OnSendData(byte[] data);
}
}

View File

@ -1,412 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace Wit.SDK.Modular.Sensor.Modular.Connector.Role
{
/// <summary>
/// 服务端
/// </summary>
public class TcpServer
{
/// <summary>
/// 服务端
/// </summary>
public Socket ServerSocket = null;
/// <summary>
/// tcp客户端字典
/// </summary>
public ConcurrentDictionary<string, ClientSession> ClientSocketDic = new ConcurrentDictionary<string, ClientSession>();
/// <summary>
/// 监听客户端连接的标志
/// </summary>
private bool FlagListen = false;
/// <summary>
/// 监听的IP和端口
/// </summary>
private IPEndPoint iPEndPoint;
/// <summary>
/// 收到数据委托
/// </summary>
/// <param name="data"></param>
public delegate void OnReceiveEvent(EndPoint remoteEP, byte[] data);
/// <summary>
/// 客户端数据接收事件
/// </summary>
public event OnReceiveEvent OnReceive;
/// <summary>
/// 构造
/// </summary>
/// <param name="iPEndPoint"></param>
public TcpServer(IPEndPoint iPEndPoint)
{
this.iPEndPoint = iPEndPoint;
}
/// <summary>
/// 创建实例
/// </summary>
/// <param name="iPEndPoint"></param>
/// <returns></returns>
internal static TcpServer CreateInstance(IPEndPoint iPEndPoint)
{
TcpServer server = new TcpServer(iPEndPoint);
return server;
}
/// <summary>
/// 启动服务
/// </summary>
/// <param name="port">端口号</param>
public void Open(IPEndPoint endPoint) {
iPEndPoint = endPoint;
Open();
}
/// <summary>
/// 启动服务
/// </summary>
/// <param name="port">端口号</param>
public void Open()
{
OpenOrClose(true);
}
/// <summary>
/// 关闭服务
/// </summary>
public void Close()
{
OpenOrClose(false);
}
/// <summary>
/// 打开或者关闭
/// </summary>
/// <param name="_open"></param>
private void OpenOrClose(bool _open) {
lock (ClientSocketDic) {
if (_open)
{
ToOpen();
}
else {
ToClose();
}
}
}
/// <summary>
/// 打开逻辑
/// </summary>
/// <returns></returns>
private void ToOpen()
{
if (FlagListen) {
return;
}
FlagListen = true;
// 创建负责监听的套接字,注意其中的参数;
ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 将负责监听的套接字绑定到唯一的ip和端口上
ServerSocket.Bind(iPEndPoint);
// 设置监听队列的长度;
ServerSocket.Listen(100);
// 创建负责监听的线程;
Thread Thread_ServerListen = new Thread(ListenConnecting);
Thread_ServerListen.IsBackground = true;
Thread_ServerListen.Start();
}
/// <summary>
/// 关闭
/// </summary>
private void ToClose()
{
if (OnReceive != null)
{
return;
}
FlagListen = false;
// 关闭服务器
if (ServerSocket != null)
{
try
{
//ServerSocket.Shutdown(SocketShutdown.Both);
//ServerSocket.Close();
ServerSocket.Dispose();
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
// 关闭每一个客户端
List<ClientSession> list = new List<ClientSession>();
foreach (var item in ClientSocketDic)
{
list.Add(item.Value);
}
for (int i = 0; i < list.Count; i++)
{
list[i].Close();
}
ClientSocketDic.Clear();
}
/// <summary>
/// 监听客户端请求的方法;
/// </summary>
private void ListenConnecting()
{
while (FlagListen)
{
// 每100ms找一次
Thread.Sleep(100);
try
{
// 一旦监听到一个客户端的请求,就返回一个与该客户端通信的 套接字;
Socket sokConnection = ServerSocket.Accept();
// 将与客户端连接的 套接字 对象添加到集合中;
string str_EndPoint = sokConnection.RemoteEndPoint.ToString();
ClientSession myTcpClient = new ClientSession() {
id = str_EndPoint,
remoteEP = sokConnection.RemoteEndPoint,
tcpSocket = sokConnection,
tcpServer = this,
};
//创建线程接收数据
ClientSocketDic.TryAdd(str_EndPoint, myTcpClient);
}
catch(Exception ex)
{
if (FlagListen) {
Debug.WriteLine(ex);
}
break;
}
}
}
/// <summary>
/// 发送数据给指定的客户端
/// </summary>
/// <param name="_endPoint">客户端套接字</param>
/// <param name="_buf">发送的数组</param>
/// <returns></returns>
public bool SendData(string _endPoint, byte[] _buf)
{
ClientSession myT = null;
if (ClientSocketDic.TryGetValue(_endPoint, out myT))
{
myT.Send(_buf);
return true;
}
else
{
return false;
}
}
/// <summary>
/// 发送数据给所有的客户端
/// </summary>
/// <param name="_buf">发送的数组</param>
/// <returns></returns>
public bool AllSendData(byte[] _buf)
{
foreach (var item in ClientSocketDic)
{
ClientSession myT = item.Value;
myT.Send(_buf);
}
return true;
}
/// <summary>
/// 数据接收事件
/// </summary>
/// <param name="remoteEP"></param>
/// <param name="buf"></param>
public void InvokeOnReceive(EndPoint remoteEP, byte[] buf)
{
OnReceive?.Invoke(remoteEP, buf);
}
}
/// <summary>
/// 会话端
/// </summary>
public class ClientSession
{
/// <summary>
/// 服务器
/// </summary>
public TcpServer tcpServer;
/// <summary>
/// 客户端
/// </summary>
public Socket tcpSocket;//socket对象
/// <summary>
/// 数据缓存
/// </summary>
public List<byte> DataBuffer = new List<byte>();//数据缓存区
/// <summary>
/// 远程IP
/// </summary>
public EndPoint remoteEP;
public string id;
/// <summary>
/// 是否启动的
/// </summary>
private bool Flag_Receive;
public ClientSession()
{
Thread th = new Thread(this.ReceiveData) {
IsBackground = true,
};
th.Start();
}
/// <summary>
/// 接收数据
/// </summary>
public void ReceiveData()
{
Flag_Receive = true;
while (Flag_Receive)
{
// 接收数据延时
Thread.Sleep(10);
try
{
// 定义一个2M的缓存区
byte[] arrMsgRec = new byte[1024 * 1024 * 2];
// 将接受到的数据存入到输入 arrMsgRec中
int length = -1;
length = tcpSocket.Receive(arrMsgRec); // 接收数据,并返回数据的长度
if (length > 0)
{
byte[] buf = new byte[length];
Array.Copy(arrMsgRec, buf, length);
tcpServer.InvokeOnReceive(remoteEP, buf);
}
}
catch (Exception ex)
{
if (Flag_Receive) {
Debug.WriteLine(ex);
Close();
}
}
}
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="buf"></param>
public void Send(byte[] buf)
{
if (buf != null)
{
tcpSocket.Send(buf);
}
}
/// <summary>
/// 获取连接的ip
/// </summary>
/// <returns></returns>
public string GetIp()
{
IPEndPoint clientipe = (IPEndPoint)tcpSocket.RemoteEndPoint;
string _ip = clientipe.Address.ToString();
return _ip;
}
/// <summary>
/// 关闭连接
/// </summary>
public void Close()
{
if (Flag_Receive) {
try
{
Flag_Receive = false;
tcpSocket.Shutdown(SocketShutdown.Both);
tcpSocket.Close();
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
// 从通信线程集合中删除被中断连接的通信线程对象;
ClientSession session = null;
tcpServer.ClientSocketDic.TryRemove(id, out session);//删除客户端字典中该socket
}
}
/// <summary>
/// 提取正确数据包
/// </summary>
public byte[] GetBuffer(int startIndex, int size)
{
byte[] buf = new byte[size];
DataBuffer.CopyTo(startIndex, buf, 0, size);
DataBuffer.RemoveRange(0, startIndex + size);
return buf;
}
/// <summary>
/// 添加队列数据
/// </summary>
/// <param name="buffer"></param>
public void AddQueue(byte[] buffer)
{
DataBuffer.AddRange(buffer);
}
/// <summary>
/// 清除缓存
/// </summary>
public void ClearQueue()
{
DataBuffer.Clear();
}
}
}

View File

@ -1,48 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Modular.Sensor.Modular.Connector.Role;
using Wit.SDK.Sensor.Connector.Modular.Udp;
namespace Wit.SDK.Sensor.Connector.Modular.Tcp
{
/// <summary>
/// Tcp服务器代理
/// </summary>
public class TcpServerPool
{
/// <summary>
/// 字典
/// </summary>
public static ConcurrentDictionary<int, TcpServer> Dict = new ConcurrentDictionary<int, TcpServer>();
/// <summary>
/// 线程锁
/// </summary>
private static object lockobj = new object();
/// <summary>
/// 创建UDP服务器
/// </summary>
public static TcpServer GetTcpServer(IPEndPoint iPEndPoint)
{
lock (lockobj)
{
if (Dict.ContainsKey(iPEndPoint.Port))
{
return Dict[iPEndPoint.Port];
}
else
{
var con = TcpServer.CreateInstance(iPEndPoint);
Dict.TryAdd(iPEndPoint.Port, con);
return con;
}
}
}
}
}

View File

@ -1,92 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Sensor.Connector.Modular.Udp;
using Wit.SDK.Udp;
using Wit.SDK.Modular.Sensor.Modular.Connector.Role;
using static Wit.SDK.Modular.Sensor.Modular.Connector.Role.TcpServer;
namespace Wit.SDK.Sensor.Connector.Modular.Tcp
{
/// <summary>
/// Tcp服务器代理
/// </summary>
public class TcpServerProxy
{
/// <summary>
/// udp服务器
/// </summary>
private TcpServer tcpServer;
/// <summary>
/// 远程服务器ip
/// </summary>
private IPEndPoint iPEndPoint;
/// <summary>
/// 收到数据事件
/// </summary>
public event OnReceiveEvent OnReceive;
/// <summary>
/// 构造
/// </summary>
/// <param name="iPEndPoint"></param>
public TcpServerProxy(IPEndPoint iPEndPoint)
{
this.iPEndPoint = iPEndPoint;
tcpServer = TcpServerPool.GetTcpServer(iPEndPoint);
}
/// <summary>
/// 关闭
/// </summary>
public void Close()
{
tcpServer.OnReceive -= UdpReceive;
tcpServer.Close();
}
/// <summary>
/// 打开
/// </summary>
public void Open()
{
tcpServer.Open();
tcpServer.OnReceive -= UdpReceive;
tcpServer.OnReceive += UdpReceive;
}
/// <summary>
/// udp收到数据
/// </summary>
/// <param name="remoteEP"></param>
/// <param name="data"></param>
private void UdpReceive(EndPoint remoteEP, byte[] data)
{
OnReceive?.Invoke(remoteEP, data);
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="data"></param>
/// <param name="remoteIpPoint"></param>
public void Send(EndPoint remoteIpPoint, byte[] data)
{
tcpServer.SendData(remoteIpPoint.ToString(), data);
}
/// <summary>
/// 发送到全部
/// </summary>
/// <param name="data"></param>
public void AllSend(byte[] data)
{
tcpServer.AllSendData(data);
}
}
}

View File

@ -1,226 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Wit.SDK.Modular.Sensor.Modular.Connector.Entity;
using Wit.SDK.Modular.Sensor.Modular.Connector.Interface;
namespace Wit.SDK.Sensor.Connector.Modular.Udp
{
/// <summary>
/// Udp服务器
/// </summary>
public class UdpServer
{
/// <summary>
/// UDP客户端
/// </summary>
private Socket newsock;
//private UdpClient UdpClient { get; set; }
/// <summary>
/// 是否打开的
/// </summary>
public bool IsOpen { get; private set; }
/// <summary>
/// 本地ip和端口
/// </summary>
public IPEndPoint LocalIpPoint = null;
/// <summary>
/// 自动任务线程
/// </summary>
private Thread AutoTaskThread = null;
/// <summary>
/// 是否运行任务线程
/// </summary>
private bool AutoTaskRun = false;
/// <summary>
/// 打开设备锁
/// </summary>
private object openlock = new object();
/// <summary>
/// 收到数据委托
/// </summary>
/// <param name="data"></param>
public delegate void OnReceiveEvent(IPEndPoint remoteEP,byte[] data);
/// <summary>
/// 收到数据事件
/// </summary>
public event OnReceiveEvent OnReceive;
/// <summary>
/// 构造
/// </summary>
/// <param name="localIpPoint"></param>
private UdpServer(IPEndPoint localIpPoint)
{
LocalIpPoint = localIpPoint;
}
/// <summary>
/// 检查配置
/// </summary>
public void CheckConfig()
{
if (LocalIpPoint == null)
{
throw new Exception("未设置udp本地监听地址和端口");
}
}
/// <summary>
/// 关闭
/// </summary>
public void Close()
{
if (OnReceive != null) {
return;
}
if (newsock != null)
{
try
{
newsock.Close();
}
catch (Exception ex) {
Debug.WriteLine(ex);
}
}
if (AutoTaskThread != null)
{
AutoTaskRun = false;
// AutoTaskThread.Abort();
}
// 标志为关闭状态
IsOpen = false;
}
/// <summary>
/// 打开连接
/// </summary>
public void Open()
{
lock (openlock) {
// 不重复打开
if (IsOpen)
{
return;
}
CheckConfig();
if (newsock != null)
{
try
{
newsock.Close();
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
// 新建套接字,基于IPv和4UDP协议
newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
// 绑定本机ip地址
newsock.Bind(LocalIpPoint);
// 读取数据线程
AutoTaskThread = new Thread(AutoTaskMethod);
AutoTaskRun = true;
AutoTaskThread.IsBackground = true;
AutoTaskThread.Start();
IsOpen = true;
}
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="data"></param>
/// <param name="remoteEP"></param>
/// <exception cref="Exception"></exception>
public void Send(byte[] data, IPEndPoint remoteEP)
{
//检查状态
if (IsOpen == false)
{
throw new Exception("发送失败,未打开连接");
}
newsock.SendTo(data, data.Length, SocketFlags.None, remoteEP);
}
/// <summary>
/// 自动任务线程方法
/// </summary>
private void AutoTaskMethod()
{
int length;
//存储数据
byte[] data = new byte[1024];
while (AutoTaskRun)
{
// 休眠1毫秒防止cpu占用率过高
//Thread.Sleep(1);
try
{
//得到客户机IP
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint remoteEP = (EndPoint)(sender);
length = newsock.ReceiveFrom(data, ref remoteEP);
if (length > 0)
{
byte[] buf = new byte[length];
Array.Copy(data, buf, length);
InvokeOnReceive((IPEndPoint)remoteEP, buf);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
Debug.WriteLine(ex.StackTrace);
}
}
}
/// <summary>
/// 收到数据时
/// </summary>
/// <param name="data"></param>
private void InvokeOnReceive(IPEndPoint remoteEP, byte[] data)
{
OnReceive?.Invoke(remoteEP,data);
}
/// <summary>
/// 创建实例
/// </summary>
/// <param name="iPEndPoint"></param>
/// <returns></returns>
public static UdpServer CreateInstance(IPEndPoint iPEndPoint)
{
return new UdpServer(iPEndPoint);
}
}
}

View File

@ -1,50 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Modular.Sensor.Modular.Connector.Entity;
using Wit.SDK.Modular.Sensor.Modular.Connector.Role;
using Wit.SDK.Sensor.Connector.Modular.Udp;
namespace Wit.SDK.Udp
{
/// <summary>
/// UDP服务器池
/// </summary>
public class UdpServerPool
{
/// <summary>
/// 字典
/// </summary>
public static ConcurrentDictionary<int, UdpServer> Dict = new ConcurrentDictionary<int, UdpServer>();
/// <summary>
/// 线程锁
/// </summary>
private static object lockobj = new object();
/// <summary>
/// 创建UDP服务器
/// </summary>
public static UdpServer GetUdpServer(IPEndPoint iPEndPoint)
{
lock (lockobj)
{
if (Dict.ContainsKey(iPEndPoint.Port))
{
return Dict[iPEndPoint.Port];
}
else
{
var con = UdpServer.CreateInstance(iPEndPoint);
Dict.TryAdd(iPEndPoint.Port, con);
return con;
}
}
}
}
}

View File

@ -1,81 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Udp;
using static Wit.SDK.Sensor.Connector.Modular.Udp.UdpServer;
namespace Wit.SDK.Sensor.Connector.Modular.Udp
{
/// <summary>
/// Udp服务器代理
/// </summary>
public class UdpServerProxy
{
/// <summary>
/// udp服务器
/// </summary>
private UdpServer udpServer;
/// <summary>
/// 远程服务器ip
/// </summary>
private IPEndPoint iPEndPoint;
/// <summary>
/// 收到数据事件
/// </summary>
public event OnReceiveEvent OnReceive;
/// <summary>
/// 构造
/// </summary>
/// <param name="iPEndPoint"></param>
public UdpServerProxy(IPEndPoint iPEndPoint)
{
this.iPEndPoint = iPEndPoint;
udpServer = UdpServerPool.GetUdpServer(iPEndPoint);
}
/// <summary>
/// 关闭
/// </summary>
public void Close()
{
udpServer.OnReceive -= UdpReceive;
udpServer.Close();
}
/// <summary>
/// 打开
/// </summary>
public void Open()
{
udpServer.Open();
udpServer.OnReceive-= UdpReceive;
udpServer.OnReceive+= UdpReceive;
}
/// <summary>
/// udp收到数据
/// </summary>
/// <param name="remoteEP"></param>
/// <param name="data"></param>
private void UdpReceive(IPEndPoint remoteEP, byte[] data)
{
OnReceive?.Invoke(remoteEP, data);
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="data"></param>
/// <param name="remoteIpPoint"></param>
public void Send(byte[] data, IPEndPoint remoteIpPoint)
{
udpServer.Send(data, remoteIpPoint);
}
}
}

View File

@ -1,184 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Modular.Sensor.Modular.Connector.Entity;
using Wit.SDK.Modular.Sensor.Modular.Connector.Interface;
namespace Wit.SDK.Modular.Sensor.Modular.Connector.Role
{
/// <summary>
/// 串口连接器
/// </summary>
public class SPConnector :IConnector
{
/// <summary>
/// 串口
/// </summary>
public SerialPort SerialPort { get; set; }
/// <summary>
/// 连接配置
/// </summary>
public SerialPortConfig SerialPortConfig = new SerialPortConfig();
/// <summary>
/// 构造
/// </summary>
/// <param name="serialPortConfig"></param>
public SPConnector(SerialPortConfig serialPortConfig) {
SerialPortConfig = serialPortConfig;
}
/// <summary>
/// 关闭
/// </summary>
public override void Close()
{
if (SerialPort != null)
{
SerialPort.Close();
}
// 标志为关闭状态
ConnectStatus = ConnectStatus.Closed;
}
/// <summary>
/// 打开
/// </summary>
public override void Open()
{
CheckConfig();
//检查状态
if (ConnectStatus != ConnectStatus.Closed)
{
throw new Exception("打开连接失败,现在已经打开");
}
if (SerialPort == null) {
SerialPort = new SerialPort();
}
// 串口号
SerialPort.BaudRate = SerialPortConfig.BaudRate;
// 波特率
SerialPort.PortName = SerialPortConfig.PortName;
// 数据位
SerialPort.DataBits = 8;
// 停止位
SerialPort.StopBits = StopBits.One;
// 校验位
SerialPort.Parity = Parity.None;
// 读取缓存
SerialPort.ReadBufferSize = 10240 * 100;
// 写出缓存
SerialPort.WriteBufferSize = 10240 * 100;
// DTS
SerialPort.RtsEnable = SerialPortConfig.RtsEnable;
// DTR
SerialPort.DtrEnable = SerialPortConfig.DTREnable;
//打开串口
if (!SerialPort.IsOpen) {
SerialPort.Open();
}
//取消注册
SerialPort.DataReceived -= new SerialDataReceivedEventHandler(SerialDataReceive);
//注册
SerialPort.DataReceived += new SerialDataReceivedEventHandler(SerialDataReceive);
ConnectStatus = ConnectStatus.Opened;
}
/// <summary>
/// 检查配置
/// </summary>
public override void CheckConfig()
{
// 检查配置
if (SerialPortConfig == null)
{
throw new Exception("未设置任何串口连接参数");
}
if (SerialPortConfig.BaudRate < 0)
{
throw new Exception("未设置连接参数,波特率不能为负数");
}
if (SerialPortConfig.PortName == null || SerialPortConfig.PortName == string.Empty)
{
throw new Exception("未设置连接参数,串口名称不能为空");
}
}
/// <summary>
/// 收到串口数据时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SerialDataReceive(object sender, SerialDataReceivedEventArgs e)
{
SerialPort _SerialPort = (SerialPort)sender;
try
{
int _bytesToRead = _SerialPort.BytesToRead;
byte[] recvData = new byte[_bytesToRead];
_SerialPort.Read(recvData, 0, _bytesToRead);
//Debug.WriteLine(ByteArrayConvert.ByteArrayToHexString(recvData));
onReceive(recvData);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="data"></param>
public override void SendData(byte[] data)
{
// 检查状态
if (ConnectStatus != ConnectStatus.Opened)
{
throw new Exception("发送失败,未打开连接");
}
if (SerialPort.IsOpen)
{
OnSendData(data);
SerialPort.Write(data, 0, data.Length);
}
}
/// <summary>
/// 设置波特率
/// </summary>
/// <param name="baudRate"></param>
public void SetBaud(int baudRate)
{
SerialPortConfig.BaudRate = baudRate;
if (SerialPort != null) {
SerialPort.BaudRate = baudRate;
}
}
/// <summary>
/// 获得配置
/// </summary>
/// <returns></returns>
public override IConnectConfig GetConfig()
{
return SerialPortConfig;
}
}
}

View File

@ -1,166 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Wit.SDK.Modular.Sensor.Modular.Connector.Entity;
using Wit.SDK.Modular.Sensor.Modular.Connector.Interface;
namespace Wit.SDK.Modular.Sensor.Modular.Connector.Role
{
/// <summary>
/// Tcp客户端
/// </summary>
public class TcpClientConnector : IConnector
{
/// <summary>
/// TCP通讯客户端
/// </summary>
private Socket TcpClient { get; set; }
/// <summary>
/// 连接配置
/// </summary>
public TcpClientConfig TcpClientConfig = new TcpClientConfig();
/// <summary>
/// 自动任务线程
/// </summary>
private Thread AutoTaskThread = null;
/// <summary>
/// 是否运行任务线程
/// </summary>
private bool AutoTaskRun = false;
/// <summary>
/// 构造
/// </summary>
/// <param name="tcpClientConfig"></param>
public TcpClientConnector(TcpClientConfig tcpClientConfig)
{
TcpClientConfig = tcpClientConfig;
}
/// <summary>
/// 检查配置
/// </summary>
public override void CheckConfig()
{
if (TcpClientConfig == null)
{
throw new Exception("未设置任何tcp客户端连接参数");
}
if (TcpClientConfig.Port < 0 || TcpClientConfig.Port > 65535)
{
throw new Exception("未设置连接参数,端口不能小于0不能大于65535");
}
if (TcpClientConfig.IP == null || TcpClientConfig.IP == string.Empty)
{
throw new Exception("未设置连接参数,IP不能为空");
}
}
/// <summary>
/// 关闭
/// </summary>
public override void Close()
{
// 标志为关闭状态
ConnectStatus = ConnectStatus.Closed;
if (TcpClient != null)
{
TcpClient.Close();
}
if (AutoTaskThread != null)
{
AutoTaskRun = false;
AutoTaskThread.Abort();
}
}
/// <summary>
/// 获得配置
/// </summary>
/// <returns></returns>
public override IConnectConfig GetConfig()
{
return TcpClientConfig;
}
/// <summary>
/// 打开
/// </summary>
public override void Open()
{
if (TcpClient == null)
{
TcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
TcpClient.Connect(TcpClientConfig.IP, TcpClientConfig.Port);
// 读取数据线程
AutoTaskThread = new Thread(AutoTaskMethod);
AutoTaskRun = true;
AutoTaskThread.IsBackground = true;
AutoTaskThread.Start();
ConnectStatus = ConnectStatus.Opened;
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="data"></param>
public override void SendData(byte[] data)
{
//检查状态
if (ConnectStatus != ConnectStatus.Opened)
{
throw new Exception("发送失败,未打开连接");
return;
}
if (TcpClient != null && TcpClient.Connected)
{
OnSendData(data);
TcpClient.Send(data);
}
}
/// <summary>
/// 自动任务线程方法
/// </summary>
private void AutoTaskMethod()
{
while (AutoTaskRun)
{
// 休眠1毫秒防止cpu占用率过高
Thread.Sleep(1);
byte[] data = new byte[1024];
if (TcpClient.Connected)
{
int len = TcpClient.Receive(data);
if (len > 0)
{
onReceive(data.Take(len).ToArray());
}
}
else
{
ConnectStatus = ConnectStatus.Closed;
}
}
}
}
}

View File

@ -1,121 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Modular.Sensor.Modular.Connector.Entity;
using Wit.SDK.Modular.Sensor.Modular.Connector.Interface;
using Wit.SDK.Sensor.Connector.Modular.Tcp;
namespace Wit.SDK.Modular.Sensor.Modular.Connector.Role
{
/// <summary>
/// TCP服务器
/// </summary>
public class TcpServerConnector : IConnector
{
/// <summary>
/// tcp服务器
/// </summary>
private TcpServerProxy TcpServer { get; set; }
/// <summary>
/// 连接配置
/// </summary>
public TcpServerConfig TcpServerConfig = new TcpServerConfig();
/// <summary>
/// 构造
/// </summary>
/// <param name="tcpServerConfig"></param>
public TcpServerConnector(TcpServerConfig tcpServerConfig) {
TcpServerConfig = tcpServerConfig;
}
/// <summary>
/// 检查配置
/// </summary>
public override void CheckConfig()
{
if (TcpServerConfig == null)
{
throw new Exception("未设置任何tcp服务端连接参数");
}
if (TcpServerConfig.IPEndPoint == null)
{
throw new Exception("未设置监听地址和端口");
}
if (TcpServerConfig.RemoteEP == null)
{
throw new Exception("未设置远程端口");
}
}
/// <summary>
/// 关闭
/// </summary>
public override void Close()
{
if (TcpServer != null)
{
TcpServer.Close();
}
// 标志为关闭状态
ConnectStatus = ConnectStatus.Closed;
}
/// <summary>
/// 获得配置
/// </summary>
/// <returns></returns>
public override IConnectConfig GetConfig()
{
return TcpServerConfig;
}
/// <summary>
/// 打开
/// </summary>
public override void Open()
{
// 创建包含ip和端口号的网络节点对象
IPEndPoint endPoint = TcpServerConfig.IPEndPoint;
if (TcpServer == null)
{
TcpServer = new TcpServerProxy(endPoint);
}
TcpServer.Open();
TcpServer.OnReceive -= AcceptData;
TcpServer.OnReceive += AcceptData;
ConnectStatus = ConnectStatus.Opened;
}
/// <summary>
/// 接收数据
/// </summary>
/// <param name="data"></param>
private void AcceptData(EndPoint remoteEP, byte[] data)
{
if (remoteEP.ToString() == TcpServerConfig.RemoteEP.ToString()) {
onReceive(data);
}
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="data"></param>
public override void SendData(byte[] data)
{
//检查状态
if (ConnectStatus != ConnectStatus.Opened)
{
throw new Exception("发送失败,未打开连接");
}
OnSendData(data);
TcpServer.Send(TcpServerConfig.RemoteEP, data);
}
}
}

View File

@ -1,142 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Wit.SDK.Modular.Sensor.Modular.Connector.Entity;
using Wit.SDK.Modular.Sensor.Modular.Connector.Interface;
using Wit.SDK.Sensor.Connector.Modular.Udp;
using Wit.SDK.Udp;
namespace Wit.SDK.Modular.Sensor.Modular.Connector.Role
{
/// <summary>
/// UDP连接器
/// </summary>
public class UdpConnector : IConnector
{
/// <summary>
/// UDP客户端
/// </summary>
private UdpServerProxy UdpServer { get; set; }
/// <summary>
/// 连接配置
/// </summary>
public UdpConfig UdpConfig = new UdpConfig();
/// <summary>
/// 构造
/// </summary>
/// <param name="udpConfig"></param>
public UdpConnector(UdpConfig udpConfig) {
UdpConfig = udpConfig;
}
/// <summary>
/// 检查配置
/// </summary>
public override void CheckConfig()
{
if (UdpConfig == null)
{
throw new Exception("未设置任何udp连接参数");
}
if (UdpConfig.localIpPoint == null)
{
throw new Exception("未设置udp本地监听地址和端口");
}
if (UdpConfig.remoteIpPoint == null)
{
throw new Exception("未设置udp远程监听地址和端口");
}
}
/// <summary>
/// 关闭
/// </summary>
public override void Close()
{
if (UdpServer != null)
{
UdpServer.Close();
}
//if (AutoTaskThread != null)
//{
// AutoTaskRun = false;
// AutoTaskThread.Abort();
//}
// 标志为关闭状态
ConnectStatus = ConnectStatus.Closed;
}
/// <summary>
/// 获得配置
/// </summary>
/// <returns></returns>
public override IConnectConfig GetConfig()
{
return UdpConfig;
}
/// <summary>
/// 打开连接
/// </summary>
public override void Open()
{
CheckConfig();
if (UdpServer == null)
{
UdpServer = new UdpServerProxy(UdpConfig.localIpPoint);
}
else
{
UdpServer.Close();
UdpServer = new UdpServerProxy(UdpConfig.localIpPoint);
}
UdpServer.Open();
UdpServer.OnReceive -= UdpServer_OnReceive;
UdpServer.OnReceive += UdpServer_OnReceive;
ConnectStatus = ConnectStatus.Opened;
}
/// <summary>
/// 接收udp数据
/// </summary>
/// <param name="remoteEP"></param>
/// <param name="data"></param>
private void UdpServer_OnReceive(IPEndPoint remoteEP, byte[] data)
{
if (UdpConfig.remoteIpPoint.ToString().Equals(remoteEP.ToString())) {
onReceive(data);
}
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="data"></param>
public override void SendData(byte[] data)
{
//检查状态
if (ConnectStatus != ConnectStatus.Opened)
{
throw new Exception("发送失败,未打开连接");
}
OnSendData(data);
UdpServer.Send(data, UdpConfig.remoteIpPoint);
}
}
}

View File

@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Sensor.Device.Constant
{
/// <summary>
/// 内部的键值
/// </summary>
public class InnerKeys
{
// 串口端口
public static string ComPort { get; } = "_ComPort";
// 串口can波特率
public static string ComBaud { get; } = "_ComBaud";
// 设备地址Key值
public static string ADDR_KEY { get; } = "ADDR";
// can波特率
public static string CanBaud { get; } = "_CanBaud";
// 数据包速率
public static string PacketRate { get; } = "_PacketRate";
// 数据大小速率
public static string DataSizeRate { get; } = "_DataSizeRate";
}
}

View File

@ -1,203 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Modular.Sensor.Device;
using Wit.SDK.Sensor.Device.Context;
namespace Wit.SDK.Modular.Sensor.DeviceManager
{
/// <summary>
/// 设备管理器
/// </summary>
public class DeviceManager: DeviceManagerEvents
{
#region
// 实例
private static DeviceManager instance;
/// <summary>
/// 获得实例
/// </summary>
/// <returns></returns>
public static DeviceManager GetInstance()
{
if (instance == null)
{
instance = new DeviceManager();
}
return instance;
}
/// <summary>
/// 私有构造
/// </summary>
private DeviceManager()
{
}
#endregion
/// <summary>
/// 当前设备
/// </summary>
public List<DeviceModel> DeviceModels
{
get
{
return DeviceDict.Values.ToList();
}
}
/// <summary>
/// 设备字典
/// </summary>
public ConcurrentDictionary<string,DeviceModel> DeviceDict = new ConcurrentDictionary<string,DeviceModel>();
/// <summary>
/// 第一个设备
/// </summary>
public DeviceModel FirstDeviceModel
{
get
{
if (DeviceDict.Count == 0)
{
return null;
}
return DeviceDict.ElementAt(0).Value;
}
}
/// <summary>
/// 用设备名称查找设备
/// </summary>
/// <param name="deviceId"></param>
/// <returns></returns>
public DeviceModel FindDeviceById(string deviceId)
{
DeviceModel result;
if (DeviceDict.TryGetValue(deviceId, out result)) {
return result;
}
return null;
}
/// <summary>
/// 添加设备
/// </summary>
public void AppendDevice(DeviceModel deviceModel) {
if (FindDeviceById(deviceModel.DeviceId) == null) {
DeviceDict.TryAdd(deviceModel.DeviceId, deviceModel);
InvokeOnAppendDevice(deviceModel);
deviceModel.OnClosed += DeviceModel_OnClosed;
deviceModel.OnOpened += DeviceModel_OnOpened;
}
}
/// <summary>
/// 设备打开事件
/// </summary>
/// <param name="deviceModel"></param>
private void DeviceModel_OnOpened(DeviceModel deviceModel)
{
InvokeOnOpenDevice(deviceModel);
}
/// <summary>
/// 设备关闭事件
/// </summary>
/// <param name="deviceModel"></param>
private void DeviceModel_OnClosed(DeviceModel deviceModel)
{
InvokeOnCloseDevice(deviceModel);
}
/// <summary>
/// 添加一批设备
/// </summary>
/// <param name="deviceModel"></param>
public void AppendDevice(List<DeviceModel> deviceModels)
{
for (int i = 0; i < deviceModels.Count; i++)
{
AppendDevice(deviceModels[i]);
}
}
/// <summary>
/// 移除设备
/// </summary>
public void RemoveDevice(DeviceModel deviceModel) {
CloseDevice(deviceModel.DeviceId);
if (ContainsDevice(deviceModel)) {
DeviceModel de;
DeviceDict.TryRemove(deviceModel.DeviceId,out de);
InvokeOnRemoveDevice(deviceModel);
}
}
/// <summary>
/// 关闭设备
/// </summary>
public void CloseDevice(string deviceId)
{
DeviceModel deviceModel = FindDeviceById(deviceId);
if (deviceModel != null) {
CloseDevice(deviceModel);
}
}
/// <summary>
/// 关闭设备
/// </summary>
/// <param name="deviceModel"></param>
public void CloseDevice(DeviceModel deviceModel)
{
deviceModel.CloseDevice();
}
/// <summary>
/// 清除所有设备
/// </summary>
public void ClearDevice()
{
List<DeviceModel> copyList = new List<DeviceModel> ();
// 关闭所有设备
for (int i = 0; i < DeviceDict.Count; i++)
{
copyList.Add(DeviceDict.ElementAt(i).Value);
}
for (int i = 0; i < copyList.Count; i++)
{
DeviceModel deviceModel = copyList[i];
RemoveDevice(deviceModel);
}
}
/// <summary>
/// 是否存在某个设备
/// </summary>
/// <param name="deviceModel"></param>
/// <returns></returns>
public bool ContainsDevice(DeviceModel deviceModel)
{
return FindDeviceById(deviceModel.DeviceId)!= null;
}
/// <summary>
/// 打开设备
/// </summary>
/// <param name="deviceModel"></param>
public void OpenDevice(DeviceModel deviceModel)
{
AppendDevice(deviceModel);
deviceModel.OpenDevice();
}
}
}

View File

@ -1,76 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Wit.SDK.Device.Sensor.Device.Utils;
using Wit.SDK.Modular.Sensor.Device;
namespace Wit.SDK.Sensor.Device.Context
{
/// <summary>
/// 设备管理器事件
/// </summary>
public abstract class DeviceManagerEvents: ReadDataSleepManager
{
/// <summary>
/// 关闭设备
/// </summary>
/// <param name="deviceModel"></param>
public delegate void CloseDeviceEvent(DeviceModel deviceModel);
public event CloseDeviceEvent OnCloseDevice;
public void InvokeOnCloseDevice(DeviceModel deviceModel) {
new Thread(() =>
{
OnCloseDevice?.Invoke(deviceModel);
})
{ IsBackground = true }.Start();
}
/// <summary>
/// 打开设备
/// </summary>
/// <param name="deviceModel"></param>
public delegate void OpenDeviceEvent(DeviceModel deviceModel);
public event OpenDeviceEvent OnOpenDevice;
public void InvokeOnOpenDevice(DeviceModel deviceModel)
{
new Thread(() =>
{
OnOpenDevice?.Invoke(deviceModel);
})
{ IsBackground = true }.Start();
}
/// <summary>
/// 移除设备
/// </summary>
/// <param name="deviceModel"></param>
public delegate void RemoveDeviceEvent(DeviceModel deviceModel);
public event RemoveDeviceEvent OnRemoveDevice;
public void InvokeOnRemoveDevice(DeviceModel deviceModel)
{
new Thread(() =>
{
OnRemoveDevice?.Invoke(deviceModel);
})
{ IsBackground = true }.Start();
}
/// <summary>
/// 添加设备
/// </summary>
/// <param name="deviceModel"></param>
public delegate void AppendDeviceEvent(DeviceModel deviceModel);
public event AppendDeviceEvent OnAppendDevice;
public void InvokeOnAppendDevice(DeviceModel deviceModel)
{
new Thread(() =>
{
OnAppendDevice?.Invoke(deviceModel);
})
{ IsBackground = true }.Start();
}
}
}

View File

@ -1,63 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Sensor.Device.Interfaces;
namespace Wit.SDK.Device.Sensor.Device.Utils
{
/// <summary>
/// 读取数据休眠事件
/// </summary>
public interface IReadSleepEvent {
void OnSleep();
}
/// <summary>
/// 读取数据休眠管理器
/// </summary>
public class ReadDataSleepManager
{
private static List<IReadSleepEvent> sleeps = new List<IReadSleepEvent>();
/// <summary>
/// 添加设备组件
/// </summary>
public static void AddReadSleepEvent(IReadSleepEvent e)
{
if (sleeps.Contains(e))
{
return;
}
sleeps.Add(e);
}
/// <summary>
/// 移除设备组件
/// </summary>
public static void RemoveReadSleepEvent(IReadSleepEvent e)
{
sleeps.Remove(e);
}
/// <summary>
/// 调用休眠事件
/// </summary>
public static void InvokeOnSleep()
{
for (int i = 0; i < sleeps.Count; i++)
{
try
{
sleeps[i].OnSleep();
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
}
}
}

View File

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Device.Device.Device.DKey
{
public class ByteKey : DataKey
{
public ByteKey(string key) : base(key)
{
}
public ByteKey(string key, string name, string unit) : base(key, name, unit)
{
}
}
}

View File

@ -1,31 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Device.Device.Device.DKey
{
/// <summary>
/// 数据键值
/// </summary>
public class DataKey
{
public string Key { get; set; } = "";
public string Name { get; set; } = "";
public string Unit { get; set; } = "";
public DataKey(string key) {
this.Key = key;
}
public DataKey(string key,string name,string unit)
{
this.Key = key;
this.Name = name;
this.Unit = unit;
}
}
}

View File

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Device.Device.Device.DKey
{
public class DoubleKey : DataKey
{
public DoubleKey(string key) : base(key)
{
}
public DoubleKey(string key, string name, string unit) : base(key, name, unit)
{
}
}
}

View File

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Device.Device.Device.DKey
{
public class FloatKey : DataKey
{
public FloatKey(string key) : base(key)
{
}
public FloatKey(string key, string name, string unit) : base(key, name, unit)
{
}
}
}

View File

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Device.Device.Device.DKey
{
public class IntKey : DataKey
{
public IntKey(string key) : base(key)
{
}
public IntKey(string key, string name, string unit) : base(key, name, unit)
{
}
}
}

View File

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Device.Device.Device.DKey
{
public class ShortKey : DataKey
{
public ShortKey(string key) : base(key)
{
}
public ShortKey(string key, string name, string unit) : base(key, name, unit)
{
}
}
}

View File

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Device.Device.Device.DKey
{
public class StringKey : DataKey
{
public StringKey(string key) : base(key)
{
}
public StringKey(string key, string name, string unit) : base(key, name, unit)
{
}
}
}

View File

@ -1,369 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Device.Device.Device.DKey;
using Wit.SDK.Modular.Sensor.Modular.DataProcessor.Interface;
using Wit.SDK.Sensor.Device;
using Wit.SDK.Sensor.Device.Constant;
namespace Wit.SDK.Modular.Sensor.Device
{
/// <summary>
/// 设备数据源操作
/// </summary>
public class DeviceDataSource : DeviceEvents
{
/// <summary>
/// 传感器数据
/// </summary>
public Dictionary<string, object> DeviceData { get; } = new Dictionary<string, object>();
/// <summary>
/// 设备的历史数据
/// </summary>
public Dictionary<string, List<string>> HistoryDeviceData { get; } = new Dictionary<string, List<string>>();
#region
/// <summary>
/// 删除一个key
/// </summary>
public bool RemoveKey(string key)
{
return DeviceData.Remove(key);
}
/// <summary>
/// 删除所有设备的key上位机的保留key不会清除
/// </summary>
public bool ClearDeviceKey()
{
for (int i = 0; i < DeviceData.Count; i++)
{
KeyValuePair<string, object> keyvalue = DeviceData.ElementAt(i);
//如果不是保留的key值那么都清除
if (!InnerKeys.ADDR_KEY.Equals(keyvalue.Key))
{
DeviceData.Remove(keyvalue.Key);
i--;
}
}
return true;
}
/// <summary>
/// 获取设备数据
/// </summary>
/// <param name="key">需要的数据</param>
/// <returns>数据的值,如果没有就返回null</returns>
public string GetDeviceData(string key)
{
if (DeviceData.ContainsKey(key))
{
return DeviceData[key].ToString();
}
else
{
return null;
}
}
/// <summary>
/// 获取设备历史数据
/// </summary>
/// <param name="i">历史第几个数据</param>
/// <param name="key">数据key</param>
/// <returns>返回数据如果没有数据就返回null</returns>
public string GetHistoryDeviceData(int i, string key)
{
if (i < 0)
{
return null;
}
if (HistoryDeviceData.ContainsKey(key))
{
int position = HistoryDeviceData[key].Count - 1 - i;
if (position >= 0)
{
return HistoryDeviceData[key][position];
}
else
{
return null;
}
}
else
{
return null;
}
}
/// <summary>
/// 设置数据
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void SetDeviceData(string key, string value)
{
Put(key, value);
}
/// <summary>
/// 设置设备地址
/// </summary>
/// <param name="addr"></param>
public void SetAddr(string addr) {
SetDeviceData(InnerKeys.ADDR_KEY, addr);
}
/// <summary>
/// 获得地址
/// </summary>
/// <returns></returns>
public string GetAddr()
{
return GetDeviceData(InnerKeys.ADDR_KEY);
}
#endregion
/// <summary>
/// 添加数据
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void Put(string key, object value)
{
// 当前数据
DeviceData[key] = value;
if (this is DeviceModel)
{
// Key刷新通知
InvokeOnKeyUpdate((DeviceModel)this, key, value);
}
//// 保存到历史数据
//if (HistoryDeviceData.ContainsKey(key))
//{
// HistoryDeviceData[key].Add(value);
// if (HistoryDeviceData[key].Count > 200)
// {
// HistoryDeviceData[key].RemoveAt(0);
// }
//}
//else
//{
// HistoryDeviceData[key] = new List<string>() { value };
//}
}
/// <summary>
/// 设置数据
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void SetDeviceData(ByteKey key, byte value) {
Put(key.Key, value);
}
/// <summary>
/// 获得数据
/// </summary>
/// <param name="dataKey"></param>
/// <returns></returns>
public byte? GetDeviceData(ByteKey dataKey) {
string key = dataKey.Key;
if (DeviceData.ContainsKey(key))
{
object o = DeviceData[key];
if (o is byte) {
return (byte)o;
}
return null;
}
else
{
return null;
}
}
/// <summary>
/// 设置数据
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void SetDeviceData(DoubleKey key, double value)
{
Put(key.Key, value);
}
/// <summary>
/// 获得数据
/// </summary>
/// <param name="dataKey"></param>
/// <returns></returns>
public double? GetDeviceData(DoubleKey dataKey)
{
string key = dataKey.Key;
if (DeviceData.ContainsKey(key))
{
object o = DeviceData[key];
if (o is double)
{
return (double)o;
}
return null;
}
else
{
return null;
}
}
/// <summary>
/// 设置数据
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void SetDeviceData(FloatKey key, float value)
{
Put(key.Key, value);
}
/// <summary>
/// 获得数据
/// </summary>
/// <param name="dataKey"></param>
/// <returns></returns>
public float? GetDeviceData(FloatKey dataKey)
{
string key = dataKey.Key;
if (DeviceData.ContainsKey(key))
{
object o = DeviceData[key];
if (o is float)
{
return (float)o;
}
return null;
}
else
{
return null;
}
}
/// <summary>
/// 设置数据
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void SetDeviceData(IntKey key, int value)
{
Put(key.Key, value);
}
/// <summary>
/// 获得数据
/// </summary>
/// <param name="dataKey"></param>
/// <returns></returns>
public int? GetDeviceData(IntKey dataKey)
{
string key = dataKey.Key;
if (DeviceData.ContainsKey(key))
{
object o = DeviceData[key];
if (o is int)
{
return (int)o;
}
return null;
}
else
{
return null;
}
}
/// <summary>
/// 设置数据
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void SetDeviceData(ShortKey key, short value)
{
Put(key.Key, value);
}
/// <summary>
/// 获得数据
/// </summary>
/// <param name="dataKey"></param>
/// <returns></returns>
public short? GetDeviceData(ShortKey dataKey)
{
string key = dataKey.Key;
if (DeviceData.ContainsKey(key))
{
object o = DeviceData[key];
if (o is short)
{
return (short)o;
}
return null;
}
else
{
return null;
}
}
/// <summary>
/// 设置数据
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void SetDeviceData(StringKey key, string value)
{
Put(key.Key, value);
}
/// <summary>
/// 获得数据
/// </summary>
/// <param name="dataKey"></param>
/// <returns></returns>
public string GetDeviceData(StringKey dataKey)
{
string key = dataKey.Key;
if (DeviceData.ContainsKey(key))
{
object o = DeviceData[key];
if (o is string)
{
return (string)o;
}
return null;
}
else
{
return null;
}
}
}
}

View File

@ -1,271 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Markup;
using Wit.SDK.Modular.Sensor.Device;
using Wit.SDK.Modular.Sensor.Modular.DataProcessor.Interface;
using Wit.SDK.Sensor.Device.Interfaces;
namespace Wit.SDK.Sensor.Device
{
/// <summary>
/// 设备事件
/// </summary>
public abstract class DeviceEvents
{
/// <summary>
/// 设备组件列表
/// </summary>
private List<IDeviceComponent> DeviceComponents = new List<IDeviceComponent>();
/// <summary>
/// 监听的key值改变事件
/// </summary>
/// <param name="deviceModel"></param>
public delegate void OnListenKeyUpdateHandler(DeviceModel deviceModel);
public event OnListenKeyUpdateHandler OnListenKeyUpdate;
/// <summary>
/// 收到数据事件
/// </summary>
/// <param name="deviceModel"></param>
public delegate void OnReceiveDataHandler(DeviceModel deviceModel, byte[] data);
public event OnReceiveDataHandler OnReceiveData;
/// <summary>
/// 读取数据事件
/// </summary>
public delegate void OnReadDataEvent(DeviceModel deviceModel, byte[] sendData, int delay = -1);
public event OnReadDataEvent OnReadData;
/// <summary>
/// 发送数据事件
/// </summary>
public delegate void OnSendDataEvent(DeviceModel deviceModel, byte[] data);
public event OnSendDataEvent OnSendData;
/// <summary>
/// key刷新事件
/// </summary>
/// <param name="deviceModel"></param>
public delegate void OnKeyUpdateHandler(DeviceModel deviceModel, string key, object value);
/// <summary>
/// key刷新事件
/// </summary>
public event OnKeyUpdateHandler OnKeyUpdate;
/// <summary>
/// 打开后事件
/// </summary>
/// <param name="deviceModel"></param>
public delegate void OpenedEvent(DeviceModel deviceModel);
public event OpenedEvent OnOpened;
/// <summary>
/// 关闭后事件
/// </summary>
/// <param name="deviceModel"></param>
public delegate void ClosedEvent(DeviceModel deviceModel);
public event ClosedEvent OnClosed;
/// <summary>
/// 添加设备组件
/// </summary>
public void AddComponent(IDeviceComponent compo) {
if (DeviceComponents.Contains(compo)) {
return;
}
DeviceComponents.Add(compo);
}
/// <summary>
/// 移除设备组件
/// </summary>
public void RemoveComponent(IDeviceComponent compo)
{
DeviceComponents.Remove(compo);
compo.OnRemove();
}
/// <summary>
/// 调用关闭设备事件
/// </summary>
/// <param name="deviceModel"></param>
public void InvokeOnClosed(DeviceModel deviceModel)
{
new Thread(() =>
{
for (int i = 0; i < DeviceComponents.Count; i++)
{
try
{
var compo = DeviceComponents[i];
compo.OnClose(deviceModel);
}
catch (Exception ex) {
Debug.WriteLine(ex);
}
}
OnClosed?.Invoke(deviceModel);
})
{ IsBackground = true }.Start();
}
/// <summary>
/// 调用键值更新事件
/// </summary>
/// <param name="deviceModel"></param>
/// <param name="key"></param>
/// <param name="value"></param>
public void InvokeOnKeyUpdate(DeviceModel deviceModel,string key,object value) {
for (int i = 0; i < DeviceComponents.Count; i++)
{
try
{
var compo = DeviceComponents[i];
compo.OnKeyUpdate(deviceModel,key,value);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
OnKeyUpdate?.Invoke(deviceModel,key,value);
}
/// <summary>
/// 调用监听键值更新事件
/// </summary>
/// <param name="deviceModel"></param>
public void InvokeOnListenKeyUpdate(DeviceModel deviceModel)
{
for (int i = 0; i < DeviceComponents.Count; i++)
{
try
{
var compo = DeviceComponents[i];
compo.OnUpdate(deviceModel);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
OnListenKeyUpdate?.Invoke(deviceModel);
}
/// <summary>
/// 调用收到数据事件
/// </summary>
/// <param name="deviceModel"></param>
/// <param name="data"></param>
public void InvokeOnReceiveData(DeviceModel deviceModel, byte[] data)
{
for (int i = 0; i < DeviceComponents.Count; i++)
{
try
{
var compo = DeviceComponents[i];
compo.OnReceiveData(deviceModel,data);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
OnReceiveData?.Invoke(deviceModel,data);
}
/// <summary>
/// 调用读取数据事件
/// </summary>
/// <param name="deviceModel"></param>
/// <param name="data"></param>
/// <param name="delay"></param>
public void InvokeOnReadData(DeviceModel deviceModel, byte[] data, int delay)
{
for (int i = 0; i < DeviceComponents.Count; i++)
{
try
{
var compo = DeviceComponents[i];
compo.OnReadData(deviceModel, data, delay);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
OnReadData?.Invoke(deviceModel, data, delay);
}
/// <summary>
/// 调用发送设备事件
/// </summary>
/// <param name="deviceModel"></param>
/// <param name="data"></param>
public void InvokeOnSendData(DeviceModel deviceModel, byte[] data)
{
new Thread(() =>
{
for (int i = 0; i < DeviceComponents.Count; i++)
{
try
{
var compo = DeviceComponents[i];
compo.OnSend(deviceModel, data);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
OnSendData?.Invoke(deviceModel, data);
})
{ IsBackground = true }.Start();
}
/// <summary>
/// 调用打开设备事件
/// </summary>
/// <param name="deviceModel"></param>
public void InvokeOnOpened(DeviceModel deviceModel) {
new Thread(() =>
{
for (int i = 0; i < DeviceComponents.Count; i++)
{
try
{
var compo = DeviceComponents[i];
compo.OnOpen(deviceModel);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
OnOpened?.Invoke(deviceModel);
})
{ IsBackground = true }.Start();
}
}
}

View File

@ -1,413 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using Wit.SDK.Device.Sensor.Device.Utils;
using Wit.SDK.Modular.Sensor.Device.Entity;
using Wit.SDK.Modular.Sensor.Modular.Connector.Interface;
using Wit.SDK.Modular.Sensor.Modular.Connector.Role;
using Wit.SDK.Modular.Sensor.Modular.DataProcessor.Interface;
using Wit.SDK.Modular.Sensor.Modular.ProtocolResolver.Interface;
using Wit.SDK.Sensor.Device.Interfaces;
namespace Wit.SDK.Modular.Sensor.Device
{
/// <summary>
/// 基础设备
/// </summary>
public class DeviceModel : DeviceDataSource, DataReceivedInterface
{
/// <summary>
/// 设备ID设备的唯一名称
/// </summary>
public string DeviceId { get; set; }
/// <summary>
/// 设备名称
/// </summary>
public string DeviceName { get; set; }
/// <summary>
/// 是否是回放的设备
/// </summary>
public bool IsPlaybackDevice { get; set; }
/// <summary>
/// 连接对象
/// </summary>
public IConnector Connector { get; set; }
/// <summary>
/// 监听Key值
/// </summary>
public string ListenerKey { get; set; } = "";
/// <summary>
/// 构造方法
/// </summary>
public DeviceModel(string deviceId,string deviceName,IProtocolResolver protocolResolver, IDataProcessor dataProcessor, string listenerKey)
{
ListenerKey = listenerKey == null ? "": listenerKey;
DeviceName = deviceName;
DeviceId = deviceId;
// 设备配置
DeviceOption = new DeviceOption()
{
ListenerKey = ListenerKey,
DataProcessorType = dataProcessor != null? dataProcessor.GetType(): null,
ProtocolResolverType = protocolResolver != null? protocolResolver.GetType(): null,
};
// 注册计数据速率组件
RateCalculationCompo rateCalculationCompo = new RateCalculationCompo();
AddComponent(rateCalculationCompo);
// 注册数据处理器
AddComponent(dataProcessor);
// 注册协议解析器
AddComponent(protocolResolver);
this.OnKeyUpdate += DeviceModel_OnKeyUpdate;
}
/// <summary>
/// 键值更新时
/// </summary>
/// <param name="deviceModel"></param>
/// <param name="key"></param>
/// <param name="value"></param>
private void DeviceModel_OnKeyUpdate(DeviceModel deviceModel, string key, object value)
{
// 触发实时数据更新
if (ListenerKey.Equals(key) || string.IsNullOrEmpty(ListenerKey))
{
// 键值改变事件
InvokeOnListenKeyUpdate(this);
}
}
#region
/// <summary>
/// 是否打开
/// </summary>
private bool _IsOpen { get; set; } = false;
/// <summary>
/// 是否打开
/// </summary>
public bool IsOpen { get { return _IsOpen; } }
/// <summary>
/// 是否正在关闭
/// </summary>
public bool Closing { get; set; }
/// <summary>
/// 设备配置
/// </summary>
public DeviceOption DeviceOption { get; private set; }
/// <summary>
/// 打开设备
/// </summary>
public void OpenDevice()
{
//如果是回放的设备就直接标为打开,不用做其它事情
if (IsPlaybackDevice)
{
// 标记为已经打开
_IsOpen = true;
InvokeOnOpened(this);
return;
}
if (Connector != null) {
//注销接收数据
Connector.LogoutReceivedObj(this);
//注册接收数据
Connector.RegisterReceivedObj(this);
//如果核心连接没有打开就打开连接
if (Connector.IsOpen() == false) Connector.Open();
_IsOpen = true;
InvokeOnOpened(this);
return;
}
else
{
_IsOpen = false;
throw new Exception("打开设备错误,没有coreConnenct对象");
}
}
/// <summary>
/// 重新打开
/// </summary>
/// <param name="v"></param>
public void ReOpen()
{
CloseDevice();
OpenDevice();
}
/// <summary>
/// 关闭设备
/// </summary>
public void CloseDevice()
{
Closing = true;
if (Connector != null)
{
//注销接收数据
Connector.LogoutReceivedObj(this);
//关闭连接
Connector.Close();
}
if (_IsOpen) {
// 关闭事件
InvokeOnClosed(this);
}
_IsOpen = false;
Closing = false;
}
/// <summary>
/// 设置串口波特率
/// </summary>
/// <param name="baudRate"></param>
public void SetSerialPortBaud(int baudRate)
{
if (Connector is SPConnector) {
SPConnector sP = Connector as SPConnector;
sP.SetBaud(baudRate);
}
}
#endregion
#region
/// <summary>
/// 发送数据锁
/// </summary>
private readonly object SendLock = new object();
/// <summary>
/// 接收数据锁
/// </summary>
private readonly object ReceiveLock = new object();
/// <summary>
/// 是否接收返回数据
/// </summary>
private bool BolWaitReturn;
/// <summary>
/// 返回的数据
/// </summary>
private List<byte> ReturnDataBuffer = new List<byte>();
/// <summary>
/// 发送数据,不等待返回
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public bool SendData(byte[] data) {
byte[] outData = new byte[0];
return SendData(data, out outData, false);
}
/// <summary>
/// 发送数据,并等待返回
/// </summary>
/// <param name="data">发送的数据</param>
/// <param name="returnData">返回的数据</param>
/// <param name="isWaitReturn">是否等待返回</param>
/// <param name="waitTime">等待时间</param>
/// <param name="repetition">等待次数</param>
/// <returns></returns>
public bool SendData(byte[] data, out byte[] returnData, bool isWaitReturn = false, int waitTime = 100, int repetition = 1) {
// 发送数据锁
lock (SendLock)
{
byte[] rtnData = new byte[0];
bool success = false;
// 标记线程释是否结束
bool newThreadRuning = true;
// 开启线程池发送数据
ThreadPool.QueueUserWorkItem(new WaitCallback((p) =>
{
try
{
success = SendDataTh(data, out rtnData, isWaitReturn, waitTime, repetition);
}
catch (Exception ex) {
Debug.WriteLine(ex.Message);
Debug.WriteLine(ex.StackTrace);
}
// 标记线程结束
newThreadRuning = false;
}), null);
// 线程没有结束就一直等
while (newThreadRuning) {
Thread.Sleep(1);
// 防止ui线程卡住
ReadDataSleepManager.InvokeOnSleep();
}
returnData = rtnData;
return success;
}
}
/// <summary>
/// 发送数据,可以有返回值
/// </summary>
/// <param name="data">发送的数据</param>
/// <param name="returnData">返回的数据</param>
/// <param name="isWaitReturn">是否等待返回</param>
/// <param name="waitTime">等待时间</param>
/// <param name="repetition">等待次数</param>
/// <returns></returns>
private bool SendDataTh(byte[] data, out byte[] returnData, bool isWaitReturn = false, int waitTime = 100, int repetition = 1)
{
// 如果正在关闭就不发送
if (Closing ||
Connector == null ||
Connector.IsOpen() == false
)
{
returnData = new byte[0];
return false;
}
try
{
ReturnDataBuffer.Clear();
BolWaitReturn = isWaitReturn;
returnData = new byte[0];
int count = 0;
if (BolWaitReturn)
{
while (count < repetition && BolWaitReturn)
{
count++;
// 发送数据
Connector.SendData(data);
// 发送数据事件
InvokeOnSendData(this, data);
Thread.Sleep(waitTime);
returnData = ReturnDataBuffer.ToArray();
if (returnData != null && returnData.Length > 0)
{
break;
}
}
}
else
{
InvokeOnSendData(this, data);
// 发送数据
Connector.SendData(data);
}
BolWaitReturn = false;
return true;
}
catch
{
returnData = new byte[0];
BolWaitReturn = false;
return false;
}
}
/// <summary>
/// 使用数据解析器发送数据
/// </summary>
public bool ReadData(byte[] data, int delay = -1)
{
if (this.IsPlaybackDevice)
{
return false;
}
try
{
// 发送数据
InvokeOnReadData(this, data, delay);
return true;
}
catch (Exception e) {
Debug.WriteLine("发送数据出错:" + e.Message);
Debug.WriteLine(e.StackTrace);
return false;
}
}
/// <summary>
/// 异步发送数据
/// </summary>
/// <param name="data"></param>
/// <param name="delay"></param>
public void AsyncReadData(byte[] data, Action callback, int delay = -1)
{
if (this.IsPlaybackDevice) { return; }
try
{
ThreadPool.QueueUserWorkItem(new WaitCallback((p) =>
{
// 发送数据
InvokeOnReadData(this, data, delay);
// 调用回调方法
callback.Invoke();
}), null);
}
catch (Exception e)
{
Debug.WriteLine("发送数据出错:" + e.Message);
Debug.WriteLine(e.StackTrace);
}
}
/// <summary>
/// 收到数据
/// </summary>
/// <param name="data"></param>
public void OnDataReceived(byte[] data) {
// 如果正在关闭就不接收数据
if (Closing)
{
return;
}
//如果需要返回
if (BolWaitReturn)
{
try
{
ReturnDataBuffer.AddRange(data);
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
// 线程锁
lock (ReceiveLock)
{
// 触发原始数据事件
InvokeOnReceiveData(this, data);
}
}
#endregion
}
}

View File

@ -1,42 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Modular.Sensor.Modular.DataProcessor.Interface;
using Wit.SDK.Modular.Sensor.Modular.ProtocolResolver.Interface;
namespace Wit.SDK.Modular.Sensor.Device.Entity
{
/// <summary>
/// 设备配置
/// </summary>
[Serializable]
public class DeviceOption
{
/// <summary>
/// 协议解析器类型
/// </summary>
public Type ProtocolResolverType { get; set; } = null;
/// <summary>
/// 数据解析器类型
/// </summary>
public Type DataProcessorType { get; set; } = null;
/// <summary>
/// 数据
/// </summary>
public string ListenerKey { get; set; } = null;
/// <summary>
/// 数据
/// </summary>
public List<string> ListenerKeyList { get; set; } = null;
/// <summary>
/// 默认的设备数据
/// </summary>
public Dictionary<string,string> DefaultData = new Dictionary<string, string>();
}
}

View File

@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Sensor.Device.Enum
{
/// <summary>
/// 数据类型
/// </summary>
public enum DataType
{
/// <summary>
/// 浮点型
/// </summary>
Double,
/// <summary>
/// 整型
/// </summary>
Int,
/// <summary>
/// 字符串型
/// </summary>
String,
/// <summary>
/// 日期时间
/// </summary>
DateTime
}
}

View File

@ -1,65 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Modular.Sensor.Device;
namespace Wit.SDK.Sensor.Device.Interfaces
{
/// <summary>
/// 设备组件接口
/// </summary>
public interface IDeviceComponent
{
/// <summary>
/// 设备打开时
/// </summary>
/// <param name="deviceModel"></param>
void OnOpen(DeviceModel deviceModel);
/// <summary>
/// 设备关闭时
/// </summary>
/// <param name="deviceModel"></param>
void OnClose(DeviceModel deviceModel);
/// <summary>
/// 被从设备中移除时
/// </summary>
void OnRemove();
/// <summary>
/// 收到数据时
/// </summary>
/// <param name="deviceModel"></param>
/// <param name="data"></param>
void OnReceiveData(DeviceModel deviceModel, byte[] data);
/// <summary>
/// 键值更新时
/// </summary>
/// <param name="deviceModel"></param>
/// <param name="key"></param>
/// <param name="value"></param>
void OnKeyUpdate(DeviceModel deviceModel,string key, object value);
/// <summary>
/// 监听键值更新时
/// </summary>
/// <param name="deviceModel"></param>
void OnUpdate(DeviceModel deviceModel);
/// <summary>
/// 读取数据时
/// </summary>
void OnReadData(DeviceModel deviceModel, byte[] sendData, int delay = -1);
/// <summary>
/// 发送数据时
/// </summary>
/// <param name="deviceModel"></param>
/// <param name="data"></param>
void OnSend(DeviceModel deviceModel, byte[] data);
}
}

View File

@ -1,115 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Wit.SDK.Modular.Sensor.Device;
using Wit.SDK.Sensor.Device.Constant;
namespace Wit.SDK.Sensor.Device.Interfaces
{
/// <summary>
/// 速率计算组件
/// </summary>
public class RateCalculationCompo : IDeviceComponent
{
/// <summary>
/// 数据大小速率
/// </summary>
private int DataSizeRate = 0;
/// <summary>
/// 数据包速率
/// </summary>
private int PacketRate = 0;
/// <summary>
/// 设备模型
/// </summary>
private DeviceModel deviceModel;
/// <summary>
/// 是否在运行
/// </summary>
private bool IsRun = true;
/// <summary>
/// 线程
/// </summary>
private Thread thread;
/// <summary>
/// 设备打开时
/// </summary>
/// <param name="deviceModel"></param>
public void OnOpen(DeviceModel deviceModel)
{
this.deviceModel = deviceModel;
IsRun = true;
thread = new Thread(MyThread) { IsBackground = true };
thread.Start();
}
/// <summary>
/// 线程
/// </summary>
private void MyThread()
{
while (IsRun) {
PacketRate = 0;
DataSizeRate = 0;
Thread.Sleep(1000);
deviceModel.SetDeviceData(InnerKeys.PacketRate,PacketRate.ToString());
deviceModel.SetDeviceData(InnerKeys.DataSizeRate,DataSizeRate.ToString());
}
}
/// <summary>
/// 设备关闭时
/// </summary>
/// <param name="deviceModel"></param>
public void OnClose(DeviceModel deviceModel)
{
IsRun = false;
try
{
if (thread != null) {
thread.Abort();
}
}
catch (Exception ex) {
Debug.WriteLine(ex);
}
}
public void OnKeyUpdate(DeviceModel deviceModel, string key, object value)
{
}
public void OnUpdate(DeviceModel deviceModel)
{
PacketRate++;
}
public void OnReceiveData(DeviceModel deviceModel, byte[] data)
{
DataSizeRate += data.Length;
}
public void OnReadData(DeviceModel deviceModel, byte[] sendData, int delay = -1)
{
}
public void OnSend(DeviceModel deviceModel, byte[] data)
{
}
public void OnRemove()
{
}
}
}

View File

@ -1,101 +0,0 @@
using System;
using Wit.SDK.Modular.Sensor.Device.Entity;
using Wit.SDK.Modular.Sensor.Modular.DataProcessor.Interface;
using Wit.SDK.Modular.Sensor.Modular.ProtocolResolver.Interface;
namespace Wit.SDK.Modular.Sensor.Device.Utils
{
/// <summary>
/// 设备模型工厂
/// </summary>
public class DeviceModelFactory
{
/// <summary>
/// 随机设备id
/// </summary>
/// <returns></returns>
public static string RandomDeviceId()
{
return Guid.NewGuid().ToString();
}
/// <summary>
/// 从配置创建设备模型
/// </summary>
/// <param name="deviceOption">设备配置</param>
/// <returns></returns>
public static DeviceModel CreateDeviceModel(string deviceId, string deviceName, DeviceOption deviceOption)
{
if (string.IsNullOrEmpty(deviceId))
{
throw new Exception("无法创建设备,设备没有id");
}
IProtocolResolver protocolResolver = null;
IDataProcessor dataProcessor = null;
try
{
if (deviceOption.ProtocolResolverType != null)
protocolResolver = (IProtocolResolver)deviceOption.ProtocolResolverType.Assembly.CreateInstance(deviceOption.ProtocolResolverType.FullName);
}
catch (Exception ex)
{
throw new Exception("无法创建协议解析器", ex);
}
try
{
if (deviceOption.DataProcessorType != null)
dataProcessor = (IDataProcessor)deviceOption.DataProcessorType.Assembly.CreateInstance(deviceOption.DataProcessorType.FullName);
}
catch (Exception ex)
{
throw new Exception("无法创建数据处理器", ex);
}
DeviceModel deviceModel = new DeviceModel(
deviceId,
deviceName,
protocolResolver,
dataProcessor,
deviceOption.ListenerKey
);
return deviceModel;
}
/// <summary>
/// 从配置创建设备模型
/// </summary>
/// <param name="deviceOption">设备配置</param>
/// <returns></returns>
public static DeviceModel CreateDeviceModel(DeviceOption deviceOption)
{
return CreateDeviceModel(RandomDeviceId(), "Unknown", deviceOption);
}
/// <summary>
/// 创建设备模型
/// </summary>
/// <param name="deviceId">设备名称</param>
/// <param name="protocolResolver">解析解析器</param>
/// <param name="dataProcessor">数据解析器</param>
/// <param name="dataUpdateListener">监听key</param>
/// <returns></returns>
public static DeviceModel CreateDeviceModel(string deviceId, string deviceName, IProtocolResolver protocolResolver, IDataProcessor dataProcessor, string dataUpdateListener)
{
DeviceModel deviceModel = new DeviceModel(
deviceId,
deviceName,
protocolResolver,
dataProcessor,
dataUpdateListener
);
return deviceModel;
}
}
}

View File

@ -1,51 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Modular.Sensor.Device;
using Wit.SDK.Sensor.Device.Interfaces;
namespace Wit.SDK.Modular.Sensor.Modular.DataProcessor.Interface
{
/// <summary>
/// 数据处理器接口
/// </summary>
public abstract class IDataProcessor : IDeviceComponent
{
/// <summary>
/// 打开设备时
/// </summary>
public abstract void OnOpen(DeviceModel deviceModel);
/// <summary>
/// 关闭传感器时
/// </summary>
public abstract void OnClose(DeviceModel deviceModel);
/// <summary>
/// 设备实时数据更新时
/// </summary>
public abstract void OnUpdate(DeviceModel deviceModel);
public void OnRemove()
{
}
public void OnReceiveData(DeviceModel deviceModel, byte[] data)
{
}
public void OnKeyUpdate(DeviceModel deviceModel, string key, object value)
{
}
public void OnReadData(DeviceModel deviceModel, byte[] sendData, int delay = -1)
{
}
public void OnSend(DeviceModel deviceModel, byte[] data)
{
}
}
}

View File

@ -1,24 +0,0 @@
using Wit.SDK.Modular.Sensor.Device;
using Wit.SDK.Modular.Sensor.Modular.DataProcessor.Interface;
namespace Wit.SDK.Modular.Sensor.Modular.DataProcessor.Roles
{
/// <summary>
/// 空的数据处理器
/// </summary>
public class EmptyProcessor : IDataProcessor
{
public override void OnClose(DeviceModel deviceModel)
{
}
public override void OnOpen(DeviceModel deviceModel)
{
}
public override void OnUpdate(DeviceModel baseDeviceModel)
{
}
}
}

View File

@ -1,37 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Modular.Sensor.Modular.ProtocolResolver.Enum
{
/// <summary>
/// 维特智能传感器协议枚举
/// </summary>
public enum WitSensorProtocol
{
/// <summary>
/// 维特协议
/// </summary>
WitProtocol = 0,
/// <summary>
/// 维特智能Can协议
/// </summary>
WitCanProtocol = 1,
/// <summary>
/// 维特智能蓝牙5.0协议
/// </summary>
WitBle5Protocol = 2,
/// <summary>
/// Modbus16协议
/// </summary>
Modbus16Protocol = 3,
/// <summary>
/// 维特JY61协议
/// </summary>
WitJY61Protocol = 4
}
}

View File

@ -1,54 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Modular.Sensor.Device;
using Wit.SDK.Sensor.Device.Interfaces;
namespace Wit.SDK.Modular.Sensor.Modular.ProtocolResolver.Interface
{
/// <summary>
/// 协议解析器接口
/// </summary>
public abstract class IProtocolResolver : IDeviceComponent
{
/// <summary>
/// 读取数据时
/// </summary>
public abstract void OnReadData(DeviceModel deviceModel, byte[] sendData, int delay = -1);
/// <summary>
/// 收到数据时
/// </summary>
/// <param name="data"></param>
public abstract void OnReceiveData(DeviceModel deviceModel, byte[] data);
public void OnClose(DeviceModel deviceModel)
{
}
public void OnKeyUpdate(DeviceModel deviceModel, string key, object value)
{
}
public void OnOpen(DeviceModel deviceModel)
{
}
public void OnRemove()
{
}
public void OnSend(DeviceModel deviceModel, byte[] data)
{
}
public void OnUpdate(DeviceModel deviceModel)
{
}
}
}

View File

@ -1,27 +0,0 @@
using Wit.SDK.Modular.Sensor.Device;
using Wit.SDK.Modular.Sensor.Modular.ProtocolResolver.Interface;
namespace Wit.SDK.Modular.Sensor.Modular.ProtocolResolver.Roles
{
public class EmptyResolver : IProtocolResolver
{
/// <summary>
///
/// </summary>
/// <param name="data"></param>
/// <param name="deviceModel"></param>
public override void OnReceiveData(DeviceModel deviceModel, byte[] data)
{
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="sendData"></param>
/// <param name="deviceModel"></param>
public override void OnReadData(DeviceModel deviceModel, byte[] sendData, int delay = -1)
{
}
}
}

View File

@ -1,106 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Wit.SDK.Modular.Sensor.Device;
namespace Wit.SDK.Modular.WitSensorApi.Interface
{
/// <summary>
/// 姿态传感器Api
/// </summary>
public interface IAttitudeSensorApi
{
/// <summary>
/// 打开设备
/// </summary>
void Open();
/// <summary>
/// 是否打开了设备
/// </summary>
/// <returns></returns>
bool IsOpen();
/// <summary>
/// 关闭设备
/// </summary>
void Close();
/// <summary>
/// 发送数据
/// </summary>
/// <param name="data">需要发送出去的数据</param>
/// <param name="returnData">传感器返回的数据</param>
/// <param name="isWaitReturn">是否需要传感器返回数据</param>
/// <param name="waitTime">等待传感器返回数据时间单位ms默认100ms</param>
/// <param name="repetition">重复发送次数</param>
void SendData(byte[] data, out byte[] returnData, bool isWaitReturn = false, int waitTime = 100, int repetition = 1);
/// <summary>
/// 发送带协议的数据,使用默认等待时长
/// </summary>
/// <param name="data">数据</param>
void SendProtocolData(byte[] data);
/// <summary>
/// 发送带协议的数据,并且指定等待时长
/// </summary>
/// <param name="data">数据</param>
/// <param name="waitTime">等待时间</param>
void SendProtocolData(byte[] data, int waitTime);
/// <summary>
/// 解锁寄存器
/// </summary>
void UnlockReg();
/// <summary>
/// 保存寄存器
/// </summary>
void SaveReg();
/// <summary>
/// 加计校准
/// </summary>
void AppliedCalibration();
/// <summary>
/// 开始磁场校准
/// </summary>
void StartFieldCalibration();
/// <summary>
/// 结束磁场校准
/// </summary>
void EndFieldCalibration();
/// <summary>
/// 设置回传速率
/// </summary>
/// <param name="rate"></param>
void SetReturnRate(byte rate);
/// <summary>
/// 获得设备名称
/// </summary>
/// <returns></returns>
string GetDeviceName();
/// <summary>
/// 获得数据
/// </summary>
/// <param name="key">数据键值</param>
/// <returns></returns>
string GetDeviceData(string key);
/// <summary>
/// 传感器数据更新时
/// </summary>
/// <param name="deviceModel"></param>
void DeviceModel_OnListenKeyUpdate(DeviceModel deviceModel);
}
}

View File

@ -1,168 +0,0 @@
using System;
using System.Text;
namespace Wit.SDK.Utils
{
/// <summary>
/// 字节数组转换工具类
/// </summary>
public class ByteArrayConvert
{
/// <summary>
/// byte数组转string
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static string ByteArrayToString(byte[] data)
{
return Encoding.Default.GetString(data);
}
/// <summary>
/// string转 byte数组
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static byte[] StringToByteArray(string data)
{
return Encoding.Default.GetBytes(data);
}
/// <summary>
/// byte数组转16进制字符串
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static string ByteArrayToHexString(byte[] data)
{
if (data == null) { return ""; }
StringBuilder builder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
builder.Append(string.Format("{0:X2} ", data[i]));
}
return builder.ToString().Trim();
}
/// <summary>
/// 16进制字符串转byte数组
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static byte[] HexStringToByteArray(string data)
{
string[] chars = data.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
byte[] returnBytes = new byte[chars.Length];
//逐个字符变为16进制字节数据
for (int i = 0; i < chars.Length; i++)
{
returnBytes[i] = Convert.ToByte(chars[i], 16);
}
return returnBytes;
}
/// <summary>
/// byte数组转10进制字符串
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static string ByteArrayToDecString(byte[] data)
{
StringBuilder builder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
builder.Append(data[i] + " ");
}
return builder.ToString().Trim();
}
/// <summary>
/// 10进制字符串转byte数组
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static byte[] DecStringToByteArray(string data)
{
string[] chars = data.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
byte[] returnBytes = new byte[chars.Length];
//逐个字符变为10进制字节数据
for (int i = 0; i < chars.Length; i++)
{
returnBytes[i] = Convert.ToByte(chars[i], 10);
}
return returnBytes;
}
/// <summary>
/// byte数组转八进制字符串
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static string ByteArrayToOtcString(byte[] data)
{
StringBuilder builder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
builder.Append(Convert.ToString(data[i], 8) + " ");
}
return builder.ToString().Trim();
}
/// <summary>
/// 八进制字符串转byte数组
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static byte[] OtcStringToByteArray(string data)
{
string[] chars = data.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
byte[] returnBytes = new byte[chars.Length];
//逐个字符变为8进制字节数据
for (int i = 0; i < chars.Length; i++)
{
returnBytes[i] = Convert.ToByte(chars[i], 8);
}
return returnBytes;
}
/// <summary>
/// 二进制字符串转byte数组
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static byte[] BinStringToByteArray(string data)
{
string[] chars = data.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
byte[] returnBytes = new byte[chars.Length];
//逐个字符变为2进制字节数据
for (int i = 0; i < chars.Length; i++)
{
returnBytes[i] = Convert.ToByte(chars[i], 2);
}
return returnBytes;
}
/// <summary>
/// byte数组转二进制字符串
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static string ByteArrayToBinString(byte[] data)
{
StringBuilder builder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
builder.Append(Convert.ToString(data[i], 2) + " ");
}
return builder.ToString().Trim();
}
}
}

View File

@ -1,200 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using Wit;
using Wit.SDK;
using Wit.SDK.Modular;
using Wit.SDK.Modular.Sensor;
using Wit.SDK.Modular.Sensor.Device.Entity;
namespace Wit.SDK.Modular.Sensor.Device.Entity
{
public class CmdBean
{
[XmlIgnore]
private string _sendData = "";
/// <summary>
/// 命令
/// </summary>
public string sendData
{
get
{
return _sendData;
}
set
{
_sendData = value;
//if (!value.Equals(_sendData))
//{
// _sendData = value;
// NotifyPropertyChange(nameof(sendData));
//}
}
}
private int _valueLength = 0;
public int valueLength
{
get
{
return _valueLength;
}
set
{
_valueLength = value;
//NotifyPropertyChange(nameof(valueLength));
}
}
[XmlIgnore]
private bool _sendHex = false;
/// <summary>
/// 是否十六进制处理
/// </summary>
public bool sendHex
{
get
{
return _sendHex;
}
set
{
if (!value.Equals(_sendHex))
{
_sendHex = value;
//NotifyPropertyChange(nameof(sendHex));
}
}
}
[XmlIgnore]
private bool _sendNewLine = false;
/// <summary>
/// 是否添加换行
/// </summary>
public bool sendNewLine
{
get
{
return _sendNewLine;
}
set
{
_sendNewLine = value;
//NotifyPropertyChange(nameof(sendNewLine));
}
}
[XmlIgnore]
private string _sendParseValue = "";
public string sendParseValue
{
get
{
return _sendParseValue;
}
set
{
if (!value.Equals(_sendParseValue))
_sendParseValue = value;
}
}
[XmlIgnore]
private int _delay = 100;
/// <summary>
/// 延时时间
/// </summary>
public int delay
{
get
{
return _delay;
}
set
{
if (!value.Equals(_delay))
{
_delay = value;
//NotifyPropertyChange(nameof(delay));
}
}
}
[XmlIgnore]
private string _statsText = "";
public string statsText
{
get
{
return _statsText;
}
set
{
_statsText = value;
//NotifyPropertyChange(nameof(statsText));
}
}
/// <summary>
/// new Property<string>("", "发送数据完成后对上位机进行调整的指令\r\n" +
// "SetBaud:deviceName:Baud //设置设备波特率\r\n" +
// "SetBaud:modeName //更改上位机模式\r\n" +
// "SearchDevice //让上位机开始搜索\r\n" +
// "SetModbusDeviceId:deviceName:ModbusId:isHex//设置设备ModbusID", "发送数据");
/// </summary>
[XmlIgnore]
private string _sendEndCmd = "";
public string sendEndCmd
{
get
{
return _sendEndCmd;
}
set
{
_sendEndCmd = value;
}
}
[XmlIgnore]
private int _sort = 0;
public int sort
{
get => _sort;
set
{
_sort = value;
}
}
}
}

View File

@ -1,179 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using Wit.SDK.Modular.Sensor.Device.Entity;
using Wit.SDK.Utils;
namespace Wit.SDK.Modular.Sensor.Utils
{
/// <summary>
/// 脚本解释器
/// </summary>
public class CmdUtils
{
/// <summary>
/// 构建指令
/// </summary>
/// <returns></returns>
public static string GenerationCmd(string cmd, Dictionary<string, object> dataResource, string value, string deviceName, string text, int valueLength = 0)
{
return Encoding.Default.GetString(GenerationCmd(cmd, false, false, dataResource, value, deviceName, text, valueLength));
}
/// <summary>
/// 生成要发送的byte数组
/// </summary>
/// <param name="cmdBean"></param>
/// <returns></returns>
public static byte[] GenerationCmd(CmdBean cmdBean, Dictionary<string, object> dataResource) {
return GenerationCmd(cmdBean.sendData, cmdBean.sendHex, cmdBean.sendNewLine, dataResource);
}
/// <summary>
/// 生成要发送的byte数组
/// </summary>
/// <param name="cmd"></param>
/// <param name="sendHex"></param>
/// <param name="sendNewLine"></param>
/// <param name="dataResource"></param>
/// <param name="value"></param>
/// <returns></returns>
public static byte[] GenerationCmd(string cmd, bool sendHex, bool sendNewLine, Dictionary<string, object> dataResource, string value = null, string deviceName = null, string text = null, int valueLegnth = 0)
{
try
{
if (sendHex && !string.IsNullOrEmpty(value))
{
value = int.Parse(value).ToString("X") + "";
if (valueLegnth != 0 && value.Length < valueLegnth)
{
int t = valueLegnth - value.Length;
value = value.PadLeft(valueLegnth, '0');
}
if (value.Length > 2)
{
value = value.Substring(0, 2) + " " + value.Substring(2);
}
}
if (value != null)
//替换值到命令里
cmd = cmd.Replace("${VAL}", value);
if (deviceName != null)
//替换值到命令里
cmd = cmd.Replace("${DEVICE_NAME}", deviceName);
if (text != null)
//替换值到命令里
cmd = cmd.Replace("${TEXT}", text);
if (sendHex)
{
//替换变量到命令里
cmd = cmdParse(cmd, dataResource, true);
}
else
{
cmd = cmdParse(cmd, dataResource, false);
}
//要发送的数据
byte[] data = new byte[0];
//如果发送回车换行
if (sendNewLine)
{
cmd = cmd + "\r\n";
}
//检查是不是要加crc校验如果要就先把占位符换出来
bool isCrc16 = false;
if (cmd.Contains("${CRC16}"))
{
isCrc16 = true;
cmd = cmd.Replace("${CRC16}", "");
}
//去除前面和后面的空格
cmd = cmd.Trim(' ');
//如果是16进制发送
if (sendHex)
{
data = ByteArrayConvert.HexStringToByteArray(cmd);
}
else
{
data = ByteArrayConvert.StringToByteArray(cmd);
}
//如果加crc16校验
if (isCrc16)
{
byte[] crc16 = Modbus16Utils.GetCrc16(data);
List<byte> l = data.ToList();
l.AddRange(crc16);
data = l.ToArray();
}
return data;
}
catch (Exception ex)
{
return Encoding.Default.GetBytes(ex.Message);
}
}
/// <summary>
/// 将变量代入到命令里
/// </summary>
/// <param name="cmd"></param>
/// <returns></returns>
public static string cmdParse(string cmd, Dictionary<string, object> dataResource, bool ishex)
{
string[] keyArr = dataResource.Keys.ToArray();
for (int i = 0; i < keyArr.Length; i++)
{
string key = keyArr[i];
string value = dataResource[key]!=null ? dataResource[key].ToString(): "";
//变量名称
string vname = "${" + key + "}";
//如果命令里包含变量就把值代入进去
if (cmd.Contains(vname))
{
if (ishex)
{
cmd = cmd.Replace(vname, int.Parse(value).ToString("X"));
}
else
{
cmd = cmd.Replace(vname, value);
}
}
}
return cmd;
}
}
}

View File

@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Utils
{
/// <summary>
/// 日期工具类
/// </summary>
public class DateTimeUtils
{
/// <summary>
/// 获取时间戳
/// </summary>
/// <returns></returns>
public static long GetTimeStamp()
{
TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalMilliseconds);
}
/// <summary>
/// 日期格式化
/// </summary>
/// <param name="dateTime"></param>
/// <param name="format"></param>
/// <returns></returns>
public static string Format(DateTime dateTime, string format) {
return dateTime.ToString(format);
}
}
}

View File

@ -1,63 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Modular.Sensor.Device;
using Wit.SDK.Modular.Sensor.Modular.Connector.Role;
using Wit.SDK.Modular.Sensor.Utils;
namespace Wit.SDK.Modular.Sensor.Modular.Resolver.Utils
{
/// <summary>
/// 自动延时工具类
/// </summary>
public class AutoDelayUtils
{
/// <summary>
/// 获得延迟
/// </summary>
/// <param name="delay"></param>
/// <param name="deviceModel"></param>
/// <returns></returns>
public static int GetAutoDelay(int delay, DeviceModel deviceModel)
{
if (delay == -1)
{
if (deviceModel.Connector is SPConnector)
{
var spc = deviceModel.Connector as SPConnector;
delay = SerialPortUtils.GetBaudAutoDelay(spc.SerialPortConfig.BaudRate);
}
else
{
delay = 100;
}
}
return delay;
}
/// <summary>
/// 获得延迟
/// </summary>
/// <param name="delay"></param>
/// <param name="deviceModel"></param>
/// <returns></returns>
public static int GetModbusAutoDelay(int delay, DeviceModel deviceModel)
{
if (delay == -1)
{
if (deviceModel.Connector is SPConnector)
{
var spc = deviceModel.Connector as SPConnector;
delay = SerialPortUtils.GetModbusAutoDelay(spc.SerialPortConfig.BaudRate);
}
else
{
delay = 100;
}
}
return delay;
}
}
}

View File

@ -1,43 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Modular.Sensor.Device.Entity;
namespace Wit.SDK.Modular.Sensor.Modular.DataProcessor.Context
{
/// <summary>
/// 数据处理器上下文
/// </summary>
public class DataProcessorContext
{
/// <summary>
/// 自动读取间隔
/// </summary>
private static int _AutoReadInterval = DefaultAutoReadInterval;
/// <summary>
/// 自动读取间隔
/// </summary>
public static int AutoReadInterval {
get { return (_AutoReadInterval > 0) ? _AutoReadInterval : 10; }
set { _AutoReadInterval = value; }
}
public static int DefaultAutoReadInterval
{
get { return 200; }
}
/// <summary>
/// 暂停自动读取
/// </summary>
public static bool AutoReadPause = false;
/// <summary>
/// 读取的命令
/// </summary>
public static List<CmdBean> ReadCmdList = new List<CmdBean>();
}
}

View File

@ -1,156 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Wit.SDK.Modular.Sensor.Device;
using Wit.SDK.Utils;
namespace Wit.SDK.Modular.Sensor.Modular.DataProcessor.Utils
{
/// <summary>
/// 记录key值切换器
/// 功能自动匹配记录的key
/// </summary>
public class RecordKeySwitch
{
/// <summary>
/// 记录触发器列表
/// </summary>
public List<string> recordTriggerList = new List<string> {};
/// <summary>
/// 字典 string:key值 long刷新时间
/// </summary>
private Dictionary<string, long> keyUpdateTimeDict = new Dictionary<string, long>();
/// <summary>
/// 是否启用切换触发器线程
/// </summary>
public bool BolSwitchRecrodThEnable = false;
/// <summary>
/// 上次更新时间
/// </summary>
public long LastUpdateTs = 0;
/// <summary>
/// 基础设备
/// </summary>
public DeviceModel DeviceModel { get; private set; }
/// <summary>
/// 初始化 启动
/// </summary>
/// <param name="deviceModel"></param>
public void Open(DeviceModel deviceModel, List<string> keyList)
{
// 设备
this.DeviceModel = deviceModel;
// 记录触发器列表
this.recordTriggerList = keyList;
DeviceModel.OnKeyUpdate -= DeviceModel_OnKeyUpdate;
DeviceModel.OnKeyUpdate += DeviceModel_OnKeyUpdate;
DeviceModel.OnListenKeyUpdate -= DeviceModel_OnListenKeyUpdate;
DeviceModel.OnListenKeyUpdate += DeviceModel_OnListenKeyUpdate;
// 创建线程
Thread th = new Thread(SwitchKeyTh) { IsBackground = true };
BolSwitchRecrodThEnable = true;
th.Start();
}
/// <summary>
/// 切换刷新用的key值
/// </summary>
private void SwitchKeyTh()
{
// 数据刷新有问题就启动线程
while (BolSwitchRecrodThEnable) {
Thread.Sleep(3000);
// 实时时间
var ts = DateTimeUtils.GetTimeStamp();
if (ts - LastUpdateTs > 3000)
{
SwitchListenerKey();
}
}
}
/// <summary>
/// 切换监听的key
/// </summary>
private void SwitchListenerKey()
{
if (recordTriggerList.Count == 0)
{
return;
}
// 最后切换的key值
string keyLast = recordTriggerList[0];
double min = 0;
for (int i = 0; i < recordTriggerList.Count; i++)
{
string item = recordTriggerList[i];
if (keyUpdateTimeDict.ContainsKey(item))
{
double tsVal = keyUpdateTimeDict[item];
if (tsVal > min)
{
min = tsVal;
keyLast = item;
}
}
}
// 切换监听的key值 让数据刷新继续下去
DeviceModel.ListenerKey = keyLast;
}
/// <summary>
/// 判断自动更新数据有无问题
/// </summary>
/// <param name="deviceModel"></param>
private void DeviceModel_OnListenKeyUpdate(DeviceModel deviceModel)
{
LastUpdateTs = DateTimeUtils.GetTimeStamp();
}
/// <summary>
/// 记录key值刷新时对应的时间
/// </summary>
/// <param name="deviceModel"></param>
/// <param name="key"></param>
/// <param name="value"></param>
private void DeviceModel_OnKeyUpdate(DeviceModel deviceModel, string key, object value)
{
// 如果是可切换的key就赋值给字典
if (recordTriggerList.Contains(key))
{
// 记录数据更新时间戳
keyUpdateTimeDict[key] = DateTimeUtils.GetTimeStamp();
}
}
/// <summary>
/// 关闭所有线程
/// </summary>
public void Close() {
// 关线程
BolSwitchRecrodThEnable = false;
if (DeviceModel != null && DeviceModel.IsOpen)
{
// 取消事件委托
DeviceModel.OnKeyUpdate -= DeviceModel_OnKeyUpdate;
DeviceModel.OnListenKeyUpdate -= DeviceModel_OnListenKeyUpdate;
}
}
}
}

View File

@ -1,77 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Modular.Sensor.Device;
namespace Wit.SDK.Modular.Sensor.Utils
{
/// <summary>
/// AT指令帮助类
/// </summary>
public class ATCommandHelper
{
/// <summary>
/// 发送读取的命令,并且查找返回结果
/// </summary>
/// <param name="sendData"></param>
/// <param name="condition"></param>
/// <returns></returns>
public static string SendReadCommandAndFindLine(DeviceModel deviceModel, string sendData, string[] condition, int repeat = 3)
{
string result = null;
int i = 0;
// 如果没有结果就重复指定次数
while (++i <= repeat)
{
string data = SendReadCommand(deviceModel, sendData);
for (int j = 0; j < condition.Length; j++)
{
result = FindLine(data, condition[j]);
if (!string.IsNullOrEmpty(result))
{
return result;
}
}
}
return null;
}
/// <summary>
/// 发送读取的命令
/// </summary>
/// <param name="sendData"></param>
/// <returns></returns>
public static string SendReadCommand(DeviceModel deviceModel, string sendData)
{
byte[] returnData;
deviceModel.SendData(Encoding.Default.GetBytes(sendData), out returnData, true, 900, 2);
string result = Encoding.Default.GetString(returnData);
return result;
}
/// <summary>
/// 查找返回结果
/// </summary>
/// <param name="data"></param>
/// <param name="condition"></param>
/// <returns></returns>
public static string FindLine(string data, string condition)
{
string[] rows = data.Split('\r', '\n');
for (int i = 0; i < rows.Length; i++)
{
if (rows[i].Contains(condition))
{
return rows[i];
}
}
return null;
}
}
}

View File

@ -1,179 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml.Serialization;
using Wit;
using Wit.SDK;
using Wit.SDK.Modular.Sensor.Utils;
using Wit.SDK.Utils;
namespace Wit.SDK.Modular.Sensor.Utils
{
/// <summary>
/// ASCII协议解析
/// </summary>
public class AsciiProtocolUtils
{
/// <summary>
/// 通过AsciiKeyPattern解析字符串解析后返回key的字典和值
/// </summary>
/// <param name="input">输入的待解析字符串</param>
/// <param name="asciiKeyPatterns">输入前必须先解析好key和pattern</param>
/// <returns></returns>
public static Dictionary<string, string> ResolvesAsciiByAsciiKeyPatterns(string input, List<AsciiKeyPattern> asciiKeyPatterns)
{
Dictionary<string, string> dic = new Dictionary<string, string>();
foreach (var asciiKeyPattern in asciiKeyPatterns)
{
dic = ResolvesAsciiByAsciiKeyPattern(input, asciiKeyPattern);
if (dic.Keys.Count > 0)
{
break;
}
}
return dic;
}
/// <summary>
/// 通过AsciiKeyPattern解析字符串解析后返回key的字典和值
///
/// </summary>
/// <param name="input">输入的待解析字符串</param>
/// <param name="asciiKeyPattern">输入前必须先解析好key和pattern</param>
/// <returns></returns>
public static Dictionary<string, string> ResolvesAsciiByAsciiKeyPattern(string input, AsciiKeyPattern asciiKeyPattern)
{
Dictionary<string, string> dic = new Dictionary<string, string>();
string matchs = @asciiKeyPattern.pattern + "\r\n";
//string matchs = @asciiKeyPattern.pattern;
input = input + "\r\n";
MatchCollection mc = Regex.Matches(input, matchs);
if (mc.Count > 0)
{
GroupCollection groupCollection = mc[0].Groups;
for (int i = 0; i < asciiKeyPattern.keys.Length && i + 1 < groupCollection.Count; i++)
{
dic[asciiKeyPattern.keys[i]] = groupCollection[i + 1].Value;
}
}
return dic;
}
/// <summary>
/// 得到带key的表达式得到它的key和正则表达式
/// </summary>
/// <param name="asciiKeyMatche"></param>
/// <returns>返回解析是否成功</returns>
public static bool GetAsciiKeyPatternKeyAndPattern(AsciiKeyPattern asciiKeyPattern)
{
//得到key
List<string> list = new List<string>();
MatchCollection mc = Regex.Matches(asciiKeyPattern.keyPattern, @"\${(.*?)}");
foreach (Match m in mc)
list.Add(m.Groups[1].Value);
asciiKeyPattern.keys = list.ToArray();
//得到正则表达式
asciiKeyPattern.pattern = Regex.Replace(asciiKeyPattern.keyPattern, @"\${(.*?)}", "(.*?)");
return true;
}
}
/// <summary>
/// Ascii协议解析表达式
/// </summary>
public class AsciiKeyPattern
{
public AsciiKeyPattern(string keyPattern)
{
this.keyPattern = keyPattern;
}
public AsciiKeyPattern()
{
}
[XmlIgnore]
private int _sort = 0;
public int sort
{
get => _sort;
set
{
_sort = value;
}
}
[XmlIgnore]
private string _keyPattern = "";
public string keyPattern
{
get => _keyPattern;
set
{
_keyPattern = value;
if (value != null)
{
AsciiProtocolUtils.GetAsciiKeyPatternKeyAndPattern(this);
}
}
}
[XmlIgnore]
public string[] _keys = new string[0];
public string[] keys
{
get => _keys;
set
{
_keys = value;
}
}
[XmlIgnore]
public string _pattern = "";
public string pattern
{
get => _pattern;
set
{
_pattern = value;
}
}
}
}

View File

@ -1,77 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Modular.Sensor.Utils
{
/// <summary>
/// 倾角传感器磁场帮助类
/// </summary>
public class DipSensorMagHelper
{
/// <summary>
/// 磁场转换标准单位uT(微特)
/// </summary>
public static double GetMagToUt(short reg72, double regMag)
{
double dRet = regMag;
switch (reg72)
{
case 2:
dRet = dRet * 0.15;
break;
case 3:
dRet = dRet * 13 / 1000.0;
break;
case 4:
dRet = dRet * 0.058;
break;
case 5:
dRet = dRet * 0.098;
break;
case 6:
dRet = dRet / 120;
break;
case 7:
dRet = dRet * 20 / 1000.0;
break;
}
return Math.Round(dRet, 3);
}
/// <summary>
/// 标准单位uT(微特)转换磁场数据
/// </summary>
public static double GetUtToMag(short reg72, double reguTMag)
{
double dRet = reguTMag;
switch (reg72)
{
case 2:
dRet = dRet / 0.15;
break;
case 3:
dRet = dRet * 1000.0 / 13.0 ;
break;
case 4:
dRet = dRet / 0.058;
break;
case 5:
dRet = dRet / 0.098;
break;
case 6:
dRet = dRet * 120;
break;
case 7:
dRet = dRet * 1000.0 / 20.0 ;
break;
}
return dRet;
}
}
}

View File

@ -1,76 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Modular.Sensor.Utils
{
/// <summary>
/// 9轴倾角传感器帮助类
/// </summary>
public class MWT925Helper
{
/// <summary>
/// 解锁命令
/// </summary>
/// <returns></returns>
public static byte[] Unlock(byte addr)
{
return Modbus16Utils.GetWrite(addr, 0x69, 0xB588);
}
/// <summary>
/// 加计校准
/// </summary>
/// <returns></returns>
public static byte[] AccelerationCalibration(byte addr)
{
return Modbus16Utils.GetWrite(addr, 0x01, 0x01);
}
/// <summary>
/// 开始磁场校准
/// </summary>
/// <returns></returns>
public static byte[] BeginFieldCalibration(byte addr)
{
return Modbus16Utils.GetWrite(addr, 0x01, 0x07);
}
/// <summary>
/// 结束磁场校准
/// </summary>
/// <returns></returns>
public static byte[] EndFieldCalibration(byte addr)
{
return Modbus16Utils.GetWrite(addr, 0x01, 0x00);
}
/// <summary>
/// 波特率调整
/// </summary>
/// <returns></returns>
public static byte[] SetBaudRate(byte addr, ushort value)
{
return Modbus16Utils.GetWrite(addr, 0x04, value);
}
/// <summary>
/// 设置输出内容
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static byte[] SetBackContent(byte addr, ushort value)
{
return Modbus16Utils.GetWrite(addr, 0x02, value);
}
// 带宽调整
// 量程调整
// 滤波参数
}
}

View File

@ -1,263 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Modular.Sensor.Utils
{
/// <summary>
/// Modbus16工具类
/// </summary>
public class Modbus16Utils
{
/// <summary>
/// 获得CRC16_Modbus效验,低位在前,高位在后
/// </summary>
/// <param name="byteData">要进行计算的字节数组</param>
/// <returns>计算后的数组</returns>
public static byte[] GetCrc16(byte[] bytes)
{
byte crcRegister_H = 0xFF, crcRegister_L = 0xFF;// 预置一个值为 0xFFFF 的 16 位寄存器
byte polynomialCode_H = 0xA0, polynomialCode_L = 0x01;// 多项式码 0xA001
for (int i = 0; i < bytes.Length; i++)
{
crcRegister_L = (byte)(crcRegister_L ^ bytes[i]);
for (int j = 0; j < 8; j++)
{
byte tempCRC_H = crcRegister_H;
byte tempCRC_L = crcRegister_L;
crcRegister_H = (byte)(crcRegister_H >> 1);
crcRegister_L = (byte)(crcRegister_L >> 1);
// 高位右移前最后 1 位应该是低位右移后的第 1 位:如果高位最后一位为 1 则低位右移后前面补 1
if ((tempCRC_H & 0x01) == 0x01)
{
crcRegister_L = (byte)(crcRegister_L | 0x80);
}
if ((tempCRC_L & 0x01) == 0x01)
{
crcRegister_H = (byte)(crcRegister_H ^ polynomialCode_H);
crcRegister_L = (byte)(crcRegister_L ^ polynomialCode_L);
}
}
}
return new byte[] { crcRegister_L, crcRegister_H };
}
/// <summary>
/// 获得CRC16_Modbus效验,低位在前,高位在后
/// </summary>
/// <param name="byteData">要进行计算的字节数组</param>
/// <param name="length">长度</param>
/// <returns>计算后的数组</returns>
public static byte[] GetCrc16(byte[] byteData, int length)
{
byte[] CRC = new byte[2];
ushort wCrc = 0xFFFF;
for (int i = 0; i < length; i++)
{
wCrc ^= Convert.ToUInt16(byteData[i]);
for (int j = 0; j < 8; j++)
{
if ((wCrc & 0x0001) == 1)
{
wCrc >>= 1;
wCrc ^= 0xA001;//异或多项式
}
else
{
wCrc >>= 1;
}
}
}
CRC[1] = (byte)((wCrc & 0xFF00) >> 8);//高位在后
CRC[0] = (byte)(wCrc & 0x00FF); //低位在前
return CRC;
}
/// <summary>
/// 获得写入的modbus指令
/// </summary>
/// <param name="addr"></param>
/// <param name="reg"></param>
/// <param name="value"></param>
/// <param name="resultBytes"></param>
/// <returns>成功返回0</returns>
public static int GetWrite(byte addr, int reg, int value, out byte[] resultBytes)
{
byte[] reghl = GetHL(reg);
byte[] valuehl = GetHL(value);
resultBytes = new byte[] { addr, 0x06, reghl[0], reghl[1], valuehl[0], valuehl[1] };
resultBytes = resultBytes.Concat(GetCrc16(resultBytes)).ToArray();
return 0;
}
/// <summary>
/// 写入的modbus指令
/// </summary>
/// <param name="addr"></param>
/// <param name="reg"></param>
/// <param name="value"></param>
/// <returns></returns>
public static byte[] GetWrite(byte addr, int reg, int value)
{
byte[] resultBytes = null;
GetWrite(addr, reg, value, out resultBytes);
return resultBytes;
}
/// <summary>
/// 读取的modbus指令
/// </summary>
/// <param name="addr"></param>
/// <param name="reg"></param>
/// <param name="count"></param>
/// <param name="resultBytes"></param>
/// <returns>成功返回0</returns>
public static int GetRead(byte addr, int reg, int count, out byte[] resultBytes)
{
byte[] reghl = GetHL(reg);
byte[] counthl = GetHL(count);
resultBytes = new byte[] { addr, 0x03, reghl[0], reghl[1], counthl[0], counthl[1] };
resultBytes = resultBytes.Concat(GetCrc16(resultBytes)).ToArray();
return 0;
}
/// <summary>
/// 读取的modbus指令
/// </summary>
/// <param name="addr"></param>
/// <param name="reg"></param>
/// <param name="count"></param>
/// <returns></returns>
public static byte[] GetRead(byte addr, int reg, int count)
{
byte[] resultBytes = null;
GetRead(addr,reg,count, out resultBytes);
return resultBytes;
}
/// <summary>
/// 获得高低位,高位在前
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static byte[] GetHL(int value)
{
return new byte[] { (byte)(value >> 8), (byte)(value << 8 >> 8) };
}
/// <summary>
/// 获得高低位,低位在前
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static byte[] GetLH(int value)
{
return new byte[] { (byte)(value << 8 >> 8), (byte)(value >> 8) };
}
/// <summary>
/// 检查校验位
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static bool CheckModbusCrc16(byte[] data)
{
if (data == null)
{
return false;
}
if (data.Length < 3)
{
return false;
}
byte[] v = GetCrc16(data, data.Length - 2);
if (v.Length < 2)
{
return false;
}
if (v[0] != data[data.Length - 2])
{
return false;
}
if (v[1] != data[data.Length - 1])
{
return false;
}
return true;
}
/// <summary>
/// 查询返回的字节里有没有发送的命令的回传
/// </summary>
/// <param name="sendByte"></param>
/// <param name="returnByte"></param>
/// <param name="modbus"></param>
/// <returns>查找成功返回true查找失败返回false</returns>
public static bool FindModbus(byte[] sendByte, byte[] returnByte, out byte[] modbus)
{
int height = sendByte[4];
int low = sendByte[5];
// 得到长度
int len = 5 + (height << 8 | low) * 2;
// 如果没有返回结果,或者返回结果根本不够长
if (returnByte == null || returnByte.Length < len)
{
modbus = new byte[0];
return false;
}
// 遍历返回结果查找
for (int i = 0; i <= returnByte.Length - len; i++)
{
byte rAddr = returnByte[i];
byte mark = 0x03;
byte[] cCrc = GetCrc16(returnByte.Skip(i).Take(len - 2).ToArray());
byte rCrcH = returnByte[i + len - 2];
byte rCrcL = returnByte[i + len - 1];
// 如果全部通过
if (sendByte[0] == rAddr && mark == sendByte[1] && rCrcH == cCrc[0] && rCrcL == cCrc[1])
{
modbus = returnByte.Skip(i).Take(len).ToArray();
return true;
}
}
modbus = new byte[0];
return false;
}
}
}

View File

@ -1,165 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Modular.Sensor.Utils
{
/// <summary>
/// 串口开发工具类
/// </summary>
public class SerialPortUtils
{
/// <summary>
/// 获取串口名称
/// </summary>
/// <returns></returns>
public static string[] GetPortNames()
{
return SerialPort.GetPortNames();
}
/// <summary>
/// 获得波特率自动适配延迟
/// </summary>
/// <returns></returns>
public static int GetBaudAutoDelay(int baud)
{
if (baud == 0)
{
return 80;
}else if (baud <= 1200)
{
return 1000;
}
else if (baud > 1200 && baud <= 2400)
{
return 500;
}
else if (baud > 2400 && baud <= 4800)
{
return 400;
}
else if (baud > 4800 && baud <= 7200)
{
return 250;
}
else if (baud > 7200 && baud <= 14400)
{
return 200;
}
else if (baud > 14400 && baud <= 19200)
{
return 200;
}
else if (baud > 19200 && baud <= 38400)
{
return 200;
}
else if (baud > 38400 && baud <= 56000)
{
return 200;
}
else if (baud > 56000 && baud <= 115200)
{
return 200;
}
else if (baud > 115200 && baud <= 230400)
{
return 200;
}
else if (baud > 230400 && baud <= 460800)
{
return 100;
}
else if (baud > 460800 && baud <= 921600)
{
return 100;
}
else if (baud > 921600)
{
return 100;
}
else
{
return 100;
}
}
/// <summary>
/// 获得Modbus自动适配延迟
/// </summary>
/// <returns></returns>
public static int GetModbusAutoDelay(int baud)
{
if (baud == 0)
{
return 80;
}
else if (baud <= 1200)
{
return 500;
}
else if (baud > 1200 && baud <= 2400)
{
return 300;
}
else if (baud > 2400 && baud <= 4800)
{
return 200;
}
else if (baud > 4800 && baud <= 7200)
{
return 150;
}
else if (baud > 7200 && baud <= 14400)
{
return 80;
}
else if (baud > 14400 && baud <= 19200)
{
return 70;
}
else if (baud > 19200 && baud <= 38400)
{
return 60;
}
else if (baud > 38400 && baud <= 56000)
{
return 60;
}
else if (baud > 56000 && baud <= 115200)
{
return 60;
}
else if (baud > 115200 && baud <= 230400)
{
return 60;
}
else if (baud > 230400 && baud <= 460800)
{
return 60;
}
else if (baud > 460800 && baud <= 921600)
{
return 60;
}
else if (baud > 921600)
{
return 60;
}
else
{
return 60;
}
}
}
}

View File

@ -1,77 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Wit.SDK.Modular.Sensor.Utils
{
/// <summary>
/// 9轴倾角传感器帮助类
/// </summary>
public class WT925Helper
{
/// <summary>
/// 解锁命令
/// </summary>
/// <returns></returns>
public static byte[] Unlock()
{
return WitProtocolUtils.GetWrite(0x69, 0xB588);
}
/// <summary>
/// 加计校准
/// </summary>
/// <returns></returns>
public static byte[] AccelerationCalibration()
{
return WitProtocolUtils.GetWrite(0x01, 0x01);
}
/// <summary>
/// 开始磁场校准
/// </summary>
/// <returns></returns>
public static byte[] BeginFieldCalibration()
{
return WitProtocolUtils.GetWrite(0x01, 0x07);
}
/// <summary>
/// 结束磁场校准
/// </summary>
/// <returns></returns>
public static byte[] EndFieldCalibration()
{
return WitProtocolUtils.GetWrite(0x01, 0x00);
}
/// <summary>
/// 波特率调整
/// </summary>
/// <returns></returns>
public static byte[] SetBaudRate(ushort value)
{
return WitProtocolUtils.GetWrite(0x04, value);
}
/// <summary>
/// 设置输出内容
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static byte[] SetBackContent(ushort value)
{
return WitProtocolUtils.GetWrite(0x02, value);
}
// 带宽调整
// 量程调整
// 滤波参数
}
}

View File

@ -1,94 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Utils;
namespace Wit.SDK.Modular.Sensor.Utils
{
/// <summary>
/// 维特CAN传感器协议工具类需要使用TTL-CAN
/// </summary>
public class WitCanProtocolUtils
{
/// <summary>
/// 获得帧ID
/// </summary>
/// <param name="id">帧ID(10进制)</param>
/// <param name="frameFormat">帧格式 0=标准 1=扩展</param>
/// <param name="frmaeType">帧类型 0=数据 ; 1=远程</param>
public static int GetFrameId(int id, int frameFormat, int frmaeType)
{
int frameId = frameFormat == 1 ? id << 3 | 0x04 : id <<= 21;
if (frmaeType == 1) { frameId |= 0x02; }
return frameId;
}
#region
/// <summary>
/// 获得标准数据桢写命令
/// </summary>
/// <param name="canId"></param>
/// <param name="reg"></param>
/// <param name="value"></param>
/// <returns></returns>
public static byte[] GetStandWrite(int canId, byte reg, short value)
{
// 返回结果
List<byte> byteList = new List<byte>();
// 数据
byte[] dataFrame = new byte[] { 0xff, 0xaa, reg, (byte)(value), (byte)(value >> 8) };
// AT2byte
byteList.AddRange(Encoding.Default.GetBytes("AT"));
// 帧ID4byte
int frameId = GetFrameId(canId, 0, 0);
byteList.AddRange(BitConverter.GetBytes(frameId));
// 数据长度2byte
byteList.AddRange(new byte[] { (byte)(dataFrame.Length >> 8), (byte)(dataFrame.Length) });
// 帧数据
byteList.AddRange(dataFrame);
// 回车换行2byte
byteList.AddRange(Encoding.Default.GetBytes("\r\n"));
return byteList.ToArray();
}
/// <summary>
/// 获得标准数据桢读命令
/// </summary>
/// <param name="canId"></param>
/// <param name="reg"></param>
/// <param name="count"></param>
/// <returns></returns>
public static byte[] GetStandRead(int canId, byte reg)
{
// 返回结果
List<byte> byteList = new List<byte>();
// 数据
byte[] dataFrame = new byte[] { 0xff, 0xaa, 0x27, reg, 00 };
// AT2byte
byteList.AddRange(Encoding.Default.GetBytes("AT"));
// 帧ID4byte
int frameId = GetFrameId(canId, 0, 0);
byteList.AddRange(BitConverter.GetBytes(frameId));
// 数据长度2byte
byteList.AddRange(new byte[] { (byte)(dataFrame.Length >> 8),(byte)(dataFrame.Length) });
// 帧数据
byteList.AddRange(dataFrame);
// 回车换行2byte
byteList.AddRange(Encoding.Default.GetBytes("\r\n"));
return byteList.ToArray();
}
#endregion
}
}

View File

@ -1,125 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Utils;
namespace Wit.SDK.Modular.Sensor.Utils
{
/// <summary>
/// 维特协议工具类
/// </summary>
public class WitProtocolUtils
{
#region SUM和校验
/// <summary>
/// 获取SUM和校验结果
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static byte ToSUM(byte[] data)
{
int sum = 0;
for (int i = 0; i < data.Length; i++)
{
sum = sum + data[i];
}
//实际上num 这里已经是结果了如果只是取int 可以直接返回了
return (byte)sum;
}
/// <summary>
/// 校验数据包和校验
/// </summary>
/// <param name="dataPack"></param>
/// <returns></returns>
public static bool CheckSUM(byte[] dataPack)
{
if (dataPack == null || dataPack.Length < 2)
{
return false;
}
int sum = 0;
for (int i = 0; i < dataPack.Length - 1; i++)
{
sum = sum + dataPack[i];
}
//实际上num 这里已经是结果了如果只是取int 可以直接返回了
byte check = (byte)sum;
//如果最后一个字节等于校验和就是通过
if (dataPack[dataPack.Length - 1] == check)
{
return true;
}
return false;
}
/// <summary>
/// 校验数据包和校验
/// </summary>
/// <param name="hexPackData">一包16进制字符串数据</param>
/// <returns></returns>
public static bool CheckPackSUM(string hexPackData)
{
byte[] packData = ByteArrayConvert.HexStringToByteArray(hexPackData);
return CheckSUM(packData);
}
#endregion
/// <summary>
/// 获得读取的命令
/// 功能:传入寄存器获得,读取寄存器的命令
/// </summary>
/// <param name="reg">寄存器</param>
/// <returns></returns>
public static byte[] GetRead(int reg)
{
return new byte[] { 0xff,0xaa,0x27,(byte)reg, 0x00};
}
/// <summary>
/// 获得写入的命令
/// 功能:传入寄存器和值,得到写入寄存器的命令
/// </summary>
/// <param name="reg">寄存器</param>
/// <param name="value">值</param>
/// <returns></returns>
public static byte[] GetWrite(int reg, ushort value)
{
byte[] vs = new byte[] { 0xff, 0xaa, (byte)reg, (byte)value, (byte)(value >> 8) };
return new byte[] { 0xff, 0xaa, (byte)reg, (byte)value, (byte)(value>>8) };
}
/// <summary>
/// 查找返回的数据
/// 功能:从传感器返回的数据里找到第一包55 5F开头的数据包
/// </summary>
/// <param name="returnData">设备返回的数据</param>
/// <returns>成功返回55 5f数据包,失败返回null</returns>
public static byte[] FindReturnData(byte[] returnData)
{
byte[] tempArr = new byte[0];
for (int i = 0; i < returnData.Length; i++)
{
tempArr = returnData.Skip(i).Take(11).ToArray(); ;
if (tempArr.Length == 11 && tempArr[0] == 0x55 && tempArr[1] == 0x5F && CheckSUM(tempArr))
{
return tempArr;
}
}
return null;
}
}
}

View File

@ -1,56 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Modular.Sensor.Device;
using Wit.SDK.Modular.Sensor.Modular.ProtocolResolver.Enum;
namespace Wit.SDK.Modular.Sensor.Utils
{
/// <summary>
/// 维特智能传感器帮助类
/// </summary>
public class WitSensorHelper
{
/// <summary>
/// 读寄存器
/// </summary>
/// <param name="reg"></param>
public static void ReadReg(DeviceModel device, WitSensorProtocol sensorPotocol, int reg)
{
byte[] sendBytes = new byte[0];
if (sensorPotocol == WitSensorProtocol.Modbus16Protocol)
{
sendBytes = Modbus16Utils.GetRead(byte.Parse(device.GetAddr()), reg, 4);
}
else
{
sendBytes = new byte[] { 0xff, 0xaa, 0x27, (byte)reg, 0 };
}
device.ReadData(sendBytes);
}
/// <summary>
/// 写寄存器
/// </summary>
/// <param name="reg"></param>
public static void WriteReg(DeviceModel device, WitSensorProtocol sensorPotocol, int reg, ushort value)
{
byte[] sendBytes = new byte[8];
if (sensorPotocol == WitSensorProtocol.Modbus16Protocol)
{
sendBytes = Modbus16Utils.GetWrite(byte.Parse(device.GetAddr()), reg, value);
}
else
{
sendBytes = WitProtocolUtils.GetWrite(reg, value);
}
device.ReadData(sendBytes, 20);
}
}
}

View File

@ -1,51 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/// <summary>
/// GPS工具类
/// </summary>
namespace Wit.SDK.Utils
{
public class GpsUtils
{
/// <summary>
/// 经纬度度分秒转换为度 选定保留小数
/// </summary>
public static double DmsToD(double value, int digits)
{
//度
double Degree = Math.Floor(value / 100);
//分
double points = (value / 100 - Degree) * 100;
Degree = Degree + points / 60;
return Math.Round(Degree, digits);
}
/// <summary>
/// 经纬度度分秒转换为度
/// </summary>
public static double DmsToD(double value)
{
return DmsToD(value,7);
}
/// <summary>
///经纬度 度转换为度分
/// </summary>
public static double DToDms(double value)
{
//度
double Degree = Math.Floor(value);
//分
double points = (value - Degree) * 60.0;
Degree = Degree * 100 + points;
return Math.Round(Degree, 7);
}
}
}

View File

@ -1,75 +0,0 @@
using System;
using System.Diagnostics;
using System.Linq;
using Wit.SDK.Device.Device.Device.DKey;
using Wit.SDK.Modular.Sensor.Device;
using Wit.SDK.Modular.Sensor.Modular.ProtocolResolver.Interface;
using Wit.SDK.Modular.Sensor.Modular.Resolver.Utils;
using Wit.SDK.Modular.Sensor.Utils;
using Wit.SDK.Utils;
namespace Wit.SDK.Modular.Sensor.Modular.ProtocolResolver.Roles
{
/// <summary>
/// Resolvedor de Protocolo ModbusCRC16
/// </summary>
public class Modbus16Resolver : IProtocolResolver
{
/// <summary>
/// Analisa os dados retornados ativamente
/// </summary>
/// <param name="data"></param>
/// <param name="baseDevice"></param>
public override void OnReceiveData(DeviceModel baseDevice, byte[] data)
{
}
/// <summary>
/// Envia dados
/// </summary>
/// <param name="sendData"></param>
/// <param name="deviceModel"></param>
public override void OnReadData(DeviceModel deviceModel, byte[] sendData, int delay = -1)
{
try
{
delay = AutoDelayUtils.GetModbusAutoDelay(delay, deviceModel);
byte[] returnData;
// Envia dados
deviceModel.SendData(sendData, out returnData, true, delay);
// Se os dados retornados estiverem corretos
byte[] modbusBytes;
if (sendData != null && returnData != null && returnData.Length >= 7
&& Modbus16Utils.FindModbus(sendData, returnData, out modbusBytes))
{
int readReg = sendData[2] << 8 | sendData[3];
byte[] regData = modbusBytes.Skip(3).Take(modbusBytes.Length - 5).ToArray();
for (int j = 0; regData != null &&
j < regData.Length - 1; j += 2)
{
string key = string.Format("{0:X2}", readReg++);
short value = (short)(regData[j] << 8 | regData[j + 1]);
deviceModel.SetDeviceData(new ShortKey(key), value);
}
}
else
{
if (returnData != null && returnData.Length > 0)
{
Debug.WriteLine("Erro na verificação dos dados");
Debug.WriteLine(ByteArrayConvert.ByteArrayToHexString(returnData));
}
}
}
catch (Exception ex)
{
Console.WriteLine("Erro: " + ex.Message);
}
}
}
}

View File

@ -1,427 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using Wit.SDK.Device.Device.Device.DKey;
using Wit.SDK.Modular.Sensor.Device;
using Wit.SDK.Modular.Sensor.Device.Entity;
using Wit.SDK.Modular.Sensor.Modular.DataProcessor.Constant;
using Wit.SDK.Modular.Sensor.Modular.DataProcessor.Context;
using Wit.SDK.Modular.Sensor.Modular.DataProcessor.Interface;
using Wit.SDK.Modular.Sensor.Modular.DataProcessor.Utils;
using Wit.SDK.Modular.Sensor.Utils;
using Wit.SDK.Utils;
namespace Wit.SDK.Modular.Sensor.Modular.DataProcessor.Role
{
/// <summary>
/// WT901C485数据处理器
/// </summary>
public class WT901C485Processor : IDataProcessor
{
/// <summary>
/// 设备模型
/// </summary>
public DeviceModel DeviceModel { get; private set; }
/// <summary>
/// 控制读取数据线程是否运行
/// </summary>
bool ReadDataThreadRuning = false;
/// <summary>
/// 记录key值切换器
/// </summary>
private RecordKeySwitch RecordKeySwitch = new RecordKeySwitch();
/// <summary>
/// 数据刷新的key值
/// </summary>
List<string> UpdateKeys = new List<string>() {};
/// <summary>
/// 当传感器打开时
/// </summary>
/// <param name="deviceModel"></param>
public override void OnOpen(DeviceModel deviceModel)
{
for (int i = 0x30; i < 0x30 + 0x30; i++)
{
UpdateKeys.Add(string.Format("{0:X2}", i));
}
// 传入刷新数据的key值
RecordKeySwitch.Open(deviceModel, UpdateKeys);
this.DeviceModel = deviceModel;
Thread thread = new Thread(ReadDataThread) { IsBackground = true };
ReadDataThreadRuning = true;
thread.Start();
}
/// <summary>
/// 自动读取线程
/// </summary>
private void ReadDataThread()
{
while (ReadDataThreadRuning) {
try
{
// 暂停读取
while (DataProcessorContext.AutoReadPause) { Thread.Sleep(1000); }
//// 发送读取命令
//DeviceModel.SendProtocolData(
// Modbus16Utils.GetRead(byte.Parse(DeviceModel.GetDeviceData("ADDR")), 0x30, 0x30),
// DataProcessorContext.AutoReadInterval);
for (int i = 0; i < DataProcessorContext.ReadCmdList.Count; i++)
{
CmdBean cmdBean = DataProcessorContext.ReadCmdList[i];
byte[] cmd = CmdUtils.GenerationCmd(cmdBean.sendData, cmdBean.sendHex, cmdBean.sendNewLine, DeviceModel.DeviceData);
// 发送读取命令
DeviceModel.ReadData(cmd, DataProcessorContext.AutoReadInterval);
}
// 读取版本号寄存器
ReadVersionNumberReg(DeviceModel);
// 读取磁场类型寄存器
ReadMagType(DeviceModel);
// 读取序列号寄存器
ReadSerialNumberReg(DeviceModel);
}
catch (Exception e)
{
Debug.WriteLine("自动读取失败:" + e.Message);
}
}
// throw new NotImplementedException();
}
/// <summary>
/// 读取版本号寄存器
/// </summary>
/// <param name="deviceModel"></param>
private void ReadVersionNumberReg(DeviceModel deviceModel)
{
// 读版本号
if (deviceModel.GetDeviceData("2E") == null)
{
// 读版本号
deviceModel.ReadData(Modbus16Utils.GetRead(byte.Parse(deviceModel.GetDeviceData("ADDR")), 0x2e, 2));
Thread.Sleep(20);
}
}
/// <summary>
/// 读取序列号寄存器
/// </summary>
/// <param name="deviceModel"></param>
private void ReadSerialNumberReg(DeviceModel deviceModel)
{
// 读序列号
if (deviceModel.GetDeviceData("7F") == null && deviceModel.GetDeviceData("82") == null)
{
// 读序列号
deviceModel.ReadData(Modbus16Utils.GetRead(byte.Parse(deviceModel.GetDeviceData("ADDR")), 0x7F, 3));
deviceModel.ReadData(Modbus16Utils.GetRead(byte.Parse(deviceModel.GetDeviceData("ADDR")), 0x7F + 3, 3));
}
}
/// <summary>
/// 当传感器关闭时
/// </summary>
public override void OnClose(DeviceModel deviceModel)
{
ReadDataThreadRuning = false;
}
/// <summary>
/// 当触发数据更新时
/// </summary>
/// <param name="deviceModel"></param>
public override void OnUpdate(DeviceModel deviceModel)
{
// 版本号
var reg2e = deviceModel.GetDeviceData("2E");// 版本号
var reg2f = deviceModel.GetDeviceData("2F");// 版本号
// 如果有版本号
if (string.IsNullOrEmpty(reg2e) == false &&
string.IsNullOrEmpty(reg2f) == false)
{
var reg2eValue = (ushort)short.Parse(reg2e);
var vbytes = BitConverter.GetBytes((ushort)short.Parse(reg2e)).Concat(BitConverter.GetBytes((ushort)short.Parse(reg2f))).ToArray();
UInt32 tempVerSion = BitConverter.ToUInt32(vbytes, 0);
string sbinary = Convert.ToString(tempVerSion, 2);
sbinary = ("").PadLeft((32 - sbinary.Length), '0') + sbinary;
if (sbinary.StartsWith("1"))//新版本号
{
string tempNewVS = Convert.ToUInt32(sbinary.Substring(4 - 3, 14 + 3), 2).ToString();
tempNewVS += "." + Convert.ToUInt32(sbinary.Substring(18, 6), 2);
tempNewVS += "." + Convert.ToUInt32(sbinary.Substring(24), 2);
deviceModel.SetDeviceData(WitSensorKey.VersionNumber, tempNewVS);
}
else
{
deviceModel.SetDeviceData(WitSensorKey.VersionNumber, reg2eValue.ToString());
}
}
// 序列号
var reg7f = deviceModel.GetDeviceData("7F");// 序列号
var reg80 = deviceModel.GetDeviceData("80");// 序列号
var reg81 = deviceModel.GetDeviceData("81");// 序列号
var reg82 = deviceModel.GetDeviceData("82");// 序列号
var reg83 = deviceModel.GetDeviceData("83");// 序列号
var reg84 = deviceModel.GetDeviceData("84");// 序列号
if (string.IsNullOrEmpty(reg7f) == false &&
string.IsNullOrEmpty(reg80) == false &&
string.IsNullOrEmpty(reg81) == false &&
string.IsNullOrEmpty(reg82) == false &&
string.IsNullOrEmpty(reg83) == false &&
string.IsNullOrEmpty(reg84) == false)
{
var sbytes = BitConverter.GetBytes(short.Parse(reg7f))
.Concat(BitConverter.GetBytes(short.Parse(reg80)))
.Concat(BitConverter.GetBytes(short.Parse(reg81)))
.Concat(BitConverter.GetBytes(short.Parse(reg82)))
.Concat(BitConverter.GetBytes(short.Parse(reg83)))
.Concat(BitConverter.GetBytes(short.Parse(reg84)))
.ToArray();
string sn = Encoding.Default.GetString(sbytes);
deviceModel.SetDeviceData(WitSensorKey.SerialNumber, sn);
}
// 30代表传感器回传的30寄存器数据,其它的同理
var reg30 = deviceModel.GetDeviceData("30");// 年月
var reg31 = deviceModel.GetDeviceData("31");// 日时
var reg32 = deviceModel.GetDeviceData("32");// 分秒
var reg33 = deviceModel.GetDeviceData("33");// 毫秒
// 如果回传了时间数据包就解算时间
if (!string.IsNullOrEmpty(reg30) &&
!string.IsNullOrEmpty(reg31) &&
!string.IsNullOrEmpty(reg32) &&
!string.IsNullOrEmpty(reg33)
)
{
// 解算数据,并且保存到设备数据里
var yy = 2000 + (byte)int.Parse(reg30);
var MM = (byte)(int.Parse(reg30) >> 8);
var dd = (byte)int.Parse(reg31);
var hh = (byte)(int.Parse(reg31) >> 8);
var mm = (byte)int.Parse(reg32);
var ss = (byte)(int.Parse(reg32) >> 8);
var ms = int.Parse(reg33).ToString("000");
deviceModel.SetDeviceData(WitSensorKey.ChipTime, $"{yy}-{MM}-{dd} {hh}:{mm}:{ss}.{ms}");
}
var reg34 = deviceModel.GetDeviceData("34");// 加速度X
var reg35 = deviceModel.GetDeviceData("35");// 加速度X
var reg36 = deviceModel.GetDeviceData("36");// 加速度X
// 如果回传了加速度数据包
if (!string.IsNullOrEmpty(reg34) &&
!string.IsNullOrEmpty(reg35) &&
!string.IsNullOrEmpty(reg36)
)
{
// 解算数据,并且保存到设备数据里
deviceModel.SetDeviceData(WitSensorKey.AccX, Math.Round(double.Parse(reg34) / 32768.0 * 16,3));
deviceModel.SetDeviceData(WitSensorKey.AccY, Math.Round(double.Parse(reg35) / 32768.0 * 16,3));
deviceModel.SetDeviceData(WitSensorKey.AccZ, Math.Round(double.Parse(reg36) / 32768.0 * 16,3));
}
var reg37 = deviceModel.GetDeviceData("37");// 角速度X
var reg38 = deviceModel.GetDeviceData("38");// 角速度Y
var reg39 = deviceModel.GetDeviceData("39");// 角速度Z
// 如果回传了角速度数据包
if (!string.IsNullOrEmpty(reg37) &&
!string.IsNullOrEmpty(reg38) &&
!string.IsNullOrEmpty(reg39)
)
{
// 解算数据,并且保存到设备数据里
deviceModel.SetDeviceData(WitSensorKey.AsX, Math.Round(double.Parse(reg37) / 32768.0 * 2000,3));
deviceModel.SetDeviceData(WitSensorKey.AsY, Math.Round(double.Parse(reg38) / 32768.0 * 2000,3));
deviceModel.SetDeviceData(WitSensorKey.AsZ, Math.Round(double.Parse(reg39) / 32768.0 * 2000,3));
}
var reg3D = deviceModel.GetDeviceData("3D");// 角度X
var reg3E = deviceModel.GetDeviceData("3E");// 角度Y
var reg3F = deviceModel.GetDeviceData("3F");// 角度Z
// 如果回传了角度数据包
if (!string.IsNullOrEmpty(reg3D) &&
!string.IsNullOrEmpty(reg3E) &&
!string.IsNullOrEmpty(reg3F)
)
{
// 解算数据,并且保存到设备数据里
deviceModel.SetDeviceData(WitSensorKey.AngleX, Math.Round(double.Parse(reg3D) / 32768.0 * 180,3));
deviceModel.SetDeviceData(WitSensorKey.AngleY, Math.Round(double.Parse(reg3E) / 32768.0 * 180,3));
deviceModel.SetDeviceData(WitSensorKey.AngleZ, Math.Round(double.Parse(reg3F) / 32768.0 * 180,3));
}
var reg3A = deviceModel.GetDeviceData("3A");// 磁场X
var reg3B = deviceModel.GetDeviceData("3B");// 磁场Y
var reg3C = deviceModel.GetDeviceData("3C");// 磁场Z
var magType = deviceModel.GetDeviceData("72");// 磁场类型
// 如果回传了磁场数据包
if (!string.IsNullOrEmpty(reg3A) &&
!string.IsNullOrEmpty(reg3B) &&
!string.IsNullOrEmpty(reg3C) &&
!string.IsNullOrEmpty(magType)
)
{
short type = short.Parse(magType);
// 解算数据,并且保存到设备数据里
deviceModel.SetDeviceData(WitSensorKey.HX, DipSensorMagHelper.GetMagToUt(type, double.Parse(reg3A)));
deviceModel.SetDeviceData(WitSensorKey.HY, DipSensorMagHelper.GetMagToUt(type, double.Parse(reg3B)));
deviceModel.SetDeviceData(WitSensorKey.HZ, DipSensorMagHelper.GetMagToUt(type, double.Parse(reg3C)));
deviceModel.SetDeviceData(WitSensorKey.HM, Math.Round(Math.Sqrt(Math.Pow(DipSensorMagHelper.GetMagToUt(type, double.Parse(reg3A)), 2) +
Math.Pow(DipSensorMagHelper.GetMagToUt(type, double.Parse(reg3B)), 2) +
Math.Pow(DipSensorMagHelper.GetMagToUt(type, double.Parse(reg3C)), 2)), 2));
}
var reg40 = deviceModel.GetDeviceData("40");// 温度
// 如果回传了温度数据包
if (!string.IsNullOrEmpty(reg40))
{
deviceModel.SetDeviceData(WitSensorKey.T, Math.Round(double.Parse(reg40) / 100.0, 2));
}
var reg41 = deviceModel.GetDeviceData(new ShortKey("41"));// 端口0
var reg42 = deviceModel.GetDeviceData(new ShortKey("42"));// 端口1
var reg43 = deviceModel.GetDeviceData(new ShortKey("43"));// 端口2
var reg44 = deviceModel.GetDeviceData(new ShortKey("44"));// 端口3
// 如果回传了端口状态数据包
if (reg41 != null &&
reg42 != null &&
reg43 != null &&
reg44 != null
)
{
deviceModel.SetDeviceData(WitSensorKey.D0, (short)reg41);
deviceModel.SetDeviceData(WitSensorKey.D1, (short)reg42);
deviceModel.SetDeviceData(WitSensorKey.D2, (short)reg43);
deviceModel.SetDeviceData(WitSensorKey.D3, (short)reg44);
}
var reg45 = deviceModel.GetDeviceData("45");// 气压低位
var reg46 = deviceModel.GetDeviceData("46");// 气压高位
var reg47 = deviceModel.GetDeviceData("47");// 高度低位
var reg48 = deviceModel.GetDeviceData("48");// 高度高位
// 如果回传了气压高度数据包
if (!string.IsNullOrEmpty(reg45) &&
!string.IsNullOrEmpty(reg46) &&
!string.IsNullOrEmpty(reg47) &&
!string.IsNullOrEmpty(reg48)
) {
var pbytes = BitConverter.GetBytes(short.Parse(reg45)).Concat(BitConverter.GetBytes(short.Parse(reg46))).ToArray();
var hbytes = BitConverter.GetBytes(short.Parse(reg47)).Concat(BitConverter.GetBytes(short.Parse(reg48))).ToArray();
deviceModel.SetDeviceData(WitSensorKey.P, BitConverter.ToInt32(pbytes, 0));
deviceModel.SetDeviceData(WitSensorKey.H, (BitConverter.ToInt32(hbytes, 0) / 100.0));
}
var reg49 = deviceModel.GetDeviceData("49");// 经度低位
var reg4A = deviceModel.GetDeviceData("4A");// 经度高位
var reg4B = deviceModel.GetDeviceData("4B");// 纬度低位
var reg4C = deviceModel.GetDeviceData("4C");// 纬度高位
// 如果有经纬度输出
if (!string.IsNullOrEmpty(reg49) &&
!string.IsNullOrEmpty(reg4A) &&
!string.IsNullOrEmpty(reg4B) &&
!string.IsNullOrEmpty(reg48)
)
{
var lonbytes = BitConverter.GetBytes(short.Parse(reg49)).Concat(BitConverter.GetBytes(short.Parse(reg4A))).ToArray();
var lon = BitConverter.ToInt32(lonbytes, 0);
var latbytes = BitConverter.GetBytes(short.Parse(reg4B)).Concat(BitConverter.GetBytes(short.Parse(reg4C))).ToArray();
var lat = BitConverter.ToInt32(latbytes, 0);
double lon_D = GpsUtils.DmsToD((double)lon / 100000.0);
deviceModel.SetDeviceData(WitSensorKey.Lon, $"{lon_D}°");
deviceModel.SetDeviceData(WitSensorKey.LonDeg, Math.Round(lon_D,6));
double lat_D = GpsUtils.DmsToD((double)lat / 100000.0);
deviceModel.SetDeviceData(WitSensorKey.Lat, $"{lat_D}°");
deviceModel.SetDeviceData(WitSensorKey.LatDeg, Math.Round(lat_D,6));
}
var reg4D = deviceModel.GetDeviceData("4D");// GPS高度
var reg4E = deviceModel.GetDeviceData("4E");// GPS航向
var reg4F = deviceModel.GetDeviceData("4F");// 地速低位
var reg50 = deviceModel.GetDeviceData("50");// 地速高位
// 如果有地速包输出
if (!string.IsNullOrEmpty(reg4D) &&
!string.IsNullOrEmpty(reg4E) &&
!string.IsNullOrEmpty(reg4F) &&
!string.IsNullOrEmpty(reg50)
) {
var svbytes = BitConverter.GetBytes(short.Parse(reg4F)).Concat(BitConverter.GetBytes(short.Parse(reg50))).ToArray();
deviceModel.SetDeviceData(WitSensorKey.GPSHeight, Math.Round(short.Parse(reg4D)/ 10.0,3));
byte[] temp = BitConverter.GetBytes(short.Parse(reg4E)); // 航向解算不要负数
uint reg4EValue = BitConverter.ToUInt16(temp, 0);
deviceModel.SetDeviceData(WitSensorKey.GPSYaw, Math.Round(reg4EValue / 100.0,3));
deviceModel.SetDeviceData(WitSensorKey.GPSV, Math.Round(BitConverter.ToInt32(svbytes, 0) / 1e3,3));
}
var reg51 = deviceModel.GetDeviceData("51");// 四元数0
var reg52 = deviceModel.GetDeviceData("52");// 四元数1
var reg53 = deviceModel.GetDeviceData("53");// 四元数2
var reg54 = deviceModel.GetDeviceData("54");// 四元数3
// 如果有四元数输出
if (!string.IsNullOrEmpty(reg51) &&
!string.IsNullOrEmpty(reg52) &&
!string.IsNullOrEmpty(reg53) &&
!string.IsNullOrEmpty(reg54)
)
{
deviceModel.SetDeviceData(WitSensorKey.Q0, Math.Round(short.Parse(reg51) / 32768.0,3));
deviceModel.SetDeviceData(WitSensorKey.Q1, Math.Round(short.Parse(reg52) / 32768.0,3));
deviceModel.SetDeviceData(WitSensorKey.Q2, Math.Round(short.Parse(reg53) / 32768.0,3));
deviceModel.SetDeviceData(WitSensorKey.Q3, Math.Round(short.Parse(reg54) / 32768.0,3));
}
var reg55 = deviceModel.GetDeviceData("55");// 卫星数
var reg56 = deviceModel.GetDeviceData("56");// 位置精度
var reg57 = deviceModel.GetDeviceData("57");// 位置精度
var reg58 = deviceModel.GetDeviceData("58");// 位置精度
// 如果有位置精度输出
if (!string.IsNullOrEmpty(reg55) &&
!string.IsNullOrEmpty(reg56) &&
!string.IsNullOrEmpty(reg57) &&
!string.IsNullOrEmpty(reg58)
)
{
deviceModel.SetDeviceData(WitSensorKey.SN, short.Parse(reg55));
deviceModel.SetDeviceData(WitSensorKey.PDOP, Math.Round(short.Parse(reg56) / 100.0,3));
deviceModel.SetDeviceData(WitSensorKey.HDOP, Math.Round(short.Parse(reg57) / 100.0,3));
deviceModel.SetDeviceData(WitSensorKey.VDOP, Math.Round(short.Parse(reg58) / 100.0,3));
}
}
/// <summary>
/// 读取磁场类型寄存器
/// </summary>
private void ReadMagType(DeviceModel deviceModel) {
// 读版本号
if (deviceModel.GetDeviceData("72") == null)
{
// 读取72磁场类型寄存器,后面解析磁场的时候要用到(读三次避免读不上)
deviceModel.ReadData(Modbus16Utils.GetRead(byte.Parse(deviceModel.GetDeviceData("ADDR")), 0x72, 1));
Thread.Sleep(20);
}
}
}
}

View File

@ -1,143 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wit.SDK.Device.Device.Device.DKey;
namespace Wit.SDK.Modular.Sensor.Modular.DataProcessor.Constant
{
/// <summary>
/// Constantes padrão de chave do sensor de inclinação
/// </summary>
public static class WitSensorKey
{
// Tempo do chip
public static StringKey ChipTime { get; } = new StringKey("ChipTime");
// Aceleração X
public static DoubleKey AccX { get; } = new DoubleKey("AccX");
// Aceleração Y
public static DoubleKey AccY { get; } = new DoubleKey("AccY");
// Aceleração Z
public static DoubleKey AccZ { get; } = new DoubleKey("AccZ");
// Soma vetorial da aceleração
public static DoubleKey AccM { get; } = new DoubleKey("AccM");
// Velocidade angular X
public static DoubleKey AsX { get; } = new DoubleKey("AsX");
// Velocidade angular Y
public static DoubleKey AsY { get; } = new DoubleKey("AsY");
// Velocidade angular Z
public static DoubleKey AsZ { get; } = new DoubleKey("AsZ");
// Soma vetorial da velocidade angular Z
public static DoubleKey AsM { get; } = new DoubleKey("AsM");
// Ângulo X
public static DoubleKey AngleX { get; } = new DoubleKey("AngleX");
// Ângulo Y
public static DoubleKey AngleY { get; } = new DoubleKey("AngleY");
// Ângulo Z
public static DoubleKey AngleZ { get; } = new DoubleKey("AngleZ");
// Campo magnético X
public static DoubleKey HX { get; } = new DoubleKey("HX");
// Campo magnético Y
public static DoubleKey HY { get; } = new DoubleKey("HY");
// Campo magnético Z
public static DoubleKey HZ { get; } = new DoubleKey("HZ");
// Soma vetorial do campo magnético
public static DoubleKey HM { get; } = new DoubleKey("HM");
// Temperatura
public static DoubleKey T { get; } = new DoubleKey("T");
// Porta de expansão 1
public static ShortKey D0 { get; } = new ShortKey("D0");
// Porta de expansão 2
public static ShortKey D1 { get; } = new ShortKey("D1");
// Porta de expansão 3
public static ShortKey D2 { get; } = new ShortKey("D2");
// Porta de expansão 4
public static ShortKey D3 { get; } = new ShortKey("D3");
// Pressão
public static DoubleKey P { get; } = new DoubleKey("P");
// Altura
public static DoubleKey H { get; } = new DoubleKey("H");
// Longitude
public static StringKey Lon { get; } = new StringKey("Lon");
// Representação em graus da longitude
public static DoubleKey LonDeg { get; } = new DoubleKey("LonDeg");
// Latitude
public static StringKey Lat { get; } = new StringKey("Lat");
// Representação em graus da latitude
public static DoubleKey LatDeg { get; } = new DoubleKey("LatDeg");
/// <summary>
/// Status do GPS
/// </summary>
public static DoubleKey GPSStatus { get; } = new DoubleKey("GPSStatus");
// Altura do GPS
public static DoubleKey GPSHeight { get; } = new DoubleKey("GPSHeight");
// Direção do GPS
public static DoubleKey GPSYaw { get; } = new DoubleKey("GPSYaw");
// Velocidade do GPS
public static DoubleKey GPSV { get; } = new DoubleKey("GPSV");
// Quaternio 0
public static DoubleKey Q0 { get; } = new DoubleKey("Q0");
// Quaternio 1
public static DoubleKey Q1 { get; } = new DoubleKey("Q1");
// Quaternio 2
public static DoubleKey Q2 { get; } = new DoubleKey("Q2");
// Quaternio 3
public static DoubleKey Q3 { get; } = new DoubleKey("Q3");
// Número de satélites
public static IntKey SN { get; } = new IntKey("SN");
// Precisão da localização
public static DoubleKey PDOP { get; } = new DoubleKey("PDOP");
// Precisão da localização horizontal
public static DoubleKey HDOP { get; } = new DoubleKey("HDOP");
// Precisão da localização vertical
public static DoubleKey VDOP { get; } = new DoubleKey("VDOP");
// Número da versão
public static StringKey VersionNumber { get; } = new StringKey("VersionNumber");
// Número de série
public static StringKey SerialNumber { get; } = new StringKey("SerialNumber");
// Percentual de energia
public static DoubleKey PowerPercent { get; } = new DoubleKey("PowerPercent");
}
}

View File

@ -1,337 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using Wit.SDK.Device.Device.Device.DKey;
using Wit.SDK.Modular.Sensor.Device;
using Wit.SDK.Modular.Sensor.Device.Entity;
using Wit.SDK.Modular.Sensor.Modular.Connector.Entity;
using Wit.SDK.Modular.Sensor.Modular.Connector.Interface;
using Wit.SDK.Modular.Sensor.Modular.Connector.Role;
using Wit.SDK.Modular.Sensor.Modular.DataProcessor.Context;
using Wit.SDK.Modular.Sensor.Modular.DataProcessor.Role;
using Wit.SDK.Modular.Sensor.Modular.ProtocolResolver.Roles;
using Wit.SDK.Modular.Sensor.Utils;
using Wit.SDK.Modular.WitSensorApi.Interface;
namespace Wit.SDK.Modular.WitSensorApi.Modular.WT901C485
{
/// <summary>
/// WT901C485连接类
/// </summary>
public class WT901C485 : IAttitudeSensorApi
{
/// <summary>
/// 设备模型
/// </summary>
private DeviceModel DeviceModel;
/// <summary>
/// 连接器
/// </summary>
private SPConnector connector = new SPConnector(new SerialPortConfig());
/// <summary>
/// 记录数据委托
/// </summary>
public delegate void OnRecordHandler(WT901C485 BWT901BLE);
/// <summary>
/// 记录数据事件
/// </summary>
public event OnRecordHandler OnRecord;
/// <summary>
/// 构造方法
/// </summary>
/// <param name="portName"></param>
/// <param name="baudrate"></param>
public WT901C485()
{
// 创建一个连接WT901C485的设备模型
DeviceModel deviceModel = new DeviceModel($"", $"",
new Modbus16Resolver(),
new WT901C485Processor(),
"34");
deviceModel.Connector = connector;
DeviceModel = deviceModel;
// 自动读取命令
DataProcessorContext.ReadCmdList = new List<CmdBean>()
{
new CmdBean(){
sendData = "${ADDR} 03 00 30 00 30 ${CRC16}",
sendHex = true
}
};
}
/// <summary>
/// 指定串口号
/// </summary>
/// <param name="portName"></param>
public void SetPortName(string portName)
{
connector.SerialPortConfig.PortName = portName;
DeviceModel.DeviceName = $"{portName}";
}
/// <summary>
/// 指定波特率
/// </summary>
/// <param name="baudrate"></param>
public void SetBaudrate(int baudRate)
{
connector.SerialPortConfig.BaudRate = baudRate;
}
/// <summary>
/// 打开设备
/// </summary>
public void Open()
{
DeviceModel.OpenDevice();
DeviceModel.OnListenKeyUpdate += DeviceModel_OnListenKeyUpdate;
}
/// <summary>
/// 是否打开的
/// </summary>
public bool IsOpen()
{
return DeviceModel.IsOpen;
}
/**
*
*
* @author huangyajun
* @date 2022/6/28 20:51
*/
public void Close()
{
DeviceModel.CloseDevice();
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="data">需要发送出去的数据</param>
/// <param name="returnData">传感器返回的数据</param>
/// <param name="isWaitReturn">是否需要传感器返回数据</param>
/// <param name="waitTime">等待传感器返回数据时间单位ms默认100ms</param>
/// <param name="repetition">重复发送次数</param>
public void SendData(byte[] data, out byte[] returnData, bool isWaitReturn = false, int waitTime = 100, int repetition = 1)
{
DeviceModel.SendData(data, out returnData, isWaitReturn, waitTime, repetition);
}
/// <summary>
/// 发送带协议的数据,使用默认等待时长
/// </summary>
/// <param name="data">数据</param>
public void SendProtocolData(byte[] data)
{
DeviceModel.ReadData(data);
}
/// <summary>
/// 发送带协议的数据,并且指定等待时长
/// </summary>
/// <param name="data">数据</param>
/// <param name="waitTime">等待时间</param>
public void SendProtocolData(byte[] data, int waitTime)
{
DeviceModel.ReadData(data, waitTime);
}
/// <summary>
/// 发送读取寄存器的命令
/// </summary>
/// <param name="reg"></param>
/// <param name="waitTime"></param>
public void SendReadReg(byte reg, int waitTime)
{
var read03Bytes = Modbus16Utils.GetRead(byte.Parse(DeviceModel.GetDeviceData("ADDR")), reg, 0x1);
DeviceModel.ReadData(read03Bytes);
}
/// <summary>
/// 解锁寄存器
/// </summary>
public void UnlockReg()
{
byte addr = GetModbusId();
byte[] setting = Modbus16Utils.GetWrite(addr, 0x69, 0xB588);
SendProtocolData(setting);
}
/// <summary>
/// 保存寄存器
/// </summary>
public void SaveReg()
{
byte addr = GetModbusId();
byte[] setting = Modbus16Utils.GetWrite(addr, 0x00, 0x0000);
SendProtocolData(setting);
}
/// <summary>
/// 加计校准
/// </summary>
public void AppliedCalibration()
{
byte addr = GetModbusId();
byte[] setting = Modbus16Utils.GetWrite(addr, 0x01, 0x01);
SendProtocolData(setting);
}
/// <summary>
/// 开始磁场校准
/// </summary>
public void StartFieldCalibration()
{
byte addr = GetModbusId();
byte[] setting = Modbus16Utils.GetWrite(addr, 0x01, 0x07);
SendProtocolData(setting);
}
/// <summary>
/// 结束磁场校准
/// </summary>
public void EndFieldCalibration()
{
byte addr = GetModbusId();
byte[] setting = Modbus16Utils.GetWrite(addr, 0x01, 0x00);
SendProtocolData(setting);
}
/// <summary>
/// 设置带宽
/// </summary>
/// <param name="rate"></param>
public void SetBandWidth(byte band)
{
byte addr = GetModbusId();
byte[] setting = Modbus16Utils.GetWrite(addr, 0x1F, band);
SendProtocolData(setting);
}
/// <summary>
/// 指定ModbusId
/// </summary>
/// <param name="modbusId"></param>
public void SetModbusId(byte modbusId)
{
if (DeviceModel.IsOpen)
{
try
{
byte addr = GetModbusId();
byte[] setting = Modbus16Utils.GetWrite(addr, 0x1A, modbusId);
SendProtocolData(setting);
}
catch (Exception)
{
//Debug.WriteLine(e.Message);
//Debug.WriteLine(e.StackTrace);
}
}
// 更改上位机地址
DeviceModel.SetAddr(modbusId.ToString());
}
/// <summary>
/// 获得设备地址
/// </summary>
/// <returns></returns>
public byte GetModbusId()
{
byte addr = 0;
try
{
addr = byte.Parse(DeviceModel.GetAddr());
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
Debug.WriteLine(e.StackTrace);
}
return addr;
}
/// <summary>
/// 获得设备名称
/// </summary>
/// <returns></returns>
public string GetDeviceName()
{
return DeviceModel.DeviceName;
}
/// <summary>
/// 获得数据
/// </summary>
/// <param name="key">数据键值</param>
/// <returns></returns>
public string GetDeviceData(string key)
{
return DeviceModel.GetDeviceData(key);
}
/// <summary>
/// 获得数据
/// </summary>
/// <param name="key">数据键值</param>
/// <returns></returns>
public short? GetDeviceData(ShortKey key)
{
return DeviceModel.GetDeviceData(key);
}
/// <summary>
/// 获得数据
/// </summary>
/// <param name="key">数据键值</param>
/// <returns></returns>
public string GetDeviceData(StringKey key)
{
return DeviceModel.GetDeviceData(key);
}
/// <summary>
/// 获得数据
/// </summary>
/// <param name="key">数据键值</param>
/// <returns></returns>
public double? GetDeviceData(DoubleKey key)
{
return DeviceModel.GetDeviceData(key);
}
/// <summary>
/// 传感器数据更新时
/// </summary>
/// <param name="deviceModel"></param>
public void DeviceModel_OnListenKeyUpdate(DeviceModel deviceModel)
{
OnRecord?.Invoke(this);
}
/// <summary>
/// 无设置回传速率
/// </summary>
/// <param name="rate"></param>
public void SetReturnRate(byte rate)
{
// 无设置回传速率
}
}
}

View File

@ -11,7 +11,6 @@ using System.Threading.Tasks;
using System.Windows.Forms;
using static AgroBase.Models.Enuns;
using System.Drawing.Drawing2D;
using Wit.SDK.Modular.WitSensorApi.Modular.WT901C485;
namespace AgroBase.Models
{
@ -26,6 +25,7 @@ namespace AgroBase.Models
public static OperacaoModel OperacaoEmAndamento { get; set; } = new OperacaoModel(ModoOperacao.Manual);
public static MqttService MqttService { get; set; } = new MqttService("localhost", 1883);
public static List<T_Code> DispositivosConexaoInicial = new List<T_Code>() { T_Code.Mvd, T_Code.Atu, T_Code.Sen };
public static List<T_Code> DispositivosModbus = new List<T_Code>() { T_Code.Pzm, T_Code.Wit };
public static SensorSinaleiroComportamentoModel ComportamentoPorStatus(StatusOperacao? _status = null)
{
if (_status == null)
@ -104,7 +104,6 @@ namespace AgroBase.Models
return comportamento;
}
public static LoRaService ConexaoLoRa = new LoRaService();
public static WT901C485 WT901C = new WT901C485();
}

View File

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AgroBase.Models
{
public class WT901CModel
{
public string Versao { get; set; }
public DateTime DataHora { get; set; }
public double AccX { get; set; }
public double AccY { get; set; }
public double AccZ { get; set; }
public double AccM { get; set; }
public double AsX { get; set; }
public double AsY { get; set; }
public double AsZ { get; set; }
public double AsM { get; set; }
public double AngleX { get; set; }
public double AngleY { get; set; }
public double AngleZ { get; set; }
public double HX { get; set; }
public double HY { get; set; }
public double HZ { get; set; }
public double HM { get; set; }
public double Temperatura { get; set; }
public double Pressao { get; set; }
public double Altitude { get; set; }
public short D0 { get; set; }
public short D1 { get; set; }
public short D2 { get; set; }
public short D3 { get; set; }
public double Q0 { get; set; }
public double Q1 { get; set; }
public double Q2 { get; set; }
public double Q3 { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public double GPS_Altitude { get; set; }
public double GPS_Orientacao { get; set; }
public double GPS_Velcodiade { get; set; }
public double GPS_NumeroSatelites { get; set; }
public double PDOP { get; set; }
public double HDOP { get; set; }
public double VDOP { get; set; }
}
}

View File

@ -828,7 +828,7 @@ namespace AgroBase.Comum
{
if (ProtocoloConfiguracao.Key != "" && ProtocoloConfiguracao.Value.Any())
{
ProtocoloConfiguracao.Value.ForEach(x => AdicionarMensagemFila(ProtocoloConfiguracao.Key, x, true, false));
ProtocoloConfiguracao.Value.ForEach(x => AdicionarMensagemFila(ProtocoloConfiguracao.Key, x, true, true));
}
}
}
@ -843,7 +843,7 @@ namespace AgroBase.Comum
{
if (ProtocoloConfiguracao.Key != "" && ProtocoloConfiguracao.Value.Any())
{
ProtocoloConfiguracao.Value.ForEach(x => AdicionarMensagemFila(ProtocoloConfiguracao.Key, x, true, false));
ProtocoloConfiguracao.Value.ForEach(x => AdicionarMensagemFila(ProtocoloConfiguracao.Key, x, true, true));
}
}
}

View File

@ -1,14 +1,60 @@
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Emgu.CV.ML.KNearest;
namespace AgroBase.Services
{
public class ModbusService
{
public static readonly object _lock = new object();
public static bool Verificando { get; set; } = false;
public static bool EnvioLiberado { get; set; } = true;
public static SerialPort _PortaModbus;
public static bool Iniciado
{
get
{
if (_PortaModbus != null && !_PortaModbus.IsOpen)
{
try
{
_PortaModbus.Open();
}
catch
{
_PortaModbus = null;
}
}
return _PortaModbus != null && _PortaModbus.IsOpen;
}
}
public static async Task EnviarComando(byte[] Comando)
{
while (!EnvioLiberado || Verificando)
{
await Task.Delay(100);
}
EnvioLiberado = false;
if (Iniciado)
{
_PortaModbus.Write(Comando, 0, Comando.Length);
await Task.Delay(200);
}
EnvioLiberado = true;
}
public static byte[] Crc16(byte[] data)
{
ushort crc = 0xFFFF;
@ -125,6 +171,78 @@ namespace AgroBase.Services
return command.ToArray();
}
public static bool FindModbus(byte[] sendByte, byte[] returnByte, out byte[] modbus)
{
int height = sendByte[4];
int low = sendByte[5];
// 得到长度
int len = 5 + (height << 8 | low) * 2;
// 如果没有返回结果,或者返回结果根本不够长
if (returnByte == null || returnByte.Length < len)
{
modbus = new byte[0];
return false;
}
// 遍历返回结果查找
for (int i = 0; i <= returnByte.Length - len; i++)
{
byte rAddr = returnByte[i];
byte mark = 0x03;
byte[] cCrc = GetCrc16(returnByte.Skip(i).Take(len - 2).ToArray());
byte rCrcH = returnByte[i + len - 2];
byte rCrcL = returnByte[i + len - 1];
// 如果全部通过
if (sendByte[0] == rAddr && mark == sendByte[1] && rCrcH == cCrc[0] && rCrcL == cCrc[1])
{
modbus = returnByte.Skip(i).Take(len).ToArray();
return true;
}
}
modbus = new byte[0];
return false;
}
private static byte[] GetCrc16(byte[] bytes)
{
byte crcRegister_H = 0xFF, crcRegister_L = 0xFF;// 预置一个值为 0xFFFF 的 16 位寄存器
byte polynomialCode_H = 0xA0, polynomialCode_L = 0x01;// 多项式码 0xA001
for (int i = 0; i < bytes.Length; i++)
{
crcRegister_L = (byte)(crcRegister_L ^ bytes[i]);
for (int j = 0; j < 8; j++)
{
byte tempCRC_H = crcRegister_H;
byte tempCRC_L = crcRegister_L;
crcRegister_H = (byte)(crcRegister_H >> 1);
crcRegister_L = (byte)(crcRegister_L >> 1);
// 高位右移前最后 1 位应该是低位右移后的第 1 位:如果高位最后一位为 1 则低位右移后前面补 1
if ((tempCRC_H & 0x01) == 0x01)
{
crcRegister_L = (byte)(crcRegister_L | 0x80);
}
if ((tempCRC_L & 0x01) == 0x01)
{
crcRegister_H = (byte)(crcRegister_H ^ polynomialCode_H);
crcRegister_L = (byte)(crcRegister_L ^ polynomialCode_L);
}
}
}
return new byte[] { crcRegister_L, crcRegister_H };
}
}

View File

@ -18,32 +18,16 @@ namespace AgroBase.Services
{
public class PZEMService
{
public static SerialPort PortaPZEM = null;
public static bool Iniciado
{
get
{
if (PortaPZEM != null && !PortaPZEM.IsOpen)
{
try
{
PortaPZEM.Open();
}
catch
{
PortaPZEM = null;
}
}
return PortaPZEM != null && PortaPZEM.IsOpen;
}
}
public static bool Iniciado { get; set; }
public static int TaxaAmostragem { get; set; } = 1000;
private static byte slaveAddress = 0x01;
public static PZEMModel UltimaLeitura = new PZEMModel();
public static PZEMModel PenultimaLeitura = new PZEMModel();
public static double TensaoMinima { get; set; } = 30;
public static double TensaoMaxima { get; set; } = 42;
private static byte slaveAddress = 0x01;
public static Dictionary<string, byte> CodigosFuncoes = new Dictionary<string, byte>()
{
{ "LeituraParametro", 0x03 },
@ -72,36 +56,43 @@ namespace AgroBase.Services
EnviarComando(porta, comando);
await Task.Delay(1000);
var resposta = SerialService.VerificarRespostaPortasDesconhecidas(porta);
if (resposta.Length > 3 && resposta[1] == CodigosFuncoes["LeituraParametro"] && DecifrarRespostaAquisicao(resposta) != null)
Iniciado = DecifrarRespostaAquisicao(resposta) != null;
if (resposta.Length > 3 && resposta[1] == CodigosFuncoes["LeituraParametro"] && Iniciado)
{
AtualizarPortaCOM(porta);
return Iniciado;
}
porta.Close();
if (!ModbusService.Iniciado)
{
porta.Close();
}
return false;
}
public static void AtualizarPortaCOM(SerialPort Porta)
{
if (PortaPZEM == null)
if (ModbusService._PortaModbus == null || !ModbusService.Iniciado)
{
PortaPZEM = new SerialPort();
}
else if (Iniciado)
{
PortaPZEM.Close();
lock (ModbusService._lock)
{
ModbusService._PortaModbus = new SerialPort();
ModbusService._PortaModbus.BaudRate = Porta.BaudRate;
ModbusService._PortaModbus.PortName = Porta.PortName;
}
}
PortaPZEM.BaudRate = Porta.BaudRate;
PortaPZEM.PortName = Porta.PortName;
PortaPZEM.DataReceived -= PortaPZEM_DataReceived;
PortaPZEM.DataReceived += PortaPZEM_DataReceived;
Porta.Close();
if (ModbusService._PortaModbus != null && !ModbusService._PortaModbus.IsOpen)
{
Porta.Close();
}
if (Iniciado)
{
bool i = ModbusService.Iniciado;
DefinirDispositivo();
ContadorCarga = new CoulombCounterService(VariaveisEquipamento.BateriaMax);
ReceberDados().ConfigureAwait(false);
@ -115,7 +106,7 @@ namespace AgroBase.Services
{
SerialService.DispositivosMapeados.Add(new SerialService.DispositivoDetalhesModel()
{
PortaCOM = PortaPZEM.PortName,
PortaCOM = ModbusService._PortaModbus.PortName,
Dispositivo = T_Code.Pzm,
Erro = !Iniciado,
Versao = 17
@ -139,39 +130,35 @@ namespace AgroBase.Services
}
}
public static void PortaPZEM_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (PortaPZEM.IsOpen)
{
PenultimaLeitura = new PZEMModel()
{
AlarmeTensaoMax = UltimaLeitura.AlarmeTensaoMax,
AlarmeTensaoMin = UltimaLeitura.AlarmeTensaoMin,
Corrente = UltimaLeitura.Corrente,
DataHora = UltimaLeitura.DataHora,
Energia = UltimaLeitura.Energia,
Potencia = UltimaLeitura.Potencia,
Tensao = UltimaLeitura.Tensao
};
int bytesToRead = PortaPZEM.BytesToRead;
byte[] buffer = new byte[bytesToRead];
PortaPZEM.Read(buffer, 0, bytesToRead);
DecifrarRespostaAquisicao(buffer);
ContadorCarga.AtualizarConsumo();
double percent = FuncoesMatematicas.Map(UltimaLeitura.Tensao, TensaoMinima, TensaoMaxima, 0, 100);
Variaveis.OperacaoEmAndamento.Sensoriamento.PorcentagemBateria = percent;
frmInstancial.frmAcompanhamento.AtualizarSensores("Bateria: " + UltimaLeitura.Tensao.ToString("0.00") + " V - " + UltimaLeitura.Corrente.ToString("0.00") + " A - " + UltimaLeitura.Potencia.ToString("0.00") + " W");
Variaveis.OperacaoEmAndamento.Sensoriamento.BateriaConsumida = ContadorCarga.PercentualConsumido;
}
}
private static async Task<bool> ReceberDados()
{
EnviarComando(PortaPZEM, ComandoAquisicaoDados());
await Task.Delay(1000);
PenultimaLeitura = new PZEMModel()
{
AlarmeTensaoMax = UltimaLeitura.AlarmeTensaoMax,
AlarmeTensaoMin = UltimaLeitura.AlarmeTensaoMin,
Corrente = UltimaLeitura.Corrente,
DataHora = UltimaLeitura.DataHora,
Energia = UltimaLeitura.Energia,
Potencia = UltimaLeitura.Potencia,
Tensao = UltimaLeitura.Tensao
};
await ModbusService.EnviarComando(ComandoAquisicaoDados());
byte[] resposta = SerialService.VerificarRespostaPortasDesconhecidas(ModbusService._PortaModbus);
Iniciado = DecifrarRespostaAquisicao(resposta) != null;
ContadorCarga.AtualizarConsumo();
double percent = FuncoesMatematicas.Map(UltimaLeitura.Tensao, TensaoMinima, TensaoMaxima, 0, 100);
Variaveis.OperacaoEmAndamento.Sensoriamento.PorcentagemBateria = percent;
frmInstancial.frmAcompanhamento.AtualizarSensores("Bateria: " + UltimaLeitura.Tensao.ToString("0.00") + " V - " + UltimaLeitura.Corrente.ToString("0.00") + " A - " + UltimaLeitura.Potencia.ToString("0.00") + " W");
Variaveis.OperacaoEmAndamento.Sensoriamento.BateriaConsumida = ContadorCarga.PercentualConsumido;
await Task.Delay(TaxaAmostragem);
return await ReceberDados();
}

View File

@ -110,6 +110,12 @@ namespace AgroBase.Services
AtualizarDispositivos();
}
// Se algum dispositivo no barramento RS485 para Modbus já foi identificado
if (ModbusService.Iniciado && DispositivosMapeados.Where(x => Variaveis.DispositivosModbus.Contains(x.Dispositivo)).Count() != Variaveis.DispositivosModbus.Count())
{
await ProcuraDispositivoModbus(ModbusService._PortaModbus, false);
}
VarreduraEmAndamento = false;
}
@ -232,14 +238,12 @@ namespace AgroBase.Services
// Método para tentar identificar dispositivos que não respondem ao comando de verificação padrão
try
{
if (!PZEMService.Iniciado)
bool DispModbus = await ProcuraDispositivoModbus(porta, true);
if (DispModbus)
{
bool Encontrado = await PZEMService.VerificaPortaPZEM(porta);
if (Encontrado)
{
return Encontrado;
}
return true;
}
if (!LoRaService.Iniciado)
{
bool Encontrado = await LoRaService.VerificaPortaLoRa(porta);
@ -256,14 +260,7 @@ namespace AgroBase.Services
return Encontrado;
}
}
if (false && !WT901CService.Iniciado)
{
bool Encontrado = await WT901CService.VerificaPortaWT901C(porta);
if (Encontrado)
{
return Encontrado;
}
}
if (TentativasPortas.TryGetValue(porta.PortName, out int tentativas))
@ -291,13 +288,46 @@ namespace AgroBase.Services
return false;
}
private static async Task<bool> ProcuraDispositivoModbus(SerialPort porta, bool PararAoEncontrar)
{
ModbusService.Verificando = true;
bool Encontrado = false;
if (!PZEMService.Iniciado)
{
Encontrado = await PZEMService.VerificaPortaPZEM(porta);
if (Encontrado && PararAoEncontrar)
{
return Encontrado;
}
}
if (!WT901CService.Iniciado)
{
Encontrado = await WT901CService.VerificaPortaWT901C(porta);
if (Encontrado && PararAoEncontrar)
{
return Encontrado;
}
}
ModbusService.Verificando = false;
return Encontrado;
}
public static byte[] VerificarRespostaPortasDesconhecidas(SerialPort Porta)
{
int bytesToRead = Porta.BytesToRead;
byte[] buffer = new byte[bytesToRead];
Porta.Read(buffer, 0, bytesToRead);
//Porta.DiscardInBuffer();
return buffer;
if (Porta.IsOpen)
{
int bytesToRead = Porta.BytesToRead;
byte[] buffer = new byte[bytesToRead];
Porta.Read(buffer, 0, bytesToRead);
//Porta.DiscardInBuffer();
return buffer;
}
else
{
return new byte[] { };
}
}
public static byte[] LerDadosDaPortaSerial(SerialPort porta, int tamanhoEsperado)

View File

@ -7,82 +7,103 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static AgroBase.Models.Enuns;
using System.Windows.Forms;
using Wit.SDK.Modular.Sensor.Modular.DataProcessor.Constant;
using Wit.SDK.Modular.WitSensorApi.Modular.WT901C485;
namespace AgroBase.Services
{
public class WT901CService
{
public static SerialPort PortaWT901C = null;
public static bool Iniciado
{
get
{
if (Variaveis.WT901C.IsOpen())
{
return true;
}
else if (PortaWT901C == null)
{
return false;
}
try
{
Variaveis.WT901C.SetPortName(PortaWT901C.PortName);
Variaveis.WT901C.SetBaudrate(PortaWT901C.BaudRate);
Variaveis.WT901C.SetModbusId(slaveAddress);
Variaveis.WT901C.Open();
Variaveis.WT901C.OnRecord += WT901C485_OnRecord;
}
catch (Exception ex)
{
return false;
}
return Variaveis.WT901C.IsOpen();
}
}
//public static SerialPort PortaWT901C = null;
public static bool Iniciado { get; set; }
public static int TaxaAmostragem { get; set; } = 1000;
public static byte slaveAddress = 0x50;
private static Dictionary<string, object> DadosSensor { get; } = new Dictionary<string, object>();
public static WT901CModel DadosLeitura { get; set; } = new WT901CModel();
private static byte[] ComandoAquisicao = new byte[8] { slaveAddress, 0x03, 0x00, 0x30, 0x00, 0x30, 0x48, 0x50 };
public static async Task<bool> VerificaPortaWT901C(SerialPort porta)
{
porta.BaudRate = 9600;
AtualizarPortaCOM(porta);
return Iniciado;
var comando = ModbusService.ComandoGetParametro(slaveAddress, new ModbusParametrosModel() { FuncaoGet = 0x03, N_Registros = 2, Registro = 0x2e });
EnviarComando(porta, comando);
await Task.Delay(1000);
var resposta = SerialService.VerificarRespostaPortasDesconhecidas(porta);
Iniciado = DecifrarRespostaAquisicao(comando, resposta);
if (resposta.Length > 3 && resposta[1] == 0x03 && Iniciado)
{
AtualizarPortaCOM(porta);
return Iniciado;
}
if (!ModbusService.Iniciado)
{
porta.Close();
}
return false;
}
public static void AtualizarPortaCOM(SerialPort Porta)
{
if (PortaWT901C == null)
if (ModbusService._PortaModbus == null || !ModbusService.Iniciado)
{
PortaWT901C = new SerialPort();
lock (ModbusService._lock)
{
ModbusService._PortaModbus = new SerialPort();
ModbusService._PortaModbus.BaudRate = Porta.BaudRate;
ModbusService._PortaModbus.PortName = Porta.PortName;
}
}
PortaWT901C.BaudRate = Porta.BaudRate;
PortaWT901C.PortName = Porta.PortName;
Porta.Close();
if (ModbusService._PortaModbus != null && !ModbusService._PortaModbus.IsOpen)
{
Porta.Close();
}
if (Iniciado)
{
bool i = ModbusService.Iniciado;
DefinirDispositivo();
ReceberDados().ConfigureAwait(false);
}
}
private static async Task<bool> ReceberDados()
{
await ModbusService.EnviarComando(ComandoAquisicao);
byte[] resposta = SerialService.VerificarRespostaPortasDesconhecidas(ModbusService._PortaModbus);
Iniciado = DecifrarRespostaAquisicao(ComandoAquisicao, resposta);
if (Iniciado)
{
PreencherDadosLeitura();
Variaveis.OperacaoEmAndamento.Sensoriamento.InclinacaoX = DadosLeitura.AngleX;
Variaveis.OperacaoEmAndamento.Sensoriamento.InclinacaoY = DadosLeitura.AngleY;
Variaveis.OperacaoEmAndamento.Sensoriamento.InclinacaoZ = DadosLeitura.AngleZ;
Variaveis.OperacaoEmAndamento.Sensoriamento.AnguloCarroBussola = DadosLeitura.HM;
}
await Task.Delay(TaxaAmostragem);
return await ReceberDados();
}
private static void DefinirDispositivo()
{
if (Iniciado)
{
SerialService.DispositivosMapeados.Add(new SerialService.DispositivoDetalhesModel()
{
PortaCOM = PortaWT901C.PortName,
PortaCOM = ModbusService._PortaModbus.PortName,
Dispositivo = T_Code.Wit,
Erro = !Iniciado,
Versao = 1
@ -90,22 +111,356 @@ namespace AgroBase.Services
}
}
private static void WT901C485_OnRecord(WT901C485 WT901C485)
public static void EnviarComando(SerialPort _Porta, byte[] Comando)
{
double magX = WT901C485.GetDeviceData(WitSensorKey.HX) ?? 0;
double magY = WT901C485.GetDeviceData(WitSensorKey.HY) ?? 0;
double magZ = WT901C485.GetDeviceData(WitSensorKey.HZ) ?? 0;
double acX = WT901C485.GetDeviceData(WitSensorKey.AccX) ?? 0;
double acY = WT901C485.GetDeviceData(WitSensorKey.AccY) ?? 0;
double acZ = WT901C485.GetDeviceData(WitSensorKey.AccZ) ?? 0;
double OrientacaoMagnetica = GPSService.CalcularOrientacaoMagneticaCompensada(magX, magY, magZ, acX, acY, acZ);
Variaveis.OperacaoEmAndamento.Sensoriamento.AnguloCarroBussola = OrientacaoMagnetica;
Variaveis.OperacaoEmAndamento.Sensoriamento.InclinacaoX = WT901C485.GetDeviceData(WitSensorKey.AngleX) ?? 0;
Variaveis.OperacaoEmAndamento.Sensoriamento.InclinacaoY = WT901C485.GetDeviceData(WitSensorKey.AngleY) ?? 0;
Variaveis.OperacaoEmAndamento.Sensoriamento.InclinacaoZ = WT901C485.GetDeviceData(WitSensorKey.AngleZ) ?? 0;
Variaveis.OperacaoEmAndamento.Sensoriamento.Temperatura = WT901C485.GetDeviceData(WitSensorKey.T) ?? 0;
Variaveis.OperacaoEmAndamento.Sensoriamento.Pressao = WT901C485.GetDeviceData(WitSensorKey.P) ?? 0;
Variaveis.OperacaoEmAndamento.Sensoriamento.Altitude = WT901C485.GetDeviceData(WitSensorKey.H) ?? 0;
if (_Porta != null)
{
if (!_Porta.IsOpen)
{
_Porta.Open();
}
if (_Porta.IsOpen)
{
_Porta.Write(Comando, 0, Comando.Length);
}
}
}
private static bool DecifrarRespostaAquisicao(byte[] comando, byte[] resposta)
{
byte[] modbusBytes;
if (comando != null && resposta != null && resposta.Length >= 7 && ModbusService.FindModbus(comando, resposta, out modbusBytes))
{
int readReg = comando[2] << 8 | comando[3];
byte[] regData = modbusBytes.Skip(3).Take(modbusBytes.Length - 5).ToArray();
for (int j = 0; regData != null && j < regData.Length - 1; j += 2)
{
string key = string.Format("{0:X2}", readReg++);
short value = (short)(regData[j] << 8 | regData[j + 1]);
DadosSensor[key] = value;
}
return true;
}
else
{
Console.WriteLine("Erro ao ler dados do WT901C");
return false;
}
}
private static dynamic GetDeviceData(string key)
{
if (DadosSensor.ContainsKey(key))
{
return DadosSensor[key].ToString();
}
else
{
return null;
}
}
private static void PreencherDadosLeitura()
{
var wt901CModel = DadosLeitura;
// Versão
var reg2e = GetDeviceData("2E"); // Versão
var reg2f = GetDeviceData("2F"); // Versão
// Se houver versão
if (!string.IsNullOrEmpty(reg2e) && !string.IsNullOrEmpty(reg2f))
{
var reg2eValue = (ushort)short.Parse(reg2e);
var vbytes = BitConverter.GetBytes((ushort)short.Parse(reg2e)).Concat(BitConverter.GetBytes((ushort)short.Parse(reg2f))).ToArray();
UInt32 tempVerSion = BitConverter.ToUInt32(vbytes, 0);
string sbinary = Convert.ToString(tempVerSion, 2);
sbinary = ("").PadLeft((32 - sbinary.Length), '0') + sbinary;
if (sbinary.StartsWith("1")) // Nova versão
{
string tempNewVS = Convert.ToUInt32(sbinary.Substring(4 - 3, 14 + 3), 2).ToString();
tempNewVS += "." + Convert.ToUInt32(sbinary.Substring(18, 6), 2);
tempNewVS += "." + Convert.ToUInt32(sbinary.Substring(24), 2);
wt901CModel.Versao = tempNewVS;
}
else
{
wt901CModel.Versao = reg2eValue.ToString();
}
}
// Número de série
var reg7f = GetDeviceData("7F"); // Número de série
var reg80 = GetDeviceData("80"); // Número de série
var reg81 = GetDeviceData("81"); // Número de série
var reg82 = GetDeviceData("82"); // Número de série
var reg83 = GetDeviceData("83"); // Número de série
var reg84 = GetDeviceData("84"); // Número de série
if (!string.IsNullOrEmpty(reg7f) && !string.IsNullOrEmpty(reg80) && !string.IsNullOrEmpty(reg81) &&
!string.IsNullOrEmpty(reg82) && !string.IsNullOrEmpty(reg83) && !string.IsNullOrEmpty(reg84))
{
var sbytes = BitConverter.GetBytes(short.Parse(reg7f))
.Concat(BitConverter.GetBytes(short.Parse(reg80)))
.Concat(BitConverter.GetBytes(short.Parse(reg81)))
.Concat(BitConverter.GetBytes(short.Parse(reg82)))
.Concat(BitConverter.GetBytes(short.Parse(reg83)))
.Concat(BitConverter.GetBytes(short.Parse(reg84)))
.ToArray();
string sn = Encoding.Default.GetString(sbytes);
// Aqui você pode adicionar o número de série ao modelo, se necessário
}
// Dados de tempo
var reg30 = GetDeviceData("30"); // Ano e mês
var reg31 = GetDeviceData("31"); // Dia e hora
var reg32 = GetDeviceData("32"); // Minuto e segundo
var reg33 = GetDeviceData("33"); // Milissegundo
// Se os dados de tempo foram retornados
if (!string.IsNullOrEmpty(reg30) && !string.IsNullOrEmpty(reg31) && !string.IsNullOrEmpty(reg32) && !string.IsNullOrEmpty(reg33))
{
// Decodificar os dados e salvar no modelo
var yy = 2000 + (byte)int.Parse(reg30);
var MM = 1 + (byte)(int.Parse(reg30) >> 8);
var dd = 1 + (byte)int.Parse(reg31);
var hh = (byte)(int.Parse(reg31) >> 8);
var mm = (byte)int.Parse(reg32);
var ss = (byte)(int.Parse(reg32) >> 8);
var ms = int.Parse(reg33).ToString("000");
string dateTimeStr = $"{yy}-{MM}-{dd} {hh}:{mm}:{ss}.{ms}";
DateTime.TryParse(dateTimeStr, out DateTime dateTime);
wt901CModel.DataHora = dateTime;
}
// Dados de aceleração
var reg34 = GetDeviceData("34"); // Aceleração X
var reg35 = GetDeviceData("35"); // Aceleração Y
var reg36 = GetDeviceData("36"); // Aceleração Z
// Se os dados de aceleração foram retornados
if (!string.IsNullOrEmpty(reg34) && !string.IsNullOrEmpty(reg35) && !string.IsNullOrEmpty(reg36))
{
// Decodificar os dados e salvar no modelo
wt901CModel.AccX = Math.Round(double.Parse(reg34) / 32768.0 * 16, 3);
wt901CModel.AccY = Math.Round(double.Parse(reg35) / 32768.0 * 16, 3);
wt901CModel.AccZ = Math.Round(double.Parse(reg36) / 32768.0 * 16, 3);
wt901CModel.AccM = Math.Round(Math.Sqrt(Math.Pow(wt901CModel.AccX, 2) + Math.Pow(wt901CModel.AccY, 2) + Math.Pow(wt901CModel.AccZ, 2)), 3);
}
// Dados de velocidade angular
var reg37 = GetDeviceData("37"); // Velocidade angular X
var reg38 = GetDeviceData("38"); // Velocidade angular Y
var reg39 = GetDeviceData("39"); // Velocidade angular Z
// Se os dados de velocidade angular foram retornados
if (!string.IsNullOrEmpty(reg37) && !string.IsNullOrEmpty(reg38) && !string.IsNullOrEmpty(reg39))
{
// Decodificar os dados e salvar no modelo
wt901CModel.AsX = Math.Round(double.Parse(reg37) / 32768.0 * 2000, 3);
wt901CModel.AsY = Math.Round(double.Parse(reg38) / 32768.0 * 2000, 3);
wt901CModel.AsZ = Math.Round(double.Parse(reg39) / 32768.0 * 2000, 3);
wt901CModel.AsM = Math.Round(Math.Sqrt(Math.Pow(wt901CModel.AsX, 2) + Math.Pow(wt901CModel.AsY, 2) + Math.Pow(wt901CModel.AsZ, 2)), 3);
}
// Dados de ângulo
var reg3D = GetDeviceData("3D"); // Ângulo X
var reg3E = GetDeviceData("3E"); // Ângulo Y
var reg3F = GetDeviceData("3F"); // Ângulo Z
// Se os dados de ângulo foram retornados
if (!string.IsNullOrEmpty(reg3D) && !string.IsNullOrEmpty(reg3E) && !string.IsNullOrEmpty(reg3F))
{
// Decodificar os dados e salvar no modelo
wt901CModel.AngleX = Math.Round(double.Parse(reg3D) / 32768.0 * 180, 3);
wt901CModel.AngleY = Math.Round(double.Parse(reg3E) / 32768.0 * 180, 3);
wt901CModel.AngleZ = Math.Round(double.Parse(reg3F) / 32768.0 * 180, 3);
}
// Dados do campo magnético
var reg3A = GetDeviceData("3A"); // Campo magnético X
var reg3B = GetDeviceData("3B"); // Campo magnético Y
var reg3C = GetDeviceData("3C"); // Campo magnético Z
var magType = GetDeviceData("72"); // Tipo de campo magnético
// Se os dados do campo magnético foram retornados
if (!string.IsNullOrEmpty(reg3A) && !string.IsNullOrEmpty(reg3B) && !string.IsNullOrEmpty(reg3C) && !string.IsNullOrEmpty(magType))
{
short type = short.Parse(magType);
// Decodificar os dados e salvar no modelo
wt901CModel.HX = GetMagToUt(type, double.Parse(reg3A));
wt901CModel.HY = GetMagToUt(type, double.Parse(reg3B));
wt901CModel.HZ = GetMagToUt(type, double.Parse(reg3C));
wt901CModel.HM = Math.Round(Math.Sqrt(Math.Pow(wt901CModel.HX, 2) + Math.Pow(wt901CModel.HY, 2) + Math.Pow(wt901CModel.HZ, 2)), 2);
}
// Dados de temperatura
var reg40 = GetDeviceData("40"); // Temperatura
// Se os dados de temperatura foram retornados
if (!string.IsNullOrEmpty(reg40))
{
wt901CModel.Temperatura = Math.Round(double.Parse(reg40) / 100.0, 2);
}
// Dados dos portos
var reg41 = GetDeviceData("41"); // Porto 0
var reg42 = GetDeviceData("42"); // Porto 1
var reg43 = GetDeviceData("43"); // Porto 2
var reg44 = GetDeviceData("44"); // Porto 3
// Se os dados dos portos foram retornados
if (reg41 != null && reg42 != null && reg43 != null && reg44 != null)
{
wt901CModel.D0 = short.Parse(reg41);
wt901CModel.D1 = short.Parse(reg42);
wt901CModel.D2 = short.Parse(reg43);
wt901CModel.D3 = short.Parse(reg44);
}
// Dados de pressão e altitude
var reg45 = GetDeviceData("45"); // Pressão baixa
var reg46 = GetDeviceData("46"); // Pressão alta
var reg47 = GetDeviceData("47"); // Altitude baixa
var reg48 = GetDeviceData("48"); // Altitude alta
// Se os dados de pressão e altitude foram retornados
if (!string.IsNullOrEmpty(reg45) && !string.IsNullOrEmpty(reg46) && !string.IsNullOrEmpty(reg47) && !string.IsNullOrEmpty(reg48))
{
var pbytes = BitConverter.GetBytes((short)short.Parse(reg45)).Concat(BitConverter.GetBytes((short)short.Parse(reg46))).ToArray();
var hbytes = BitConverter.GetBytes((short)short.Parse(reg47)).Concat(BitConverter.GetBytes((short)short.Parse(reg48))).ToArray();
wt901CModel.Pressao = BitConverter.ToInt32(pbytes, 0);
wt901CModel.Altitude = BitConverter.ToInt32(hbytes, 0) / 100.0;
}
// Dados de latitude e longitude
var reg49 = GetDeviceData("49"); // Longitude baixa
var reg4A = GetDeviceData("4A"); // Longitude alta
var reg4B = GetDeviceData("4B"); // Latitude baixa
var reg4C = GetDeviceData("4C"); // Latitude alta
// Se os dados de latitude e longitude foram retornados
if (!string.IsNullOrEmpty(reg49) && !string.IsNullOrEmpty(reg4A) && !string.IsNullOrEmpty(reg4B) && !string.IsNullOrEmpty(reg4C))
{
var lonbytes = BitConverter.GetBytes((short)short.Parse(reg49)).Concat(BitConverter.GetBytes((short)short.Parse(reg4A))).ToArray();
var lon = BitConverter.ToInt32(lonbytes, 0);
var latbytes = BitConverter.GetBytes((short)short.Parse(reg4B)).Concat(BitConverter.GetBytes((short)short.Parse(reg4C))).ToArray();
var lat = BitConverter.ToInt32(latbytes, 0);
double lon_D = DmsToD((double)lon / 100000.0);
wt901CModel.Longitude = Math.Round(lon_D, 6);
double lat_D = DmsToD((double)lat / 100000.0);
wt901CModel.Latitude = Math.Round(lat_D, 6);
}
// Dados de altura, orientação e velocidade do GPS
var reg4D = GetDeviceData("4D"); // Altura do GPS
var reg4E = GetDeviceData("4E"); // Orientação do GPS
var reg4F = GetDeviceData("4F"); // Velocidade baixa
var reg50 = GetDeviceData("50"); // Velocidade alta
// Se os dados de altura, orientação e velocidade do GPS foram retornados
if (!string.IsNullOrEmpty(reg4D) && !string.IsNullOrEmpty(reg4E) && !string.IsNullOrEmpty(reg4F) && !string.IsNullOrEmpty(reg50))
{
var svbytes = BitConverter.GetBytes((short)short.Parse(reg4F)).Concat(BitConverter.GetBytes((short)short.Parse(reg50))).ToArray();
wt901CModel.GPS_Altitude = Math.Round(short.Parse(reg4D) / 10.0, 3);
byte[] temp = BitConverter.GetBytes((short)short.Parse(reg4E)); // Decodificar orientação sem valores negativos
uint reg4EValue = BitConverter.ToUInt16(temp, 0);
wt901CModel.GPS_Orientacao = Math.Round(reg4EValue / 100.0, 3);
wt901CModel.GPS_Velcodiade = Math.Round(BitConverter.ToInt32(svbytes, 0) / 1e3, 3);
}
// Dados dos quaternions
var reg51 = GetDeviceData("51"); // Quaternion 0
var reg52 = GetDeviceData("52"); // Quaternion 1
var reg53 = GetDeviceData("53"); // Quaternion 2
var reg54 = GetDeviceData("54"); // Quaternion 3
// Se os dados dos quaternions foram retornados
if (!string.IsNullOrEmpty(reg51) && !string.IsNullOrEmpty(reg52) && !string.IsNullOrEmpty(reg53) && !string.IsNullOrEmpty(reg54))
{
wt901CModel.Q0 = Math.Round(short.Parse(reg51) / 32768.0, 3);
wt901CModel.Q1 = Math.Round(short.Parse(reg52) / 32768.0, 3);
wt901CModel.Q2 = Math.Round(short.Parse(reg53) / 32768.0, 3);
wt901CModel.Q3 = Math.Round(short.Parse(reg54) / 32768.0, 3);
}
// Dados de precisão de posição
var reg55 = GetDeviceData("55"); // Número de satélites
var reg56 = GetDeviceData("56"); // PDOP
var reg57 = GetDeviceData("57"); // HDOP
var reg58 = GetDeviceData("58"); // VDOP
// Se os dados de precisão de posição foram retornados
if (!string.IsNullOrEmpty(reg55) && !string.IsNullOrEmpty(reg56) && !string.IsNullOrEmpty(reg57) && !string.IsNullOrEmpty(reg58))
{
wt901CModel.GPS_NumeroSatelites = short.Parse(reg55);
wt901CModel.PDOP = Math.Round(short.Parse(reg56) / 100.0, 3);
wt901CModel.HDOP = Math.Round(short.Parse(reg57) / 100.0, 3);
wt901CModel.VDOP = Math.Round(short.Parse(reg58) / 100.0, 3);
}
}
private static double GetMagToUt(short reg72, double regMag)
{
double dRet = regMag;
switch (reg72)
{
case 2:
dRet = dRet * 0.15;
break;
case 3:
dRet = dRet * 13 / 1000.0;
break;
case 4:
dRet = dRet * 0.058;
break;
case 5:
dRet = dRet * 0.098;
break;
case 6:
dRet = dRet / 120;
break;
case 7:
dRet = dRet * 20 / 1000.0;
break;
}
return Math.Round(dRet, 3);
}
private static double GetUtToMag(short reg72, double reguTMag)
{
double dRet = reguTMag;
switch (reg72)
{
case 2:
dRet = dRet / 0.15;
break;
case 3:
dRet = dRet * 1000.0 / 13.0;
break;
case 4:
dRet = dRet / 0.058;
break;
case 5:
dRet = dRet / 0.098;
break;
case 6:
dRet = dRet * 120;
break;
case 7:
dRet = dRet * 1000.0 / 20.0;
break;
}
return dRet;
}
private static double DmsToD(double value, int digits)
{
double Degree = Math.Floor(value / 100);
double points = (value / 100 - Degree) * 100;
Degree = Degree + points / 60;
return Math.Round(Degree, digits);
}
private static double DmsToD(double value)
{
return DmsToD(value, 7);
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
[{"Momento":"2024-05-20T10:39:44.5813691-03:00","Protocolo":"@11;258;ET,1,0,0,1,0,4,0,6,0,5,0,7,0,4$","Enviado":true},{"Momento":"2024-05-20T10:39:44.5874754-03:00","Protocolo":"655;11;$\r","Enviado":false},{"Momento":"2024-05-20T10:39:44.6066725-03:00","Protocolo":"@12;258;EF,1,1,0,1,0,-12,0,42,0,2,0,41,0,1$","Enviado":true},{"Momento":"2024-05-20T10:39:44.6136734-03:00","Protocolo":"655;12;$\r","Enviado":false},{"Momento":"2024-05-20T10:39:44.623798-03:00","Protocolo":"@13;258;DT,1,2,0,1,0,5,0,12,0,13,0,11,0,14$","Enviado":true},{"Momento":"2024-05-20T10:39:44.6299323-03:00","Protocolo":"655;13;$\r","Enviado":false},{"Momento":"2024-05-20T10:39:44.6390689-03:00","Protocolo":"@14;258;DF,1,3,1,1,0,16,0,21,0,20,0,47,0,19$","Enviado":true},{"Momento":"2024-05-20T10:39:44.6451821-03:00","Protocolo":"DF Iniciado\r","Enviado":false},{"Momento":"2024-05-20T10:39:44.656326-03:00","Protocolo":"#211;DF;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:45.1674652-03:00","Protocolo":"655;14;$\r","Enviado":false},{"Momento":"2024-05-20T10:39:45.1805744-03:00","Protocolo":"@15;258;MD,1,00500$","Enviado":true},{"Momento":"2024-05-20T10:39:45.184574-03:00","Protocolo":"#211;MD;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:45.294848-03:00","Protocolo":"655;15;$\r","Enviado":false},{"Momento":"2024-05-20T10:39:45.6458374-03:00","Protocolo":"#111;DF;0;-38;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:46.1453266-03:00","Protocolo":"#111;DF;0;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:46.6459356-03:00","Protocolo":"#111;DF;0;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:47.1461303-03:00","Protocolo":"#111;DF;0;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:47.6458423-03:00","Protocolo":"#111;DF;1;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:48.1455332-03:00","Protocolo":"#111;DF;2;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:48.6489345-03:00","Protocolo":"#111;DF;1;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:49.1459554-03:00","Protocolo":"#111;DF;2;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:49.646036-03:00","Protocolo":"#111;DF;2;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:50.1457068-03:00","Protocolo":"#111;DF;1;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:50.646075-03:00","Protocolo":"#111;DF;1;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:51.1493316-03:00","Protocolo":"#111;DF;1;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:51.6459839-03:00","Protocolo":"#111;DF;1;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:52.1500948-03:00","Protocolo":"#111;DF;1;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:52.6460731-03:00","Protocolo":"#111;DF;2;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:53.1458463-03:00","Protocolo":"#111;DF;2;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:53.6469168-03:00","Protocolo":"#111;DF;2;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:54.1468515-03:00","Protocolo":"#111;DF;1;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:54.646497-03:00","Protocolo":"#111;DF;1;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:55.1456691-03:00","Protocolo":"#111;DF;1;4;0;1$\r","Enviado":false},{"Momento":"2024-05-20T10:39:55.4149805-03:00","Protocolo":"@16;258;ET,0,0,0,1,0,4,0,6,0,5,0,7,0,4$","Enviado":true},{"Momento":"2024-05-20T10:39:55.4210855-03:00","Protocolo":"655;16;$\r","Enviado":false},{"Momento":"2024-05-20T10:39:55.4261769-03:00","Protocolo":"@17;258;EF,0,1,0,1,0,-12,0,42,0,2,0,41,0,1$","Enviado":true},{"Momento":"2024-05-20T10:39:55.4321758-03:00","Protocolo":"655;17;$\r","Enviado":false},{"Momento":"2024-05-20T10:39:55.4422682-03:00","Protocolo":"@18;258;DT,0,2,0,1,0,5,0,12,0,13,0,11,0,14$","Enviado":true},{"Momento":"2024-05-20T10:39:55.4483533-03:00","Protocolo":"655;18;$\r","Enviado":false},{"Momento":"2024-05-20T10:39:55.4574348-03:00","Protocolo":"@19;258;DF,0,3,1,1,0,16,0,21,0,20,0,47,0,19$","Enviado":true},{"Momento":"2024-05-20T10:39:55.464434-03:00","Protocolo":"DF Desligado\r","Enviado":false},{"Momento":"2024-05-20T10:39:55.4745173-03:00","Protocolo":"#211;DF;0$\r","Enviado":false},{"Momento":"2024-05-20T10:39:55.9856446-03:00","Protocolo":"655;19;$\r","Enviado":false},{"Momento":"2024-05-20T10:39:56.0007597-03:00","Protocolo":"@20;258;MD,0,00500$","Enviado":true},{"Momento":"2024-05-20T10:39:56.004758-03:00","Protocolo":"#211;MD;0$\r","Enviado":false},{"Momento":"2024-05-20T10:39:56.1154946-03:00","Protocolo":"655;20;$\r","Enviado":false}

Some files were not shown because too many files have changed in this diff Show More