XKCD – Open Letter

Uncategorized — Jeff Eske on October 7, 2013 at 8:27 am
XKCD Comic - Oct. 7, 2013

Source: http://xkcd.com/1274/

Amen…

Although I’m not sure how much control Exxon has anymore.

Jeff

Javascript – Submitting a form by hitting “Enter”

Programming,Snippets — Jeff Eske on September 6, 2013 at 9:41 am

I’m working within a commercial web-based application that uses a lot of forms, none of which can be submitted by simply hitting the Enter key.  Users were wanting to be able to at least submit a particular search form by simply hitting Enter, rather than having to click the “Search” button, so I decided to do some checking.  I found a pretty simple javascript function that can handle what I need done.  Basically, it watches key presses and when it sees the Enter key pressed (keyCode 13) it runs my search function (some_function_here).  The nice thing is that the default Search button is still available and works the same as always.

Simply add this code to the HEAD code on your page, and change the actions within the if statement to match what the current button does “onClick” and you should be good-to-go.

[code]

<script language=”Javascript”>
function detectEnterKey(e) {
var evt = e || window.event;
if(evt.keyCode == 13){
some_function_here();
}
return document.defaultAction;
}
document.onkeypress=detectEnterKey
</script>

[/code]

 

Jeff Eske

Carb Upgrade – Rejetting

< 4 Wheels — Jeff Eske on June 24, 2013 at 2:15 pm

Finally had time this weekend to re-jet the carburetor on my 2001 Sportster 1200 Custom (XL1200C).  I’m now up to about a Stage .5, since all I’ve done is some minor carb work.  I haven’t replaced the air cleaner with a high-flow unit or replaced the stock pipes yet.  Turns out that I received the wrong intake gaskets, so I wasn’t able to replace them.  I don’t know if I ordered the wrong ones or if they pulled the wrong ones.  It doesn’t really matter at this point, since I was just going to replace them as a precautionary measure.

I love how straightforward and easy the Keihin carb is to work on.  It reminds me of my days as an auto mechanic, back in the 80s; fuel injection was just beginning to take over on new cars and there were still as many carbureted cars coming into the shop as there were FI cars.  I also like only having one carb for multiple cylinders, like a car, so that you don’t have to deal with carb syncing, etc.  On my past import (Japanese) bikes, carb syncing was a pain in the @$$.

Anyway, the Dynajet kit went in with no issues.  I stuck to the 160 main jet, that they recommend for stock setups.  While I was in there, I also replaced the stock .42 pilot jet with a .45.  I don’t know if it’s the dynajet kit or the pilot jet, but seat-of-the-pants testing would indicate a fair improvement in low-end driveability.  Previously, it seemed kind of starved when trying to accelerate.  Now, it just seems to have more “oomph” when I hit the throttle.

Hopefully, soon I’ll be able to spring for a higher flow A/C, and may re-route the crankcase ventilation while I’m at it.  I’m not sure what to do with the exhaust at this point.  I’m a fan of “rumble”, but not “loud and obnoxious”.  We’ll see.

Jeff Eske

OTRS – Manuallly Importing CMDB Items

OTRS — Jeff Eske on June 19, 2013 at 7:56 am

UPDATED:  I’ve changed employers and have moved on to other projects.  I no longer use OTRS, or have access to OTRS, so I won’t really be able to help you beyond what I’ve already posted here. 

Jeff

I’ve seen the number of people looking at my short entry dealing with importing items into OTRS’s CMDB, so I thought I’d expand on that a bit.  I’ll go ahead and give a slight overview, then provide a quick-and-dirty description of how to manually import items into the CMDB.  Later, when time permits, I’ll add a better explanation of how to automate the import process.  I may clean this up at a later time, bur for now, I want to get down the basics.

You can manually import CMDB items (computers, software, etc.) into OTRS using the Import/Export function, via the web interface.  There is also a way that you can automatically import items, via cron and the commandline.  I have a brief overview of that here, but will create a more complete explanation at a later time.  First things first though; you have to do the steps below anyway, before you can automatically import items.  You have to have the import template created in order to automate the process, since the automation uses an existing template.

Overview

To create the template, we’ll need to identify what we’re importing, the delimiter, and the CMDB columns to be included.  In my example, I’m importing desktop computers, the file is a comma-delimited format, and I’ll be submitting the minimum required fields.

Required Fields
What I mean by minimum required fields is that OTRS has a small number of fields within a CMDB record that have to be filled in.  If you go into the CMDB section online and manually add an item, you can see what the requried fields are; they’ll be marked with an asterisk (star).  For my desktop computer import, I’ll need to AT LEAST provide: Computer Name,  Deployment State, Incident State, Network Adapter  1(NIC1), and whether it gets IP over DHCP.

Creating an Import Template

So, here’s a quick-and-dirty rundown of how to setup an import template.  The values that are shown in the images below SHOULD get you a working template.  You will however, probably want to edit the values to more precisely match what you need.  As always, please read my disclaimer before proceeding.

1> Goto: Admin -> System Administration -> Import/Export

Import/Export Link Location

 

2> On the Import/Export Management screen, click the “Add Template” button.

Import Template - Add Template

 

3> Set the values in the Step 1 screen

Import Template - Step 1

Name: Name of your new template
Object: The object type
Format: format of the import data
Valid: set it as valid, if you want to be able to use the template…

 

4> When finished, click Next

 

5> Set the values in the Step 2 screen

Import Template - Step 2
Class: whatever type of import it will be – this affects what elements show up later.
Maximum number of one element: Not sure what this does 🙂
Empty field means keep value:  This will leave existing data, rather than “blanking” it out.

6> When finished, click Next

 

7> Set the values in Step 3 screen

Import Template - Step 3
Column Separator: The separator used in your import file.
Include Column Headers: That’s up to you.  I do “No”

 

8> When finishd, click Next

 

9> Add mapping elements

Import Template - Step4

There are a few things to note when adding elements:

1> Click “Add Mapping Element” to add a line for each field that is in the import file.
2> Add an entry for EVERY field in the import file, in the order they exist in the file.
3> There are some REQUIRED fields.  These fields have to exist in the import file, and have valid values, in order for the record to import.  The required fields are: Name,Deployment State, Incident State,NIC1,IP over DHCP
Name,Vendor,Model,OS,NIC-IP

 

10> When finished adding elements, click Next

 

11> Fill in search criteria to be used for exporting (optional)

Import Template - Step 5

You don’t really need to do anything with this, if you’re only planning on importing items.

12> If/when you finish adding search criteria, click Finish

 

13> Note the number of the template that you just created

List of Existing Templates

This should bring you back to Import/Export Management page that shows a listing of the existing Import/Export templates.  You should see your newly created template listed there.  Note the Number of your template, since this is what will be used to automate the import.

To actually import items, you’ll simply click on the “Import” link for the appropriate import template, select the source file with all of the records in it, and hit the “Import” button.  When it finishes, it will give you Summary page which indicates total records, successes, and failures.

 

 

Carb Tuning

Uncategorized — Jeff Eske on June 13, 2013 at 3:58 pm

The Sporty doesn’t seem to be getting enough gas to idle, if I push the choke all the way in, even after it’s warmed up.  That would lead me to believe that it’s probably running lean on idle.  When I went to reset the idle, I found out that the little anti-tamper plug had already been removed by someone.  That makes things easier for me.  The interesting thing is there are only 10k miles on the thing, with 8k of those coming from my brother-in-law and he claims no one has done any carb/tuneup work on the bike since he’s had it.  He said the the previous guy bought a jet kit, but chickened out and didn’t put it in.  I’m guessing that he probably went so far as to drill out the plug, but not do the jets.  I still have the jet kit, plus I ordered a .45 pilot jet from J&P Cycles, so if/when I install those, I’ll see if everything is still stock on the inside.

I also ordered new intake and carb gaskets from J&P Cycles, since I’ve seen on the forums that those are only good for a few riding seasons before they dry up.  If they’re dried up, they could be leaking and leaning things out some.  I guess we’ll see once I get the parts and pull things apart.

Jeff Eske

“New” Motorcycle!

< 4 Wheels — Jeff Eske on June 12, 2013 at 9:59 am

I got a “new” motorcycle over the weekend.  It’s a used 2001 Harley-Davidson XL1200C Sportster.  I wasn’t really in the market for a motorcycle, but the deal was too good to pass up.  My brother-in-law was interested in selling it, and he gave me a good deal on it.  It’s low miles (10k) and basically stock.

I’ve owned a few motorcycles over the years, but they’ve always been “vintage” japanese machines.  The Sporty is the closest I’ve come to a new bike.  All of the others basically required some resuscitation in order to be ride-able.   I previously owned a 60s Suzuki 250cc two-cycle Scrambler, a ’76 Kawasaki KZ900 (the original superbike!), a 70s Suzuki 750 ( a top-heavy pig), and an ’87 Yamaha Virago 1100.

The Sporty is taking a while to get used to.  Like the Suzuki 750, it seems like it’s slightly top-heavy.  In addition to that, it has a somewhat stretched fork so, when turning, the frontend wants to “fall” in the direction you’re turning.  Basically, when you start to turn, the handlebars really want to turn all the way in that direction.  I rode my other brother-in-law’s Heritage Softtail and, even though it’s a lot heavier bike, it doesn’t feel as top-heavy and the steering feels “lighter”.  These things aren’t deal-breakers, they’re just differences that I’ve noticed between the Sportster and the other bikes that I’ve ridden.

More to come, as it happens.

Jeff Eske

Microsoft Office365 is more popular than almost everything

Web Stuff — Jeff Eske on May 30, 2013 at 11:16 am

Office365 is more popular than just about everyone except for Instagram.  Sort of.  According to Microsoft.

http://blogs.office.com/b/office-news/archive/2013/05/29/thanks-a-million.aspx

My Hobby is Post-Apocalyptic Doomsday Gold

General — Jeff Eske on March 27, 2013 at 4:14 pm

It appears that, according to National Geographics “Doomsday Preppers” infographic (see the graphic and a link to the site below), my leatherworking hobby would put me in the top 10 Most Valuable Professions. You have to look pretty hard to find it (HINT: As far down and to the right as you can go).

Would You Survive Doomsday? An Infographic – Nat Geo TV Blogs

Infographic from National Geographic

Infographic from National Geographic

OTRS – Parsing Out the Variables in a SOAP Response

OTRS,Programming,Snippets,Web Services,Web Stuff — Jeff Eske on March 5, 2013 at 5:16 pm

Unlike some web services, the OTRS web services don’t return the values in specific xml tags; it uses generic “s-gensym” tags.  Also, it returns field name within a set of generic tags, followed by the field value in a set of generic tags.  Here’s part of the SOAP response:

<s-gensym1558 xsi:type="xsd:string">PriorityID</s-gensym1558>
<s-gensym1560 xsi:type="xsd:int">3</s-gensym1560>
<s-gensym1562 xsi:type="xsd:string">ServiceID</s-gensym1562>
<s-gensym1564 xsi:type="xsd:string" />
<s-gensym1566 xsi:type="xsd:string">Type</s-gensym1566>
<s-gensym1568 xsi:type="xsd:string">Failure</s-gensym1568>

Makes a lot of sense, doesn’t it?  Here’s an example of one that actually uses the field name as the enclosing tag name.  It makes it easier to understand:

<fusion:ServiceDown><fusion:v>false</fusion:v></fusion:ServiceDown>
<fusion:BusinessUnit><fusion:v>Some Business Unit</fusion:v></fusion:BusinessUnit>

In this example, you can see that the ServiceDown field(fusion:ServiceDown) has a value(fusion:v) of “false”.  With OTRS, every time you run your SOAP request, you some random-ass “s-gensym” field name for everything.

To actually pull the SOAP response data out, you can use a foreach() loop and dump the field names and values into a more useful array.  In addition to that, the array will be setup as a key/value pair, so you can actually get the field value by referring to the field name.  I’m sure that there’s a much better, more elegant method to do the same thing, but this way works.  First the code, then an explanation of what’s going on:

[code]
$ticketInfo = array();
$i = 0;
foreach ($TicketDetails as $name => $value){ 
 if (false !== strpos($name, "s-gensym")){
 $temp[$i] = $value; 
 $v = $temp[$i-1]; 
 if($i % 2 != 0){ 
 $ticketInfo[$v] = $value; 
 }
 $i++;
 }
}
[/code]

Basically, what this code does is take your SOAP response array ($ticketInfo) and run it through a foreach() loop.  The OTRS SOAP response includes to entries for each field.  The first entry is the field name and the second entry is the field value.  So, what I want to do is combine both entries into a key->value pair in an array.

The foreach() explodes the values of the s-gensym variables out and adds the value to 2 different arrays.  This is where the elegance is definitely lacking.  I’m first saving the value into the $temp[] array to refer back to it later.  Then, if the row is divisble by two – basically every other, or every second row, I grab the previous value from temp[] and write it to $ticketInfo[] as the key and write the current value as the value.  What I end up with in the end is an array ($ticketInfo[]) that has the field name as the key and the field value as the value.

You can then pull the desired value by referring to the appropriate key, such as:

$ticket_age = $ticketInfo[Age];
$ticket_title = $ticketInfo[Title];

A simple way to print out all of the values in your array is, again, with the foreach() loop.  All you need is this little piece of code:

[code]
foreach ($ticketInfo as $name => $value){
 echo "<b>".$name.":</b> ".$value."<br>";
}
[/code]

The foreach() will loop through the array and explode out the key/value pairs, then echo them out.  It can be handy for troubleshooting, to see what everything actually looks like in the array.

Jeff Eske

OTRS – Web Services Descriptions and Examples

OTRS,Web Services,Web Stuff — Jeff Eske on March 5, 2013 at 4:47 pm

The OTRS ticketing system comes with some basic web service functions included by default.  I’ve already done a post about using web services to create a new ticket via TicketCreate(), as well as a post about retrieving an existing ticket via TicketGet().  I’ve also created a page to allow you to search for a ticket using the TicketSearch() function, but I haven’t posted anything about that yet.  I’ve also posted a code snippet that actually helped me considerably when I was troubleshooting exactly what was going on.

What I’d like to do here is just note some observations that I’ve made while messing around trying to figure all of this out.  Hopefully it will be of some use to someone.  As with everything on this site, the Disclaimer holds here to – all I can guarantee is that this stuff worked for me.  What I have listed below is what I’ve determined from trial-and-error, so take it with a grain of salt.  This is almost more to document it for myself than anyone else.

===============

TicketCreate()
Purpose:
Used to create new tickets object (duh!).  Generally, you’ll want to do an ArticleCreate() also, to add some useful information to the ticket.
Required Input Values: TypeID(integer), QueueID(integer), LockID(integer), PriorityID(integer), State(text), CustomerUser(text), OwnerID(integer), UserID(integer).
Optional, but Recommended: Title(text). The title is required, but it seems logical to add one.
Returns: TicketID(integer)

[code]
// PHP code sample for TicketCreate().  Adjust the values as necessary
$TicketID = $client->__soapCall(
 "Dispatch",array($username, $password,
 "TicketObject", "TicketCreate",
 "Title", "Some Title",
 "TypeID", some_typeID_number,
 "QueueID",  some_queueID_number,
 "LockID", 1,
 "PriorityID", some_priorityID_number,
 "State", "new",
 "CustomerUser", "some_user@your_organization",
 "OwnerID", some_ownerID_number,
 "UserID", some_userID_number,
 )
 );
[/code]

===============

ArticleCreate()
Purpose: Add an article to a ticket.  The TicketCreate() function basically just creates a “wrapper” for articles.  The articles provide the content.
Required Input Values: TicketID(integer), ArticleType(text), SenderType(text), HistoryType(text), HistoryComment(text), ContentType(text), UserID(integer)
Optional, but Recommended: From(text), Subject(text), Body(text), Loop(integer), AutoRepsonseType(text), OrigHeader(array)
Returns: ArticleID(integer)

[code]
// PHP code sample for ArticleCreate().  Adjust the values as necessary
$ArticleID = $client->__soapCall("Dispatch", 
array($username, $password,
"TicketObject", "ArticleCreate",
"TicketID", some_ticketID_to_add_article_to,
"ArticleType", "webrequest",
"SenderType", "customer",
"HistoryType", "WebRequestCustomer",
"HistoryComment", "created from PHP",
"From", "some_customer@your_organization",
"Subject", "Some Subject",
"ContentType", "text/plain; charset=ISO-8859-1",
"Body", "Some Article Body text",
"UserID", some_userID_number,
"Loop", 0,
"AutoResponseType", 'auto reply',
"OrigHeader", array(
'From' => 'some_customer@your_organization',
'To' =>  'some_customer@your_organization',
'Subject' => 'Some Subject.  Probably the subject from above',
'Body' => 'Some Body text.  Probably the body from above'
),
)
);
[/code]

===============

TicketGet() 
Required Input Values: TicketID(integer)
Returns: Array of Age(integer), PriorityID(integer)ServiceID(integer), Type(text), Responsible(text), StateID(integer), ResponsibleID(integer), ChangeBy(integer), EscalationTime(integer), Changed(date/time), OwnerID(integer), RealTillTimeNotUsed(integer), GroupID(integer), Owner(text), CustomerID(text), TypeID(integer), Created(date/time), Priority(text), UntilTime(integer), EscalationUpdateTime(integer), QueueID(integer), Queue(text), State(text), Title(text), FirstLock(date/time), CreateBy(integer), TicketID(integer), StateType(text), EscalationResponseTime(integer), UnlockTimeout(integer), EscalationSolutionTime(integer), LockID(integer), TicketNumber(integer), ArchiveFlag(text), CreateTimeUnix(unixtime), Lock(text), SLAID(integer), CustomerUserID(text)

[code]
// PHP code sample for TicketGet().  Adjust the values as necessary
$TicketDetails = $client->__soapCall("Dispatch", 
array($username, $password,
"TicketObject", "TicketGet",
"TicketID", some_ticketID_number,
"Extended", 1,
));
[/code]

===============

TicketSearch()
Required Input Values: CustomerUserID(text)
Returns: Array of TicketID(integer), TicketNumber(integer)

[code]
// PHP code sample for TicketSearch().  Adjust the values as necessary
$TicketDetails = $client->__soapCall("Dispatch", 
array($username, $password,
"TicketObject", "TicketSearch",
"CustomerUserID", "some_customers_login",
));
[/code]

One additional thing to note.  Both of the last two functions return arrays of values, rather than a single value.  You might want to look at my post about how to parse the values into a usable array.

Jeff Eske

SEE ALSO:
OTRS – Simple Web Service Example Using PHP,

PHP Script to Display SOAP Requests and Responses,

OTRS – TicketGet() Web Service Example in PHP

« Previous PageNext Page »
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 License. | Jeff's Blog