This could probably be optimized a bit and you'll learn a lot about how SNMP discovery works in LM. If it's working for you and you don't want to change it, I totally understand, you can ignore the rest of this.
It looks like the goal of this DS is to gather two kinds of data: 1) about the status of the switch, which is found at 1.3.6.1.4.1.12356.101.24.1.1.1.7.1.x where x is the ID of the switch and 2) the status of each port, which is found at 1.3.6.1.4.1.12356.101.24.2.1.1.6.1.x.y, where x is the id of the switch and y is the id of the port.
Because of this, I think you should consider two datasources. One to collect information about the switch and one to collect the info about the ports. The switch datasource would be basically what you have now, without the port datapoints (although you might consider removing the .1 from the end of the discovery OID as that might be variable and should be part of the wildvalue instead of hardcoded).
For the port datasource, you'd change your discovery OID to 1.3.6.1.4.1.12356.101.24.2.1.1.6.1.5. When you pass this OID int LM for discovery, it will do an snmp walk and the returning data will look something like this (totally made up since i don't have the right fortigates to test against):
1.16.1 => port1
1.16.2 => port2
1.16.3 => port3
1.16.4 => port4
1.16.5 => port5
1.16.6 => port6
1.16.7 => port7
1.16.8 => port8
1.16.9 => port9
1.16.10 => port10
1.16.11 => port11
1.16.12 => port12
Discovery has three options for turning this list into instances. Remember, the goal of discovery is to return a list of instances. The list of instances needs a minimum of two parameters, wildvalue (id) and wildalias (display name). The difference between them is what to use as the wildalias or display name for the instance.
value - choosing this option will use the left side of the returned data as the wildvalue and the right side as the wildalias. This is what you do in 98% of the cases. You do this any time there is an OID that contains the display name you want to use. It uses the "value" on the right side as the wildalias.
wildcard - choosing this option will use the left side of the returned data as the wildvalue and also as the wildalias. This is what you do in 1.9% of the cases. You do this any time there is no OID containing a good display name for your instance. In this case, your instances would display as "16.1", "16.2", etc. This happens with CPU; the standard hrProcessor MIB doesn't provide any OID that can be used for a meaningful name. Instead, we just refer to each CPU using a display name that's the same as the ID.
lookup - this option is for 0.1% of the cases out there and is so rare, it's not worth explaining in the context of this problem.
Since we do have an OID that contains a good display name (1.3.6.1.4.1.12356.101.24.2.1.1.5), we should use "value" discovery. This will create a list of ports on the switch. Each port will have a good display name and the ID will be comprised of the switch id and the port id, which we'll need when we make our datapoint.
As for the datapoint, we won't need to make more than one. Since the status is contained in 1.3.6.1.4.1.12356.101.24.2.1.1.6, all we need to do is make one datapoint, where the OID is 1.3.6.1.4.1.12356.101.24.2.1.1.6.##WILDVALUE##.
This obviously changes how you'd do that complex datapoint. It adds up the status of all the ports (assuming 52 ports). I think this would be better done using aggregation on an overview graph, rather than through a complex datapoint.
Reply here with any questions, i'm always eager to help out with this kind of stuff.