Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Microsoft Point of Service for .NET (POS para .NET) Objetos de Servicio realizan un seguimiento continuo y actualizan diversas estadísticas de dispositivo para cada dispositivo conectado. El seguimiento estadístico se realiza mediante la DeviceStatistics clase , que contiene métodos para restablecer, recuperar y actualizar estadísticas, así como métodos auxiliares para crear estadísticas, incrementar estadísticas y cargar o guardar estadísticas en o desde el almacenamiento de archivos XML.
Los informes de estadísticas en POS para .NET admiten estadísticas almacenadas en hardware o software. Las estadísticas basadas en software se almacenan en un archivo de estadísticas XML, \Program Files\Common Files\Microsoft Shared\Point of Service\Statistics\PosDeviceStatistics.xmly se actualizan en un intervalo de vaciado definido globalmente que se determina en el momento de la instalación y configuración del sistema. De forma predeterminada, este intervalo de vaciado es de 1 segundo. Cuando la aplicación reclama un dispositivo, POS para .NET carga las estadísticas adecuadas del archivo XML.
La administración de estadísticas específicas del dispositivo es compatible con la interfaz de clase de dispositivo base o básica . Los objetos de servicio que heredan de una clase Base o Basic normalmente solo son necesarios para llamar a IncrementStatistic, que incrementa el valor de una estadística especificada o SetStatistic, que establece una estadística en un valor especificado. La interfaz de clase Base o Basic proporciona todas las demás implementaciones de estadísticas.
Los miembros clave de la clase DeviceStatistics se detallan a continuación:
CapStatisticsReporting identifica las funcionalidades de informes de estadísticas del dispositivo. Cuando CapStatisticsReporting se establece en false, no hay datos estadísticos relacionados con el dispositivo disponibles. Si CapStatisticsReporting es true, algunos datos estadísticos están disponibles y el dispositivo puede empezar a acumular varias estadísticas con respecto al uso. La información acumulada y notificada es específica del dispositivo y se recupera mediante el método RetrieveStatistics .
CapUpdateStatistics define si las estadísticas recopiladas se pueden restablecer o actualizar mediante una aplicación que emplea los métodos UpdateStatistics y ResetStatistics . Esta propiedad solo es válida si CapStatisticsReporting es true. Si CapStatisticsReporting es false, la propiedad CapUpdateStatistics siempre es false.
ResetStatistics puede ser llamado solo si CapStatisticsReporting y CapUpdateStatistics son verdadero. Este método restablece una, alguna o todas las estadísticas de dispositivo restableables a cero. Restablece las estadísticas restablecibles definidas en un dispositivo a cero. Todas las estadísticas solicitadas deben restablecerse correctamente para que este método se complete correctamente. De lo contrario, se produce un error con el método Extended ErrorCode . Este método siempre se ejecuta sincrónicamente.
UpdateStatistics establece una, algunas o todas las estadísticas de dispositivo restabletables en los valores especificados. Todas las estadísticas solicitadas deben actualizarse correctamente para que este método se complete correctamente. Si algunos no se pueden actualizar por algún motivo, se devuelve un evento ErrorCode . Tanto CapStatisticsReporting como CapUpdateStatistics deben establecerse en true para llamar a este método. El método UpdateStatistics siempre se ejecuta sincrónicamente.
RetrieveStatistics recupera las estadísticas solicitadas de un dispositivo. CapStatisticsReporting debe ser true para poder usar correctamente este método. Todas las llamadas a RetrieveStatistics devolverán el siguiente XML como mínimo.
<?xml version='1.0'?> <UPOSStat version="1.10.0" xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xmlns="http://www.nrf-arts.org/IXRetail/namespace/" xsi:schemaLocation="http://www.nrf-arts.org/IXRetail/namespace/ UPOSStat.xsd"> <Event> <Parameter> <Name>RequestedStatistic</Name> <Value>1234</Value> </Parameter> </Event> <Equipment> <UnifiedPOSVersion>1.10</UnifiedPOSVersion> <DeviceCategory UPOS="CashDrawer"/> <ManufacturerName>Cashdrawers R Us</ManufacturerName> <ModelName>CD-123</ModelName> <SerialNumber>12345</SerialNumber> <FirmwareRevision>1.0 Rev. B</FirmwareRevision> <Interface>RS232</Interface> <InstallationDate>2000-03-01</InstallationDate> </Equipment> </UPOSStat>Si la aplicación solicita un nombre estadístico que el dispositivo no admite, la
<Parameter>entrada se devolverá con un vacío<Value>. Por ejemplo:<Parameter> <Name>RequestedStatistic</Name> <Value></Value> </Parameter>Todas las estadísticas que recopila el dispositivo que son específicas del fabricante y no definidas en el esquema se devolverán en una
<ManufacturerSpecific>etiqueta en lugar de una<Parameter>etiqueta. Por ejemplo:<ManufacturerSpecific> <Name>TheAnswer</Name> <Value>42</Value> </ManufacturerSpecific>Cuando una aplicación solicita todas las estadísticas del dispositivo, el dispositivo devuelve una
<Parameter>entrada para cada estadística definida en la categoría de dispositivo. La categoría de dispositivo se define mediante la versión del esquema XML especificado por elversionatributo de la<UPOSStat>etiqueta . Si el dispositivo no registra ninguna estadística, la<Value>etiqueta estará vacía.
POS para .NET usa controladores para realizar la lectura y escritura de estadísticas de forma similar a la forma en que se controlan los eventos. Cuando se crea uno de estos controladores estadísticos, se asigna a una estadística de dispositivo determinada. Cuando se lee o actualiza esta estadística, el controlador llama a un delegado que puede leer o escribir en el dispositivo según sea necesario.
Los controladores estadísticos usan diferentes tipos de delegados para realizar diferentes operaciones de estadísticas. GetStatistic los delegados se usan para recuperar valores estadísticos, mientras que SetStatistic los delegados asignan valores estadísticos. Los delegados GetStatistics toman el nombre de la estadística que se va a recuperar como parámetro y devuelven una cadena que representa el valor de esa estadística. Los delegados SetStatistic toman el nombre de la estadística que se va a cambiar y el valor que se va a asignar a esa estadística como parámetros. Los delegados SetStatistic no devuelven ningún valor.
Los controladores de estadísticas se pueden asignar a cualquiera de las estadísticas estándar definidas por la especificación Unified Point Of Service (UnifiedPOS), pero también se admiten controladores personalizados para las estadísticas creadas mediante CreateStatistic by Service Object Code.
Example
En el ejemplo de código siguiente se muestra cómo habilitar, controlar y recuperar datos de estadísticas de un dispositivo MSR.
// File FORM1.CS
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.IO;
using Microsoft.PointOfService;
using Microsoft.PointOfService.BaseServiceObjects;
namespace Statistics
{
public partial class SampleStatistics : Form
{
// Indicates whether or not the Service Object has
// been started.
bool ServiceObjectStarted = false;
// The Service Object.
PosCommon so = null;
public SampleStatistics()
{
InitializeComponent();
// Disable the buttons until the SO is loaded successfully.
UpdateControls();
}
public void UpdateControls()
{
btnGenerateStatistics.Enabled = ServiceObjectStarted;
btnRetrieveStatistics.Enabled = ServiceObjectStarted ;
txtStatisticName.Enabled = ServiceObjectStarted;
// The statistic name text box is disabled until the
// Service Object is loaded.
if (ServiceObjectStarted)
{
btnStartSO.Text = "Close SO";
}
else
{
txtStatisticName.Clear();
txtRetrievedStatistics.Clear();
btnStartSO.Text = "Start SO";
}
// The retrieve one statistic button is disabled until
// the user has entered a statistic name.
if (txtStatisticName.TextLength > 0)
{
btnRetrieveStatistic.Enabled = true;
}
else
{
btnRetrieveStatistic.Enabled = false;
}
}
private void StartServiceObject(object sender, EventArgs e)
{
PosExplorer explorer = new PosExplorer(this);
string SOName = "SampleStatistics";
if (ServiceObjectStarted)
{
so.DeviceEnabled = false;
so.Close();
so = null;
ServiceObjectStarted = false;
UpdateControls();
}
else
{
foreach (DeviceInfo d in explorer.GetDevices())
{
if (d.ServiceObjectName == SOName)
{
try
{
// Standard Service Object startup.
so = explorer.CreateInstance(d)
as PosCommon;
so.Open();
so.Claim(0);
so.DeviceEnabled = true;
// Application-specific setup.
ServiceObjectStarted = true;
UpdateControls();
}
catch
{
// Something went wrong starting the SO
MessageBox.Show("The Service Object '" +
SOName + "' failed to load",
"Service Object Error",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
return;
}
break;
}
}
if (so == null)
{
// No Service Object with the
// specified name could be found.
MessageBox.Show("The Service Object '" +
SOName + "' could not be found",
"Service Object Error",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
}
}
}
private void GenerateStatistics(object sender, EventArgs e)
{
// In this example case, you use this
// property to tell the Service Object to change statistic
// values.
so.DeviceEnabled = true;
// Report status.
txtRetrievedStatistics.Text = "DeviceEnabled called to" +
" to modify statistic values.";
}
private void RetrieveStatistics(object sender, EventArgs e)
{
string statistics;
bool IsXml = true;
try
{
statistics = so.RetrieveStatistics();
}
catch
{
statistics = "No statistics found";
IsXml = false;
}
DisplayStatistics(statistics, IsXml);
}
private void RetrieveOneStatistic(object sender, EventArgs e)
{
string statistics;
bool IsXml = true;
try
{
statistics = so.RetrieveStatistic(
txtStatisticName.Text);
}
catch
{
statistics = "Statistic not found: " +
txtStatisticName.Text;
IsXml = false;
}
DisplayStatistics(statistics, IsXml);
txtStatisticName.Clear();
btnRetrieveStatistic.Enabled = false;
}
private void StatisticSizeChanged(object sender, EventArgs e)
{
if (txtStatisticName.TextLength > 0)
{
btnRetrieveStatistic.Enabled = true;
}
else
{
btnRetrieveStatistic.Enabled = false;
}
}
// When retrieving statistics, POS for .NET returns a block
// of XML (as specified in the UPOS specification). This
// method will make it look readable with white space
// and indenting and then display it in the text box.
private void DisplayStatistics(string inputString, bool isXml)
{
string s = null;
// In case of an exception, you do not have an XML
// string, so just display the error description. Otherwise,
// load the XML string into an XmlDocument object and
// make it look readable.
if (!isXml)
{
s = inputString;
}
if(isXml)
{
// Create new XML document and load the statistics
// XML string.
XmlDocument doc = new XmlDocument();
doc.LoadXml(inputString);
// Create a XmlTextWriter using a MemoryStream and
// tell it to indent the XML output (so that it is
// readable.)
MemoryStream m = new MemoryStream();
XmlTextWriter writer = new XmlTextWriter(m, null);
writer.Formatting = Formatting.Indented;
writer.Indentation = 4;
// Save the document to the memory stream using the
// XmlWriter.
doc.Save(writer);
// The stream will be encoded as UTF8, so convert the
// buffer into a string.
UTF8Encoding u = new UTF8Encoding();
s = u.GetString(m.GetBuffer());
}
// Write the string to the text box.
txtRetrievedStatistics.Text = s;
}
}
}
// File FORM1.DESIGNER.CS
namespace Statistics
{
partial class SampleStatistics
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnStartSO = new System.Windows.Forms.Button();
this.btnGenerateStatistics = new System.Windows.Forms.Button();
this.btnRetrieveStatistics = new System.Windows.Forms.Button();
this.txtStatisticName = new System.Windows.Forms.TextBox();
this.txtRetrievedStatistics = new System.Windows.Forms.TextBox();
this.btnRetrieveStatistic = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// btnStartSO
//
this.btnStartSO.Location = new System.Drawing.Point(45, 35);
this.btnStartSO.Name = "btnStartSO";
this.btnStartSO.Size = new System.Drawing.Size(133, 23);
this.btnStartSO.TabIndex = 0;
this.btnStartSO.Text = "Start SO";
this.btnStartSO.UseVisualStyleBackColor = true;
this.btnStartSO.Click += new System.EventHandler(this.StartServiceObject);
//
// btnGenerateStatistics
//
this.btnGenerateStatistics.Location = new System.Drawing.Point(45, 75);
this.btnGenerateStatistics.Name = "btnGenerateStatistics";
this.btnGenerateStatistics.Size = new System.Drawing.Size(133, 23);
this.btnGenerateStatistics.TabIndex = 1;
this.btnGenerateStatistics.Text = "GenerateStatistics";
this.btnGenerateStatistics.UseVisualStyleBackColor = true;
this.btnGenerateStatistics.Click += new System.EventHandler(this.GenerateStatistics);
//
// btnRetrieveStatistics
//
this.btnRetrieveStatistics.Location = new System.Drawing.Point(45, 117);
this.btnRetrieveStatistics.Name = "btnRetrieveStatistics";
this.btnRetrieveStatistics.Size = new System.Drawing.Size(133, 23);
this.btnRetrieveStatistics.TabIndex = 2;
this.btnRetrieveStatistics.Text = "Retrieve Statistics";
this.btnRetrieveStatistics.UseVisualStyleBackColor = true;
this.btnRetrieveStatistics.Click += new System.EventHandler(this.RetrieveStatistics);
//
// txtStatisticName
//
this.txtStatisticName.Location = new System.Drawing.Point(16, 68);
this.txtStatisticName.Name = "txtStatisticName";
this.txtStatisticName.Size = new System.Drawing.Size(205, 20);
this.txtStatisticName.TabIndex = 4;
this.txtStatisticName.TextChanged += new System.EventHandler(this.StatisticSizeChanged);
//
// txtRetrievedStatistics
//
this.txtRetrievedStatistics.BackColor = System.Drawing.Color.White;
this.txtRetrievedStatistics.Location = new System.Drawing.Point(45, 157);
this.txtRetrievedStatistics.Multiline = true;
this.txtRetrievedStatistics.Name = "txtRetrievedStatistics";
this.txtRetrievedStatistics.ReadOnly = true;
this.txtRetrievedStatistics.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtRetrievedStatistics.Size = new System.Drawing.Size(476, 247);
this.txtRetrievedStatistics.TabIndex = 5;
//
// btnRetrieveStatistic
//
this.btnRetrieveStatistic.Location = new System.Drawing.Point(16, 30);
this.btnRetrieveStatistic.Name = "btnRetrieveStatistic";
this.btnRetrieveStatistic.Size = new System.Drawing.Size(133, 23);
this.btnRetrieveStatistic.TabIndex = 6;
this.btnRetrieveStatistic.Text = "Retrieve Statistic";
this.btnRetrieveStatistic.UseVisualStyleBackColor = true;
this.btnRetrieveStatistic.Click += new System.EventHandler(this.RetrieveOneStatistic);
//
// groupBox1
//
this.groupBox1.Controls.Add(this.btnRetrieveStatistic);
this.groupBox1.Controls.Add(this.txtStatisticName);
this.groupBox1.Location = new System.Drawing.Point(219, 35);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(302, 105);
this.groupBox1.TabIndex = 7;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Single Statistic";
//
// SampleStatistics
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.MenuBar;
this.ClientSize = new System.Drawing.Size(565, 439);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.txtRetrievedStatistics);
this.Controls.Add(this.btnRetrieveStatistics);
this.Controls.Add(this.btnGenerateStatistics);
this.Controls.Add(this.btnStartSO);
this.Name = "SampleStatistics";
this.Text = "Form1";
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button btnStartSO;
private System.Windows.Forms.Button btnGenerateStatistics;
private System.Windows.Forms.Button btnRetrieveStatistics;
private System.Windows.Forms.TextBox txtStatisticName;
private System.Windows.Forms.TextBox txtRetrievedStatistics;
private System.Windows.Forms.Button btnRetrieveStatistic;
private System.Windows.Forms.GroupBox groupBox1;
}
}
// File STATISTICSSO.CS
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.PointOfService;
using Microsoft.PointOfService.BaseServiceObjects;
[assembly: PosAssembly("Service Object Contractors, Inc.")]
namespace SOSamples.Statistics
{
[ServiceObject(DeviceType.Msr,
"SampleStatistics",
"Sample Statistics Service Object",
1,
9)]
public class StatisticsTest : MsrBase
{
// This will be incremented every time DeviceEnabled
// is set so that different sets of demonstration
// statistics can be generated.
int enableCount = 0;
// The name of a custom created statistic used to demonstrate
// custom Statistic handlers.
private const string PollingStatistic = "Polling Interval";
// Statistic used to demonstrate IncrementStatistic.
private const string TestIncrement = "MyIncrementableStat";
// String returned from CheckHealth
private string MyHealthText;
public StatisticsTest()
{
DevicePath = "Sample Statistics";
}
// This is the delegate which will be called for each
// statistic that we have associated with this delegate by
// calling SetStatisticHandler().
//
// Delegates like this should most commonly be used
// to get and set statistics in hardware. The delegate
// allows the POS for .NET statistic subsystem to query
// the value of a statistic in real time, before it is
// returned to the application.
private string GetHardwareInfo(string name)
{
// Add your code to query values from hardware here.
// Very simple demonstration: just return the name
// of the statistic as its value;
return name;
}
// In a typical Service Object implementation, statistics
// will be modified throughout the Service Object code. This
// method demonstrates the methods used to modify statistic
// values.
public void SetDemonstrationStatistics()
{
// IncrementStatistic can be used to easily
// increment a numeric statistic.
IncrementStatistic(TestIncrement);
switch(enableCount)
{
case 0:
SetStatisticValue(StatisticManufacturerName,
"Microsoft Corporation");
break;
case 1:
SetStatisticValue(StatisticManufacturerName,
"Service Control Contractors, Inc.");
break;
case 2:
SetStatisticValue(StatisticManufacturerName,
"Point of Service Controls .com");
break;
}
if (++enableCount == 3 )
{
enableCount = 0;
}
}
#region PosCommon overrides
// Returns the result of the last call to CheckHealth()
public override void Open()
{
base.Open();
// In your implementation of Open(), your Service Object
// code should:
// 1. Initialize statistics.
// 2. Create custom statistics.
// 3. Set statistic handlers for hardware Statistics.
// 1. Initialize statistics
SetStatisticValue(StatisticManufacturerName,
"Microsoft Corporation");
SetStatisticValue(StatisticManufactureDate,
"2004-10-23");
SetStatisticValue(StatisticModelName,
"Statistic Sample");
SetStatisticValue(StatisticMechanicalRevision,
"1.0");
SetStatisticValue(StatisticInterface,
"USB");
// 2a. Create a new statistic to test Increment
// method. No custom handler needed.
CreateStatistic(TestIncrement, false, "blobs");
// 2b. Create a new manufacturer statistic to demonstrate
// custom attributes with StatisticHandlers.
CreateStatistic(PollingStatistic, false,
"milliseconds");
// 3. Set handlers for statistics stored in hardware.
SetStatisticHandlers(PollingStatistic,
new GetStatistic(GetHardwareInfo), null);
SetStatisticHandlers(StatisticSerialNumber,
new GetStatistic(GetHardwareInfo), null);
}
public override bool DeviceEnabled
{
get
{
return base.DeviceEnabled;
}
set
{
// This method will set various statistics to
// demonstrate the statistic APIs. We are going
// to change statistic values every time the device
// is enabled. This operation is just for
// demonstration and would not be found in live code.
SetDemonstrationStatistics();
base.DeviceEnabled = value;
}
}
public override string CheckHealthText
{
get
{
// MsrBasic.VerifyState(musBeClaimed,
// mustBeEnabled). This may throw an exception
VerifyState(false, false);
return MyHealthText;
}
}
public override string CheckHealth(
HealthCheckLevel level)
{
// Verify that device is open, claimed, and enabled.
VerifyState(true, true);
// Your code here:
// check the health of the device and return a
// descriptive string.
// Cache result in the CheckHealthText property.
MyHealthText = "Ok";
return MyHealthText;
}
public override DirectIOData DirectIO(
int command,
int data,
object obj)
{
// Verify that the device is open.
VerifyState(false, false);
return new DirectIOData(data, obj);
}
#endregion PosCommon overrides
#region MsrBasic Overrides
protected override MsrFieldData ParseMsrFieldData(
byte[] track1Data,
byte[] track2Data,
byte[] track3Data,
byte[] track4Data,
CardType cardType)
{
// Your code here:
// Implement this method to parse track data
// into fields which will be returned as
// properties to the application (e.g.,FirstName,
// AccountNumber, etc.)
return new MsrFieldData();
}
protected override MsrTrackData ParseMsrTrackData(
byte[] track1Data,
byte[] track2Data,
byte[] track3Data,
byte[] track4Data,
CardType cardType)
{
// Your code here:
// Implement this method to convert raw track data.
return new MsrTrackData();
}
#endregion MsrBasic Overrides
}
}
Compilar el código
- Para obtener más información sobre cómo crear y compilar un proyecto de objeto de servicio, vea Ejemplos de objetos de servicio: Introducción.