Skip to content

Commit

Permalink
Merge pull request #251 from dasgarner/develop
Browse files Browse the repository at this point in the history
v3 R303
  • Loading branch information
dasgarner authored Mar 15, 2022
2 parents c732dbe + b5e7500 commit b57630f
Show file tree
Hide file tree
Showing 14 changed files with 612 additions and 106 deletions.
31 changes: 30 additions & 1 deletion Action/Action.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (C) 2021 Xibo Signage Ltd
* Copyright (C) 2022 Xibo Signage Ltd
*
* Xibo - Digital Signage - http://www.xibo.org.uk
*
Expand Down Expand Up @@ -43,6 +43,7 @@ public class Action
public string LayoutCode { get; set; }
public bool Bubble { get; set; }
public bool IsDrawer { get; set; }
public string CommandCode { get; set; }

public Rect Rect { get; set; }

Expand Down Expand Up @@ -73,6 +74,34 @@ public static Action CreateFromXmlNode(XmlNode node, int top, int left, int widt
};
}

/// <summary>
/// Create an action from a schedule XML node
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
public static Action CreateFromScheduleNode(XmlNode node)
{
XmlAttributeCollection attributes = node.Attributes;

return new Action
{
Id = int.Parse(attributes["scheduleid"].Value),
ActionType = attributes["actionType"]?.Value,
TriggerType = "webhook",
TriggerCode = attributes["triggerCode"]?.Value,
WidgetId = 0,
SourceId = 0,
Source = "schedule",
TargetId = 0,
Target = "screen",
LayoutCode = attributes["layoutCode"]?.Value,
Bubble = false,
IsDrawer = false,
CommandCode = attributes["commandCode"]?.Value,
Rect = new Rect(0, 0, 0, 0)
};
}

/// <summary>
/// Create a list of Actions from an XmlNodeList
/// </summary>
Expand Down
37 changes: 16 additions & 21 deletions Action/XmrSubscriber.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (C) 2021 Xibo Signage Ltd
* Copyright (C) 2022 Xibo Signage Ltd
*
* Xibo - Digital Signage - http://www.xibo.org.uk
*
Expand Down Expand Up @@ -41,8 +41,9 @@ class XmrSubscriber

/// <summary>
/// Last Heartbeat packet received
/// Assume a successful connection so that a check doesn't immediately tear down the socket.
/// </summary>
public DateTime LastHeartBeat = DateTime.MinValue;
public DateTime LastHeartBeat = DateTime.Now;

// Events
public delegate void OnActionDelegate(PlayerActionInterface action);
Expand All @@ -65,11 +66,6 @@ public HardwareKey HardwareKey
/// </summary>
private NetMQPoller _poller;

/// <summary>
/// The Init Address
/// </summary>
private string _address;

/// <summary>
/// Runs the agent
/// </summary>
Expand All @@ -89,9 +85,6 @@ public void Run()
// Check we have an address to connect to.
if (!string.IsNullOrEmpty(ApplicationSettings.Default.XmrNetworkAddress) && ApplicationSettings.Default.XmrNetworkAddress != "DISABLED")
{
// Cache the address for this socket (the setting may change outside).
_address = ApplicationSettings.Default.XmrNetworkAddress;

// Get the Private Key
AsymmetricCipherKeyPair rsaKey = _hardwareKey.getXmrKey();

Expand Down Expand Up @@ -278,21 +271,22 @@ private void processMessage(NetMQMessage message, AsymmetricCipherKeyPair rsaKey
/// </summary>
public void Restart()
{
// Stop the poller
try
{
// Stop the poller
if (_poller != null)
{
_poller.Stop();
_poller.Dispose();
}

// Wakeup
_manualReset.Set();
}
catch (Exception e)
{
Trace.WriteLine(new LogMessage("XmrSubscriber - Restart", "Unable to Restart XMR: " + e.Message), LogType.Info.ToString());
Trace.WriteLine(new LogMessage("XmrSubscriber - Restart", "Unable to stop XMR during restart: " + e.Message), LogType.Info.ToString());
}

// Wakeup
_manualReset.Set();
}

/// <summary>
Expand All @@ -306,18 +300,19 @@ public void Stop()
if (_poller != null)
{
_poller.Stop();
_poller.Dispose();
}

// Stop the thread at the next loop
_forceStop = true;

// Wakeup
_manualReset.Set();
}
catch (Exception e)
{
Trace.WriteLine(new LogMessage("XmrSubscriber - Stop", "Unable to Stop XMR: " + e.Message), LogType.Info.ToString());
}

// Stop the thread at the next loop
_forceStop = true;

// Wakeup
_manualReset.Set();
}
}
}
71 changes: 71 additions & 0 deletions Helpers/GeoHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* Copyright (C) 2022 Xibo Signage Ltd
*
* Xibo - Digital Signage - http://www.xibo.org.uk
*
* This file is part of Xibo.
*
* Xibo is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Xibo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
*/
using GeoJSON.Net.Contrib.MsSqlSpatial;
using GeoJSON.Net.Feature;
using GeoJSON.Net.Geometry;
using Microsoft.SqlServer.Types;
using Newtonsoft.Json;
using System;
using System.Device.Location;
using System.Diagnostics;

namespace XiboClient.Helpers
{
class GeoHelper
{
/// <summary>
/// Is the provided geoJson inside the provided point
/// </summary>
/// <param name="geoJson"></param>
/// <param name="point"></param>
/// <returns></returns>
public static bool IsGeoInPoint(string geoJson, Point point)
{
try
{
// Test against the geo location
var geo = JsonConvert.DeserializeObject<Feature>(geoJson);

// Use SQL spatial helper to calculate intersection or not
SqlGeometry polygon = (geo.Geometry as Polygon).ToSqlGeometry();

return point.ToSqlGeometry().STIntersects(polygon).Value;
}
catch (Exception e)
{
Trace.WriteLine(new LogMessage("GeoHelper", "IsGeoInPoint: Cannot parse geo location: e = " + e.Message), LogType.Audit.ToString());

return false;
}
}

/// <summary>
/// Is the provided geoJson inside the provided point, denoted by a location
/// </summary>
/// <param name="geoJson"></param>
/// <param name="geoCoordinate"></param>
/// <returns></returns>
public static bool IsGeoInPoint(string geoJson, GeoCoordinate geoCoordinate)
{
return IsGeoInPoint(geoJson, new Point(new Position(geoCoordinate.Latitude, geoCoordinate.Longitude)));
}
}
}
5 changes: 5 additions & 0 deletions Logic/RegionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ public struct RegionOptions
public int PlayerWidth { get; set; }
public int PlayerHeight { get; set; }

// Region out transition
public string TransitionType;
public int TransitionDuration;
public string TransitionDirection;

public override string ToString()
{
return string.Format("({0},{1},{2},{3},{4},{5})", width, height, top, left, layoutId, regionId);
Expand Down
44 changes: 39 additions & 5 deletions Logic/Schedule.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (C) 2021 Xibo Signage Ltd
* Copyright (C) 2022 Xibo Signage Ltd
*
* Xibo - Digital Signage - http://www.xibo.org.uk
*
Expand Down Expand Up @@ -63,6 +63,11 @@ public class Schedule
/// </summary>
private bool _stopCalled = false;

/// <summary>
/// Should we trigger a schedule call on register complete?
/// </summary>
private bool _triggerScheduleOnRegisterComplete = false;

#region Threads and Agents
// Key
private HardwareKey _hardwareKey;
Expand Down Expand Up @@ -117,6 +122,7 @@ public Schedule(string scheduleLocation)
// Create a Register Agent
_registerAgent = new RegisterAgent();
_registerAgent.OnXmrReconfigure += _registerAgent_OnXmrReconfigure;
_registerAgent.OnRegisterComplete += _registerAgent_OnRegisterComplete;
_registerAgentThread = new Thread(new ThreadStart(_registerAgent.Run));
_registerAgentThread.Name = "RegisterAgentThread";

Expand Down Expand Up @@ -312,6 +318,21 @@ void _registerAgent_OnXmrReconfigure()
restartXmr();
}

/// <summary>
/// Regiser call has completed.
/// </summary>
/// <param name="error"></param>
private void _registerAgent_OnRegisterComplete(bool error)
{
if (!error && _triggerScheduleOnRegisterComplete)
{
_scheduleAndRfAgent.WakeUp();
}

// Reset
_triggerScheduleOnRegisterComplete = false;
}

/// <summary>
/// XMR Subscriber Action
/// </summary>
Expand Down Expand Up @@ -400,17 +421,20 @@ private void _requiredFilesAgent_OnFullyProvisioned()
/// </summary>
public void wakeUpXmds()
{
// Wake up schedule/rf after the register call, which will update our CRC's.
_triggerScheduleOnRegisterComplete = true;
_registerAgent.WakeUp();
_logAgent.WakeUp();
_faultsAgent.WakeUp();

// Wake up schedule/rf in 20 seconds to give time for register to complete, which will update our CRC's.
// Wake up other calls in a little while (give the rest time to complete so we send the latest info)
var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(20) };
timer.Tick += (timerSender, args) =>
{
// You only tick once
timer.Stop();
_scheduleAndRfAgent.WakeUp();

// Wake
_logAgent.WakeUp();
_faultsAgent.WakeUp();
};
timer.Start();
}
Expand Down Expand Up @@ -631,6 +655,7 @@ public void Stop()
_stopCalled = true;

// Stop the register agent
_registerAgent.OnRegisterComplete -= _registerAgent_OnRegisterComplete;
_registerAgent.Stop();

// Stop the requiredfiles agent
Expand Down Expand Up @@ -758,5 +783,14 @@ public Ad GetAd(double width, double height)
{
return _scheduleManager.GetAd(width, height);
}

/// <summary>
/// Get the current actions schedule
/// </summary>
/// <returns></returns>
public List<Action.Action> GetActions()
{
return _scheduleManager.CurrentActionsSchedule;
}
}
}
31 changes: 10 additions & 21 deletions Logic/ScheduleItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Collections.Generic;
using System.Device.Location;
using System.Diagnostics;
using XiboClient.Helpers;

namespace XiboClient.Logic
{
Expand Down Expand Up @@ -194,29 +195,17 @@ public bool SetIsGeoActive(GeoCoordinate geoCoordinate)
}
else
{
try
{
// Current location.
Point current = new Point(new Position(geoCoordinate.Latitude, geoCoordinate.Longitude));

// Have we already tested this?
if (this.testedAgainst == null || !testedAgainst.Equals(current))
{
// Not tested yet, or position changed.
this.testedAgainst = current;

// Test against the geo location
var geo = JsonConvert.DeserializeObject<Feature>(GeoLocation);
// Current location.
Point current = new Point(new Position(geoCoordinate.Latitude, geoCoordinate.Longitude));

// Use SQL spatial helper to calculate intersection or not
SqlGeometry polygon = (geo.Geometry as Polygon).ToSqlGeometry();

IsGeoActive = current.ToSqlGeometry().STIntersects(polygon).Value;
}
}
catch (Exception e)
// Have we already tested this?
if (this.testedAgainst == null || !testedAgainst.Equals(current))
{
Trace.WriteLine(new LogMessage("ScheduleItem", "SetIsGeoActive: Cannot parse geo location: e = " + e.Message), LogType.Audit.ToString());
// Not tested yet, or position changed.
this.testedAgainst = current;

// Test
IsGeoActive = GeoHelper.IsGeoInPoint(GeoLocation, current);
}
}

Expand Down
Loading

0 comments on commit b57630f

Please sign in to comment.