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.
hi have you an example of the xml file required for this?
thanks
Hi Jim,
I use the users Emailaddress to update their expiration date, so my xml looks like this:
<update>
<user>
<email>[email protected]</email>
<expiration>10-08-2016</expiration>
</user>
</update>