import math

def focalToFov ( focal, aperture ):
    return math.degrees( math.atan2(aperture/2, focal) *2 )

def fovToFocal ( fov, aperture ):
    return (aperture/2) / ( math.tan(math.radians(fov/2)) )

def addFovKnob():
    n = nuke.thisNode()
    fovKnob = nuke.Double_Knob( 'fov','FOV' )
    fovKnob.setRange( 5, 179 )
    focal = n['focal'].value()
    hap = n['haperture'].value()
    fovKnob.setValue( focalToFov( focal, hap ) )
    n.addKnob( fovKnob )
nuke.addOnUserCreate( addFovKnob, nodeClass='Camera2' )

def fovCB():
    n = nuke.thisNode()
    k = nuke.thisKnob()
    hap = n['haperture'].value()
    
    if k.name() == 'fov':
        n['focal'].setValue( fovToFocal( k.value(), hap ) )
    elif k.name() == 'focal':
        n['fov'].setValue( focalToFov( k.value(), hap) )
        
nuke.addKnobChanged( fovCB, nodeClass='Camera2' )