using Newtonsoft.Json;
|
using Shared.Common;
|
using System;
|
using System.Collections.Generic;
|
using System.Threading.Tasks;
|
using ZigBee.Device;
|
|
namespace Shared.Phone
|
{
|
/// <summary>
|
/// 网关业务的逻辑类
|
/// </summary>
|
public class HdlGatewayLogic
|
{
|
#region ■ 变量声明___________________________
|
|
/// <summary>
|
/// 网关业务的逻辑类
|
/// </summary>
|
private static HdlGatewayLogic m_Current = null;
|
/// <summary>
|
/// 网关业务的逻辑类
|
/// </summary>
|
public static HdlGatewayLogic Current
|
{
|
get
|
{
|
if (m_Current == null)
|
{
|
m_Current = new HdlGatewayLogic();
|
}
|
return m_Current;
|
}
|
}
|
/// <summary>
|
/// 备份用的网关ID
|
/// </summary>
|
private List<string> listBackupGwId = new List<string>();
|
/// <summary>
|
/// 网关文件的前缀名字
|
/// </summary>
|
private string gwFirstName = "Gateway_";
|
/// <summary>
|
/// 全部网关(这里保存的是虚拟网关,而不是真实物理网关对象)
|
/// </summary>
|
private Dictionary<string, ZbGateway> dicGateway = new Dictionary<string, ZbGateway>();
|
|
#endregion
|
|
#region ■ 刷新网关___________________________
|
|
/// <summary>
|
/// 刷新本地网关信息
|
/// </summary>
|
public void ReFreshByLocal()
|
{
|
lock (dicGateway)
|
{
|
this.dicGateway.Clear();
|
|
List<string> listFile = this.GetAllGatewayFile();
|
//反序列化添加到缓存
|
foreach (string file in listFile)
|
{
|
//从文件中反序列化出网关对象
|
var gateway = this.GetGatewayFromFile(file);
|
if (gateway == null)
|
{
|
continue;
|
}
|
//添加缓存
|
dicGateway[gateway.GwId] = gateway;
|
}
|
}
|
}
|
|
/// <summary>
|
/// 刷新APP前一次选择的网关ID
|
/// </summary>
|
public void RefreshAppOldSelectGatewayId()
|
{
|
HdlGatewayResourse.AppOldSelectGatewayId = string.Empty;
|
|
//从文件中获取上一次选择的网关id
|
byte[] data = HdlFileLogic.Current.ReadFileByteContent(HdlFileNameResourse.AppOldSelectGatewayFile);
|
if (data != null)
|
{
|
string strvalue = System.Text.Encoding.UTF8.GetString(data);
|
HdlGatewayResourse.AppOldSelectGatewayId = JsonConvert.DeserializeObject<string>(strvalue);
|
}
|
//如果本地没有这个网关的话
|
if (this.IsGatewayExist(HdlGatewayResourse.AppOldSelectGatewayId) == false)
|
{
|
HdlGatewayResourse.AppOldSelectGatewayId = string.Empty;
|
lock (dicGateway)
|
{
|
//随便选一个网关
|
foreach (string wayId in this.dicGateway.Keys)
|
{
|
HdlGatewayResourse.AppOldSelectGatewayId = wayId;
|
break;
|
}
|
}
|
}
|
}
|
|
/// <summary>
|
/// 同步云端的网关id,如果本地拥有云端不存在的id,则表示应该被换绑了,直接删除(切换住宅后,重新刷新网关列表和设备之后使用)
|
/// </summary>
|
/// <returns></returns>
|
public void SynchronizeDbGateway()
|
{
|
//从云端获取网列表ID
|
Dictionary<string, GatewayResult> result = this.GetGateWayListFromDataBase(Config.Instance.Home.Id);
|
if (result == null)
|
{
|
return;
|
}
|
|
List<string> listBackupGwId = new List<string>();
|
var fileData = HdlFileLogic.Current.ReadFileByteContent(HdlFileNameResourse.BackupGatewayIdFile);
|
if (fileData != null)
|
{
|
//新增:虽然概率低,但是确实发生了。如果有网络时,App重新绑定记录的网关失败的话
|
//不应该删除它
|
listBackupGwId = JsonConvert.DeserializeObject<List<string>>(System.Text.Encoding.UTF8.GetString(fileData));
|
}
|
|
List<string> listDelete = new List<string>();
|
foreach (var gatewayId in this.dicGateway.Keys)
|
{
|
if (result.ContainsKey(gatewayId) == false && listBackupGwId.Contains(gatewayId) == false)
|
{
|
//本地存在云端不存在的网关,则删除
|
listDelete.Add(gatewayId);
|
}
|
}
|
foreach (var gatewayId in listDelete)
|
{
|
//删除本地这个网关所有的设备
|
List<CommonDevice> list = HdlDeviceCommonLogic.Current.GetDeviceByGatewayID(gatewayId);
|
foreach (var device in list)
|
{
|
//删除一般设备
|
HdlDeviceCommonLogic.Current.DeleteMemmoryDevice(device, true);
|
//删除Ota设备
|
HdlDeviceCommonLogic.Current.DeleteMemmoryOtaDevice(device.DeviceAddr);
|
}
|
//删除网关文件
|
this.DeleteGatewayFile(gatewayId);
|
}
|
//如果网关都没了的话,把场景全部删了
|
if (listDelete.Count > 0 && this.GetAllLocalGateway().Count == 0)
|
{
|
HdlSceneLogic.Current.DeleteAllLocalScene();
|
}
|
}
|
|
/// <summary>
|
/// 从文件中反序列化出网关对象
|
/// </summary>
|
/// <param name="file"></param>
|
/// <returns></returns>
|
private ZbGateway GetGatewayFromFile(string file)
|
{
|
try
|
{
|
byte[] filebyte = Global.ReadFileByHomeId(file);
|
string strvalue = System.Text.Encoding.UTF8.GetString(filebyte);
|
var gateway = JsonConvert.DeserializeObject<ZbGateway>(strvalue);
|
if (gateway.GwId == string.Empty)
|
{
|
//这是旧数据,需要特殊处理
|
var jobject = Newtonsoft.Json.Linq.JObject.Parse(strvalue);
|
string gwInfo = jobject["getGwInfo"].ToString();
|
|
var result = JsonConvert.DeserializeObject<ZbGatewayData.GetGwData>(gwInfo);
|
//将网关的数据设置到本地缓存中
|
this.SetGatewayDataToLocalMemmory(gateway, result);
|
}
|
if (gateway.HomeId == string.Empty)
|
{
|
gateway.HomeId = Config.Instance.Home.Id;
|
}
|
return gateway;
|
}
|
catch (Exception ex)
|
{
|
HdlLogLogic.Current.WriteLog(ex);
|
return null;
|
}
|
}
|
|
#endregion
|
|
#region ■ 添加网关___________________________
|
|
/// <summary>
|
/// 添加新网关(仅限追加新的网关)
|
/// </summary>
|
/// <param name="zbGateway">网关</param>
|
/// <param name="mode">是否显示错误</param>
|
/// <param name="logMode">是否写Log</param>
|
public bool AddNewGateway(ZbGateway zbGateway, ShowErrorMode mode, WriteLogMode logMode = WriteLogMode.NO)
|
{
|
//设置网关的经纬度
|
bool falge = this.SetGatewaySite(zbGateway.GwId, Common.Config.Instance.Home.Longitude, Common.Config.Instance.Home.Latitude, ShowErrorMode.NO);
|
if (falge == false)
|
{
|
if (logMode == WriteLogMode.YES)
|
{
|
HdlLogLogic.Current.WriteLog(-1, zbGateway.GwIP + " 设置经纬度失败");
|
}
|
return falge;
|
}
|
//执行添加网关到内存
|
var result = this.DoAddGatewayToMemory(zbGateway, mode, logMode);
|
//前的网关绑定在了当前账号下的不同住宅里面
|
if (result == 0)
|
{
|
if (mode == ShowErrorMode.YES)
|
{
|
//网关绑定在当前账号下的其他住宅里\r\n请解除绑定后再试
|
string msg = Language.StringByID(R.MyInternationalizationString.uTheGatewayInOtherResidenceMsg);
|
if (msg.Contains("{0}") == true)
|
{
|
msg = string.Format(msg, "\r\n");
|
}
|
this.ShowTipMsg(msg);
|
}
|
if (logMode == WriteLogMode.YES)
|
{
|
HdlLogLogic.Current.WriteLog(-1, zbGateway.GwIP + " 网关绑定在了当前账号下的不同住宅里面,云端不给绑定");
|
}
|
return false;
|
}
|
if (result == -1)
|
{
|
return false;
|
}
|
//添加网关的话,强制主页刷新
|
UserView.UserPage.Instance.RefreshAllForm = true;
|
|
if (Config.Instance.Home.TemplateMode == 2)
|
{
|
//如果这个类型的网关只有一个模板,则自动匹配
|
var dicName = HdlTemplateCommonLogic.Current.GetGatewayCanSelectTemplateName(zbGateway);
|
if (dicName.Count == 1)
|
{
|
foreach (var tempId in dicName.Keys)
|
{
|
HdlTemplateCommonLogic.Current.AddGatewayTemplateSelect(zbGateway.GwId, tempId);
|
break;
|
}
|
}
|
}
|
|
return true;
|
}
|
|
/// <summary>
|
/// 创建一个虚拟的网关对象
|
/// </summary>
|
/// <param name="gatewayId">网关ID</param>
|
public void AddVirtualGateway(string gatewayId)
|
{
|
var gateWay = new ZbGateway { IsVirtual = true };
|
gateWay.GwId = gatewayId;
|
gateWay.HomeId = Shared.Common.Config.Instance.HomeId;
|
gateWay.ReSave();
|
this.dicGateway[gatewayId] = gateWay;
|
}
|
|
/// <summary>
|
/// 执行添加网关到内存(1:正常 -1:异常 0:当前的网关绑定在了当前账号下的不同住宅里面)
|
/// </summary>
|
/// <param name="zbGateway">网关对象</param>
|
/// <param name="mode">是否显示错误</param>
|
/// <param name="logMode">是否写Log</param>
|
/// <returns></returns>
|
private int DoAddGatewayToMemory(ZbGateway zbGateway, ShowErrorMode mode, WriteLogMode logMode = WriteLogMode.NO)
|
{
|
if (zbGateway == null)
|
{
|
if (mode == ShowErrorMode.YES)
|
{
|
//错误:网关对象丢失
|
string msg = Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg);
|
this.ShowTipMsg(msg);
|
}
|
return -1;
|
}
|
//获取网关的信息
|
var result = this.RefreshGatewayInfo(zbGateway, true, mode);
|
if (result == null)
|
{
|
if (mode == ShowErrorMode.YES)
|
{
|
//获取网关信息失败
|
string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayInfoFail);
|
this.ShowTipMsg(msg);
|
}
|
if (logMode == WriteLogMode.YES)
|
{
|
HdlLogLogic.Current.WriteLog(-1, zbGateway.GwIP + " 获取网关信息失败");
|
}
|
return -1;
|
}
|
|
//设置住宅ID到网关
|
if (result.HomeId != Common.Config.Instance.HomeId)
|
{
|
bool flage2 = this.SetHomeIdToGateway(zbGateway, Common.Config.Instance.HomeId, mode);
|
if (flage2 == false)
|
{
|
if (mode == ShowErrorMode.YES)
|
{
|
//向网关设置住宅ID失败
|
string msg = Language.StringByID(R.MyInternationalizationString.uSetHomeIdToGatewayFail);
|
this.ShowTipMsg(msg);
|
}
|
if (logMode == WriteLogMode.YES)
|
{
|
HdlLogLogic.Current.WriteLog(-1, zbGateway.GwIP + " 向网关设置住宅ID失败");
|
}
|
return -1;
|
}
|
}
|
|
//更新云端数据库
|
int flage1 = this.SetGatewayIdToDataBase(zbGateway.GwId);
|
//异常也不鸟它,0是特殊含义
|
if (flage1 == 0)
|
{
|
return flage1;
|
}
|
if (flage1 == -1)
|
{
|
//备份失败的网关ID
|
this.BackupGatewayIdOnNotNetwork(zbGateway);
|
}
|
|
//是否已经存在
|
string gwID = zbGateway.GwId;
|
bool isEsist = this.IsGatewayExist(zbGateway);
|
if (isEsist == false)
|
{
|
//新建一个虚拟的网关出来
|
zbGateway.ReSave();
|
var way = this.GetGatewayFromFile(zbGateway.FilePath);
|
this.dicGateway[gwID] = way;
|
}
|
|
//刷新的是缓存,不刷新真实物理网关
|
this.dicGateway[gwID].OnlineTime = DateTime.Now;
|
//将网关的数据设置到本地缓存中
|
this.SetGatewayDataToLocalMemmory(this.dicGateway[gwID], result);
|
//顺便这个变量也设置一下
|
this.SetGatewayDataToLocalMemmory(zbGateway, result, false);
|
|
if (isEsist == false)
|
{
|
//添加备份
|
HdlBackupLogic.Current.AddOrEditorAutoBackFileStatu(this.dicGateway[gwID].FilePath);
|
}
|
|
return 1;
|
}
|
|
/// <summary>
|
/// 设置住宅ID到网关(失败时,不弹出任何错误信息,网关断网除外)
|
/// </summary>
|
/// <param name="zbGateway"></param>
|
/// <param name="HomeId"></param>
|
/// <returns></returns>
|
public bool SetHomeIdToGateway(ZbGateway zbGateway, string HomeId, ShowErrorMode mode)
|
{
|
//账号ID
|
string accountId = string.Empty;
|
if (HomeId != string.Empty)
|
{
|
accountId = Config.Instance.Guid;
|
}
|
var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 0 }, { "Command", 82 } };
|
var data = new Newtonsoft.Json.Linq.JObject { { "HomeId", HomeId }, { "AccountId", accountId } };
|
jObject.Add("Data", data);
|
//住宅ID的设置,固定使用局域网,不存在远程的说法
|
var result = this.SendJobjectDataToGateway(zbGateway.GwId, "GwSetHomeId", jObject.ToString(), "GwSetHomeId_Respon", 5, true);
|
if (result.ErrorMsgDiv == -1)
|
{
|
if (mode == ShowErrorMode.YES)
|
{
|
//错误:网关对象丢失
|
string msg = Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg);
|
this.ShowTipMsg(msg);
|
}
|
return false;
|
}
|
if (result.ErrorMsgDiv == 0)
|
{
|
return false;
|
}
|
return true;
|
}
|
|
/// <summary>
|
/// 住宅ID是否为空
|
/// </summary>
|
/// <param name="zbGateway"></param>
|
/// <returns></returns>
|
public bool HomeIdIsEmpty(ZbGateway zbGateway)
|
{
|
return this.HomeIdIsEmpty(zbGateway.HomeId);
|
}
|
|
/// <summary>
|
/// 住宅ID是否为空
|
/// </summary>
|
/// <param name="HomeId"></param>
|
/// <returns></returns>
|
public bool HomeIdIsEmpty(string HomeId)
|
{
|
if (string.IsNullOrEmpty(HomeId) == true || HomeId[0] == '\0')
|
{
|
return true;
|
}
|
return false;
|
}
|
|
#endregion
|
|
#region ■ 重新绑定网关_______________________
|
|
/// <summary>
|
/// 重新绑定网关(1:正常 -1:异常 0:当前的网关绑定在了当前账号下的不同住宅里面)
|
/// </summary>
|
/// <param name="zbGateway">网关</param>
|
/// <param name="btnMsg">消息控件</param>
|
public int ReBindNewGateway(ZbGateway zbGateway, NormalViewControl btnMsg = null)
|
{
|
if (zbGateway == null)
|
{
|
//错误:网关对象丢失
|
string msg = Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg);
|
this.ShowTipMsg(msg);
|
return -1;
|
}
|
//设置网关的经纬度
|
bool falge = this.SetGatewaySite(zbGateway.GwId, Common.Config.Instance.Home.Longitude, Common.Config.Instance.Home.Latitude, ShowErrorMode.YES);
|
if (falge == false)
|
{
|
return -1;
|
}
|
|
//设置住宅ID到网关
|
bool flage2 = this.SetHomeIdToGateway(zbGateway, Common.Config.Instance.HomeId, ShowErrorMode.YES);
|
if (flage2 == false)
|
{
|
//向网关设置住宅ID失败
|
string msg = Language.StringByID(R.MyInternationalizationString.uSetHomeIdToGatewayFail);
|
this.ShowTipMsg(msg);
|
return -1;
|
}
|
|
//更新云端数据库
|
int flage1 = this.SetGatewayIdToDataBase(zbGateway.GwId);
|
//异常也不鸟它,0是特殊含义
|
if (flage1 == 0)
|
{
|
return flage1;
|
}
|
if (flage1 == -1)
|
{
|
//备份失败的网关ID
|
this.BackupGatewayIdOnNotNetwork(zbGateway);
|
}
|
|
if (btnMsg == null)
|
{
|
//网关内部数据变更中,请稍后
|
ProgressBar.SetValue(Language.StringByID(R.MyInternationalizationString.uGatewayDataIsChangingPleaseWhait));
|
}
|
else
|
{
|
HdlThreadLogic.Current.RunMain(() =>
|
{
|
//网关内部数据变更中,请稍后
|
btnMsg.TextID = R.MyInternationalizationString.uGatewayDataIsChangingPleaseWhait;
|
});
|
}
|
System.Threading.Thread.Sleep(8000);
|
|
//获取网关的信息
|
ZbGatewayData.GetGwData result = null;
|
int count = 5;
|
while (count >= 0)
|
{
|
result = this.RefreshGatewayInfo(zbGateway, true, ShowErrorMode.NO);
|
if (result != null)
|
{
|
break;
|
}
|
count--;
|
//最多再等20秒
|
System.Threading.Thread.Sleep(4000);
|
}
|
if (result == null)
|
{
|
//获取网关信息失败
|
string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayInfoFail);
|
this.ShowTipMsg(msg);
|
return -1;
|
}
|
|
//是否已经存在
|
string gwID = zbGateway.GwId;
|
bool isEsist = HdlGatewayLogic.Current.IsGatewayExist(zbGateway);
|
if (isEsist == false)
|
{
|
//新建一个虚拟的网关出来
|
zbGateway.ReSave();
|
var way = this.GetGatewayFromFile(zbGateway.FilePath);
|
this.dicGateway[gwID] = way;
|
}
|
|
//刷新的是缓存,不刷新真实物理网关
|
this.dicGateway[gwID].OnlineTime = DateTime.Now;
|
//将网关的数据设置到本地缓存中
|
this.SetGatewayDataToLocalMemmory(this.dicGateway[gwID], result);
|
//顺便这个变量也设置一下
|
this.SetGatewayDataToLocalMemmory(zbGateway, result, false);
|
|
if (isEsist == false)
|
{
|
//添加备份
|
HdlBackupLogic.Current.AddOrEditorAutoBackFileStatu(this.dicGateway[gwID].FilePath);
|
}
|
|
//添加网关的话,强制主页刷新
|
UserView.UserPage.Instance.RefreshAllForm = true;
|
|
if (Config.Instance.Home.TemplateMode == 2)
|
{
|
//如果这个类型的网关只有一个模板,则自动匹配
|
var dicName = HdlTemplateCommonLogic.Current.GetGatewayCanSelectTemplateName(zbGateway);
|
if (dicName.Count == 1)
|
{
|
foreach (var tempId in dicName.Keys)
|
{
|
HdlTemplateCommonLogic.Current.AddGatewayTemplateSelect(zbGateway.GwId, tempId);
|
break;
|
}
|
}
|
}
|
|
return 1;
|
}
|
|
#endregion
|
|
#region ■ 修改网关___________________________
|
|
/// <summary>
|
/// 修改本地网关名字(失败时会显示信息)
|
/// </summary>
|
/// <param name="zbGateway">网关对象</param>
|
/// <param name="gatewayName">网关名</param>
|
public bool ReName(ZbGateway zbGateway, string gatewayName)
|
{
|
//只取32个byte
|
var bytes = new byte[32];
|
var reamarkGwBytes = System.Text.Encoding.UTF8.GetBytes(gatewayName);
|
System.Array.Copy(reamarkGwBytes, 0, bytes, 0, 32 < reamarkGwBytes.Length ? 32 : reamarkGwBytes.Length);
|
gatewayName = System.Text.Encoding.UTF8.GetString(bytes);
|
|
var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 0 }, { "Command", 91 } };
|
var data = new Newtonsoft.Json.Linq.JObject { { "GwName", gatewayName } };
|
jObject.Add("Data", data);
|
var result = this.SendJobjectDataToGateway(zbGateway.GwId, "GwReName", jObject.ToString(), "GwReName_Respon");
|
if (result.ErrorMsg != null)
|
{
|
this.ShowTipMsg(result.ErrorMsg);
|
return false;
|
}
|
if (result.ErrorMsgDiv == 0)
|
{
|
//网关名称修改失败
|
string msg = Language.StringByID(R.MyInternationalizationString.uGatewayReNameFail);
|
//网关回复超时
|
msg = HdlCommonLogic.Current.CombineGatewayTimeOutMsg(msg, null, "回复超时");
|
this.ShowTipMsg(msg);
|
return false;
|
}
|
|
//修改缓存
|
string gwID = zbGateway.GwId;
|
this.dicGateway[gwID].GwName = gatewayName;
|
this.dicGateway[gwID].ReSave();
|
|
//添加自动备份
|
HdlBackupLogic.Current.AddOrEditorAutoBackFileStatu(zbGateway.FilePath);
|
|
return true;
|
}
|
|
#endregion
|
|
#region ■ 网关切换___________________________
|
|
/// <summary>
|
/// 执行切换网关操作
|
/// </summary>
|
/// <param name="gatewayId"></param>
|
public bool DoSwitchGateway(string gatewayId)
|
{
|
//重新获取在线网关的信息
|
var result = this.GetOnlineGatewayInfo(gatewayId);
|
if (result == false)
|
{
|
return false;
|
}
|
|
//切换网关,保存缓存
|
this.SaveGatewayIdToLocation(gatewayId);
|
//切换网关的话,主页需要重新刷新
|
UserView.UserPage.Instance.RefreshAllForm = true;
|
|
return true;
|
}
|
|
/// <summary>
|
/// 获取在线网关信息
|
/// </summary>
|
/// <param name="gatewayId"></param>
|
/// <returns></returns>
|
private bool GetOnlineGatewayInfo(string gatewayId)
|
{
|
//显示进度条
|
ProgressBar.Show();
|
|
//检测广播到的这个网关是否拥有住宅ID
|
ZbGateway realWay = null;
|
bool getGatewayInfo = true;
|
if (this.GetRealGateway(ref realWay, gatewayId) == true)
|
{
|
//重新设置住宅ID(这个应该是不经过APP,直接把网关恢复了出厂设置)
|
if (this.HomeIdIsEmpty(realWay.HomeId) == true)
|
{
|
int result2 = this.ReBindNewGateway(realWay);
|
if (result2 == 0)
|
{
|
//出现未知错误,请稍后再试
|
this.ShowTipMsg(Language.StringByID(R.MyInternationalizationString.uUnKnowErrorAndResetAgain));
|
//关闭进度条
|
ProgressBar.Close();
|
}
|
else if (result2 == -1)
|
{
|
//关闭进度条
|
ProgressBar.Close();
|
return false;
|
}
|
//重新绑定网关里面已经重新获取了网关信息
|
getGatewayInfo = false;
|
}
|
}
|
|
if (getGatewayInfo == true)
|
{
|
//获取网关信息
|
var info = this.RefreshGatewayInfo(realWay, false);
|
if (info == null)
|
{
|
//关闭进度条
|
ProgressBar.Close();
|
return false;
|
}
|
}
|
//刷新全部场景
|
if (this.IsMainGateway(realWay) == 1)
|
{
|
HdlSceneLogic.Current.RefreshSceneUIList(false);
|
}
|
|
//获取全部设备
|
int result = HdlDeviceCommonLogic.Current.SetDeviceToMemmoryByGateway(realWay.GwId, false);
|
//关闭进度条
|
ProgressBar.Close();
|
if (result == -1)
|
{
|
return false;
|
}
|
return true;
|
}
|
|
/// <summary>
|
/// 保存选择的网关ID到本地
|
/// </summary>
|
/// <param name="gatewayId"></param>
|
public void SaveGatewayIdToLocation(string gatewayId)
|
{
|
HdlGatewayResourse.AppOldSelectGatewayId = gatewayId;
|
HdlFileLogic.Current.SaveFileContent(HdlFileNameResourse.AppOldSelectGatewayFile, HdlGatewayResourse.AppOldSelectGatewayId);
|
}
|
|
#endregion
|
|
#region ■ 删除网关___________________________
|
|
/// <summary>
|
/// 删除网关,包括云端和本地(失败时不会显示信息,并且会返回true)
|
/// </summary>
|
/// <param name="zbGatewayID"></param>
|
public bool DeleteGateway(string zbGatewayID)
|
{
|
ZbGateway realWay = null;
|
this.GetRealGateway(ref realWay, zbGatewayID);
|
//清空网关的住宅ID 网关解绑失败 不理它,因为网关可以按按键强制搜索得到
|
if (realWay != null)
|
{
|
this.SetHomeIdToGateway(realWay, string.Empty, ShowErrorMode.NO);
|
}
|
|
//删除云端的网关
|
this.DeleteDataBaseGateway(zbGatewayID);
|
|
//删除网关文件
|
this.DeleteGatewayFile(zbGatewayID);
|
|
//移除
|
ZbGateway.GateWayList.RemoveAll((obj) => obj.GwId == zbGatewayID);
|
//断开mqtt连接
|
if (realWay != null)
|
{
|
realWay.CloseLocalConnectionOnForce();
|
}
|
|
return true;
|
}
|
|
/// <summary>
|
/// 删除网关文件
|
/// </summary>
|
/// <param name="zbGatewayID">网关id</param>
|
public void DeleteGatewayFile(string zbGatewayID)
|
{
|
if (dicGateway.ContainsKey(zbGatewayID) == false)
|
{
|
return;
|
}
|
//删除文件
|
string file = dicGateway[zbGatewayID].FilePath;
|
if (Global.IsExistsByHomeId(file) == true)
|
{
|
Global.DeleteFilebyHomeId(file);
|
}
|
|
//移除缓存
|
dicGateway.Remove(zbGatewayID);
|
//删除自动备份
|
HdlBackupLogic.Current.DeleteAutoBackFileStatu(file);
|
|
//删除设备文件
|
List<CommonDevice> list = HdlDeviceCommonLogic.Current.GetDeviceByGatewayID(zbGatewayID);
|
foreach (var device in list)
|
{
|
//删除设备文件
|
HdlDeviceCommonLogic.Current.DeleteMemmoryDevice(device, true);
|
//删除Ota设备
|
HdlDeviceCommonLogic.Current.DeleteMemmoryOtaDevice(device.DeviceAddr);
|
}
|
//如果是主网关
|
if (this.IsMainGateway(zbGatewayID) == 1)
|
{
|
var listAllRoom = HdlRoomLogic.Current.GetAllListRooms();
|
foreach (var room in listAllRoom)
|
{
|
//删除场景文件
|
foreach (var sceneId in room.ListSceneId)
|
{
|
if (Global.IsExistsByHomeId($"Scene_{sceneId}.json") == true)
|
{
|
Global.DeleteFilebyHomeId($"Scene_{sceneId}.json");
|
}
|
}
|
}
|
}
|
}
|
|
#endregion
|
|
#region ■ 网关掉线___________________________
|
|
/// <summary>
|
/// 刷新网关的在线状态(注意,刷新的是缓存,请调用CheckGatewayOnlineByFlag来判断是否在线)
|
/// </summary>
|
/// <param name="listGateway"></param>
|
/// <returns></returns>
|
public void RefreshGatewayOnlineStatu(List<ZbGateway> listGateway)
|
{
|
var listRealWay = new List<ZbGateway>();
|
for (int i = 0; i < listGateway.Count; i++)
|
{
|
ZbGateway zbTemp = null;
|
if (this.GetRealGateway(ref zbTemp, listGateway[i]) == true)
|
{
|
//真实物理网关
|
listRealWay.Add(zbTemp);
|
}
|
else
|
{
|
//虚拟物理网关
|
listRealWay.Add(listGateway[i]);
|
}
|
}
|
//检查是否拥有网关存在于WIFi下
|
if (this.CheckHadGatewayInWifi(listRealWay) == false)
|
{
|
//第二道坎:在远程的情况下刷新网关的在线状态
|
this.RefreshGatewayOnlineOnRemode(listRealWay);
|
}
|
//wifi情况下,由Application自己刷新标识
|
}
|
|
/// <summary>
|
/// 检查是否拥有网关存在于WIFi下
|
/// </summary>
|
/// <param name="listGateway"></param>
|
/// <returns></returns>
|
private bool CheckHadGatewayInWifi(List<ZbGateway> listGateway)
|
{
|
foreach (var zbway in listGateway)
|
{
|
//如果广播得到网关,则会刷新OnlineTime,如果与当前时间相差少于指定秒数,则判断为存在网关存在于WIFI下
|
if ((DateTime.Now - zbway.OnlineTime).TotalSeconds <= ZigBee.Common.Application.SendTime * 2)
|
{
|
return true;
|
}
|
}
|
return false;
|
}
|
|
/// <summary>
|
/// 在远程的情况下刷新网关的在线状态
|
/// </summary>
|
/// <param name="listGateway"></param>
|
/// <returns></returns>
|
private void RefreshGatewayOnlineOnRemode(List<ZbGateway> listGateway)
|
{
|
//获取云端上面的网关
|
Dictionary<string, GatewayResult> dicDbGateway = this.GetGateWayListFromDataBase(Config.Instance.Home.Id);
|
if (dicDbGateway == null)
|
{
|
return;
|
}
|
foreach (var way in listGateway)
|
{
|
if (way == null)
|
{
|
continue;
|
}
|
string strId = way.GwId;
|
if (dicDbGateway.ContainsKey(strId) == true
|
&& dicDbGateway[strId].MqttOnlineStatus == true) //如果云端上面有这个网关
|
{
|
way.OnlineTime = DateTime.Now;
|
}
|
}
|
}
|
|
/// <summary>
|
/// 根据本地缓存判断指定网关是否在线
|
/// </summary>
|
/// <param name="zbGateway"></param>
|
/// <returns></returns>
|
public bool CheckGatewayOnlineByMemory(ZbGateway zbGateway)
|
{
|
if (zbGateway == null)
|
{
|
return false;
|
}
|
//使用缓存的,因为刷新在线状态的时候,刷新的就是缓存,而不是真实物理网关
|
string gwID = zbGateway.GwId;
|
if (this.dicGateway.ContainsKey(gwID) == true)
|
{
|
return this.CheckGatewayOnlineByFlage(dicGateway[gwID]);
|
}
|
|
return this.CheckGatewayOnlineByFlage(zbGateway);
|
}
|
|
/// <summary>
|
/// 刷新网关的在线时间点
|
/// </summary>
|
/// <param name="i_gatewayId">网关ID</param>
|
public void RefreshGatewayOnlineTime(string i_gatewayId)
|
{
|
try
|
{
|
if (this.dicGateway.ContainsKey(i_gatewayId) == true)
|
{
|
this.dicGateway[i_gatewayId].OnlineTime = DateTime.Now;
|
}
|
}
|
catch { }
|
}
|
|
/// <summary>
|
/// 根据指定标识,判断网关是否在线
|
/// </summary>
|
/// <param name="zbGateway"></param>
|
/// <returns></returns>
|
private bool CheckGatewayOnlineByFlage(ZbGateway zbGateway)
|
{
|
if (this.nowGwConnectMode == GatewayConnectMode.Remote)
|
{
|
//远程每20秒检测一次
|
return (DateTime.Now - zbGateway.OnlineTime).TotalSeconds <= 40;
|
}
|
//如果广播得到网关,则会刷新OnlineTime,如果与当前时间相差少于10秒,则判断为在线
|
return (DateTime.Now - zbGateway.OnlineTime).TotalSeconds <= 15;
|
}
|
|
#endregion
|
|
#region ■ 获取网关___________________________
|
|
/// <summary>
|
/// 从网关获取全部的网关(以本地网关为标准)
|
/// </summary>
|
/// <returns></returns>
|
public List<ZbGateway> GetAllGatewayFromGateway()
|
{
|
//不要去Foreach 它的列表
|
List<ZbGateway> list = new List<ZbGateway>();
|
list.AddRange(ZbGateway.GateWayList);
|
|
List<ZbGateway> newlist = new List<ZbGateway>();
|
foreach (var way in list)
|
{
|
if (Config.Instance.HomeId != way.HomeId)
|
{
|
//如果不是当前住宅
|
continue;
|
}
|
string gwID = way.GwId;
|
if (this.dicGateway.ContainsKey(gwID) == false)
|
{
|
//如果本地并没有这个网关
|
continue;
|
}
|
newlist.Add(way);
|
}
|
return newlist;
|
}
|
|
/// <summary>
|
/// 获取本地全部的网关
|
/// </summary>
|
/// <returns>The all gateway.</returns>
|
public List<ZbGateway> GetAllLocalGateway()
|
{
|
List<ZbGateway> listData = new List<ZbGateway>();
|
lock (dicGateway)
|
{
|
foreach (var way in dicGateway.Values)
|
{
|
listData.Add(way);
|
}
|
}
|
return listData;
|
}
|
|
/// <summary>
|
/// 获取本地的网关
|
/// </summary>
|
/// <param name="gatewayId">网关ID</param>
|
/// <returns></returns>
|
public ZbGateway GetLocalGateway(string gatewayId)
|
{
|
if (this.dicGateway.ContainsKey(gatewayId) == true)
|
{
|
return this.dicGateway[gatewayId];
|
}
|
return null;
|
}
|
|
/// <summary>
|
/// 获取本地所有的网关文件
|
/// </summary>
|
/// <returns></returns>
|
public List<string> GetAllGatewayFile()
|
{
|
List<string> list = new List<string>();
|
List<string> listFile = HdlFileLogic.Current.GetRootPathListFile();
|
foreach (string file in listFile)
|
{
|
//只获取网关设备
|
if (file.StartsWith(gwFirstName) == false)
|
{
|
continue;
|
}
|
list.Add(file);
|
}
|
return list;
|
}
|
|
/// <summary>
|
/// 获取系统内部的真实网关对象变量
|
/// </summary>
|
/// <param name="zbGateway">真实网关</param>
|
/// <param name="tagartWay">目标网关</param>
|
/// <returns></returns>
|
public bool GetRealGateway(ref ZbGateway zbGateway, ZbGateway tagartWay)
|
{
|
if (tagartWay == null)
|
{
|
return false;
|
}
|
return this.GetRealGateway(ref zbGateway, tagartWay.GwId);
|
}
|
|
/// <summary>
|
/// 获取系统内部的真实网关对象变量
|
/// </summary>
|
/// <param name="zbGateway"></param>
|
/// <param name="gwId"></param>
|
/// <returns></returns>
|
public bool GetRealGateway(ref ZbGateway zbGateway, string gwId)
|
{
|
var realWay = ZbGateway.GateWayList.Find((obj) =>
|
{
|
return obj.GwId == gwId;
|
});
|
if (realWay == null)
|
{
|
//如果网关对象丢失了,则创建个新的
|
realWay = new ZbGateway { IsVirtual = true, };
|
realWay.GwId = gwId;
|
realWay.HomeId = Shared.Common.Config.Instance.HomeId;
|
ZbGateway.GateWayList.Add(realWay);
|
}
|
zbGateway = realWay;
|
return true;
|
}
|
|
#endregion
|
|
#region ■ 获取协调器当前信道_________________
|
|
/// <summary>
|
/// 获取协调器当前信道(会有等待延迟,返回-1代表错误)
|
/// </summary>
|
/// <param name="zbGateway"></param>
|
/// <returns></returns>
|
public int GetGatewayChannelId(ZbGateway zbGateway)
|
{
|
ZbGateway realWay = null;
|
if (this.GetRealGateway(ref realWay, zbGateway) == false)
|
{
|
//错误:网关对象丢失
|
this.ShowTipMsg(Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg));
|
return -1;
|
}
|
int data = -1;
|
Action<string, string> action = (topic, message) =>
|
{
|
var gatewayID = topic.Split('/')[0];
|
if (topic == gatewayID + "/" + "ZbGw/GetChannel_Respon")
|
{
|
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
|
data = Convert.ToInt32(jobject["Data"]["Channel"].ToString());
|
}
|
};
|
realWay.Actions += action;
|
|
var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 64512 }, { "Command", 8 } };
|
realWay.Send("ZbGw/GetChannel", jObject.ToString());
|
|
int TimeOut = 0;
|
while (data == -1 && TimeOut < 30)
|
{
|
System.Threading.Thread.Sleep(100);
|
TimeOut++;
|
}
|
|
realWay.Actions -= action;
|
if (data == -1)
|
{
|
//获取协调器信道失败
|
string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayChannelIdFail);
|
msg = HdlCommonLogic.Current.CombineGatewayTimeOutMsg(msg, null, "回复超时");
|
this.ShowTipMsg(msg);
|
}
|
|
return data;
|
}
|
|
#endregion
|
|
#region ■ 获取协调器MAC______________________
|
|
/// <summary>
|
/// 获取协调器MAC地址(会有等待延迟,返回null代表错误)
|
/// </summary>
|
/// <param name="zbGateway"></param>
|
/// <returns></returns>
|
public string GetGatewayCoordinatorMac(ZbGateway zbGateway)
|
{
|
ZbGateway realWay = null;
|
if (this.GetRealGateway(ref realWay, zbGateway) == false)
|
{
|
//错误:网关对象丢失
|
this.ShowTipMsg(Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg));
|
return null;
|
}
|
string data = null;
|
Action<string, string> action = (topic, message) =>
|
{
|
var gatewayID = topic.Split('/')[0];
|
if (topic == gatewayID + "/" + "ZbGw/GetMac_Respon")
|
{
|
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
|
data = jobject["Data"]["MacAddr"].ToString();
|
}
|
};
|
realWay.Actions += action;
|
|
var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 64512 }, { "Command", 13 } };
|
realWay.Send("ZbGw/GetMac", jObject.ToString());
|
|
int TimeOut = 0;
|
while (data == null && TimeOut < 30)
|
{
|
System.Threading.Thread.Sleep(100);
|
TimeOut++;
|
}
|
|
realWay.Actions -= action;
|
if (data == null)
|
{
|
//获取协调器Mac失败
|
string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayCoordinatorMacFail);
|
msg = HdlCommonLogic.Current.CombineGatewayTimeOutMsg(msg, null, "回复超时");
|
this.ShowTipMsg(msg);
|
}
|
|
return data;
|
}
|
|
#endregion
|
|
#region ■ 获取协调器PanID____________________
|
|
/// <summary>
|
/// 获取协调器PanID(会有等待延迟,返回-1代表错误)
|
/// </summary>
|
/// <param name="zbGateway"></param>
|
/// <returns></returns>
|
public int GetGatewayPanId(ZbGateway zbGateway)
|
{
|
ZbGateway realWay = null;
|
if (this.GetRealGateway(ref realWay, zbGateway) == false)
|
{
|
//错误:网关对象丢失
|
this.ShowTipMsg(Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg));
|
return -1;
|
}
|
int panId = -1;
|
Action<string, string> action = (topic, message) =>
|
{
|
var gatewayID = topic.Split('/')[0];
|
if (topic == gatewayID + "/" + "ZbGw/GetPanId_Respon")
|
{
|
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
|
panId = Convert.ToInt32(jobject["Data"]["PANID"].ToString());
|
}
|
};
|
realWay.Actions += action;
|
|
var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 64512 }, { "Command", 12 } };
|
realWay.Send("ZbGw/GetPanId", jObject.ToString());
|
|
int TimeOut = 0;
|
while (panId == -1 && TimeOut < 30)
|
{
|
System.Threading.Thread.Sleep(100);
|
TimeOut++;
|
}
|
|
realWay.Actions -= action;
|
if (panId == -1)
|
{
|
//获取协调器PanID失败
|
string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayPanIDFail);
|
msg = HdlCommonLogic.Current.CombineGatewayTimeOutMsg(msg, null, "回复超时");
|
this.ShowTipMsg(msg);
|
}
|
|
return panId;
|
}
|
|
#endregion
|
|
#region ■ 网关自动备份设置___________________
|
|
/// <summary>
|
/// 获取网关自动备份设置(-1:异常 0:关闭 1:打开)
|
/// </summary>
|
/// <param name="zbGateway"></param>
|
/// <returns></returns>
|
public int GetGatewayAutoBackupStatu(ZbGateway zbGateway)
|
{
|
ZbGateway realWay = null;
|
if (this.GetRealGateway(ref realWay, zbGateway) == false)
|
{
|
//错误:网关对象丢失
|
this.ShowTipMsg(Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg));
|
return -1;
|
}
|
int statu = -1;
|
Action<string, string> action = (topic, message) =>
|
{
|
var gatewayID = topic.Split('/')[0];
|
if (topic == gatewayID + "/GatewayAutoBackup_Respon")
|
{
|
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
|
statu = Convert.ToInt32(jobject["Data"]["AutoBackupStatus"].ToString());
|
}
|
};
|
realWay.Actions += action;
|
|
var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 0 }, { "Command", 6205 } };
|
var data = new Newtonsoft.Json.Linq.JObject { { "AutoBackup", 1 } };
|
jObject.Add("Data", data);
|
realWay.Send("GatewayAutoBackup", jObject.ToString());
|
|
int TimeOut = 0;
|
while (statu == -1 && TimeOut < 60)
|
{
|
System.Threading.Thread.Sleep(100);
|
TimeOut++;
|
}
|
|
realWay.Actions -= action;
|
if (statu == -1)
|
{
|
//获取网关自动备份设置失败
|
string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayAutoBackupStatuFail);
|
msg = HdlCommonLogic.Current.CombineGatewayTimeOutMsg(msg, null, "回复超时");
|
this.ShowTipMsg(msg);
|
}
|
|
return statu;
|
}
|
|
/// <summary>
|
/// 设置网关自动备份设置
|
/// </summary>
|
/// <param name="zbGateway"></param>
|
/// <param name="statu"></param>
|
/// <returns></returns>
|
public bool SetGatewayAutoBackupStatu(ZbGateway zbGateway, bool statu)
|
{
|
ZbGateway realWay = null;
|
if (this.GetRealGateway(ref realWay, zbGateway) == false)
|
{
|
//错误:网关对象丢失
|
this.ShowTipMsg(Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg));
|
return false;
|
}
|
int result = -1;
|
Action<string, string> action = (topic, message) =>
|
{
|
var gatewayID = topic.Split('/')[0];
|
if (topic == gatewayID + "/GatewayAutoBackup_Respon")
|
{
|
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
|
result = Convert.ToInt32(jobject["Data"]["AutoBackupStatus"].ToString());
|
}
|
};
|
realWay.Actions += action;
|
|
var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 0 }, { "Command", 6205 } };
|
var data = new Newtonsoft.Json.Linq.JObject { { "AutoBackup", statu == true ? 2 : 3 } };
|
jObject.Add("Data", data);
|
realWay.Send("GatewayAutoBackup", jObject.ToString());
|
|
int TimeOut = 0;
|
while (result == -1 && TimeOut < 60)
|
{
|
System.Threading.Thread.Sleep(100);
|
TimeOut++;
|
}
|
|
realWay.Actions -= action;
|
if (result == -1)
|
{
|
//设置网关自动备份失败
|
string msg = Language.StringByID(R.MyInternationalizationString.uSetGatewayAutoBackupStatuFail);
|
msg = HdlCommonLogic.Current.CombineGatewayTimeOutMsg(msg, null, "回复超时");
|
this.ShowTipMsg(msg);
|
return false;
|
}
|
|
return true;
|
}
|
|
#endregion
|
|
#region ■ 获取名称___________________________
|
|
/// <summary>
|
/// 获取网关加特效的名称
|
/// </summary>
|
/// <param name="zbGateway"></param>
|
/// <returns></returns>
|
public string GetGatewayName(ZbGateway zbGateway)
|
{
|
if (zbGateway == null) { return string.Empty; }
|
|
string gwId = zbGateway.GwId;
|
if (this.dicGateway.ContainsKey(gwId) == false)
|
{
|
return zbGateway.GwName;
|
}
|
var localWay = this.dicGateway[gwId];
|
|
string name = this.GetGatewaySimpleName(localWay);
|
if (string.IsNullOrEmpty(name) == false)
|
{
|
return name;
|
}
|
|
var nameContent = HdlDeviceCommonLogic.Current.GetDeviceModelIdNameInfo(localWay.LinuxImageType.ToString());
|
if (nameContent != null)
|
{
|
return nameContent.A备注名字;
|
}
|
|
return string.Empty;
|
}
|
|
/// <summary>
|
/// 单纯获取网关名称
|
/// </summary>
|
/// <param name="zbGateway">网关对象</param>
|
/// <returns></returns>
|
private string GetGatewaySimpleName(ZbGateway zbGateway)
|
{
|
if (zbGateway == null)
|
{
|
return string.Empty;
|
}
|
return zbGateway.GwName;
|
}
|
|
/// <summary>
|
/// 设置网关镜像类型的翻译名字
|
/// </summary>
|
/// <param name="button"></param>
|
/// <param name="zbGateway"></param>
|
/// <returns></returns>
|
public void SetGatewayImageText(Button button, ZbGateway zbGateway)
|
{
|
//初始值:无法识别的网关设备
|
button.TextID = R.MyInternationalizationString.uUnDistinguishTheGatewayDevice;
|
|
string gwId = zbGateway.GwId;
|
if (this.dicGateway.ContainsKey(gwId) == false)
|
{
|
//如果这个网关没有信息,则从新获取
|
if (zbGateway.LinuxImageType != -1)
|
{
|
var nameContent = HdlDeviceCommonLogic.Current.GetDeviceModelIdNameInfo(zbGateway.LinuxImageType.ToString());
|
if (nameContent != null)
|
{
|
button.Text = nameContent.A官方名字;
|
}
|
}
|
else
|
{
|
//给一个线程去获取它的镜像类型
|
HdlThreadLogic.Current.RunThread(() =>
|
{
|
var result = this.RefreshGatewayInfo(zbGateway, false, ShowErrorMode.NO);
|
if (result != null)
|
{
|
//将网关的数据设置到本地缓存中
|
this.SetGatewayDataToLocalMemmory(zbGateway, result, false);
|
|
HdlThreadLogic.Current.RunMain(() =>
|
{
|
var nameContent = HdlDeviceCommonLogic.Current.GetDeviceModelIdNameInfo(zbGateway.LinuxImageType.ToString());
|
if (nameContent != null)
|
{
|
button.Text = nameContent.A官方名字;
|
}
|
});
|
}
|
});
|
}
|
}
|
else
|
{
|
var nameContent = HdlDeviceCommonLogic.Current.GetDeviceModelIdNameInfo(zbGateway.LinuxImageType.ToString());
|
if (nameContent != null)
|
{
|
button.Text = nameContent.A官方名字;
|
}
|
}
|
}
|
|
#endregion
|
|
#region ■ 获取网关信息_______________________
|
|
/// <summary>
|
/// 刷新网关信息(版本信息,镜像类型,基本信息等。只刷新本地网关的缓存)
|
/// </summary>
|
/// <param name="zbGateway"></param>
|
/// <param name="useLocalConnect">是否强制使用本地连接发送</param>
|
/// <param name="mode"></param>
|
/// <returns></returns>
|
public ZbGatewayData.GetGwData RefreshGatewayInfo(ZbGateway zbGateway, bool useLocalConnect, ShowErrorMode mode = ShowErrorMode.YES)
|
{
|
//从网关那里刷新网关信息
|
var getGwInfo = this.RefreshGatewayInfo(zbGateway.GwId, useLocalConnect, mode);
|
//顺便这个变量也设置一下
|
this.SetGatewayDataToLocalMemmory(zbGateway, getGwInfo, false);
|
|
return getGwInfo;
|
}
|
|
/// <summary>
|
/// 从网关那里刷新网关信息
|
/// </summary>
|
/// <param name="gatewateId">网关ID</param>
|
/// <param name="useLocalConnect">是否强制使用本地连接发送</param>
|
/// <param name="mode"></param>
|
/// <returns></returns>
|
public ZbGatewayData.GetGwData RefreshGatewayInfo(string gatewateId, bool useLocalConnect, ShowErrorMode mode = ShowErrorMode.YES)
|
{
|
//获取网关版本信息
|
var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 0 }, { "Command", 95 } };
|
var result = this.SendJobjectDataToGateway(gatewateId, "GetZbGwInfo", jObject.ToString(), "GetZbGwInfo_Respon", 5, useLocalConnect);
|
|
if (result.ErrorMsgDiv != 1)
|
{
|
if (mode == ShowErrorMode.YES)
|
{
|
//获取网关信息失败
|
string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayInfoFail);
|
//拼接上【网关回复超时】的Msg
|
msg = HdlCommonLogic.Current.CombineGatewayTimeOutMsg(msg, null, "回复超时");
|
this.ShowErrorMsg(msg);
|
}
|
return null;
|
}
|
|
var getGwInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<ZbGatewayData.GetGwData>(result.ReceiptData);
|
if (this.dicGateway.ContainsKey(gatewateId) == true)
|
{
|
//刷新缓存
|
ZbGateway localWay = this.dicGateway[gatewateId];
|
//将网关的数据设置到本地缓存中
|
this.SetGatewayDataToLocalMemmory(localWay, getGwInfo);
|
}
|
return getGwInfo;
|
}
|
|
/// <summary>
|
/// 将网关的数据设置到本地缓存中
|
/// </summary>
|
/// <param name="localWay">本地网关</param>
|
/// <param name="data">网关数据</param>
|
/// <param name="saveFile">是否保存文件</param>
|
private void SetGatewayDataToLocalMemmory(ZbGateway localWay, ZbGatewayData.GetGwData data, bool saveFile = true)
|
{
|
localWay.GwId = data.GwId;
|
localWay.GwName = data.GwName;
|
localWay.GwSerialNum = data.GWSN;
|
localWay.IsMainGateWay = data.IsDominant == 1 ? true : false;
|
localWay.GwIP = data.GwIP;
|
localWay.GwMac = data.GwMac;
|
localWay.LinuxImageType = data.LinuxImageType;
|
localWay.LinuxHardVersion = data.LinuxHWVersion;
|
localWay.LinuxFirmwareVersion = data.LinuxFWVersion;
|
localWay.CoordinatorHardVersion = data.ZbHWVersion;
|
localWay.CoordinatorFirmwareVersion = data.ZbFWVersion;
|
localWay.CoordinatorImageId = data.ZbImageType;
|
localWay.DriveCodeList = data.DriveCodeList;
|
localWay.GwVersionDate = data.AppVersion;
|
localWay.OnlineTime = DateTime.Now;
|
|
if (saveFile == true)
|
{
|
localWay.ReSave();
|
}
|
}
|
|
#endregion
|
|
#region ■ 清空真实网关链接___________________
|
|
/// <summary>
|
/// 清空全部的真实物理网关的链接
|
/// </summary>
|
/// <param name="roadGateway">是否加载本地的网关对象到真实列表中</param>
|
public void ClearAllRealGatewayConection(bool roadGateway)
|
{
|
//断开mqtt连接(即使保存在内存当中也没问题,因为如果广播不到,则它不会建立链接)
|
for (int i = 0; i < ZbGateway.GateWayList.Count; i++)
|
{
|
ZbGateway.GateWayList[i].CloseLocalConnectionOnForce();
|
}
|
//加载本地网关对象
|
if (roadGateway == true)
|
{
|
List<string> listFile = this.GetAllGatewayFile();
|
//反序列化添加到缓存
|
foreach (string file in listFile)
|
{
|
//从文件中反序列化出网关对象
|
var gateway = this.GetGatewayFromFile(file);
|
if (gateway == null)
|
{
|
continue;
|
}
|
var tempWay = ZbGateway.GateWayList.Find(obj => (obj != null) && (obj.GwId == gateway.GwId));
|
if (tempWay == null)
|
{
|
ZbGateway.GateWayList.Add(gateway);
|
}
|
}
|
}
|
}
|
|
#endregion
|
|
#region ■ 检测并获取网关各种固件新版本_______
|
|
/// <summary>
|
/// 检测并获取网关各固件的新版本,没有新版本,则对应位置存的是null,直接返回null代表失败(0:Linux新版本 1:协调器新版本 2~X:都是虚拟驱动的)
|
/// </summary>
|
/// <param name="zbGateway">网关对象</param>
|
/// <param name="mode">错误时,是否显示错误</param>
|
/// <returns></returns>
|
public List<FirmwareVersionInfo> GetGatewayAllNewVersion(ZbGateway zbGateway, ShowErrorMode mode = ShowErrorMode.YES)
|
{
|
//如果是展示模板,或者是虚拟住宅的话,没有什么新版本的说法
|
if (Common.Config.Instance.Home.IsVirtually == true || Common.Config.Instance.Home.IsShowTemplate == true)
|
{
|
return new List<FirmwareVersionInfo> { null, null, null };
|
}
|
//获取网关版本信息
|
var result = this.RefreshGatewayInfo(zbGateway, false, mode);
|
if (result == null)
|
{
|
return null;
|
}
|
//使用本地缓存对象
|
var localWay = this.GetLocalGateway(zbGateway.GwId);
|
if (localWay == null)
|
{
|
return null;
|
}
|
|
//添加网关的升级固件(成不成功都无所谓)
|
var flage = HdlFirmwareUpdateLogic.Current.AddFirmwareVersionInfo(FirmwareLevelType.Linux,
|
localWay.LinuxHardVersion.ToString(),
|
localWay.LinuxImageType.ToString());
|
|
//添加协调器的升级固件(成不成功都无所谓) 必须能够联网才行
|
if (flage == 1)
|
{
|
//没网的时候不再处理
|
HdlFirmwareUpdateLogic.Current.AddFirmwareVersionInfo(FirmwareLevelType.A协调器,
|
localWay.CoordinatorHardVersion.ToString(),
|
localWay.CoordinatorImageId.ToString());
|
}
|
|
//网关的版本
|
var gatewayFirmware = HdlFirmwareUpdateLogic.Current.GetFirmwareMostVersionInfo(FirmwareLevelType.Linux,
|
localWay.LinuxHardVersion.ToString(),
|
localWay.LinuxImageType.ToString(),
|
localWay.LinuxFirmwareVersion);
|
|
//协调器版本
|
var coordinatorFirmware = HdlFirmwareUpdateLogic.Current.GetFirmwareMostVersionInfo(FirmwareLevelType.A协调器,
|
localWay.CoordinatorHardVersion.ToString(),
|
localWay.CoordinatorImageId.ToString(),
|
localWay.CoordinatorFirmwareVersion);
|
|
var list = new List<FirmwareVersionInfo>();
|
list.Add(gatewayFirmware);
|
list.Add(coordinatorFirmware);
|
|
//这个网关需要有虚拟驱动这个东西才行
|
if (HdlGatewayLogic.Current.CheckGatewayHadDriveCode(localWay) == true)
|
{
|
//虚拟驱动号
|
foreach (var data in localWay.DriveCodeList)
|
{
|
//添加虚拟驱动的升级固件(成不成功都无所谓) 必须能够联网才行
|
if (flage == 1)
|
{
|
HdlFirmwareUpdateLogic.Current.AddFirmwareVersionInfo(FirmwareLevelType.A虚拟驱动,
|
data.DriveHwVersion.ToString(),
|
data.DriveImageType.ToString());
|
}
|
|
//虚拟驱动
|
var virtualFirmware = HdlFirmwareUpdateLogic.Current.GetFirmwareMostVersionInfo(FirmwareLevelType.A虚拟驱动,
|
data.DriveHwVersion.ToString(),
|
data.DriveImageType.ToString(),
|
data.DriveFwVersion);
|
|
if (virtualFirmware != null)
|
{
|
virtualFirmware.VirtualCode = data.DriveCode;
|
list.Add(virtualFirmware);
|
}
|
}
|
}
|
if (list.Count == 2)
|
{
|
//虚拟驱动如果没有新版本的话,固定添加一个空的
|
list.Add(null);
|
}
|
return list;
|
}
|
|
/// <summary>
|
/// 获取网关的虚拟驱动号(返回null时代表获取失败)
|
/// </summary>
|
/// <param name="zbGateway"></param>
|
/// <returns></returns>
|
public List<ZbGatewayData.DriveCodeObj> GetListVDDriveCode(ZbGateway zbGateway)
|
{
|
//如果是展示模板,或者是虚拟住宅的话,直接取缓存
|
if (Common.Config.Instance.Home.IsVirtually == true || Common.Config.Instance.Home.IsShowTemplate == true)
|
{
|
//取本地对象
|
var localgw = this.GetLocalGateway(zbGateway.GwId);
|
return localgw != null ? zbGateway.DriveCodeList : zbGateway.DriveCodeList;
|
}
|
var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 0 }, { "Command", 505 } };
|
var result = this.SendJobjectDataToGateway(zbGateway.GwId, "VirtualDrive/CatDriveCode", jObject.ToString(), "VirtualDrive/CatDriveCode_Respon");
|
if (result.ErrorMsg != null)
|
{
|
this.ShowTipMsg(result.ErrorMsg);
|
}
|
if (result.ErrorMsgDiv == 0)
|
{
|
return null;
|
}
|
var dataInfo = JsonConvert.DeserializeObject<ZbGatewayData.VDriveDriveCodeResponData>(result.ReceiptData);
|
return dataInfo.DriveCodeList;
|
}
|
|
#endregion
|
|
#region ■ 主网关判定_________________________
|
|
/// <summary>
|
/// 判断是否主网关(1:主网关 0:不在线 2:子网关)
|
/// </summary>
|
/// <param name="zbGateway">网关对象</param>
|
/// <returns></returns>
|
public int IsMainGateway(ZbGateway zbGateway)
|
{
|
return this.IsMainGateway(zbGateway.GwId);
|
}
|
|
/// <summary>
|
/// 判断是否主网关(1:主网关 0:不在线 2:子网关)
|
/// </summary>
|
/// <param name="waiID">网关id</param>
|
/// <returns></returns>
|
public int IsMainGateway(string waiID)
|
{
|
var realWay = ZbGateway.GateWayList.Find((obj) =>
|
{
|
return obj.GwId == waiID;
|
});
|
//虚拟网关也返回 0
|
if (realWay == null || realWay.IsVirtual == true)
|
{
|
return 0;
|
}
|
return realWay.IsMainGateWay == true ? 1 : 2;
|
}
|
|
#endregion
|
|
#region ■ 设置网关图片_______________________
|
|
/// <summary>
|
/// 设置真实网关的图片(已废弃)
|
/// </summary>
|
/// <param name="button"></param>
|
/// <param name="zbGateway"></param>
|
public void SetRealGatewayPictrue(Button button, ZbGateway zbGateway)
|
{
|
var localWay = this.GetLocalGateway(zbGateway.GwId);
|
if (localWay == null)
|
{
|
if (zbGateway.LinuxImageType != -1)
|
{
|
button.UnSelectedImagePath = "Gateway/RealGateway" + zbGateway.LinuxImageType + ".png";
|
}
|
else
|
{
|
//给一个线程去获取它的镜像类型
|
HdlThreadLogic.Current.RunThread(() =>
|
{
|
var result = this.RefreshGatewayInfo(zbGateway, true, ShowErrorMode.NO);
|
if (result != null)
|
{
|
//将网关的数据设置到本地缓存中
|
this.SetGatewayDataToLocalMemmory(zbGateway, result, false);
|
HdlThreadLogic.Current.RunMain(() =>
|
{
|
button.UnSelectedImagePath = "Gateway/RealGateway" + result.LinuxImageType + ".png";
|
});
|
}
|
});
|
}
|
}
|
else
|
{
|
button.UnSelectedImagePath = "Gateway/RealGateway" + localWay.LinuxImageType + ".png";
|
}
|
}
|
|
/// <summary>
|
/// 设置网关图标
|
/// </summary>
|
/// <param name="button"></param>
|
/// <param name="zbGateway"></param>
|
public void SetGatewayIcon(Button button, ZbGateway zbGateway)
|
{
|
var localWay = this.GetLocalGateway(zbGateway.GwId);
|
if (localWay == null)
|
{
|
if (zbGateway.LinuxImageType != -1)
|
{
|
this.SetgatewayIcon(button, "Gateway/GatewayIcon" + zbGateway.LinuxImageType + ".png");
|
}
|
else
|
{
|
//给一个线程去获取它的镜像类型
|
HdlThreadLogic.Current.RunThread(() =>
|
{
|
var result = this.RefreshGatewayInfo(zbGateway, true, ShowErrorMode.NO);
|
if (result != null)
|
{
|
//将网关的数据设置到本地缓存中
|
this.SetGatewayDataToLocalMemmory(zbGateway, result, false);
|
HdlThreadLogic.Current.RunMain(() =>
|
{
|
this.SetgatewayIcon(button, "Gateway/GatewayIcon" + result.LinuxImageType + ".png");
|
});
|
}
|
});
|
}
|
}
|
else
|
{
|
this.SetgatewayIcon(button, "Gateway/GatewayIcon" + localWay.LinuxImageType + ".png");
|
}
|
}
|
|
/// <summary>
|
/// 设置网关图标
|
/// </summary>
|
/// <param name="button"></param>
|
/// <param name="i_IconName"></param>
|
public void SetgatewayIcon(Button button, string i_IconName)
|
{
|
//这个图片本地是否存在?
|
if (string.IsNullOrEmpty(IO.FileUtils.GetImageFilePath(i_IconName)) == true)
|
{
|
//则使用共通图片
|
i_IconName = "Gateway/GatewayIcon.png";
|
}
|
button.UnSelectedImagePath = i_IconName;
|
}
|
|
#endregion
|
|
#region ■ 网关存在检测_______________________
|
|
/// <summary>
|
/// 网关是否已经存在
|
/// </summary>
|
/// <param name="zbGateway"></param>
|
/// <returns></returns>
|
public bool IsGatewayExist(ZbGateway zbGateway)
|
{
|
return this.IsGatewayExist(zbGateway.GwId);
|
}
|
|
/// <summary>
|
/// 网关是否已经存在
|
/// </summary>
|
/// <param name="gatewayId">网关ID</param>
|
/// <returns></returns>
|
public bool IsGatewayExist(string gatewayId)
|
{
|
if (gatewayId == null)
|
{
|
return false;
|
}
|
return dicGateway.ContainsKey(gatewayId);
|
}
|
|
#endregion
|
|
#region ■ 网关定位___________________________
|
|
/// <summary>
|
/// 发送指令到网关进行定位(网关LED闪烁识别)
|
/// </summary>
|
/// <param name="zbGateway"></param>
|
public void SetFixedPositionCommand(ZbGateway zbGateway)
|
{
|
ZbGateway realWay = null;
|
if (this.GetRealGateway(ref realWay, zbGateway) == false)
|
{
|
return;
|
}
|
var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 0 }, { "Command", 85 } };
|
if (this.IsGatewayExist(zbGateway) == true)
|
{
|
realWay.Send("GwLinuxLocate_Respon", jObject.ToString());
|
}
|
else
|
{
|
//如果这个网关还没有绑定的话,则强制使用本地连接
|
realWay.SendLocation("GwLinuxLocate_Respon", System.Text.Encoding.UTF8.GetBytes(jObject.ToString()));
|
}
|
}
|
|
#endregion
|
|
#region ■ 设置网关经纬度_____________________
|
|
/// <summary>
|
/// 设置网关经纬度
|
/// </summary>
|
/// <param name="gatewayId">网关Id</param>
|
/// <param name="Longitude">经度</param>
|
/// <param name="Latitude">维度</param>
|
/// <param name="mode">显示错误</param>
|
/// <returns></returns>
|
public bool SetGatewaySite(string gatewayId, double Longitude, double Latitude, ShowErrorMode mode)
|
{
|
if (((decimal)Longitude) == 0 && ((decimal)Latitude) == 0)
|
{
|
//没有配置过经纬度
|
return true;
|
}
|
|
int result = -1;
|
HdlGatewayReceiveLogic.Current.AddGatewayReceiveEvent(gatewayId, (topic, message) =>
|
{
|
if (topic == gatewayId + "/" + "Logic/SetSite_Respon")
|
{
|
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
|
result = Convert.ToInt32(jobject["Data"]["Result"].ToString());
|
}
|
});
|
//两位小数
|
Longitude = Math.Round(Longitude, 2);
|
Latitude = Math.Round(Latitude, 2);
|
|
int intLongitude = Convert.ToInt32(Longitude.ToString().Replace(".", string.Empty));
|
int intLatitude = Convert.ToInt32(Latitude.ToString().Replace(".", string.Empty));
|
|
var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 0 }, { "Command", 2013 } };
|
var data = new Newtonsoft.Json.Linq.JObject { { "Longitude", intLongitude }, { "Latitude", intLatitude } };
|
jObject.Add("Data", data);
|
|
//如果这个网关还没有绑定的话,则强制使用本地连接
|
this.SendJobjectData(gatewayId, "Logic/SetSite", jObject.ToString(), this.IsGatewayExist(gatewayId) == false);
|
|
int TimeOut = 0;
|
while (result == -1 && TimeOut < 30)
|
{
|
System.Threading.Thread.Sleep(100);
|
TimeOut++;
|
}
|
|
//移除监听事件
|
HdlGatewayReceiveLogic.Current.RemoveGatewayReceiveEvent();
|
if (result != 0)
|
{
|
if (mode == ShowErrorMode.YES)
|
{
|
//设置网关经纬度失败
|
string msg = Language.StringByID(R.MyInternationalizationString.uSetGatewaySiteFail);
|
if (result == -1)
|
{
|
msg = HdlCommonLogic.Current.CombineGatewayTimeOutMsg(msg, null, "回复超时");
|
}
|
this.ShowTipMsg(msg);
|
}
|
return false;
|
}
|
|
return true;
|
}
|
|
#endregion
|
|
#region ■ 断网备份及绑定网关ID_______________
|
|
/// <summary>
|
/// 在没网的情况下备份网关ID
|
/// </summary>
|
/// <param name="zbGateway"></param>
|
public void BackupGatewayIdOnNotNetwork(ZbGateway zbGateway)
|
{
|
var strId = zbGateway.GwId;
|
if (listBackupGwId.Contains(strId) == false)
|
{
|
listBackupGwId.Add(strId);
|
|
//备份
|
HdlFileLogic.Current.SaveFileContent(HdlFileNameResourse.BackupGatewayIdFile, listBackupGwId);
|
}
|
}
|
|
/// <summary>
|
/// 重新发送命令去绑定断网情况下备份的网关
|
/// </summary>
|
public bool ResetComandToBindBackupGateway()
|
{
|
var fileData = HdlFileLogic.Current.ReadFileByteContent(HdlFileNameResourse.BackupGatewayIdFile);
|
if (fileData == null)
|
{
|
return true;
|
}
|
this.listBackupGwId = JsonConvert.DeserializeObject<List<string>>(System.Text.Encoding.UTF8.GetString(fileData));
|
var listTempId = new List<string>();
|
listTempId.AddRange(this.listBackupGwId);
|
|
foreach (var gwId in listTempId)
|
{
|
if (this.IsGatewayExist(gwId) == true)
|
{
|
//调用接口,绑定网关(即使失败,也返回true往下走)
|
var result = this.SetGatewayIdToDataBase(gwId);
|
if (result != 1)
|
{
|
break;
|
}
|
}
|
this.listBackupGwId.Remove(gwId);
|
}
|
|
if (this.listBackupGwId.Count == 0)
|
{
|
//如果没有了内容,则删除文件
|
string file = HdlFileNameResourse.BackupGatewayIdFile;
|
if (System.IO.File.Exists(file) == true)
|
{
|
System.IO.File.Delete(file);
|
}
|
return true;
|
}
|
else
|
{
|
//备份
|
HdlFileLogic.Current.SaveFileContent(HdlFileNameResourse.BackupGatewayIdFile, listBackupGwId);
|
return false;
|
}
|
}
|
|
#endregion
|
|
#region ■ 发送网关命令给网关_________________
|
|
/// <summary>
|
/// 发送数据到网关,并接受网关返回的数据(ReceiptData为返回值)
|
/// </summary>
|
/// <param name="gateway">网关对象</param>
|
/// <param name="sendTopic">发送的主题</param>
|
/// <param name="sendData">需要发送的数据 JObject.ToString()的东西</param>
|
/// <param name="receiptTopic">指定接收哪个主题</param>
|
/// <param name="waitTime">超时时间(秒)</param>
|
/// <param name="useLocalConnect">是否强制使用本地连接发送</param>
|
/// <returns>网关返回的数据</returns>
|
public ReceiptGatewayResult SendJobjectDataToGateway(string gatewayId, string sendTopic, string sendData, string receiptTopic, int waitTime = 5, bool useLocalConnect = false)
|
{
|
var reResult = new ReceiptGatewayResult();
|
|
//错误主题
|
string errorTopic = gatewayId + "/" + "Error_Respon";
|
//检测对象的主题
|
string checkTopic = gatewayId + "/" + receiptTopic;
|
|
HdlGatewayReceiveLogic.Current.AddGatewayReceiveEvent(gatewayId, (topic, message) =>
|
{
|
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
|
|
//网关回复错误
|
if (topic == errorTopic)
|
{
|
var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
|
reResult.ErrorMsg = HdlCheckLogic.Current.CheckGatewayErrorCode(temp.Error);
|
}
|
//如果是指定的主题
|
if (topic == checkTopic)
|
{
|
reResult.ReceiptData = jobject["Data"].ToString();
|
}
|
});
|
|
//发送数据
|
this.SendJobjectData(gatewayId, sendTopic, sendData, useLocalConnect);
|
|
//超时时间
|
int TimeOut = 0;
|
waitTime = 20 * waitTime;
|
while (reResult.ReceiptData == null && TimeOut < waitTime)
|
{
|
//全部接收才退出
|
System.Threading.Thread.Sleep(50);
|
TimeOut++;
|
}
|
//移除网关监听事件
|
HdlGatewayReceiveLogic.Current.RemoveGatewayReceiveEvent();
|
|
if (reResult.ReceiptData == null)
|
{
|
reResult.ErrorMsgDiv = 0;
|
}
|
|
return reResult;
|
}
|
|
/// <summary>
|
/// 单纯执行发送json数据到网关
|
/// </summary>
|
/// <param name="i_gatewayId">网关id</param>
|
/// <param name="topic">主题</param>
|
/// <param name="sendData">发送的json数据</param>
|
/// <param name="useLocalConnect">是否强制使用本地连接发送</param>
|
public void SendJobjectData(string i_gatewayId, string topic, string sendData, bool useLocalConnect = false)
|
{
|
ZbGateway realWay = null;
|
for (int i = 0; i < ZbGateway.GateWayList.Count; i++)
|
{
|
//寻找真实物理网关对象
|
if (ZbGateway.GateWayList[i].GwId == i_gatewayId)
|
{
|
realWay = ZbGateway.GateWayList[i];
|
break;
|
}
|
}
|
if (realWay == null)
|
{
|
//如果网关对象丢失了,则创建个新的
|
realWay = new ZbGateway { IsVirtual = true, };
|
realWay.GwId = i_gatewayId;
|
realWay.HomeId = Config.Instance.HomeId;
|
ZbGateway.GateWayList.Add(realWay);
|
}
|
if (useLocalConnect == false)
|
{
|
realWay.Send(topic, System.Text.Encoding.UTF8.GetBytes(sendData));
|
}
|
else
|
{
|
//强制使用本地连接
|
realWay.SendLocation(topic, System.Text.Encoding.UTF8.GetBytes(sendData));
|
}
|
}
|
|
#endregion
|
|
#region ■ 网关监视___________________________
|
|
/// <summary>
|
/// 当前的网络连接模式
|
/// </summary>
|
private GatewayConnectMode nowGwConnectMode = GatewayConnectMode.None;
|
/// <summary>
|
/// 是否存在网关正在升级
|
/// </summary>
|
private bool hadGatewayUpdate = false;
|
|
/// <summary>
|
/// 当网关的连接方式改变时,记录当前的连接方式
|
/// </summary>
|
/// <param name="connectMode">网关变更后的连接方式</param>
|
public void CheckGatewayByConnectChanged(GatewayConnectMode connectMode)
|
{
|
this.nowGwConnectMode = connectMode;
|
}
|
|
/// <summary>
|
/// 开启检测网关在线状态的线程(此方法是给设备列表界面用的)
|
/// </summary>
|
/// <param name="frameLayout">界面对象</param>
|
public void StartCheckGatewayOnlineThread(EditorCommonForm frameLayout)
|
{
|
HdlThreadLogic.Current.RunThread(() =>
|
{
|
int waitCount = 0;
|
//如果住宅ID变更了,则不再处理
|
while (frameLayout.Parent != null && Config.Instance.HomeId != string.Empty)
|
{
|
System.Threading.Thread.Sleep(1000);
|
if (this.hadGatewayUpdate == true)
|
{
|
//网关正在升级,不需要操作
|
continue;
|
}
|
|
waitCount++;
|
if (this.nowGwConnectMode == GatewayConnectMode.Remote)
|
{
|
//远程每20秒检测一次
|
if (waitCount < 20) { continue; }
|
}
|
else if (this.nowGwConnectMode == GatewayConnectMode.WIFI)
|
{
|
//局域网每8秒检测一次
|
if (waitCount < 8) { continue; }
|
}
|
waitCount = 0;
|
|
//获取前回网关的在线状态
|
Dictionary<string, bool> dicOldOnline = this.GetOldGatewayOnlineStatu();
|
if (dicOldOnline == null)
|
{
|
//则不处理
|
continue;
|
}
|
//可以叫4G
|
if (this.nowGwConnectMode == GatewayConnectMode.Remote)
|
{
|
//在远程的条件下,检查网关的在线状态
|
this.CheckGatewayStatuByRemote(dicOldOnline);
|
}
|
//WIFI
|
else if (this.nowGwConnectMode == GatewayConnectMode.WIFI)
|
{
|
//在WIFI的条件下,检查网关的在线状态
|
this.CheckGatewayStatuByWIFI(dicOldOnline);
|
}
|
}
|
}, ShowErrorMode.NO);
|
}
|
|
/// <summary>
|
/// 在WIFI的条件下,检查网关的在线状态
|
/// </summary>
|
private void CheckGatewayStatuByWIFI(Dictionary<string, bool> dicOldOnline)
|
{
|
//从网关获取全部的网关
|
List<ZbGateway> list = this.GetAllLocalGateway();
|
|
//2020.05.25追加:此住宅是否拥有网关在线
|
var hadGwOnline = false;
|
foreach (var way in list)
|
{
|
if (dicOldOnline.ContainsKey(way.GwId) == true
|
&& this.CheckGatewayOnlineByFlage(way) == true)
|
{
|
//有一个网关在线,即在线
|
hadGwOnline = true;
|
break;
|
}
|
}
|
|
foreach (var way in list)
|
{
|
string gwId = way.GwId;
|
if (dicOldOnline.ContainsKey(gwId) == true)
|
{
|
//网关也不多,直接推送吧
|
bool online = this.CheckGatewayOnlineByFlage(way);
|
this.PushGatewayOnlineStatuToForm(gwId, online, hadGwOnline);
|
}
|
else
|
{
|
//没有包含,默认为false
|
this.PushGatewayOnlineStatuToForm(gwId, false, hadGwOnline);
|
}
|
}
|
}
|
|
/// <summary>
|
/// 在远程的条件下,检查网关的在线状态
|
/// </summary>
|
private void CheckGatewayStatuByRemote(Dictionary<string, bool> dicOldOnline)
|
{
|
//获取云端上面的网关
|
Dictionary<string, GatewayResult> dicDbGateway = this.GetGateWayListFromDataBase(Config.Instance.Home.Id);
|
if (dicDbGateway == null)
|
{
|
//如果网络不通,则也往下走
|
dicDbGateway = new Dictionary<string, GatewayResult>();
|
}
|
|
//2020.05.25追加:此住宅是否拥有网关在线
|
var hadGwOnline = false;
|
foreach (var gwId in dicOldOnline.Keys)
|
{
|
//如果云端上面有这个网关
|
if (dicDbGateway.ContainsKey(gwId) == true
|
&& dicDbGateway[gwId].MqttOnlineStatus == true)
|
{
|
//有一个网关在线,即在线
|
hadGwOnline = true;
|
break;
|
}
|
}
|
|
foreach (var gwId in dicOldOnline.Keys)
|
{
|
//如果云端上面有这个网关
|
if (dicDbGateway.ContainsKey(gwId) == true)
|
{
|
//网关也不多,直接推送
|
this.PushGatewayOnlineStatuToForm(gwId, dicDbGateway[gwId].MqttOnlineStatus, hadGwOnline);
|
}
|
else
|
{
|
//云端不包含的,当不在线处理
|
this.PushGatewayOnlineStatuToForm(gwId, false, hadGwOnline);
|
}
|
}
|
}
|
|
/// <summary>
|
/// 获取前回网关的在线状态
|
/// </summary>
|
/// <returns></returns>
|
private Dictionary<string, bool> GetOldGatewayOnlineStatu()
|
{
|
if (this.dicGateway.Count == 0)
|
{
|
//没有网关,则不处理
|
return null;
|
}
|
|
try
|
{
|
var dicOldOnline = new Dictionary<string, bool>();
|
//如果在循环的过程中,动了里面的东西,报错则不理它,下一回合
|
foreach (var zbway in this.dicGateway.Values)
|
{
|
//获取前回的在线状态
|
dicOldOnline[zbway.GwId] = this.CheckGatewayOnlineByFlage(zbway);
|
}
|
return dicOldOnline;
|
}
|
catch { return null; }
|
}
|
|
/// <summary>
|
/// 将变化的网关推送到界面上
|
/// </summary>
|
/// <param name="gwId"></param>
|
/// <param name="online"></param>
|
/// <param name="hadGwOnline">2020.05.25追加:此住宅是否拥有网关在线</param>
|
private void PushGatewayOnlineStatuToForm(string gwId, bool online, bool hadGwOnline)
|
{
|
try
|
{
|
var listForm = HdlFormLogic.Current.GetAllOpenForm();
|
for (int i = 0; i < listForm.Count; i++)
|
{
|
//网关在线推送
|
var zbway = this.GetLocalGateway(gwId);
|
if (zbway != null)
|
{
|
//切换住宅时,这个东西有可能是null
|
if (online == true)
|
{
|
zbway.OnlineTime = DateTime.Now;
|
}
|
listForm[i]?.GatewayOnlinePush(zbway, online, hadGwOnline);
|
}
|
}
|
}
|
catch { }
|
}
|
|
/// <summary>
|
/// 设置存在网关正在升级的标识
|
/// </summary>
|
/// <param name="update">是否有网关在升级</param>
|
public void SetHadGatewayUpdateFlage(bool update)
|
{
|
this.hadGatewayUpdate = update;
|
}
|
|
#endregion
|
|
#region ■ 调用云端接口的方法_________________
|
|
/// <summary>
|
/// 更新网关ID到云端数据库(1:正常 -1:异常 0:当前的网关绑定在了当前账号下的不同住宅里面)
|
/// </summary>
|
/// <param name="i_gatewayIds">网关ID</param>
|
/// <returns></returns>
|
private int SetGatewayIdToDataBase(string i_gatewayId)
|
{
|
//调用接口,绑定网关(即使失败,也返回true往下走)
|
var pra = new { homeId = Config.Instance.Home.Id, mac = i_gatewayId, gatewayType = "ZIGBEEGATEWAY" };
|
var result = HdlHttpLogic.Current.RequestResponseFromZigbeeHttps("home-wisdom/gateway/bindGateway", RestSharp.Method.POST, pra, null, null, CheckMode.A账号权限);
|
if (result == null || result.Code != HttpMessageEnum.A成功)
|
{
|
return -1;
|
}
|
return 1;
|
}
|
|
/// <summary>
|
/// 从云端获取全部网关列表ID
|
/// </summary>
|
/// <returns></returns>
|
public Dictionary<string, GatewayResult> GetGateWayListFromDataBase(string i_homeId)
|
{
|
//这个接口特殊,不需要检测权限
|
var pra = new { homeId = i_homeId };
|
var result = HdlHttpLogic.Current.RequestResponseFromZigbeeHttps("home-wisdom/gateway/getGatewayList", RestSharp.Method.POST, pra);
|
if (result == null || result.Code != HttpMessageEnum.A成功)
|
{
|
return null;
|
}
|
var listData = JsonConvert.DeserializeObject<List<GatewayResult>>(result.Data.ToString());
|
|
var dicDbGateway = new Dictionary<string, GatewayResult>();
|
foreach (var data in listData)
|
{
|
if (data.GatewayType == "ZIGBEEGATEWAY")
|
{
|
dicDbGateway[data.Mac] = data;
|
}
|
}
|
return dicDbGateway;
|
}
|
|
/// <summary>
|
/// 解绑云端绑定的网关
|
/// </summary>
|
/// <param name="strWayId"></param>
|
public bool DeleteDataBaseGateway(string strWayId)
|
{
|
var pra = new { homeId = Config.Instance.Home.Id, mac = strWayId };
|
var result = HdlHttpLogic.Current.RequestResponseFromZigbeeHttps("home-wisdom/gateway/untieGateway", RestSharp.Method.POST, pra, null, null, CheckMode.A账号权限);
|
if (result == null || result.Code != HttpMessageEnum.A成功)
|
{
|
return false;
|
}
|
return true;
|
}
|
|
#endregion
|
|
#region ■ 一般方法___________________________
|
|
/// <summary>
|
/// 检测本地全部网关,是否都支持发送启动模板导入的Json命令(返回的是不支持启动命令的网关ID)
|
/// </summary>
|
/// <returns></returns>
|
public List<string> CheckAllGatewayCanSendSetupComand()
|
{
|
var list = new List<string>();
|
foreach (var gateway in this.dicGateway.Values)
|
{
|
if (gateway.LinuxFirmwareVersion < 10205)
|
{
|
//网关小于这个版本,都需要升级
|
list.Add(gateway.GwId);
|
}
|
}
|
return list;
|
}
|
|
/// <summary>
|
/// 是否是mini网关
|
/// </summary>
|
/// <param name="i_zbGateway">网关对象</param>
|
/// <returns></returns>
|
public bool IsMiniGateway(ZbGateway i_zbGateway)
|
{
|
if (i_zbGateway == null) { return false; }
|
|
if (i_zbGateway.LinuxImageType == 11 || i_zbGateway.LinuxImageType == 13)
|
{
|
//这个网关是mini网关
|
return true;
|
}
|
return false;
|
}
|
|
/// <summary>
|
/// 判断网关是否拥有虚拟驱动
|
/// </summary>
|
/// <param name="i_zbGateway">网关对象</param>
|
/// <returns></returns>
|
public bool CheckGatewayHadDriveCode(ZbGateway i_zbGateway)
|
{
|
if (i_zbGateway == null) { return false; }
|
|
if (i_zbGateway.LinuxImageType != 6 && i_zbGateway.LinuxImageType != 12)
|
{
|
//这个网关没有虚拟驱动
|
return false;
|
}
|
return false;
|
}
|
|
/// <summary>
|
/// 显示错误信息窗口
|
/// </summary>
|
/// <param name="msg"></param>
|
private void ShowErrorMsg(string msg)
|
{
|
Application.RunOnMainThread(() =>
|
{
|
var contr = new ShowMsgControl(ShowMsgType.Error, msg);
|
contr.Show();
|
});
|
}
|
|
/// <summary>
|
/// 显示Tip信息窗口
|
/// </summary>
|
/// <param name="msg"></param>
|
private void ShowTipMsg(string msg)
|
{
|
Application.RunOnMainThread(() =>
|
{
|
var contr = new ShowMsgControl(ShowMsgType.Tip, msg);
|
contr.Show();
|
});
|
}
|
|
#endregion
|
}
|
}
|