© 2018 Capita Business Services Ltd. All rights reserved.

Capita Education Software Solutions is a trading name of Capita Business Services Ltd. Our Registered office is 30 Berners Street, London, W1T 3LR and our registered number is 02299747. Further information about Capita plc can be found in our legal statement.

Local API - Lesson Attendance Concepts

Lesson Attendance Concepts

A typical partner system offers some form of location recording. In essence their system will have allowed some form of setup that identifies where an access point is; it knows the time and the access point activation by card, biometric or other mechanism in effect identifies the student at the location.

Whilst partner systems work in many different ways, if we can provide a training session that shows how to convert:

A room ID

A student ID

A date / time for the student triggering the system in that room

Then this is probably sufficient for most partners to adapt to their way of working.

In order to simplify the information here, we will assume that the partner system has exported via command reporter the set of room names and their ids and used this to configure their access points and hence identify where they are.

We will further assume that a second export has been achieved, again command reporter which is the list of student ids, surname, forename, admission number, house, year group and registration group. This will have been used to map the identity token to a student id by the partner system.

Like the Cluedo® game we now know that C S Tudent is in the Library at 09:40:12 on 3rd September 2011. The sample aims to work back from this information to recording a mark in SIMS for the student’s lesson attendance; identifying pitfalls on the way…

The key function call that identifies what C S Tudent is up to is

TPTimetable tpt = new TPTimetable();
string tt = tpt.GetXmlStudentTimetable(StudentID, DateTime.Now, DateTime.Now);

Simply replace the DateTime.Now with the time of the Swipe and this will return the student’s timetable at the time of the swipe. For example:

<Timetable>
  <StudentID>5253</StudentID>
  <EmployeeID>82</EmployeeID>
  <EventInstanceID>25292</EventInstanceID>
  <EventID>202</EventID>
  <TimetableDate>2009-09-02T10:15:00</TimetableDate>
  <PeriodName>Wed:2</PeriodName>
  <PeriodNumber>12</PeriodNumber>
  <BaseGroupID>5390</BaseGroupID>
  <LocationID>4</LocationID>
  <SubjectID>521</SubjectID>
</Timetable>

Any full implementation will need to consider the possibility that the swipe occurs during break time (5 seconds early say) and the above call would return no results.  However, if the call is made for:

string testdata = timetable.GetXmlStudentTimetable (StudentID, DateTime.Parse("01/09/2009T00:00:01"), DateTime.Parse("01/09/2009T23:59:59"));

… would return all the timetabled lessons for that student on the day.  It is up to the partner system how they choose to deal with this.

Writing the data back:

string xmlstring = @"<LessonAttendances>
  <LessonAttendance>
    <PersonID>4582</PersonID>
    <EventInstanceID>25719</EventInstanceID>
    <AttendanceMark>M</AttendanceMark>
    <Comments></Comments>
    <MinsLate></MinsLate>
    <BaseGroupID>5390</BaseGroupID>
    <EmployeeID>82</EmployeeID>
    <LocationID>4</LocationID>
  </LessonAttendance>
</LessonAttendances>"; 
TPAttendanceWrite attWrite = new TPAttendanceWrite(); bool done = attWrite.WriteLessonAttendances(xmlstring);

The XML string passed for writing the lesson marks should pass the personID, EventInstanceId of the lesson and the mark that needs to be written. Exact mark will be written in SIMS database that has been supplied in the XML passed to this method.

From Autumn 2011 release of SIMS, the interaface can be used to write MinsLate and Comments back with lesson marks. The writing of Comments and MinsLate will be optional.

In the summer 2012 release of SIMS we will add the option of including the room id and base group id.  The interface prior to that release supports only period attendance.  Whilst this is the same outcome for students who have single classes per period, where a student is timetabled for multiple classes in a period, has a class with multiple teachers or a class timetabled for multiple rooms then every combination would have received the same mark. There are circumstances where this would technically record the wrong information, for example if C S Tudent has a music lesson that replaces his maths lesson every few weeks then he should be marked present at music and absent for maths where applicable. The Third Party APIs do not deal with that circumstance prior to the change described here.

By passing the base group id and the room id, the function call can update the desired lessons independently.  It does however mean that partners passing the additional XML data will need to decide what to do with say multiple teachers or rooms and submit appropriate updates from the partner’s code.

For example if a student was taught by 2 teachers in the same room, 2 entries would occur in their time table. A location system would have no idea of which teacher was taking the session and so it may be appropriate to mark them present for both lessons.

Example 2: If a student had 2 timetabled lessons in 2 locations, a mark for one would typically have no effect on the other.

Please note that any mark providing one or other of room ID / base group ID but not both will be rejected and flagged as an error.

 Concepts for Swipe Card Systems

“Known Knowns and Known Unknowns” courtesy of Donald Rumsfeld February 12, 2002.  

In order to save a mark for a lesson, the following information

  • The event instance id – (The instance of a lesson)
  • The id of the class being taught
  • The Id of the student
  • The Attendance Mark
  • [Minutes Late]
  • [Comments]
  • The Room ID
  • The Class ID
  • The Member of Staff ID

When a swipe card is used, we know:

  • Where the reader is
  • What time it is
  • What the ID of the card is.

Using the partner system we can convert the above to:

  • Who the student is (Student ID) – SIMS won’t know which student has which card.
  • What the room is (Room ID) – The location of the reader is usually fixed and needs to be associated with a SIMS room id.
  • The date and time of the swipe

The partner system can interrogate SIMS to find.

  1. The set of periods taught on a given day. In order to do this it needs to get the set of event instances for that day and select all those of type ‘Period’ (Code is: <TBA>)

Sample

  • Mon1                 09:00-10:00
  • Mon2                 10:15-11:15
  • Mon3                 11:15-12:15
  • Mon4                 13:15-14:15
  • Mon5                 14:30-15:30

Please note that there is no formal recording of the registration period timings which would be common to all schools. SIMS Lesson monitor will however know where in the list the AM and PM registration sits, e.g. After period 5.

Whilst this may seem like a simple query, it requires iteration through event types, events and event instances. Sample code is provided below.

2. The system can work out what that individual student is doing today

Period 1                           Maths                 Rm4                    Mrs Brown

Period 2                           English                Rm4                    Mrs Jones

                                         English                Rm4                    Miss Smith

Period3                            Physics               Ph3                     Prof Jones

                                         Music                 Mu5                    Ms P Anno

Period4                            Free

Period5                            Badminton         Hall                     Ms S Port

                                         Footie                 Field                    Ms K Ball

                                         Swimming          Pool                    Ms D Round

                                         Chess                  Hall                     Ms C Board

                                        

Sample XML 

<Timetable>
  <StudentID>8894</StudentID>
  <EmployeeID>86</EmployeeID>
  <EventInstanceID>32358</EventInstanceID>
  <EventID>211</EventID>
  <TimetableDate>2012-10-05T09:15:00</TimetableDate>
  <PeriodName>Fri:1</PeriodName>
  <PeriodNumber>21</PeriodNumber>
  <BaseGroupID>7124</BaseGroupID>
  <LocationID>44</LocationID>
  <SubjectID>545</SubjectID>
</Timetable>

Sample code is given below for how to get the students time table.

Algorithms

The partner system needs to work out what a swipe at any given time means. Some basic issues to consider are:

  • A student may arrive early for a lesson. If they swipe at 11:10 are they 5 minutes early or 55 minutes late? [Decision for partner system.]
  • In Period 5 Fred swipes in in the hall – What marks should be given?
  • In Period 3 Fred swipes in to Music [and is absent form Physics] what’s recorded.
  • Fred swipes in to a Physics lesson in Period 4.  [What happens then?]
  • What happens for multiple periods (not shown in the example)

So it can work out

  • The period is being taught. (Event instance id). (Using the partner application’s algorithm)
  • The Student ID ( A look up in the partner system)
  • The date and time of the swipe.
  • Minutes Late - Using the time and algorithm within the partner application.
  • Using the student time table: Which lessons are being taught to the student at that time.
  • Using the room swipe and the student time table, the subset of lessons that match up with the swipe.

If there is only one match the student should get a present (or late) mark for that lesson.

If none match – the partner system needs to decide what to do (it may be real or malicious)

If many match – if there are multiple teachers in that room for the same class, as is the case for Period 2 then both should get a present / late mark (Author’s opionion).  If the mark is ambiguous as would be the case for period 5 in the hall; the partner system must decide what to do. (There are no generic answers).

Writing the data back: 

string xmlstring = @"<LessonAttendances>
  <LessonAttendance>
    <PersonID>4582</PersonID>
    <EventInstanceID>25719</EventInstanceID>
    <AttendanceMark>M</AttendanceMark>
    <Comments></Comments>
    <MinsLate></MinsLate>
    <BaseGroupID>5390</BaseGroupID>
    <EmployeeID>82</EmployeeID>
    <LocationID>4</LocationID>
  </LessonAttendance>
</LessonAttendances>"; 
TPAttendanceWrite attWrite = new TPAttendanceWrite(); bool done = attWrite.WriteLessonAttendances(xmlstring);

The XML string passed for writing the lesson marks should pass the personID, EventInstanceId of the lesson and the mark that needs to be written. Exact mark will be written in SIMS database that has been supplied in the XML passed to this method.

From Autumn 2011 release of SIMS, the interaface can be used to write MinsLate and Comments back with lesson marks. The writing of Comments and MinsLate will be optional.

Known unknowns

We have no idea who is teaching a group based on a student swipe. It may be a cover for the teacher expected or one of the scenarios above!

We know where a card is at a given time. This is an indicator that the student may be holding the card when swiped but that is not guaranteed.

Timetable variation. If a member of staff has a great idea or a room springs a leak, the set of swipes in a room without a class would occur. In SIMS, a known user chooses their class and marks the students present (the location would be as per their timetable).

Conclusion

The actual writing back of lesson attendance data back is not in itself a difficult task. The challenge for swipe card systems is filling in the blanks in a way that is appropriate for your customers. ESS may have an opinion as to whether the chosen algorithm is ‘reasonable’ but the partner will need to explain and justify ‘their’ application to ‘their’ customers.

ESS would apply a narrower view of ‘fit for purpose’ for any partner products that we commercially endorse / sell.

Sample code for getting the periods today

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace SIMSInterfaceSample
{
    public class Events
    {
        public class PeriodInfo
        {
            private DateTime MAXDATE = DateTime.Parse("2079-01-01");
            public DateTime End {get; private set;}
            public DateTime Start {get; private set;}
            public string Name { get; private set; }
            public string EventInstanceID { get; private set; }
            public PeriodInfo(string _name, DateTime _start, DateTime _end, string evID)
            {
                Name = _name;
                End = _end;
                Start = _start;
                EventInstanceID = evID;

            }
            public PeriodInfo(string _name, string _start, string _end, string evID)
            {
                Name = _name;
                if (string.IsNullOrEmpty(_end))
                {
                    End = MAXDATE;
                }
                End = DateTime.Parse(_end);
                Start = DateTime.Parse(_start);
                EventInstanceID = evID;
            }
        }

        public static Dictionary<string, PeriodInfo> GetPeriods(DateTime date)
        {
            Dictionary<string, PeriodInfo> pi = new Dictionary<string, PeriodInfo>();
            SIMS.Processes.TPCalendar tpc = new SIMS.Processes.TPCalendar();
            XmlDocument et = new XmlDocument();
            et.InnerXml = tpc.GetXmlEventTypes();
            string PeriodTypeId = "";
            foreach (XmlNode n in et.SelectNodes("CalendarEventTypes/CalendarEventType"))
            {
                if (n["Code"].InnerXml == "TTPeriod")
                {
                    PeriodTypeId = n["EventTypeID"].InnerXml;
                    break;
                }
            }
            XmlDocument evs = new XmlDocument();
            evs.InnerXml = tpc.GetXmlEvents();
            foreach (XmlNode n2 in evs.SelectNodes("CalendarEvents/CalendarEvent"))
            {
                if (n2["EventTypeID"].InnerXml == PeriodTypeId && n2["IsActive"].InnerXml == "T")
                {
                    PeriodInfo p = new PeriodInfo(n2["Description"].InnerXml, n2["DefaultStartTime"].InnerXml, n2["DefaultEndTime"].InnerXml, n2["EventId"].InnerXml);
                    pi.Add(p.EventInstanceID,p);
                }
            }
            Dictionary<string, PeriodInfo> pi2 = new Dictionary<string, PeriodInfo>();
            XmlDocument evinst = new XmlDocument();
            evinst.InnerXml = tpc.GetXmlEventInstances(DateTime.Today, DateTime.Today.AddHours(23).AddMinutes(59));
            foreach (XmlNode n3 in evinst.SelectNodes("CalendarEventInstances/CalendarEventInstance"))
            {
                if (pi.ContainsKey(n3["EventId"].InnerXml))
                {
                    pi2.Add(pi[n3["EventId"].InnerXml].Name, pi[n3["EventId"].InnerXml]);               
                }
            }

            return pi2;
        }
    }
}

Sample code for getting a student’s timetable

 

Be warned, if you ask for a timetable over a range that is too short, you may get less than you hoped for! Best recommendation is to get the time table for a whole day and decide which bits you want!

/// <summary>
/// Warning - this won't be a winner in the summer holidays!
/// </summary>
/// <param name="id"></param>
/// <param name="start"></param>
/// <param name="end"></param>
/// <returns></returns>
public static XmlDocument GetStudentTT(int id, DateTime start, DateTime end)
{
    XmlDocument d = new XmlDocument();
    SIMS.Processes.TPTimetable tptt = new SIMS.Processes.TPTimetable();
    d.InnerXml = tptt.GetXmlStudentTimetable(id, start, end);
    return d;

}