Any experience with run levels in linux and daemons?

I don't think that running "/etc/init.d/zoneswitch start" will show you any more error messages than "service zoneswitch start" because Proc::Daemon::Init in the perl script detaches stdout/stderr from the terminal. You could of course try to comment out Proc::Daemon::Init and see if it then shows some warnings.

I didn't see anything obviously wrong in the perl script. Do you know where exactly serial communication fails? Does it fail at the initialization/connection phase or when you try to write in the /dev/ttyUSB0? It may be easier to debug if you write a minimal version of the script that only initializes the serial port and writes to it. Try to catch all error messages and log them to syslog. If the script seem to silently die at some point, add the suspicious lines within an eval block and log the error message, e.g:

eval {
   $port = Device::SerialPort->new($portPath);
};
if ($@) {
    syslog(LOG_ERR, "Device::SerialPort->new failed: $@");
}

Btw, are you logged in as the same user (root?) when you run the perl script directly and when you try to execute is a service? What are the permissions/owner of /dev/ttyUSB0?