using Newtonsoft.Json;
using Shared.Common;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using ZigBee.Device;
namespace Shared.Phone.UserCenter
{
///
/// 网关业务的逻辑类
///
public class HdlGatewayLogic
{
#region ■ 变量声明___________________________
///
/// 网关业务的逻辑类
///
private static HdlGatewayLogic m_Current = null;
///
/// 网关业务的逻辑类
///
public static HdlGatewayLogic Current
{
get
{
if (m_Current == null)
{
m_Current = new HdlGatewayLogic();
}
return m_Current;
}
}
///
/// 备份用的网关ID
///
private List listBackupGwId = new List();
///
/// 网关文件的前缀名字
///
private string gwFirstName = "Gateway_";
///
/// 全部网关(这里保存的是虚拟网关,而不是真实物理网关对象)
///
private Dictionary dicGateway = new Dictionary();
#endregion
#region ■ 刷新网关___________________________
///
/// 刷新本地网关信息
///
public void ReFreshByLocal()
{
lock (dicGateway)
{
this.dicGateway.Clear();
List listFile = this.GetAllGatewayFile();
//反序列化添加到缓存
foreach (string file in listFile)
{
//从文件中反序列化出网关对象
var gateway = this.GetGatewayFromFile(file);
if (gateway == null)
{
continue;
}
//添加缓存
dicGateway[gateway.GwId] = gateway;
}
}
}
///
/// 刷新APP前一次选择的网关ID
///
public void RefreshAppOldSelectGatewayId()
{
GatewayResourse.AppOldSelectGatewayId = string.Empty;
//从文件中获取上一次选择的网关id
byte[] data = Global.ReadFileByDirectory(DirNameResourse.LocalMemoryDirectory, DirNameResourse.AppOldSelectGatewayFile);
if (data != null)
{
string strvalue = System.Text.Encoding.UTF8.GetString(data);
GatewayResourse.AppOldSelectGatewayId = JsonConvert.DeserializeObject(strvalue);
}
//如果本地没有这个网关的话
if (this.IsGatewayExist(GatewayResourse.AppOldSelectGatewayId) == false)
{
GatewayResourse.AppOldSelectGatewayId = string.Empty;
lock (dicGateway)
{
//随便选一个网关
foreach (string wayId in this.dicGateway.Keys)
{
GatewayResourse.AppOldSelectGatewayId = wayId;
break;
}
}
}
}
///
/// 同步云端的网关id,如果本地拥有云端不存在的id,则表示应该被换绑了,直接删除(切换住宅后,重新刷新网关列表和设备之后使用)
///
///
public void SynchronizeDbGateway()
{
//从云端获取网列表ID
Dictionary result = HdlGatewayLogic.Current.GetGateWayListFromDataBase();
if (result == null)
{
return;
}
List listBackupGwId = new List();
var fileData = Global.ReadFileByDirectory(DirNameResourse.LocalMemoryDirectory, DirNameResourse.BackupGatewayIdFile);
if (fileData != null)
{
//新增:虽然概率低,但是确实发生了。如果有网络时,App重新绑定记录的网关失败的话
//不应该删除它
listBackupGwId = JsonConvert.DeserializeObject>(System.Text.Encoding.UTF8.GetString(fileData));
}
List listDelete = new List();
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 list = Common.LocalDevice.Current.GetDeviceByGatewayID(gatewayId);
foreach (var device in list)
{
//删除一般设备
Common.LocalDevice.Current.DeleteMemmoryDevice(device, true);
//删除Ota设备
Common.LocalDevice.Current.DeleteMemmoryOtaDevice(device.DeviceAddr);
}
//删除网关文件
this.DeleteGatewayFile(gatewayId);
}
//LOG输出
if (listDelete.Count > 0)
{
string msg = "本地拥有的网关:";
foreach (var gatewayId in this.dicGateway.Keys)
{
msg += gatewayId + ",";
}
msg += "\r\n被删除的网关:";
foreach (var gatewayId in listDelete)
{
msg += gatewayId + ",";
}
msg += "\r\n此时云端返回当前账号所绑定有的网关:";
foreach (var gatewayId in result.Keys)
{
msg += gatewayId + ",";
}
var bytes = System.Text.Encoding.UTF8.GetBytes(msg);
Common.Global.WriteFileByBytesByHomeId("GatewayDeleteLog.txt", bytes);
}
}
///
/// 从文件中反序列化出网关对象
///
///
///
private ZbGateway GetGatewayFromFile(string file)
{
try
{
byte[] filebyte = Global.ReadFileByHomeId(file);
string strvalue = System.Text.Encoding.UTF8.GetString(filebyte);
var gateway = JsonConvert.DeserializeObject(strvalue);
if (gateway.GwId == string.Empty)
{
//这是旧数据,需要特殊处理
var jobject = Newtonsoft.Json.Linq.JObject.Parse(strvalue);
string gwInfo = jobject["getGwInfo"].ToString();
var result = JsonConvert.DeserializeObject(gwInfo);
//将网关的数据设置到本地缓存中
this.SetGatewayDataToLocalMemmory(gateway, result);
}
return gateway;
}
catch (Exception ex)
{
HdlLogLogic.Current.WriteLog(ex);
return null;
}
}
#endregion
#region ■ 添加网关___________________________
///
/// 添加新网关(仅限追加新的网关)
///
/// 网关
/// 是否显示错误
public async Task AddNewGateway(ZbGateway zbGateway, ShowErrorMode mode)
{
//设置网关的经纬度
bool falge = this.SetGatewaySite(zbGateway, Common.Config.Instance.Home.Longitude, Common.Config.Instance.Home.Latitude, ShowErrorMode.NO);
if (falge == false)
{
return falge;
}
//执行添加网关到内存
var result = await this.DoAddGatewayToMemory(zbGateway, mode);
//前的网关绑定在了当前账号下的不同住宅里面
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);
}
return false;
}
if (result == -1)
{
return false;
}
//添加网关的话,强制主页刷新
UserView.UserPage.Instance.RefreshForm = true;
return true;
}
///
/// 创建一个虚拟的网关对象
///
/// 网关ID
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;
}
///
/// 执行添加网关到内存(1:正常 -1:异常 0:当前的网关绑定在了当前账号下的不同住宅里面)
///
/// 网关对象
/// 是否显示错误
///
private async Task DoAddGatewayToMemory(ZbGateway zbGateway, ShowErrorMode mode)
{
if (zbGateway == null)
{
if (mode == ShowErrorMode.YES)
{
//错误:网关对象丢失
string msg = Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg);
this.ShowTipMsg(msg);
}
return -1;
}
//获取网关的信息
var result = await zbGateway.GetZbGwInfoAsync();
//检测网关返回的共通错误状态码
string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
if (error != null)
{
if (mode == ShowErrorMode.YES)
{
this.ShowTipMsg(error);
}
return -1;
}
if (result == null)
{
if (mode == ShowErrorMode.YES)
{
//获取网关信息失败
string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayInfoFail);
this.ShowTipMsg(msg);
}
return -1;
}
if (result.getGwData == null)
{
if (mode == ShowErrorMode.YES)
{
//获取网关信息失败
string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayInfoFail);
this.ShowTipMsg(msg);
}
return -1;
}
//设置住宅ID到网关
bool flage2 = await 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);
}
return -1;
}
//更新云端数据库
int flage1 = this.SetGatewayIdToDataBase(zbGateway);
//异常也不鸟它,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].GatewayOnlineFlage = zbGateway.GatewayOnlineFlage;
//将网关的数据设置到本地缓存中
this.SetGatewayDataToLocalMemmory(this.dicGateway[gwID], result.getGwData);
//顺便这个变量也设置一下
this.SetGatewayDataToLocalMemmory(zbGateway, result.getGwData, false);
if (isEsist == false)
{
//添加备份
HdlAutoBackupLogic.AddOrEditorFile(this.dicGateway[gwID].FilePath);
}
return 1;
}
///
/// 设置住宅ID到网关(失败时,不弹出任何错误信息,网关断网除外)
///
///
///
///
public async Task SetHomeIdToGateway(ZbGateway zbGateway, string HomeId, ShowErrorMode mode)
{
ZbGateway realWay = null;
if (this.GetRealGateway(ref realWay, zbGateway) == false)
{
if (mode == ShowErrorMode.YES)
{
//错误:网关对象丢失
string msg = Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg);
this.ShowTipMsg(msg);
}
return false;
}
var info = await realWay.GwSetHomeIdAsync(HomeId);
if (info != null && info.gwSetHomeIdData != null)
{
return true;
}
return false;
}
///
/// 更新网关ID到云端数据库(1:正常 -1:异常 0:当前的网关绑定在了当前账号下的不同住宅里面)
///
/// 网关对象
///
private int SetGatewayIdToDataBase(ZbGateway zbGateway)
{
//调用接口,绑定网关(即使失败,也返回true往下走)
var bindGateway = new BindGatewayPra();
bindGateway.BindGateways.Add(zbGateway.GwId);
//获取控制主人账号的Token
bindGateway.LoginAccessToken = UserCenterLogic.GetConnectMainToken();
var result = UserCenterLogic.GetResultCodeByRequestHttps("App/BindGatewayToHome", true, bindGateway);
if (result == "Error")
{
return -1;
}
if (result == "BindGatewaysExists")
{
return 0;
}
return result == "Success" ? 1 : -1;
}
///
/// 住宅ID是否为空
///
///
///
public bool HomeIdIsEmpty(ZbGateway zbGateway)
{
return this.HomeIdIsEmpty(zbGateway.HomeId);
}
///
/// 住宅ID是否为空
///
///
///
public bool HomeIdIsEmpty(string HomeId)
{
if (string.IsNullOrEmpty(HomeId) == true || HomeId[0] == '\0')
{
return true;
}
return false;
}
#endregion
#region ■ 重新绑定网关_______________________
///
/// 重新绑定网关(1:正常 -1:异常 0:当前的网关绑定在了当前账号下的不同住宅里面)
///
/// 网关
/// 消息控件
public async Task 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, Common.Config.Instance.Home.Longitude, Common.Config.Instance.Home.Latitude, ShowErrorMode.YES);
if (falge == false)
{
return -1;
}
//设置住宅ID到网关
bool flage2 = await 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);
//异常也不鸟它,0是特殊含义
if (flage1 == 0)
{
return flage1;
}
if (flage1 == -1)
{
//备份失败的网关ID
HdlGatewayLogic.Current.BackupGatewayIdOnNotNetwork(zbGateway);
}
if (btnMsg == null)
{
//网关内部数据变更中,请稍后
ProgressBar.SetValue(Language.StringByID(R.MyInternationalizationString.uGatewayDataIsChangingPleaseWhait));
}
else
{
HdlThreadLogic.Current.RunMain(() =>
{
//网关内部数据变更中,请稍后
btnMsg.TextID = R.MyInternationalizationString.uGatewayDataIsChangingPleaseWhait;
});
}
await Task.Delay(8000);
//获取网关的信息
ZbGatewayData.GetGwAllData result = null;
int count = 5;
while (count >= 0)
{
result = await zbGateway.GetZbGwInfoAsync();
if (result != null && result.getGwData != null)
{
break;
}
count--;
//最多再等20秒
await Task.Delay(4000);
}
//检测网关返回的共通错误状态码
string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
if (error != null)
{
this.ShowTipMsg(error);
return -1;
}
if (result == null || result.getGwData == 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].GatewayOnlineFlage = zbGateway.GatewayOnlineFlage;
//将网关的数据设置到本地缓存中
this.SetGatewayDataToLocalMemmory(this.dicGateway[gwID], result.getGwData);
//顺便这个变量也设置一下
this.SetGatewayDataToLocalMemmory(zbGateway, result.getGwData, false);
if (isEsist == false)
{
//添加备份
HdlAutoBackupLogic.AddOrEditorFile(this.dicGateway[gwID].FilePath);
}
//添加网关的话,强制主页刷新
UserView.UserPage.Instance.RefreshForm = true;
return 1;
}
#endregion
#region ■ 修改网关___________________________
///
/// 修改本地网关名字(失败时会显示信息)
///
/// 网关对象
/// 网关名
public async Task ReName(ZbGateway zbGateway, string gatewayName)
{
ZbGateway realWay = null;
if (this.GetRealGateway(ref realWay, zbGateway) == false)
{
//获取网关对象失败
string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayTagartFail);
this.ShowErrorMsg(msg);
return false;
}
var result = await realWay.GwReNameAsync(gatewayName);
//检测网关返回的共通错误状态码
string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
if (error != null)
{
this.ShowErrorMsg(error);
return false;
}
if (result == null)
{
//网关名称修改失败
string msg = Language.StringByID(R.MyInternationalizationString.uGatewayReNameFail);
this.ShowErrorMsg(msg);
return false;
}
//网关修改失败
if (result.gwReNameData == null)
{
//网关名称修改失败
string msg = Language.StringByID(R.MyInternationalizationString.uGatewayReNameFail);
this.ShowErrorMsg(msg);
return false;
}
//修改缓存
string gwID = zbGateway.GwId;
this.dicGateway[gwID].GwName = gatewayName;
this.dicGateway[gwID].ReSave();
//添加自动备份
HdlAutoBackupLogic.AddOrEditorFile(zbGateway.FilePath);
return true;
}
#endregion
#region ■ 网关切换___________________________
///
/// 执行切换网关操作
///
///
public async Task DoSwitchGateway(string gatewayId)
{
var zbGateway = this.GetLocalGateway(gatewayId);
if (this.CheckGatewayOnlineByFlag(zbGateway) == true)
{
//重新获取在线网关的信息
var result = await this.GetOnlineGatewayInfo(gatewayId);
if (result == false)
{
return false;
}
}
//切换网关,保存缓存
this.SaveGatewayIdToLocation(gatewayId);
//切换网关的话,主页需要重新刷新
UserView.UserPage.Instance.RefreshForm = true;
return true;
}
///
/// 获取在线网关信息
///
///
///
private async Task 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 = await 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.GetGatewayInfo(realWay);
if (info == null)
{
//关闭进度条
ProgressBar.Close();
return false;
}
}
//获取全部设备
int result = LocalDevice.Current.SetDeviceToMemmoryByGateway(realWay);
//关闭进度条
ProgressBar.Close();
if (result == -1)
{
return false;
}
return true;
}
///
/// 保存选择的网关ID到本地
///
///
public void SaveGatewayIdToLocation(string gatewayId)
{
GatewayResourse.AppOldSelectGatewayId = gatewayId;
byte[] data = System.Text.Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(GatewayResourse.AppOldSelectGatewayId));
Global.WriteFileToDirectoryByBytes(DirNameResourse.LocalMemoryDirectory, DirNameResourse.AppOldSelectGatewayFile, data);
}
#endregion
#region ■ 删除网关___________________________
///
/// 删除网关,包括云端和本地(失败时不会显示信息,并且会返回true)
///
///
public async Task DeleteGateway(ZbGateway zbGateway)
{
//移除本地网关信息
return await this.DeleteGateway(zbGateway.GwId);
}
///
/// 删除网关,包括云端和本地(失败时不会显示信息,并且会返回true)
///
///
public async Task DeleteGateway(string zbGatewayID)
{
ZbGateway realWay = null;
bool hadReal = this.GetRealGateway(ref realWay, zbGatewayID);
//暂不支持分享
if (hadReal == true && realWay.GatewayOnlineFlage == true)
{
//清空网关的住宅ID
bool result = await this.SetHomeIdToGateway(realWay, string.Empty, ShowErrorMode.YES);
if (result == false)
{
//网关解绑失败 不理它,因为网关可以按按键强制搜索得到
string msg = Language.StringByID(R.MyInternationalizationString.uGatewayUnBindFail);
//this.ShowErrorMsg(msg);
//return false;
}
}
//删除云端的网关
this.DeleteDataBaseGateway(zbGatewayID);
//删除网关文件
this.DeleteGatewayFile(zbGatewayID);
//移除
ZbGateway.GateWayList.RemoveAll((obj) => obj.GwId == zbGatewayID);
//断开mqtt连接
realWay.DisConnectLocalMqttClient("GD");
return true;
}
///
/// 删除网关文件
///
/// 网关id
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);
//删除自动备份
HdlAutoBackupLogic.DeleteFile(file);
//删除设备文件
List list = Common.LocalDevice.Current.GetDeviceByGatewayID(zbGatewayID);
foreach (var device in list)
{
//删除设备文件
Common.LocalDevice.Current.DeleteMemmoryDevice(device, true);
//删除Ota设备
Common.LocalDevice.Current.DeleteMemmoryOtaDevice(device.DeviceAddr);
}
//如果是主网关
if (this.IsMainGateway(zbGatewayID) == 1)
{
var listAllRoom = UserCenter.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 ■ 网关掉线___________________________
///
/// 刷新网关的在线状态(注意,刷新的是缓存,请调用CheckGatewayOnlineByFlag来判断是否在线)
///
///
///
public void RefreshGatewayOnlineStatu(List listGateway)
{
var listRealWay = new List();
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]);
}
//标识指定网关为不在线
listRealWay[i].GatewayOnlineFlage = false;
}
//这是第一道坎,强制检查WIFI:等待2秒(因为wifi的时候,它会自动去刷新flage)
System.Threading.Thread.Sleep(2000);
//检查是否拥有网关存在于WIFi下
if (this.CheckHadGatewayInWifi(listRealWay) == false)
{
//第二道坎:在远程的情况下刷新网关的在线状态
this.RefreshGatewayOnlineOnRemode(listRealWay);
}
//刷新缓存的在线标识
foreach (var zbway in listRealWay)
{
string gwID = zbway.GwId;
if (this.dicGateway.ContainsKey(gwID) == false)
{
continue;
}
this.dicGateway[gwID].GatewayOnlineFlage = zbway.GatewayOnlineFlage;
}
}
///
/// 检查是否拥有网关存在于WIFi下
///
///
///
private bool CheckHadGatewayInWifi(List listGateway)
{
foreach (var zbway in listGateway)
{
//是否存在网关存在于WIFI下
if (zbway.GatewayOnlineFlage == true)
{
return true;
}
}
return false;
}
///
/// 在远程的情况下刷新网关的在线状态
///
///
///
private void RefreshGatewayOnlineOnRemode(List listGateway)
{
//获取云端上面的网关
Dictionary dicDbGateway = HdlGatewayLogic.Current.GetGateWayListFromDataBase();
if (dicDbGateway == null)
{
return;
}
foreach (var way in listGateway)
{
if (way == null)
{
continue;
}
string strId = way.GwId;
if (dicDbGateway.ContainsKey(strId) == true) //如果云端上面有这个网关
{
way.GatewayOnlineFlage = dicDbGateway[strId].MqttOnlineStatus;
}
}
}
///
/// 根据某种标识判断指定网关是否在线
///
///
///
public bool CheckGatewayOnlineByFlag(ZbGateway zbGateway)
{
if (zbGateway == null)
{
return false;
}
//使用缓存的,因为刷新在线状态的时候,刷新的就是缓存,而不是真实物理网关
string gwID = zbGateway.GwId;
if (this.dicGateway.ContainsKey(gwID) == true)
{
return this.dicGateway[gwID].GatewayOnlineFlage;
}
return zbGateway.GatewayOnlineFlage;
}
#endregion
#region ■ 获取网关___________________________
///
/// 从网关获取全部的网关(以本地网关为标准)
///
///
public List GetAllGatewayFromGateway()
{
//不要去Foreach 它的列表
List list = new List();
list.AddRange(ZbGateway.GateWayList);
List newlist = new List();
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;
}
///
/// 获取本地全部的网关
///
/// The all gateway.
public List GetAllLocalGateway()
{
List listData = new List();
lock (dicGateway)
{
foreach (var way in dicGateway.Values)
{
listData.Add(way);
}
}
return listData;
}
///
/// 获取本地的网关
///
/// 网关ID
///
public ZbGateway GetLocalGateway(string gatewayId)
{
if (this.dicGateway.ContainsKey(gatewayId) == true)
{
return this.dicGateway[gatewayId];
}
return null;
}
///
/// 获取本地所有的网关文件
///
///
public List GetAllGatewayFile()
{
List list = new List();
List listFile = Global.FileListByHomeId();
foreach (string file in listFile)
{
//只获取网关设备
if (file.StartsWith(gwFirstName) == false)
{
continue;
}
list.Add(file);
}
return list;
}
///
/// 获取系统内部的真实网关对象变量
///
/// 真实网关
/// 目标网关
///
public bool GetRealGateway(ref ZbGateway zbGateway, ZbGateway tagartWay)
{
if (tagartWay == null)
{
return false;
}
return this.GetRealGateway(ref zbGateway, tagartWay.GwId);
}
///
/// 获取系统内部的真实网关对象变量
///
///
///
///
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 ■ 获取协调器当前信道_________________
///
/// 获取协调器当前信道(会有等待延迟,返回-1代表错误)
///
///
///
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 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 = UserCenterLogic.CombineGatewayTimeOutMsg(msg, null, "回复超时");
this.ShowTipMsg(msg);
}
return data;
}
#endregion
#region ■ 获取协调器MAC______________________
///
/// 获取协调器MAC地址(会有等待延迟,返回null代表错误)
///
///
///
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 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 = UserCenterLogic.CombineGatewayTimeOutMsg(msg, null, "回复超时");
this.ShowTipMsg(msg);
}
return data;
}
#endregion
#region ■ 获取协调器PanID____________________
///
/// 获取协调器PanID(会有等待延迟,返回-1代表错误)
///
///
///
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 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 = UserCenterLogic.CombineGatewayTimeOutMsg(msg, null, "回复超时");
this.ShowTipMsg(msg);
}
return panId;
}
#endregion
#region ■ 网关自动备份设置___________________
///
/// 获取网关自动备份设置(-1:异常 0:关闭 1:打开)
///
///
///
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 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 = UserCenterLogic.CombineGatewayTimeOutMsg(msg, null, "回复超时");
this.ShowTipMsg(msg);
}
return statu;
}
///
/// 设置网关自动备份设置
///
///
///
///
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 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 = UserCenterLogic.CombineGatewayTimeOutMsg(msg, null, "回复超时");
this.ShowTipMsg(msg);
return false;
}
return true;
}
#endregion
#region ■ 获取名称___________________________
///
/// 获取网关加特效的名称
///
///
///
///
public string GetGatewayName(ZbGateway zbGateway, GetNameMode mode = GetNameMode.SpecialGateway)
{
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;
}
if (mode == GetNameMode.SpecialGateway)
{
string keyName = Common.LocalDevice.deviceModelIdName + localWay.LinuxImageType;
if (LocalDevice.Current.dicDeviceAllNameID.ContainsKey(keyName) == true)
{
//没有名称时,则使用R文件里面设置的默认设备名称
return Language.StringByID(LocalDevice.Current.dicDeviceAllNameID[keyName] + 20000);
}
}
return string.Empty;
}
///
/// 单纯获取网关名称
///
/// 网关对象
///
private string GetGatewaySimpleName(ZbGateway zbGateway)
{
if (zbGateway == null)
{
return string.Empty;
}
return zbGateway.GwName;
}
///
/// 设置网关镜像类型的翻译名字
///
///
///
///
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)
{
string keyName = Common.LocalDevice.deviceModelIdName + zbGateway.LinuxImageType;
if (Common.LocalDevice.Current.dicDeviceAllNameID.ContainsKey(keyName) == true)
{
//使用R文件里面设置的东西
button.TextID = LocalDevice.Current.dicDeviceAllNameID[keyName];
}
}
else
{
//给一个线程去获取它的镜像类型
HdlThreadLogic.Current.RunThread(() =>
{
var result = this.GetGatewayInfo(zbGateway, ShowErrorMode.NO);
if (result != null)
{
//将网关的数据设置到本地缓存中
this.SetGatewayDataToLocalMemmory(zbGateway, result, false);
HdlThreadLogic.Current.RunMain(() =>
{
string keyName = Common.LocalDevice.deviceModelIdName + zbGateway.LinuxImageType;
if (Common.LocalDevice.Current.dicDeviceAllNameID.ContainsKey(keyName) == true)
{
//使用R文件里面设置的东西
button.TextID = LocalDevice.Current.dicDeviceAllNameID[keyName];
}
});
}
});
}
}
else
{
string keyName = Common.LocalDevice.deviceModelIdName + this.dicGateway[gwId].LinuxImageType;
if (Common.LocalDevice.Current.dicDeviceAllNameID.ContainsKey(keyName) == true)
{
//使用R文件里面设置的东西
button.TextID = Common.LocalDevice.Current.dicDeviceAllNameID[keyName];
}
}
}
#endregion
#region ■ 获取网关信息_______________________
///
/// 获取网关信息(版本信息,镜像类型,基本信息等。只刷新本地网关的缓存)
///
///
///
///
public ZbGatewayData.GetGwData GetGatewayInfo(ZbGateway zbGateway, ShowErrorMode mode = ShowErrorMode.YES)
{
//获取网关版本信息
var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 0 }, { "Command", 95 } };
var result = this.SendJobjectDataToGateway(zbGateway, "GetZbGwInfo", jObject.ToString(), "GetZbGwInfo_Respon");
if (result.ErrorMsgDiv != 1)
{
if (mode == ShowErrorMode.YES)
{
//获取网关信息失败
string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayInfoFail);
//拼接上【网关回复超时】的Msg
msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, null, "回复超时");
this.ShowErrorMsg(msg);
}
return null;
}
var getGwInfo = Newtonsoft.Json.JsonConvert.DeserializeObject(result.ReceiptData);
string gwID = zbGateway.GwId;
if (this.dicGateway.ContainsKey(gwID) == true)
{
//刷新缓存
ZbGateway localWay = this.dicGateway[gwID];
//将网关的数据设置到本地缓存中
this.SetGatewayDataToLocalMemmory(localWay, getGwInfo);
}
//顺便这个变量也设置一下
this.SetGatewayDataToLocalMemmory(zbGateway, getGwInfo, false);
return getGwInfo;
}
///
/// 将网关的数据设置到本地缓存中
///
/// 本地网关
/// 网关数据
/// 是否保存文件
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.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;
if (saveFile == true)
{
localWay.ReSave();
}
}
#endregion
#region ■ 网关房间相关_______________________
///
/// 获取网关所在的房间
///
/// 网关对象
///
public Room GetRoomByGateway(ZbGateway zbGateway)
{
return this.GetRoomByGateway(zbGateway.GwId);
}
///
/// 获取网关所在的房间
///
/// 网关ID
///
public Room GetRoomByGateway(string gatewayId)
{
var localGateway = this.GetLocalGateway(gatewayId);
if (localGateway == null)
{
return null;
}
return HdlRoomLogic.Current.GetRoomById(localGateway.RoomId);
}
///
/// 变更网关房间
///
/// 网关对象
/// 房间ID
public void ChangedGatewayRoom(ZbGateway zbGateway, string roomId)
{
var localGateway = this.GetLocalGateway(zbGateway.GwId);
if (localGateway != null)
{
localGateway.RoomId = roomId;
localGateway.ReSave();
//添加备份
HdlAutoBackupLogic.AddOrEditorFile(localGateway.FilePath);
}
}
#endregion
#region ■ 清空真实网关列表___________________
///
/// 清空全部的真实物理网关对象
///
public void ClearAllRealGateway()
{
//因为那一瞬间,有可能mqtt会加回来,所以先加缓存
var list = new List();
list.AddRange(ZbGateway.GateWayList);
//然后清空掉
ZbGateway.GateWayList.Clear();
//最后再断开mqtt连接
for (int i = 0; i < list.Count; i++)
{
list[i].DisConnectLocalMqttClient("G");
}
list.Clear();
}
#endregion
#region ■ 检测并获取网关各种固件新版本_______
///
/// 检测并获取网关各固件的新版本,没有新版本,则对应位置存的是null,直接返回null代表失败(0:Linux新版本 1:协调器新版本 2~X:都是虚拟驱动的)
///
/// 网关对象
/// 错误时,是否显示错误
///
public List GetGatewayAllNewVersion(ZbGateway zbGateway, ShowErrorMode mode = ShowErrorMode.YES)
{
//获取网关版本信息
var result = this.GetGatewayInfo(zbGateway, mode);
if (result == null)
{
return null;
}
//使用本地缓存对象
var localWay = this.GetLocalGateway(zbGateway.GwId);
if (localWay == null)
{
return null;
}
//添加网关的升级固件(成不成功都无所谓)
var flage = HdlFirmwareUpdateLogic.AddFirmwareVersionInfo(FirmwareLevelType.Linux,
localWay.LinuxHardVersion.ToString(),
localWay.LinuxImageType.ToString());
//添加协调器的升级固件(成不成功都无所谓) 必须能够联网才行
if (flage == 1)
{
//没网的时候不再处理
HdlFirmwareUpdateLogic.AddFirmwareVersionInfo(FirmwareLevelType.Coordinator,
localWay.CoordinatorHardVersion.ToString(),
localWay.CoordinatorImageId.ToString());
}
//网关的版本
var gatewayFirmware = HdlFirmwareUpdateLogic.GetFirmwareMostVersionInfo(FirmwareLevelType.Linux,
localWay.LinuxHardVersion.ToString(),
localWay.LinuxImageType.ToString(),
localWay.LinuxFirmwareVersion);
//协调器版本
var coordinatorFirmware = HdlFirmwareUpdateLogic.GetFirmwareMostVersionInfo(FirmwareLevelType.Coordinator,
localWay.CoordinatorHardVersion.ToString(),
localWay.CoordinatorImageId.ToString(),
localWay.CoordinatorFirmwareVersion);
var list = new List();
list.Add(gatewayFirmware);
list.Add(coordinatorFirmware);
//这个网关需要有虚拟驱动这个东西才行
if (localWay.LinuxImageType != 6)
{
//虚拟驱动号
foreach (var data in localWay.DriveCodeList)
{
//添加虚拟驱动的升级固件(成不成功都无所谓) 必须能够联网才行
if (flage == 1)
{
HdlFirmwareUpdateLogic.AddFirmwareVersionInfo(FirmwareLevelType.VirtualDevice,
data.DriveHwVersion.ToString(),
data.DriveImageType.ToString());
}
//虚拟驱动
var virtualFirmware = HdlFirmwareUpdateLogic.GetFirmwareMostVersionInfo(FirmwareLevelType.VirtualDevice,
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;
}
///
/// 获取网关的虚拟驱动号(返回null时代表获取失败)
///
///
///
public List GetListVDDriveCode(ZbGateway zbGateway)
{
var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 0 }, { "Command", 505 } };
var result = this.SendJobjectDataToGateway(zbGateway, "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(result.ReceiptData);
return dataInfo.DriveCodeList;
}
#endregion
#region ■ 主网关判定_________________________
///
/// 判断是否主网关(1:主网关 0:不在线 2:子网关)
///
/// 网关对象
///
public int IsMainGateway(ZbGateway zbGateway)
{
return this.IsMainGateway(zbGateway.GwId);
}
///
/// 判断是否主网关(1:主网关 0:不在线 2:子网关)
///
/// 网关id
///
public int IsMainGateway(string waiID)
{
ZbGateway zbGateway = null;
if (this.GetRealGateway(ref zbGateway, waiID) == false)
{
return 0;
}
return zbGateway.IsMainGateWay == true ? 1 : 2;
}
#endregion
#region ■ 设置网关图片_______________________
///
/// 设置真实网关的图片
///
///
///
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.GetGatewayInfo(zbGateway, 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";
}
}
///
/// 设置网关图标
///
///
///
public void SetGatewayIcon(Button button, ZbGateway zbGateway)
{
var localWay = this.GetLocalGateway(zbGateway.GwId);
if (localWay == null)
{
if (zbGateway.LinuxImageType != -1)
{
button.UnSelectedImagePath = "Gateway/GatewayIcon" + zbGateway.LinuxImageType + ".png";
}
else
{
//给一个线程去获取它的镜像类型
HdlThreadLogic.Current.RunThread(() =>
{
var result = this.GetGatewayInfo(zbGateway, ShowErrorMode.NO);
if (result != null)
{
//将网关的数据设置到本地缓存中
this.SetGatewayDataToLocalMemmory(zbGateway, result, false);
HdlThreadLogic.Current.RunMain(() =>
{
button.UnSelectedImagePath = "Gateway/GatewayIcon" + result.LinuxImageType + ".png";
});
}
});
}
}
else
{
button.UnSelectedImagePath = "Gateway/GatewayIcon" + localWay.LinuxImageType + ".png";
}
}
#endregion
#region ■ 网关存在检测_______________________
///
/// 网关是否已经存在
///
///
///
public bool IsGatewayExist(ZbGateway zbGateway)
{
return this.IsGatewayExist(zbGateway.GwId);
}
///
/// 网关是否已经存在
///
/// 网关ID
///
public bool IsGatewayExist(string gatewayId)
{
if (gatewayId == null)
{
return false;
}
return dicGateway.ContainsKey(gatewayId);
}
#endregion
#region ■ 网关定位___________________________
///
/// 发送指令到网关进行定位(网关LED闪烁识别)
///
///
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 ■ 从云端获取全部网关列表ID___________
///
/// 从云端获取全部网关列表ID
///
/// 从云端获取全部网关列表ID
public Dictionary GetGateWayListFromDataBase()
{
Dictionary dicDbGateway = null;
if (UserCenterResourse.UserInfo.AuthorityNo == 3)
{
//成员
return dicDbGateway;
}
bool canBreak = false;
HdlThreadLogic.Current.RunThread(() =>
{
List list = new List() { "NotCheck" };
//设置访问接口的参数
var pra = new GetGatewayPra();
pra.ReqDto.PageSetting.Page = 1;
pra.ReqDto.PageSetting.PageSize = 999;
//获取控制主人账号的Token
pra.ReqDto.LoginAccessToken = UserCenterLogic.GetConnectMainToken();
var result = UserCenterLogic.GetResponseDataByRequestHttps("App/GetSingleHomeGatewayPagger", true, pra, list);
if (string.IsNullOrEmpty(result) == true)
{
canBreak = true;
return;
}
var infoResult = Newtonsoft.Json.JsonConvert.DeserializeObject(result);
Dictionary dic = new Dictionary();
foreach (var data in infoResult.PageData)
{
dic[data.GatewayUniqueId] = data;
}
dicDbGateway = dic;
canBreak = true;
});
int count = 0;
while (canBreak == false)
{
System.Threading.Thread.Sleep(200);
count++;
if (count == 25)
{
//如果5秒还不能获取得到数据,则中断此次操作
break;
}
}
return dicDbGateway;
}
#endregion
#region ■ 设置网关经纬度_____________________
///
/// 设置网关经纬度
///
/// 网关对象
/// 经度
/// 维度
/// 显示错误
///
public bool SetGatewaySite(ZbGateway gateway, double Longitude, double Latitude, ShowErrorMode mode)
{
ZbGateway realWay = null;
if (this.GetRealGateway(ref realWay, gateway) == false)
{
if (mode == ShowErrorMode.YES)
{
//错误:网关对象丢失
string msg = Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg);
this.ShowTipMsg(msg);
}
return false;
}
int result = -1;
Action action = (topic, message) =>
{
var gatewayID = topic.Split('/')[0];
if (topic == gatewayID + "/" + "Logic/SetSite_Respon")
{
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
result = Convert.ToInt32(jobject["Data"]["Result"].ToString());
}
};
realWay.Actions += action;
//两位小数
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);
if (this.IsGatewayExist(gateway) == true)
{
realWay.Send("Logic/SetSite", jObject.ToString());
}
else
{
//如果这个网关还没有绑定的话,则强制使用本地连接
realWay.SendLocation("Logic/SetSite", System.Text.Encoding.UTF8.GetBytes(jObject.ToString()));
}
int TimeOut = 0;
while (result == -1 && TimeOut < 30)
{
System.Threading.Thread.Sleep(100);
TimeOut++;
}
realWay.Actions -= action;
if (result != 0)
{
if (mode == ShowErrorMode.YES)
{
//设置网关经纬度失败
string msg = Language.StringByID(R.MyInternationalizationString.uSetGatewaySiteFail);
if (result == -1)
{
msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, null, "回复超时");
}
this.ShowTipMsg(msg);
}
return false;
}
return true;
}
#endregion
#region ■ 解绑云端网关_______________________
///
/// 解绑云端绑定的网关
///
///
public bool DeleteDataBaseGateway(string strWayId)
{
var Pra = new DeleteGatewayPra();
Pra.BindGateways.Add(strWayId);
//获取控制主人账号的Token
Pra.LoginAccessToken = UserCenterLogic.GetConnectMainToken();
List listNotShowError = new List() { "NoExist", "NoBind", "NoRecord" };
bool result = UserCenterLogic.GetResultStatuByRequestHttps("App/ReleaseGatewayToHome", true, Pra, listNotShowError);
if (result == false)
{
return false;
}
return true;
}
#endregion
#region ■ 断网备份及绑定网关ID_______________
///
/// 在没网的情况下备份网关ID
///
///
public void BackupGatewayIdOnNotNetwork(ZbGateway zbGateway)
{
var strId = zbGateway.GwId;
if (listBackupGwId.Contains(strId) == false)
{
listBackupGwId.Add(strId);
//备份
var strData = Newtonsoft.Json.JsonConvert.SerializeObject(listBackupGwId);
var byteData = System.Text.Encoding.UTF8.GetBytes(strData);
Global.WriteFileToDirectoryByBytes(DirNameResourse.LocalMemoryDirectory, DirNameResourse.BackupGatewayIdFile, byteData);
}
}
///
/// 重新发送命令去绑定断网情况下备份的网关
///
public void ResetComandToBindBackupGateway()
{
HdlThreadLogic.Current.RunThread(() =>
{
var fileData = Global.ReadFileByDirectory(DirNameResourse.LocalMemoryDirectory, DirNameResourse.BackupGatewayIdFile);
if (fileData == null)
{
return;
}
this.listBackupGwId = Newtonsoft.Json.JsonConvert.DeserializeObject>(System.Text.Encoding.UTF8.GetString(fileData));
var listTempId = new List();
listTempId.AddRange(this.listBackupGwId);
//调用接口,绑定网关
var bindGateway = new BindGatewayPra();
//获取控制主人账号的Token
bindGateway.LoginAccessToken = UserCenterLogic.GetConnectMainToken();
foreach (var gwId in listTempId)
{
bindGateway.BindGateways.Clear();
bindGateway.BindGateways.Add(gwId);
var result = UserCenterLogic.GetResultCodeByRequestHttps("App/BindGatewayToHome", true, bindGateway);
if (result == "Success")
{
this.listBackupGwId.Remove(gwId);
}
if (result == "Error")
{
break;
}
}
if (this.listBackupGwId.Count == 0)
{
//如果没有了内容,则删除文件
string file = UserCenterLogic.CombinePath(DirNameResourse.LocalMemoryDirectory, DirNameResourse.BackupGatewayIdFile);
if (System.IO.File.Exists(file) == true)
{
System.IO.File.Delete(file);
}
}
else
{
//备份
var strData = Newtonsoft.Json.JsonConvert.SerializeObject(listBackupGwId);
var byteData = System.Text.Encoding.UTF8.GetBytes(strData);
Global.WriteFileToDirectoryByBytes(DirNameResourse.LocalMemoryDirectory, DirNameResourse.BackupGatewayIdFile, byteData);
}
});
}
#endregion
#region ■ 发送网关命令给网关_________________
///
/// 发送数据到网关,并接受网关返回的数据(ReceiptData为返回值)
///
/// 网关对象
/// 发送的主题
/// 需要发送的数据 JObject.ToString()的东西
/// 指定接收哪个主题
/// 超时时间(秒)
/// 网关返回的数据
public ReceiptGatewayResult SendJobjectDataToGateway(ZbGateway gateway, string sendTopic, string sendData, string receiptTopic, int waitTime = 5)
{
var reResult = new ReceiptGatewayResult();
ZbGateway myGateway = null;
if (this.GetRealGateway(ref myGateway, gateway) == false)
{
//获取网关对象失败
reResult.ErrorMsg = Language.StringByID(R.MyInternationalizationString.uGetGatewayTagartFail);
reResult.ErrorMsgDiv = -1;
return reResult;
}
//网关ID
string gatewayID = gateway.GwId;
//错误主题
string errorTopic = gatewayID + "/" + "Error_Respon";
//检测对象的主题
string checkTopic = gatewayID + "/" + receiptTopic;
Action receiptAction = (topic, message) =>
{
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
//网关回复错误
if (topic == errorTopic)
{
var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString());
reResult.ErrorMsg = HdlCheckLogic.Current.CheckCommonErrorCode(temp.Error);
}
//如果是指定的主题
if (topic == checkTopic)
{
reResult.ReceiptData = jobject["Data"].ToString();
}
};
myGateway.Actions += receiptAction;
//发送数据
myGateway.Send(sendTopic, sendData);
//超时时间
int TimeOut = 0;
waitTime = 20 * waitTime;
while (reResult.ReceiptData == null && TimeOut < waitTime)
{
//全部接收才退出
System.Threading.Thread.Sleep(50);
TimeOut++;
}
myGateway.Actions -= receiptAction;
receiptAction = null;
if (reResult.ReceiptData == null)
{
reResult.ErrorMsgDiv = 0;
}
return reResult;
}
#endregion
#region ■ 网关监视___________________________
///
/// 当前的网络连接模式
///
private GatewayConnectMode nowGwConnectMode = GatewayConnectMode.None;
///
/// 是否存在网关正在升级
///
private bool hadGatewayUpdate = false;
///
/// 当网关的连接方式改变时,记录当前的连接方式
///
/// 网关变更后的连接方式
public void CheckGatewayByConnectChanged(GatewayConnectMode connectMode)
{
this.nowGwConnectMode = connectMode;
}
///
/// 开启检测网关在线状态的线程(此方法是给设备列表界面用的)
///
/// 界面对象
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)
{
//局域网每5秒检测一次
if (waitCount < 5) { continue; }
}
waitCount = 0;
//获取前回网关的在线状态
Dictionary 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);
}
///
/// 在WIFI的条件下,检查网关的在线状态
///
private void CheckGatewayStatuByWIFI(Dictionary dicOldOnline)
{
//从网关获取全部的网关
List list = this.GetAllGatewayFromGateway();
foreach (var way in list)
{
//将标识置为false
way.GatewayOnlineFlage = false;
}
//等个2秒
System.Threading.Thread.Sleep(2000);
//2020.05.25追加:此住宅是否拥有网关在线
var hadGwOnline = false;
foreach (var way in list)
{
if (dicOldOnline.ContainsKey(way.GwId) == true)
{
if (way.GatewayOnlineFlage == true)
{
//有一个网关在线,即在线
hadGwOnline = true;
break;
}
}
}
foreach (var way in list)
{
string gwId = way.GwId;
if (dicOldOnline.ContainsKey(gwId) == true)
{
//网关也不多,直接推送吧
this.PushGatewayOnlineStatuToForm(gwId, way.GatewayOnlineFlage, hadGwOnline);
}
else
{
//没有包含,默认为false
this.PushGatewayOnlineStatuToForm(gwId, false, hadGwOnline);
}
}
}
///
/// 在远程的条件下,检查网关的在线状态
///
private void CheckGatewayStatuByRemote(Dictionary dicOldOnline)
{
//获取云端上面的网关
Dictionary dicDbGateway = HdlGatewayLogic.Current.GetGateWayListFromDataBase();
if (dicDbGateway == null)
{
//如果网络不通,则也往下走
dicDbGateway = new Dictionary();
}
//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);
}
}
}
///
/// 获取前回网关的在线状态
///
///
private Dictionary GetOldGatewayOnlineStatu()
{
if (this.dicGateway.Count == 0)
{
//没有网关,则不处理
return null;
}
try
{
var dicOldOnline = new Dictionary();
//如果在循环的过程中,动了里面的东西,报错则不理它,下一回合
foreach (var zbway in this.dicGateway.Values)
{
//获取前回的在线状态
dicOldOnline[zbway.GwId] = zbway.GatewayOnlineFlage;
}
return dicOldOnline;
}
catch { return null; }
}
///
/// 将变化的网关推送到界面上
///
///
///
/// 2020.05.25追加:此住宅是否拥有网关在线
private void PushGatewayOnlineStatuToForm(string gwId, bool online, bool hadGwOnline)
{
try
{
for (int i = 0; i < UserCenterResourse.listActionFormId.Count; i++)
{
string formId = UserCenterResourse.listActionFormId[i];
if (UserCenterResourse.DicActionForm.ContainsKey(formId) == false)
{
continue;
}
//网关在线推送
var zbway = this.GetLocalGateway(gwId);
if (zbway != null)
{
//切换住宅时,这个东西有可能是null
zbway.GatewayOnlineFlage = online;
UserCenterResourse.DicActionForm[formId]?.GatewayOnlinePush(zbway, online, hadGwOnline);
}
}
}
catch { }
}
///
/// 设置存在网关正在升级的标识
///
/// 是否有网关在升级
public void SetHadGatewayUpdateFlage(bool update)
{
this.hadGatewayUpdate = update;
}
#endregion
#region ■ 一般方法___________________________
///
/// 显示错误信息窗口
///
///
private void ShowErrorMsg(string msg)
{
Application.RunOnMainThread(() =>
{
var contr = new ShowMsgControl(ShowMsgType.Error, msg);
contr.Show();
});
}
///
/// 显示Tip信息窗口
///
///
private void ShowTipMsg(string msg)
{
Application.RunOnMainThread(() =>
{
var contr = new ShowMsgControl(ShowMsgType.Tip, msg);
contr.Show();
});
}
#endregion
}
}