|
@@ -27,14 +27,9 @@ namespace EVCB_OCPP.TaskScheduler.Jobs
|
|
|
|
|
|
public CheckEVSEOnlineJob()
|
|
|
{
|
|
|
- CreateEVSEOnlineRecordTable();
|
|
|
+
|
|
|
}
|
|
|
- //測試方式
|
|
|
-
|
|
|
- // A: 假裝更新心跳包
|
|
|
- // B: 一直開著程式 / 一段時間關程式(關掉時間點 online/offline)
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
public async Task Execute(IJobExecutionContext context)
|
|
|
{
|
|
|
logger.Debug(this.ToString() + " :Starting........");
|
|
@@ -49,180 +44,37 @@ namespace EVCB_OCPP.TaskScheduler.Jobs
|
|
|
latestHeartbeatTime = evse.HeartbeatUpdatedOn;
|
|
|
if (IsOnlineNow(evse))
|
|
|
{
|
|
|
- if (evse.Online)
|
|
|
- {
|
|
|
|
|
|
- if (latestHeartbeatTime.Minute % 10 == 0)
|
|
|
- {
|
|
|
- //on-on
|
|
|
- //現在是整點,找上一筆填入end time and insert start time
|
|
|
-
|
|
|
- // var _pickDate = currentTime.AddHours(-1);
|
|
|
- var _pickDate = latestHeartbeatTime;
|
|
|
- bool isCrossDay = false;
|
|
|
- int _startHour = _pickDate.AddHours(-6).Hour; //往回巡視六個小時前紀錄
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- //跨日處理
|
|
|
- if (_startHour > _pickDate.Hour)
|
|
|
- {
|
|
|
- isCrossDay = true;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var _picks = await GetOnlineRecords(_pickDate, evse.CustomerId.ToString(), evse.ChargeBoxId, isCrossDay ? 0 : _startHour, _pickDate.Hour);
|
|
|
-
|
|
|
- if (isCrossDay)
|
|
|
- {
|
|
|
- var _picksCrossData = await GetOnlineRecords(_pickDate.AddHours(-6), evse.CustomerId.ToString(), evse.ChargeBoxId, _startHour, 23);
|
|
|
- _picks.AddRange(_picksCrossData);
|
|
|
- }
|
|
|
-
|
|
|
- _picks = _picks.OrderBy(x => x.OnlineTime).ToList();
|
|
|
-
|
|
|
- bool _isIgnore = true;
|
|
|
-
|
|
|
- for (int i = 0; i < _picks.Count; i++)
|
|
|
- {
|
|
|
- if (_picks[i].HourIndex != evse.HeartbeatUpdatedOn.Hour && _picks[i].OfflineTime == DefaultSetting.DefaultNullTime)
|
|
|
- {
|
|
|
- _picks[i].OfflineTime = new DateTime(_picks[i].OnlineTime.AddHours(1).Year,
|
|
|
- _picks[i].OnlineTime.AddHours(1).Month, _picks[i].OnlineTime.AddHours(1).Day, _picks[i].OnlineTime.AddHours(1).Hour, 0, 0);
|
|
|
-
|
|
|
- _picks[i].TotalMinute = (int)_picks[i].OfflineTime.Subtract(_picks[i].OnlineTime).TotalMinutes;
|
|
|
- updateData.Add(_picks[i]);
|
|
|
-
|
|
|
- var checkTime = _picks[i].OfflineTime;
|
|
|
- while ((int)latestHeartbeatTime.Subtract(checkTime).TotalHours > 0)
|
|
|
- {
|
|
|
- var _existedCount = _picks.Where(x => x.HourIndex == checkTime.Hour).ToList().Count;
|
|
|
-
|
|
|
- if (_existedCount == 0)
|
|
|
- {
|
|
|
- insertData.Add(new EVSEOnlineRecord()
|
|
|
- {
|
|
|
- CustomerId = evse.CustomerId,
|
|
|
- StationId = "0",
|
|
|
- HourIndex = checkTime.Hour,
|
|
|
- ChargeBoxId = evse.ChargeBoxId,
|
|
|
- OnlineTime = new DateTime(checkTime.Year, checkTime.Month, checkTime.Day, checkTime.Hour, 0, 0),
|
|
|
- OfflineTime = new DateTime(checkTime.AddHours(1).Year, checkTime.AddHours(1).Month, checkTime.AddHours(1).Day, checkTime.AddHours(1).Hour, 0, 0),
|
|
|
- TotalMinute = 60
|
|
|
-
|
|
|
- });
|
|
|
- checkTime = checkTime.AddHours(1);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- _isIgnore = _picks.Where(x => x.HourIndex == latestHeartbeatTime.Hour).ToList().Count == 0 ? false : true;
|
|
|
-
|
|
|
- if (!_isIgnore)
|
|
|
- {
|
|
|
- insertData.Add(new EVSEOnlineRecord()
|
|
|
- {
|
|
|
- CustomerId = evse.CustomerId,
|
|
|
- StationId = "0",
|
|
|
- HourIndex = evse.HeartbeatUpdatedOn.Hour,
|
|
|
- ChargeBoxId = evse.ChargeBoxId,
|
|
|
- OnlineTime = new DateTime(latestHeartbeatTime.Year,
|
|
|
- latestHeartbeatTime.Month, latestHeartbeatTime.Day, latestHeartbeatTime.Hour, 0, 0),
|
|
|
- OfflineTime = DefaultSetting.DefaultNullTime
|
|
|
-
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
+ if (!evse.Online)
|
|
|
+ { //off - on
|
|
|
+ logger.Debug(evse.ChargeBoxId + " Off-On Started");
|
|
|
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //off - on
|
|
|
UpdateEVSECurrentStatus(evse.CustomerId.ToString(), evse.ChargeBoxId, true, DefaultSetting.DefaultNullTime);
|
|
|
|
|
|
- insertData.Add(new EVSEOnlineRecord()
|
|
|
- {
|
|
|
- CustomerId = evse.CustomerId,
|
|
|
- StationId = "0",
|
|
|
- HourIndex = evse.HeartbeatUpdatedOn.Hour,
|
|
|
- ChargeBoxId = evse.ChargeBoxId,
|
|
|
- OnlineTime = evse.HeartbeatUpdatedOn,
|
|
|
-
|
|
|
- });
|
|
|
-
|
|
|
+ await UpdateOnlineRecords(evse.ChargeBoxId, true, evse.HeartbeatUpdatedOn, null);
|
|
|
|
|
|
+ logger.Debug(evse.ChargeBoxId + " Off-On Finished");
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
|
|
|
if (evse.Online)
|
|
|
{
|
|
|
-
|
|
|
//on -off
|
|
|
- UpdateEVSECurrentStatus(evse.CustomerId.ToString(), evse.ChargeBoxId, false, evse.HeartbeatUpdatedOn);
|
|
|
-
|
|
|
- var _pickDate = evse.HeartbeatUpdatedOn.Date;
|
|
|
- var _picks = await GetOnlineRecords(_pickDate, evse.CustomerId.ToString(), evse.ChargeBoxId, _pickDate.Hour, evse.HeartbeatUpdatedOn.Hour);
|
|
|
- _picks = _picks.Where(x => x.OfflineTime == DefaultSetting.DefaultNullTime).ToList();
|
|
|
-
|
|
|
- foreach (var item in _picks)
|
|
|
+ logger.Debug(evse.ChargeBoxId + " On-Off Started");
|
|
|
+ var online_row = await GetOnlineRecord(evse.ChargeBoxId);
|
|
|
+ if(online_row!=null)
|
|
|
{
|
|
|
- if (evse.HeartbeatUpdatedOn.Hour - item.OnlineTime.Hour > 0)
|
|
|
- {
|
|
|
- item.OfflineTime = new DateTime(item.OnlineTime.AddHours(1).Year, item.OnlineTime.AddHours(1).Month, item.OnlineTime.AddHours(1).Day, item.OnlineTime.AddHours(1).Hour, 0, 0);
|
|
|
- item.TotalMinute = (int)item.OfflineTime.Subtract(item.OnlineTime).TotalMinutes;
|
|
|
- updateData.Add(item);
|
|
|
-
|
|
|
- var checkTime = item.OfflineTime;
|
|
|
- while (evse.HeartbeatUpdatedOn.Hour - checkTime.Hour >= 0)
|
|
|
- {
|
|
|
- insertData.Add(new EVSEOnlineRecord()
|
|
|
- {
|
|
|
- CustomerId = evse.CustomerId,
|
|
|
- StationId = "0",
|
|
|
- HourIndex = checkTime.Hour,
|
|
|
- ChargeBoxId = evse.ChargeBoxId,
|
|
|
- OnlineTime = checkTime,
|
|
|
- OfflineTime = evse.HeartbeatUpdatedOn.Hour == checkTime.Hour ? evse.HeartbeatUpdatedOn : new DateTime(checkTime.AddHours(1).Year, checkTime.AddHours(1).Month, checkTime.AddHours(1).Day, checkTime.AddHours(1).Hour, 0, 0)
|
|
|
-
|
|
|
- });
|
|
|
- checkTime = evse.HeartbeatUpdatedOn.Hour == checkTime.Hour ? insertData.LastOrDefault().OfflineTime.AddHours(1) : insertData.LastOrDefault().OfflineTime;
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- item.OfflineTime = evse.HeartbeatUpdatedOn;
|
|
|
- item.TotalMinute = (int)item.OfflineTime.Subtract(item.OnlineTime).TotalMinutes;
|
|
|
- updateData.Add(item);
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
+ await UpdateOnlineRecords(evse.ChargeBoxId, false, evse.HeartbeatUpdatedOn, online_row.Id);
|
|
|
+ }
|
|
|
|
|
|
+ logger.Debug(evse.ChargeBoxId + " On-Off Finished");
|
|
|
}
|
|
|
- else
|
|
|
- {
|
|
|
- //off-off do nothing
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
- if ((insertData.Count + updateData.Count) % 100 == 0)
|
|
|
- {
|
|
|
- await UpdateOnlineRecords(updateData, insertData);
|
|
|
- ClearCache();
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
- await UpdateOnlineRecords(updateData, insertData);
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
@@ -290,94 +142,74 @@ namespace EVCB_OCPP.TaskScheduler.Jobs
|
|
|
}
|
|
|
|
|
|
|
|
|
- async private Task UpdateOnlineRecords(List<EVSEOnlineRecord> updateItems, List<EVSEOnlineRecord> insertItems)
|
|
|
+ async private Task UpdateOnlineRecords(string chargeBoxId, bool online, DateTime hearbeatDt, Int64? rowId)
|
|
|
{
|
|
|
- List<EVSEOnlineRecord> records = new List<EVSEOnlineRecord>();
|
|
|
try
|
|
|
{
|
|
|
- for (int i = 0; i < updateItems.Count; i++)
|
|
|
+ if (online)
|
|
|
{
|
|
|
- string sqlString = string.Format("UPDATE [dbo].[EVSEOnlineRecord_{0}] SET OfflineTime=@OfflineTime , TotalMinute=@TotalMinute WHERE customerId=@customerId and chargeBoxId=@chargeBoxId and " +
|
|
|
- "OnlineTime=@OnlineTime", updateItems[i].OnlineTime.Date.ToString("yyMMdd"));
|
|
|
+ string sqlString = "INSERT INTO [dbo].[EVSEOnlineRecord] (\"ChargeBoxId\",\"OnlineTime\",\"OfflineTime\")" +
|
|
|
+ "VALUES( @ChargeBoxId,@OnlineTime,@OfflineTime); ";
|
|
|
using (var dbConn = new SqlConnection(onlineDBConnectString))
|
|
|
{
|
|
|
dbConn.Open();
|
|
|
- await dbConn.ExecuteAsync(sqlString, updateItems[i]);
|
|
|
- }
|
|
|
+ var parameters = new DynamicParameters();
|
|
|
+ parameters.Add("@ChargeBoxId", chargeBoxId, System.Data.DbType.String);
|
|
|
+ parameters.Add("@OnlineTime", hearbeatDt, System.Data.DbType.DateTime);
|
|
|
+ parameters.Add("@OfflineTime", DefaultSetting.DefaultNullTime, System.Data.DbType.DateTime);
|
|
|
|
|
|
+ await dbConn.ExecuteAsync(sqlString, parameters);
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- for (int i = 0; i < insertItems.Count; i++)
|
|
|
+ else
|
|
|
{
|
|
|
- string sqlString = string.Format("INSERT INTO [dbo].[EVSEOnlineRecord_{0}] (\"CustomerId\",\"StationId\",\"ChargeBoxId\",\"HourIndex\",\"TotalMinute\",\"OnlineTime\",\"OfflineTime\")" +
|
|
|
- "VALUES(@CustomerId,@StationId, @ChargeBoxId,@HourIndex,@TotalMinute,@OnlineTime,@OfflineTime); ", insertItems[i].OnlineTime.Date.ToString("yyMMdd"));
|
|
|
- using (var dbConn = new SqlConnection(onlineDBConnectString))
|
|
|
+ if (rowId.HasValue)
|
|
|
{
|
|
|
- dbConn.Open();
|
|
|
- await dbConn.ExecuteAsync(sqlString, insertItems[i]);
|
|
|
+ string sqlString = "UPDATE [dbo].[EVSEOnlineRecord] SET OfflineTime=@OfflineTime WHERE Id=@Id";
|
|
|
+ using (var dbConn = new SqlConnection(onlineDBConnectString))
|
|
|
+ {
|
|
|
+ dbConn.Open();
|
|
|
+ var parameters = new DynamicParameters();
|
|
|
+ parameters.Add("@OfflineTime", hearbeatDt, System.Data.DbType.DateTime);
|
|
|
+ parameters.Add("@Id", rowId.Value, System.Data.DbType.Int64);
|
|
|
+
|
|
|
+ await dbConn.ExecuteAsync(sqlString, parameters);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ logger.Error("Can't find update row id from " + chargeBoxId);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
- logger.Error("Update Data Error " + ex.ToString());
|
|
|
+ logger.Error(string.Format("UpdateOnlineRecords Exception:{0}", ex.ToString()));
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- async private Task<List<EVSEOnlineRecord>> GetOnlineRecords(DateTime pickDate, string customerId, string chargeBoxId, int startHourCondition, int stopHourCondition)
|
|
|
+ async private Task<EVSEOnlineRecord> GetOnlineRecord(string chargeBoxId)
|
|
|
{
|
|
|
- List<EVSEOnlineRecord> records = new List<EVSEOnlineRecord>();
|
|
|
+ EVSEOnlineRecord lastrow = new EVSEOnlineRecord();
|
|
|
try
|
|
|
{
|
|
|
- string sqlString = string.Format("SELECT * FROM [dbo].[EVSEOnlineRecord_{0}] WHERE customerId=@customerId and chargeBoxId=@chargeBoxId and " +
|
|
|
- "HourIndex >= @startHourCondition and HourIndex <= @stopHourCondition and OfflineTime=@OfflineTime", pickDate.ToString("yyMMdd"));
|
|
|
+ string sqlString = string.Format("SELECT Id FROM [dbo].[EVSEOnlineRecord] WHERE chargeBoxId=@chargeBoxId Order by OnlineTime desc");
|
|
|
using (var dbConn = new SqlConnection(onlineDBConnectString))
|
|
|
{
|
|
|
dbConn.Open();
|
|
|
var parameters = new DynamicParameters();
|
|
|
- parameters.Add("@customerId", new Guid(customerId), System.Data.DbType.Guid);
|
|
|
parameters.Add("@chargeBoxId", chargeBoxId, System.Data.DbType.String);
|
|
|
- parameters.Add("@startHourCondition", startHourCondition, System.Data.DbType.Int32);
|
|
|
- parameters.Add("@stopHourCondition", stopHourCondition, System.Data.DbType.Int32);
|
|
|
- parameters.Add("@OfflineTime", DefaultSetting.DefaultNullTime, System.Data.DbType.Date);
|
|
|
|
|
|
- var result = await dbConn.QueryAsync<EVSEOnlineRecord>(sqlString, parameters);
|
|
|
- records = result.ToList();
|
|
|
- }
|
|
|
|
|
|
- }
|
|
|
- catch (Exception ex)
|
|
|
- {
|
|
|
- logger.Error("Query Data Error " + ex.ToString());
|
|
|
- }
|
|
|
- return records;
|
|
|
- }
|
|
|
-
|
|
|
- private void CreateEVSEOnlineRecordTable()
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- string sqlString = string.Format("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME ='EVSEOnlineRecord_{0}'", latestHeartbeatTime.ToString("yyMMdd"));
|
|
|
- using (var dbConn = new SqlConnection(onlineDBConnectString))
|
|
|
- {
|
|
|
- bool exists = dbConn.ExecuteScalar<bool>(sqlString);
|
|
|
- if (!exists)
|
|
|
- {
|
|
|
- dbConn.Execute(string.Format(@"
|
|
|
- CREATE TABLE [dbo].[EVSEOnlineRecord_{0}] (
|
|
|
- [CustomerId] [UNIQUEIDENTIFIER] NOT NULL,
|
|
|
- [StationId] [nvarchar](36) NOT NULL,
|
|
|
- [ChargeBoxId] [nvarchar](36) NOT NULL,
|
|
|
- [HourIndex] [int] NOT NULL,
|
|
|
- [TotalMinute] [int] NOT NULL,
|
|
|
- [OnlineTime] [datetime] NOT NULL,
|
|
|
- [OfflineTime] [datetime] NOT NULL
|
|
|
- ) ON [PRIMARY]
|
|
|
- ", latestHeartbeatTime.ToString("yyMMdd")));
|
|
|
- }
|
|
|
+ var result = await dbConn.QueryAsync<EVSEOnlineRecord>(sqlString, parameters);
|
|
|
+ lastrow = result.FirstOrDefault();
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -385,22 +217,8 @@ namespace EVCB_OCPP.TaskScheduler.Jobs
|
|
|
{
|
|
|
logger.Error("Query Data Error " + ex.ToString());
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- private void ClearCache()
|
|
|
- {
|
|
|
- if (updateData != null)
|
|
|
- {
|
|
|
- updateData.Clear();
|
|
|
- }
|
|
|
-
|
|
|
- if (insertData != null)
|
|
|
- {
|
|
|
- insertData.Clear();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
+ return lastrow;
|
|
|
+ }
|
|
|
|
|
|
|
|
|
private bool IsOnlineNow(EVSECurrentStatus currentEVSE)
|