Sunday, October 28, 2012

Cisco VPN Client 5 Connection issue on Windows 8

After installing Windows 8, I was setting up the new OS for work, play and development. Almost everything went without any issues, except - when I tried connecting through Cisco VPN, I got an error message :


"Reason 442 : Failed to enable Virtual Adapter"


Following are steps I took to solve the issue, and hope it works for you as well.


Warning: The solution involves editing windows 8 registry. Done the wrong way, editing the registry may cause your Win-8 to become unstable, and you may need to re-install windows. Proceed with caution, and only if you know what you are doing.


1) On the "Run" dialog (Windows Key + R), type "regedit".



2) Go to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CVirtA


3) Double Click on "Display Name" string to edit it, and change it to "Cisco Systems VPN Adapter for 64-bit Windows"



4) Exit Regedit; Start Cisco VPN, and try to connect. It should work now!.


Good Luck!


References:


http://www.bidn.com/blogs/BradSchacht/ssis/3103/cisco-vpn-client-5-on-windows-8

Sunday, September 09, 2012

Joomla 2.5–Documenting the Basics!

 

Note: I'm trying out dictation to create blog posts. There may be errors in the post as I progress.

Joomla! is a powerful content management system (CMS), with backend technology as PHP. Joomla! can be utilized to create impressive websites and can be used to enable multiple people to collaborate and share information without having much knowledge of web development. Joomla! also features a powerful user access features enabling a website to have a public and private areas.

The initial learning curve for Joomla! is on the steep side, but once we get the hang of it, it becomes relatively straightforward.

Joomla! is backed by a number of third-party modules, plug-ins, and templates. These can be used to define the functionality of our website with little coding. At the same time, if there is a functionality that requires development, we can create our own plug-ins or modules as well. Custom user interface can be achieved by creating your own templates.

Before getting started with a Joomla! website, the first step is to plan the website properly. We should have an idea of how the website is going to be organized, what the menu structure would be, what kind of content is going to be displayed and what the target audience is.

The reason why we need this planning is because when creating content in Joomla!, we follow the “CAM” approach. The CAM stands for Category, Article, Menu. Content in Joomla! should be created strictly in this order. This is because an article should always be assigned to a category, and a menu to an article or a category.

image

 

Creating a new category using category manager

After logging in as admin,click on the category manager icon.On the top left,click on the new icon to open category editor.

image

Provide a category title, and select a parent category. It is the top-level category, and select parent as “No parent”. We will later and articles to this category.

Note that the alias will be auto created based on the title. Of course, we have the option of creating our own alias as well by typing in an alias.

Using Joomla!’s UAC (user access control), we can control the access permissions of this category. Basically the access permissions of a category gets applied to all articles assigned to this category. This can be overridden in an individual article.

image

Once all the information about a category has been entered, click on the save button at the top left hand corner.

 

Creating a new article and assigning it to a category

After logging in as admin, click on “Add New Article” button from the Control Panel. We can also use the menu path “Content –> Article Manager –> Add New Article”.

Give a title, and choose a category for this article. The importance of preplanning of site starts becoming apparent here. Without prior planning, the categories may not be in place and there will be confusion assigning articles to appropriate categories. Additionally, planning helps set access levels for the site users.

Use editor at the bottom of the page to create the page contents including graphics, links, page breaks …etc.

Click on the save button ones editing is complete.

image

 

Creating site menus

Till now whatever work was done on the site, that is, creation of categories and articles did not change anything on the site. This is because for the site to display content, it should be linked to a menu.

After logging in as admin, to create a new menu click on the menu manager button. Alternatively use the following menu path: “Menu –> Menu Manager”.

By default, a menu named “Main Menu” is already created and assigned to the site.

Click on “Main Menu” to open the menu for editing. Use the “new” button on top left to add a menu item.

To create a new menu, we have to specify the “Menu Item Type”. A menu can have multiple functionalities based on the chosen menu type. It can be linked to an individual article, an entire category, news feeds, contacts, and many more. The most basic menu is the link to an article. To do this, choose single article from the pop-up options after clicking on the select button.

image

Give a menu title, and in the required settings on right hand side, select an article to be displayed and clicking on the menu item.

Monday, September 03, 2012

Dividing and formatting long articles in Joomla!

Sometimes when creating Joomla! site there may be articles or pages with long content. However, we may be able to separate them into logical sections.

In Joomla!, we utilize page breaks between such logical sections, and we can configure the page break plug-in to modify its appearance and functionality.

Here are the steps to insert multiple page breaks into an article and modify the presentation of these page breaks.
1) To insert a page break inside an article, press the page break button at the bottom of the editor.
2) Repeat insertion of page breaks in the article where required, as shown in the below screenshot.
image
In the above screenshot, each of the horizontal line represents a page break I inserted in the article.
3) Next, go to Extensions –> Plug-in manager, and select the plug-in “Content – Pagebreak”, as shown below.
image
4) Within the page break plug-in, we can modify the basic options to fine tune the page break functionality and appearance. One of the options is the presentation style, and setting the presentation style to “Sliders” can give the following effect.

Experiment with other options on the page and see its effects on your Joomla! site.

Saturday, August 25, 2012

Shortcut to insert multiple rows in Microsoft Excel

Sometimes, when working with Excel we will need to insert multiple rows or columns within a worksheet. There are no obvious shortcuts for achieving this. Here are a set of key combinations that can be used to speed up multiple insertions of rows or columns.

  • To insert a row, press Alt + i , and then “r” key.
  • To insert a column, press ALT + i, and then “c” key.
  • To repeat the last action, press F4 key. Keep pressing F4 key until the desired number of rows or columns are inserted.

 

Thursday, January 12, 2012

Learning Objective C - Part 2

Topics Covered

In this post, I will be making notes/pointers on following topics

  • How to add a UI element to Interface Builder.
  • How to declare controller variables of type IBOutlet, and IBAction
  • @property and @synthesize

 

Here is a link to first part of this post : Learning Objective C - Part 1

 

Once we create an iOS project in Xcode, we will be presented with couple of files, as shown in the following screen shot.

 

FileList

The files which end with ".storyboard" file names form the UI components of the application. (Atleast, that is my understanding as of now… will change this post if I find otherwise).  As the name indicates, the one with _iPhone will be the iPhone UI, and the one with _iPad will be the iPad UI. At this time, I think we will have to create separate UI for these different devices, but we can link these UI elements to the same code/objects that we create in our application. This gives us the flexibility of tailoring our UI to different device sizes, which will result in a better app experience for the end user.

It is now time to add several UI elements into the application. You can select UI elements from object library, and adjust their properties. Here is an example of an iPhone Screen.

NewImage

In the above example, I have added a text box, and a button. There is also a label, which is invisible here.

The text box, and the label forms the outlets here. We will handle the button through actions.

 

Declare Controller variable types for IBOutlet and IBAction

Because we are following MVC architecture, we will be going through the controller to perform something in the application from the UI layer (View). Inorder to achieve this, following steps have to be done

  • Declare appropriate variables in Controller object to hold reference of these UI elements
  • Create "Getters" and "Setters" for these variables in controller. This will allow the UI layer (View) to access these objects.
  • Link the actual UI Objects to these variables.

Below is the code which does all the above.

#import <UIKit/UIKit.h>

 

@interface BasicViewController : UIViewController

{

IBOutlet UITextField *txtName;

IBOutlet UILabel *lblMessage;

}

 

@property(nonatomic, retain) IBOutlet UITextField *txtName;

@property(nonatomic, retain) IBOutlet UILabel *lblMessage;

 

-(IBAction) doSomething;

-(IBAction)makeKeyboardGoAway;

 

@end

 

In the above code, we declare the text and label objects using IBOutlet. Remember that we have not linked them to the UI yet.

The @property declaration indicates to the compiler that the attributes txtName and lblMessage needs to be treated as properties, and we will need to generate "Getters" and "Setters" to access these. Later, we will use "@synthesize" in the ".m" file to generate these properties.

@implementation BasicViewController

 

@synthesize txtName;

@synthesize lblMessage;

 

-(IBAction)makeKeyboardGoAway

{

[txtName resignFirstResponder];

}

 

 

-(IBAction)doSomething

{

[txtName resignFirstResponder];

NSString *msg = [[NSString alloc] initWithFormat:@"Hello %@",txtName.text];

 

lblMessage.text = msg;

 

 

}

 

The method declarations indicate actions that can be linked to different events.

Once these outlets and actions are in place, it will show up in the popup .

Xcode

Sunday, January 08, 2012

Switching between UI design mode, and Source Code mode in XCode 4.2.1

The Problem

While learning iOS programming, at one point, I was working on adding some UI elements into the iPhone storyboard in Xcode 4.1. However, I clicked something by mistake, and now, the storyboard, instead of UI, was all XML code. I had no idea how to switch back to UI mode to drag and drop UI elements.

 

The Solution

To switch between code-mode, and UI mode, right -click on the .storyboard file, and choose "Open As…". There, select "Source Code" to view the file as code, and select "Interface Builder - IOS Storyboard" to get back to UI format.

NewImage

Tuesday, January 03, 2012

Android List View–Part 1 Basics

List views are an important part of many android applications because of a number of reasons. Most importantly, is the ability to display large number of data pieces, in limited space provided by a mobile device like an android phone.

In this tutorial, we will be looking into the basics of Android List views. I will also provide a link to completed project at the end of this post.

Overview of steps to make a ListView work

  1. Declare the data source. This can be for example, a String array, ArrayList, Database Cursor..etc.
  2. Declare and instantiate an adapter.
    • As part of instantiation, link the adapter to data source.
    • Specify the UI resource for each line of ListView.
  3. Attach the adapter to ListView User Interface
  4. Perform data modification operations on the underlying data source.
  5. Notify the adapter of any data change. This will result in the ListView being updated with latest data.

 

2. Declare and Instantiate an Adapter

The first step in making a ListView work is to instantiate an adapter. In this post (Part 1), I am keeping things pretty simple. We will look into complex List views (eg: a ListView with Images, text..etc) in Part 2.

If you look at the source code, the line of code which initialize the adapter is as follows:

//Initialize array adapter to be attached with list
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,arrData);

Here, we are using an ArrayAdapter object, as the adapter, because we are working with an ArrayList Object. (look at data type of arrData).

  • The first parameter(this) we pass is the context.
  • The second parameter (android.R.layout.simple_list_item_1) is a view/UI resource that is packaged with Android. This is simply a textView. For now, we will be using this. But, in part 2, we will be using our own view/UI to define how each item in the list view looks.
  • The third parameter (arrData) is the ArrayList object. This is where all our data is stored, for the sample application. More often than not, we will be using database cursors with ListViews. If this is the case for you, then use CursorAdapter instead of ArrayAdapter.

 

3. Attach the adapter to ListView User Interface Object

Once we instantiate the adapter, and link it to our data source, it is time to link the ListView UI object to the adapter. To do this, first we will have to get a reference to the UI object within our application. Following line of code does exactly that.

ListView     lstData = (ListView) findViewById(R.id.lstData);

The object lstData refers to the UI element that we added to main.xml (refer to the code). Once we have a reference to the UI element, following line of code attaches the adapter to the UI.

//Attach the adapter to list view.
lstData.setAdapter(adapter);

This completes all the steps needed to make the ListView work with a set of data.

4. Perform Data modification on underlying data source

However, there still is an issue of data being modified by the application. If/When the underlying data is modified, we have to let the adapter know that there is a change. Unless we do this, the changes will not be reflected in the UI.

Probably you are thinking “Why should I do this notification when data is changed? Cant android just keep track of the data, and detect the changes?”. I will let you ponder on that, and do leave your thoughts as comments.

 

5. Notify the adapter of any data change. This will result in the ListView being updated with latest data.

One important point to note here is that, we are notifying the adapter, that the data has changed. We are not directly communicating with the LIstView UI object. Once the adapter knows about data change, it is then responsible for modification of UI. More about this in Part 2, which will be about custom adapters, and more complex ListView.

Following line of code lets the adapter know that underlying data has changed

adapter.notifyDataSetChanged();

That’s it for simple ListView documentation. We will talk more about ListViews in part 2.

 

References

Base Adapter
http://developer.android.com/reference/android/widget/BaseAdapter.html

 

Source Code

https://github.com/gopalnair/SimpleListView/tree/master/SimpleListView

Saturday, December 31, 2011

Learning Objective C - Part1

Now that I got a Mac, this holiday season, I decided to start working on learning Objective-C. Objective-C is the programming language used in almost everything Apple - including iPhone and iPad development. It is also used in developing Mac native applications. Working on a system, which I don't fully understand, or can develop with, always bothers me, and hence, all the above reasons combined, I start my Objective-C. Right off the bat, it became clear that, this is a totally different beast in terms of syntax. My C, C++ knowledge will surely come handy here, but at the same time, there are so many things that are being done in Objective-C in a totally different way.

As I proceed through Objective-C, I will be using my Blog to document what I would like to refer back.

 

Variable Declarations in Objective-C


Simple variables are declared just like in traditional C. However, when it comes to object declarations, things are different in Objective-C.

Example of simple variable declaration:

int testInteger = 0;

Not a big surprise here, as objective-C has its roots in traditional C language.


Example of declaring a string


NSString *testString;

The object declarations in Objective-C is always with a pointer. We then allocate and initialize this memory location, and gets the reference of the memory location to the pointer variable. More on memory allocation and freeing, later.

By the way... almost all the standard classes in Objective-C start with "NS".... because if NEST history of apple.


Example of declaring a Custom Class (say... Dog class)

Dog *pluto = [Dog new];

The above line of code declares a pointer of name "pluto". This pointer points to a memory location with some space reserved for instance of the object "Dog". The "new" keyword allocates AND initializes the memory location at the same time.


Another (More Commonly used) example of declaring a custom class

Dog *pluto = [[Dog alloc] init];

The above line of code also initializes a memory location. This is done by the "alloc" section of the code. The square brackets tells XCode that this is Objective-C code. Once allocation is done, the result is passed out, but right into the hands of init method. The job of init method is to initialize the memory location. Once the memory is initialized, it returns the pointer to the memory location out , which promptly gets assigned to the pointer variable "*pluto".


Memory Allocation and De-Allocation


What is Memory Leak

Unlike many modern programming languages like Java, C#...etc, Objective-C does NOT have an in-build garbage collector (There is something called Automatic Reference Counter, or ARC in objective-C. We will get to this sometime later). This means that, we are responsible for cleaning up and freeing memory after its use. If we don't do this, the application will gradually eat away available memory - until no more memory is available.  This is called "Memory Leak" - Pretty bad situation to be in, for mobile devices, and a guarentee for 1 star comments at app store... that is, if the application ever makes it to the app market.

Difference between using "new" and "alloc-init" combination to initialize objects

In the above example, we saw 2 ways of instantiating the “Dog” class. One used the “new” keyword and, the other, 2 keywords, namely “alloc” and “init”. Surely, the second option seemed more complex and unnecessary, as we have a one-step way of doing this.

The reason why the second approach is more desired, is because of the different options we have to initialize the memory location. It gives us finer control on initialization, before allocating the location information to pointer variable.

Instead of “init”, we can use many other “specialized” initializations, with parameters, as shown. This is not possible when using “new”.

image

All right.. 2:25AM now… that’s it for part 1. This was primarily capturing whatever I learned till now. There is some more… and it wil be captured in this/next blog. If someone stumbles across this blog, and find it useful, please leave a comment.

Sunday, May 01, 2011

My First Published Android App (And its not Hello World! :) )

So, finally, after lots of sleepless nights, going through thousands of pages of documentations, tutorials, Stack Overflow, and lots of other websites, finally, my first App was ready.

I give you RIFT Assistant.

What is RIFT Assistant?

RIFT Assistant is a mobile app for game called RIFT (doh!). For people not familiar with RIFT, it is a MMORPG (Massively multiplayer online role-playing game), where others you see in the game are real people, just like you. Millions of people play the game, and thus make up a strong community, with guilds, Player Vs Player fights, Economy, Auctions…etc. Its a whole different world.

Consider this game world as a “sandbox/development system” for some of your real world decisions. There are some decisions (esp, the ones driven by peoples emotions, behavior..etc), that you can analyze, before making that in real life – We are digressing.. so, let me leave things about RIFT or WOW (World Of Warcraft) at that.

RIFT Assistant helps the players by providing following features:

  1. Provides Shard (server) status, including information like server population, queue size, recommendations..etc.
  2. Ability to view North American/European shards, and a separate easy to reach tab for Favorites.
  3. Provides players with a Home Screen Widget which can be used to monitor shards.
  4. Provides RIFT official news, and also Patch Notes
  5. Provides Alerts/Notifications in your android device’s task bar when new news/patch notes are received.

Here are some screen shots of the app

HomeWidgets   NA_Shard_Status notifications Patch

settings_main_page Main Screen

Why RIFT Assistant?

So, why did I start developing this app? Learning android development was one of my highest priority things for quiet some time. When I say “learn android”, I don't just mean coding. I also mean aspects of the project like publishing, marketing, interacting with users – Basically any and everything from A to Z. For me, this is a perfect miniature scenario of corporate world – One which I can use to learn / understand the big picture of what I am a part of in corporate world.

And so, on April 2nd night, I began. Days that followed found my sometimes happy, depressed, irritated… all kinds of emotions while I progressed slowly through Android development. I even thought of giving up, but just kept going. After 2 weeks or so, something strange started happening.

You see, when searching for many of the issues/problems I encountered as a beginner, I was getting lots of not-so-useful answers when searching forums and other online resources, and finally, after like an hour or so, I would get the solution I was looking for. However, the efforts stuck with me… what I mean by that is, in the process of looking for something, I unknowingly picked up many other solutions (though I was not looking for at that time). But then, as I dived deeper into Android development, I started encountering those problems one by one – and imagine my excitement when, like magic, I was able to recollect/at least have an idea of how to approach the issue. Things were going easy then for some time. Then, I hit the next steep curve up.

So, in any technology, you will see a lot of beginners, then a lot of people who have good knowledge of the subject (not beginners, but intermediate knowledge). However, with some of the things I was trying to do, I was slowing drifting away from even intermediate, to advanced or super advanced stuff in android. It was like going from a thickly populated city to a rural area – all of a sudden I saw myself searching for answers longer and longer, and sometimes, the answers were not there online, as I probably was the first person to hot that problem.  One site that really helped me a lot was Stack Overflow. What followed was lots of trial and errors, while I applied the knowledge I got from beginner and intermediate steps – and every single problem – fell before me – Some took hours & some days. But, eventually, the problem will get solved. I never really knew what “never give up” as seen in movie dialog..etc was all about… but having lived that in this situation – it felt good, and sense of accomplishment.

RIFT Assistant was the means/goal by which I was formulating requirements/problems, and then, searching or learning solutions. Its still in making, and there are a lot of features to be added, each coming with a lot of learning experience as well.

Upcoming Updates/Features

 

In the coming days, I will use this blog to write about some key things I learned. Hopefully it will make the life of another android beginner a tad easier!

Saturday, April 30, 2011

Starting Android Development with Motorola Xoom

I was excited to finally purchase Motorola Xoom tablet, and even more excited at the thought of starting android development for the tablet. So, as soon as I reached home, I connected the xoom to my PC, and was eager to push an existing app from eclipse workspace to the tablet… things are never easy… are they… there is always a roadblock… and, later, once you solve it, the sheer joy!..

The Problem

Eclipse/ADB was not ready to push the APK file into the device. When looking at the list of devices, it does come up, but it shows as “unknown” target, and offline, as shown in screen shot below:

image

 

Cause

There are 2 primary reasons for the above problem

1) Xoom Driver
2) Google has not included Xoom in their driver ini files (yet).

At the time of writing this BLOG, you can download driver files from following location:

http://www.motorola.com/Support/US-EN/Support-Homepage/Software_and_Drivers/USB-and-PC-Charging-Drivers

Solution

First, download and install the driver from above URL, and make sure your OS recognizes  Xoom. Now comes the part where we are going to tell ADB to use debug drivers provided by Google to debug apps in your new Xoom tablet. To do this, follow these steps:

  1. Go to your SDK installation folder, and find a folder named “google-usb_driver”.
  2. In the folder, you will see a file named “android_winusb.inf”
  3. Open the file in notepad or another text editor
  4. Paste the following at the end of sections labelled “[Google.NTx86]” and “[Google.NTamd64]”

;
;Xoom
%SingleAdbInterface%        = USB_Install, USB\VID_22B8&PID_70A9
%CompositeAdbInterface%     = USB_Install, USB\VID_22B8&PID_70A9&MI_01

 

Restart your ADB and make sure you have debug mode turned on in your device by going to your device application settings (Standard Android app development stuff)…. but if you dont know what I am talking about, please head over to : http://developer.android.com/resources/faq/commontasks.html#neweclipseandroidproject

Once done, your device listing should look like the following:

image

 

References

http://community.developer.motorola.com/t5/Android-App-Development-for/Getting-USB-Debugging-ADB-working-with-Xoom/td-p/12060

Monday, August 30, 2010

Getting to actual function module for a Function Exit in SAP ABAP

 

It is common to find customer exits in SAP’s code and Function modules, to accommodate customer specific business rules in SAP provided applications. These exits sometimes are in the form:

Call Customer-Function ‘xxx’, where ‘xxx’ is usually a number. So, how do we know what the actual function module is, where we should put our custom code? This BLOG tells you exactly this.

Here is a screen shot of a function module with customer exit:

image

To find out the actual function module, we will need to know what the main program name is. You can go to the main program using the menu item GO TO –> Main Program

image

Now, our customer exit name would be:

EXIT_<Progam Name>_<XXX>,

Where
<Program_Name> is the main program name
<XXX>                  is the number next to “Customer-Function”

 

In this example function module, the main program was : SAPLHRBEN00GENERAL.

Hence, our customer exit will be
EXIT_SAPLHRBEN00GENERAL_022

Wednesday, August 11, 2010

Problem Steps Recorder – A new tool in Windows 7

Here is a video I made for PSR (Problem Steps Recorder)… a very handy tool to record screen actions, and share the recording with others to seek help with a problem.

This is my first video blog. As always, your comments are most welcome.

Friday, May 07, 2010

“Page Cannot be found” error when browsing aspx pages in Windows Server

 

You may be frustrated with a “page not found” error when attempting to execute your .aspx page. If you have a static “index.html” page, everything looks good.

The problem lies in the fact that by default, in windows Server-2003, all extensions are disabled. Its understandable, as its a server environment, and its safer to let the administrator specifically enable a setting, than auto enable it.

Here are the steps to resolve this:

  1. In “Run” dialog, type in “inetmgr” or start IIS administration.
  2. Go to “Webservice Extensions” node
  3. Enable the required extensions. For ASP.Net to work, enable the extensions as shown in the screen shot.
  4. Try accessing your page again, and everything should be working now.

image

Detect DirectX version installed in your system

 

Here are the steps to detect directX version installed in your system:

  • Select Start—>Run, or <windows key> + R, and type in “dxDiag”
  • You will get a dialog which shows you the directx version, as shown below:

image

Tuesday, April 13, 2010

Setting admin password for fresh Tomcat installation

When tomcat server is installed for the first time in your local machine, and you point to : http://localhost:8080, and try to access admin console, you will be presented with the admin userID/password. However, you have no idea what the userID/password is!!.

Tomcat does not come with an admin userID/password. Instead, we are going to create one.

First, go to “<Tomcat Installation Directory>\conf” folder. Here, you will see a file named “tomcat-users.xml”. Open this file in your XML editor, or notepad. Change the file to look like the following:

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
  <role rolename="manager"/>
  <role rolename="tomcat"/>
  <role rolename="admin"/>
  <role rolename="role1"/>
  <user username="both" password="tomcat" roles="tomcat,role1"/>
  <user username="tomcat" password="tomcat" roles="tomcat"/>
  <user username="admin" password="adminpassword" roles="admin,manager"/>
  <user username="role1" password="tomcat" roles="role1"/>
</tomcat-users>

 

Make sure you change the admin passwords to something more secure. I just used “adminpassword” as the password here for ease of understanding.

That’s it!!. Restart the Tomcat server, and you should now be able to log in as admin.

Friday, March 12, 2010

Windows 7 God Mode

Here is a trick to get access to all of Windows 7 configuration settings in one single place. Follow the following steps:

  1. Create an empty folder
  2. Name this folder : “GodMode.{ED7BA470-8E54-465E-825C-99712043E01C}” , of course without the “.

    image
  3. The folder icon will now change into a shortcut.

     image
  4. Double click on this new shortcut, and get access to all the feature settings – Some of which you didn't even know existed!

Friday, February 12, 2010

Useful Workflow Administration Transactions

I am in the process of learning workflows in SAP, and thought of documenting couple of workflow administration transactions that are pretty useful. If you are interested in learning more about workflows, consider this book. Its the one I am using and find it very useful.

 

Reporting on Workflow Progress

Workflows For Objects SWI6
Workflows for Object Type SWI4

Reporting on Workflow Performance

Work Items by processing duration SWI2_DURA
Work Items with monitored Deadlines SWI2_DEAD
Number of work items processed per period SWI2_FREQ
Work Load analysis for agents SWI5

 

Support tools for Agent Determination problems

Execute rules for work items SWI1_RULE
List of work items without agents (Orphaned Work items) SWI2_ADMI
Execute work items without agent check SWIA

 

Resolving Buffering errors (The Cinderella Principle)

The SAP system buffers/keeps a copy of different data in memory to improve overall performance. This is particularly prevalent in organizational management related entities like Org Units, Jobs, Positions, agents, tasks and relationships between them. Buffering problems can also occur when there is a change in task definition, or after transporting new workflows or versions of workflows into a system.

The buffering while important for system performance, may cause issues in the over all working of workflows. Typically, the system refreshes its buffer every midnight. So, the problems caused may be temporary. Its not uncommon to work on an issue all day, and come back the next day to find the problem does not even exist!!!. More frustrating is the realization that what ever changes/tries you made the previous day, in an attempt to “fix” the issue have to be reversed.

The above scenario is called “Midnight Magic” or the “Cinderella Principle” (i.e.) everything back to normal after midnight.

Solution to the above problem is either to wait a day, or more practically, synchronize the run time buffer.

To synchronize the runtime buffer, use the transaction : SWU_OBUF

After executing the above transaction, some workflow functions may have a performance hit. But this performance hit will go away, as the buffers are rebuild.

Some More Support Tools

Diagnosis of workflows with errors SWI2_DIAG
Deadline monitoring for work items. This transaction is useful to control the working of background job which monitors deadlines. SWWA
Background job/report that monitors work item start or end steps RSWWICOND
Continue workflow after system crash SWPC

Monday, November 30, 2009

Mapping MobileMe iDisk in Windows

I have a mobile Me account, which is integrated with my IPhone. The subscription comes with a 20GB space for storage. However, I rarely use it to upload photos..etc, and the space is pretty much a waste.

So, I started exploring ways by which I could use that space as an online storage of my files (Something like Drop Box, but have much more space)

The following steps details how to map a network drive in windows 7 to the iDisk folder:

  1. Open windows explorer, and go to Tools—> Map Network Drives…If the “Tools” menu is not visible, try pressing the “ALT” key
  2. In the network drive mapping dialog, enter the folder path as : http://idisk.me.com/<username>, where, <username> is your signin userid which you use at http://www.me.com image
  3. Check the “Connect Using Different Credentials” checkmark
  4. Click on “finish”, and enter your mobileme credentials when asked. Thats it!!!

Enjoy putting your iDisk in Mobile Me account, to use.

Thursday, August 13, 2009

Finding BADI in any SAP transaction

One of the options to consider when a need arise to change the standard out of the box SAP feature is to take advantage of Business Add ins , or in short, BADIs. BADIs are basically exit classes which are integrated in the SAP transaction program, and are called during execution, usually with run time variables which can be modified. By taking advantage of these BADIs, application developers can change these variables during run time, based on the business rules, and transfer the values back to the main SAP transaction application, there by modifying the way in which standard out of the box SAP transaction work.

The 2 transactions of notice when coming to BADIs are SE18 and SE19, where we implement the BADIs using our own classes. These classes use the same interface as that of the BADI class.

Having said that, many a times, the issue I have run into, especially in a new environment is how to find these exit points/BADIs that are available for a given transaction. One option is to spend a very long time debugging and keeping a close eye on each and every call that is made in the SAP program. However, this is not an option when it comes to web transactions because web applications time out.

The BADI class we implement is considered an Instance of the actual BADI class. For SAP to find out if a BADI has any active implementations, it first calls a static method called “getInstance()” of class : CL_EXITHANDLER. If we set a break point within this method, the execution will break for every single BADI that is implemented in the SAP transaction.

Hence, set a Break point in: CL_EXITHANDLER=>GET_INSTANCE()

While this is a sure shot way of finding BADIs in a transaction, the down part of this method is that there will be too many break point hits. The most effective method to find BADIs is to go to SDN and check out the user forums. However, if all else fails, the method I detailed below will get you the BADI you are looking for.

Tuesday, February 17, 2009

Controlling Servo Motor Positions using Duration in Parallax Basic Stamp BS2

 

One of the problems I came across when attempting to control a servo motor was the position of motor horn. It is a well known fact that the servo motor need pulses for it to work. This is achieved by raising voltage on control pins (Hi), Making it Low (LO), and then, pausing for set amount of time, say , 20 ms. The “Raising” and Making “Low” can be achieved using the PULSOUT command. The syntax of PULSOUT command is as follows:

PULSOUT <pinNumber>, <Duration>

The Pin number is an obvious parameter (Doh!), but the Duration part is a bit tricky, because the unit of Duration is actually 2 micro Seconds (written as 2us from now on).

Hence, the following command:

                    PULSOUT 14, 1

Will result in getting a pulse to pin 14, with HIGH lasting for just 2us, and then becoming LOW. Lets see another example:

                    PULSOUT 14,1000

will result in getting a pulse to pin 14 with HIGH lasting for 1000*2us  = 2ms. The relevance of this duration discussion will become evident in just a second. Basically, it is this duration, that determines the positioning of a servo motor horn / amount of turn that the motor will do when its given control pulse. This pulse train needs to be sent to servo motor once in say 10 – 30 ms. Hence, to hold a motor on a particular location, we use FOR loops and PAUSE statements, as you will see in the example shortly.

For now, here is a diagram which gives an idea of durations and locations. This diagram was got from Parallax forums, where one of the best teacher, Andy Lindsay posted the information.

Servo Position Control WRT a Clock's Hour Hand

As you can see from the above diagram, to achieve a horn position of 12:00 O Clock, the following can be used, assuming the control pin is PIN 14:

PULSOUT 14, 750

Similarly a 9 O’Clock position –> PULSOUT 14, 1250

3 O’Clock Position –> PULSOUT 14, 250

As we can see, as the duration becomes higher than 750, the movement becomes counter clockwise. With duration lesser than 750 (which = 750* 2us = 1.5 ms ), the motor turns clockwise.

Now, with that “mystery” duration out of our way, lets see an example which will turn the servo motor Counter Clockwise, Clockwise, and then, to 12 O’Clock position. This is the program I came across when starting my robotics/electronics/microcontroller studies, and got utterly confused on how/why the servo motor was behaving as it was. The following program was available in the Microcontroller tutorial book by Parallax, written by Andy Lindsay. After the book was published, with many people having the same question, Andy Lindsay published an extra page on this topic in Parallax forum site. The following URL will take you there:

http://forums.parallax.com/forums/default.aspx?f=6&m=164400

Now, to the program:

********************************* Begining of program *******************

  counter VAR Word

DEBUG "counterclockwise 10 oclock", CR

FOR counter = 1 TO 150
   PULSOUT 14, 1000
   PAUSE 20
NEXT

DEBUG "clockwise 2 oclock", CR

FOR counter = 1 TO 150
   PULSOUT 14, 500
   PAUSE 20
NEXT

DEBUG "center 12 oclock", CR

FOR counter = 1 TO 150
  PULSOUT 14, 750
   PAUSE 20
NEXT

DEBUG "all done"

END

*********************************End Of Program *************************

The First Loop

DEBUG "counterclockwise 10 oclock", CR

FOR counter = 1 TO 150
   PULSOUT 14, 1000
   PAUSE 20
NEXT

First, the servo motor will get 150 pulse signal trains, each HI lasting for 1000 * 2us = 2ms duration. After each such signal, the PAUSE 20 will insert a delay of 20 milliseconds, and the loop continues. As per our discussion earlier, regarding the duration and location of servo motor horn, we understand that the servo horn should come somewhere near 10 O’Clock position. Once it reaches the position, the motor will hold that position for some time. Now, how much time does it hold that position? Lets find out…

Each loop has a pause of 20 ms. Also, each pulse last 2 ms. Hence, total delay in the loop = 20 ms (from PAUSE) + 2 ms (from duration of PULSOUT) = 22ms.

Hence, total time required to execute the first 150 loops
                                       = 22 * 150
                                       = 3300 milliseconds
                                       = 3.3 Seconds.

The Second Loop

DEBUG "clockwise 2 oclock", CR

FOR counter = 1 TO 150
   PULSOUT 14, 500
   PAUSE 20
NEXT

Now, lets consider the second loop. Here too, the servo motor will get a train of 150 pulses. But this time, the duration parameter is 500. This means that each pulse will last only 500 * 2us = 1ms.

From what we have seen in above duration/position explanation/diagram, we understand that the servo motor will move to a location somewhere near to 2 O’Clock position, and hold the position. Again… for how long? Lets find out:

Each loop as a pause of 20ms, because of the PAUSE command. Also, each pulse last 1 ms.

Total delay of loop = 20 ms (From PAUSE) + 1ms (from PULSOUT)
                            = 21 ms.

Total time required to execute 150 loops
                            =  21ms * 150
                            = 3150 milliseconds
                            = 3.1 Seconds.

I leave it to you to figure out how the 3rd and final loop works.

Food For Thought

Before concluding this post, let me discuss how to control the time for which the servo motor holds a position. Remember.. in real world though… we may be using an infinite loop to get input from say, a switch/sensor, to control the motor. But for this example, we can control the time and speed in which the motor moves by changing the number of loops and the PAUSE parameter. In the first loop, increasing the PAUSE duration will result in the servo motor getting to the intended position more slowly, and then holding the position.

However, if you want to motor to reach its position fast, and THEN hold the position, leave the PAUSE duration alone, but increase the number of loops. Think about it … :).