C# application for paxton door access
Paxton offers a product range including IP, wireless and battery powered access control solutions to provide reliable security for any site requirement.
We ordered one door access card reader & control unit, with it comes net2 software shipped, in wich you can manage users access cards (wich doors who can open and when, expiration date etc..)
I will use the access control for a gym, where members can open the front door with their personal (rfid) card, untill their membership expires.
There was no way to automatically re-activate the members card after they renewed their subscription online, but since the net2 software paxton develops has a net2 sdk available, I created a c# application that updates the user automatically.
In this case a simple console application would be enough, wich runs every 5 minutes, checking a directory for xml files.
If a member renews their subscription or a new member is created an xml is sent to the server where the application picks up the xml and updates / creates the user in the net2 database:
class Program { private const int REMOTE_PORT = 8025; private const string REMOTE_HOST = "IPADDRESS NET2 SERVER"; private OemClient _net2Client = new OemClient(REMOTE_HOST, REMOTE_PORT); private static string logFile = string.Format("log/log-{0}-{1}-{2}.txt", DateTime.Now.Day.ToString(), DateTime.Now.Month.ToString(), DateTime.Now.Year.ToString()); private string sourceDirectory = @"xml"; private string archiveDirectory = @"archive\"; private StreamWriter log = File.AppendText(logFile); static void Main(string[] args) { Program main = new Program(); main.startUp(); } //Check if there are xml files with user updates in the directory public int startUp() { IEnumerable xmlFiles = Directory.EnumerateFiles(sourceDirectory, "*.xml"); if (xmlFiles.Count() <= 0) { Log("Nothing to do, shutting down.."); return 1; } bool res = AuthenticateUser("OEM Client", "password"); if(res != true) { Log("Authentication failed, exiting application"); return 1; } Log("Authentication success"); //Check for available xml files loadAndParseXml(xmlFiles); return 1; } private void loadAndParseXml(IEnumerable xmlFiles) { //Check if there are files foreach (string file in xmlFiles) { Log(file); string contents = File.ReadAllText(file); if(parseXml(contents) == true) { string fileName = file.Substring(sourceDirectory.Length + 1); File.Move(file, archiveDirectory + fileName); } } } private bool parseXml(string xmlstr) { Log("Parse XML"); XElement users = XElement.Parse(xmlstr); Log(users.Name.ToString()); if(users.Name.ToString() == "update") { Log("This user needs an update"); updateUsers(users); } if(users.Name.ToString() == "create") { Log("This user needs an add"); addUsers(users); } return true; } private DateTime stringToDateTime(string date) { // Date strings are interpreted according to the current culture. // If the culture is en-US, this is interpreted as "January 8, 2008", // but if the user's computer is fr-FR, this is interpreted as "August 1, 2008" DateTime dt = Convert.ToDateTime(date); return dt; } /** * Update existing users in Net2 * Field9_50 is Emailaddress (don't ask me why) **/ private void updateUsers(XElement users) { var data = from item in users.Descendants("user") select new { email = item.Element("emailaddress").Value, expiration = item.Element("expirationdate").Value, }; foreach (var p in data) { //IUser interface object is returned IUsers userList = _net2Client.ViewUserRecords(String.Format("Field9_50 = '{0}' AND active=1", p.email)); if (userList.UsersList().Count - 1 > 1) { Log("Houston, we've got a problem, multiple users!! Abort Abort!"); Environment.Exit(0); } //Since there is always only one user, we can assume the only one in the list is the correct user var user = userList.UsersList()[userList.UsersList().Keys.ElementAt(userList.UsersList().Count - 1)]; DateTime expDate; expDate = stringToDateTime(p.expiration); string[] customFields = new string[] { "" }; bool blnResult = false; blnResult = _net2Client.UpdateUserRecord(user.UserId, user.AccessLevelId, user.DepartmentId, user.AntiPassbackUser, user.AlarmUser, user.FirstName, user.MiddleName, user.Surname, user.Telephone, user.Extension, user.PIN, user.Picture, user.ActivationDate, user.Active, user.Fax, expDate, customFields); Log(string.Format("Update user Status: {0}, Name: {1}, ExpirationDate: {2}", blnResult, user.FirstName, expDate)); } } /** * Authenticate user * For some reason we can't authenticate with username password, only with userId Password.. * So we need to get the userId and Authenticate with it.. **/ private bool AuthenticateUser(string userName, string password) { IOperators operators = _net2Client.GetListOfOperators(); Dictionary<int, string> operatorsList = operators.UsersDictionary(); foreach (int userID in operatorsList.Keys) { if (operatorsList[userID] == userName) { Dictionary<string, int> methodList = _net2Client.AuthenticateUser(userID, password); return (methodList != null); } } return false; } private void Log(string logMessage) { Console.WriteLine(logMessage); log.Write("\r\nLog Entry : "); log.WriteLine("{0} {1} : {2}", DateTime.Now.ToShortDateString(), DateTime.Now.ToLongDateString(), logMessage); log.WriteLine("-------------------------------"); } }
The xml files that are added in the xml directory look like this:
<update> <user> <email>[email protected]</email> <expiration>10-08-2016</expiration> </user> </update>
After the file has been parsed it will be moved to the archive folder, for later reference or checking.