Subdivide in GUI vs Subdivide in Python
Processing edges twice.

The logic is wrong.  If an edge is a boundary of two selected faces it gets subdivided twice (for each face).  These are the edges to have seam set to false

To get all the edges of smooth faces. First will select smooth faces. Set the material on these faces.  From these faces get the edges.

faces = [f for f in bm.faces if f.smooth]
edges = set(e for f in faces for e in f.edges)


by making edges a set it has only one of each unique member. Pass list(edges) to an operator.

Can use this narrowed down selection to do the seam setting.

Object mode test script.  With object selected and active in OBJECT mode run the script below.

Set use_grid_fill=True in the bmesh subdivide operator if you wish to subdivide faces too.

import bpy
import bmesh

context = bpy.context
ob = context.object
me = ob.data

# object mode bmesh

bm = bmesh.new()
bm.from_mesh(me)

faces = [f for f in bm.faces if f.smooth]

for f in faces:
    f.material_index = 1

edges = set(e for f in faces for e in f.edges)

for e in edges:
    if all(f.smooth for f in e.link_faces):
        e.seam = False

bmesh.ops.subdivide_edges(bm,
        edges=list(edges),
        cuts=1,
        use_grid_fill=True,
        )
bm.to_mesh(me) 
me.update()


Recommend when using bmesh choosing which mode you wish script to run in. The toggle mode operator is not required in your question script. 

If you wish to see live results as you are editing would go with an edit mode bmesh as below.

Here is a test file to run in EDIT mode.  Can run this script against a "live" selection of edges. 

import bpy
import bmesh

context = bpy.context
ob = context.object
me = ob.data

# edit mode bmesh

bm = bmesh.from_edit_mesh(me)

edges = [e for e in bm.edges if e.select]

bmesh.ops.subdivide_edges(bm,
        edges=edges,
        cuts=1,
        use_grid_fill=True,
        )
bmesh.update_edit_mesh(me)
me.update()