Yes, if you don't have any reason not to, I would recommend writing one driver.
So basically, first you would add a device template with the switch (S2/S3) in mind and select "Write c++ code". There are LMCE utilities that will generate the C++ skeleton to write your code in. Real easy. This gives you a complete executable that will connect to the dcerouter and can communicate with LMCE.
In this template, you can specify commands and events for the device. You could see the ZWave and probably other existing DTs what could make sense to add. For instance: you will probably add a "Sensor tripped" event, as your sensors will fire this, and the device receive it and send the event to LMCE.
Is the S2 and S3 switches the same model, or present much the same functionality? If so, maybe you should create one driver (and one device template) for both. You could then add two devices in LMCE, one for each switch.
For the sensor templates, I would use the existing ones, if they suit your need. Basically, sensors will only emit events, and has only a few device data. If you need to store much data in the devices, maybe you could add new DTs for them.