Ralf Hohoff

Geräteinformationen von Dell automatisch auslesen

Die Informationen über auslaufende Service-Verträge gelangten recht schwach strukturiert in unser Unternehmen und dies war seitens Dell auch nicht einfach änderbar. Der Abruf dieser und weiterer Informationen wie Gerätedaten über den Dell-Kundenbereich gestaltete sich auch als schwierig, weil das Dateiformat geändert wurde und Datumsangaben mal im deutschen und mal im amerikanischen Format angegeben wurden (in einer Spalte!).

Eine zentrale Verwaltung der Informationen in einer Datenbank und das automatische Aktualisieren der Gerätedaten musste her. Nach einiger Suche habe ich herausgefunden, dass es eine API gibt, die aber Probleme bereitet.

Hilfreich waren PHP: Querying Dell AssetService webservice to retrieve asset information und Get Dell System Warranty with PowerShell.

Ich habe erst versucht, die Daten mit Pentaho Data Integration direkt über den Webservice-Aufruf die Daten auszulesen. Das scheiterte, weil die im WSDL-File angegebene Adresse http://support.dell.com/WebServices/GetAssetInformation für die Funktion “GetAssetInformation” nicht verfügbar war. Wenn man diese Adresse durch http://xserv.dell.com/services/AssetService.asmx überschreibt, erhält man die Daten. Das “Überschreiben” ging nicht in Pentaho Data Integration und deshalb habe ich das mit PHP gemacht. Das PHP-Skript wird mit dem Service-Tag aufgerufen und gibt die Informationen im JSON-Format zurück.

$DELL_URL = "http://xserv.dell.com/services/assetservice.asmx?WSDL";
$soap = new SoapClient($DELL_URL, array('soap_version' => SOAP_1_2));
 
// Location muss überschrieben werden, weil die Url (die im WSDL angegeben wird!) nicht mehr korrekt ist!
// http://www.scconfigmgr.com/2013/06/23/get-dell-system-warranty-with-powershell/
$soap->__setLocation('http://xserv.dell.com/services/AssetService.asmx');
 
$tag = $_GET['ServiceTag'];
$response = $soap->GetAssetInformation(
	array(
	"guid" => "11111111-1111-1111-1111-111111111111",
	"applicationName" => "AssetService",
	"serviceTags" => $tag
	)
);
echo json_encode($response, JSON_PRETTY_PRINT);

Das Pentaho-Skript liest alle Service-Tags aus der Datenbank, ruft die PHP-Seite parametrisiert mit dem Service-Tag auf, verarbeitet das zurückgegebene JSON-Format und speichert die Informationen in der Datenbank.

Dell Servive-Tags auslesen

 

JSON-Beispiel für Service-Tag “4FL45W1”

{
    "GetAssetInformationResult": {
        "Asset": {
            "AssetHeaderData": {
                "ServiceTag": "4FL45W1",
                "SystemID": "optiplex-9010-aio",
                "Buid": "8270",
                "Region": "Asia \/ Pacific",
                "SystemType": "OptiPlex",
                "SystemModel": "OptiPlex 9010 All In One (Mid 2012)",
                "SystemShipDate": "2012-12-12T13:00:00-06:00"
            },
            "Entitlements": {
                "EntitlementData": [
                    {
                        "ServiceLevelCode": "HDD",
                        "ServiceLevelDescription": "For Non Returnable HDD",
                        "Provider": "",
                        "StartDate": "2012-12-12T00:00:00",
                        "EndDate": "2015-12-13T00:00:00",
                        "DaysLeft": 88,
                        "EntitlementType": "Active"
                    },
                    {
                        "ServiceLevelCode": "AD",
                        "ServiceLevelDescription": "Accidental Damage Service",
                        "Provider": "",
                        "StartDate": "2012-12-12T00:00:00",
                        "EndDate": "2015-12-13T00:00:00",
                        "DaysLeft": 88,
                        "EntitlementType": "Active"
                    },
                    {
                        "ServiceLevelCode": "NBD",
                        "ServiceLevelDescription": "Next Business Day response",
                        "Provider": "",
                        "StartDate": "2013-12-13T00:00:00",
                        "EndDate": "2015-12-13T00:00:00",
                        "DaysLeft": 88,
                        "EntitlementType": "Active"
                    },
                    {
                        "ServiceLevelCode": "POW",
                        "ServiceLevelDescription": "Parts Only Warranty",
                        "Provider": "",
                        "StartDate": "2013-12-13T00:00:00",
                        "EndDate": "2015-12-13T00:00:00",
                        "DaysLeft": 88,
                        "EntitlementType": "Active"
                    },
                    {
                        "ServiceLevelCode": "NBD",
                        "ServiceLevelDescription": "Next Business Day response",
                        "Provider": "",
                        "StartDate": "2012-12-12T00:00:00",
                        "EndDate": "2013-12-13T00:00:00",
                        "DaysLeft": 0,
                        "EntitlementType": "Expired"
                    },
                    {
                        "ServiceLevelCode": "POW",
                        "ServiceLevelDescription": "Parts Only Warranty",
                        "Provider": "",
                        "StartDate": "2012-12-12T00:00:00",
                        "EndDate": "2013-12-13T00:00:00",
                        "DaysLeft": 0,
                        "EntitlementType": "Expired"
                    }
                ]
            }
        }
    }
}

Es geht so einfach: mehrere Excel-Dateien auf einmal einlesen!

Für einen Import musste ich auf Excel als Datenquelle zurückgreifen und das mache ich nicht gerne 😉 Aber die Daten lagen nun mal nicht in einer Datenbank vor.

Da beim täglichen Import nicht nur eine sondern auch mehrere Dateien bereitliegen konnten, wollte ich – recht umständlich – eine Schleife bauen, die die Dateien nacheinander einliest und den Datenstrom aufbaut.

Das ist aber nicht notwendig, das kann der “Microsoft Excel Input” auch ganz alleine schon!

Ich habe nur noch das Verzeichnis und einen regulären Ausdruck “.*\.xlsx$” angegeben, dann werden alle Excel-Dateien eingelen und in einen Datenstrom überführt. Die Excel-Dateien können unterschiedlich benannt sein, die Datenstruktur (Spalten) muss natürlich identisch sein.

Excel_Input_Regex

Delete Firefox auto-complete entries

Mit Shift und Delete können Fehleingaben durch dicke Finger wieder aus Firefox-Vorschlagslisten entfernt werden:

You once fat-fingered your login name to a web site and now Firefox suggests the typo every single time in the auto-complete dropdown. So annoying! But the Captain’s Universe web site has a quick tip on how to delete the bad suggestions:

Just start to type in into the form field until the grey dropdown appears, then use the cursor keys to move to the entry to be deleted and press the SHIFT key and the delete key. Voila!

von Delete Firefox auto-complete entries

The New Open Source CRM: Gamified, Mobile, Social

Ein guter alter Ex-Kollege hat mich auf Zurmo CRM aufmerksam gemacht.

The New Open Source CRM: Gamified, Mobile, Social.

Zurmo is an Open Source Customer Relationship Management (CRM) application that is mobile, social, and gamified. We use a test-driven methodology for building every part of the application. This means you can create and maintain a custom-built CRM system or platform with the assurance that future updates are not going to break your installation. Head over to the forums to learn more.

Sieht vielversprechend aus, sollte man weiter beobachten. Und die Tools sind im Vormarsch, die einfach in der Bedienung sind – vielfach ist weniger mehr: Lieber 70% Funktionalität, die stabil laufen und einfach zu bedienen sind, als 95 % unbeherrschbare Applikation (Systemkomplexität, Abhängigkeiten, Bedienung, Schulung,…)

Cannot modify header information

Bei der Umsetzung für ein CRM-Projekt erhielt ich die Fehlermeldung “Cannot modify header information – headers already sent by…”.
Die einschlägige Google-Suche brachte folgende Ergebnisse:

The problem? White space after the closing ?> PHP tag. You can have as many carriage returns as you like, but don’t try a space.

This error occurs if there is any output before calling header() function. The most common and mostly “invisible” mistake is having whitespaces at the beginning or the end of one or more of your files. Make sure there are none before opening < ?php or after closing ?> tags.

Das war’s aber nicht, die Lösung war die UTF-Codierung des Quellcodes:

Another very common problem is extra whitespace at the *start* of php files – especially editors inserting invisibly UTF BOM bytes. If you want to make a maintenance tool, it would be good to check for this issue too.

In diesem Fall ist die PHP-Datei in UTF-8-Codierung abgepeichert und enthält ein “Byte Order Mark” (kurz: BOM). Das BOM-Steuerzeichen wird von PHP falsch erkannt, weshalb man für diese Datei “UTF-8 ohne BOM” als Kodierung wählen muss.

Danach funktioniert’s!

SQL mit CakePHP und der Bedingung NOT IN

$this->set('agents',$this->Contract->User->find('list',array(
			'fields' => array('User.id','User.username'),
			'conditions' => array(
						'User.active =' => '1',
						'NOT' => array(
							'User.username' => array('admin',$this->Auth->user('username'))
							))
			))
);

Which produces the following:

SELECT `User`.`id`, `User`.`username` FROM `users` AS `User` WHERE  `User`.`active` = 1 AND NOT (`User`.`username` IN ('admin', 'user'))

Quelle: http://cakebaker.42dh.com/2007/04/26/how-to-use-not-in-in-a-condition/

Ganz schön komfortabel aber auch tricky, wenn man diesen Weg nicht kennt 😉

Regular Expression für Wildcards in pdi

In einigen Transformations- und Jobschritten, insbesondere die die Handhabung von Dateien umsetzen, gibt es die Möglichkeit, Wildcards anzugeben. Aber natürlich gleich in der mächtigen Variante: Wildcard als Regulärer Ausdruck (Regular Expression)!

Wie es geht wird auf How to process a Kettle transformation once per filename beschrieben

The correct regex to get all files whose extension is .xml is ”.*\.xml”. This isn’t a regex tutorial, go look that up on the web.

Bitte die Anführungszeichen nicht mit angeben, für Excel-Dokumente lautet das z.B.  “.*\.xlsx” oder “.*\.xlsx$”, wenn man das konkret auf das Zeilen- oder Stringende prüfen will.

Hilfreich bei der Erstellung von Regulären Ausdrücken ist auch der Online Regular Expression Builder

Einlesen von Verzeichnissen

Auch dasEinlesen von Verzeichnissen nutzt reguläre Ausdrücke, nachfolgend ein Beispiel mit der Transformation Get File Names

 

How to process a Kettle transformation once per filename