diff --git a/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/CzechLightDiscovery.java b/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/CzechLightDiscovery.java
new file mode 100644
index 0000000..1ccbcad
--- /dev/null
+++ b/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/CzechLightDiscovery.java
@@ -0,0 +1,381 @@
+/*
+ * Copyright 2019-2020 Jan Kundrát, CESNET, <jan.kundrat@cesnet.cz> and Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.czechlight;
+
+import com.google.common.collect.Lists;
+
+import org.apache.commons.configuration.HierarchicalConfiguration;
+
+import org.onlab.packet.ChassisId;
+import org.onlab.util.Frequency;
+import org.onosproject.drivers.utilities.XmlConfigParser;
+import org.onosproject.net.ChannelSpacing;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Device;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.device.DefaultDeviceDescription;
+import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.DeviceDescriptionDiscovery;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfController;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+
+import org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery;
+import org.slf4j.Logger;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.optical.device.OmsPortHelper.omsPortDescription;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Device description behaviour for CzechLight SDN ROADM devices using NETCONF.
+ */
+public class CzechLightDiscovery
+        extends AbstractHandlerBehaviour implements DeviceDescriptionDiscovery {
+
+    public enum DeviceType {
+        LINE_DEGREE,
+        ADD_DROP_FLEX,
+        COHERENT_ADD_DROP,
+        INLINE_AMP,
+    };
+    public static final String DEVICE_TYPE_ANNOTATION = "czechlight.model";
+
+    public static final int PORT_COMMON = 100;
+    public static final int PORT_INLINE_WEST = PORT_COMMON + 1;
+    public static final int PORT_INLINE_EAST = PORT_INLINE_WEST + 1;
+    public static final ChannelSpacing CHANNEL_SPACING_50 = ChannelSpacing.CHL_50GHZ;
+    public static final ChannelSpacing CHANNEL_SPACING_NONE = ChannelSpacing.CHL_0GHZ;
+    public static final Frequency START_CENTER_FREQ_50 = Frequency.ofGHz(191_350);
+    public static final Frequency END_CENTER_FREQ_50 = Frequency.ofGHz(196_100);
+
+    private static final String MOD_ROADM_DEVICE = "czechlight-roadm-device";
+    private static final String MOD_ROADM_DEVICE_DATE = "2019-09-30";
+    private static final String MOD_ROADM_FEATURE_LINE_DEGREE = "hw-line-9";
+    private static final String MOD_ROADM_FEATURE_FLEX_ADD_DROP = "hw-add-drop-20";
+    private static final String MOD_COHERENT_A_D = "czechlight-coherent-add-drop";
+    private static final String MOD_COHERENT_A_D_DATE = "2019-09-30";
+    private static final String MOD_INLINE_AMP = "czechlight-inline-amp";
+    private static final String MOD_INLINE_AMP_DATE = "2019-09-30";
+    private static final String NS_CZECHLIGHT_PREFIX = "http://czechlight.cesnet.cz/yang/";
+    public static final String NS_CZECHLIGHT_ROADM_DEVICE = NS_CZECHLIGHT_PREFIX + MOD_ROADM_DEVICE;
+    public static final String NS_CZECHLIGHT_COHERENT_A_D = NS_CZECHLIGHT_PREFIX + MOD_COHERENT_A_D;
+    public static final String NS_CZECHLIGHT_INLINE_AMP  = NS_CZECHLIGHT_PREFIX + MOD_INLINE_AMP;
+
+    private static final String YANGLIB_KEY_REVISION = "data.modules-state.module.revision";
+    private static final String YANGLIB_KEY_MODULE_NAME = "data.modules-state.module.name";
+    private static final String YANGLIB_XMLNS = "urn:ietf:params:xml:ns:yang:ietf-yang-library";
+    private static final String YANGLIB_XML_PREFIX = "yanglib";
+    private static final String YANGLIB_XPATH_FILTER = "/" + YANGLIB_XML_PREFIX + ":modules-state/module[(name='"
+            + MOD_ROADM_DEVICE + "') or (name='" + MOD_COHERENT_A_D + "') or (name='" + MOD_INLINE_AMP + "')]";
+    private static final String YANGLIB_PATH_QUERY_FEATURES = "data.modules-state.module.feature";
+
+    public static final String CHANNEL_DEFS_FILTER =
+            "<channel-plan xmlns=\"http://czechlight.cesnet.cz/yang/czechlight-roadm-device\">" +
+                    "<channel><lower-frequency/><upper-frequency/></channel>" +
+                    "</channel-plan>";
+    private static final String UNIDIR_CFG_SUBSTR = "<port/><attenuation/><power/>";
+    public static final String XML_MC_OPEN = "<media-channels " +
+            "xmlns=\"http://czechlight.cesnet.cz/yang/czechlight-roadm-device\">";
+    public static final String XML_MC_CLOSE = "</media-channels>";
+    public static final String MC_ROUTING_FILTER =
+            XML_MC_OPEN +
+                    "<add>" + UNIDIR_CFG_SUBSTR + "</add>" +
+                    "<drop>" + UNIDIR_CFG_SUBSTR + "</drop>" +
+                    XML_MC_CLOSE;
+
+    public static final String LINE_EXPRESS_PREFIX = "E";
+
+    private static final String DESC_PORT_LINE_WEST = "Line West";
+    private static final String DESC_PORT_LINE_EAST = "Line East";
+    private static final String DESC_PORT_LINE = "Line";
+    private static final String DESC_PORT_EXPRESS = "Express";
+
+
+    private static final Logger log = getLogger(CzechLightDiscovery.class);
+
+    @Override
+    public DeviceDescription discoverDeviceDetails() {
+        NetconfSession session = getNetconfSession();
+        if (session == null) {
+            log.error("Cannot request NETCONF session for {}", data().deviceId());
+            return null;
+        }
+
+        DefaultAnnotations.Builder annotations = DefaultAnnotations.builder();
+        final var noDevice = new DefaultDeviceDescription(handler().data().deviceId().uri(), Device.Type.OTHER,
+                null, null, null, null, null, annotations.build());
+
+        try {
+            Boolean isLineDegree = false, isAddDrop = false, isCoherentAddDrop = false, isInlineAmp = false;
+            var data = doGetXPath(getNetconfSession(), YANGLIB_XML_PREFIX, YANGLIB_XMLNS, YANGLIB_XPATH_FILTER);
+            if (!data.containsKey(YANGLIB_KEY_REVISION)) {
+                log.error("Not talking to a supported CzechLight device, is that a teapot?");
+                return noDevice;
+            }
+            final var revision = data.getString(YANGLIB_KEY_REVISION);
+            if (data.getString(YANGLIB_KEY_MODULE_NAME).equals(MOD_ROADM_DEVICE)) {
+                if (!revision.equals(MOD_ROADM_DEVICE_DATE)) {
+                    log.error("Revision mismatch for YANG module {}: got {}", MOD_ROADM_DEVICE, revision);
+                    return noDevice;
+                }
+                final var features = data.getStringArray(YANGLIB_PATH_QUERY_FEATURES);
+                isLineDegree = Arrays.stream(features)
+                        .anyMatch(s -> s.equals(MOD_ROADM_FEATURE_LINE_DEGREE));
+                isAddDrop = Arrays.stream(features)
+                        .anyMatch(s -> s.equals(MOD_ROADM_FEATURE_FLEX_ADD_DROP));
+                if (!isLineDegree && !isAddDrop) {
+                    log.error("Device type not recognized, but {} YANG model is present. Reported YANG features: {}",
+                            MOD_ROADM_DEVICE, String.join(", ", features));
+                    return noDevice;
+                }
+            } else if (data.getString(YANGLIB_KEY_MODULE_NAME).equals(MOD_COHERENT_A_D)) {
+                if (!revision.equals(MOD_COHERENT_A_D_DATE)) {
+                    log.error("Revision mismatch for YANG module {}: got {}", MOD_COHERENT_A_D, revision);
+                    return noDevice;
+                }
+                isCoherentAddDrop = true;
+            } else if (data.getString(YANGLIB_KEY_MODULE_NAME).equals(MOD_INLINE_AMP)) {
+                if (!revision.equals(MOD_INLINE_AMP_DATE)) {
+                    log.error("Revision mismatch for YANG module {}: got {}", MOD_INLINE_AMP, revision);
+                    return noDevice;
+                }
+                isInlineAmp = true;
+            }
+
+            if (isLineDegree) {
+                log.info("Talking to a Line/Degree ROADM node");
+                annotations.set(DEVICE_TYPE_ANNOTATION, DeviceType.LINE_DEGREE.toString());
+            } else if (isAddDrop) {
+                log.info("Talking to an Add/Drop ROADM node");
+                annotations.set(DEVICE_TYPE_ANNOTATION, DeviceType.ADD_DROP_FLEX.toString());
+            } else if (isCoherentAddDrop) {
+                log.info("Talking to a Coherent Add/Drop ROADM node");
+                annotations.set(DEVICE_TYPE_ANNOTATION, DeviceType.COHERENT_ADD_DROP.toString());
+            } else if (isInlineAmp) {
+                log.info("Talking to an inline ampifier, not a ROADM, but we will fake it as a ROADM for now");
+                annotations.set(DEVICE_TYPE_ANNOTATION, DeviceType.INLINE_AMP.toString());
+            } else {
+                log.error("Device type not recognized");
+                return noDevice;
+            }
+        } catch (NetconfException e) {
+            log.error("Cannot request ietf-yang-library data", e);
+            return noDevice;
+        }
+
+        // FIXME: initialize these
+        String vendor       = "CzechLight";
+        String hwVersion    = "n/a";
+        String swVersion    = "n/a";
+        String serialNumber = "n/a";
+        ChassisId chassisId = null;
+
+        return new DefaultDeviceDescription(handler().data().deviceId().uri(), Device.Type.ROADM,
+                vendor, hwVersion, swVersion, serialNumber, chassisId, annotations.build());
+    }
+
+    public static String leafPortName(final DeviceType deviceType, final long number) {
+        switch (deviceType) {
+            case LINE_DEGREE:
+                return LINE_EXPRESS_PREFIX + Long.toString(number);
+            default:
+                return Long.toString(number);
+        }
+    }
+
+    @Override
+    public List<PortDescription> discoverPortDetails() {
+        DeviceId deviceId = handler().data().deviceId();
+        DeviceService deviceService = checkNotNull(handler().get(DeviceService.class));
+        Device device = deviceService.getDevice(deviceId);
+        var deviceType = DeviceType.valueOf(device.annotations().value(DEVICE_TYPE_ANNOTATION));
+
+        List<PortDescription> portDescriptions = Lists.newArrayList();
+
+        if (deviceType == DeviceType.INLINE_AMP) {
+            DefaultAnnotations.Builder annotations = DefaultAnnotations.builder();
+            annotations.set(AnnotationKeys.PORT_NAME, DESC_PORT_LINE_WEST);
+            annotations.set(OdtnDeviceDescriptionDiscovery.PORT_TYPE,
+                    OdtnDeviceDescriptionDiscovery.OdtnPortType.LINE.toString());
+            portDescriptions.add(omsPortDescription(PortNumber.portNumber(PORT_INLINE_WEST),
+                    true,
+                    START_CENTER_FREQ_50,
+                    END_CENTER_FREQ_50,
+                    CHANNEL_SPACING_50.frequency(),
+                    annotations.build()));
+
+            annotations = DefaultAnnotations.builder();
+            annotations.set(AnnotationKeys.PORT_NAME, DESC_PORT_LINE_EAST);
+            annotations.set(OdtnDeviceDescriptionDiscovery.PORT_TYPE,
+                    OdtnDeviceDescriptionDiscovery.OdtnPortType.LINE.toString());
+            portDescriptions.add(omsPortDescription(PortNumber.portNumber(PORT_INLINE_EAST),
+                    true,
+                    START_CENTER_FREQ_50,
+                    END_CENTER_FREQ_50,
+                    CHANNEL_SPACING_50.frequency(),
+                    annotations.build()));
+
+            return portDescriptions;
+        }
+
+        DefaultAnnotations.Builder annotationsForCommon = DefaultAnnotations.builder();
+        switch (deviceType) {
+            case LINE_DEGREE:
+                annotationsForCommon.set(AnnotationKeys.PORT_NAME, DESC_PORT_LINE);
+                annotationsForCommon.set(OdtnDeviceDescriptionDiscovery.PORT_TYPE,
+                        OdtnDeviceDescriptionDiscovery.OdtnPortType.LINE.toString());
+                break;
+            case ADD_DROP_FLEX:
+            case COHERENT_ADD_DROP:
+                annotationsForCommon.set(AnnotationKeys.PORT_NAME, DESC_PORT_EXPRESS);
+                break;
+            case INLINE_AMP:
+                assert false : "this cannot happen because it's handled above, but I have to type this here anyway";
+            default:
+                assert false : "unhandled device type";
+        }
+        portDescriptions.add(omsPortDescription(PortNumber.portNumber(PORT_COMMON),
+                true,
+                START_CENTER_FREQ_50,
+                END_CENTER_FREQ_50,
+                CHANNEL_SPACING_50.frequency(),
+                annotationsForCommon.build()));
+
+        final int leafPortCount;
+        switch (deviceType) {
+            case LINE_DEGREE:
+                leafPortCount = 9;
+                break;
+            case ADD_DROP_FLEX:
+                leafPortCount = 20;
+                break;
+            case COHERENT_ADD_DROP:
+                leafPortCount = 8;
+                break;
+            default:
+                log.error("Unsupported CzechLight device type");
+                return null;
+        }
+
+        for (var i = 1; i <= leafPortCount; ++i) {
+            DefaultAnnotations.Builder annotations = DefaultAnnotations.builder();
+            final Frequency channelSpacing;
+            annotations.set(AnnotationKeys.PORT_NAME, leafPortName(deviceType, i));
+            switch (deviceType) {
+                case LINE_DEGREE:
+                    channelSpacing = CHANNEL_SPACING_50.frequency();
+                    break;
+                case ADD_DROP_FLEX:
+                    annotations.set(OdtnDeviceDescriptionDiscovery.PORT_TYPE,
+                            OdtnDeviceDescriptionDiscovery.OdtnPortType.CLIENT.toString());
+                    channelSpacing = CHANNEL_SPACING_50.frequency();
+                    break;
+                case COHERENT_ADD_DROP:
+                    annotations.set(OdtnDeviceDescriptionDiscovery.PORT_TYPE,
+                            OdtnDeviceDescriptionDiscovery.OdtnPortType.CLIENT.toString());
+                    channelSpacing = CHANNEL_SPACING_NONE.frequency();
+                    break;
+                default:
+                    log.error("Unsupported CzechLight device type");
+                    return null;
+            }
+            portDescriptions.add(omsPortDescription(PortNumber.portNumber(i),
+                    true,
+                    START_CENTER_FREQ_50,
+                    END_CENTER_FREQ_50,
+                    channelSpacing,
+                    annotations.build()));
+        }
+        return portDescriptions;
+    }
+
+    private NetconfSession getNetconfSession() {
+        NetconfController controller =
+                checkNotNull(handler().get(NetconfController.class));
+        return controller.getNetconfDevice(data().deviceId()).getSession();
+    }
+
+    public static double dbmToMilliwatts(final double dbm) {
+        return java.lang.Math.pow(10, dbm / 10);
+    }
+
+    public static double milliwattsToDbm(final double mw) {
+        return 10 * java.lang.Math.log10(mw);
+    }
+
+    /** Run a <get> NETCONF command with an XPath filter.
+     *
+     * @param session well, a NETCONF session
+     * @param prefix Name of a XML element prefix to use. Can be meaningless, such as "M"
+     * @param namespace Full URI of the XML namespace to use. This is the real meat.
+     * @param xpathFilter String with a relative XPath filter. This *MUST* start with "/" followed by 'prefix' and ":".
+     * @return Result of the <get/> operation via NETCONF as a XmlHierarchicalConfiguration
+     * @throws NetconfException exactly as session.doWrappedRpc() would do.
+     * */
+    public static HierarchicalConfiguration doGetXPath(final NetconfSession session, final String prefix,
+                                                       final String namespace, final String xpathFilter)
+            throws NetconfException {
+        final var reply = session.doWrappedRpc("<get xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
+                + "<filter type=\"xpath\" xmlns:" + prefix + "=\"" + namespace + "\""
+                + " select=\"" + xpathFilter.replace("\"", "&quot;") + "\"/>"
+                + "</get>");
+        log.debug("GET RPC w/XPath {}", reply);
+        var data = XmlConfigParser.loadXmlString(reply);
+        if (!data.containsKey("data[@xmlns]")) {
+            log.error("NETCONF <get> w/XPath returned error: {}", reply);
+            return null;
+        }
+        return data;
+    }
+
+    public static HierarchicalConfiguration doGetSubtree(final NetconfSession session, final String subtreeXml)
+            throws NetconfException {
+        final var data = XmlConfigParser.loadXmlString(session.getConfig(DatastoreId.RUNNING, subtreeXml));
+        if (!data.containsKey("data[@xmlns]")) {
+            log.error("NETCONF <get> w/subtree returned error");
+            return null;
+        }
+        return data;
+    }
+
+    /** Massage an XPath fragment (without the "/module:" prefix) into a key suitable for XmlConfigParser.getString()
+     *
+     * This might or might not work properly for various corner cases. It will fail horribly when XML namespaces are not
+     * being done in exactly the same manner as the author of this code assumed was the case.
+     *
+     * @param xpath XPath subset without the "/module:" prefix, such as "container/another-container/leaf"
+     * @return a string to be passed to XmlConfigParser.getString(...) of the XmlHierarchicalConfiguration
+     * */
+    public static String xpathToXmlKey(final String xpath) {
+        return "data." // prefix added by RPC handling
+                // turn XPath level delimiters into XmlConfigParser's key format
+                + xpath.replace('/', '.')
+                // filter out XPath list keys/selectors, they are not visible in XmlConfigParser
+                .replaceAll("\\[[^]]*\\]", "");
+    }
+
+}
diff --git a/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/CzechLightDriversLoader.java b/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/CzechLightDriversLoader.java
new file mode 100644
index 0000000..e98e8d2
--- /dev/null
+++ b/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/CzechLightDriversLoader.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.czechlight;
+
+import org.osgi.service.component.annotations.Component;
+import org.onosproject.net.driver.AbstractDriverLoader;
+import org.onosproject.net.optical.OpticalDevice;
+
+/**
+ * Loader for CzechLight device drivers from specific XML.
+ */
+@Component(immediate = true)
+public class CzechLightDriversLoader extends AbstractDriverLoader {
+
+    // OSGI: help bundle plugin discover runtime package dependency.
+    @SuppressWarnings("unused")
+    private OpticalDevice optical;
+
+    public CzechLightDriversLoader() {
+        super("/czechlight-drivers.xml");
+    }
+}
diff --git a/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/CzechLightFlowRuleProgrammable.java b/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/CzechLightFlowRuleProgrammable.java
new file mode 100644
index 0000000..e3205c2
--- /dev/null
+++ b/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/CzechLightFlowRuleProgrammable.java
@@ -0,0 +1,500 @@
+/*
+ * Copyright 2019-2020 Jan Kundrát, CESNET, <jan.kundrat@cesnet.cz> and Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.czechlight;
+
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.onlab.util.Spectrum;
+import org.onosproject.core.CoreService;
+import org.onosproject.drivers.odtn.impl.DeviceConnectionCache;
+import org.onosproject.net.ChannelSpacing;
+import org.onosproject.net.GridType;
+import org.onosproject.net.Lambda;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.OchSignalType;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleProgrammable;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.criteria.OchSignalCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.flow.instructions.L0ModificationInstruction;
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfController;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Objects;
+import java.util.TreeMap;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/** Modification of the MC by a ROADM device.
+ * The signal might be either attenuated by a specified amount of dB, or its target power can be set
+ * to a specified power in dBm.
+ */
+class MCManipulation {
+    Double attenuation;
+    Double targetPower;
+
+    public MCManipulation(final Double attenuation, final Double targetPower) {
+        this.attenuation = attenuation;
+        this.targetPower = targetPower;
+    }
+
+    public String toString() {
+        if (attenuation != null) {
+            return "attenuation: " + String.valueOf(attenuation);
+        }
+
+        if (targetPower != null) {
+            return "targetPower: " + String.valueOf(targetPower);
+        }
+
+        return "none";
+    }
+};
+
+/** Representation of a ROADM configuration for a given Media Channel.
+ * This contains frequency (`channel`), routing (`leafPort`) and attenuation or power set point (`manipulation`).
+ * */
+class CzechLightRouting {
+    MediaChannelDefinition channel;
+    int leafPort;
+    MCManipulation manipulation;
+
+    public CzechLightRouting(final MediaChannelDefinition channel, final int leafPort, final MCManipulation manip) {
+        this.channel = channel;
+        this.leafPort = leafPort;
+        this.manipulation = manip;
+    }
+
+    public String toString() {
+        return channel.toString() + " -> " + String.valueOf(leafPort) + " (" + manipulation.toString() + ")";
+    }
+};
+
+/**
+ * Implementation of FlowRuleProgrammable interface for CzechLight SDN ROADMs.
+ */
+public class CzechLightFlowRuleProgrammable extends AbstractHandlerBehaviour implements FlowRuleProgrammable {
+
+    private final Logger log =
+            LoggerFactory.getLogger(getClass());
+
+    private static final String NETCONF_OP_MERGE = "merge";
+    private static final String NETCONF_OP_NONE = "none";
+    private static final String ELEMENT_ADD = "add";
+    private static final String ELEMENT_DROP = "drop";
+
+    private enum Direction {
+        ADD,
+        DROP,
+    };
+    // FIXME: can we get this programmaticaly?
+    private static final String DEFAULT_APP = "org.onosproject.drivers.czechlight";
+
+    @Override
+    public Collection<FlowEntry> getFlowEntries() {
+        if (deviceType() == CzechLightDiscovery.DeviceType.INLINE_AMP
+                || deviceType() == CzechLightDiscovery.DeviceType.COHERENT_ADD_DROP) {
+            final var data = getConnectionCache().get(data().deviceId());
+            if (data == null) {
+                return new ArrayList<>();
+            }
+            return data.stream()
+                    .map(rule -> new DefaultFlowEntry(rule))
+                    .collect(Collectors.toList());
+        }
+
+        HierarchicalConfiguration xml;
+        try {
+            xml = doGetSubtree(CzechLightDiscovery.CHANNEL_DEFS_FILTER + CzechLightDiscovery.MC_ROUTING_FILTER);
+        } catch (NetconfException e) {
+            log.error("Cannot read data from NETCONF: {}", e);
+            return new ArrayList<>();
+        }
+        final var allChannels = MediaChannelDefinition.parseChannelDefinitions(xml);
+
+        Collection<FlowEntry> list = new ArrayList<>();
+
+        final var allMCs = xml.configurationsAt("data.media-channels");
+        allMCs.stream()
+                .map(cfg -> confToMCRouting(ELEMENT_ADD, allChannels, cfg))
+                .filter(Objects::nonNull)
+                .forEach(flow -> {
+                    log.debug("{}: found ADD: {}", data().deviceId(), flow.toString());
+                    list.add(new DefaultFlowEntry(asFlowRule(Direction.ADD, flow), FlowEntry.FlowEntryState.ADDED));
+                });
+        allMCs.stream()
+                .map(cfg -> confToMCRouting(ELEMENT_DROP, allChannels, cfg))
+                .filter(Objects::nonNull)
+                .forEach(flow -> {
+                    log.debug("{}: found DROP: {}", data().deviceId(), flow.toString());
+                    list.add(new DefaultFlowEntry(asFlowRule(Direction.DROP, flow), FlowEntry.FlowEntryState.ADDED));
+                });
+        return list;
+    }
+
+    @Override
+    public Collection<FlowRule> applyFlowRules(Collection<FlowRule> rules) {
+        if (deviceType() == CzechLightDiscovery.DeviceType.INLINE_AMP
+                || deviceType() == CzechLightDiscovery.DeviceType.COHERENT_ADD_DROP) {
+            rules.forEach(
+                    rule -> {
+                        log.debug("{}: asked for {} (whole C-band is always forwarded by the HW)",
+                                data().deviceId(), rule);
+                        getConnectionCache().add(data().deviceId(), rule.toString(), rule);
+                    }
+            );
+            return rules;
+        }
+
+        HierarchicalConfiguration xml;
+        try {
+            xml = doGetSubtree(CzechLightDiscovery.CHANNEL_DEFS_FILTER + CzechLightDiscovery.MC_ROUTING_FILTER);
+        } catch (NetconfException e) {
+            log.error("Cannot read data from NETCONF: {}", e);
+            return new ArrayList<>();
+        }
+        final var allChannels = MediaChannelDefinition.parseChannelDefinitions(xml);
+        var hopefullyAdded = new ArrayList<FlowRule>();
+
+        // temporary store because both ADD and DROP must go into the same <media-channel> list item
+        var changes = new TreeMap<String, String>();
+        rules.forEach(
+                rule -> {
+                    log.debug("{}: asked to INSERT rule for:", data().deviceId());
+                    rule.selector().criteria().forEach(
+                            criteria -> log.debug("  criteria {}", criteria.toString())
+                    );
+                    rule.treatment().allInstructions().forEach(
+                            instruction -> log.debug("  instruction {}", instruction.toString())
+                    );
+
+                    String element;
+                    long leafPort;
+                    if (inputPortFromFlow(rule).toLong() == CzechLightDiscovery.PORT_COMMON) {
+                        element = ELEMENT_DROP;
+                        leafPort = outputPortFromFlow(rule).toLong();
+                    } else {
+                        element = ELEMENT_ADD;
+                        leafPort = inputPortFromFlow(rule).toLong();
+                    }
+                    final var och = ochSignalFromFlow(rule);
+                    final var channel = allChannels.entrySet().stream()
+                            .filter(entry -> MediaChannelDefinition.mcMatches(entry, och))
+                            .findAny()
+                            .orElse(null);
+                    if (channel == null) {
+                        log.error("No matching channel definition available for the following rule at {}:",
+                                data().deviceId());
+                        rule.selector().criteria().forEach(
+                                criteria -> log.error("  criteria {}", criteria.toString())
+                        );
+                        rule.treatment().allInstructions().forEach(
+                                instruction -> log.error("  instruction {}", instruction.toString())
+                        );
+                    } else {
+                        log.info("{}: Creating \"{}\" MC {}: leaf {}", data().deviceId(),
+                                element, channel.getKey(), leafPort);
+                        var sb = new StringBuilder();
+                        sb.append("<");
+                        sb.append(element);
+                        sb.append(">");
+                        sb.append("<port>");
+                        if (deviceType() == CzechLightDiscovery.DeviceType.LINE_DEGREE) {
+                            sb.append(CzechLightDiscovery.LINE_EXPRESS_PREFIX);
+                        }
+                        sb.append(String.valueOf(leafPort));
+                        sb.append("</port>");
+                        // FIXME: propagate attenuation or power target
+                        if (deviceType() == CzechLightDiscovery.DeviceType.LINE_DEGREE) {
+                            if (outputPortFromFlow(rule).toLong() == CzechLightDiscovery.PORT_COMMON) {
+                                sb.append("<power>-5.0</power>");
+                            } else {
+                                sb.append("<power>-12.0</power>");
+                            }
+                        } else {
+                            if (outputPortFromFlow(rule).toLong() == CzechLightDiscovery.PORT_COMMON) {
+                                sb.append("<power>-12.0</power>");
+                            } else {
+                                sb.append("<power>-5.0</power>");
+                            }
+                        }
+                        sb.append("</");
+                        sb.append(element);
+                        sb.append(">");
+                        changes.put(channel.getKey(),
+                                changes.getOrDefault(channel.getKey(), "") + sb.toString());
+                        hopefullyAdded.add(rule);
+                    }
+                });
+
+        if (!hopefullyAdded.isEmpty()) {
+            var sb = new StringBuilder();
+            changes.forEach(
+                    (channel, data) -> {
+                        sb.append(CzechLightDiscovery.XML_MC_OPEN);
+                        sb.append("<channel>");
+                        sb.append(channel);
+                        sb.append("</channel>");
+                        sb.append(data);
+                        sb.append(CzechLightDiscovery.XML_MC_CLOSE);
+                    });
+            doEditConfig(NETCONF_OP_MERGE, sb.toString());
+        }
+        return hopefullyAdded;
+    }
+
+    @Override
+    public Collection<FlowRule> removeFlowRules(Collection<FlowRule> rules) {
+        if (deviceType() == CzechLightDiscovery.DeviceType.INLINE_AMP
+                || deviceType() == CzechLightDiscovery.DeviceType.COHERENT_ADD_DROP) {
+            rules.forEach(
+                    rule -> {
+                        log.debug("{}: asked to remove {} (whole C-band is always forwarded by the HW)",
+                                data().deviceId(), rule);
+                        getConnectionCache().remove(data().deviceId(), rule);
+                    }
+            );
+            return rules;
+        }
+        HierarchicalConfiguration xml;
+        try {
+            xml = doGetSubtree(CzechLightDiscovery.CHANNEL_DEFS_FILTER + CzechLightDiscovery.MC_ROUTING_FILTER);
+        } catch (NetconfException e) {
+            log.error("Cannot read data from NETCONF: {}", e);
+            return new ArrayList<>();
+        }
+        final var allChannels = MediaChannelDefinition.parseChannelDefinitions(xml);
+
+        var hopefullyRemoved = new ArrayList<FlowRule>();
+
+        // temporary store because both ADD and DROP must go into the same <media-channel> list item
+        var changes = new TreeMap<String, String>();
+
+        rules.forEach(
+                rule -> {
+                    final String element = inputPortFromFlow(rule).toLong() == CzechLightDiscovery.PORT_COMMON ?
+                            ELEMENT_DROP : ELEMENT_ADD;
+                    final var och = ochSignalFromFlow(rule);
+                    final var channel = allChannels.entrySet().stream()
+                            .filter(entry -> MediaChannelDefinition.mcMatches(entry, och))
+                            .findAny()
+                            .orElse(null);
+                    if (channel == null) {
+                        log.error("Cannot find what channel to remove for the following flow rule at {}:",
+                                data().deviceId());
+                        rule.selector().criteria().forEach(
+                                criteria -> log.error("  criteria {}", criteria.toString())
+                        );
+                        rule.treatment().allInstructions().forEach(
+                                instruction -> log.error("  instruction {}", instruction.toString())
+                        );
+                    } else {
+                        log.info("{}: Removing {} MC {}", data().deviceId(), element, channel.getKey());
+                        changes.put(channel.getKey(),
+                                changes.getOrDefault(channel.getKey(), "")
+                                        + "<" + element + " nc:operation=\"remove\"/>");
+                        hopefullyRemoved.add(rule);
+                    }
+                });
+
+        if (!hopefullyRemoved.isEmpty()) {
+            var sb = new StringBuilder();
+            changes.forEach(
+                    (channel, data) -> {
+                        sb.append(CzechLightDiscovery.XML_MC_OPEN);
+                        sb.append("<channel>");
+                        sb.append(channel);
+                        sb.append("</channel>");
+                        sb.append(data);
+                        sb.append(CzechLightDiscovery.XML_MC_CLOSE);
+                    });
+            doEditConfig(NETCONF_OP_NONE, sb.toString());
+        }
+        return hopefullyRemoved;
+    }
+
+    private static CzechLightRouting confToMCRouting(final String keyPrefix,
+                                                     final Map<String, MediaChannelDefinition> allChannels,
+                                                     final HierarchicalConfiguration item) {
+        if (!item.containsKey(keyPrefix + ".port")) {
+            return null;
+        }
+        // the leaf port is either just a number, or a number prefixed by "E"
+        final var portStr = item.getString(keyPrefix + ".port");
+        final int leafPort = Integer.parseInt(portStr.startsWith(CzechLightDiscovery.LINE_EXPRESS_PREFIX) ?
+                portStr.substring(1) : portStr);
+        return new CzechLightRouting(
+                allChannels.get(item.getString("channel")),
+                leafPort,
+                new MCManipulation(
+                        item.getDouble(keyPrefix + ".attenuation", null),
+                        item.getDouble(keyPrefix + ".power", null)
+                )
+        );
+    }
+
+    private FlowRule asFlowRule(final Direction direction, final CzechLightRouting routing) {
+        FlowRuleService service = handler().get(FlowRuleService.class);
+        Iterable<FlowEntry> entries = service.getFlowEntries(data().deviceId());
+
+        final var portIn = PortNumber.portNumber(direction == Direction.DROP ?
+                CzechLightDiscovery.PORT_COMMON : routing.leafPort);
+        final var portOut = PortNumber.portNumber(direction == Direction.ADD ?
+                CzechLightDiscovery.PORT_COMMON : routing.leafPort);
+
+        final var channelWidth = routing.channel.highMHz - routing.channel.lowMHz;
+        final var channelCentralFreq = (int) (routing.channel.lowMHz + channelWidth / 2);
+
+        for (FlowEntry entry : entries) {
+            final var och = ochSignalFromFlow(entry);
+            if (och.centralFrequency().asMHz() == channelCentralFreq
+                    && och.slotWidth().asMHz() == channelWidth
+                    && portIn.equals(inputPortFromFlow(entry))
+                    && portOut.equals(outputPortFromFlow(entry))) {
+                return entry;
+            }
+        }
+
+        final var channelSlotWidth = (int) (channelWidth / ChannelSpacing.CHL_12P5GHZ.frequency().asMHz());
+        final var channelMultiplier = (int) ((channelCentralFreq - Spectrum.CENTER_FREQUENCY.asMHz())
+                / ChannelSpacing.CHL_6P25GHZ.frequency().asMHz());
+
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchInPort(portIn)
+                .add(Criteria.matchOchSignalType(OchSignalType.FLEX_GRID))
+                .add(Criteria.matchLambda(Lambda.ochSignal(GridType.FLEX, ChannelSpacing.CHL_6P25GHZ,
+                        channelMultiplier, channelSlotWidth)))
+                .build();
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setOutput(portOut)
+                .build();
+        return DefaultFlowRule.builder()
+                .forDevice(data().deviceId())
+                .withSelector(selector)
+                .withTreatment(treatment)
+                // the concept of priorities does not make sense for a ROADM MC configuration,
+                // but it's mandatory nonetheless
+                .withPriority(666)
+                .makePermanent()
+                .fromApp(handler().get(CoreService.class).getAppId(DEFAULT_APP))
+                .build();
+    }
+
+    private static PortNumber inputPortFromFlow(final Object flow) {
+        return ((flow instanceof FlowEntry) ?
+                ((FlowEntry) flow).selector() : ((FlowRule) flow).selector()).criteria().stream()
+                .filter(c -> c instanceof PortCriterion)
+                .map(c -> ((PortCriterion) c).port())
+                .findAny()
+                .orElse(null);
+    }
+
+    private static PortNumber outputPortFromFlow(final Object flow) {
+        return ((flow instanceof FlowEntry) ?
+                ((FlowEntry) flow).treatment() : ((FlowRule) flow).treatment()).immediate().stream()
+                .filter(c -> c instanceof Instructions.OutputInstruction)
+                .map(c -> ((Instructions.OutputInstruction) c).port())
+                .findAny()
+                .orElse(null);
+    }
+
+    private static OchSignal ochSignalFromFlow(final Object flow) {
+        final var fromCriteria = ((flow instanceof FlowEntry) ?
+                ((FlowEntry) flow).selector() : ((FlowRule) flow).selector()).criteria().stream()
+                .filter(c -> c instanceof OchSignalCriterion)
+                .map(c -> ((OchSignalCriterion) c).lambda())
+                .findAny()
+                .orElse(null);
+        if (fromCriteria != null) {
+            return fromCriteria;
+        }
+        return ((flow instanceof FlowEntry) ?
+                ((FlowEntry) flow).treatment() : ((FlowRule) flow).treatment()).immediate().stream()
+                .filter(c -> c instanceof L0ModificationInstruction.ModOchSignalInstruction)
+                .map(c -> ((L0ModificationInstruction.ModOchSignalInstruction) c).lambda())
+                .findAny()
+                .orElse(null);
+    }
+
+    private CzechLightDiscovery.DeviceType deviceType() {
+        var annotations = this.handler().get(DeviceService.class).getDevice(handler().data().deviceId()).annotations();
+        return CzechLightDiscovery.DeviceType.valueOf(annotations.value(CzechLightDiscovery.DEVICE_TYPE_ANNOTATION));
+    }
+
+    private DeviceConnectionCache getConnectionCache() {
+        return DeviceConnectionCache.init();
+    }
+
+    private HierarchicalConfiguration doGetSubtree(final String subtreeXml) throws NetconfException {
+        NetconfSession session = getNetconfSession();
+        if (session == null) {
+            log.error("Cannot request NETCONF session for {}", data().deviceId());
+            return null;
+        }
+        return CzechLightDiscovery.doGetSubtree(session, subtreeXml);
+    }
+
+    private HierarchicalConfiguration doGetXPath(final String prefix, final String namespace, final String xpathFilter)
+            throws NetconfException {
+        NetconfSession session = getNetconfSession();
+        if (session == null) {
+            log.error("Cannot request NETCONF session for {}", data().deviceId());
+            return null;
+        }
+        return CzechLightDiscovery.doGetXPath(session, prefix, namespace, xpathFilter);
+    }
+
+    public boolean doEditConfig(String mode, String cfg) {
+        NetconfSession session = getNetconfSession();
+        if (session == null) {
+            log.error("Cannot request NETCONF session for {}", data().deviceId());
+            return false;
+        }
+
+        try {
+            return session.editConfig(DatastoreId.RUNNING, mode, cfg);
+        } catch (NetconfException e) {
+            throw new IllegalStateException(new NetconfException("Failed to edit configuration.", e));
+        }
+    }
+
+    private NetconfSession getNetconfSession() {
+        NetconfController controller =
+                checkNotNull(handler().get(NetconfController.class));
+        return controller.getNetconfDevice(data().deviceId()).getSession();
+    }
+}
diff --git a/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/CzechLightLambdaQuery.java b/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/CzechLightLambdaQuery.java
new file mode 100644
index 0000000..f8533dd
--- /dev/null
+++ b/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/CzechLightLambdaQuery.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.drivers.czechlight;
+
+import org.onlab.util.Frequency;
+import org.onlab.util.Spectrum;
+import org.onosproject.net.ChannelSpacing;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.LambdaQuery;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.stream.IntStream;
+import java.util.stream.Collectors;
+
+/**
+ * Implementation of lambda query interface for CzechLight ROADMs.
+ *
+ * These devices are actually fully flexgrid-capable. Same as the other devices supported by ONOS,
+ * we're just returning a dummy list of 50 GHz channels.
+ */
+public class CzechLightLambdaQuery extends AbstractHandlerBehaviour implements LambdaQuery {
+
+    private static final Frequency START_CENTER_FREQ_50 = Frequency.ofGHz(191_350);
+    private static final Frequency END_CENTER_FREQ_50 = Frequency.ofGHz(196_100);
+
+    @Override
+    public Set<OchSignal> queryLambdas(PortNumber portNumber) {
+        DeviceService deviceService = this.handler().get(DeviceService.class);
+        Port port = deviceService.getPort(data().deviceId(), portNumber);
+
+        if ((port.type() == Port.Type.FIBER) || (port.type() == Port.Type.OMS)) {
+            final int startMultiplier50 = (int) (START_CENTER_FREQ_50.subtract(Spectrum.CENTER_FREQUENCY).asHz()
+                    / Frequency.ofGHz(50).asHz());
+            final int endMultiplier50 = (int) (END_CENTER_FREQ_50.subtract(Spectrum.CENTER_FREQUENCY).asHz()
+                    / Frequency.ofGHz(50).asHz());
+            return IntStream.range(startMultiplier50, endMultiplier50 + 1)
+                    .mapToObj(x -> OchSignal.newDwdmSlot(ChannelSpacing.CHL_50GHZ, x))
+                    .collect(Collectors.toSet());
+        } else {
+            return Collections.emptySet();
+        }
+    }
+}
+
+
diff --git a/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/CzechLightPowerConfig.java b/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/CzechLightPowerConfig.java
new file mode 100644
index 0000000..8e63bd7
--- /dev/null
+++ b/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/CzechLightPowerConfig.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright 2019-2020 Jan Kundrát, CESNET, <jan.kundrat@cesnet.cz> and Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.czechlight;
+
+import com.google.common.collect.Range;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.behaviour.PowerConfig;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+
+import java.util.Arrays;
+import java.util.Optional;
+
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfController;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.slf4j.Logger;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+public class CzechLightPowerConfig<T> extends AbstractHandlerBehaviour
+        implements PowerConfig<T> {
+
+    private final Logger log = getLogger(getClass());
+
+
+    @Override
+    public Optional<Double> getTargetPower(PortNumber port, T component) {
+        return Optional.empty();
+    }
+
+    //Used by the ROADM app to set the "attenuation" parameter
+    @Override
+    public void setTargetPower(PortNumber port, T component, double power) {
+        switch (deviceType()) {
+            case LINE_DEGREE:
+            case ADD_DROP_FLEX:
+                if (!(component instanceof OchSignal)) {
+                    log.error("Cannot set target power or anything but a Media Channel");
+                    return;
+                }
+                HierarchicalConfiguration xml;
+                try {
+                    xml = doGetSubtree(CzechLightDiscovery.CHANNEL_DEFS_FILTER + CzechLightDiscovery.MC_ROUTING_FILTER);
+                } catch (NetconfException e) {
+                    log.error("Cannot read data from NETCONF: {}", e);
+                    return;
+                }
+                final var allChannels = MediaChannelDefinition.parseChannelDefinitions(xml);
+                final var och = ((OchSignal) component);
+                final var channel = allChannels.entrySet().stream()
+                        .filter(entry -> MediaChannelDefinition.mcMatches(entry, och))
+                        .findAny()
+                        .orElse(null);
+                if (channel == null) {
+                    log.error("Cannot map OCh definition {} to a channel from the channel plan", och);
+                    return;
+                }
+                final String element = port.toLong() == CzechLightDiscovery.PORT_COMMON ? "add" : "drop";
+                log.debug("{}: {} power for {} to {}", data().deviceId(), channel.getKey(), power);
+                var sb = new StringBuilder();
+                sb.append(CzechLightDiscovery.XML_MC_OPEN);
+                sb.append("<channel>");
+                sb.append(channel.getKey());
+                sb.append("</channel>");
+                sb.append("<");
+                sb.append(element);
+                sb.append("><power>");
+                sb.append(power);
+                sb.append("</power></");
+                sb.append(element);
+                sb.append(">");
+                sb.append(CzechLightDiscovery.XML_MC_CLOSE);
+                doEditConfig("merge", sb.toString());
+                return;
+            default:
+                log.error("Target power is only supported on WSS-based devices");
+                return;
+        }
+    }
+
+    @Override
+    public Optional<Double> currentPower(PortNumber port, T component) {
+        if (component instanceof OchSignal) {
+            // FIXME: this should be actually very easy for MCs that are routed...
+            log.debug("per-MC power not implemented yet");
+            return Optional.empty();
+        }
+        switch (deviceType()) {
+            case LINE_DEGREE:
+            case ADD_DROP_FLEX:
+                if (port.toLong() == CzechLightDiscovery.PORT_COMMON) {
+                    return Optional.ofNullable(fetchLeafDouble(CzechLightDiscovery.NS_CZECHLIGHT_ROADM_DEVICE,
+                            "aggregate-power/common-out"));
+                } else {
+                    return Optional.ofNullable(fetchLeafSum(CzechLightDiscovery.NS_CZECHLIGHT_ROADM_DEVICE,
+                            "media-channels[drop/port = '" +
+                                    CzechLightDiscovery.leafPortName(deviceType(), port.toLong()) +
+                                    "']/power/leaf-out"));
+                }
+            case COHERENT_ADD_DROP:
+                if (component instanceof OchSignal) {
+                    log.debug("Coherent Add/Drop: cannot query per-MC channel power");
+                    return Optional.empty();
+                }
+                if (port.toLong() == CzechLightDiscovery.PORT_COMMON) {
+                    return Optional.ofNullable(fetchLeafDouble(CzechLightDiscovery.NS_CZECHLIGHT_COHERENT_A_D,
+                            "aggregate-power/express-out"));
+                } else {
+                    return Optional.ofNullable(fetchLeafDouble(CzechLightDiscovery.NS_CZECHLIGHT_COHERENT_A_D,
+                            "aggregate-power/drop"));
+                }
+            case INLINE_AMP:
+                return Optional.ofNullable(fetchLeafDouble(CzechLightDiscovery.NS_CZECHLIGHT_INLINE_AMP,
+                        inlineAmpStageNameFor(port) + "/optical-power/output"));
+            default:
+                assert false : "unhandled device type";
+        }
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<Double> currentInputPower(PortNumber port, T component)  {
+        if (component instanceof OchSignal) {
+            log.debug("per-MC power not implemented yet");
+            return Optional.empty();
+        }
+        switch (deviceType()) {
+            case LINE_DEGREE:
+            case ADD_DROP_FLEX:
+                if (port.toLong() == CzechLightDiscovery.PORT_COMMON) {
+                    return Optional.ofNullable(fetchLeafDouble(CzechLightDiscovery.NS_CZECHLIGHT_ROADM_DEVICE,
+                            "aggregate-power/common-in"));
+                } else {
+                    return Optional.ofNullable(fetchLeafSum(CzechLightDiscovery.NS_CZECHLIGHT_ROADM_DEVICE,
+                            "media-channels[add/port = '" +
+                                    CzechLightDiscovery.leafPortName(deviceType(), port.toLong()) +
+                                    "']/power/leaf-in"));
+                }
+            case COHERENT_ADD_DROP:
+                if (component instanceof OchSignal) {
+                    log.debug("Coherent Add/Drop: cannot query per-MC channel power");
+                    return Optional.empty();
+                }
+                if (port.toLong() == CzechLightDiscovery.PORT_COMMON) {
+                    return Optional.ofNullable(fetchLeafDouble(CzechLightDiscovery.NS_CZECHLIGHT_COHERENT_A_D,
+                            "aggregate-power/express-in"));
+                } else {
+                    return Optional.ofNullable(fetchLeafDouble(CzechLightDiscovery.NS_CZECHLIGHT_COHERENT_A_D,
+                            "client-ports[port='" + Long.toString(port.toLong()) + "']/input-power"));
+                }
+            case INLINE_AMP:
+                return Optional.ofNullable(fetchLeafDouble(CzechLightDiscovery.NS_CZECHLIGHT_INLINE_AMP,
+                        inlineAmpStageNameFor(port) + "/optical-power/input"));
+            default:
+                assert false : "unhandled device type";
+        }
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<Range<Double>> getTargetPowerRange(PortNumber portNumber, T component) {
+        switch (deviceType()) {
+            case LINE_DEGREE:
+            case ADD_DROP_FLEX:
+                if (component instanceof OchSignal) {
+                    // not all values might be actually set, it's complicated, so at least return some limit
+                    return Optional.ofNullable(Range.closed(-25.0, 5.0));
+                }
+            default:
+                // pass
+        }
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<Range<Double>> getInputPowerRange(PortNumber portNumber, T component) {
+        switch (deviceType()) {
+            case LINE_DEGREE:
+            case ADD_DROP_FLEX:
+                if (component instanceof OchSignal) {
+                    // not all values might be actually set, it's complicated, so at least return some limit
+                    return Optional.ofNullable(Range.closed(-30.0, +10.0));
+                }
+            default:
+                // pass
+        }
+        return Optional.empty();
+    }
+
+    private CzechLightDiscovery.DeviceType deviceType() {
+        var annotations = this.handler().get(DeviceService.class).getDevice(handler().data().deviceId()).annotations();
+        return CzechLightDiscovery.DeviceType.valueOf(annotations.value(CzechLightDiscovery.DEVICE_TYPE_ANNOTATION));
+    }
+
+    private Double fetchLeafDouble(final String namespace, final String xpath) {
+        try {
+            final var res = doGetXPath("M", namespace, "/M:" + xpath);
+            final var key = CzechLightDiscovery.xpathToXmlKey(xpath);
+            if (!res.containsKey(key)) {
+                log.error("<get> reply does not contain data for key '{}'", key);
+                return null;
+            }
+            return res.getDouble(key);
+        } catch (NetconfException e) {
+            log.error("Cannot read data from NETCONF: {}", e);
+            return null;
+        }
+    }
+
+    private Double fetchLeafSum(final String namespace, final String xpath) {
+        try {
+            final var data = doGetXPath("M", namespace, "/M:" + xpath);
+            final var key = CzechLightDiscovery.xpathToXmlKey(xpath);
+            final var power = Arrays.stream(data.getStringArray(key))
+                    .map(s -> Double.valueOf(s))
+                    .map(dBm -> CzechLightDiscovery.dbmToMilliwatts(dBm))
+                    .reduce(0.0, Double::sum);
+            log.debug(" -> power lin {}, dBm: {}", power, CzechLightDiscovery.milliwattsToDbm(power));
+            return CzechLightDiscovery.milliwattsToDbm(power);
+        } catch (NetconfException e) {
+            log.error("Cannot read data from NETCONF: {}", e);
+            return null;
+        }
+    }
+
+    private String inlineAmpStageNameFor(final PortNumber port) {
+        return port.toLong() == CzechLightDiscovery.PORT_INLINE_WEST ? "west-to-east" : "east-to-west";
+    }
+
+    private HierarchicalConfiguration doGetXPath(final String prefix, final String namespace, final String xpathFilter)
+            throws NetconfException {
+        NetconfSession session = getNetconfSession();
+        if (session == null) {
+            log.error("Cannot request NETCONF session for {}", data().deviceId());
+            return null;
+        }
+        return CzechLightDiscovery.doGetXPath(session, prefix, namespace, xpathFilter);
+    }
+
+    private HierarchicalConfiguration doGetSubtree(final String subtreeXml) throws NetconfException {
+        NetconfSession session = getNetconfSession();
+        if (session == null) {
+            log.error("Cannot request NETCONF session for {}", data().deviceId());
+            return null;
+        }
+        return CzechLightDiscovery.doGetSubtree(session, subtreeXml);
+    }
+
+    public boolean doEditConfig(String mode, String cfg) {
+        NetconfSession session = getNetconfSession();
+        if (session == null) {
+            log.error("Cannot request NETCONF session for {}", data().deviceId());
+            return false;
+        }
+
+        try {
+            return session.editConfig(DatastoreId.RUNNING, mode, cfg);
+        } catch (NetconfException e) {
+            throw new IllegalStateException(new NetconfException("Failed to edit configuration.", e));
+        }
+    }
+
+    private NetconfSession getNetconfSession() {
+        NetconfController controller =
+                checkNotNull(handler().get(NetconfController.class));
+        return controller.getNetconfDevice(data().deviceId()).getSession();
+    }
+}
diff --git a/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/MediaChannelDefinition.java b/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/MediaChannelDefinition.java
new file mode 100644
index 0000000..124337e
--- /dev/null
+++ b/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/MediaChannelDefinition.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2019-2020 Jan Kundrát, CESNET, <jan.kundrat@cesnet.cz> and Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.czechlight;
+
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.onosproject.net.OchSignal;
+
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/** Media Channel definition specifies a frequency range, i.e., a channel in a flexgrid DWDM system as retrieved from
+ * the ROADM device. We cannot use something like an OchSignal because this represents raw data on the device.
+ */
+class MediaChannelDefinition {
+    public int lowMHz;
+    public int highMHz;
+
+    public MediaChannelDefinition(final int lowMHz, final int highMHz) {
+        this.lowMHz = lowMHz;
+        this.highMHz = highMHz;
+    }
+
+    public String toString() {
+        return "Channel{" + String.valueOf(lowMHz / 1_000_000.0) + " - " + String.valueOf(highMHz / 1_000_000.0) + "}";
+    }
+
+    public static Map<String, MediaChannelDefinition> parseChannelDefinitions(final HierarchicalConfiguration xml) {
+        return xml.configurationsAt("data.channel-plan.channel").stream()
+                .collect(Collectors.toMap(x -> x.getString("name"),
+                        x -> new MediaChannelDefinition(x.getInt("lower-frequency"),
+                                x.getInt("upper-frequency"))));
+    }
+
+    public static boolean mcMatches(final Map.Entry<String, MediaChannelDefinition> entry, final OchSignal och) {
+        return entry.getValue().lowMHz == och.centralFrequency().asMHz() - och.slotWidth().asMHz() / 2
+                && entry.getValue().highMHz == och.centralFrequency().asMHz() + och.slotWidth().asMHz() / 2;
+    }
+
+};
+
diff --git a/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/package-info.java b/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/package-info.java
new file mode 100644
index 0000000..2c40d55
--- /dev/null
+++ b/drivers/czechlight/src/main/java/org/onosproject/drivers/czechlight/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Package for CzechLight device drivers.
+ */
+package org.onosproject.drivers.czechlight;
